English | 日本語
スケーリングとコンテナ構成¶
AccelMCP は 同一イメージのまま、1台運用にも複数台運用にも対応します。 役割(WEB管理画面 / MCPエンドポイント)を別コンテナに分け、Streamable HTTP の セッションを Redis で共有することで、MCP エンドポイントだけを水平スケールできます。
コンテナ構成¶
| サービス | 役割 | 備考 |
|---|---|---|
caddy |
リバースプロキシ / TLS | パスで web と mcp に振り分け |
web |
管理UI + REST API | 起動時に DB マイグレーションを実行 |
mcp |
MCP エンドポイント | web と同一イメージ。マイグレーションは実行しない |
redis |
セッション共有ストア | Streamable HTTP セッションを保持 |
db |
PostgreSQL | アプリのデータ |
web と mcp は 同じイメージ・同じアプリ(全Blueprint登録)で、Caddy が
リクエストのパスで振り分けます。これにより「全部入り1台」も「役割分担の複数台」も
同じ compose 定義で動きます。
Caddy のルーティング¶
ホスト名に関わらず、パスで web/mcp に振り分けます。
| パス | 振り分け先 |
|---|---|
/mcp, /mcp/<subdomain>, /<identifier>/mcp, /admin/mcp, /tools/* |
mcp |
上記以外(/, /dashboard, /api/*, /assets/* など) |
web |
Caddy は localhost(または ACCEL_MCP_DOMAIN)と、ローカル開発用の lvh.me / *.lvh.me
の両方を受け付けます。lvh.me は常に 127.0.0.1 を指す公開DNSなので、サブドメイン方式の
MCPサービス(<identifier>.lvh.me/mcp)を追加設定なしでテストできます。
1. 1台運用(ローカル・AWS 等)¶
Dify と同様に、1つのマシンで全コンテナを起動します。ローカルPCでも、AWS EC2のような クラウドVMでも、手順は同じです(違いは「実ドメインを使うか」だけ)。
ローカル開発・検証¶
git clone https://github.com/t-ogawa-dev/octopus-mcp-proxy.git
cd octopus-mcp-proxy
cp .env.example .env
docker compose up -d
https://localhost/ でアクセスします(自己署名証明書の警告は許容して進む。
HTTPS 節を参照)。ACCEL_MCP_DOMAINは設定不要です。
本番運用(実ドメインで1台に集約。AWS EC2 / 自前サーバ等)¶
- マシンを用意し、Docker と Docker Compose をインストールする
(AWSの場合: EC2インスタンスを起動し、セキュリティグループで 80・443番を
0.0.0.0/0に許可、SSH用に22番を許可) - 取得したドメインのDNS Aレコードを、そのマシンのパブリックIPに向ける
- リポジトリを配置し
.envを作成・編集:
git clone https://github.com/t-ogawa-dev/octopus-mcp-proxy.git
cd octopus-mcp-proxy
cp .env.example .env
.env で以下を変更:
ACCEL_MCP_DOMAIN=mcp.example.com # 取得したドメイン
FLASK_ENV=production
SECRET_KEY=<openssl rand -hex 32 などで生成したランダム文字列>
ADMIN_USERNAME=<デフォルトから変更>
ADMIN_PASSWORD=<デフォルトから変更>
- 本番用 Caddyfile (Let's Encrypt) を指定して起動:
(.env に CADDYFILE=./Caddyfile.prod を書いておけば、以降は単に
docker compose up -d でも反映されます)
-
https://mcp.example.com/loginにアクセスして確認(Let's Encrypt証明書が 自動取得されるので、ブラウザの警告は出ません) -
web/mcp/redis/db/caddyが同一マシンで動きます。 - Redis があるので Streamable HTTP セッションは Redis に保存されますが、 1台なら in-memory でも動作します(後述)。
- 複数マシンに分けたい場合は 4. 複数ホストに分散する へ。
HTTPS¶
web/mcp コンテナのポート 5000 はホストには公開されません(expose のみ)。
ブラウザ・MCPクライアントからは必ず Caddy 経由でアクセスします。
| 用途 | URL |
|---|---|
| Web管理画面 | https://localhost/ |
| MCPサービス(サブドメイン方式) | https://<identifier>.lvh.me/mcp |
| MCPサービス(パス方式) | https://localhost/<identifier>/mcp |
ポート番号は不要です(Caddyが443番で受けて内部の5000番へ中継します)。
証明書が「信頼されていません」と表示される¶
これは正常です。ローカル開発用の Caddyfile は tls internal で Caddy自身の自己署名CA
から証明書を発行しています(Let's Encryptはローカル開発では使えません。localhostやlvh.me
は実在の公開ドメインではないため)。対処方法は2つあります。
A. ブラウザの警告を無視して進む(最も簡単)
警告画面で「詳細」→「アクセスする(安全ではありません)」を選べば表示されます。
B. CaddyのローカルCAをOSに信頼させる(警告を消したい場合)
取り出した caddy_local_ca.crt を、macOSなら「キーチェーンアクセス」にドラッグして
「常に信頼」に設定、Windowsなら「信頼されたルート証明機関」にインポートします。
Docker を使わず python run.py で直接起動する場合¶
Flask開発サーバーがポート5000で直接起動するので、TLSなしでアクセスします
(http://localhost:5000/、http://<identifier>.lvh.me:5000/mcp)。
2. セッションストア(Redis)について¶
Streamable HTTP は initialize で発行した Mcp-Session-Id を後続リクエストで
検証します。MCP エンドポイントを複数レプリカ/複数ホストにすると、後続リクエストが
別レプリカに振られた際にセッションを認識できなくなるため、セッションを共有ストアに
置く必要があります。
- 環境変数
REDIS_URLが 設定されている場合: Redis にセッションを保存(共有)。 - 例:
REDIS_URL=redis://redis:6379/0 mcpを複数レプリカ化しても、どのレプリカでもセッションを検証できます。- 環境変数
REDIS_URLが 未設定の場合: プロセス内メモリに保存。 - 追加インフラ不要。1台・単一プロセス運用ならこれで十分です。
- 複数レプリカにするとセッションがレプリカ間で共有されないので不可。
compose.yaml ではデフォルトで REDIS_URL=redis://redis:6379/0 を渡しています。
Redis を使いたくない単一構成にする場合は REDIS_URL を空にしてください。
3. MCP エンドポイントだけスケールする¶
同一ホストでレプリカを増やす場合:
(Caddy の reverse_proxy mcp:5000 は Docker DNS のラウンドロビンで複数レプリカに
分散します。REDIS_URL でセッションが共有されているため、どのレプリカが後続
リクエストを受けても整合します。)
4. 複数ホストに分散する¶
WEB / MCP / Redis / DB を別々のマシンで動かす構成です。deploy/ ディレクトリに
ホストの役割ごとに分割した compose ファイルを用意しているので、各マシンで該当する
ファイルだけを起動します。
| ファイル | 役割 | 起動するマシン |
|---|---|---|
deploy/host-db.compose.yaml |
PostgreSQL | DBホスト |
deploy/host-redis.compose.yaml |
Redis (セッション共有) | Redisホスト |
deploy/host-web.compose.yaml |
管理UI + REST API(マイグレーション実行) | WEBホスト |
deploy/host-mcp.compose.yaml |
MCPエンドポイント | MCPホスト(複数可) |
deploy/host-caddy.compose.yaml |
リバースプロキシ / TLS(公開窓口) | Caddyホスト |
ネットワーク要件(ファイアウォール/セキュリティグループ)¶
| ホスト | 開けるポート | 許可元 |
|---|---|---|
| DBホスト | 5432 | WEBホスト・MCPホストのIPのみ |
| Redisホスト | 6379 | WEBホスト・MCPホストのIPのみ |
| WEBホスト | 5000 | CaddyホストのIPのみ |
| MCPホスト | 5000 | Caddyホストのみ |
| Caddyホスト | 80・443 | インターネット全体(公開窓口) |
手順¶
各マシンに Docker / Docker Compose をインストールし、リポジトリを配置してから
以下を実行します(deploy/ ディレクトリで実行)。
1. DBホストで:
2. Redisホストで:
3. WEBホストと MCPホスト(全台)に共通の .env を配置:
# .env (リポジトリルート)
DATABASE_URL=postgresql://mcpuser:mcppassword@<DBホストのアドレス>:5432/mcpdb
REDIS_URL=redis://<Redisホストのアドレス>:6379/0
SECRET_KEY=<ランダムな文字列>
ADMIN_USERNAME=<デフォルトから変更>
ADMIN_PASSWORD=<デフォルトから変更>
FLASK_ENV=production
4. WEBホストで(マイグレーションが実行されます):
5. MCPホストで(MCPホストを増やす場合は同じ手順を他のマシンでも繰り返す):
6. Caddyホストで(WEB_UPSTREAM/MCP_UPSTREAMに各ホストのアドレスを指定):
cd deploy
ACCEL_MCP_DOMAIN=mcp.example.com \
WEB_UPSTREAM=<WEBホストのアドレス>:5000 \
MCP_UPSTREAM="<MCPホスト1のアドレス>:5000 <MCPホスト2のアドレス>:5000" \
CADDYFILE=../Caddyfile.prod \
docker compose -f host-caddy.compose.yaml up -d
MCP_UPSTREAM はスペース区切りで複数指定できます(MCPホストが複数台の場合)。
ローカルでの動作確認など実ドメインが無い場合は CADDYFILE=../Caddyfile(自己署名証明書)
を使います。
7. 確認: https://mcp.example.com/login(または https://<Caddyホストのアドレス>/login)
にアクセスして管理画面が表示されることを確認します。
ポイント¶
mcpはマイグレーションを実行しません(webが実行)。スキーマ更新は WEBホスト側の デプロイで一度だけ行われます。- WEBホスト・全MCPホストが同じ
REDIS_URLと同じDATABASE_URLを参照すること。 - MCPホストを増設する場合は、新しいマシンで手順5を実行し、Caddyホストの
MCP_UPSTREAMに追加してCaddyを再起動するだけです。 - 各
deploy/host-*.compose.yamlのコメントにも同じ手順を記載しています。
関連する実装¶
- セッションストア抽象化: app/services/session_store.py
InMemorySessionStore/RedisSessionStore/get_session_store(namespace)- 名前空間
"mcp"(MCP本体)と"admin"(Admin MCP)でセッションを分離 - セッション利用箇所:
- app/controllers/mcp_controller.py
- app/controllers/admin_mcp_controller.py
テスト¶
tests/unit/infrastructure/test_session_store.py— セッションストア(in-memory / Redis / バックエンド選択)のユニットテストtests/unit/mcp/test_relay_and_streamable.py::TestStreamableHttpRedisSession— Redis バックエンドでの Streamable HTTP セッション往復tests/integration/test_streamable_chain.py— 実サーバー多段の Streamable HTTP 連結