MCPサーバーの初回呼び出しはなぜ遅い?コールドスタートの計測と対策【MCP Hosting・2026年実測】
ホスティングしたMCPサーバーが最初のtools/listだけ遅い・失敗する原因を実測で解説。キャッシュなしのnpx -yは7,550ms、インストール済みなら171ms、Pythonはバイトコード事前コンパイルで初回1,199ms→476ms。curlでの計測方法、コールドスタートの6段階、Cloud Run・Lambda SnapStart・Workers・Vercel・Fly Machines・Railway・Renderの設定、クライアントのタイムアウト(Codex 10秒、TypeScript SDK 60秒)、常時起動のコスト計算まで。
最終更新:2026年10月17日 / 対象:MCP仕様 2026-07-28 と2025年版のサーバー。計測は2026年10月17日、Node.js 22.22.0、Python 3.13、
@modelcontextprotocol/server-memory1.0.0、mcp-server-fetch2026.10.10、supergateway 4.2.0 で実施
結論(30秒で読める要約)
MCPサーバーのコールドスタートとは、しばらく使われていないサーバーに最初のリクエストが届いたとき、マシンの起動、ランタイムの起動、依存関係の解決、サーバーの初期化を待つ時間のことです。MCP Hostingでは「接続直後の tools/list が遅い・失敗する」「2回目なら動く」という形で現れます。
- 一番大きく、しかも避けられる遅延は、起動時のパッケージ取得です。今回の計測では、同じNode.jsサーバーの
initialize応答までの時間が、インストール済みなら171ms、npx -y(キャッシュあり)で960ms、npx -y(キャッシュなし)で7,550msでした。Pythonのuvxも同じ傾向です(インストール済み503ms、キャッシュなし7,173ms、最悪49秒)。 - Pythonはバイトコードの事前コンパイルが効きます。
.pycがない状態の初回起動は1,199ms、--compile-bytecode付きでインストールすると476msでした。 - プラットフォーム側の起動時間は、数ミリ秒から1分まで幅があります。Cloudflare Workersのisolateは「コンテナ上のNodeプロセスより約100倍速く起動する」、Fly Machinesのsuspendからの復帰は「数百ミリ秒」、Renderの無料プランは「約1分」かかると公式に書かれています。
- クライアントのタイムアウトと突き合わせます。Codexはサーバー起動を既定で10秒しか待たず、公式TypeScript SDKはリクエストを60,000msでタイムアウトさせます。1分かかる起動はどちらでも失敗します。
- 常時1台起動しておけばコールドスタートは消えますが、待機時間もすべて課金されます。512MBを1か月起動しっぱなしにすると約365 GB時間です。
計測方法は3章、プラットフォーム別の設定は5章、タイムアウト一覧は6章にあります。
目次
- MCPサーバーのコールドスタートとは
- コールドスタートの内訳:どこで時間がかかるか
- コールドスタートの計測方法
- 実測:起動コマンドで初回応答はどれだけ変わるか
- プラットフォーム別の対策
- クライアントは何秒待つか(タイムアウト一覧)
- 常時起動か、スケールtoゼロか:コスト計算
- チェックリスト
- トラブルシューティング(症状→原因→対処)
- NodeFlareならこう解決できる
- よくある質問
1. MCPサーバーのコールドスタートとは
MCPサーバーのコールドスタートとは、動いているインスタンスがない状態でリクエストが届いてから、最初の応答が返るまでの追加の待ち時間です。ウォームなリクエストはすでに待ち受けているプロセスに届きますが、コールドなリクエストは、プラットフォームがインスタンスを作成または復帰させ、プロセスが起動し、MCPサーバー自身の初期化が終わるまで待たされます。
MCPでは、コールドになるのはほぼ必ず最初の「一覧取得」です。2025年版のサーバーなら initialize ハンドシェイク、initialize を廃止して各リクエストの _meta でバージョンを送る2026-07-28版のサーバーなら、たいてい最初の tools/list です。クライアントはこの応答が来るまでツールを表示できないので、コールドスタートが長いと「ツールが0個」「接続に失敗」と見えます。ツールが遅いようには見えないのが厄介な点です。
コールドスタートが問題になるのは、ホスティング先がスケールtoゼロするか、インスタンスを入れ替える場合だけです。常時起動のVPSなら起きませんが、代わりに待機時間の費用を払います。どちらを選ぶかは柱記事「MCP Hosting 2026年版:MCPサーバーをリモートで動かす6つの方法」で扱いました。この記事は、スケールtoゼロを選んだうえで速くする方法を扱います。
2. コールドスタートの内訳:どこで時間がかかるか
コールドスタートは6つの段階の合計で、自分で縮められる段階とそうでない段階があります。どこが支配的かはプラットフォームとサーバーで変わるので、最適化の前に計測します。
| 段階 | 何が起きるか | 目安 | 誰が決めるか |
|---|---|---|---|
| プラットフォームの起動 | コンテナ作成、VM起動、スナップショット復元、isolate起動 | ミリ秒(isolate・スナップショット)〜約1分(無料プランの復帰) | プラットフォームとその設定 |
| イメージ・コードの読み込み | イメージのpull、バンドルの配置 | イメージが大きいほど増える | 自分(サイズ)、プラットフォーム(キャッシュ) |
| ランタイムの起動 | Node.js、Python、JVM、.NETの起動 | Node/Pythonで約0.1〜0.5秒、JVMはそれ以上 | 自分(ランタイムの選択) |
| 依存関係の解決 | npx -y や uvx がレジストリを確認し、パッケージを取得 |
キャッシュありで約0.5秒、なしで数秒 | 自分(ビルド時にインストール) |
| サーバーの初期化 | モジュールのimport、設定読み込み、DB接続、カタログ取得 | ミリ秒〜数秒 | 自分(遅延初期化) |
| 最初のMCPのやりとり | initialize(2025年版)または最初の tools/list |
小さい。ただしリクエストごとにプロセスを起動するブリッジは例外 | 自分(ブリッジのモード) |
見落としやすいのは2つです。1つは依存関係の解決で、起動コマンドが npx -y … や uvx … だと毎回発生します。多くのMCPサーバーのREADMEはローカル用にこの書き方を案内しているので、そのままデプロイすると踏みます。もう1つはブリッジで、supergatewayのステートレスモードはPOSTごとに子プロセスを起動するため、ランタイムの起動が初回だけでなく毎回かかります。ブリッジのプロセス管理は「stdioのMCPサーバーをリモートで動かす方法」で詳しく解説しています。
3. コールドスタートの計測方法
コールドスタートは「アイドル状態になった後の最初のリクエストの初回バイトまでの時間」と「その1秒後の同じリクエスト」の差で測ります。curl なら内訳まで1コマンドで出せます。
cat > curl-mcp.txt <<'EOF'
dns: %{time_namelookup}s
tls done: %{time_appconnect}s
first byte: %{time_starttransfer}s
total: %{time_total}s
status: %{http_code}
EOF
probe() {
curl -s -o /dev/null -w @curl-mcp.txt -X POST "$MCP_URL" \
-H "Authorization: Bearer $MCP_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
}
probe # コールドの可能性あり
sleep 1; probe # ウォームの基準値
コールドな状態を作るには、最初の probe の前にプラットフォームのアイドル時間より長く待つか(Renderの無料プランなら15分超)、再デプロイします。結果の読み方は次のとおりです。
tls doneが大きく、first byteもそれに近い:コールドスタートではなく、ネットワークかTLSの問題です。利用者や上流APIに近い場所に置きます。- 最初の1回だけ
first byteが大きい:コールドスタートです。4章と5章の対策が効きます。 - 毎回
first byteが大きい:コールドスタートではありません。リクエストごとのプロセス起動(ステートレスなブリッジ)か、上流APIの遅さを疑います。 - 最初が502か503、2回目が200:起動中にプラットフォームがエラーを返しています。Railwayは「スリープ中のサービスへの最初のリクエストは502 Bad Gatewayを返すことがある」と明記しています。
サーバー自身の起動時間をプラットフォームと切り分けるには、ローカルでstdio経由の起動時間を測ります。次のスクリプトはコマンドを起動して initialize を送り、最初の応答までの時間を表示します。4章の計測にはこのスクリプトを使いました。
# coldstart.py - stdioでプロセス起動から最初のMCP応答までを計測
import json, subprocess, sys, time, statistics
INIT = {"jsonrpc": "2.0", "id": 1, "method": "initialize",
"params": {"protocolVersion": "2025-06-18", "capabilities": {},
"clientInfo": {"name": "bench", "version": "0"}}}
def once(cmd: str) -> float:
t0 = time.perf_counter()
p = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)
p.stdin.write((json.dumps(INIT) + "\n").encode()); p.stdin.flush()
p.stdout.readline()
elapsed = (time.perf_counter() - t0) * 1000
p.kill(); p.wait()
return elapsed
cmd, runs = sys.argv[1], int(sys.argv[2])
times = [once(cmd) for _ in range(runs)]
print(f"median {statistics.median(times):.0f} ms runs {[round(t) for t in times]}")
python3 coldstart.py "npx -y @modelcontextprotocol/server-memory" 7
python3 coldstart.py "node node_modules/@modelcontextprotocol/server-memory/dist/index.js" 7
4. 実測:起動コマンドで初回応答はどれだけ変わるか
同じサーバーでも、起動コマンドを変えるだけで最初の initialize 応答までの時間が最大44倍変わりました。2vCPUのLinuxコンテナで、公式のリファレンスサーバー2つを計測しています(2026年10月17日)。各行は5〜7回の中央値です。「キャッシュなし」は毎回npmまたはuvのキャッシュを消してから測った値で、新しいコンテナがコールドスタートのたびに置かれる状態と同じです。
| サーバー | 起動コマンド | 最初の応答までの中央値 | 補足 |
|---|---|---|---|
| server-memory 1.0.0(Node.js) | node …/dist/index.js(インストール済み) |
171ms | 基準 |
| server-memory 1.0.0 | npx -y …@1.0.0、npmキャッシュあり |
960ms | npxの解決だけで+789ms |
| server-memory 1.0.0 | npx -y …(バージョン固定なし)、キャッシュあり |
1,032ms | 初回はレジストリ確認で2,733ms |
| server-memory 1.0.0 | npx -y …@1.0.0、キャッシュなし |
7,550ms | コールドスタートのたびにダウンロード |
| mcp-server-fetch 2026.10.10(Python) | インストール済み、2回目以降 | 503ms | 基準 |
| mcp-server-fetch | バイトコードなしでインストール、初回起動 | 1,199ms | 初回importで .pyc を生成 |
| mcp-server-fetch | --compile-bytecode 付きでインストール、初回起動 |
476ms | 初回から2回目以降と同等 |
| mcp-server-fetch | uvx …、uvキャッシュあり |
564ms | |
| mcp-server-fetch | uvx …、キャッシュなし |
7,173ms | 5回で3.3〜49秒とばらつく |
| server-memory+supergateway 4.2.0(ステートレス) | HTTPで initialize をPOST |
1リクエストあたり194ms | POSTごとに子プロセスを起動 |
数字から言えることは次の5つです。
- 本番の起動コマンドで
npx -yやuvxを使わない。新しいコンテナはキャッシュが空なので、コールドスタートのたびにダウンロードが走ります。しかもダウンロード時間は一番ばらつく部分です(同じパッケージで3.3秒〜49秒)。ビルド時にインストールし、実行ファイルを直接起動します。 - バージョンを固定する。固定しない
npx -yは新しい版がないかレジストリに確認するため、初回は約1.7秒余計にかかりました。 - Pythonはイメージ作成時にバイトコードをコンパイルしておく。uvのDockerガイドは、バイトコードのコンパイルは「起動時間を改善する傾向がある(インストール時間とイメージサイズの増加と引き換えに)」としています。今回は初回起動が約720ms短くなりました。
UV_COMPILE_BYTECODE=1かuv pip install --compile-bytecode、pipならpython -m compileallをビルド時に実行します。 - ステートレスなブリッジは、毎回ランタイムの起動分を払う。194msなら問題ありませんが、起動に1.5秒かかるサーバーなら、すべてのツール呼び出しが1.5秒遅くなります。
- Nodeのコンパイルキャッシュは、この小さなサーバーには効かなかった。
NODE_COMPILE_CACHEを使っても中央値は174msから169msでした。大きなバンドルでは効く場合もあるので、まず測ります。
計測環境はHTTPSプロキシ経由なので、ダウンロード時間の絶対値は環境によって変わります。参考にしてほしいのは行と行の比率です。
起動を速くするDockerfileの例です。
# ブリッジ経由のNode.js stdioサーバー:すべてビルド時にインストール
FROM node:22-slim
RUN npm install -g supergateway@4.2.0 @modelcontextprotocol/server-memory@1.0.0
CMD ["supergateway", "--stdio", "mcp-server-memory", \
"--outputTransport", "streamableHttp", "--stateful", \
"--sessionTimeout", "600000", "--port", "8000"]
# Pythonサーバー:uvでインストールし、バイトコードを事前コンパイル
FROM python:3.13-slim
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
ENV UV_COMPILE_BYTECODE=1
RUN uv pip install --system mcp-proxy mcp-server-fetch==2026.10.10
CMD ["mcp-proxy", "--host", "0.0.0.0", "--port", "8080", \
"--pass-environment", "mcp-server-fetch"]
自作サーバーのコードでも考え方は同じで、最初の応答までにやることを最小にします。DB接続、大きなカタログの読み込み、上流APIの認証は、import時ではなく、それを必要とする最初のツール呼び出しで行います。
5. プラットフォーム別の対策
主要なプラットフォームには、コールドスタートを短くするか無くす設定がありますが、その多くは待機中にも費用がかかります。2026年10月時点の公式ドキュメントの記述をまとめます。
| プラットフォーム | アイドル時の挙動 | 公式の起動時間の記述 | 効く設定 | 対策の待機コスト |
|---|---|---|---|---|
| Google Cloud Run | 既定でスケールtoゼロ | イメージとランタイム次第 | --min 1(最小インスタンス)、--cpu-boost |
最小インスタンスは待機中も課金(リクエストベース課金なら低い料金) |
| AWS Lambda | 実行環境が回収される | SnapStartで「数秒から1秒未満まで」 | SnapStart(Python、.NET、Java。2026年9月からコンテナイメージにも対応)、プロビジョニング済み同時実行 | SnapStartは別料金、プロビジョニング済み同時実行は待機中も課金 |
| Cloudflare Workers | isolate方式 | isolateは「コンテナやVM上のNodeプロセスより約100倍速く起動」 | isolate自体には不要 | なし。ただしstdioや任意のバイナリは動かない |
| Vercel(Fluid compute) | インスタンスは縮小する | 数値の記載なし | バイトコードキャッシュ(Node.js 20以上、本番のみ)と本番デプロイの事前ウォームアップ。どちらも自動 | 自動機能には追加費用なし |
Fly Machines(Fly.io) |
auto_stop_machines で停止またはsuspend |
suspendからの復帰は「数百ミリ秒」、stop/startは「2秒以上」 | auto_stop_machines = "suspend"(2GBまでのマシン) |
suspend中は課金なし |
| Railway(サーバーレス) | 最後の送信トラフィックから5〜10分でスリープ | コールドブートあり。最初のリクエストは「502を返すことがある」 | スリープを無効化 | 起動中は課金 |
| Render(無料) | 受信トラフィックが15分ないと停止 | 「約1分」 | 有料のインスタンスタイプ | 有料インスタンスは常時課金 |
MCPで使うときの注意点です。
- Cloud Runのstartup CPU boostは「インスタンスの起動中と、起動後10秒間に追加のCPUを与える」機能です(CPU上限1以下なら2vCPU)。Pythonのimportのように、CPUで詰まる起動を短くします。ダウンロードには効きません。
- Cloud Runの最小インスタンスは「ベストエフォート」です。容量不足、再配置、クラッシュなどで一時的に下回ることがあるとGoogleは書いているので、
--min 1でもクライアントのタイムアウトは余裕を持たせます。 - SnapStartは初期化済みの環境をスナップショットします。初期化中に張ったDB接続、乱数のシード、期限付きの認証情報もスナップショットから戻るので、接続は遅延させて張り直します。
- Railwayが見るのは受信ではなく送信トラフィックです。DB接続を保持したりテレメトリを送ったりするサーバーはスリープしないことがあり、その場合コールドスタートは起きませんが、節約にもなりません。
- Renderの約1分の起動は、たいていのMCPクライアントのタイムアウト(6章)を超えます。無料プランは検証には使えますが、Codexやエージェントから接続するサーバーには向きません。
stdio対応・認証・料金も含めたホスティング先の比較は「MCPサーバーホスティングのおすすめランキング」にまとめています。
6. クライアントは何秒待つか(タイムアウト一覧)
コールドスタートがエラーになるのは、クライアントのタイムアウトより長いときだけです。なので2つの数字を直接比べます。2026年10月時点で公式ドキュメントかソースコードで確認できた既定値は次のとおりです。
| クライアント・ライブラリ | 設定 | 既定値 | 効いてくる場面 |
|---|---|---|---|
| Codex CLI | startup_timeout_sec |
10秒 | 初回利用時のサーバー起動 |
| Codex CLI | tool_timeout_sec |
60秒 | 各ツール呼び出し |
| MCP TypeScript SDK 1.32.1 | DEFAULT_REQUEST_TIMEOUT_MSEC |
60,000ms | SDKで作った自作エージェントのすべてのリクエスト |
| Gemini CLI | timeout |
600,000ms | 各リクエスト |
| Claude Code | MCP_TIMEOUT(環境変数、ミリ秒) |
ドキュメントに記載なし | サーバー起動 |
使い方は3つです。
- 実用上の目標は10秒未満です。ここで一番厳しい既定値がCodexの起動タイムアウトだからです。キャッシュなしの
npx -y(7.5秒+プラットフォームの起動)やRenderの無料プランはこれを超えます。 - 縮められない場合はクライアント側で延ばします。Codexは
config.tomlでstartup_timeout_sec = 30、Claude CodeはMCP_TIMEOUT=30000、TypeScript SDKはリクエストオプションで{ timeout: 30000 }を指定します。 - エージェントが必要とする前に起こしておきます。自作エージェントならタスク開始時に
tools/listを1回送れば、コールドスタートをモデルの最初の推論と並行させられます。
各クライアントの設定ファイルの場所は「リモートMCPクライアント設定チートシート」にまとめています。
7. 常時起動か、スケールtoゼロか:コスト計算
メモリ×時間で課金されるプラットフォームでは、1台を常時起動しておくと、呼ばれても呼ばれなくても「メモリ×730時間」が毎月かかります。スケールtoゼロなら、使っている時間と、使い始めごとのコールドスタート1回分だけです。
| 構成 | 月間GB時間 |
|---|---|
| 512MB、スケールtoゼロ、1日2時間稼働(約60時間) | 約30 |
| 512MB、スケールtoゼロ、1日8時間稼働(約240時間) | 約120 |
| 512MB、常時起動(約730時間) | 約365 |
| 1GB、常時起動 | 約730 |
数分おきにcronでpingしてウォームに保つ方法は、たいていのプラットフォームでは常時起動と同じ費用になります。インスタンスが停止するほど長くアイドルにならないからです。プラットフォーム標準の設定より安い場合に限って使います。
判断の目安です。
- スケールtoゼロを選ぶのは、使い方が断続的で、コールドスタートがクライアントのタイムアウトより短い場合です。まず起動コマンドを直します(4章)。これは無料でできます。
- 1台を常時起動するのは、最初の呼び出しが即答でなければならない場合(ユーザーが待つエージェントなど)、変更できないタイムアウトをコールドスタートが超える場合、作り直すのが重い接続やキャッシュをサーバーが持つ場合です。
- プラットフォームがスナップショットやsuspendからの復帰に対応しているなら、常時起動より先に検討します。待機課金なしで、プラットフォームとランタイムの起動の大半を省けます。
8. チェックリスト
- [ ]
curl -wで1回目と2回目のtools/listを測り、コールドスタートが何秒か把握している - [ ] 起動コマンドに
npx -y、uvx、インストール処理が含まれていない - [ ] サーバーとブリッジのバージョンを固定している
- [ ] Pythonのイメージを
UV_COMPILE_BYTECODE=1かcompileall付きでビルドしている - [ ] DB接続や大きなカタログは、import時ではなく初回利用時に読み込んでいる
- [ ] ステートレスなブリッジは、起動の速いサーバーにだけ使っている
- [ ] コールドスタートが、すべてのクライアントのタイムアウトより短い(Codexの起動は既定10秒)
- [ ] プラットフォームの起動設定(最小インスタンス、SnapStart、suspend、常時起動)を意図して選んでいる
- [ ] 常時起動のGB時間と、実際の稼働時間を比べた
- [ ] 再デプロイ直後の最初のリクエストが、リトライなしで成功する
9. トラブルシューティング(症状→原因→対処)
| 症状 | 原因 | 対処 |
|---|---|---|
| 初回だけ「接続に失敗」し、再試行で動く | コールドスタートがクライアントの起動タイムアウトより長い | 起動を短くする(4章)か、startup_timeout_sec / MCP_TIMEOUT を延ばす |
| 初回が5〜50秒かかり、毎回ばらつく | npx -y や uvx がコールドスタートのたびにダウンロードしている |
ビルド時にインストールし、実行ファイルを直接起動 |
| デプロイ直後の初回だけ遅く、その後は速い | キャッシュが空で、.pyc を初回生成している |
バイトコードを事前コンパイルし、バージョンを固定 |
| 初回だけでなく毎回遅い | ステートレスなブリッジがリクエストごとにプロセスを起動、または上流APIが遅い | ステートフルなブリッジかネイティブHTTPにする。上流のレイテンシを確認 |
| 初回が502、2回目は200 | 起動中にプラットフォームがエラーを返す(Railwayは明記) | クライアントで1回リトライするか、スリープを無効化 |
| 初回が約1分止まる | 無料プランの復帰待ち(Renderは「約1分」) | 有料インスタンスにするか、復帰の速いホストへ |
| 最小インスタンスを設定しても遅いことがある | 最小インスタンスはベストエフォートで、インスタンスが入れ替わった | タイムアウトに余裕を持たせ、プラットフォームのイベントを確認 |
| 復帰直後にDBエラーが出る | スナップショットから戻った接続、またはimport時に張った接続が古い | 接続は遅延して張り、エラー時に再接続 |
| アイドル後にクライアントでツールが0個になる | 起動中に tools/list がタイムアウトした |
1行目と同じ |
10. NodeFlareならこう解決できる
NodeFlareは、GitHubリポジトリにあるMCPサーバー(stdio専用のものも含む)を、https://<your-server>.nodeflare.tech/mcp のHTTPSエンドポイントとしてデプロイするMCP Hostingサービスです。この記事で挙げた課題には、次のように対応しています。
| この記事で挙げた課題 | NodeFlareでの対応 |
|---|---|
| アイドル後のプラットフォームの起動時間 | サーバーごとに専用のFirecracker microVMで動作します。数分アイドルが続くとVMをスナップショットして停止し、次のリクエストでスナップショットから1秒未満で復元します |
| 最初の呼び出しを即答させたい | Always-On(Pro以上)でウォームなレプリカを1台維持し、コールドスタートをなくせます。待機時間は課金されます |
起動時の npx -y / uvx、Dockerfileの手書き |
ビルダーがリポジトリからランタイム、トランスポート、起動コマンドを検出します。Dockerfileやコードの変更は不要です |
| stdioサーバーにはブリッジが必要 | 同梱のアダプター(stdio-adapter.cjs)がstdioサーバーをHTTPで包みます |
| デプロイ後に「本当に起動したか」分からない | 実際のMCP initialize ハンドシェイクに正しい応答が返って初めてデプロイ成功になります(バックオフ付きで最大8回再試行) |
| 新旧のクライアントが混在する | Streamable HTTPに加え、旧来のHTTP+SSE(2024-11-05)にも対応します |
| 起動時のクラッシュ | クラッシュ時の再起動は1秒から30秒まで間隔を延ばしながら行います |
| 常時起動とスケールtoゼロのコスト | コンピュートは1 GB時間あたり5円で、スケールtoゼロで停止中は0円です。メモリは256MB、512MB、1GB、2GBから選べます。月の上限額に達するとHTTP 402でサーバーを一時停止するスペンドリミットもあります |
料金:Freeプランは0円で、MCPサーバー1つ、月30 GB時間のコンピュート、スケールtoゼロ付きです。Proは月2,980円で、サーバー数無制限、コンピュート300 GB時間とストレージ10GBが含まれます。
最小の始め方:
- nodeflare.techにサインインし、MCPサーバーのGitHubリポジトリを選ぶ。
- 環境変数を入れてデプロイする。NodeFlareが
initializeを確認してから公開する。 /mcpのURLとAPIキーをClaude、Cursor、自作エージェントに設定し、3章のcurlで復帰時間を自分で確かめる。
1サーバーまで無料で試せます → nodeflare.tech
よくある質問
MCPサーバーのコールドスタートとは?
動いているインスタンスがないMCPサーバーに最初のリクエストが届いたとき、マシンの起動、ランタイムの起動、サーバーの初期化を待つ追加の遅延です。アイドル後にクライアントが接続したとき、initialize や tools/list が遅くなる形で現れます。
ホスティングしたMCPサーバーの最初の呼び出しが遅いのはなぜ?
多くの場合、起動コマンドがパッケージを取得している(npx -y や uvx)か、プラットフォームがインスタンスを作成・復帰させているためです。今回の計測では、キャッシュなしの npx -y が7,550ms、インストール済みなら171msでした。curl -w で1回目と2回目を比べると、どの段階が原因か分かります。
MCPサーバーのコールドスタートを短くするには?
依存関係をビルド時にインストールし、バージョンを固定し、Pythonはバイトコードを事前コンパイルし、DB接続は最初のツール呼び出しまで遅らせます。そのうえで、スナップショットやsuspendからの復帰、最小インスタンス、常時起動から、用途に合う起動方式を選びます。
本番でnpxやuvxを使ってMCPサーバーを起動してよい?
おすすめしません。どちらもプロセス起動時にパッケージを解決し、多くの場合ダウンロードするため、コールドスタートのたびにインストールが走ります。イメージにパッケージを入れておき、実行ファイルを直接起動します。npx -y と uvx はローカル用と考えます。
Cloudflare WorkersのMCPサーバーにコールドスタートはある?
WorkersはV8のisolateで動き、Cloudflareは「コンテナやVM上のNodeプロセスより約100倍速く起動する」としているので、コールドスタートが問題になることはまれです。その代わりstdioサーバーや任意のバイナリは動かせないため、GitHubにある多くのMCPサーバーは書き直しが必要です。
Cloud RunでMCPサーバーのコールドスタートをなくすには?
gcloud run services update SERVICE --min 1 で最小インスタンスを1にし、--cpu-boost で起動を速くします。最小インスタンスは待機中も課金され、「ベストエフォート」なので、クライアントのタイムアウトには余裕を持たせます。
CodexはMCPサーバーの起動を何秒待つ?
既定では起動に10秒(startup_timeout_sec)、ツール呼び出し1回に60秒(tool_timeout_sec)です。コールドスタートがそれより長い場合は、config.toml の [mcp_servers.<name>] で startup_timeout_sec を延ばします。
MCP TypeScript SDKの既定のリクエストタイムアウトは?
60,000msです。バージョン1.32.1では DEFAULT_REQUEST_TIMEOUT_MSEC = 60000 が定義され、リクエストオプションで timeout を渡さない限りすべてのリクエストに適用されます。SDKで作ったエージェントは、1分を超えるコールドスタートで失敗します。
MCPサーバーは常時起動にすべき?
最初の呼び出しを即答させたい場合か、変更できないタイムアウトをコールドスタートが超える場合に限ります。512MBを1か月常時起動すると約365 GB時間で、1日2時間だけ動いてスケールtoゼロするなら約30 GB時間です。
定期的なpingでコールドスタートは防げる?
防げますが、メモリ×時間の課金では常時起動とほぼ同じ費用になります。インスタンスが停止するほど長くアイドルにならないからです。プラットフォーム標準の最小インスタンス、suspend、常時起動の設定を使うほうが分かりやすく管理できます。
まとめ
MCPサーバーのコールドスタートは複数の段階の合計で、一番大きいのはたいてい自分で招いている「起動時のパッケージ取得」です。ビルド時にインストールしてバージョンを固定し、Pythonはバイトコードを事前コンパイルし、初期化を遅らせれば、サーバー自身の起動は数百ミリ秒まで縮みます。残るのはプラットフォームの起動時間で、受け入れる(スナップショットやsuspendなら短い)、お金を払って消す(最小インスタンス、常時起動)、クライアントのタイムアウトを延ばして吸収する、のいずれかで対応します。変更の前後で curl -w で測り、対応したいクライアントの中で一番厳しいタイムアウトより短く保ちます。
参考資料
- MCP Specification 2026-07-28: Key Changes
- MCP TypeScript SDK(GitHub)
- Google Cloud Run:最小インスタンスの設定
- Google Cloud Run:CPU上限とstartup CPU boostの設定
- AWS:Lambda SnapStartのコンテナイメージ対応(2026年9月)
- Cloudflare Workers:How Workers works
- Vercel:Fluid compute
- Fly Machines:Suspend and resume
- Railway:App sleeping
- Render:Deploy for free
- uv:Using uv in Docker
- OpenAI Codex:MCPの設定
