内容
# MCP压缩路由
[](https://github.com/ameshkov/mcp-compress-router/actions/workflows/ci.yml)
[](https://www.npmjs.com/package/mcp-compress-router)
[](https://github.com/ameshkov/mcp-compress-router/releases)
<p align="center">
将所有连接的MCP压缩成单个路由器MCP,节省高达99%的token。
</p>
<p align="center">
<img src="docs/assets/mcp-compress-router.png"
alt="MCP压缩路由" width="600"/>
</p>
## 目录
- [问题](#问题)
- [解决方案](#解决方案)
- [前提条件](#前提条件)
- [快速入门](#快速入门)
- [配置](#配置)
- [配置文件位置](#配置文件位置)
- [添加下游服务器](#添加下游服务器)
- [每台服务器启用/禁用](#每台服务器启用禁用)
- [每台服务器工具选择](#每台服务器工具选择)
- [检查工具](#检查工具)
- [OAuth](#oauth)
- [重定向URL](#重定向url)
- [GitHub MCP(特殊情况)](#github-mcp特殊情况)
- [Figma MCP(特殊情况)](#figma-mcp特殊情况)
- [自定义标头](#自定义标头)
- [机密和变量扩展](#机密和变量扩展)
- [连接编码代理](#连接编码代理)
- [Opencode](#opencode)
- [Claude Code](#claude-code)
- [Codex](#codex)
- [GitHub Copilot](#github-copilot)
- [工作原理](#工作原理)
- [致谢](#致谢)
## 问题
当您有多个MCP时,每个LLM的请求将包含所有工具和描述,这可能会迅速消耗您的token限额并增加成本。
查看此[示例](docs/assets/tools.json)以了解其增长速度和规模。此示例仅代表3个流行的MCP服务器:Notion MCP、Github MCP和Pylance MCP。
产生的开销约为**26K tokens**,但让我们计算一下它实际上为您带来了多少美元的成本。我将使用Opus API定价进行计算,并假设平均而言,您有一个50回合的编码会话(这些天来相当合理)。
- 输入:`26K tokens * $5 / 1M = $0.13`
- 缓存写入(缓存不是免费的):`26K tokens * $6.25 / 1M = $0.1625`
- 缓存读取(49回合):`26K tokens * 49 * $0.50 / 1M = $0.637`
因此,平均编码会话的总开销约为**$0.9275**。这只是在3个MCP的情况下,如果您有更多的话,想象一下吧!
## 解决方案
与其每次发送所有工具和描述,不如使用单个路由器MCP,将所有连接的MCP压缩成一个,只包含两个工具:`get_tool_schema`、`invoke_tool`。
`get_tool_schema`在描述中只包含MCP服务器列表、可选描述(您可以自己编写)和每个MCP服务器的工具名称列表。[这里有一个示例](docs/assets/tools-compressed.json)展示了压缩版本的样子,它大约需要900个token。
如果我们重复使用压缩版本进行练习,那么平均编码会话的总开销将约为**$0.032175**,因此我们节省了大约**96.5%**的成本!
这只是一个包含3个MCP服务器的基本示例,您拥有的MCP服务器越多,节省的越多。
## 前提条件
- **Node.js 24 或更高版本** — 路由器在Node.js上运行,并通过`npx`启动,因此不需要单独的安装步骤。
- **支持stdio MCP服务器的编码代理** — 这涵盖了几乎所有现代编码代理(opencode、Claude Code、Codex、GitHub Copilot、Cursor等)。路由器将自己暴露为单个stdio MCP服务器,因此任何可以启动本地MCP进程的代理都可以使用。
## 快速入门
路由器作为[`mcp-compress-router`](https://www.npmjs.com/package/mcp-compress-router)在npm上发布。您不需要安装它 — 只需使用`npx`运行它:
```bash
npx mcp-compress-router add playwright2 -- npx -y @playwright/mcp
```
这会注册一个名为`playwright`的下游MCP服务器,并将其写入您的[配置文件](#配置文件位置)。重复此操作以添加您要压缩的每个MCP服务器。
然后,将您的[编码代理](#连接编码代理)指向路由器:
```bash
npx mcp-compress-router
```
当没有子命令启动时,路由器通过stdio运行MCP服务器,并向代理公开`get_tool_schema`和`invoke_tool`两个工具。
## 配置
路由器从单个JSON(C)文件中读取其配置,该文件列出了要压缩的每个下游MCP服务器。您可以通过编辑此文件或使用`add`/`remove`/`get`/`list`CLI命令来编辑此文件。
### 配置文件位置
默认情况下,配置文件位于平台特定的目录中(`mcp.jsonc`优先于`mcp.json`,如果两者都存在):
- **Windows:** `%APPDATA%\mcp-compress-router\`
- **macOS:** `~/Library/Application Support/mcp-compress-router/`
- **Linux:** `~/.local/share/mcp-compress-router/`
您可以使用以下方法覆盖此设置:
- 任意命令上的`-c, --config <path>`标志,或
- `MCP_COMPRESS_ROUTER_HOME`环境变量(指向包含配置文件的文件夹)。
如果在运行管理命令时文件不存在,则会自动创建具有空`{ "mcpServers": {} }`正文的文件。
`.env`文件在**同一目录**中自动加载,因此您可以将机密信息排除在配置文件之外(请参见[机密和变量扩展](#机密和变量扩展))。
> **注意`-c`和凭证存储:**当您使用`-c /some/dir/mcp.json`覆盖配置路径时,`credentials.json`(OAuth令牌)和`mcp.json`都位于`/some/dir/`中 — 即您指定的配置文件旁边。但是,`.env`文件从`MCP_COMPRESS_ROUTER_HOME`解析的[配置目录](#配置文件位置)或平台默认值加载,而不是从自定义`-c`路径旁边加载。要将`.env`与自定义配置一起定位,请将`MCP_COMPRESS_ROUTER_HOME`设置为相同目录。
### 添加下游服务器
使用`add`命令注册下游MCP服务器。
良好的描述有助于LLM将请求路由到正确的服务器。当多个服务器被压缩到路由器后面时,模型会看到每个服务器的名称、其描述和`get_tool_schema`目录中的工具名称列表。清晰的描述(例如*“GitHub API工具,用于问题、PR和仓库”*)比裸名称更能引导模型到达正确的服务器。
**stdio服务器**(本地进程):
```bash
npx mcp-compress-router add github --description "GitHub API工具" \
-- npx -y @modelcontextprotocol/server-github
# 使用环境变量
npx mcp-compress-router add github -e GITHUB_PERSONAL_TOKEN=ghp_xxx \
--description "GitHub API工具" \
-- npx -y @modelcontextprotocol/server-github
```
**HTTP服务器**(远程端点;从URL自动检测传输方式):
```bash
npx mcp-compress-router add my-http https://localhost:3100/mcp
# 使用自定义标头
npx mcp-compress-router add my-http \
--header "Authorization: Bearer mytoken" \
https://localhost:3100/mcp
```
这会生成一个如下所示的配置文件:
```jsonc
{
"mcpServers": {
"github": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": { "GITHUB_PERSONAL_TOKEN": "ghp_xxx" },
"description": "GitHub API工具"
},
"my-http": {
"type": "http",
"url": "https://localhost:3100/mcp",
"headers": { "Authorization": "Bearer mytoken" }
}
}
}
```
支持`.json`和`.jsonc`(带有注释和尾随逗号的JSON);CLI命令写入纯`.json`;手动编辑的文件可以使用`.jsonc`。
其他管理命令:
```bash
npx mcp-compress-router list # 列出所有服务器 + 认证状态
npx mcp-compress-router get my-http # 显示一个服务器的配置
npx mcp-compress-router remove my-http # 删除一个服务器
```
### 每台服务器启用/禁用
每个服务器条目接受一个可选的`enabled`布尔值。当设置为`false`时,路由器在启动时完全跳过该服务器 — 不会启动进程,不会建立网络连接,也不会在`get_tool_schema`目录中显示。所有配置都保留,以便您可以立即将其打开,而无需修改`mcp.json`。
在不触摸其他配置的情况下,从CLI切换它:
```bash
npx mcp-compress-router disable github # 写入"enabled": false
npx mcp-compress-router enable github # 删除该字段
```
您也可以在创建时设置它:
```bash
npx mcp-compress-router add archive --disabled -- npx -y server-archive
```
### 每台服务器工具选择
两个可选字段控制每个服务器的哪些工具被公开给LLM。两个字段都是工具名称的glob模式数组([picomatch](https://github.com/micromatch/picomatch)语法:`*`, `?`, `{a,b}`, `[abc]`):
- **`allowedTools`** — 如果存在,则只会公开匹配的工具。空数组(`[]`)公开*没有*工具(对于构建工具列表很有用)。
- **`disabledTools`** — 从其他工具中删除匹配的工具。拒绝列表生效:一个工具同时匹配两个列表会被阻止。
过滤后的工具在目录中*和* `invoke_tool`中被硬拒绝,因此即使LLM猜测了过滤后的名称,也无法访问下游服务器。
```jsonc
"dangerous": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@some/mcp-server"],
"allowedTools": ["list_issues", "get_pull_request"],
"disabledTools": ["*_delete"]
}
```
在创建时设置筛选器时使用可重复的标志:
```bash
npx mcp-compress-router add github \
--allowed-tools list_issues \
--allowed-tools get_pull_request \
-- npx -y server-github
```
### 检查工具
要查看服务器实际提供的工具 — 以及根据当前选择哪些工具是`[exposed]`或`[filtered]` — 请在不启动完整路由器的情况下连接到它:
```bash
npx mcp-compress-router tools github
```
无论服务器的`enabled`状态如何(检查禁用的服务器是构建其允许列表的主要方法),此操作都有效。对于HTTP服务器,存储的OAuth凭证和`oauth`覆盖都将重用。如果无法访问服务器或缺少必需的身份验证,则命令退出并显示清晰的错误信息,并且不打印部分列表。
### OAuth
支持需要OAuth的HTTP服务器。您添加HTTP服务器时,路由器会探测其OAuth元数据,并在检测到OAuth时自动启动登录流程。您也可以手动触发它:
```bash
npx mcp-compress-router login my-http
```
这会打开您的浏览器以完成授权码流程。令牌存储在与`mcp.json`位于同一目录的单独`credentials.json`文件中(Unix上权限为`0600`),因此您可以安全地共享或版本控制`mcp.json`而不暴露令牌。请将`credentials.json`添加到您的`.gitignore`中。
默认情况下,路由器使用[动态客户端注册](https://datatracker.ietf.org/doc/html/rfc7591)。如果您的服务器需要预注册的客户端,请在服务器条目(在`mcp.json`中)添加`oauth`块:
```jsonc
"my-http": {
"type": "http",
"url": "https://example.com/mcp",
"oauth": {
"clientId": "${MY_CLIENT_ID}",
"clientSecret": "${MY_CLIENT_SECRET}",
"scope": "read write"
}
}
```
只有`clientId`是必需的;`clientSecret`和`scope`是可选的。
#### 重定向URL
在`login`过程中,路由器启动一个临时的本地HTTP服务器,并使用循环回调URI(按照[RFC 8252](https://datatracker.ietf.org/doc/html/rfc8252)):
```text
http://localhost:<port>/mcp-compress-router/oauth-callback
```
`<port>`在登录时由操作系统选择,因此没有固定的端口来注册。当提供者需要预注册的重定向URI时,请注册循环表单**不带端口**:
```text
http://localhost/mcp-compress-router/oauth-callback
```
大多数提供者(包括GitHub)匹配scheme、host和path,并忽略localhost上的端口。如果您的提供者要求重定向URI具有**确切端口**,请使用`--port`固定它:
```bash
npx mcp-compress-router login my-http --port 8765
```
这会将回调服务器绑定到`8765`,因此重定向URI变为`http://localhost:8765/mcp-compress-router/oauth-callback` — 将该确切URL注册到提供者。要在每次`login`时重用相同的端口,请在服务器的`oauth`块中保留它,而不是每次传递标志:
```jsonc
"my-http": {
"type": "http",
"url": "https://example.com/mcp",
"oauth": { "clientId": "${ID}", "callbackPort": 8765 }
}
```
`--port`覆盖`oauth.callbackPort`仅适用于一次运行。传递`--port 0`强制使用操作系统分配的端口,即使设置了`oauth.callbackPort`。
#### GitHub MCP与OAuth(特殊情况)
官方GitHub MCP服务器在`https://api.githubcopilot.com/mcp`处宣传OAuth,但不支持动态客户端注册,因此您必须预注册GitHub OAuth应用程序,并通过`oauth`块传递其凭证。GitHub还要求OAuth应用程序安装到您要访问的仓库和组织中。
1. **创建GitHub OAuth应用程序。**
打开<https://github.com/settings/developers> → *新建OAuth应用程序*(或*注册应用程序*)。给它命名和主页URL。
2. **配置回调URL。**
将*授权回调URL*设置为:`http://localhost/mcp-compress-router/oauth-callback`
3. **添加GitHub MCP服务器按URL。**
```bash
npx mcp-compress-router add github https://api.githubcopilot.com/mcp
```
4. **在`mcp.json`中设置`oauth`凭证。**
复制客户端ID并生成客户端密钥,然后将其放入服务器条目(使用变量扩展以保持机密文件不暴露):
```jsonc
"github": {
"type": "http",
"url": "https://api.githubcopilot.com/mcp",
"oauth": {
"clientId": "${GITHUB_OAUTH_CLIENT_ID}",
"clientSecret": "${GITHUB_OAUTH_CLIENT_SECRET}",
"scope": "repo read:org"
}
}
```
请求仅需要的范围;`repo read:org`涵盖常见的仓库和组织操作。实际值放在您的`.env`文件中(请参见[机密和变量扩展](#机密和变量扩展))。
5. **运行登录命令。**
```bash
npx mcp-compress-router login github
```
您的浏览器会授权。批准后,令牌存储在`credentials.json`中,路由器可以调用GitHub MCP工具。
> **注意:**如果您使用了*GitHub应用程序*(不是经典OAuth应用程序),则必须在您要访问的帐户/仓库之前安装该应用程序,并且其客户端密钥在*常规* → *生成新的客户端密钥*下生成。
#### Figma MCP 特殊情况
`https://mcp.figma.com/mcp` 处的官方 Figma MCP 服务器**不支持**通过标准 MCP 流进行动态客户端注册。
相反,您需要使用个人访问令牌通过 Figma 的 REST API 注册 OAuth 客户端,然后通过 `oauth` 块传递生成的凭证。Figma 还要求重定向 URI 使用**固定端口** - 您注册的端口在每次 `login` 时都会被重用,因此您必须使用 `oauth.callbackPort` 固定它。
1. **创建 Figma 个人访问令牌。**
按照
<https://developers.figma.com/docs/rest-api/personal-access-tokens/>
生成 PAT 并将其导出为 `FIGMA_PERSONAL_ACCESS_TOKEN`。它仅用于在下一步中注册 MCP 客户端。
2. **通过 Figma API 注册 MCP 客户端。**
重定向 URI 必须使用固定端口上的 `127.0.0.1` - **端口很重要**,它在每次 `login` 时都会被重用。此示例使用 `19876`:
```bash
curl -X POST https://api.figma.com/v1/oauth/mcp/register \
-H "Content-Type: application/json" \
-H "X-Figma-Token: $FIGMA_PERSONAL_ACCESS_TOKEN" \
-d '{
"client_name": "Claude Code (figma)",
"redirect_uris": ["http://127.0.0.1:19876/mcp-compress-router/oauth-callback"],
"grant_types": ["authorization_code", "refresh_token"],
"response_types": ["code"],
"token_endpoint_auth_method": "none"
}'
```
保存响应中的 `client_id` 和 `client_secret`(还要注意 `scope` 为 `mcp:connect`):
```json
{
"client_id": "CLIENTID",
"client_secret": "CLIENTSECRET",
"client_name": "Claude Code (figma)",
"redirect_uris": ["http://127.0.0.1:19876/mcp-compress-router/oauth-callback"],
"token_endpoint_auth_method": "none",
"scope": "mcp:connect"
}
```
3. **按 URL 添加 Figma MCP 服务器。**
```bash
npx mcp-compress-router add --transport http figma https://mcp.figma.com/mcp
```
4. **在 `mcp.json` 中设置 `oauth` 凭证。**
将步骤 2 中的客户端 ID 和密码放入服务器条目中,使用 `mcp:connect` 范围和您注册的**相同固定端口**作为 `callbackPort`:
```jsonc
"figma": {
"type": "http",
"url": "https://mcp.figma.com/mcp",
"oauth": {
"clientId": "${FIGMA_CLIENT_ID}",
"clientSecret": "${FIGMA_CLIENT_SECRET}",
"scope": "mcp:connect",
"callbackPort": 19876
}
}
```
将实际值放入您的 `.env` 文件中(参见
[机密和变量扩展](#机密和变量扩展))。
5. **运行登录命令。**
```bash
npx mcp-compress-router login figma
```
您的浏览器将打开授权页面。您批准后,令牌将存储在 `credentials.json` 中,路由器可以调用 Figma MCP 工具。
其他 OAuth 命令:
```bash
npx mcp-compress-router logout my-http # 删除存储的凭证
```
对于无头或 CI 环境,请使用环境变量 `MCP_COMPRESS_ROUTER_BROWSER` 重写浏览器。授权 URL 作为单个最终参数附加(无 shell):
```bash
MCP_COMPRESS_ROUTER_BROWSER="node /path/to/headless-browser.js" \
npx mcp-compress-router login my-http
```
默认登录超时为 120 秒;使用 `MCP_COMPRESS_ROUTER_LOGIN_TIMEOUT_MS` 重写它。
### 自定义头部
对于使用静态 API 密钥或 bearer 令牌而非 OAuth 进行身份验证的 HTTP 服务器,请使用 `headers` 字段。您可以通过 CLI 或直接在 `mcp.json` 中设置它:
```bash
npx mcp-compress-router add my-http \
--header "Authorization: Bearer mytoken" \
--header "X-Custom: value" \
https://example.com/mcp
```
```jsonc
"my-http": {
"type": "http",
"url": "https://example.com/mcp",
"headers": {
"Authorization": "Bearer ${MY_SERVER_TOKEN}",
"X-Custom": "value"
}
}
```
头部值支持
[变量扩展](#机密和变量扩展),因此您可以将实际令牌保留在配置文件之外。
### 机密和变量扩展
服务器条目中的每个字符串字段(`command`、`args`、`env`、`headers`、`url`、`oauth.*`)都会在加载时根据进程环境进行扩展。支持两种语法:
| 语法 | 行为 |
| --- | --- |
| `${VAR}` | 用 `VAR` 的值替换。如果未设置,则抛出异常。 |
| `${VAR:-default}` | 如果 `VAR` 设置且不为空,则用 `VAR` 替换;否则用 `default` 替换。 |
将您的机密放入 `mcp.json` 旁边的 `.env` 文件中:
```bash
# <config directory>/.env
GITHUB_PERSONAL_TOKEN=ghp_abc123
MY_SERVER_TOKEN=secret-token
```
Shell 环境变量始终优先于 `.env` 值。
## 连接编码代理
一旦配置了下游服务器,请将代理连接到路由器,就像连接任何其他 MCP 服务器一样 - 通过指向 `npx mcp-compress-router`。以下示例假设默认的 [配置文件位置](#配置文件位置);如果使用自定义位置,请传递 `-c <path>`。
### Opencode
在 `opencode.json` 的 `mcp` 下添加路由器:
```json
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"mcp-compress-router": {
"type": "local",
"command": ["npx", "-y", "mcp-compress-router"],
"enabled": true
}
}
}
```
### Claude Code
将以下内容添加到工作区根目录的项目级 `.mcp.json` 或用户级配置(适用于所有项目):
- **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
- **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
- **Linux:** `~/.config/Claude/claude_desktop_config.json`
```json
{
"mcpServers": {
"mcp-compress-router": {
"command": "npx",
"args": ["-y", "mcp-compress-router"]
}
}
}
```
### Codex
在 Codex 配置中添加一个 `[mcp_servers.mcp-compress-router]` 表(注意
snake_case 键)。macOS/Linux 上的配置文件路径为 `~/.codex/config.toml`,Windows 上的配置文件路径为 `%USERPROFILE%\.codex\config.toml`;您也可以通过受信任项目中的 `.codex/config.toml` 将其限定为单个项目。
```toml
[mcp_servers.mcp-compress-router]
command = "npx"
args = ["-y", "mcp-compress-router"]
enabled = true
```
### GitHub Copilot
将以下内容添加到工作区中的 `.vscode/mcp.json`(项目级,仅适用于该工作区),或适用于所有工作区的**用户级** MCP 设置:打开命令面板 →
`Preferences: Open User Settings (JSON)` 并在 `mcp` 键下添加相同的 `servers` 块。项目级和用户级条目会合并,项目级优先。
```json
{
"servers": {
"mcp-compress-router": {
"command": "npx",
"args": ["-y", "mcp-compress-router"]
}
}
}
```
## 工作原理
连接后,代理会看到**两个工具**:
- **`get_tool_schema(server, tools)`** - 检索下游 MCP 服务器上一个或多个工具的 JSON 参数模式。工具的描述包括所有服务器及其可用工具名称的紧凑列表。
- **`invoke_tool(server, tool, arguments)`** - 将工具调用转发到下游 MCP 服务器并返回结果。
典型工作流程:
1. 代理从 `get_tool_schema`
描述中读取紧凑的目录,并确定需要哪些工具。
2. 它调用 `get_tool_schema` 以了解确切的参数。
3. 它调用 `invoke_tool` 以执行工具,验证其是否符合缓存的模式。
这将数千个工具列表替换为一个紧凑的 ~900 令牌目录,而不管您有多少个下游服务器。
有关完整的配置和环境变量参考,请参阅
[configuration.md](docs/configuration.md)。
## 致谢
- [mcp2cli](https://github.com/knowsuchagency/mcp2cli) - 一个非常相似的
MCP 可以压缩到 CLI 的想法。
- [mcp-compressor](https://github.com/atlassian-labs/mcp-compressor) -
另一个非常相似的想法;“两个工具”的方法是从
该项目借鉴的,尽管它只压缩单个 MCP 服务器。
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器