内容
<div align="center">
# 🛡️ mcp-bastion
**模型上下文协议(MCP)的可靠性与安全性代理。**
_自愈连接、运行时工具安全性和合规映射审计追踪,适用于您的MCP服务器。_
[](https://www.npmjs.com/package/mcp-bastion)
[](https://www.npmjs.com/package/mcp-bastion)
[](https://github.com/Gowthaman90/mcp-bastion/actions/workflows/ci.yml)
[](./LICENSE)
[](https://nodejs.org)
[](https://www.typescriptlang.org/)
[](#contributing)
<br/>
<img src="./assets/demo.svg" alt="mcp-bastion: 一个MCP服务器在会话中崩溃,代理自动恢复" width="760">
</div>
---
`mcp-bastion` 位于您的MCP客户端(Claude Code、Cursor、Cline、Windsurf、Zed、Claude Desktop或任何MCP兼容代理)和MCP服务器之间。它是**客户端无关的** - 它适用于任何兼容的客户端,只需通过配置即可,无需客户端特定代码 - 而且**非侵入性的**:您的服务器无需更改即可运行,移除Bastion只需一行配置即可恢复。
📖 **发布故事:** [Medium](https://medium.com/p/e74f638e9e15) · [dev.to](https://dev.to/gowthaman90/the-mcp-reliability-security-gap-and-an-open-source-proxy-that-fills-it-3ppo)
## 目录
- [为什么](#为什么)
- [工作原理](#工作原理)
- [功能](#功能)
- [快速开始](#快速开始)
- [演示](#演示)
- [控制工具](#控制工具)
- [配置](#配置)
- [传输](#传输)
- [运行时安全](#运行时安全)
- [审计和合规](#审计和合规)
- [客户端设置](#客户端设置)
- [架构](#架构)
- [开发](#开发)
- [路线图](#路线图)
- [贡献](#贡献)
- [安全](#安全)
- [许可证](#许可证)
## 为什么
当MCP服务器在会话中斷开时,代理只会看到一个通用的_"没有可用的工具"_错误 - **与从未存在的工具无法区分** - 并且无法重新连接;只有人类才能做到这一点。长时间的代理会话会默默地失去功能,并以令人困惑的方式失败。
Bastion弥补了这一空白。它对每个服务器进行健康检查,自动重新连接,并 - 至关重要的是 - 暴露控制工具,以便**代理本身**可以检查连接健康状况并在无人干预的情况下恢复一个已掉落的服务器。
> Bastion 现在跨越三个层:**可靠性**(v0.1)、**运行时安全**(v0.2 - 工具固定/地毯拉扯和中毒检测)和**审计和合规**(v0.3 - 可插入的汇 sink 映射到NIST AI RMF / OWASP LLM Top 10)。
## 工作原理
今天,您的客户端直接连接到每个服务器。使用Bastion,您的客户端连接到**Bastion**,后者代表您连接到这些相同的服务器 - 因此它位于工具调用路径中,可以透明地添加可靠性(和稍后的安全性)。
```
之前: 客户端 ─▶ 服务器 A / 服务器 B / 服务器 C
之后: 客户端 ─▶ mcp-bastion ─▶ 服务器 A
─▶ 服务器 B
─▶ 服务器 C
```
Bastion是您客户端的标准MCP**服务器**,也是每个上游的标准MCP**客户端**。因为它忠实地讲协议,所以它与每个兼容的客户端自动配合 - 唯一的客户端差异是您放置几行配置的位置。
## 功能
- 🔌 **客户端无关** - 一个二进制文件,只需配置即可集成;无需客户端特定插件。
- ♻️ **自愈** - 健康检查 + 有上限的指数退避自动重新连接stdio服务器。
- 🧭 **代理可恢复** - `bastion__status` 和 `bastion__reconnect` 让代理检测和修复掉落的服务器本身,而不是遇到不透明的“没有此类工具”墙。
- 🧩 **透明聚合** - 合并多个服务器到一个,具有服务器特定的工具命名空间以防止冲突和工具遮蔽。
- 💬 **易读的故障** - 一个掉落的服务器产生一个可操作的错误信息,而不是崩溃。
- 🛡️ **运行时安全** _(新增 v0.2)_ - 固定每个工具的定义并阻止“地毯拉扯”(服务器在批准后更改工具);启发式检查描述中的中毒;检测跨服务器遮蔽。参见 [运行时安全](#运行时安全)。
- 📝 **审计和合规** _(新增 v0.3)_ - 结构化、篡改证据审计事件到可插入的 sink(控制台/文件/ webhook),映射到NIST AI RMF 和 OWASP LLM Top 10。参见 [审计和合规](#审计和合规)。
- 🪶 **非侵入性和可逆转** - 您的服务器无需更改即可运行;卸载是一个配置恢复。
- 🧱 **企业级代码库** - 严格的TypeScript、分层架构、ESLint + Prettier,以及单元 + 端到端测试。
## 快速开始
**1. 将Bastion添加到您的客户端**,指向一个配置文件:
```jsonc
// 客户端的 mcpServers 配置
{
"mcpServers": {
"bastion": {
"command": "npx",
"args": ["-y", "mcp-bastion", "--config", "bastion.config.json"],
},
},
}
```
**2. 在`bastion.config.json`中列出您的真实服务器** (直接从客户端移动):
```jsonc
{
"servers": {
"github": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-github"] },
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/dir"],
},
},
"reconnect": { "auto": true },
"healthCheck": { "enabled": true },
}
```
**3. 重启您的客户端。** 您的工具现在出现在命名空间(例如`github__create_issue`)以及Bastion的控制工具中。参见 [`bastion.config.example.json`](./bastion.config.example.json) 以获取完整的选项集。
## 演示
查看整个过程 - 一个服务器在会话中崩溃并自行恢复:
```bash
npm run demo
```
它启动Bastion,在一个按需崩溃的服务器前面,显示代理获得一个可操作的“重新连接”消息,而不是一个神秘的错误,然后连接在无人干预的情况下自动恢复。要将其记录为GIF:`asciinema rec demo.cast -c "npm run demo" && agg demo.cast assets/demo.gif`.
## 控制工具
Bastion注入控制工具,以便代理可以使用标准MCP调用管理连接并自行审查安全性:
| 工具 | 用途 |
| --- | --- |
| `bastion__status` | 每个代理服务器的健康状况:已连接/断开/重新连接/失败,工具计数,最后错误。 |
| `bastion__reconnect` | 在无需人为干预的情况下重新连接命名服务器(参数:`{ "server": "<name>" }`)。 |
| `bastion__security` | 每个工具的安全报告:固定状态(批准 vs 更改),中毒发现和遮蔽。 |
| `bastion__approve` | 重新批准更改的工具(参数:`{ "server": "...", "tool": "..." }`)以清除地毯拉扯阻塞。 |
| `bastion__compliance` | 最近活动的审计摘要,映射到NIST AI RMF / OWASP LLM Top 10(需要`audit.enabled`)。 |
## 配置
| 键 | 类型 | 默认值 | 描述 |
| --- | --- | --- | --- |
| `servers` | 地图 | - | 代理的上游服务器(必需,至少一个)。 |
| `servers.<name>.command` | 字符串 | - | 要启动的可执行文件(例如 `npx`、`node`)。 |
| `servers.<name>.args` | 字符串[] | `[]` | `command` 的参数。 |
| `servers.<name>.env` | 地图 | - | 进程环境变量的覆盖合并。 |
| `servers.<name>.cwd` | 字符串 | - | 启动进程的工作目录。 |
| `reconnect.auto` | 布尔值 | `true` | 连接意外断开后自动重新连接。 |
| `reconnect.maxRetries` | 数字 | `10` | 最大尝试次数(`-1` = 无限)。 |
| `reconnect.initialBackoffMs` | 数字 | `500` | 初始退避,倍增每次尝试。 |
| `reconnect.maxBackoffMs` | 数字 | `30000` | 退避上限。 |
| `healthCheck.enabled` | 布尔值 | `true` | 启用周期性活动探测。 |
| `healthCheck.intervalMs` | 数字 | `30000` | 探测之间的间隔。 |
| `healthCheck.timeoutMs` | 数字 | `5000` | 每个探测的超时时间。 |
| `namespace.strategy` | `prefix` \| `passthrough` | `prefix` | 上游工具名称的公开方式。 |
| `namespace.separator` | 字符串 | `__` | `prefix` 策略使用的分隔符。 |
| `security.pinTools` | 布尔值 | `true` | 固定工具定义并检测后续更改。 |
| `security.onRugPull` | `block` \| `warn` | `block` | 检测到工具定义更改时的操作。 |
| `security.inspectDescriptions` | 布尔值 | `true` | 对工具描述运行中毒启发式检测。 |
| `security.onPoisoning` | `block` \| `warn` | `warn` | 发现中毒时的操作。 |
| `audit.enabled` | 布尔值 | `false` | 为每个工具调用记录审计事件。 |
| `audit.includeArgs` | `none`\|`redacted`\|`full` | `none` | 记录工具参数的方式。 |
| `audit.tamperEvident` | 布尔值 | `false` | 哈希链事件,以便检测篡改。 |
| `audit.sinks` | 数组 | 控制台 | 目的地:`console`、`file`、`webhook`、`otlp`。 |
| `servers.<name>.transport` | `stdio` \| `http` | `stdio` | 本地子进程或远程端点。 |
| `servers.<name>.url` | 字符串 | - | 远程MCP URL(`http`必填)。 |
| `servers.<name>.headers` | 地图 | - | `http`上游的标头(例如`Authorization`)。 |
| `listen.mode` | `stdio` \| `http` | `stdio` | 通过stdio或Streamable HTTP提供Bastion。 |
| `listen.host` / `listen.port` | 字符串 / 数字 | `127.0.0.1` / `3000` | `http`模式的绑定地址。 |
## 传输
Bastion 在 **双方** 都支持两种传输:
- **stdio** (默认)- 客户端启动Bastion,Bastion启动本地服务器。
- **Streamable HTTP** - 连接到 **远程** MCP服务器(`servers.<name>`带有`transport: "http"`,一个`url`和可选身份验证`headers`),和/或 **提供** Bastion通过HTTP访问多个/远程客户端(`listen.mode: "http"`,或`--http <port>`)。
HTTP上游配置为没有身份验证标头时会被标记为`authenticated: false`,并在连接时发出警告。
## 运行时安全
_新增 v0.2._ Bastion 在工具调用路径中添加了一个安全层,默认启用:
- **地毯拉扯检测(工具固定)。** 每个工具的定义在首次使用时固定。如果服务器后来更改了定义,则该工具被阻止(`onRugPull: "block"`)直到您审查并重新批准 `bastion__approve`。这可以捕获一个服务器在安装时看起来是良性的,但在之后变成恶意的。
- **中毒检查。** 工具名称和描述会扫描操纵启发式(指令覆盖、秘密访问、数据流出、隐蔽指令、嵌入式指令、隐藏/零宽度字符)。由于启发式可能会假阳性,默认是`warn`(记录并报告,但不阻止);设置`onPoisoning: "block"`强制执行。
- **遮蔽。** 当两个服务器公开具有相同名称的工具时,它会在报告中显示。
使用 `bastion__security` 工具查看所有内容。这些检查目前适用于本地stdio服务器;身份验证检查将随HTTP传输支持到达。
## 审计和合规
_新增 v0.3. 需启用._ 启用 `audit` 以记录每个工具调用的结构化、版本化的事件 - 包括安全层阻止的调用:
```jsonc
"audit": {
"enabled": true,
"includeArgs": "redacted", // none | redacted | full
"tamperEvident": true, // hash-chain events
"sinks": [
{ "type": "file", "path": "./bastion-audit.jsonl" },
{ "type": "webhook", "url": "https://collector.example/v1/audit" }
]
}
```
- **可插入的sink.** `console`(stderr JSONL),`file`(JSONL追加),`webhook`(批处理POST),以及`otlp`(原生OpenTelemetry日志导出 - 将其指向OTel Collector以分发到任何SIEM/cloud后端)。 Sink接口使新目的地可添加。
- **合规映射.** 每个事件都映射到 **NIST AI RMF** 函数和 **OWASP LLM Top 10** 类别; `bastion__compliance` 返回最近活动的聚合报告。
- **篡改证据.** 使用 `tamperEvident`,事件被哈希链接;导出的 `verifyChain` 帮助程序检测任何溯源编辑或删除。
- **数据隐藏.** 参数默认省略;设置 `includeArgs` 为 `redacted` 以保留结构同时屏蔽敏感键。
## 客户端设置
步骤对于每个客户端都是相同的 - 只有 **配置文件位置** 不同:
| 客户端 | 添加 `bastion` 条目的位置 |
| --- | --- |
| Claude Code | 项目 `.mcp.json` (或 `claude mcp add`) |
| Cursor | `~/.cursor/mcp.json` 或项目 `.cursor/mcp.json` |
| Claude Desktop | `claude_desktop_config.json` |
| Cline | `cline_mcp_settings.json` |
| Windsurf | `~/.codeium/windsurf/mcp_config.json` |
> **渐进采用:** 您不必将每个服务器路由通过Bastion - 只需将您的flaky或不信任的服务器放在后面并让其他服务器直接连接。
## 架构
Bastion被组织成清晰的层,一-way依赖流,因此每个关注点都是独立可测试且易于演进:```
src/
├── cli.ts # thin CLI entrypoint(解析 → 线程 → 服务)
├── index.ts # public library API
├── errors.ts # error hierarchy(BastionError,…)
├── config/ # schema(Zod)+ loader
├── core/ # domain: upstream connection lifecycle, aggregation & routing
├── proxy/ # client-facing MCP server + control tools
├── observability/ # logging(audit sinks in v0.3)
└── internal/ # small cross-cutting utilities
```
设计细节 - 包括客户端无关的理由、拦截器管道和审计sink策略 - 存在于项目的设计文档中。
## 开发
```bash
npm install
npm run check # format:check + lint + typecheck + test(完整的门)
npm test # unit + end-to-end tests(in-memory transport)tests
npm run build # bundle to dist/(CLI + library)
npm run dev -- --config bastion.config.json
```
| 脚本 | 执行操作 |
| --- | --- |
| `build` | 使用 `tsup` 捆绑 CLI + 库。 |
| `dev` | 使用 `tsx` 从源代码运行 CLI。 |
| `typecheck` | `tsc --noEmit`(严格)。 |
| `lint` / `lint:fix` | ESLint(扁平配置)。 |
| `format` / `format:check` | Prettier。 |
| `test` / `test:watch` | Vitest。 |
| `check` | 所有上述操作,作为一个门。 |
## 路線图
| 版本 | 主题 | 亮点 |
| --- | --- | --- |
| **v0.1** | **可靠性** |聚合代理,自动重新连接,`bastion__status` / `__reconnect`。 |
| **v0.2** | **运行时安全** |工具定义固定(地毯拉扯检测),中毒检查,遮蔽检测。 |
| **v0.3** | **审计和合规** |可插入的审计sink(控制台/文件/webhook),NIST AI RMF / OWASP LLM Top 10 映射。 |
两种传输方式都支持 **stdio** 和 **Streamable HTTP** (见 [传输](#传输))。
## 贡献
非常欢迎贡献 - 该项目旨在社区拥有。请阅读 **[CONTRIBUTING.md](./CONTRIBUTING.md)** 获取开发设置,项目布局和PR工作流程,以及我们的 **[Code of Conduct](./CODE_OF_CONDUCT.md)**。
简而言之:对于非琐碎的更改,请打开一个问题;保持PR集中并附上测试,确保 `npm run check` 通过(CI在Node 18/20/22上运行)。良好的起点:额外的客户端设置说明,更多的上游测试fixtures,以及Streamable HTTP传输支持。
## 安全
`mcp-bastion` 是与安全相关的软件,因此我们对其保持高标准。请 **私下** 报告漏洞 - **不要公开问题**。请参阅 **[SECURITY.md](./SECURITY.md)** 获取披露流程。
## 许可证
[Apache-2.0](./LICENSE) © mcp-bastion contributors