MCP Gateway について
MCP Gateway は、クライアントからのリクエストを個別の MCP サーバーへ転送するか、ゲートウェイ配下のすべての MCP サーバーを単一のポータルから利用できるようにするリバースプロキシです。SSE と Streamable HTTP の両方のトランスポートに対応し、OAuth 2.1 によるリソースサーバー認証も備えています。
主な機能
- 01複数の MCP サーバーのツールと SSE ストリームを集約する統一エンドポイント
- 02SSE と Streamable HTTP の切り替え可能なトランスポート
- 03Mcp-Session-Id ヘッダーによるセッション管理
- 04Bearer トークン認証と OAuth 2.1 メタデータの検出
- 05config.json によるプロトコル、認証、セッションの設定
活用シーン
- 01複数の MCP サーバーを一つのエンドポイントの背後にデプロイする
- 02MCP サーバーに Bearer トークンや OAuth による保護を追加する
- 03ローカル開発で認証なしの MCP アクセスを行う
MCP 対応
本ゲートウェイは MCP サーバーのリバースプロキシとして動作し、集約されたツールを SSE または Streamable HTTP のエンドポイントでクライアントに公開し、下流の各 MCP サーバーへリクエストを転送します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
MCP Gateway
説明
MCP ゲートウェイは、クライアントからのリクエストを MCP サーバーに転送するリバースプロキシサーバーです。または、統合ポータルを通じて、ゲートウェイ配下のすべての MCP サーバーを利用できます。
起動時に切り替え可能な 2 つのトランスポートプロトコルをサポートしています。
- SSE(デフォルト、従来の MCP トランスポート)
- Streamable HTTP(MCP 仕様
2025-03-26)
機能
- 複数の MCP サーバーをデプロイする
- MCP サーバーに接続する
- ゲートウェイを使って MCP サーバーを呼び出す
- すべての MCP サーバーの SSE ストリームを取得する
- すべての MCP サーバーのツールを取得する
Mcp-Session-Idヘッダーによるセッション管理に対応した、Streamable HTTP の集約エンドポイント- 動的な機能集約(少なくとも 1 つの下流 MCP がサポートする機能のみをゲートウェイが通知します)
- 保護されたリソースメタデータの検出に対応した、MCP OAuth 2.1 リソースサーバー認証
インストール
- GitHub パッケージをプルする
docker pull ghcr.io/lucky-aeon/mcp-gateway:latest
- 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 | サーバーのリッスンアドレスです。 |
GatewayProtocol | all | 公開するゲートウェイプロトコルです。all、sse、または streamhttp を指定します。--protocol フラグでも上書きできます。 |
Auth.Enabled | true | 認証を必須にするかどうかです。ローカルで認証なしの MCP 利用を許可するには、false に設定します。 |
Auth.ApiKey | 123456 | 従来の単一キー管理 API ログイン用トークンです。MCP 認証には使用されません。 |
Auth.Mode | single-key | single-key または saas です。SaaS モードでは、MCP Gateway アカウントとパスワードログインを使用します。 |
Auth.AuthorizationServers | empty | 任意の外部 OAuth 発行者 URL です。SaaS モードでは、空にするとゲートウェイ自身を認可サーバーとして通知します。 |
Auth.TokenIssuer | first authorization server | MCP OAuth アクセストークンに想定される iss クレームです。 |
Auth.TokenJWKSURI | discovered from issuer | JWT アクセストークンの検証に使用する JWKS URL です。 |
Auth.TokenIntrospectionURL | empty | 不透明なアクセストークン用の RFC 7662 イントロスペクションエンドポイントです。設定すると、JWKS の代わりにイントロスペクションを使用します。 |
Auth.TokenAudience | request resource URL | 想定される aud クレームです。認可サーバーで使用する MCP リソースインジケーターを設定します。 |
Auth.RequiredScopes | empty | MCP リクエストに必要なスコープで、WWW-Authenticate に通知されます。 |
Auth.ScopesSupported | empty | 保護されたリソースメタデータで通知されるスコープです。 |
SessionGCInterval | 10s | アイドル状態のプロキシセッションをガベージコレクションする間隔です。 |
ProxySessionTimeout | 1m | アイドル状態のプロキシセッションがガベージコレクションされるまでのタイムアウトです。 |
McpServiceMgrConfig.McpServiceRetryCount | 3 | MCP サービスが 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 Protected Resource Metadata を公開します。
GET /.well-known/oauth-protected-resource
GET /.well-known/oauth-protected-resource/stream
OAuth ディスカバリーが利用可能な場合、認証されていない MCP リクエストは、WWW-Authenticate: Bearer ... resource_metadata="..." チャレンジとともに 401 を返します。認証なしでローカル開発を行う場合は、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
組み込みの認可エンドポイントは、Gateway アカウントのログインフォームを表示し、PKCE を含む OAuth 認可コードフローを完了します。
/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
}
Gateway を使用する(SSE モード)
GatewayProtocolがall(デフォルト)またはsseの場合に利用できます。
ゲートウェイと MCP への直接接続の違いは、ゲートウェイとのやり取りだけで済み、リクエストはゲートウェイによって対応する MCP サーバーに自動的に転送される点です。call 時には、リクエストがどの MCP サーバーからのものかを示すため、method の前に mcpServerName の内容を追加する必要があります。
GET SSE
GET /sse HTTP/1.1
Host: localhost:8080
ここでの SSE は、ゲートウェイ配下にあるすべての MCP サーバーの SSE ストリームです。
クライアントが SSE を購読すると、ゲートウェイは各 MCP サーバーへの SSE 接続を作成し、すべての MCP サーバーの SSE ストリームを統合します。
すべての tools/call の結果では、結果がどの MCP サーバーからのものかを示すため、method の前に mcpServerName の内容が追加されます。
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"
]
}
}
]
}
}
Gateway を使用する(Streamable HTTP モード)
GatewayProtocolがall(デフォルト)またはstreamhttpの場合に利用できます。spec
2025-03-26で定義されている MCP Streamable HTTP トランスポートを実装しています。ゲートウェイは、POST、GET、DELETEを受け付ける単一の集約エンドポイント/streamを公開します。セッション識別子は、HTTP ヘッダーMcp-Session-Idで受け渡されます。
1. セッションを確立する(initialize)
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 での接続
- Inspector で トランスポートタイプ に
Streamable HTTPを選択します。 - URL:
http://localhost:8080/stream。 - 認可サーバーで OAuth フローを完了し、
Authorization: Bearer <access-token>を指定します。 - Connect をクリックします。Inspector が
Mcp-Session-Idの交換を自動的に処理します。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。