关于 OpenZiti MCP Gateway
OpenZiti MCP Gateway 是 NetFoundry 提供的 MCP 网关,借助 OpenZiti 覆盖网络让 AI 助手安全访问内部工具,无需暴露公共端点。它面向需要跨分布式系统或团队共享 MCP 工具的用户,并支持聚合与过滤多个后端。
主要功能
- 01基于 OpenZiti 的零信任访问
- 02无需公网 IP 或端口转发
- 03将多个后端聚合为单一端点
- 04按后端过滤可用工具
- 05支持 stdio 与 HTTP 传输
适用场景
- 01让 AI 助手安全访问内网中的工具
- 02将远程机器上的 MCP 服务共享给团队
- 03在单一连接中组合文件系统、GitHub 和数据库工具
MCP 相关
该项目是 MCP 网关,mcp-tools 作为客户端连接远程 zrok 共享或 Agora 隧道,mcp-gateway 将多个 MCP 服务聚合为一个端点,mcp-bridge 将单个 MCP 服务暴露到网络中。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
MCP Gateway
通过 OpenZiti 零信任地访问 MCP 工具
MCP Gateway 让 AI 助手能够安全地访问内部工具,而无需暴露公共端点。它基于 OpenZiti、zrok 和 Agora 构建,可提供采用密码学保障的零信任连接,且不留攻击面。
MCP Gateway 由 NetFoundry 赞助,是其安全工作负载和智能 Agent 计算解决方案组合的一部分。NetFoundry 是 OpenZiti 和 zrok 的创建者。
三位一体
三个简单的组件协同工作:
| 组件 | 用途 |
|---|---|
| mcp-tools | 将 MCP 客户端连接到远程 zrok 共享或 Agora 隧道(stdio 或 HTTP) |
| mcp-gateway | 通过 zrok 和/或 Agora 将多个后端聚合到一个安全端点 |
| mcp-bridge | 通过 zrok 或 Agora 将单个 MCP 服务暴露到网络 |
flowchart LR
A[Agent] -->|stdio| B[mcp-tools]
B -->|zrok or Agora| C[mcp-gateway]
C -->|stdio / zrok / Agora / HTTP| D[MCP Servers]
C -->|https| E[Remote MCP APIs]
为什么?
问题: MCP 服务通常通过 stdio 在本地运行。若要访问远程计算机上的工具,或在团队中共享工具,就需要暴露端点,从而带来安全风险。保护已暴露的 MCP 工具可能很复杂。
解决方案: MCP Gateway 使用 OpenZiti 的覆盖网络创建“暗服务”,这些服务:
- 绝不会在公共 IP 上侦听
- 需要通过密码学身份验证才能访问
- 无需端口转发,即可穿过 NAT 和防火墙
- 可通过 Agora 目录和 Layer 1 隧道发布和提供服务
- 部署起来极其简单,同时确保安全
快速入门
初次使用 MCP Gateway? 请参阅入门指南,了解完整的操作步骤。
1. 安装
go install github.com/openziti/mcp-gateway/cmd/...@latest
2. 启用 zrok
注意: mcp-gateway 需要 zrok
v2.0.x或更高版本。目前最佳版本是 zrok v2.0.0-rc7
zrok2 enable <your-zrok-token> # get token at https://api-v2.zrok.io
3. 运行 Gateway
创建 config.yml:
aggregator:
name: "my-gateway"
version: "1.0.0"
backends:
- id: filesystem
transport:
type: stdio
command: npx
args: ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/documents"]
- id: github
transport:
type: stdio
command: npx
args: ["-y", "@modelcontextprotocol/server-github"]
env:
GITHUB_TOKEN: "ghp_xxx"
mcp-gateway run config.yml
# outputs: {"share_token":"abc123..."}
4. 从 Agent 连接
添加到 Agent 配置中:
{
"mcpServers": {
"my-tools": {
"command": "mcp-tools",
"args": ["run", "abc123..."]
}
}
}
就这么简单。现在,你的 Agent 可以通过单个安全连接使用两个后端中的工具。
使用场景
聚合多个工具服务
将文件系统、GitHub、数据库和自定义工具合并为一个连接:
backends:
- id: fs
transport: { type: stdio, command: mcp-server-filesystem, args: ["/data"] }
- id: github
transport: { type: stdio, command: mcp-server-github }
- id: postgres
transport: { type: stdio, command: mcp-server-postgres }
工具会自动添加命名空间:fs:read_file、github:create_issue、postgres:query。
暴露远程工具服务
在远程计算机上运行 mcp-bridge,以暴露本地 MCP 服务:
# on remote server
mcp-bridge mcp-server-custom --config /etc/custom.yml
# outputs share token
# from anywhere
mcp-tools run <share_token>
串联 Bridge 和 Gateway
Gateway 可以将远程 Bridge(或其他 Gateway)作为后端连接:
backends:
- id: remote-tools
transport:
type: zrok
share_token: "token-from-bridge"
通过 Agora 提供和发现服务
Gateway、Bridge 和工具除了使用 zrok,也可以使用 Agora Layer 1 隧道。Gateway 可以同时通过 zrok 和 Agora 提供服务、发布目录公告,并连接到由 mcp-bridge --network=agora 暴露的后端。
agora:
enabled: true
serve:
enabled: true
advertisement:
publish: true
backends:
- id: remote-filesystem
transport:
type: agora
agora_tunnel: filesystem-relay
mcp-tools run --agora mcp-gateway-engineering
有关配置、CLI 标志、集成文件和冒烟测试场景,请参阅 Agora 集成。
连接到 HTTP 和 HTTPS MCP 服务
Gateway 可以通过 HTTP(S) 聚合远程 MCP 服务,使用 Streamable HTTP(默认)或旧版 SSE 传输方式。对于 SSE 端点,请明确设置 protocol: sse。type: https 为严格模式,只接受 https:// 端点。type: http 同时支持 http:// 和 https://,但使用明文 HTTP 需要明确选择启用。
backends:
- id: remote-api
transport:
type: https
endpoint: "https://mcp.example.com/mcp"
headers:
Authorization: "Bearer sk-abc123"
- id: legacy-api
transport:
type: https
endpoint: "https://mcp.internal.corp/sse"
protocol: "sse"
tls:
ca_cert_file: "/etc/ssl/certs/internal-ca.pem"
这与 stdio 和 zrok 后端兼容,可按需混合使用。
对于本地开发或可信的内部网络,你可以明确选择启用明文 HTTP:
backends:
- id: local-dev
transport:
type: http
endpoint: "http://localhost:8080/mcp"
allow_insecure: true
HTTP 后端客户端会直接连接,并默认拒绝重定向。只有在明确需要更广泛的网络行为时,才在传输层设置 allow_environment_proxy: true 或 allow_redirects: true。
持久共享
默认情况下,mcp-gateway 和 mcp-bridge 会创建临时共享,并在进程退出时消失。持久共享存储在 zrok 服务端,因此网关或桥接器可以停止并重启,而无需更改共享令牌。
临时共享默认处于关闭状态,且仅所有者可访问。桥接器可以通过可重复使用的标志向其他 zrok 账户授予访问权限:
mcp-bridge --access-grant [email protected] mcp-filesystem /data
对于 mcp-gateway,请在网关配置的 zrok.share.access_grants 下添加相同的账户邮箱。创建共享的账户无需列出,因为它已经拥有访问权限。
# create a persistent share with a chosen name
zrok2 create share -s my-gateway
# the chosen name is the share token
# use the token in a gateway config (share_token: my-gateway) or bridge
mcp-gateway run config.yml
mcp-bridge --share-token my-gateway npx -y @modelcontextprotocol/server-filesystem /home/user
# the gateway/bridge can restart and reconnect to the same share
# when done, delete the share
zrok2 delete share my-gateway
如果省略名称,zrok 会生成随机令牌:
zrok2 create share
# outputs the share token
令牌名称必须为 3–32 个字符,且只能包含小写字母、数字和连字符([a-z0-9-])。
HTTP 传输
除了 stdio 外,所有组件也支持基于 HTTP 的 MCP 传输。
通过 mcp-tools 使用 HTTP 提供服务:
# expose a zrok share as a local HTTP server
mcp-tools http <share_token> --bind 127.0.0.1:8080
# expose an Agora tunnel as a local HTTP server
mcp-tools http --agora <tunnel> --bind 127.0.0.1:8080
选项:
--stateless- 无状态模式(不保留会话)--json-response- 优先使用 JSON 响应,而非流式响应--session-idle-timeout <duration>- 超过此时长后关闭不活动的本地会话;默认值为30m,0表示禁用
网关和桥接器通过 zrok 和 Agora 原生提供基于 Streamable HTTP 的 MCP 服务。当你需要本地 Streamable HTTP 端点,以供不支持 mcp-tools 直接提供的 stdio 传输的客户端使用时,请使用 mcp-tools http。
mcp-tools http 可为任意数量的本地 Agent 提供服务,每个 Agent 在远程网关或桥接器上都有自己的 MCP 会话。zrok 访问连接或 Agora 附加连接只会打开一次,并在整个进程运行期间保持打开;本地 Agent 连接时会打开新的 fabric 会话,并在其断开连接、会话过期、初始化失败或 mcp-tools 关闭时将其关闭。后端状态按 Agent 隔离,与直接连接到网关的 Agent 完全相同。在 --stateless 模式下没有需要持有的会话,因此每个请求都会打开并关闭一个 fabric 会话——这虽然正确,但意味着每次调用都要通过覆盖网络完成完整的 MCP 握手。
关闭时,mcp-tools 最多等待 5 秒,让仍在进行中的握手完成,以便释放在关闭期间完成的会话,而不是让其滞留。fabric HTTP 客户端不设置超时,因此等待时间有上限,不会无限延长;但这个上限也带来了一项可接受的代价:远程会话会在其 initialize 请求到达网关或桥接器时创建,因此,如果等待时间到期时握手响应仍在传输中,就会留下真实的远程会话(并占用真实的后端资源),而 mcp-tools 已无法将其终止。它会记录放弃的会话数量,另一端会通过自身的空闲过期机制回收这些会话。另一种做法是无限期等待,但这样一来,卡住的覆盖网络可能会让关闭过程永远无法结束。
不活动的 Streamable HTTP 会话会在 30 分钟后过期,避免客户端消失后未终止会话,导致专用后端连接或桥接器子进程无限期占用资源。你可以在网关 YAML 中设置 session_idle_timeout,或向 mcp-bridge 或 mcp-tools http 传递 --session-idle-timeout <duration>,以调整此时长。显式设置为 0 会禁用空闲过期;这些资源可能会一直保留,直到客户端终止会话或服务器关闭。
工具筛选
控制每个后端公开哪些工具:
backends:
- id: filesystem
transport: { type: stdio, command: mcp-server-filesystem }
tools:
mode: allow
list:
- "read_file"
- "list_directory"
# write operations not exposed
- id: github
tools:
mode: deny
list:
- "delete_*"
# everything except delete operations
架构
MCP Gateway 会为每个连接的客户端创建隔离会话:
flowchart LR
subgraph Clients
A[Client A]
B[Client B]
end
A --> G[Gateway]
B --> G
subgraph Session A
G --> A1[Backend 1]
G --> A2[Backend 2]
end
subgraph Session B
G --> B1[Backend 1]
G --> B2[Backend 2]
end
每个客户端都有专用的后端连接,不共享状态,也不会相互干扰。
从源代码构建
git clone https://github.com/openziti/mcp-gateway.git
cd mcp-gateway
go build ./cmd/mcp-gateway
go build ./cmd/mcp-bridge
go build ./cmd/mcp-tools
每个二进制文件都有一个 version 子命令,可输出构建元数据:
mcp-gateway version
本地构建会报告开发者构建版本(例如 v0.1.x [developer build]);发布版二进制文件会附带版本、提交、构建日期、分支和构建者信息。
文档
- 配置示例 - 完整的配置文件文档
- Agora 集成 - Agora 服务、后端连接、mcp-tools 拨号和冒烟测试场景
- 端到端冒烟测试套件 -
make e2e,涵盖所有三个组件的手动运行检查 - OpenZiti 文档
- zrok 文档
- MCP 规范
许可证
Apache 2.0 - 请参阅 LICENSE
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。