Skip to main content
Glama
R0Wi

mcp-gateway

by R0Wi

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_issuemsdocs_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 运行并监听 :8000docker 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/mcp

Claude 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

none

不发送任何凭据

bearer

token

每次请求加 Authorization: Bearer <token>

headers

headers: {Name: value}

静态标头(API 密钥等)

oauth

scopesprefer_dcrclient_idclient_secret

完整 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 logsdocker compose logs -f),默认级别为 INFO:启动/关闭、配置摘要、登录尝试、OAuth 授权/确认/令牌签发、上游后端连接/断开以及后端挂载状态。级别为 DEBUG 时输出更详细的信息(客户端构建、令牌轮换、CIMD 刷新、存储清理)。任何级别下都不会记录任何凭据或令牌。

通过 MCP_GATEWAY_LOG_LEVEL 环境变量设置日志级别(debuginfowarningerrorcritical):

# .env (picked up by docker compose)
MCP_GATEWAY_LOG_LEVEL=debug
# or inline
docker compose run --rm -e MCP_GATEWAY_LOG_LEVEL=debug mcp-gateway

docker-compose.yml 已经将该变量转发到容器,未设置时默认为 info

在 Docker 之外,mcp-gateway run 上的 --log-level 具有相同的效果,并且会覆盖环境变量:

mcp-gateway run -c config.yaml --log-level debug

端点

路径

用途

/mcp

MCP 端点(Streamable HTTP)

/.well-known/oauth-protected-resource[/mcp]

RFC 9728 受保护资源元数据

/.well-known/oauth-authorization-server

RFC 8414 AS 元数据(及 OIDC 别名)

/authorize/token/register/revoke

OAuth 2.1 端点(PKCE、DCR、撤销)

/ui/authorize

登录 + 确认(Svelte 5)

/ui/backends

后端连接状态 / 显示 / 断开

/oauth/client-metadata.json

网关自身的 CIMD 文档(上游一端)

/oauth/connect/<backend>/oauth/callback

上游 OAuth 连接流程

/healthz

存活探测

安全注意事项

  • PKCE (S256) 是强制要求的;授权码一次性使用,5 分钟过期。

  • 刷新令牌每次使用都会轮换(OAuth 2.1 公共客户端要求)。

  • 访问令牌、刷新令牌和授权码仅限于 SHA-256 哈希形式存储。

  • 已注册的客户端记录和上游凭据在静态时使用 Fernet 加密(auth.encryption_key;密码短语通过 scrypt + 每个数据库的盐进行拉伸)。

  • 同意页面会显示客户端名称和确切的 redirect 目标,并在环回重定向时发出警告(这是规范中针对 localhost 冒充的指引)。

  • 签发给 MCP 客户端的令牌永远不会被转发到后端;后端的凭据也永远不会到达 MCP 客户端。

  • 会话是用 itsdangerous 签名的,并设置为 HttpOnlySameSite=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 终止,就把它放在你自己的反向代理后面,并备份一个文件。

A
license - permissive license
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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

  • F
    license
    Not graded
    quality
    Not graded
    maintenance
    Aggregates 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
  • F
    license
    Not graded
    quality
    B
    maintenance
    Multi-tenant MCP server with OAuth 2.1 authorization, enabling tenant-scoped tool access and audit logging.
  • A
    license
    A
    quality
    C
    maintenance
    A 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.
    5
    10
    MIT

View all related MCP servers

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.

View all MCP Connectors

Latest Blog Posts

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