内容
# nix-mcp-gateway
[](https://github.com/ismailkattakath/nix-mcp-gateway/actions/workflows/ci.yml)
[](./LICENSE)
[](https://nixos.org)
**单个共享的MCP端点,而不是N个重复的stdio进程。** 一个小型的
home-manager模块,运行一个单一的`mcp-proxy` launchd用户代理,托管
**您自己的**一组 [模型上下文协议](https://modelcontextprotocol.io)
服务器,通过HTTP在环回`主机:端口`上。 将您使用的每个MCP客户端 —
Claude Code、Claude Desktop、VS Code、CLI — 指向生成的端点
代替每个客户端启动自己的stdio副本的相同服务器。
> 状态:早期/测试中。 仅限macOS。 从一个个人nix-darwin
> 群集中提取,其中它托管十几个服务器在单个网关后面。
## 什么是(和不是)
该模块只负责一件事:**运行时网关** — 一个launchd
代理,一个`mcp-proxy`进程,您的服务器在它后面。 它**不**
生成每个服务器的Nix打包,特定提供商的选项模式或
已知服务器的固定存储路径命令 — 这个工作已经很好地
被 [natsukium/mcp-servers-nix](https://github.com/natsukium/mcp-servers-nix) 完成。
使用它(或普通的`npx`/`uvx`启动器,或您自己的脚本)生成一个
`命令`/`参数`,并将其交给此模块的`服务器`选项 — 它不
关心命令来自哪里。
## 先决条件
- **macOS** — 网关作为launchd *用户*(GUI)代理运行,需要
运行`home-manager switch`的帐户是登录到
Mac的帐户。 该模块在Linux上是一个干净的无操作。
- **Nix**,启用了flakes(`experimental-features = nix-command flakes`)。
- **[home-manager](https://github.com/nix-community/home-manager)**。
- `mcp-proxy` ([sparfenyuk/mcp-proxy](https://github.com/sparfenyuk/mcp-proxy))
在nixpkgs中可用为`pkgs.mcp-proxy` — 不需要单独安装。
## 安装
```nix
{
inputs.mcp-gateway.url = "github:ismailkattakath/nix-mcp-gateway";
# 在您的home-manager模块中:
# mcp-gateway.homeManagerModules.default
}
```
然后定义您的服务器:
```nix
{ pkgs, lib, config, ... }:
{
services.mcpGateway = {
enable = true;
extraPath = [ pkgs.nodejs ]; # npx启动的服务器需要Node在PATH上
servers = {
memory = {
command = "npx";
args = [ "-y" "@modelcontextprotocol/server-memory" ];
};
fetch.command = "${pkgs.mcp-server-fetch}/bin/mcp-server-fetch";
};
};
# 将生成的端点连接到您使用的客户端,例如
# home-manager的claude-code模块:
programs.claude-code.mcpServers = lib.mapAttrs (_: url: {
type = "http";
inherit url;
}) config.services.mcpGateway.endpoints;
}
```
参见 [`examples/basic.nix`](./examples/basic.nix) 获取更完整的目录,
包括需要启动时秘密的服务器的模式。
## 选项
| 选项 | 默认值 | 描述 |
|---|---|---|
| `services.mcpGateway.enable` | `false` | 启用网关(仅限macOS;其他平台无操作)。 |
| `services.mcpGateway.host` | `"127.0.0.1"` | 代理绑定的环回地址。 |
| `services.mcpGateway.port` | `8096` | 代理绑定的TCP端口。 |
| `services.mcpGateway.package` | `pkgs.mcp-proxy` | `mcp-proxy`包。 |
| `services.mcpGateway.servers` | `{}` | 您的MCP服务器:每个服务器的`{ command; args; env; }`。 |
| `services.mcpGateway.extraPath` | `[]` | 预添加到代理PATH的包。 |
| `services.mcpGateway.logFile` | `~/Library/Logs/mcp-gateway.log` | stdout+stderr日志路径。 |
| `services.mcpGateway.endpoints` | *(计算)* | 只读`name -> http://host:port/servers/name/mcp`映射。 |
`servers` 默认**为空** — 此模块不包含任何服务器。 您
提供目录;参见上面的示例和 `examples/basic.nix`。
## 秘密
`servers.<name>.env` 值在生成的JSON配置(和
Nix存储)中以明文显示 — 适用于非秘密配置,不适用于
API密钥或连接字符串。 对于需要在启动时使用秘密的服务器,
用脚本包装实际命令,该脚本在运行时(从
macOS密钥链、`pass`、1Password CLI等)获取它,然后指向
`命令`到该包装器。 参见 `example-with-secret` 条目
在 [`examples/basic.nix`](./examples/basic.nix).
## 工作原理
- **传输:** [sparfenyuk/mcp-proxy](https://github.com/sparfenyuk/mcp-proxy)
在一个进程中托管 `services.mcpGateway.servers` 中的每个服务器,
每个服务器在 `/servers/<name>/mcp` (可流式HTTP)中可访问 —
同时也支持SSE的客户端。
- **进程模型:** 一个launchd **用户** 代理(`RunAtLoad` + `KeepAlive`),
绑定到环回 — 没有外部监听。
- **配置:** `servers` 被渲染为 `{mcpServers: {name: {command, args,
env}}}` JSON文件,mcp-proxy通过 `--named-server-config` 消费。
## 何时使用其他方法
| 您想要… | 使用 |
|---|---|
| Nix打包,已知的MCP服务器的固定命令 | [mcp-servers-nix](https://github.com/natsukium/mcp-servers-nix) (与此配合良好 — 将其输出输入到`servers`) |
| 每个客户端启动自己的进程(无共享网关) | 您的MCP客户端的原生stdio配置 |
| 公开/外部暴露,带有身份验证 | 在前面添加您自己的反向代理 + 身份验证 — 此模块仅绑定环回 |
## 生产环境中使用
在 **[kattakath/nix-config](https://github.com/kattakath/nix-config)** 中查看它与实际群集的连接 —
[`modules/shared/mcp.nix`](https://github.com/kattakath/nix-config/blob/main/modules/shared/mcp.nix)
在 `macos` 主机上托管十几个MCP服务器,网关后面。
## 许可证
MIT © Ismail Kattakath