使用说明
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
测试
- 启动示例后端MCP服务器:
uv run python run_example_mcp_servers.py
- 启动网关:
uv run python mcp_x.py
- 通过以下方式进行验证:
- Swagger用户界面 --打开
http://localhost:9000/docs检查并尝试REST端点 - MCP检查员 --
npx @modelcontextprotocol/inspector然后连接到http://localhost:9000/mcp带有来自的Bearer代币config.toml(例如。123爱丽丝)
- Swagger用户界面 --打开
配置
复制 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_bazvs服务器foo_bar使用工具baz). -
工具名称重写 --中间件在将工具返回给客户端之前会删除内部服务器哈希前缀,这样客户端就可以看到干净的工具名称。开
call_tool,中间件会重新添加正确的前缀,并尝试每个允许的服务器,直到成功为止。 -
JWT --
POST /register_client发出JWT(1小时到期)。签名密钥是自动生成的,并保存到jwt_secret第一次跑步。
