mcpField
M
MCP Gateway

MCP Gateway

本地服务
github.com/lucky-aeon开发工具3421 周前更新

关于 MCP Gateway

MCP Gateway 是一个反向代理服务,可将客户端请求转发至后端 MCP 服务,或通过统一入口使用网关下的全部 MCP 服务。它支持 SSE 与 Streamable HTTP 两种传输协议,并提供 OAuth 2.1 资源服务器认证。

主要功能

  1. 01统一入口聚合多个 MCP 服务的工具与 SSE 流
  2. 02支持 SSE 与 Streamable HTTP 两种传输协议
  3. 03Streamable HTTP 下通过 Mcp-Session-Id 管理会话
  4. 04基于 Bearer Token 的认证,支持 OAuth 2.1 元数据发现
  5. 05通过 config.json 配置协议、认证与会话参数

适用场景

  1. 01将多个 MCP 服务部署在一个统一端点后供客户端调用
  2. 02为 MCP 服务添加 Bearer Token 或 OAuth 认证
  3. 03在本地开发时以无认证方式访问 MCP 服务

MCP 相关

该网关作为 MCP 服务的反向代理,向客户端暴露聚合后的工具列表与 SSE 或 Streamable HTTP 端点,并将请求转发至下游的各个 MCP 服务。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"gateway-lucky-aeon": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"pull"
]
}
}
}
启动命令docker run -i --rm pull

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
ocipull

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

MCP Gateway

描述

MCP 网关是一个反向代理服务,可将客户端的请求转发到 MCP 服务,也可以通过统一入口使用网关下的所有 MCP 服务。

支持两种传输协议(可在启动时切换):

  • SSE(默认,旧版 MCP 传输协议)
  • Streamable HTTP(MCP 规范 2025-03-26)

功能

  • 部署多个 MCP 服务
  • 连接到 MCP 服务
  • 使用网关调用 MCP 服务
  • 获取所有 MCP 服务的 SSE 流
  • 获取所有 MCP 服务的工具
  • 提供支持通过 Mcp-Session-Id 标头管理会话的 Streamable HTTP 聚合端点
  • 动态聚合能力(网关只公布至少一个下游 MCP 服务支持的能力)
  • 支持通过受保护资源元数据发现进行 MCP OAuth 2.1 资源服务器身份验证

安装

  1. 拉取 GitHub 软件包
docker pull ghcr.io/lucky-aeon/mcp-gateway:latest
  1. 自行构建 Docker 镜像
docker build -t mcp-gateway .

使用

运行 GitHub Docker 容器

docker run -d --name mcp-gateway -p 8080:8080 ghcr.io/lucky-aeon/mcp-gateway

运行自行构建的 Docker 容器

docker run -d --name mcp-gateway -p 8080:8080 mcp-gateway

配置

网关会从配置目录读取 config.json(若存在 ./vm,则默认为该目录;否则默认为 .)。最简示例如下:

{
    "LogLevel": 0,
    "Bind": "[::]:8080",
    "Auth": {
        "Enabled": true,
        "AuthorizationServers": ["https://auth.example.com"],
        "TokenIssuer": "https://auth.example.com",
        "TokenJWKSURI": "https://auth.example.com/.well-known/jwks.json",
        "TokenAudience": "http://localhost:8080/stream",
        "RequiredScopes": ["mcp:read"],
        "ScopesSupported": ["mcp:read"]
    },
    "GatewayProtocol": "all",
    "McpServiceMgrConfig": {
        "McpServiceRetryCount": 3
    }
}

关键字段:

字段默认值描述
Bind[::]:8080服务监听地址。
GatewayProtocolall对外提供的网关协议:all、sse 或 streamhttp。也可通过 --protocol 标志覆盖。
Auth.Enabledtrue是否强制进行身份验证。本地无需身份验证即可使用 MCP 时设为 false。
Auth.ApiKey123456旧版单密钥管理 API 登录令牌;不用于 MCP 身份验证。
Auth.Modesingle-keysingle-key 或 saas。SaaS 模式使用 MCP Gateway 账户和密码登录。
Auth.AuthorizationServers空可选的外部 OAuth 颁发方 URL。SaaS 模式下若为空,网关将公布自身为授权服务器。
Auth.TokenIssuer第一个授权服务器MCP OAuth 访问令牌预期的 iss 声明。
Auth.TokenJWKSURI从颁发方发现用于验证 JWT 访问令牌的 JWKS URL。
Auth.TokenIntrospectionURL空不透明访问令牌的 RFC 7662 内省端点。若设置,则使用内省而非 JWKS。
Auth.TokenAudience请求资源 URL预期的 aud 声明。请配置为授权服务器使用的 MCP 资源指示符。
Auth.RequiredScopes空MCP 请求所需的作用域,并在 WWW-Authenticate 中公布。
Auth.ScopesSupported空在受保护资源元数据中公布的作用域。
SessionGCInterval10s垃圾回收空闲代理会话的间隔。
ProxySessionTimeout1m垃圾回收前空闲代理会话的超时时间。
McpServiceMgrConfig.McpServiceRetryCount3MCP 服务失败后将其标记为 failed 前的最大重试次数。
选择网关协议

可在 config.json 中设置 GatewayProtocol:

{ "GatewayProtocol": "all" }

也可传入 CLI 标志(优先级更高):

./mcp-gateway --protocol=streamhttp

有效值:all(默认)、sse 或 streamhttp。

身份验证

当 Auth.Enabled 为 true 时,每个 MCP 协议请求都必须提供 Bearer 令牌:

Authorization: Bearer <access-token>

网关不再将 api_key、sessionId、Mcp-Session-Id 或 X-Session-Id 视为身份验证凭据。Mcp-Session-Id 仍是传输会话标识符,在经过身份验证的 Streamable HTTP 请求中,必须与 Bearer 令牌一同发送。

对于 MCP OAuth 发现,网关会提供 OAuth 受保护资源元数据:

GET /.well-known/oauth-protected-resource
GET /.well-known/oauth-protected-resource/stream

当 OAuth 发现可用时,未经授权的 MCP 请求会返回 401,并附带 WWW-Authenticate: Bearer ... resource_metadata="..." 挑战。若要在本地进行无需身份验证的开发,请将 Auth.Enabled 设为 false。

在 Auth.Mode = "saas" 且未配置外部 Auth.AuthorizationServers 时,网关会使用自身的账户系统进行 MCP 登录。发现信息会将网关源站公布为授权服务器,并提供:

GET /.well-known/oauth-authorization-server
POST /oauth/token
POST /oauth/register

/oauth/token 接受采用表单编码的 grant_type=password,以及 username/password,并返回与 /api/v1/auth/login 相同的网关 JWT。仅当需要使用 Keycloak、Auth0 或其他外部 OAuth 提供方时,才配置 Auth.AuthorizationServers。

基于浏览器的 MCP 客户端也可以使用公布的授权端点:

GET /oauth/authorize

内置授权端点会显示网关账户登录表单,并完成 OAuth 授权码流程,包括 PKCE。 /oauth/register 实现了精简的动态客户端注册,适用于 MCP Inspector 等客户端。

API

部署

支持:uvx、npx,或 SSE URL

POST /deploy HTTP/1.1
Host: localhost:8080
Content-Type: application/json

{
    "mcpServers": {
        "time": {
            "url": "http://mcp-server:8080",  // url 和 command 二选一
            "command": "uvx",  // url 和 command 二选一
            "args": ["mcp-server-time", "--local-timezone=America/New_York"],  // 可选,command 的参数
            "env": {  // 可选,环境变量
                "KEY1": "VALUE1",
                "KEY2": "VALUE2"
            }
        }
    }
}
使用 MCP(SSE 模式)

当 GatewayProtocol 为 all(默认值)或 sse 时可用。

GET SSE
GET /{mcp-server-name}/sse HTTP/1.1
Host: localhost:8080
POST 消息
POST /{mcp-server-name}/message HTTP/1.1
Host: localhost:8080
Content-Type: application/json

{
    "method": "tools/call",
    "params": {
        "name": "get_current_time",
        "arguments": {
            "timezone": "Asia/Seoul"
        }
    },
    "jsonrpc": "2.0",
    "id": 2
}
使用网关(SSE 模式)

当 GatewayProtocol 为 all(默认值)或 sse 时可用。

网关与直连 MCP 的区别在于,你只需与网关交互,网关会自动将请求转发到对应的 MCP 服务。调用时,需要在 method 前面添加 mcpServerName,用于标识该请求来自哪个 MCP 服务。

GET SSE
GET /sse HTTP/1.1
Host: localhost:8080

这里的 SSE 是整个网关下所有 MCP 服务的 SSE 流。

当客户端订阅 SSE 时,网关会为每个 MCP 服务创建一个 SSE 连接,并将所有 MCP 服务的 SSE 流合并到一起。

在所有 tools/call 响应的结果中,都会在 method 前面添加 mcpServerName,用于标识该结果来自哪个 MCP 服务。

POST 消息
POST /message HTTP/1.1
Host: localhost:8080
Content-Type: application/json

{
    "method": "tools/call",
    "params": {
        "name": "{mcp-server-name}-get_current_time",
        "arguments": {
            "timezone": "Asia/Seoul"
        }
    },
    "jsonrpc": "2.0",
    "id": 2
}

获取网关下的所有工具

POST /message HTTP/1.1
Host: localhost:8080
Content-Type: application/json

{
    "method": "tools/list",
    "jsonrpc": "2.0",
    "id": 1
}

# SSE 响应 message event

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "tools": [
      {
        "name": "{mcpServerName}-get_current_time",
        "description": "Get current time in a specific timezones",
        "inputSchema": {
          "type": "object",
          "properties": {
            "timezone": {
              "type": "string",
              "description": "IANA timezone name (e.g., 'America/New_York', 'Europe/London'). Use 'America/New_York' as local timezone if no timezone provided by the user."
            }
          },
          "required": [
            "timezone"
          ]
        }
      },
      {
        "name": "{mcpServerName}-convert_time",
        "description": "Convert time between timezones",
        "inputSchema": {
          "type": "object",
          "properties": {
            "source_timezone": {
              "type": "string",
              "description": "Source IANA timezone name (e.g., 'America/New_York', 'Europe/London'). Use 'America/New_York' as local timezone if no source timezone provided by the user."
            },
            "time": {
              "type": "string",
              "description": "Time to convert in 24-hour format (HH:MM)"
            },
            "target_timezone": {
              "type": "string",
              "description": "Target IANA timezone name (e.g., 'Asia/Tokyo', 'America/San_Francisco'). Use 'America/New_York' as local timezone if no target timezone provided by the user."
            }
          },
          "required": [
            "source_timezone",
            "time",
            "target_timezone"
          ]
        }
      }
    ]
  }
}
使用网关(Streamable HTTP 模式)

当 GatewayProtocol 为 all(默认值)或 streamhttp 时可用。

实现规范 2025-03-26 中定义的 MCP Streamable HTTP 传输。网关提供单一聚合端点 /stream,支持 POST、GET 和 DELETE。会话标识符通过 HTTP 标头 Mcp-Session-Id 传递。

1. 建立会话(初始化)
POST /stream HTTP/1.1
Host: localhost:8080
Authorization: Bearer <access-token>
Accept: application/json, text/event-stream
Content-Type: application/json

{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "initialize",
    "params": {
        "protocolVersion": "2025-03-26",
        "capabilities": {},
        "clientInfo": {"name": "my-client", "version": "1.0.0"}
    }
}

响应:

HTTP/1.1 200 OK
Content-Type: application/json
Mcp-Session-Id: 7782f2f9-563c-4379-b961-df06e49e54c0

{
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
        "protocolVersion": "2025-03-26",
        "serverInfo": {"name": "mcp-gateway", "version": "1.0.0"},
        "capabilities": { /* OR-merged from all downstream MCP servers */ },
        "instructions": "MCP Gateway aggregates multiple MCP servers. Tools are namespaced as <serverName>_<toolName>."
    }
}

保留返回的 Mcp-Session-Id,并在后续每个请求中发送。

2. 完成握手(通知)
POST /stream HTTP/1.1
Host: localhost:8080
Authorization: Bearer <access-token>
Content-Type: application/json
Mcp-Session-Id: 7782f2f9-563c-4379-b961-df06e49e54c0

{"jsonrpc": "2.0", "method": "notifications/initialized"}

响应:202 Accepted(空响应体)。

3. 调用工具或列出资源
POST /stream HTTP/1.1
Host: localhost:8080
Authorization: Bearer <access-token>
Accept: application/json, text/event-stream
Content-Type: application/json
Mcp-Session-Id: 7782f2f9-563c-4379-b961-df06e49e54c0

{
    "jsonrpc": "2.0",
    "id": 2,
    "method": "tools/call",
    "params": {
        "name": "{mcp-server-name}_get_current_time",
        "arguments": {"timezone": "Asia/Seoul"}
    }
}

聚合工具名称遵循 <serverName>_<toolName> 模式,与 SSE 网关模式使用相同的规则。

响应会同步返回在 HTTP 响应体中:

{"jsonrpc": "2.0", "id": 2, "result": { /* ... */ }}

通知(不含 id 的 JSON-RPC 消息)会收到 202 Accepted 响应,并以异步方式转发。

4. 订阅服务器发起的事件(可选)
GET /stream HTTP/1.1
Host: localhost:8080
Authorization: Bearer <access-token>
Accept: text/event-stream
Mcp-Session-Id: 7782f2f9-563c-4379-b961-df06e49e54c0

网关会保持连接打开,并为服务器 → 客户端的 JSON-RPC 请求和通知(例如进度更新、日志消息)发送 event: message 帧。JSON-RPC 响应不会在此推送,而是通过发起该请求的 POST /stream 请求的 HTTP 响应返回。

以 : 开头的行是 SSE 保活注释,可以忽略。

5. 关闭会话
DELETE /stream HTTP/1.1
Host: localhost:8080
Authorization: Bearer <access-token>
Mcp-Session-Id: 7782f2f9-563c-4379-b961-df06e49e54c0

响应:200 OK。

单服务器直通

在 Streamable HTTP 模式下,你也可以直接访问单个 MCP 服务:

POST /{mcp-server-name} HTTP/1.1
GET  /{mcp-server-name} HTTP/1.1

网关会将请求转发到目标 MCP 的 message 端点。在此模式下,会话管理由下游服务负责。

使用 MCP Inspector 连接
  1. 在 Inspector 中选择 传输类型:Streamable HTTP。
  2. URL:http://localhost:8080/stream。
  3. 在授权服务器中完成 OAuth 流程,并提供 Authorization: Bearer <access-token>。
  4. 点击 连接。Inspector 会自动处理 Mcp-Session-Id 交换。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。