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 installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
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 gradedqualityBmaintenanceMulti-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.510MIT
- AlicenseNot gradedqualityCmaintenanceAuthenticating reverse proxy for MCP servers providing credential isolation, OAuth2 token management, and composite tool aggregation.BSD Zero Clause
Related MCP Connectors
Self-hosted federated MCP gateway: one OAuth 2.1 MCP server in front of N apps, user-level scopes.
MCP Hub: AI service discovery, per-user OAuth, and multi-service workflow orchestration
An authenticated remote MCP server for user-owned devices and one-shot capability invocation.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/R0Wi/mcp-gateway'
If you have feedback or need assistance with the MCP directory API, please join our Discord server