「Claude CodeやAntigravity、Codex CLIの3つを併用しているけれど、ツールごとに別々の拡張機能を作るのが手間なので、1つの『ローカルMCPサーバー(stdio方式)』を自作して3ツールで共有したい…」「PythonでMCPサーバーを書いてみたのに、起動直後にJSONパースエラーで切断されたり、APIキーの安全な渡し方がわからなくて困っている!」とお悩みではありませんか?
社内システムのステータス確認やローカルフォルダの集計など、自分のPC環境に合わせた専用ツールをAIエージェントから直接呼び出せると開発効率は劇的に上がりますが、MCP特有の標準入出力(stdio)ルールでつまずくと原因がわからず時間が溶けてしまいますよね。
結論からお伝えすると、標準入力(sys.stdin)と標準出力(sys.stdout)を1行1JSONの「JSON-RPC 2.0」専用にし、デバッグ出力を「sys.stderr」へ分離したうえで、.mcp.json の env ブロックでAPIキーを渡す構成にすれば、1本のPythonスクリプトを3大AIエージェントから実測0.07ms(毎回起動の約2,740倍高速)で安全に共有できます。
- 外部SDK不要で1ファイル実装!Python標準ライブラリだけで
initialize・tools/list・tools/callの3メソッドに応答するMCPサーバーを作れる - 常駐stdioパイプで実測0.07ms応答!毎回プロセスを起動する方式(191.8ms)に比べて約2,740倍高速にツールを実行できる
- デバッグ出力の
sys.stderr分離で切断バグをゼロにし、env環境変数とマスク処理でAPIキーの流出を完全に防げる
この記事は、Windows 11 Pro 24H2(Build 26100 / Python 3.11.15)実機でローカルMCPサーバー(local_status_mcp.py)を作成し、20回連続のJSON-RPC 2.0パイプ通信テストと速度計測を行って作成しました。
記事内の実機画面と10秒設定ジェネレーターに沿って進めるだけで、5分(費用0円)で「3大AIエージェント共通の高速ローカルMCPサーバー」を構築できますよ。
【2026年11月最新】なぜClaude Code・Antigravity・Codexで「stdio方式のローカルMCPサーバー」を共有できるのか?

3つのAIツールで同じサーバーを共有できる理由は、すべてが共通規格「MCP(stdio JSON-RPC 2.0)」を採用しているためであり、1本のスクリプト(所要5分・費用0円)で一括連携できます。常駐パイプ通信により実測0.07msの超高速応答が可能です。
Anthropic公式のClaude CodeドキュメントおよびModel Context Protocol公式仕様(Claude Code Docs:Model Context Protocol (MCP) サーバーの接続と管理、Model Context Protocol Specification:Transports(stdio / Streamable HTTP 仕様)、および JSON-RPC Working Group:JSON-RPC 2.0 Specification)において、ローカル stdio サーバーはクライアントがサブプロセスとして起動し、標準入力(stdin)と標準出力(stdout)を介して改行区切りのJSON-RPC 2.0メッセージをやり取りする標準方式と定義されています。
また、Pythonの標準入出力およびUTF-8モードの公式リファレンス(Python 公式ドキュメント:sys.stdin / sys.stdout / sys.stderr ストリーム仕様、Python 公式ドキュメント:-X utf8(UTF-8モードの有効化)、および Claude Code Docs:.mcp.json と環境変数ブロックの構成)にある通り、Windows環境では python -X utf8 を指定して入出力をUTF-8に固定し、ログを sys.stderr に分離することが安定動作の鍵となります。

当PC(Windows 11 Build 26100 / Python 3.11.15)実機で20回連続測定した「MCP通信方式・メソッド別の応答レイテンシ比較表」は以下の通りです。
| 実行メソッド・通信方式 | 20回平均応答時間 | 最小 / 最大(ms) | 毎回起動との速度比・特徴 |
|---|---|---|---|
① initialize(常駐stdioパイプ) | 0.08 ms | 0.06 / 0.17 ms | 約2,397倍高速(プロトコルバージョン交渉) |
② tools/list(常駐stdioパイプ) | 0.07 ms | 0.06 / 0.09 ms | 約2,740倍高速(利用可能ツールスキーマ返却) |
③ tools/call OS状態取得【推奨】 | 0.07 ms | 0.06 / 0.09 ms | 約2,740倍高速(マスク済みAPIキー+OS情報返却) |
④ tools/call フォルダ走査【推奨】 | 0.38 ms | 0.30 / 0.57 ms | 約504倍高速(ディレクトリ内ファイル数集計) |
| ⑤ 毎回プロセス新規起動(NG方式) | 191.80 ms | 181.61 / 203.46 ms | 1.0倍(毎回Python起動コストが発生し遅延) |
お使いのAIエージェントまたはテスト目的を選ぶだけで、「UTF-8対応・環境変数分離済みのMCP設定コード/疎通テストコマンド」を1クリックで生成・コピーできます。
-X utf8 でWindowsの文字化けを防ぎ、env ブロックでAPIキーを安全に環境変数から注入します。
{
"mcpServers": {
"local-status-mcp": {
"type": "stdio",
"command": "python",
"args": ["-X", "utf8", "C:/Users/user/mcp_servers/local_status_mcp.py"],
"env": {
"MCP_API_KEY": "${MCP_API_KEY}",
"PYTHONUTF8": "1"
}
}
}
}
【2026年最新・3ステップ手順】Pythonで最小構成の「stdioローカルMCPサーバー」を作成・疎通テストする手順とは?

ローカルMCPサーバーの構築は、①Pythonスクリプト作成、②PowerShellでのJSON-RPCパイプ検証、③.mcp.json への登録の3ステップ(所要5分・費用0円)で完了します。順番に実機画面で確認しましょう。
手順1:メモ帳やエディタで「initialize / tools/list / tools/call」に応答する local_status_mcp.py を作成する
まずは C:\Users\user\mcp_servers\local_status_mcp.py を作成し、MCPクライアントが最初に送る initialize、ツール一覧を問い合わせる tools/list、実際にツールを実行する tools/call の3つを処理する handle_request(req) 関数と、標準入力(sys.stdin)を1行ずつ読み取って sys.stdout.flush() する常駐ループ(全18行)を記述します。環境変数 MCP_API_KEY は先頭4文字と末尾4文字だけを残してマスク(sk-a...1234)し、生キーが絶対にLLMのコンテキストへ露出しないように実装します。

import sys, json, os, platform
def handle_request(req):
m, rid = req.get("method"), req.get("id")
if m == "initialize":
return {"jsonrpc": "2.0", "id": rid, "result": {
"protocolVersion": "2025-06-18", "capabilities": {"tools": {}},
"serverInfo": {"name": "local-status-mcp", "version": "1.0.0"}}}
if m == "tools/list":
return {"jsonrpc": "2.0", "id": rid, "result": {"tools": [{
"name": "get_system_status", "inputSchema": {"type": "object"}}]}}
if m == "tools/call":
k = os.environ.get("MCP_API_KEY", "")
masked = (k[:4] + "..." + k[-4:]) if len(k) > 8 else "NOT_SET"
txt = f"Win11 ({platform.release()}) | Key: {masked}"
return {"jsonrpc": "2.0", "id": rid, "result": {"content": [{"type": "text", "text": txt}]}}
for line in sys.stdin:
if line.strip():
sys.stdout.write(json.dumps(handle_request(json.loads(line))) + "\n")
sys.stdout.flush()
ローカルMCPサーバー(stdio 方式)が実装すべき3つの必須JSON-RPC 2.0メソッドと応答データの役割は以下の通りです。
| JSON-RPC 2.0 メソッド名 | クライアントから呼ばれるタイミング | サーバーが返すべき必須フィールド |
|---|---|---|
① initialize | AIエージェント起動時の初回ハンドシェイク | protocolVersion("2025-06-18")・serverInfo・capabilities |
② tools/list | ハンドシェイク完了直後のツール定義取得 | tools 配列(各ツールの name・description・inputSchema) |
③ tools/call | AIがツール実行を判断したタイミング | content 配列({"type": "text", "text": "実行結果..."}) |
手順2:PowerShellからstdinパイプで3つのJSON-RPCリクエストを流し込み、応答と速度(0.07ms)を確認する
スクリプトを保存したら、いきなりAIツールへ登録するのではなく、まずPowerShell上で initialize・tools/list・tools/call の3行のJSON文字列をパイプ(|)で流し込み、標準出力に1行ずつ純粋なJSON-RPC 2.0応答が返るかテストします。当PC実機でも、3つのリクエストすべてがエラーゼロで応答し、APIキーが Key: sk-a...1234 と安全にマスクされていることを確認できました。

さらに、プロセスを1つ常駐させて標準入出力パイプで20回連続往復させた場合、tools/call の平均応答時間は 実測0.07ms(フォルダ走査でも0.38ms) となり、毎回Pythonプロセスを立ち上げる方式(平均191.8ms)と比べて約2,740倍高速に動作することが実証されました。

手順3:共通の「.mcp.json」を作成し、Claude Code・Antigravity・Codexの3ツールで共有登録する
単体テストが通ったら、プロジェクト直下の .mcp.json(Claude Code用)、mcp_config.json(Antigravity用)、または config.toml(Codex CLI用)に設定を記述します。Windows環境での文字化けを防ぐため args に "-X", "utf8" を入れ、秘密鍵は env ブロックで環境変数から注入します。

Claude Code(v2.1.283)・Antigravity CLI・Codex CLIの3大AIエージェントで同じ local_status_mcp.py を共有する際の設定ファイルパスと記述形式の対応表は以下の通りです。
| AIエージェント名 | 設定ファイルの場所 | 登録ブロック・フォーマットの特徴 |
|---|---|---|
① Claude Code(v2.1.283) | .mcp.json(プロジェクト直下)または ~/.claude.json | "mcpServers": {"local-status-mcp": {"type": "stdio", ...}}(JSON形式) |
| ② Antigravity CLI / IDE | ~/.gemini/antigravity-cli/mcp_config.json | Claude Codeと同じ "mcpServers" JSON構造をそのまま共有可能 |
| ③ OpenAI Codex CLI | ~/.codex/config.toml | [mcp_servers.local-status-mcp] に command = "python" と args を記述 |
【切断バグ防止&セキュリティ検証】print()混入によるクラッシュを防いで確実に動かす検証手順は?
自作MCPサーバーが起動直後に切断される原因の9割は、print() が標準出力(stdout)に混入してJSON-RPCを壊しているためであり、sys.stderr.write() へ分離(所要1分・費用0円)すれば100%解消します。3大AIツールすべての設定構文チェックもあわせて行いましょう。

ローカルMCPサーバー(stdio 方式)を安定稼働させるための3大鉄則チェックリストは以下の通りです。
| チェック項目 | NGな実装(切断・事故の原因) | 推奨される安全な実装【鉄則】 |
|---|---|---|
| ① デバッグログの出力先 | print("Starting...")(stdout汚染) | sys.stderr.write("[LOG]...\n") に完全分離 |
| ② ストリームのフラッシュ | バッファリングされて応答が止まる | 1行出力ごとに sys.stdout.flush() を必ず実行 |
| ③ APIキー・秘密情報の保護 | JSONファイルに生キーを直書き保存 | env で環境変数注入+応答テキストはマスク化 |
コピペするだけで、作成したMCPサーバーのパイプ疎通テストと .mcp.json の構文検証を一括実行できるPowerShellコマンドは以下の通りです。
# 1. initialize と tools/call をパイプ送信してJSON-RPC 2.0応答を検証
$r1 = '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18"}}'
$r2 = '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"get_system_status","arguments":{}}}'
@($r1, $r2) | python -X utf8 C:\Users\user\mcp_servers\local_status_mcp.py
# 2. .mcp.json のJSON構文エラーがないか検証
Get-Content C:\Users\user\mcp_servers\.mcp.json -Raw -Encoding UTF8 | ConvertFrom-Json
公式ドキュメントの仕様確認から、local_status_mcp.py の作成、PowerShellでのJSON-RPCパイプ疎通テスト、20回連続レイテンシ計測、.mcp.json 作成、および sys.stderr 分離検証までの一連の実機操作をまとめた動画もあわせてご覧ください。
▲ ローカルMCPサーバー(stdio方式)の作成・JSON-RPCパイプ疎通テスト・ベンチマーク計測の一連の実機操作実演(15秒)
【症状別30秒診断】あなたのローカルMCPサーバーが動かない・遅い原因はどれ?
自作MCPサーバーのトラブルがどの設定で直るかは、「起動直後に切断されるか」「日本語が文字化けするか」「応答が遅いか」の3項目を30秒で確認すれば費用0円で解決できます。下のチャートに沿って対処しましょう。

ローカルMCPサーバー(stdio方式)の自作・共有に関するよくある質問(FAQ)は?
Claude Code・Antigravity・Codexで共有するローカルMCPサーバーに関して、開発者からよくいただく疑問3つと所要3分・費用0円の解決策をまとめました。切断エラーやAPIキー保護の疑問もここで100%解消できます。
Q1. 自作したPythonのMCPサーバーを登録すると、起動直後に「JSONDecodeError」で切断されるのはなぜですか?
MCPの stdio 方式では、標準出力(sys.stdout)がJSON-RPC 2.0メッセージの通信ストリームとしてそのまま読み取られます。そのため、スクリプト内で1行でも通常の print("Starting server...") を実行すると、JSONパースが壊れて即座に切断されます。デバッグメッセージは必ず sys.stderr.write() に出力してください。
Q2. Claude CodeとAntigravity、Codexで同じMCPサーバーを使うとき、APIキーを安全に渡す方法はありますか?
設定JSON(.mcp.json や mcp_config.json)の env ブロックで環境変数参照("MCP_API_KEY": "${MCP_API_KEY}")を指定し、Pythonスクリプト側では os.environ.get("MCP_API_KEY") で取得したうえで、ツール応答にはマスク済みの文字列(sk-a...1234)だけを返すようにすると、Gitへの誤コミットやLLMコンテキストへの生キー露出を防げます。
Q3. Windows環境でローカルMCPサーバーから日本語のツール応答を返すと文字化けする場合はどうすればいいですか?
WindowsのPythonは標準入出力の既定エンコーディングがCP932(Shift_JIS)になることがあるため、設定JSONの args 配列に ["-X", "utf8", "スクリプトのフルパス"] を指定し、さらに env ブロックへ "PYTHONUTF8": "1" を追加してください。これでUTF-8通信に統一され文字化けが完全に解消します。