mcp-gateway
MCP Gateway
一个轻量级、自托管的 MCP 聚合网关:一个公共 MCP 端点,位于任意数量的受保护后端 MCP 服务器之前,并带有一个符合规范的 OAuth 2.1 授权服务器,面向 MCP 客户端——这是大多数现有网关所缺失的部分。
Claude Code / Claude.ai ──OAuth 2.1 (DCR/CIMD + PKCE)──▶ MCP Gateway ──own credentials──▶ GitHub MCP
│ ▶ Microsoft Learn MCP
└── /mcp (Streamable HTTP) ▶ …more backends使用 FastAPI + FastMCP 构建,通过单个 YAML 文件配置,状态存储在一个加密的 SQLite 数据库中,并以一个小型独立容器形式交付——无需反向代理,虽然你也可以在它前面放一个用于 TLS。
功能
面向客户端(MCP 授权规范,2025-11-25):
OAuth 2.1 授权码流程,强制要求 PKCE (S256)
在
/register提供动态客户端注册(RFC 7591)——claude mcp add无需预先共享凭据即可工作客户端 ID 元数据文档(CIMD)——使用 HTTPS URL 作为客户端 ID,包括
private_key_jwt客户端认证,并通过client_id_metadata_document_supported: true公布授权服务器元数据(RFC 8414)+ OIDC 发现别名
受保护资源元数据(RFC 9728);401 响应携带
WWW-Authenticate: Bearer resource_metadata="…",正如 Claude 的连接器所要求接受资源指示器(RFC 8707)并将其绑定到已颁发的令牌
短期不透明访问令牌、轮换刷新令牌、一次性授权码——全部以哈希形式存储;客户端记录在静态加密
环回重定向 URI 按端口无关方式匹配(Claude Code CLI 注册一个端口,授权时却使用另一个端口);非环回 URI 需要精确匹配注册
小巧的 Svelte 5 登录 + 同意界面(使用配置文件中的单个本地身份)
面向后端:
none——公共服务器(例如 Microsoft Learn MCP)bearer——静态令牌注入(Authorization: Bearer …,例如 PAT)headers——任意静态标头(API 密钥)oauth——符合 MCP 规范的完整 OAuth 客户端:元数据发现、当上游 AS 支持 CIMD 时使用 CIMD(网关托管自己的客户端元数据文档)、DCR 回退、PKCE、自动令牌刷新。通过浏览器连接一次;令牌以加密(Fernet)方式保存在 SQLite 中。客户端的网关令牌永远不会被转发到上游(不进行令牌透传,符合规范要求);后端永远只会看到网关持有的凭据。
聚合:
每个后端的工具/资源/提示按后端命名空间隔离:
github_create_issue、msdocs_microsoft_docs_search、……通过 Streamable HTTP 进行实时代理;一个宕机或尚未连接的后端只会移除它自己的工具,而不会导致整个网关中断
内置
gateway_status工具
Related MCP server: MCP OAuth Test
快速开始
cp config.example.yaml config.yaml
$EDITOR config.yaml # set public_url, users, backends
cp .env.example .env
$EDITOR .env # set MCP_GATEWAY_ENCRYPTION_KEY (openssl rand -base64 32)
docker compose up -d网关 standalone 运行并监听 :8000;docker compose 会自动从 .env 获取 MCP_GATEWAY_ENCRYPTION_KEY。你可以把它放在你选择的反向代理后面以启用 TLS,或直接暴露端口。
为配置文件生成密码哈希:
docker compose run --rm mcp-gateway mcp-gateway hash-password连接 Claude Code(CLI)
claude mcp add --transport http gateway https://mcp.example.com/mcpClaude Code 会先发现网关的授权服务器,通过 DCR(或使用其 CIMD 客户端 ID)注册自己,然后打开你的浏览器:使用 config.yaml 中的用户登录代码,点击同意,完成。不需要粘贴任何令牌。
连接 Claude.ai / Claude Code web(自定义连接器)
将 https://mcp.example.com/mcp 添加为自定义连接器。浏览器重定向到 https://claude.ai/api/mcp/auth_callback,并经历同一套登录/同意流程。
连接 OAuth 后端
打开 https://mcp.example.com/ui/backends,登录,然后点击每个 OAuth 后端旁边的连接(例如 GitHub MCP)。你会被重定向到该后端的授权服务器一次;之后网关会自动刷新令牌。
配置
所有内容都位于一个 YAML 文件中(参见 config.example.yaml)。值支持 ${ENV_VAR} / ${ENV_VAR:-default} 展开。
server:
public_url: https://mcp.example.com # behind your reverse proxy
auth:
encryption_key: ${MCP_GATEWAY_ENCRYPTION_KEY} # encrypts secrets at rest
users:
- username: admin
password_hash: "$2b$12$…" # mcp-gateway hash-password
access_token_expiry_seconds: 3600
refresh_token_expiry_seconds: 2592000
storage:
path: /data/gateway.db # SQLite; the only state
backends:
github: # → tools namespaced github_*
url: https://api.githubcopilot.com/mcp/
auth:
type: oauth
# GitHub's authorization server supports neither CIMD nor DCR, so
# register a GitHub OAuth App and provide its credentials directly:
client_id: ${GITHUB_OAUTH_CLIENT_ID}
client_secret: ${GITHUB_OAUTH_CLIENT_SECRET}
microsoft-docs: # → tools namespaced microsoft-docs_*
url: https://learn.microsoft.com/api/mcp
auth: { type: none }
something-with-a-pat:
url: https://example.com/mcp
auth: { type: bearer, token: "${SOME_PAT}" }添加后端只需改配置——无需修改代码。
后端认证参考
type | fields | behaviour |
| – | 不发送任何凭据 |
|
| 每次请求加 |
|
| 静态标头(API 密钥等) |
|
| 完整 OAuth 客户端:CIMD → DCR 回退、PKCE、刷新、加密存储 |
对于 oauth 后端,网关会在 <public_url>/oauth/client-metadata.json 托管自己的客户端 ID 元数据文档,并在上游 AS 公布支持 CIMD 时将其用作 client ID(这要求使用 HTTPS public_url);否则会回退到动态客户端注册。如果上游 AS 什么都不支持(例如 GitHub),请设置 client_id(如果应用是机密应用,还需要 client_secret)来使用预先注册的 OAuth 客户端——CIMD/DCR 将被完全跳过。
日志
网关将日志输出到 stdout/stderr(docker logs、docker compose logs -f),默认级别为 INFO:启动/关闭、配置摘要、登录尝试、OAuth 授权/确认/令牌签发、上游后端连接/断开以及后端挂载状态。级别为 DEBUG 时输出更详细的信息(客户端构建、令牌轮换、CIMD 刷新、存储清理)。任何级别下都不会记录任何凭据或令牌。
通过 MCP_GATEWAY_LOG_LEVEL 环境变量设置日志级别(debug、info、warning、error 或 critical):
# .env (picked up by docker compose)
MCP_GATEWAY_LOG_LEVEL=debug# or inline
docker compose run --rm -e MCP_GATEWAY_LOG_LEVEL=debug mcp-gatewaydocker-compose.yml 已经将该变量转发到容器,未设置时默认为 info。
在 Docker 之外,mcp-gateway run 上的 --log-level 具有相同的效果,并且会覆盖环境变量:
mcp-gateway run -c config.yaml --log-level debug端点
路径 | 用途 |
| MCP 端点(Streamable HTTP) |
| RFC 9728 受保护资源元数据 |
| RFC 8414 AS 元数据(及 OIDC 别名) |
| OAuth 2.1 端点(PKCE、DCR、撤销) |
| 登录 + 确认(Svelte 5) |
| 后端连接状态 / 显示 / 断开 |
| 网关自身的 CIMD 文档(上游一端) |
| 上游 OAuth 连接流程 |
| 存活探测 |
安全注意事项
PKCE (S256) 是强制要求的;授权码一次性使用,5 分钟过期。
刷新令牌每次使用都会轮换(OAuth 2.1 公共客户端要求)。
访问令牌、刷新令牌和授权码仅限于 SHA-256 哈希形式存储。
已注册的客户端记录和上游凭据在静态时使用 Fernet 加密(
auth.encryption_key;密码短语通过 scrypt + 每个数据库的盐进行拉伸)。同意页面会显示客户端名称和确切的 redirect 目标,并在环回重定向时发出警告(这是规范中针对 localhost 冒充的指引)。
签发给 MCP 客户端的令牌永远不会被转发到后端;后端的凭据也永远不会到达 MCP 客户端。
会话是用
itsdangerous签名的,并设置为HttpOnly、SameSite=Lax;在 HTTPS 下还会添加Secure。任何级别都不会记录凭据。
开发
uv venv && uv pip install -e ".[dev]" # or: pip install -e ".[dev]"
(cd ui && npm install && npm run build) # build the Svelte UI
pytest # 35 tests incl. full e2e OAuth flows
mcp-gateway run -c config.yaml测试套件会启动真实的网关(以及一个作为受 OAuth 保护的上游的第二个实例),并通过 HTTP 驱动完整的 DCR/CIMD + PKCE 流程。
架构
src/mcp_gateway/oauth_server.py—— 面向客户端的 OAuth AS。构建在 MCP SDK 的授权服务器处理程序和 FastMCP 的 CIMD 管理器之上,而不是自己冷启动实现协议;网关负责 SQLite 持久化、登录/同意/流程流程以及令牌签发/轮换策略。src/mcp_gateway/upstream.py—— 后端客户端。OAuth 后端使用官方 SDK 的OAuthClientProvider(发现、CIMD/DCR、刷新),配合加密的 SQLite 令牌存储和浏览器驱动的连接流程。src/mcp_gateway/gateway.py—— FastMCP 服务器;每个后端都作为一个活跃的代理挂载到其命名空间下。src/mcp_gateway/app.py/web.py—— FastAPI 应用:面向 UI 的 JSON API、上游回调、CIMD 文档、静态 Svelte 应用;FastMCP 应用(MCP 端点 + OAuth 路由 + well-known)挂载在根部。ui/—— Svelte 5 + Vite 单页应用(登录、同意、后端)。
设计上就是单实例(SQLite + 内存中的连接流程)。它独立运行;如果你想做 TLS 终止,就把它放在你自己的反向代理后面,并备份一个文件。
This server cannot be deployed
Maintenance
Related MCP Connectors
Governed MCP gateway: one endpoint for your tools, with credential custody and audit log.
One MCP endpoint for your company's tools, with per-person sign-in, policy and audit.
Self-hosted federated MCP gateway: one OAuth 2.1 MCP server in front of N apps, user-level scopes.
MCP server for mandates, delegation, policy-gated execution, credential grants, and audit.
Related MCP Servers
- FlicenseNot gradedqualityNot gradedmaintenanceAggregates multiple MCP servers behind a single, secure endpoint with unified tool/resource discovery, OAuth authentication, and resilient request routing. Enables users to manage and interact with multiple MCP backends through one centralized interface with load balancing and circuit breakers.2-
- FlicenseNot gradedqualityDmaintenanceMulti-tenant MCP server with OAuth 2.1 authorization, enabling tenant-scoped tool access and audit logging.-
- AlicenseAqualityCmaintenanceA federated MCP gateway that consolidates multiple plain-HTTP backends into a single, OAuth-protected MCP server, enabling agents to access diverse tools through one endpoint with centralized authentication and audit.512MIT
- AlicenseNot gradedqualityDmaintenanceAuthenticating reverse proxy for MCP servers providing credential isolation, OAuth2 token management, and composite tool aggregation.BSD Zero Clause