🗂

MCPサーバーをCloud Runで動かす:stdio→HTTP変換でサーバーレス化

に公開
2026/01/15

はじめに

TL;DR
MCPサーバーをチームで共有したいけど、stdioベースだからCloud Runにデプロイできない——そんな課題を、stdio→HTTP変換アダプターで解決しました。

MCPサーバーを個人のローカル環境だけでなく、チームメンバーや複数のAIエージェントから利用したい——そんなとき、Cloud Runのようなサーバーレス環境にデプロイできると便利です。しかし、MCP(Model Context Protocol)サーバーの多くは標準入出力(stdio)による通信を前提として設計されており、HTTP環境では直接動作しません。

この課題を解決するため、stdio通信をHTTPエンドポイント化するアダプター(tumiki-mcp-http-adapter)を使ってCloud Runにデプロイする仕組みを構築しました。

※本記事はローカル検証・PoC用途を想定しています。

tumiki-mcp-http-adapterとは

tumiki-mcp-http-adapterは、Goで実装されたstdio↔HTTP変換アダプターです。シングルバイナリで動作し、軽量かつ高速に動作します。

他のOSSとの違い

HTTP変換proxyは他のOSSでも実現できますが、tumiki-mcp-http-adapterには以下のような特徴があります。

1. ステートレス環境でのホスティング

Cloud Runなどのステートレスなサーバーレス環境でMCPサーバーをホスティングできます。HTTP化とプロセス管理により、サーバーレス環境での運用が可能です。

2. アップデート追従性の維持

既存のMCPサーバーをフォークしてHTTP変換を組み込む方法もありますが、その場合は元のMCPサーバーのアップデートに追従する対応が大変になります。アダプター方式であれば、元のMCPサーバーをそのまま利用できるため、npmで公開されているMCPサーバーのアップデートに容易に追従できます。

3. リクエストごとの動的な設定変更

HTTPヘッダー経由でAPIキーなどの設定を動的に変更できます。これにより、リクエストごとに異なるAPIキーを使用したり、マルチテナント環境での運用が可能になります。環境変数を固定する必要がないため、柔軟な運用ができます。

主な機能

  • プロトコル変換:MCPサーバーのstdio/SSE通信をHTTP/SSEに変換
  • 環境変数の注入:--header-envオプションでHTTPヘッダー経由でAPIキーなどを渡せる
  • 柔軟なポート設定:--portオプションまたは${PORT}環境変数で動的にポート設定

既存のstdio MCPサーバーをそのまま利用でき、コードの変更は一切不要です。

基本的な使い方

インストールはGitHubからバイナリをダウンロードするか、ソースからビルドします。

# Goでビルド
git clone https://github.com/rayven122/tumiki-mcp-http-adapter.git
cd tumiki-mcp-http-adapter
go build -o tumiki-mcp-http ./cmd/tumiki-mcp-http

基本的な使い方は次の通りです。

./tumiki-mcp-http --stdio 'mcp-server-brave-search' \
  --header-env 'X-Brave-API-Key=BRAVE_API_KEY' \
  --port 8080

オプション:

  • --stdio: MCPサーバーのコマンド(スペース含む場合はクォートで囲む)
  • --header-env: HTTPヘッダーから環境変数への変換(例:'ヘッダー名=環境変数名')
  • --port: リッスンするポート番号

Dockerでの実行例

マルチステージビルドを使ったDockerfileの例です。ローカルで試す場合とCloud Runにデプロイする場合をそれぞれ記載します。

ローカルで試す場合

ローカルDockerで動かす場合は、固定ポート(8080)を使用します。

FROM golang:alpine AS builder
WORKDIR /build
RUN apk add --no-cache git && \
    git clone https://github.com/rayven122/tumiki-mcp-http-adapter.git . && \
    go build -o tumiki-mcp-http ./cmd/tumiki-mcp-http

FROM node:20-alpine
WORKDIR /app
COPY --from=builder /build/tumiki-mcp-http .
RUN npm install -g @modelcontextprotocol/server-brave-search
CMD sh -c "./tumiki-mcp-http --stdio 'mcp-server-brave-search' \
    --header-env 'X-Brave-API-Key=BRAVE_API_KEY' \
    --port 8080"

Dockerイメージをビルドして実行します。

# Dockerイメージをビルド
docker build -t mcp-http-adapter-demo .

# コンテナを起動(ポート8080で待ち受け)
docker run -p 8080:8080 mcp-http-adapter-demo

# 別のターミナルでテスト
curl -X POST http://localhost:8080/mcp \
  -H 'X-Brave-API-Key: your-api-key-here' \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","method":"tools/list","id":1}'

正常に動作すれば、以下のようなレスポンスが返ってきます。

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "tools": [
      {
        "name": "brave_web_search",
        "description": "Performs a web search using the Brave Search API...",
        "inputSchema": {
          "type": "object",
          "properties": {
            "query": {
              "type": "string",
              "description": "Search query (max 400 chars, 50 words)"
            },
            "count": {
              "type": "number",
              "description": "Number of results (1-20, default 10)",
              "default": 10
            }
          },
          "required": ["query"]
        }
      },
      {
        "name": "brave_local_search",
        "description": "Searches for local businesses and places...",
        "inputSchema": {
          "type": "object",
          "properties": {
            "query": {
              "type": "string",
              "description": "Local search query"
            }
          },
          "required": ["query"]
        }
      }
    ]
  }
}

この出力により、Brave Search MCP サーバーが正常にHTTP経由で動作していることが確認できます。

Cloud Runにデプロイする場合

Cloud Runでは${PORT}環境変数を使用します。Cloud Runが自動的にポート番号を設定するため、DockerfileのCMDで${PORT}を指定します。

...
# 以下のみDockerデプロイと異なる
CMD sh -c "./tumiki-mcp-http --stdio 'mcp-server-brave-search' \
    --header-env 'X-Brave-API-Key=BRAVE_API_KEY' \
    --port ${PORT}"

デプロイコマンド:

# Dockerイメージをビルド&プッシュ
docker build -t asia-northeast1-docker.pkg.dev/your-project/your-repo/brave-mcp .
docker push asia-northeast1-docker.pkg.dev/your-project/your-repo/brave-mcp

# Cloud Runにデプロイ
gcloud run deploy brave-mcp \
  --image asia-northeast1-docker.pkg.dev/your-project/your-repo/brave-mcp \
  --region asia-northeast1 \
  --platform managed

APIキーはHTTPヘッダー経由で渡すため、コンテナイメージに含まれません

メリットと今後の展開

stdio→HTTP変換により以下のメリットが得られます。

  • HTTP化による拡張性:stdio MCPサーバーをWebサービスとして利用可能
  • 既存資産の活用:npmで公開されているMCPサーバーをそのまま利用
  • デプロイの柔軟性:Docker環境で動かせるため、将来的にCloud Runなどのサーバーレス環境へのデプロイも容易

現在、TumikiではBrave Search、Figma、YouTube、Slackなど複数のMCPサーバーでこのアダプターを活用しています。

まとめ

tumiki-mcp-http-adapterを使うことで、stdio形式のMCPサーバーをHTTP/SSEに変換し、Docker環境で動かすことができました。既存のnpmパッケージをそのまま活用でき、シンプルな設定で実行が可能です。

このアダプターがあれば、将来的にCloud Runなどのサーバーレス環境へのデプロイも容易に行えます。興味がある方は、ぜひリポジトリをチェックしてみてください。

Discussion