MCPサーバーが動かないときの最短ルートは、クライアント(Claude DesktopやClaude Code)に組み込む前に、公式の MCP Inspector(npx @modelcontextprotocol/inspector <サーバー起動コマンド>)で単体テストをして「サーバー側の問題か、クライアント設定の問題か」を切り分けることです。接続エラーの三大原因は「相対パス(作業ディレクトリ未定義)」「環境変数の未引き継ぎ」「stdoutへのログ出力によるプロトコル破壊」。ツール未検出の多くは tools/list への応答か能力(capability)宣言の問題です。本記事で順に切り分けていきましょう。
「MCPサーバーを書いた(あるいは入れた)のに、クライアントから全然つながらない…」
先日、検証環境で自作のstdioサーバーをClaude Desktopに登録したとき、まさにこれにハマりました。ターミナルから直接起動すれば正常に動くのに、クライアント経由だと沈黙する。原因は後述する「作業ディレクトリが未定義になる」問題で、設定ファイル内の相対パスが全て空振りしていました。ログの見方さえ知っていれば5分で気づけた内容です。
この経験から言えるのは、MCPのデバッグは「勘で設定をいじる」のではなく、Inspector単体テスト → クライアントログ確認 → 症状別の切り分けという決まった手順で進めるのが圧倒的に速い、ということです。
この記事では、Model Context Protocol公式ドキュメントで確認できる手順に絞って、接続エラー・ツール未検出の切り分け方法をコマンド付きで解説します。stdioサーバーとStreamable HTTPサーバーの両方をカバーします。
まず最初にやること:MCP Inspectorで単体テスト
クライアント側の設定を疑う前に、サーバー単体が正しくMCPを話せているかを確認します。公式のMCP Inspectorは、インストール不要でnpxから直接起動できる対話型のテストUIです。公式デバッグガイドでも「最初に使うべきツール(first stop)」と位置づけられています。
ローカルで開発中のサーバーを検査する場合のコマンドは次のとおりです。
# TypeScript/Node.jsのサーバー
npx @modelcontextprotocol/inspector node path/to/server/index.js args...
# Pythonのサーバー(uv管理のプロジェクト)
npx @modelcontextprotocol/inspector
uv
--directory path/to/server
run
package-name
args...
npmやPyPIで配布されているサーバーパッケージなら、次の形式で起動できます。
# npmパッケージの例(filesystemサーバー)
npx -y @modelcontextprotocol/inspector npx @modelcontextprotocol/server-filesystem /Users/username/Desktop
# PyPIパッケージの例(gitサーバー)
npx @modelcontextprotocol/inspector uvx mcp-server-git --repository ~/code/mcp/servers.git
動作環境: Node.js(npx実行可能な環境)。Pythonサーバーの検査にはuv/uvxが必要です。
# 注意: 本番環境で使用する前に、必ずテスト環境で動作確認してください。
Inspectorを起動すると、ブラウザベースのUIで以下を確認できます。
- Server connection pane: トランスポート(stdio / Streamable HTTP)の選択、ローカルサーバーの起動コマンド・環境変数のカスタマイズ
- Toolsタブ: ツール一覧・スキーマ表示・任意入力でのツール実行テスト
- Resourcesタブ: リソース一覧・メタデータ(MIMEタイプ等)・内容の確認
- Promptsタブ: プロンプトテンプレートの引数確認とテスト
- Notificationsペイン: サーバーから受け取ったログ・通知の一覧
ポイントは、Inspectorで動けばサーバー実装はほぼ正常だと判断できることです。この時点で動かなければサーバー側のコード・依存関係の問題、動くのにクライアントからつながらなければクライアント設定(パス・環境変数・JSON)の問題、と大きく二分できます。
症状別の切り分け早見表
実際にデバッグ支援をしてきた経験と公式ガイドの「Common issues」を突き合わせると、症状と原因の対応はかなりパターン化できます。まずこの表で当たりをつけてみましょう。
| 症状 | よくある原因 | 最初に確認すること |
|---|---|---|
| サーバーが起動すらしない | 実行ファイルのパス誤り、必要ファイル欠落、権限不足 | commandを絶対パスにして再試行。ターミナルで同じコマンドを直接実行 |
| 起動するが接続に失敗する | stdoutへのログ出力でプロトコル汚染、プロトコルバージョン不一致 | クライアントログを確認し、Inspectorで単体接続テスト |
| 接続できるがツールが出てこない | tools/list未実装・登録漏れ、capability宣言漏れ |
InspectorのToolsタブでツールが列挙されるか確認 |
| 特定のツールだけ失敗する | 環境変数(APIキー等)の未引き継ぎ、相対パス参照 | 設定のenvキーと絶対パス化を確認 |
| 直したのに反映されない | クライアントの再起動漏れ | 設定変更はクライアント再起動、サーバーコード変更は完全終了→再起動 |
| HTTPサーバーが不安定に切れる | サーバー側5xx・タイムアウト | curlやDevToolsのNetworkパネルでリクエスト/SSEストリームを直接確認 |
それぞれの対処を、接続エラー系とツール未検出系に分けて詳しく見ていきます。
接続エラーの原因と対処(stdioサーバー)
原因1: 作業ディレクトリが未定義
公式デバッグガイドに明記されている重要な仕様として、クライアントの設定ファイル経由で起動されたstdioサーバーは、作業ディレクトリが未定義(macOSでは/になることもある)という点があります。クライアントアプリはどこから起動されるか分からないためです。
つまり、./dataのような相対パスは、ターミナルから手動起動したときは動くのに、クライアント経由では全く別の場所を指します。冒頭で紹介した私のハマりポイントもこれでした。
対策はシンプルで、設定ファイルと.env内のパスをすべて絶対パスにすることです。Claude Desktopのclaude_desktop_config.jsonでの正しい例は次のとおりです。
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/username/data"
]
}
}
}
ポイントは以下の3つです。
- 引数のディレクトリ指定は
./dataではなく/Users/username/dataのような絶対パスにする - サーバー本体が読み書きするファイルパスも、コード内で絶対パス化しておく
- 起動しない場合は
command自体も絶対パス(例:nodeのフルパス)を試す
原因2: 環境変数が引き継がれない
もう1つの定番が環境変数です。stdio経由で起動されたMCPサーバーは、環境変数の限られたサブセットしか自動的に引き継ぎません(引き継がれる範囲はプラットフォーム依存です)。シェルの~/.zshrc等で設定したAPIキーは、クライアント経由の起動では見えないことが多いのです。
必要な変数は設定ファイルのenvキーで明示的に渡します。
{
"mcpServers": {
"myserver": {
"command": "mcp-server-myapp",
"env": {
"MYAPP_API_KEY": "some_key"
}
}
}
}
APIキーを設定ファイルに直書きしたくない場合は、シークレット管理の仕組みと組み合わせるか、サーバー側で.envファイル(絶対パス指定)を読む設計にしましょう。設定ファイルをそのままリポジトリにコミットしない運用も必須です。
原因3: stdoutへのログ出力がプロトコルを壊す
これは自作サーバーで最も多い「起動はするのに接続確立しない」原因です。stdioトランスポートでは、stdout(標準出力)はJSON-RPCメッセージ専用です。ここにprint()やconsole.log()でデバッグメッセージを流すと、クライアントはプロトコルメッセージとして解釈しようとして失敗します。
公式ガイドは「ローカルMCPサーバーはstdoutにログを書いてはならない(プロトコル動作を妨げる)」と警告しています。ログはstderr(標準エラー出力)に書きます。stdioの場合、stderrに書いたログはホストアプリケーションが自動的にキャプチャしてくれます。
Python SDKでのログ実装例です。loggingモジュールは既定でstderrに出力するため、この形が安全です。
import logging
from mcp.server import MCPServer
logger = logging.getLogger(__name__)
mcp = MCPServer("reports")
@mcp.tool()
async def fetch_report(report_id: str) -> str:
"""Fetch a report by id."""
# stdoutではなくloggerを使う(stdio環境ではstderr経由でホストが回収する)
logger.info("Fetching report %s", report_id)
return f"Report {report_id} is ready."
動作環境: Python 3.10以上、MCP公式Python SDK。
# 注意: 本番環境で使用する前に、必ずテスト環境で動作確認してください。
なお、プロトコル経由のロギング機構(notifications/message)は、プロトコルバージョン2026-07-28で非推奨(deprecated)になりました。移行期間中は使えますが、これから作るサーバーはstderr(stdio)またはOpenTelemetry等のサーバー側ログ基盤(全トランスポート)に寄せるのが公式推奨です。
原因4: 設定JSONの構文エラー
地味ですが頻発します。公式ガイドの「Configuration Errors」でも、無効なJSON構文・必須フィールドの欠落・型の不一致が起動失敗の典型として挙げられています。カンマの過不足やクォート漏れは、エディタのJSONバリデーションかpython3 -m json.toolへの読み込みで機械的にチェックしましょう。
ツールが検出されないときのチェックリスト
接続はできているのに「ツールが1つも出てこない」「作ったはずのツールが見えない」場合は、以下を順に確認します。
Step 1: InspectorのToolsタブで列挙されるか
InspectorのToolsタブには、サーバーがtools/listで返すツールの一覧・スキーマ・説明が表示されます。ここに出てこなければ、クライアント以前にサーバー側の登録に問題があります。SDKのツール登録(デコレータやハンドラ)が実行されているか、ビルド後の成果物を起動しているか(TypeScriptでソース修正後にリビルドを忘れるケースが多い)を確認してください。
Step 2: capability宣言を確認する
接続直後の初期化では能力交渉(capability negotiation)が行われます。Inspectorの接続確認で「Check capability negotiation」が公式ワークフローに含まれているのはこのためです。サーバーがtools capabilityを宣言していなければ、クライアントはツールを探しにいきません。逆に、tools capabilityを宣言しているのにツールを1つも公開していないサーバーは、Claude Codeの/mcpパネルで警告としてフラグ表示されます。
Step 3: クライアント側の反映漏れを疑う
公式ガイドの「Testing changes」によると、反映のルールは次のとおりです。
- 設定変更: MCPクライアントを再起動すれば反映
- サーバーコードの変更: クライアントを再起動。Claude Desktopの場合はウィンドウを閉じるだけでは不十分で、完全終了して開き直す必要あり
- 高速に試行錯誤したいとき: 開発中はInspectorを使う(Reconnectで再接続できる)
「修正したのに変わらない」の多くはこの再起動漏れです。特にClaude Desktopの「完全終了が必要」という仕様は見落としがちなので注意してください。
Step 4: プロトコルバージョンとエラーコードを見る
2026-07-28版の公式デバッグガイドでは、接続問題の確認手順としてプロトコル互換性の検証が追加されています。押さえておきたいエラーコードは次の3つです。
| エラーコード | 名称 | 意味と対処 |
|---|---|---|
-32022 |
UnsupportedProtocolVersionError | プロトコルバージョン不一致。dataフィールドにサーバーの対応バージョン一覧が入るので、クライアント/SDKのバージョンを合わせる |
-32602 |
Invalid params | 必須の_metaフィールド(protocolVersion / clientCapabilities)欠落を含む、不正パラメータ全般 |
-32021 |
MissingRequiredClientCapabilityError | サーバーが必要とするcapability(elicitation等)をクライアントが宣言していない。不足しているcapability名がエラーに含まれる |
古いSDKで作ったサーバーを新しいクライアントにつなぐ(またはその逆の)ケースでは、まずここを疑うと早いです。
クライアント別:ログとステータスの確認方法
Claude Desktopの場合
ログファイルの場所は公式に定義されています。
- macOS:
~/Library/Logs/Claude - Windows:
%APPDATA%Claudelogs
リアルタイムで追いかけるには次のコマンドが便利です。
# macOS: MCP関連ログを追跡表示
tail -n 20 -F ~/Library/Logs/Claude/mcp*.log
このログには、サーバー接続イベント・設定の問題・実行時エラー・メッセージ交換が記録されます。「そもそもサーバーの起動を試みているか」「起動直後に何のエラーで落ちたか」がここで分かります。
さらに深掘りしたい場合は、Claude Desktop内でChrome DevToolsを有効化できます。
# macOS: DevToolsを許可する設定ファイルを作成
echo '{"allowDevTools": true}' > ~/Library/Application Support/Claude/developer_settings.json
# その後 Command-Option-I でDevToolsを開く(Windowsは Ctrl+Alt+I)
Consoleパネルでクライアント側エラーを、Networkパネルでメッセージペイロードと接続タイミングを確認できます。サーバーの状態自体は、チャット入力欄のプラスアイコンからConnectorsメニューをホバーすると、接続済みサーバーと利用可能ツールの一覧が見られます。
Claude Codeの場合
Claude CodeにはMCP管理用のCLIコマンドが揃っており、接続の健全性をターミナルから確認できます。
# 登録済みサーバー一覧と接続ステータスを確認
claude mcp list
# 特定サーバーの詳細を確認
claude mcp get notion
# セッション内でサーバー状態・認証を管理
/mcp
claude mcp listは各サーバーの横にヘルスステータスを表示します。✔ Connected(接続成功)、! Needs authentication(要認証。/mcpからOAuth認証する)、✘ Failed to connect(接続失敗)の3状態が基本です。プロジェクトの.mcp.json由来のサーバーが承認待ちの場合は⏸ Pending approvalと表示され、claudeを対話起動して承認するまで接続されません。
起動が遅いサーバーでタイムアウトする場合は、環境変数MCP_TIMEOUTで起動タイムアウトを調整できます(例: MCP_TIMEOUT=10000 claudeで10秒)。また、ツール出力が大きすぎて途中で切られていると感じたら、既定で25,000トークンに制限されている出力上限をMAX_MCP_OUTPUT_TOKENSで引き上げられます。
Claude Codeの導入手順そのものは、Claude MCP入門で基礎から解説しているので、初めての方はそちらから読むのがおすすめです。
Streamable HTTPサーバーのデバッグ
リモートで動かすStreamable HTTPトランスポートのサーバーは、stdioとデバッグ方法が根本的に異なります。公式ガイドが明確に区別している点は次の2つです。
- stderrはクライアントに回収されない。サーバー側で独自のログ集約、またはOpenTelemetryを使う
- リクエストとSSEストリームの検査には、curlやブラウザDevToolsのNetworkパネルといった標準HTTPツールを使う
つまりHTTPサーバーの場合、「クライアントのログを見る」よりも「サーバーのアクセスログ・アプリケーションログを見る」「HTTPレイヤーを直接叩く」が基本動作になります。ヘッダー付きでエンドポイントを叩いてステータスコードとレスポンスを確認し、5xxが返っていないか、認証ヘッダーが正しく通っているかをチェックしましょう。
Claude Codeを使っている場合は再接続の挙動も知っておくと切り分けに役立ちます。HTTP/SSEサーバーがセッション中に切断されると、Claude Codeは1秒から始まる指数バックオフで最大5回自動再接続を試み、その間/mcpではpending表示になります。5回失敗するとfailedとしてマークされ、/mcpから手動リトライできます。一方、認証エラーや404はリトライされません。設定変更で直すべきエラーだからです。「何度も再接続している」ならネットワークかサーバー側の一時障害、「即failedで止まる」なら認証・URL設定を疑う、という読み方ができます。
Streamable HTTPトランスポート自体の実装方法(セッション管理・SSEストリームの仕組み)はMCP Streamable HTTP実装ガイドで詳しく解説しています。
【要注意】よくある失敗パターンと回避策
失敗1: print()デバッグでプロトコルを壊す
❌ stdioサーバーの動作確認にprint("here")やconsole.log(data)を挟む
⭕ logging(Python)やstderr出力でログを書き、Inspectorの Notificationsペインやクライアントログで確認する
なぜ重要か: stdioではstdoutがプロトコルの通信路そのものです。1行の混入でもJSON-RPCのパースが壊れ、「原因不明の接続断」に見えます。普段のスクリプト開発の癖が最も出やすい罠です。
失敗2: ターミナルで動いたから本番設定でも動くと思い込む
❌ 手元のシェルで起動確認しただけでクライアントに登録する
⭕ 作業ディレクトリ未定義・環境変数未引き継ぎを前提に、絶対パス化とenvキー明示をしてから登録する
なぜ重要か: シェルにはPATHもカレントディレクトリも環境変数も揃っています。クライアント経由の起動はそのどれも保証されません。「手元では動くのに」の9割はこの環境差です。
失敗3: 修正のたびに再起動せず「直っていない」と誤診する
❌ サーバーコードを直してすぐクライアントで再テストする
⭕ 開発ループはInspector(再接続で即反映)で回し、クライアント側の確認は完全再起動してから行う
なぜ重要か: クライアントは古いサーバープロセスを掴んだままのことがあります。特にClaude Desktopはウィンドウを閉じても終了しないため、「直したのに同じエラー」という無限ループに陥りがちです。
失敗4: エラー応答を実装せず沈黙させる
❌ ツール内の例外を握りつぶして空文字を返す
⭕ スタックトレースとコンテキストをログに残し、クライアントには適切なエラー応答を返す。Inspectorの公式ワークフローどおり、不正入力・引数欠落・並行実行のエッジケースをテストする
なぜ重要か: エラーが見えないサーバーはデバッグ不能です。公式ベストプラクティスも、構造化ログ(一貫フォーマット・タイムスタンプ・リクエストID)とエラーコンテキストの記録を推奨しています。あわせて、ログに認証情報や個人情報を残さないサニタイズも忘れずに。
よくある質問
MCP Inspectorはインストールが必要ですか?
不要です。npx @modelcontextprotocol/inspector <起動コマンド>で直接実行できます。Node.js環境(npx)があれば動きます。Pythonサーバーを検査する場合はuv/uvxを併用します。
接続エラーとツール未検出はどちらから調べるべきですか?
接続からです。ツールの列挙(tools/list)は接続確立と能力交渉の後に行われるため、接続が不安定なままツール実装を疑っても空振りします。Inspectorで「接続→capability→ツール列挙」の順に確認しましょう。
クライアントのログにサーバーの起動記録すらない場合は?
設定ファイルがそもそも読まれていない可能性が高いです。JSON構文エラー、設定ファイルの置き場所違い、サーバー名の記述ミスを確認してください。Claude Codeならclaude mcp listに名前が出てくるかどうかで、設定が認識されているかを判別できます。
デバッグ中にAPIキーをログへ出してしまいました。問題ありますか?
はい、すぐにそのキーをローテーション(無効化・再発行)してください。公式ガイドもデバッグ時のログのサニタイズ、認証情報の保護、個人情報のマスキングを明示的に求めています。ログ共有前の確認を習慣にしましょう。セキュリティ面の全体像はMCPサーバーのセキュリティ脆弱性と防御ガイドも参考にしてください。
まとめ:今日から始める3つのアクション
- 今日やること: 手元のMCPサーバーを
npx @modelcontextprotocol/inspectorで起動し、接続・capability・Toolsタブの列挙まで確認する - 今週中: 設定ファイルのパスを全て絶対パス化し、必要な環境変数を
envキーへ明示。stdout汚染がないかコードをgrepする - 今月中: stderr(またはOpenTelemetry)ベースの構造化ログを整備し、リクエストID・タイムスタンプ・エラーコンテキスト付きで本番運用に備える
あわせて読みたい:
- FastMCPで作るPython製MCPサーバー入門 — サーバー実装そのものを基礎から学びたい方に
- MCP Streamable HTTP実装ガイド — リモートサーバーのトランスポート実装を深掘り
この記事を読んで導入イメージが固まってきた方へ
UravationではAIエージェント導入の研修・コンサルを行っています。
著者: 佐藤傑(さとう・すぐる)
株式会社Uravation代表取締役。X(@SuguruKun_ai)フォロワー約10万人。100社以上の企業向けAI研修・導入支援。著書『AIエージェント仕事術』。
参考・出典
- Debugging – Model Context Protocol — Model Context Protocol公式ドキュメント(参照日: 2026-08-01)
- MCP Inspector – Model Context Protocol — Model Context Protocol公式ドキュメント(参照日: 2026-08-01)
- Connect Claude Code to tools via MCP — Anthropic公式ドキュメント(参照日: 2026-08-01)
- modelcontextprotocol/inspector — MCP Inspector公式リポジトリ(参照日: 2026-08-01)
