5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

MCPサーバーをコンテナで動かす:stdio→HTTP変換でサーバーレス化

5
Last updated at Posted at 2026-01-03

はじめに

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などのサーバーレス環境へのデプロイも容易に行えます。興味がある方は、ぜひリポジトリをチェックしてみてください。

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?