内容
# mcpmux
一个二进制文件(`mux`)可以在纯命令行界面下为任意数量的MCP服务器提供多路复用服务 —— 代理和人类可以直接调用MCP工具**而无需将任何工具模式加载到模型上下文中**。
你会得到:
- **上下文保持极小** —— 在提示中大约有80个令牌索引,而不是每个服务器的完整工具模式(一个GitLab服务器大约有120个工具)。
- **按需模式** —— `mux tools <server>` 列出没有模式的工具;`mux schema <server> <tool>` 在您实际需要时拉取一个。
- **输出准备好管道** —— `--json` 删除多余信息,以便 `| jq` 直接使用,即使在服务器将结果包装在聊天中的情况下; `--compact` 使其最小化。
- **温暖守护进程** —— 连接和OAuth会话在调用之间存活,因此有状态服务器不会在每次调用时重新握手。
- **守护进程中的防护,而不是提示中** —— 按服务器设置的 `allow`/`deny` 模式模型无法绕过。
- **机密存储在配置之外** —— `${VAR}` 引用从一个 0600 存储库中解析;纯文本令牌从不出现在 `servers.jsonc` 中。
- **MCP 和纯命令行界面的单一接口** —— playwright、kubectl、aws 等都出现在同一能力列表中,以相同的方式调用。
- **隔离实例** —— 一个环境变量为代理提供其自己的配置、机密、身份验证和守护进程。
为什么不直接延迟加载模式?延迟加载修复了令牌账单,但创建了一个更糟糕的故障模式:上下文之外 = 心外 = 代理忘记了该能力存在。始终存在的索引在工具不可用的情况下保持可发现,而其模式在调用前保持在上下文之外。
## 快速开始
**1. 安装** —— 下载发布二进制文件,验证其校验和,将 `mux` 放入 `~/.local/bin`:
```sh
curl -fsSL https://raw.githubusercontent.com/TheFox666/mcpmux/main/install.sh | sh
```
确保 `~/.local/bin` 在您的 `PATH` 中(如果不是,安装程序会发出警告)。从源代码检查开始:`bun run build && cp dist/mux ~/.local/bin/`。
**2. 添加机密** —— `${VAR}` 引用从一个 0600 存储库中解析,因此令牌存储在配置文件之外(→ [机密](#机密)):
```sh
echo "$YOUR_GITLAB_PAT" | mux secret set GITLAB_PAT
```
**3. 配置服务器** —— 编辑 `~/.config/mcpmux/servers.jsonc`:
```jsonc
{
"servers": {
// 本地服务器 —— mux 启动此进程并通过 stdio 与其通信
"gitlab": {
"command": "npx",
"args": ["-y", "@yoda.digital/gitlab-mcp-server"],
"env": { "GITLAB_PERSONAL_ACCESS_TOKEN": "${GITLAB_PAT}", "GITLAB_URL": "https://gitlab.com" },
"guard": { "deny": ["delete_*"] },
"note": "GitLab: MRs, pipelines, issues, repos"
},
// 远程服务器 —— mux 通过 HTTP 与托管的 MCP 端点通信(无需安装)
"my-remote": { "url": "https://mcp.example.com/mcp", "headers": { "Authorization": "Bearer ${REMOTE_TOKEN}" } }
}
}
// 每个服务器要么是 `command`+`args`(本地进程),要么是 `url`(远程 HTTP) —— 名称由您选择
```
不喜欢手动编辑?`mux add` 打开一个交互式选择器,而 `mux import` 从现有的 Claude 配置中提取服务器(→ [导入和注册](#导入和注册))。
**4. 使用它** —— 守护进程在第一次调用时自动启动,并在后续调用中保持连接温暖:
```sh
mux call gitlab get_current_user
mux call gitlab list_issues state=opened --timeout 30
mux tools gitlab # 紧凑的工具列表,无模式
mux schema gitlab create_issue
mux status # 解析的套接字/配置/机密路径
```
**5. 将其连接到 Claude** *(可选,仅适用于 Claude Code)* —— SessionStart 钩子注入 `mux index` 提示块,而 PreToolUse 钩子将 `mcp__*` 调用重定向到 mux(→ [Claude 钩子](#claude-钩子)):
```sh
mux hook install claude
```
如果您不使用 Claude,请将 `mux index` 粘贴到您的代理的系统提示中(→ [提示块](#提示块))。
## 守护进程
所有操作都通过后台守护进程运行 —— 它持有实时 MCP 连接和 OAuth 会话,以便它们在调用之间存活(stdio 服务器不会重新启动,远程服务器不会在每次 `mux call` 时重新握手)。它还强制执行防护措施,不受模型控制。
您永远不会手动启动它。第一次 `mux call` 会启动它,它会在后续调用中保持温暖;每个实例([配置文件](#命名实例))都有自己的守护进程。
```sh
mux status # 它是否启动?哪个实例回答了(套接字/配置/机密)
mux logs [server] # 最近的守护进程活动,可选地针对一个服务器
mux daemon --stop # 停止它(下一次调用会重启它)
mux daemon # 在前台运行 — 使用此方法查看启动失败的原因
```
默认情况下,守护进程仅在需要时运行。为了让守护进程在登录时启动并在失败时重启,请安装可选的 systemd 用户单元:
```sh
mux daemon --install # systemd 用户单元,Restart=on-failure
```
## 提示块
`mux index` 打印每行服务器 —— 将其放入您的系统提示中或 CLAUDE.md 中(计划 2 中提供一个自动注入的 SessionStart 钩子):
```
MCP 工具可通过 `mux` CLI 访问(详细信息:mux tools <server>;调用:mux call <server> <tool> key=value):
gitlab — GitLab: MRs, pipelines, issues, repos
```
## 输出合同(代理是主要读取者)
- 文本内容 → 标准输出。 二进制内容(截图,文件)→ 写入 `$TMPDIR/mcpmux/`,标准输出打印路径。
- 错误 → 标准错误,退出 1,每个错误都命名下一个操作(`unknown tool "x" — see: mux tools gitlab`)。
- `key=value` 表示扁平参数, `--args '<json>'` 表示嵌套参数, `--raw` 表示完整的结果信封。
## 防护
按服务器允许/拒绝模式,在守护进程中强制执行 —— 不在提示中:
```jsonc
"guard": { "allow": ["list_*", "get_*"] } // 只读服务器,无论模型如何
```
## 环境
| 变量 | 影响 |
|---|---|
| `MCPMUX_PROFILE` | 命名实例 → `~/.config/mcpmux-<profile>/` + 其自己的套接字(见下文) |
| `MCPMUX_CONFIG` | 配置路径(默认 `~/.config/mcpmux[-<profile>]/servers.jsonc`) |
| `MCPMUX_SECRETS` | 机密存储(默认 `~/.config/mcpmux[-<profile>]/secrets.json`) |
| `MCPMUX_SOCKET` | 守护进程套接字(默认 `$XDG_RUNTIME_DIR/mcpmux[-<profile>].sock`) |
`mux status` 打印已解析的套接字/配置/机密路径,因此始终清楚哪个实例回答了。
## 命名实例
运行多个完全隔离的 mux —— 每个实例都有自己的配置、机密、身份验证和守护进程,仅需一个环境变量,与 Claude 的 `~/.claude` 与 `~/.claude-<profile>` 类似:
```sh
mux servers # 默认实例 → ~/.config/mcpmux/
MCPMUX_PROFILE=office mux servers # 单独实例 → ~/.config/mcpmux-office/
```
每个配置文件都有自己的守护进程(`…/mcpmux-<profile>.sock`)、自己的凭证和自己的服务器集 —— 因此一个代理/帐户无法看到或使用另一个代理/帐户的服务器。显式的 `MCPMUX_CONFIG`/`MCPMUX_SECRETS`/`MCPMUX_SOCKET` 重写仍然有效。
## CLI 工具(不仅仅是 MCP)
`tools` 部分与 `servers` 并列,因此普通 CLI 工具(playwright、kubectl、aws)变得可发现并可以通过 **相同** 的入口点调用 —— 代理看到一个能力列表,没有 MCP 与 CLI 的区别:
```jsonc
"tools": {
"playwright": {
"run": "npx", "args": ["playwright"],
"env": { "NODE_PATH": "${PLAYWRIGHT_NODE_PATH}" }, // 中央应用的特殊设置
"check": "node -e \"require('playwright')\"",
"setup": "npm i -g playwright && playwright install chromium",
"note": "UI 烟雾测试的无头浏览器"
}
}
```
```sh
mux run playwright test.js # 使用工具的环境/包装执行,stdio 和退出代码直通
mux tool status # 已安装 / 缺失每个工具(+ 更新提示,用于固定的 npm 工具)
mux tool setup playwright # 运行其安装程序
mux tool update [name] # 将 npm 支持的工具更新到最新发布的版本
mux add kubectl --tool --check "kubectl version --client" -- kubectl
```
`mux run` 应用存储的环境/包装,因此具有特殊设置的工具在任何地方都相同工作 —— 没有环境锁定。对于 npm 支持的工具(`bunx pkg@version`),`mux tool status` 显示 `↑ update X → Y` 当有新版本时,`mux tool update` 增加固定版本号;未固定的(`@latest`)跟踪最新版本。
## 机密
配置文件中的 `${VAR}` 解析时,首先检查 `process.env`,然后检查 0600 机密存储 —— 因此正常情况下不需要 shell 导出:
```sh
echo "$TOKEN" | mux secret set GITLAB_PAT # 或隐藏的 TTY 提示
mux secret list # 仅名称,从不值
```
`mux add --env` 和 `mux import` 自动将字面机密值移动到存储中,并在配置文件中留下 `${ref}` —— 明文令牌从不出现在 `servers.jsonc` 中。
## OAuth 服务器
```sh
mux auth linear # 一次浏览器同意;存储 0600,守护进程自动刷新
```
在 http 服务器上设置 `"auth": "oauth"`;然后守护进程自动使用和刷新存储的令牌。死亡会话以 `run: mux auth <server>` 失败。
## Claude 钩子
```sh
mux hook install claude # SessionStart 注入 `mux index`;PreToolUse 重定向 mcp__* 调用
```
## 导入和注册
```sh
mux add # 交互式 TUI 选择器(箭头键,/ 搜索注册表, ⏎ 切换)
mux import # 跨所有 Claude 配置列出 MCP 服务器(~/.claude*,.mcp.json)
mux import linear # 复制一个到 mux 中(外部化机密)
mux search gitlab # 公共 MCP 注册表
mux add com.gitlab/mcp --as gitlab # 通过注册表引用安装(版本固定)
mux doctor # 重叠报告:直接附加和由 mux 提供服务的服务器
```
裸 `mux add` 在终端上打开一个原始模式选择器 —— ↑↓/jk 移动, `/` 搜索注册表, ⏎ 安装一个点击或删除一个已安装的服务器, `q` 退出。非交互式(管道/代理)使用传递显式参数。
## 尚未构建
npm (`npx mcpmux`) 和 Homebrew 分发渠道 —— `install.sh`(GitHub 版本二进制文件 + 校验和)是受支持的安装方式,直到那时;`bun run build` 从源代码构建。
MIT.