多客户端MCP网关

MCP-X是一个单文件多客户端MCP网关,具有按工具访问控制功能,适用于需要安全共享和访问MCP工具的场景。

  • by camelop
  • Python
  • 本地部署
  • 2 星标
  • 更新于
在 GitHub 查看 camelop/mcp-x

使用说明

MCP-X

MCP-X是一种 单文件 多客户端 MCP网关,具有每个工具的访问控制。整个实施过程都在 mcp_x.py.

每个客户端都使用承载令牌进行身份验证,并可以携带自己的MCP服务器列表,然后与其他客户端共享这些服务器中的特定工具。客户通过以下方式与MCP交谈 /mcp;中间件根据每个客户端可以查看/调用的工具进行过滤 config.toml 政策。服务器所有者始终可以完全访问自己的工具。

                        MCP-X (:9000)
                     ┌─────────────────┐
 ┌───────┐  auth     │  FastAPI REST   │
 │ alice ├──token──> │  /register_*    │
 └───┬───┘           │  /update_*      │
     │               │  /get_*         │
     │  MCP          ├─────────────────┤          ┌──────────┐
     └──protocol──>  │   FastMCP       │──proxy──>│ server_a │ <── owned by alice
                     │   /mcp          │          └──────────┘
 ┌───────┐  MCP      │  ┌────────────┐ │          ┌──────────┐
 │  bob  ├────────>  │  │ middleware │ │──proxy──>│ server_b │ <── owned by bob
 └───────┘           │  │ filter by  │ │          └──────────┘
                     │  │ allow list │ │
                     │  └────────────┘ │
                     └─────────────────┘

给定 server_a 有工具 [a-tool-qwe, a-tool-zxc] 和 server_b 有 [b-tool-asd, b-tool-jkl],使用下面的示例配置,每个客户端都会看到:

 alice (owns server_a)
   server_a: a-tool-qwe, a-tool-zxc        (owner -- full access)
   server_b: b-tool-asd                    (allowed: ["b-*a*"])
   ─────────────────────────────────────
   tools:    a-tool-qwe, a-tool-zxc, b-tool-asd

 bob (owns server_b)
   server_b: b-tool-asd, b-tool-jkl        (owner -- full access)
   server_a: a-tool-qwe, a-tool-zxc        (allowed: ["*"])
   ─────────────────────────────────────
   tools:    b-tool-asd, b-tool-jkl, a-tool-qwe, a-tool-zxc

快速开始

uv sync
# start the gateway (default port 9000)
uv run python mcp_x.py
# or with a custom port
uv run python mcp_x.py --port 8080

测试

  1. 启动示例后端MCP服务器:
uv run python run_example_mcp_servers.py
  1. 启动网关:
uv run python mcp_x.py
  1. 通过以下方式进行验证:
    • Swagger用户界面 --打开 http://localhost:9000/docs 检查并尝试REST端点
    • MCP检查员 -- npx @modelcontextprotocol/inspector 然后连接到 http://localhost:9000/mcp 带有来自的Bearer代币 config.toml (例如。 123 爱丽丝)

配置

复制 config.example.toml 到 config.toml 并对其进行编辑。该文件有三个部分:

# 1. Clients: name -> static auth token
[clients.alice]
auth_token = "123"

[clients.bob]
auth_token = "456"

# 2. MCP servers: name -> upstream URL + which client registered it
[mcp_servers.server_a]
url = "http://localhost:9001"
from_client = "alice"          # alice owns server_a

[mcp_servers.server_b]
url = "http://localhost:9002"
from_client = "bob"

# 3. Access control: server_name -> { client -> [tool_patterns] }
#    Patterns use fnmatch syntax: * ? [seq] [!seq]
[allow.server_a]
bob = ["*"]                            # bob can use all tools on server_a
charlie = ["tool_0", "tool_1*", "*_2"] # charlie gets specific tools

[allow.server_b]
alice = ["b-*a*"]                      # alice gets matching tools on server_b

服务器所有者( from_client 字段)始终可以完全访问自己的服务器工具——否 [allow] 需要进入。

关于重复工具名称的注意事项: 如果客户端可以访问多个公开同名工具的服务器,则只会使用一个(来自首先匹配的服务器)。在共享服务器之前,始终会检查自有服务器中的工具。

实时重新加载

config.toml 在每次请求时检查是否有更改(限制为每秒一次)。在服务器运行时编辑它,更改会立即生效,无需重新启动。

当客户端通过REST API注册时,服务器也会写入该文件(POST /register_client, /register_mcp_server, /update_access_control).在这些写入过程中,文件中手动配置的客户端令牌会被保留。

REST API

所有端点(除 /register_client)要求a Bearer 令牌在 Authorization 头球

方法 端点 描述
POST /register_client 创建新客户端。返回a client_id 以及JWT auth_token (1小时到期)。
POST /register_mcp_server 注册上游MCP服务器URL。调用客户端成为所有者。
POST /update_access_control 授予或撤销其他客户端对您服务器上工具的访问权限。接受 client_id 和 server_access: {server_name: [tool_patterns]}.
GET /get_access_control 查看您拥有的所有服务器的当前访问策略。

MCP端点位于 /mcp (无状态HTTP)。客户端使用标准MCP协议来列出和调用工具。

运作原理

  • 服务器名称哈希 --服务器名称在内部存储为SHA-256哈希值。这避免了FastMCP用下划线连接服务器和工具名称时发生冲突(例如,名为 foo 使用工具 bar_baz vs服务器 foo_bar 使用工具 baz).

  • 工具名称重写 --中间件在将工具返回给客户端之前会删除内部服务器哈希前缀,这样客户端就可以看到干净的工具名称。开 call_tool,中间件会重新添加正确的前缀,并尝试每个允许的服务器,直到成功为止。

  • JWT -- POST /register_client 发出JWT(1小时到期)。签名密钥是自动生成的,并保存到 jwt_secret 第一次跑步。