MCP Hostingのメモリ設計:MCPサーバーに必要なRAMを10種類・npx/uvx・ブリッジ別に実測【2026年版】
MCPサーバーに必要なメモリを10種類で実測。待機中61〜105 MB、npx・uvxで約45〜50 MB増、supergateway・mcp-proxyで125〜140 MB、ステートフルは1セッション約40 MB増、fetchはピーク348 MB。Cloud Run・Lambda・Workersの上限、1.5倍ルールでの段階選び、GB時間の料金計算、測定スクリプトまで解説。
最終更新:2026年10月28日 / 対象:
@modelcontextprotocol/server-everything2.0.1、server-filesystem2.0.1、server-memory2.0.0、server-sequential-thinking2.0.0、@upstash/context7-mcp4.4.4、mcp-server-time・mcp-server-git2026.10.19、mcp-server-fetch2026.10.24、MCP TypeScript SDK 1.32.2、MCP Python SDK 2.3.0、supergateway 4.2.1、mcp-proxy 0.13.0。検証は2026年10月28日、2 vCPU・メモリ8 GBのLinux、Node.js 24.22.1、Python 3.13.18、uvで実施。
結論(30秒で読める要約)
MCPサーバーのメモリとは、サーバーを動かしている間にプロセスツリー全体が使うRAMのことです。サーバー本体だけでなく、起動に使うランチャー(npx、uvx)、HTTP化のためのブリッジ(supergateway、mcp-proxy)、ツールが呼び出す補助プロセスも含みます。MCP Hostingでは、この値で必要なインスタンスサイズが決まり、メモリ×時間で課金されるサービスでは料金の大半もここで決まります。
10種類のサーバーを各3回ずつ測った結果は次のとおりです。
- 一般的なMCPサーバーは待機中60〜105 MBでした。Pythonのサーバー(
time、git、Python SDKの最小サーバー)はPSSで61〜70 MB、Node.jsのサーバー(filesystem、memory、everything、sequential-thinking、TypeScript SDKの最小サーバー)は73〜84 MB。最も重いContext7でも104〜105 MBです。ツールを50回呼んでも増加は0〜7 MBにとどまりました。 - npxとuvxは、常に払い続ける「上乗せ」です。
npx -yで起動したfilesystemサーバーは、3プロセスで127〜129 MB(直接起動なら1プロセスで78〜79 MB)。uvx経由のtimeサーバーは62 MBから106〜107 MBに増えました。ランチャーはサーバーが動いている間ずっと常駐します。 - ブリッジは何もしなくても125〜140 MBを使い、ステートフルなものはセッションごとに増えます。supergateway単体で133〜138 MB。ステートフルモードでは接続1つにつき約40 MB増え、4セッションで294 MBになりました。mcp-proxyは子プロセスを1つ共有するため、1セッションでも4セッションでも125〜134 MBのままでした。
- ピークを作るのは呼び出し回数ではなく、データの大きさと補助プロセスです。
mcp-server-fetchは、PATHにnodeがあるとReadability.jsを動かすためにNode.jsを起動するので、取得のたびに76 MBから312〜348 MBへ跳ね上がりました。20 MBのファイルを読むとfilesystemサーバーは368 MBまで上がり、2,000件のエンティティを持つmemoryサーバーは219 MBを保ちました。 - サイズの決め方は「実測ピークの1.5倍以上で、いちばん小さい段階」です。軽いサーバーを直接起動するなら256 MBで足ります。npx・uvx・ブリッジを使うなら512 MBを見込みます。ブラウザを動かすサーバーは1 GB以上です。
実測の一覧は3章、ランチャーとブリッジの上乗せは4・5章、サイズの選び方と料金の計算は8・9章にあります。
目次
- 「MCPサーバーのメモリ」とは何を指すか
- 測定方法
- 実測:10種類のMCPサーバーのメモリ
- ランチャーの上乗せ:npxとuvx
- ブリッジ:supergateway(ステートレス・ステートフル)とmcp-proxy
- メモリが跳ね上がる原因
- プラットフォームごとのメモリの下限と上限
- サイズの決め方と段階の選び方
- メモリの料金:GB時間の計算
- 自分のサーバーを測る
- チェックリスト
- よくあるハマりどころ(症状→原因→対処)
- NodeFlareならこう解決できる
- FAQ
1. 「MCPサーバーのメモリ」とは何を指すか
MCPサーバーに必要なメモリとは、プロセスツリー全体が使う常駐メモリのピーク値です。パッケージのサイズでも、1プロセスのRAMでもありません。混同しやすい指標が3つあります。
| 指標 | 数えるもの | 使いどころ |
|---|---|---|
| RSS(常駐セットサイズ) | プロセスがRAM上に持つすべてのページ(共有ライブラリを含む) | 1プロセスをざっと見るとき。複数プロセスを足すと重複して多めに出る |
| PSS(比例配分セットサイズ) | RSSと同じだが、共有ページは共有しているプロセス間で按分する | プロセスツリー(サーバー+ランチャー+子プロセス)の合計。本記事はこの値を使う |
| コンテナ(cgroup)のメモリ | カーネルがコンテナに計上するすべて。読んだファイルのページキャッシュも含む | Docker、Kubernetes、多くのホスティングが上限と比べる値 |
ホスティングで効いてくるのは次の2点です。
- ツリー全体を数えます。
npxはサーバーの上にnpm execとシェルを残します。ブリッジはもう1つのランタイムです。ツールの呼び出しごとに子プロセスを起動するサーバーもあります。プラットフォームはこれらをすべて同じ上限で数えます。 - 待機時ではなくピークに合わせます。上限を超えたコンテナは止められます。Kubernetesは、コンテナは「上限を超えるメモリを使うことは許されない」と明記し、Cloud Runも上限を超えたインスタンスは終了されると書いています。大きなツール結果が1回返るだけで起こりえます。
2. 測定方法
各サーバーを、Claude Codeやブリッジと同じようにstdioで起動し、小さなPythonクライアントから操作しました。サーバーとすべての子孫プロセスについて /proc/<pid>/smaps_rollup を読んでいます。
| 段階 | クライアントの操作 | 記録した値 |
|---|---|---|
| 起動 | initialize(プロトコル 2025-11-25)、notifications/initialized、tools/list |
3秒後の待機時PSS・RSSとプロセス数 |
| 負荷 | 代表的な読み取りツールを50回(fetch は10回) |
50ミリ秒ごとに測ったPSSの最大値 |
| 負荷後 | 2秒待つ | 負荷直後のPSS |
4章でランチャーを比べる場合を除き、サーバーは事前にインストールし、ランタイムから直接起動しました(node dist/index.js、または仮想環境のエントリーポイント)。各構成を3回ずつ実行し、表には範囲を載せています。測定中のマシンはほかに負荷のない状態で、すべてのツール呼び出しが成功しました。
3. 実測:10種類のMCPサーバーのメモリ
ほとんどのMCPサーバーは待機中60〜105 MBで、軽いツール呼び出しを繰り返してもほぼ増えません。
| サーバー(バージョン) | ランタイム | ツール数 | 待機時PSS | 待機時RSS | 呼び出し中のピークPSS | 負荷後 | 負荷の内容 |
|---|---|---|---|---|---|---|---|
Python SDKの最小サーバー(mcp 2.3.0) |
Python | 1 | 61〜70 MB | 66〜75 MB | 61〜70 MB | 61〜70 MB | hello を50回 |
mcp-server-time 2026.10.19 |
Python | 2 | 62 MB | 67 MB | 62 MB | 62 MB | get_current_time を50回 |
mcp-server-git 2026.10.19 |
Python | 12 | 64 MB | 69 MB | 65 MB | 65 MB | git_status を50回 |
| TypeScript SDKの最小サーバー(SDK 1.32.2) | Node.js | 1 | 73〜74 MB | 75〜76 MB | 74 MB | 74 MB | hello を50回 |
server-sequential-thinking 2.0.0 |
Node.js | 1 | 75〜76 MB | 77〜78 MB | 78〜79 MB | 78〜79 MB | sequentialthinking を50回 |
mcp-server-fetch 2026.10.24 |
Python(+Node.jsの補助) | 1 | 76 MB | 81 MB | 312〜348 MB | 99 MB | PyPIのページを fetch で10回 |
server-memory 2.0.0 |
Node.js | 9 | 77 MB | 79 MB | 84 MB | 84 MB | create_entities を50回 |
server-filesystem 2.0.1 |
Node.js | 14 | 78〜79 MB | 80〜81 MB | 84 MB | 84 MB | 27 KBのファイルを read_text_file で50回 |
server-everything 2.0.1 |
Node.js | 16 | 82 MB | 84 MB | 84 MB | 84 MB | echo を50回 |
@upstash/context7-mcp 4.4.4 |
Node.js | 2 | 104〜105 MB | 106〜107 MB | 104〜105 MB | 104〜105 MB | 起動と一覧取得のみ(ツールは外部APIを呼ぶため) |
読み取れること:
- 下限を決めるのはランタイムです。ほぼ空のNode.jsサーバー(TypeScript SDK)でも約73 MB、ほぼ空のPython SDKサーバーで約61 MBあります。その上に載せるツールのコストはずっと小さく、filesystemの14個のツールでも最小サーバーより約5 MB多いだけでした。
- 小さな呼び出しを繰り返してもリークしません。50回呼んでも、どのサーバーも0〜7 MBしか動きませんでした。
- ツールの数より依存ライブラリが効きます。Context7はツール2つですが、Node.jsのサーバーでいちばん重く、最小サーバーより約30 MB多く使いました。
- fetchサーバーだけは例外です。待機中は軽いのに、動くと重くなります。理由は6章で説明します。
4. ランチャーの上乗せ:npxとuvx
npx -y や uvx で起動すると、サーバーが動いている間ずっと残るプロセスが1つ増え、PSSで約45〜50 MB上乗せされます。
| 起動コマンド | プロセス数 | 待機時PSS | 待機時RSS | initialize の応答までの時間(キャッシュあり) |
|---|---|---|---|---|
node .../server-filesystem/dist/index.js |
1 | 78〜79 MB | 80 MB | 0.18〜0.24秒 |
npx -y @modelcontextprotocol/server-filesystem@2.0.1 |
3(npm exec、sh、node) |
127〜129 MB | 177〜178 MB | 0.63〜0.67秒 |
.venv/bin/mcp-server-time |
1 | 62 MB | 67 MB | 0.68〜0.73秒 |
uvx mcp-server-time==2026.10.19 |
2(uv、python) |
106〜107 MB | 113〜114 MB | 0.73〜0.84秒 |
起動時間は、パッケージがすでにnpmやuvのキャッシュにある状態での値です。新しいコンテナでは、コールドスタートのたびにnpxやuvxがパッケージをダウンロードするので、さらに通信の時間がかかります。
起動コマンドを自分で決められるなら、対処は簡単です。ビルド時にイメージへインストールし、エントリーポイントを直接起動します。
# Node.js:一度インストールして、npxなしで起動
FROM node:24-slim
RUN npm install -g @modelcontextprotocol/server-filesystem@2.0.1
CMD ["mcp-server-filesystem", "/data"]
# Python:イメージにインストールして、uvxなしで起動
FROM python:3.13-slim
RUN pip install --no-cache-dir mcp-server-time==2026.10.19
CMD ["mcp-server-time"]
手元のPCなら、50 MBは気にならず自動更新も便利なので、npxやuvxで構いません。ただ256 MBのインスタンスでは、同じ50 MBが上限の5分の1にあたります。
5. ブリッジ:supergateway(ステートレス・ステートフル)とmcp-proxy
stdioにしか対応しないサーバーをHTTPで公開するにはブリッジが必要で、そのメモリはセッションとプロセスの対応のさせ方で決まります。filesystemサーバー(node で直接起動)を各ブリッジで包み、Streamable HTTPのクライアントを1つまたは4つ接続しました。各クライアントはツールを10回呼び、接続したままにしています。
| ブリッジとモード | ブリッジのみ | 1セッション | 4セッション | 4セッション時のプロセス数 | 4セッション×11リクエストの所要時間 |
|---|---|---|---|---|---|
| supergateway 4.2.1、ステートレス | 134〜138 MB | ピーク174〜181 MB | ピーク183〜202 MB | リクエストの合間は1 | 9.65〜10.44秒 |
supergateway 4.2.1、--stateful |
133〜138 MB | 171〜175 MB | 294 MB | 9(ブリッジ+sh×4+サーバー×4) |
1.25〜1.27秒 |
| mcp-proxy 0.13.0 | 125〜131 MB(子プロセス1つを含む) | 129〜134 MB | 133〜134 MB | 2 | 0.29〜0.30秒 |
見方:
- supergatewayのステートレスモードは、リクエストのたびにサーバーのプロセスを新しく起動します。そのためリクエストの合間のメモリは横ばいで、子プロセスが動く間だけピークが出ます。代わりに毎回起動の時間がかかり、今回は1リクエストあたり約0.22〜0.24秒でした(プロセスを使い回す場合は約0.03秒)。
- supergatewayのステートフルモードは、セッションごとにサーバーのプロセスを1つ持ち続けます。そのため接続しているクライアント1つにつき約40 MBずつ増え、セッションがタイムアウトするまで減りません。待機中のセッションが10あれば、約400 MB増える計算です。
- mcp-proxyは子プロセスを1つだけ起動してセッション間で共有するので、クライアント数が増えてもメモリはほとんど変わりません。その代わり、セッション同士がその1プロセスの状態を共有します。
どのブリッジがどのサーバーに合うか、それぞれがソースコード上でプロセスをどう扱っているかは、stdioのMCPサーバーをリモートで動かす方法で解説しています。
6. メモリが跳ね上がる原因
ピークの原因は、大きなデータ、ツールが起動する補助プロセス、サーバーがメモリに抱えるデータの3つです。
| 原因 | 観測したこと | 理由 | 対処 |
|---|---|---|---|
| 呼び出しごとの補助プロセス | mcp-server-fetch が取得のたびに76 MBから312〜348 MB(2プロセス)に増えた |
HTMLをMarkdownに変換する処理が readabilipy を use_readability=True で呼び、Node.jsがあれば node でMozillaのReadability.jsを動かすため |
ピークに合わせてサイズを決める。PATHに node がなければ約101 MBで済んだが、その場合 readabilipy はPythonだけの抽出処理に切り替わり、今回の検証では出力がかなり粗くなった |
| 大きなツール結果 | 20 MBのファイルを read_text_file で読むと、ピーク368 MB、その後167 MB |
ファイルを文字列として保持し、さらにJSON-RPCのメッセージに変換するため | ファイルサイズを制限する。サーバーに head・tail の引数があれば使う |
| メモリに抱えるデータ | server-memory にエンティティ2,000件(2.1 MBの memory.jsonl)を入れると219 MBになり、そのまま下がらなかった |
呼び出しのたびにナレッジグラフを読み込んで答えるため | データとともに増えることを見込み、長く使うグラフには大きめの段階を選ぶ |
| ブラウザ | 以前の検証で、Playwright MCPはクライアント1つで413〜439 MB、4つで586 MB | セッションごとにChromiumを動かすため | Playwright MCPをリモートでホスティングする方法を参照 |
大きなツール結果は、サーバーのRAMとモデルのコンテキストの両方を消費します。結果を小さくする方法はMCPツールの応答によるトークン消費にまとめています。
7. プラットフォームごとのメモリの下限と上限
どのプラットフォームにも選べる最小サイズがあり、多くの場合、実際の使用量ではなくそのサイズに対して課金されます。
| プラットフォーム | 設定できる最小メモリ | 最大 | 上限を超えたとき | 課金の基準 |
|---|---|---|---|---|
| Google Cloud Run(サービス) | 第1世代128 MiB、第2世代512 MiB。既定値512 MiB | 32 GiB | 上限を超えたインスタンスは終了される | 割り当てたメモリ(課金対象の時間中) |
| AWS Lambda | 128 MB(既定値も同じ)、1 MB単位 | 10,240 MB | 呼び出しがメモリ不足のエラーで失敗する | 設定メモリ×実行時間。CPUはメモリに比例(1,769 MBで1 vCPU相当) |
| Cloudflare Workers | 固定。1つのisolateが使えるのは最大128 MB | 128 MB | Error 1102「Worker exceeded resource limits」。新しいisolateが起動する | リクエスト数とCPU時間(メモリではない) |
| Kubernetes | resources.limits.memory に設定した値 |
ノードのサイズ | 上限を超えるメモリは使えず、OOM killされて(終了コード137)、再起動ポリシーに従う | ノード |
| VPS上のDocker | --memory、または無制限 |
VM | コンテナ内でOOM kill、またはVM全体がスワップする | VM |
補足:
- Cloudflare Workersは別のランタイムです。128 MBの上限はNode.jsのプロセスではなくV8のisolateに対するものです。3章のstdioサーバーはそのままでは動かないので、数値は当てはまりません。Workers向けに書かれたサーバーは、通常ずっと少ないメモリで動きます。
- LambdaのCPUはメモリに連動します。128 MBの関数に割り当てられるCPUは1 vCPUのごく一部なので、フルのコアで起動に0.7秒かかるPythonのサーバーは、さらに遅くなります。
8. サイズの決め方と段階の選び方
実際の使い方で測ったピークPSSの1.5倍以上になる、いちばん小さいサイズを選びます。残りの5割で、ガベージコレクションによる増減、コンテナに計上されるページキャッシュ、テストより大きな入力をカバーします。
| 構成 | 今回の検証でのピーク | 1.5倍の余裕を持たせた最小サイズ | 目安の段階 |
|---|---|---|---|
| 軽いサーバー1つを直接起動(PythonまたはNode.js) | 61〜105 MB | 92〜158 MB | 256 MB |
| サーバー1つをnpxまたはuvxで起動 | 106〜131 MB | 159〜197 MB | 256 MBでぎりぎり。入力の大きさが変わるなら512 MB |
| mcp-proxyの後ろのstdioサーバー(セッション数を問わない) | 129〜134 MB | 194〜201 MB | 256 MBでぎりぎり。512 MBを推奨 |
| supergateway(ステートレス)の後ろのstdioサーバー | 174〜202 MB | 261〜303 MB | 512 MB |
| supergateway(ステートフル)、4セッションまで | 175〜294 MB | 263〜441 MB | 512 MB |
Node.jsがある環境の mcp-server-fetch |
312〜348 MB | 468〜522 MB | 512 MBでぎりぎり。安全をとるなら1 GB |
| 大きなファイルを読む・大きなデータを抱えるサーバー | 219〜368 MB | 329〜552 MB | 512 MB〜1 GB |
| Playwright MCP、クライアント1〜4(以前の検証) | 413〜586 MB | 620〜879 MB | 1 GB |
| 重いサイトでブラウザのセッションを複数 | 要測定 | 要測定 | 2 GB |
これは下限の目安として使ってください。今回の入力は小さく、マシンもほかに負荷のない状態でした。最小のサイズを選ぶ前に、自分のツール呼び出しで実際に測ってください(10章)。
9. メモリの料金:GB時間の計算
メモリと時間でコンピュートを課金するプラットフォームの多くでは、MCPサーバーの月額はおおむね「割り当てたメモリ×稼働時間」です。トラフィックと同じくらい、選ぶサイズが効きます。
月のGB時間 = 割り当てたGB × 稼働時間
| 割り当てメモリ | 常時稼働(730時間) | 業務時間だけ(8時間×21.75日 ≒ 174時間) | 1日約2時間(≒ 61時間) |
|---|---|---|---|
| 256 MB | 182.5 GB時間 | 43.5 GB時間 | 15.2 GB時間 |
| 512 MB | 365 GB時間 | 87 GB時間 | 30.4 GB時間 |
| 1 GB | 730 GB時間 | 174 GB時間 | 61 GB時間 |
| 2 GB | 1,460 GB時間 | 348 GB時間 | 122 GB時間 |
測定結果から言えるコストへの影響:
- npxやuvxをやめるだけで料金が半分になることがあります。約50 MBの差が、256 MBに収まるか512 MBが必要かの分かれ目になりやすく、後者ならGB時間は2倍です。
- ステートフルなブリッジは、待機中のセッションをメモリに変えます。タイムアウトまで開いたままのセッション1つにつき40 MBを、誰もツールを呼んでいない間も払うことになります。
- サイズを小さくするより、スケールゼロのほうが効きます。512 MBを256 MBにすれば半分ですが、常時稼働を1日2時間にすれば約92%減ります。代わりにコールドスタートが発生します。短くする方法は最初のMCP呼び出しが遅い理由で解説しています。
10. 自分のサーバーを測る
実際のクライアントが実際の呼び出しをしている間に、プロセスツリー全体を測ります。次のスクリプトは、指定したプロセスとすべての子孫プロセスのPSSを1秒ごとに表示します。必要なのはLinuxとPython 3だけです。
#!/usr/bin/env python3
# mcp_mem.py PID - プロセスツリー全体のPSS/RSSを1秒ごとに表示(Linux)
import glob, sys, time
def tree(root):
parent = {}
for st in glob.glob("/proc/[0-9]*/stat"):
try:
data = open(st).read()
pid = int(data.split()[0]); ppid = int(data.rsplit(")", 1)[1].split()[1])
parent[pid] = ppid
except OSError:
pass
out = [root]
for p in out:
out += [c for c, pp in parent.items() if pp == p]
return out
def usage(root):
pss = rss = 0; n = 0
for p in tree(root):
try:
for line in open(f"/proc/{p}/smaps_rollup"):
if line.startswith("Pss:"): pss += int(line.split()[1])
elif line.startswith("Rss:"): rss += int(line.split()[1])
n += 1
except OSError:
pass
return pss / 1024, rss / 1024, n
peak = 0
while True:
pss, rss, n = usage(int(sys.argv[1]))
peak = max(peak, pss)
print(f"PSS {pss:6.0f} MB RSS {rss:6.0f} MB procs {n:2d} peak PSS {peak:6.0f} MB", flush=True)
time.sleep(1)
いちばん外側のプロセス(ブリッジ、npx、またはサーバー本体)のPIDを渡し、MCP Inspectorや自分のエージェントからサーバーを操作します。入力は、想定しうる最大のもの(最大のファイル、最長のページ、最大の検索結果)を使ってください。Dockerの中なら docker stats とも比べます。こちらはページキャッシュを含むコンテナのcgroupメモリを、上限と並べて表示します。
11. チェックリスト
- [ ] 1プロセスのRSSではなく、プロセスツリー全体のピークPSSを測った
- [ ] 実際のツール呼び出しと、想定しうる最大の入力で測った
- [ ] 本番では
npx -yやuvxではなく、インストール済みのエントリーポイントから起動している - [ ] ブリッジがリクエストごと・セッションごと・共有1プロセスのどれで動くか把握している
- [ ] ステートフルなブリッジにはセッションのタイムアウトを設定し、想定するセッション数でメモリを測った
- [ ] 補助プロセス(Node.js、ブラウザ、CLI)を起動するツールがないか確認した
- [ ] 選んだサイズは実測ピークの1.5倍以上ある
- [ ] プラットフォームの最小サイズと、上限に達したときの挙動を把握している
- [ ] サイズと実際の稼働時間からGB時間を見積もった
- [ ] サーバーや依存ライブラリを更新したら、メモリを測り直している
12. よくあるハマりどころ(症状→原因→対処)
| 症状 | 考えられる原因 | 対処 |
|---|---|---|
コンテナが終了コード137や OOMKilled で再起動する |
ピークが上限を超えた。大きなツール結果1回が原因のことが多い | 実際の入力でピークを測り、サイズを上げるか結果の大きさを制限する |
| 手元では動くのに、256 MBのインスタンスでOOMになる | npx・uvx の約50 MBと、ブリッジの分 |
イメージにインストールし、エントリーポイントを直接起動する |
| クライアントが増えるたびにメモリが増え、かなり後になって減る | supergatewayの --stateful がセッションごとにサーバーのプロセスを持つ |
--sessionTimeout を短くする、1プロセスを共有するブリッジに替える、または開いているセッション数に合わせてサイズを決める |
| メモリは少ないが、ツール呼び出しが毎回約0.2秒遅い | supergatewayのステートレスモードがリクエストごとにサーバーを起動している | メモリより起動時間を重視するなら、ステートフルモードかmcp-proxyを使う |
| fetchサーバーが、ページ取得のときだけ落ちる | Readability.jsのためのNode.jsの補助プロセス | 約350 MBを見込むか、PATHから node を外して粗い出力を受け入れる |
| memoryサーバーが毎週少しずつ大きくなる | ナレッジグラフをメモリに持ち、データとともに増える | グラフの大きさを見込む。古いデータを退避または分割する |
ps では問題ないのに、プラットフォームの表示は多い |
プラットフォームはページキャッシュや子プロセスを含むcgroup全体を数える | docker stats やプラットフォームのメモリ指標と比べる |
| Cloudflare WorkerがError 1102を返す | isolateの128 MBの上限 | 大きな結果はストリーミングやページングにする。重い処理はWorkerの外へ出す |
| 128 MBのLambdaでサーバーの起動が遅い | CPUがメモリに比例する | メモリを増やしてCPUを確保するか、コンテナのホスティングに移す |
13. NodeFlareならこう解決できる
NodeFlareは、GitHubのリポジトリからMCPサーバー(stdioにしか対応しないものを含む)を、認証付きのHTTPSエンドポイントとしてデプロイできるMCP Hostingサービスです。本記事で挙げたメモリの課題に、次のように対応します。
| 本記事の課題 | NodeFlareでの対応 |
|---|---|
| データがないうちにメモリのサイズを決めなければならない | サーバーごとに256 MB・512 MB・1 GB・2 GBから選べます(上限はプランによる)。右サイズの提案は、初期の安定化期間を除いた約1か月の使用状況と、直近でいちばん忙しかった1週間をもとに出されます。自動では適用されず、「適用」か「却下」を選びます |
| 小さくしすぎてOOMになる | 小さくしたサイズでメモリ不足が起きた場合は自動で元のサイズに戻り、そのサイズは再び提案されません |
| セッションごとにプロセスが増えるブリッジ | 同梱の stdio-adapter.cjs がstdioのサーバーを子プロセス1つとして動かし、リクエストごとに内部IDを割り当てます。同時に接続したクライアントはそのプロセスを共有するため、1人ずつプロセスが増えることはありません。クラッシュ時は1秒から30秒までの指数バックオフで再起動します |
| npxやuvxによる上乗せ | 明示した起動コマンドが自動検出より優先されるので、node dist/index.js やインストール済みのエントリーポイントを直接起動できます |
| 待機中もメモリ分を払い続ける | 数分アイドルが続くとスナップショットを取って停止し、次のリクエストで1秒未満で復元します。停止中は課金されません |
| どのツールが大きな結果を返しているか分からない | リクエストログに tool_name、duration_ms、res_bytes、outcome、error_message が記録されます。保持期間はFreeが7日、ProとTeamが30日です |
| ブラウザを使うサーバーでChromiumをイメージに入れる必要がある | マネージドブラウザ(Pro以上)がVM内でヘッドレスのChromeを提供するので、イメージにChromeを入れる必要がありません |
| 段階を上げたことで、気づかないうちに料金が増える | 有料プランでは月間の上限金額を設定できます(達するとサーバーはHTTP 402を返します) |
料金:コンピュートはメモリ×稼働時間で1 GB時間あたり5円、アイドル中のサーバーは0円です。Freeは0円で、MCPサーバー1つと月30 GB時間のコンピュートが含まれます。256 MBのサーバーなら約120時間動かせる量です。Freeでは30 GB時間を使い切ると、その月の残りはサーバーが一時停止します。Proは月2,980円で、サーバー数は無制限、300 GB時間が含まれ、256 MBのサーバーを1か月動かし続けても(182.5 GB時間)収まります。9章の表でいえば、業務時間だけ動かす512 MBのサーバー(87 GB時間)はFreeの30 GB時間を超えますが、Proの300 GB時間には十分収まります。
最小の始め方:
- nodeflare.techにGitHubでサインインし、MCPサーバーのリポジトリを選びます。起動コマンドは、npxやuvxを使わずにサーバーを直接起動するものにします。
- ブリッジ型のサーバーやピークが分からない場合は512 MB、実測済みの軽いサーバーなら256 MBで始めます。
- 数週間の実際のトラフィックのあと、右サイズの提案を確認し、合っていれば適用します。
1サーバーまで無料で試せます → nodeflare.tech
14. FAQ
MCPサーバーに必要なメモリはどれくらい?
多くのMCPサーバーは待機中60〜105 MBなので、軽いサーバーを直接起動するなら256 MBに収まります。npxやuvxで起動するなら約50 MB、supergatewayやmcp-proxyのようなブリッジを使うなら125〜140 MBが加わり、たいてい512 MBが必要になります。Playwright MCPのようにブラウザを使うサーバーは1 GB以上を見込みます。
Node.jsのMCPサーバーのメモリ使用量は?
今回の検証では、Node.jsのMCPサーバーは待機中PSSで73〜84 MBでした。TypeScript SDKの最小サーバーが約73 MB、filesystem・memory・everythingのリファレンスサーバーが78〜82 MB、Context7が104〜105 MBです。軽いツール呼び出しを50回しても、数MBしか増えませんでした。
PythonのMCPサーバーのメモリ使用量は?
検証したPythonのサーバーは待機中PSSで61〜70 MBでした。Python SDK 2.3.0の最小サーバーが約61〜70 MB、mcp-server-time が62 MB、mcp-server-git が64 MBです。Node.jsのサーバーより少し少ない一方、起動には時間がかかりました(約0.7秒、Node.jsは約0.2秒)。
MCPサーバーは256 MBで足りる?
軽いサーバー1つを直接起動するなら足ります。今回の検証ではピークが61〜105 MBでした。npx・uvx・mcp-proxyを使うと106〜134 MBになって余裕がなくなり、複数セッションのステートフルなsupergateway、Node.jsがある環境の mcp-server-fetch、ブラウザを動かすサーバーには足りません。
npxで起動するとメモリが増えるのはなぜ?
npx -y は、サーバーが動いている間ずっと、その上に npm exec のプロセスとシェルを残すためです。今回の検証では、filesystemサーバーが1プロセス78〜79 MBから、3プロセス127〜129 MBに増えました。イメージにパッケージをインストールし、エントリーポイントを直接起動すれば避けられます。
uvxでもメモリは増える?
増えます。uvx では、Pythonのサーバーの親として uv のプロセスが常駐します。今回の検証では、mcp-server-time が仮想環境からの起動で62 MB、uvx 経由で106〜107 MBでした。ホスティングでは、ビルド時にインストールしてエントリーポイントを実行します。
supergatewayを使うとメモリはどれくらい増える?
supergateway 4.2.1は、クライアントが接続する前の時点で単体133〜138 MBを使いました。ステートレスモードではリクエストごとにサーバーのプロセスを起動するため、メモリは一時的にピークが出るだけです。--stateful ではセッションごとにサーバーのプロセスを持つので、接続1つにつき約40 MB増え、filesystemサーバーで4セッションなら294 MBでした。
MCPサーバーがOOMKilledになるのはなぜ?
コンテナのプロセスツリー全体のピークが上限を超えたためです。よくある原因は、大きなツール結果(今回は20 MBのファイル読み込みで368 MB)、補助プロセスを起動するツール、多数のセッションが開いたままのステートフルなブリッジ、数に入れていなかったnpxなどのランチャーです。実際の入力でピークを測り、その1.5倍のサイズにします。
mcp-server-fetchがメモリを多く使うのはなぜ?
Node.jsがある環境では、mcp-server-fetch はページの変換にReadability.jsを使い、取得のたびに node のプロセスを起動するためです。今回の検証では、取得のたびに76 MBから312〜348 MBに増えました。PATHに node がなければ約101 MBで済みましたが、出力はPythonだけの粗い抽出処理によるものになりました。
Cloudflare Workersの128 MBの上限でMCPサーバーは動く?
Workersのランタイム向けに書かれたサーバーなら動きます。128 MBはNode.jsのプロセスではなく、V8のisolateに対する上限だからです。本記事で測ったstdioのサーバーは、そのままではWorkersで動きません。その場合はコンテナのホスティングを使い、本記事の数値をもとにサイズを決めます。
メモリのサイズでMCP Hostingの料金は変わる?
変わります。メモリと時間でコンピュートを課金するプラットフォームでは、料金はおおむね「割り当てたGB×稼働時間」です。512 MBのサーバーを1か月動かし続けると365 GB時間、256 MBなら182.5 GB時間です。npxや重いブリッジをやめることが、この2つの段階の分かれ目になることがあります。
まとめ
MCPサーバーのメモリを決めるのは、ツールの数ではなく、主にランタイムとその周りで動くものです。今回の検証では、サーバー単体は待機中60〜105 MB、npxとuvxはそれぞれ消えない約45〜50 MB、ブリッジは125〜140 MBを上乗せし、ステートフルなブリッジは開いているセッション1つにつき約40 MB増えました。ピークを作ったのは、大きなデータと補助プロセス(mcp-server-fetch が取得のたびに起動するNode.jsなど)です。実際の呼び出しでプロセスツリー全体を測り、インストール済みのエントリーポイントから起動し、クライアントの使い方に合ったプロセスモデルのブリッジを選び、ピークの1.5倍以上でいちばん小さいサイズを選んでください。料金は「割り当てたGB×稼働時間」で見積もれます。
参考資料
- Google Cloud Run: Configure memory limits for services
- AWS Lambda: Configure Lambda function memory
- Cloudflare Workers: Limits
- Kubernetes: Assign Memory Resources to Containers and Pods
- modelcontextprotocol/servers(GitHub)
- mcp-server-fetch(PyPI)
- readabilipy(PyPI)
- supergateway(npm)
- mcp-proxy(PyPI)
- Linux kernel: /proc filesystem(smaps_rollup、PSS)
