MCP Gateway
About
A reverse proxy gateway for managing and accessing multiple MCP servers through a single entry point, deployable via Docker.
Details
- Author
- lucky-aeon
- Categories
- Developer Tools, API, Infrastructure, Other
Jump to
Setup
Install MCP Gateway in your MCP client (Claude Desktop, Cursor, Windsurf, and others).
Repository: https://github.com/lucky-aeon/mcp-gateway
Follow the installation instructions in the repository README, then restart your MCP client.
The MCP gateway is a reverse proxy server that forwards requests from clients to the MCP server or uses all MCP servers under the gateway through a unified portal.
Supports two transport protocols (switchable at startup):
- SSE(default, legacy MCP transport)
- Streamable HTTP(MCP spec2025-03-26)
- Deploy multiple MCP servers
- Connect to MCP server
- Use gateway to call MCP servers
- Get all MCP servers' SSE streams
- Get all MCP servers' tools
- Streamable HTTP aggregated endpoint with session management viaMcp-Session-Idheader
- Dynamic capability aggregation (gateway only advertises capabilities that at least one downstream MCP supports)
- MCP OAuth 2.1 resource server authentication with Protected Resource Metadata discovery
docker pull ghcr.io/lucky-aeon/mcp-gateway:latest
docker run -d --name mcp-gateway -p 8080:8080 ghcr.io/lucky-aeon/mcp-gateway
docker run -d --name mcp-gateway -p 8080:8080 mcp-gateway
The gateway readsconfig.jsonfrom the config directory (defaults to./vmwhen present, otherwise.). A minimal example:
{ "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 } }
Either setGatewayProtocolinconfig.json:
{ "GatewayProtocol": "all" }
Or pass the CLI flag (takes precedence):
Valid values:all(default),sse, orstreamhttp.
WhenAuth.Enabledistrue, every MCP protocol request must present a Bearer token:
Authorization: Bearer <access-token>
The gateway no longer treatsapi_key,sessionId,Mcp-Session-Id, orX-Session-Idas authentication credentials.Mcp-Session-Idremains a transport session identifier and must be sent together with the Bearer token on authenticated Streamable HTTP requests.
For MCP OAuth discovery, the gateway exposes OAuth Protected Resource Metadata:
GET /.well-known/oauth-protected-resource GET /.well-known/oauth-protected-resource/stream
Unauthorized MCP requests return401with aWWW-Authenticate: Bearer ... resource_metadata="..."challenge when OAuth discovery is available. For local unauthenticated development, setAuth.Enabledtofalse.
InAuth.Mode = "saas"with no externalAuth.AuthorizationServers, the gateway uses its own account system for MCP login. Discovery advertises the gateway origin as the authorization server and exposes:
GET /.well-known/oauth-authorization-server POST /oauth/token POST /oauth/register
/oauth/tokenaccepts form-encodedgrant_type=passwordwithusername/passwordand returns the same gateway JWT used by/api/v1/auth/login. ConfigureAuth.AuthorizationServersonly when you want Keycloak, Auth0, or another external OAuth provider.
Browser-based MCP clients can also use the advertised authorization endpoint:
The built-in authorization endpoint renders a Gateway account login form and completes the OAuth authorization-code flow, including PKCE./oauth/registerimplements minimal dynamic client registration for clients such as MCP Inspector.
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" } } } }
Available whenGatewayProtocolisall(default) orsse.
GET /{mcp-server-name}/sse HTTP/1.1 Host: localhost:8080
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 }
Available whenGatewayProtocolisall(default) orsse.
网关和直连MCP的区别在于,只需要与网关交互,网关会自动将请求转发到对应的MCP服务器。在call 时,需要在method前面添加mcpServerName内容,标识该请求来自哪个 MCP 服务器。
当客户端订阅 sse 时,网关会为每个 MCP 服务器创建一个 SSE 连接,并将所有 MCP 服务器的 SSE 流合并到一起。
在响应的所有tools/call 的结果中,会在method前面添加mcpServerName内容,标识该结果来自哪个 MCP 服务器。
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" ] } } ] } }
Available whenGatewayProtocolisall(default) orstreamhttp.
Implements the MCP Streamable HTTP transport defined in spec2025-03-26. The gateway exposes a single aggregated endpoint/streamthat acceptsPOST,GETandDELETE. Session identifiers are carried in theMcp-Session-IdHTTP header.
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>." } }
Keep the returnedMcp-Session-Idand send it on every subsequent request.
2. Complete the handshake (notification)
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"}
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"} } }
Aggregated tool names follow the pattern<serverName>_<toolName>, same rule as the SSE gateway mode.
The response arrives synchronously in the HTTP response body:
{"jsonrpc": "2.0", "id": 2, "result": { / ... / }}
Notifications (JSON-RPC messages withoutid) are answered with202 Acceptedand forwarded asynchronously.
GET /stream HTTP/1.1 Host: localhost:8080 Authorization: Bearer <access-token> Accept: text/event-stream Mcp-Session-Id: 7782f2f9-563c-4379-b961-df06e49e54c0
The gateway keeps the connection open and emitsevent: messageframes for server → client JSON-RPCrequestsandnotifications(e.g. progress updates, log messages). JSON-RPCresponsesare never pushed here — they are returned in the HTTP response of the originatingPOST /streamrequest.
Lines starting with:are SSE keepalive comments and can be ignored.
DELETE /stream HTTP/1.1 Host: localhost:8080 Authorization: Bearer <access-token> Mcp-Session-Id: 7782f2f9-563c-4379-b961-df06e49e54c0
In Streamable HTTP mode you can also reach an individual MCP server directly:
POST /{mcp-server-name} HTTP/1.1 GET /{mcp-server-name} HTTP/1.1
The gateway forwards the request to the target MCP'smessageendpoint. Session management in this mode is the responsibility of the downstream server.
- In Inspector selectTransport Type:Streamable HTTP.
- URL:http://localhost:8080/stream.
- Complete the OAuth flow in your authorization server and provideAuthorization: Bearer <access-token>.
- ClickConnect. The Inspector handles theMcp-Session-Idexchange automatically.
This is a web browser that enables your coding agent, such as Claude Code, to visit websites on your behalf and assist you in identifying bugs or creating UI test cases.
A Ruby implementation of an MCP server for managing and using Docker
Manage Docker containers, volumes, and services using natural language commands.
Orchestration tool for managing multiple MCP servers with a Docker Compose-style interface and a unified HTTP proxy.
A Docker-based proxy to access local MCP servers through Claude's web UI using the Remote MCP protocol.
All Azure MCP tools in a single server. The Azure MCP Server implements the MCP specification to create a seamless connection between AI agents and Azure services. Azure MCP Server can be used alone or with the GitHub Copilot for Azure extension in VS Code.
Official Docker MCP Toolkit for discovering, configuring, and running containerized MCP servers through Docker Desktop and the Docker MCP gateway.
Tool platform by IBM to build, test and deploy tools for any data source
The Railway MCP Server enables natural language interaction with your Railway projects and infrastructure. Ask your IDE or AI assistant to create projects, deploy templates, manage environments, pull variables, redeploy services, and more.
The Shipyard CLI provides an MCP server for agents to manage Shipyard environments directly: by pulling logs, comparing branches, running tests, and stopping/starting environments..
Secure virtual machines for agents hosted by Superserve
Sign in to leave a review
Use Google, GitHub, or an email account so ratings stay tied to real people.
No reviews posted yet.





