内容
# pi-mcp-桥接
> 一个 [Pi 代理](https://pi.dev/docs/latest/extensions) 扩展程序,将任何 [模型上下文协议](https://modelcontextprotocol.io/)(MCP)服务器通过 **三个LLM可调用工具** — `CallMcpTool`、`FetchMcpResource` 和 `ListMcpResources` — 以及 **基于文件系统的注册表** 和 **类似光标的系统提示注入** 集成到Pi中,以保持代理的上下文窗口廉价且缓存友好。
[](./LICENSE)
[](./package.json)
[](./openspec/)
**简体中文** · [英文](./README.md)
---
## 为什么
Cursor 的 [动态上下文发现](https://cursor.com/cn/blog/dynamic-context-discovery) 论文提出了敏锐的观察:直接向LLM公开所有MCP工具会使系统膨胀并消耗上下文。解决方法是仅公开几个通用工具,让模型按需从紧凑、可发现的注册表中获取特定工具模式。
`pi-mcp-bridge` 将该模式引入Pi代理 — 并与Cursor的实现方式保持一致:
- **`CallMcpTool`** — 通过 `server` + `toolName` + `arguments` 调用任意MCP工具。
- **`FetchMcpResource`** — 通过 `server` + `uri` 读取任意MCP资源,可选保存到磁盘。
- **`ListMcpResources`** — 列出服务器公开的资源(在获取前先发现)。
- **文件系统是关键** — 每个MCP服务器都由 `registry/<server>/meta.json` + `registry/<server>/tools/<tool>.json` 描述。代理读取这些文件以了解如何调用工具,然后使用正确的参数调用 `CallMcpTool`。
- **类似光标的系统提示注入** — 在每个回合中,注册表的紧凑Markdown索引通过 `before_agent_start` 事件**追加到系统提示**(不是作为用户消息预先追加)。系统提示是最稳定的缓存前缀,因此只要注册表不变,该块就会在回合之间缓存。对于小型注册表(默认≤10个工具),完整的 `inputSchema` 内联,以便模型可以正确调用;对于较大的注册表,该块会退回到名称 + 描述,模型按需读取模式文件。
## 架构(60秒游览)
```
┌──────────────────────────────────────────────────────────────────┐
│ Pi 代理(LLM) │
│ 系统提示 ◀── MCP注册表块通过 │
│ before_agent_start (类似光标) │
│ 工具:[CallMcpTool, FetchMcpResource, ListMcpResources] │
└───────────────┬──────────────────────────────────────────────────┘
│ CallMcpTool({server, toolName, arguments})
▼
┌──────────────────────────────────────────────────────────────────┐
│ pi-mcp-bridge │
│ 1. 解析(server, toolName)→ registry/<server>/tools/*.json │
│ 2. 延迟连接到该MCP服务器(空闲超时) │
│ 3. 转发参数,等待结果 │
│ 4. 输出保护:截断 + 溢出到临时文件 │
│ 5. 返回内容块到Pi │
└───────────────┬──────────────────────────────────────────────────┘
│ MCP协议(stdio / HTTP / SSE)
▼
┌──────────────────────────────────────────────────────────────────┐
│ MCP服务器(文件系统,github,slack,…) │
└──────────────────────────────────────────────────────────────────┘
```
查看 [`docs/architecture.md`](./docs/architecture.md) 以获取完整的模块地图、设计决策和行为合约。
## 快速开始
### 1. 安装
```bash
pi install npm:@qianhuan-lxs/pi-mcp-bridge
```
此命令在 `~/.pi/agent/npm/` 下安装软件包,并通过其 `pi.extensions` 清单自动注册扩展程序 — 无需手动编辑配置。
> **注意:** `pi install` 需要Pi v0.74+。如果您使用的是较旧的Pi或希望手动管理,请在 `~/.pi/agent/settings.json` 的 `packages` 数组中添加 `"@qianhuan-lxs/pi-mcp-bridge"`。
### 2. 注册扩展程序
添加到您的Pi代理配置中(例如 `~/.pi/agent.json`):
```jsonc
{
"extensions": [
"pi-mcp-bridge"
]
}
```
### 3. 将MCP服务器添加到注册表
#### stdio — context7(库文档查找)
```
# 在Pi内部 - 将实时MCP服务器的工具同步到注册表(主要路径))
/mcp-bridge sync context7 -- npx -y @upstash/context7-mcp
# 或先添加服务器存根(带有环境变量),然后同步
/mcp-bridge add github --env GITHUB_PERSONAL_ACCESS_TOKEN -- npx -y @modelcontextprotocol/server-github
/mcp-bridge sync github
# 验证 / 列出 / 检查状态
/mcp-bridge validate
/mcp-bridge list
/mcp-bridge status
```
#### 流式HTTP(现代MCP HTTP传输)
在单独的终端中启动服务器:
```bash
npx -y @modelcontextprotocol/server-everything streamableHttp
# 在 http://localhost:3000/mcp 提供服务
```
然后在Pi中:
```
/mcp-bridge add everything-http --url http://localhost:3000/mcp --description "Everything MCP(流式HTTP)"
/mcp-bridge sync everything-http
```
#### SSE(旧版HTTP传输)
在单独的终端中启动服务器:
```bash
npx -y @modelcontextprotocol/server-everything sse
# 在 http://localhost:3001/sse 提供服务
```
然后在Pi中:
```
/mcp-bridge add everything-sse --url http://localhost:3001/sse --description "Everything MCP(SSE)"
/mcp-bridge sync everything-sse
```
> **传输自动检测:** 对于 `kind: "http"` 服务器,`/mcp-bridge sync` 和延迟连接都会首先探测 **StreamableHTTP**,然后自动回退到 **SSE** — 您无需显式选择传输;URL足够。
> **为什么使用斜杠命令?** 注册表管理通过 `/mcp-bridge ...` 在Pi内部进行,因此无需PATH设置和单独的CLI二进制文件。仍包含可选的 `cli.ts` 以用于脚本编写 — 通过 `npx tsx ./node_modules/@qianhuan-lxs/pi-mcp-bridge/cli.ts <cmd>` 运行。
这会生成:
```
~/.pi/agent/mcp-registry/
context7/
meta.json
tools/
resolve-library-id.json
query-docs.json
...
everything-http/
meta.json
tools/...
index.json
```
### 4. 重启Pi并询问
```
> 使用context7查找最新的AgentScope文档
```
代理将:
1. 从其 **系统提示** (通过 `before_agent_start` 注入)读取MCP注册表块。对于小型注册表,已经内联了完整的 `inputSchema`;对于大型注册表,它会看到服务器的 `folder:` 路径并按需读取 `<folder>/tools/<tool>.json`。
2. 调用 `CallMcpTool({server:"context7", toolName:"resolve-library-id", arguments:{...}})`,然后 `CallMcpTool({server:"context7", toolName:"query-docs", arguments:{...}})`.
3. 接收结果(如果结果太大,则截断,并为完整内容溢出到临时文件)。
要先发现资源,请使用 `ListMcpResources({server:"..."})`,然后 `FetchMcpResource({server, uri})`。
## 注册表布局
```
~/.pi/agent/mcp-registry/
<server>/
meta.json # 服务器配置:命令、环境、传输、超时、说明
tools/
<tool>.json # 每个工具一个文件:名称、描述、inputSchema
index.json # 聚合索引(由 `sync` / `validate` 重建)
```
`meta.json` 示例(stdio — context7):
```json
{
"name": "context7",
"description": "Context7文档MCP服务器",
"instructions": "使用此服务器获取库的最新文档。始终先调用resolve-library-id,然后调用query-docs。",
"transport": {
"kind": "stdio",
"command": "npx",
"args": ["-y", "@upstash/context7-mcp"],
"env": {}
},
"auth": { "kind": "none" },
"lifecycle": { "mode": "lazy", "idleTimeoutMinutes": 10 },
"syncedFrom": "live-server",
"syncedAt": "2026-07-19T06:00:00.000Z"
}
```
`meta.json` 示例(HTTP — 流式HTTP或SSE,相同结构):
```json
{
"name": "everything-http",
"description": "Everything MCP(流式HTTP)",
"transport": {
"kind": "http",
"url": "http://localhost:3000/mcp",
"headers": {}
},
"auth": { "kind": "none" },
"lifecycle": { "mode": "lazy", "idleTimeoutMinutes": 10 },
"syncedFrom": "live-server",
"syncedAt": "2026-07-19T06:00:00.000Z"
}
```
> `instructions` 在 `/mcp-bridge sync` 期间从MCP服务器的 `initialize` 响应中自动捕获。您也可以手动编辑。对于HTTP服务器,传输类型只是 `"http"` — 同步和延迟连接会自动探测StreamableHTTP,然后回退到SSE。
`tools/resolve-library-id.json` 示例:
```json
{
"name": "resolve-library-id",
"description": "从库名称解析Context7兼容的库ID。",
"inputSchema": {
"type": "object",
"properties": {
"query": { "type": "string" },
"libraryName": { "type": "string" }
},
"required": ["query", "libraryName"]
}
}
```
查看 [`docs/config-format.md`](./docs/config-format.md) 以获取完整的模式参考。
## 上下文注入(模型如何了解MCP)
注入块通过 `before_agent_start` 事件**追加到系统提示**。它走一个截断梯度(首先是最多细节;能容纳的级别为准):
| 级别 | 内容 | 何时使用 |
|-------|---------|-----------|
| 1. `renderWithSchemas` | 工具名称 + 描述 + **完整的 `inputSchema` JSON内联** + 服务器 `instructions` | 注册表 ≤ `schemaInjectionToolLimit` 工具(默认为10)并且符合预算 |
| 2. `renderFull(80)` | 工具名称 + 80字符描述 + 服务器 `instructions` | 级别1跳过/溢出 |
| 3. `renderFull(40)` | 工具名称 + 40字符描述 + `instructions` | 级别2溢出 |
| 4. `renderKeysOnly` | 仅工具键 + `instructions` | 级别3溢出 |
| 5. `renderCountsOnly` | 服务器名称 + 工具计数 | 级别4溢出 |
每个服务器标题都包含 `folder: <绝对描述符路径>`,因此模型知道在哪里 `ls`/`read` 以获取模式。该块还包含一个 `MANDATORY: 在调用CallMcpTool之前读取工具的描述文件` 指令(有一个例外,即内联模式让模型跳过读取)。
**为什么使用系统提示注入?** 这是最具缓存友好的注入点 — 系统提示是最稳定的缓存前缀,因此只要注册表不变,该块就会在回合之间缓存。(早期版本通过 `context` 事件预先追加了一个 `user` 消息,这有效但移动了消息数组并且不太缓存友好。v0.3.0 切换到 `before_agent_start` 以匹配Cursor的方法。)
## 斜杠命令
`/mcp-bridge` 命令是注册表管理的主要接口(无需单独的CLI二进制文件,无需PATH设置):
/mcp-bridge sync <server> [--env K=V]... [--force] -- <command> [args...]
连接到实时MCP服务器,捕获其说明 + 工具/资源,
并将meta.json + tools/*.json写入注册表。自动为下一个回合重新加载代理上下文。
/mcp-bridge add <server> [--env K=V]... -- <command> [args...]
一步添加服务器并同步其工具/资源。
/mcp-bridge add <server> --url <url> [--description <text>]
添加HTTP传输服务器并针对URL自动同步。
/mcp-bridge remove <server> [--keep-config]
删除服务器的注册目录,关闭任何实时连接,
并将其从mcp-servers.json中删除(跳过JSON编辑时使用--keep-config)。
别名:rm,delete。
/mcp-bridge validate
验证注册表是否符合JSON模式并重建index.json。
/mcp-bridge list
列出注册表中的所有服务器及其工具。
/mcp-bridge status
显示服务器/工具,MCP上下文占用量(~tokens vs 预算),
以及与始终内联完整模式相比节省的token。
/mcp-bridge reload
调和可选的mcp-servers.json(添加/更新/0工具自动同步),
重新读取注册表,并在下一个回合刷新系统提示上下文。
/mcp-bridge approve <server>
(仅当 `requireConsent` 开启时。)批准服务器以便CallMcpTool调用通过。
/mcp-bridge revoke <server>
撤销服务器的同意;未来CallMcpTool调用将被阻止,直到重新批准。
可选的 `cli.ts` 包装相同的逻辑用于脚本编写/CI:
```bash
npx tsx ./node_modules/@qianhuan-lxs/pi-mcp-bridge/cli.ts <sync|add|validate|list> ...
```
## 配置
### MCP服务器文件(OpenCode对齐,可选)
在单个JSON文件中手动编辑传输配置 — 与OpenCode的 `mcp` 块相同结构。桥接器在 `session_start` 和 `/mcp-bridge reload` 时将其协调到文件系统注册表(`meta.json`),然后自动同步**添加**、**更新传输**或配置但仍有 **0 个工具** 的服务器。
重启Pi后 **重启Pi** 以加载新的扩展代码 — `/mcp-bridge reload` 只会重载注册表 + `mcp-servers.json`,不会重载扩展本身。
路径(项目覆盖全局服务器名称):
- 全局: `~/.pi/agent/mcp-servers.json`
- 项目: `.pi/mcp-servers.json`
```jsonc
{
"mcp": {
"context7": {
"type": "local",
"command": ["npx", "-y", "@upstash/context7-mcp"],
"enabled": true
},
"filesystem": {
"type": "local",
"command": ["npx", "-y", "@modelcontextprotocol/server-filesystem", "/path/to/root"],
"environment": { "FOO": "bar" }
},
"docs": {
"type": "remote",
"url": "https://mcp.example.com/mcp",
"headers": { "Authorization": "Bearer ..." },
"enabled": true
}
}
}
```
| 字段 | 含义 |
| --- | --- |
| `type` | `"local"`(stdio)或 `"remote"`(HTTP / SSE) |
| `command` | 本地仅:命令 + 参数为字符串数组(OpenCode样式) |
| `environment` / `cwd` | 本地仅:环境变量/工作目录 |
| `url` / `headers` | 远程仅 |
| `oauth` | 远程仅:OAuth对象(存储在 `meta.auth` 中用于第2阶段)或 `false` |
| `enabled` | `false` 跳过服务器(OpenCode语义);默认为启用 |
| `timeout` | 请求超时毫秒 → `meta.lifecycle.requestTimeoutMs` |
策略:注册表中缺少的服务器会 **警告**,永远不会删除。 `/mcp-bridge add` 仍然有效作为快捷方式;如果 `mcp-servers.json` 已经存在, `add` 也会更新OpenCode形状的条目。
工具模式保留在 `registry/<server>/tools/*.json` (同步产品) — 编辑JSON用于传输,不用于模式。
### 桥接器设置
`~/.pi/agent/mcp-bridge.json`(所有字段可选;显示默认值):
```jsonc
{
"idleTimeout": 10, // 分钟,默认为10,0禁用
"requestTimeoutMs": 0, // 毫秒,0 = 使用SDK默认值
"outputGuard": true, // 截断超大工具输出
"contextBudgetTokens": 4000, // 注入系统提示块的最大令牌数
"schemaInjectionToolLimit": 10, // 注册表 > N 工具跳过内联模式
// 0 = 完全禁用内联模式
"uiViewer": "auto", // "auto" | "browser" | "glimpse"
"requireConsent": false // CallMcpTool背后门控/mcp-bridge approve(默认为false)
}
环境变量覆盖:
- `PI_CODING_AGENT_DIR` — 覆盖Pi代理目录(默认为 `~/.pi/agent`)。
- `PI_MCP_BRIDGE_REGISTRY` — 覆盖注册根目录(默认为 `<agent dir>/mcp-registry`)。
- `MCP_OUTPUT_GUARD=0` — 禁止输出保护。
## 许可证
MIT © 2026 [qianhuan-lxs](https://github.com/qianhuan-lxs))
</div>
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器