ego (lite) はブラウザそのもの、ego は端末を横断して動くあなた専属のエージェントです。
順番待ちリストに参加する
MCPMCP InspectorMCPサーバーテストCI

デプロイ前にMCPサーバーの品質をテストする方法とツール

2026年9月19日14 分で読了
デプロイ前に MCP サーバーをテストする方法: Inspector での確認、スキーマ検証、CI ゲート

MCP サーバーのバグは、ユーザーの目に触れる前に捕まえるのが一番です。その作業のためのリファレンスツールが MCP Inspector です。サーバーが接続できるか、正しいツールを公開しているか、実際の引数を受け取るか、期待どおりのペイロードを返すか、そしてクライアントが理解できる形で失敗するかを確認できます。

優れたデプロイ前チェックは、これらのレイヤーを順にたどるべきです。ハンドシェイク、ツールの公開サーフェス、スキーマ、動作、異常系、認証境界、ログ、そして最後に CI です。そのほとんどは MCP Inspector で足ります。サーバーが最終的に実際のサインイン済みブラウザに依存するなら、最後のステップでは ego (lite) が適しています。エージェントに、既存のログイン状態を持つ可視の Chromium の Space を渡し、必要に応じて人が引き継げるようにします。

以下のコマンドは、2026年9月20日に確認した公式の Inspector ドキュメントとリポジトリのスモークテストガイドに基づいています。本ガイドの Web クライアントのキャプチャは、固定した @2.5.0 ランチャーをローカルのフィクスチャに対して実際に実行した一次情報で、終了コードのクロスチェックは可視の ego (lite) Space で取得しました。バージョンは厳密に固定し、デプロイゲートにする前に各アサーションをご自身のサーバーで検証してください。

デプロイ前にMCPサーバーで何をテストすべき?

MCP サーバーには、一般的なテストスイートが網羅しない公開サーフェスがあります。次の順で 7 つの確認を行うと、本番に届いてしまう障害を捉えられます。

レイヤー何を証明するか実行する場所
接続サーバーが起動し、MCP のハンドシェイクを完了するInspector の initialize プローブ
公開サーフェスツール・リソース・プロンプトがリリースノートの記載と一致するtools/list、resources/list、prompts/list
スキーマ実際のクライアントがツールスキーマを受け入れるtools/list に --strict を付けて実行
動作代表的な呼び出しが期待どおりのペイロードを返すtools/call とアサーション
異常系タイムアウト・認証チャレンジ・拒否が正しく、はっきり失敗する終了コードと --connect-timeout
境界トークン・スコープ・仕込んだ指示が意図以上に広がらない分離した認証ストアとフィクスチャサーバー
ゲートコミットごとに同じアサーションを再実行するInspector のバージョンを固定した CI ジョブ

以降のセクションで各行を詳しく説明します。リストを誠実に保つルールが 1 つあります。結果を表示するだけの確認はテストではありません。テストは値をアサートし、その前提が崩れたら非ゼロで終了します。

MCP Inspector で MCP サーバーを調べるには?

MCP Inspector は単一のパッケージ @modelcontextprotocol/inspector として配布され、1 つのバイナリで 3 つのクライアントを提供します。Web UI(デフォルト)、スクリプト化できる CLI、対話型のターミナル UI です。いずれも Node 22.19.0 以降が必要で、npx からインストールなしで実行できます。

1 つのパッケージに Web・CLI・TUI の 3 クライアントが用意されていることを示す、公開 MCP Inspector リファレンスページ
公開 MCP Inspector リファレンスページでは、1 つのパッケージに 3 つのクライアント(Web・CLI・TUI)が用意されていることが示されており、用途に合ったサーフェスを選べます。
npx @modelcontextprotocol/inspector node path/to/server/index.js
npx @modelcontextprotocol/inspector --cli node path/to/server/index.js --method tools/list
npx @modelcontextprotocol/inspector --tui node path/to/server/index.js

リモートサーバーの場合は、コマンドの代わりに URL を指定します。Streamable HTTP なら --server-url https://api.example.com/mcp --transport http、SSE なら --transport sse です。まずサーバー自身の README を読んでください。サーバーごとにコマンドと引数が異なり、起動コマンドはそこに書かれています。

Streamable HTTP 経由でローカルの MCP フィクスチャに接続した Inspector Web クライアント。右側に Protocol のトランスクリプトが表示されています
実際の Inspector Web セッション。Servers タブには Streamable HTTP で 127.0.0.1:6605 に接続されたフィクスチャが表示され、Protocol タブがメッセージのトランスクリプトを並べて記録しています。

Web クライアントが表示するタブは、サーバーが実際に報告したケイパビリティに対応するものだけです。Tools は各入力スキーマをフォームとして描画し、結果を構造化コンテンツとして表示します。Prompts は生成されるメッセージをプレビューし、Resources は参照・読み取り・購読を行い、Protocol は JSON-RPC の記録を保持し、Logs はサーバー通知を表示します。HTTP と SSE のサーバーにはステータス・ヘッダー・ボディを扱う Network タブも加わり、stdio サーバーにはプロセスの stderr を表示する Console タブが加わります。両方が同時に現れることはなく、これらのビューではシークレットがマスクされます。

echo ツールを選択し、その入力スキーマが入力可能なフォームとして描画されている Inspector Web クライアントの Tools タブ
同じセッションの Tools タブ。echo ツールが選択され、その入力スキーマがクライアントから見えるとおりに入力可能なフォームとして描画されています。

手動での確認は、自動化する前にサーバーの本当の性格を知る場です。現実的な引数でツールを呼び、Protocol の記録で正確なリクエストとレスポンスを確認し、あとでアサートする値を書き留めます。CLI は同じ接続をスクリプトに変えます。--method initialize は接続だけを行うプローブで、serverInfo、protocolVersion、capabilities、instructions を出力し、何も呼び出さずに終了します。パイプラインに置ける最も安価な「生きていて MCP を話しているか」のアサーションです。

stdio の細かい注意点が 1 つあります。サーバー自身がフラグを取る場合は、二重ダッシュで区切ります。--cli では、区切りより前が対象コマンド、後ろが Inspector 自身のオプションです。

ロールアウト前にツールスキーマを検証するには?

ツールスキーマは有効な JSON Schema であっても、サーバーが対応すべきクライアントに拒否されることがあります。スキーマの移植性は独立したテストに値します。クライアントが実際に受け取る一覧を出力し、厳格に検査しましょう。

npx @modelcontextprotocol/inspector --cli node build/index.js --method tools/list
npx @modelcontextprotocol/inspector --cli node build/index.js --method tools/list --strict

--strict は移植性の問題をパス・問題点・具体的な修正方法とともに列挙します。modelcontextprotocol.io の CLI ドキュメントでは終了コード 0 から 5 が定義されており、リポジトリのスモークテストガイドでは error 重大度の strict 指摘に対して終了コード 6 が追加され、警告は報告されるが終了コードは変わらないと注記されています。

JSON パイプラインでは構造化された出力を読みます。--format json を付けると、指摘はツールごとにまとめられた schemaFindings 配列として stdout に出力され、stderr には人間向けレポートも出力されます。

npx @modelcontextprotocol/inspector --cli node build/index.js \
  --method tools/list --strict --format json \
  | jq -e '[.schemaFindings[]?.findings[]? | select(.severity=="error")] | length == 0' > /dev/null

スクリプト化する際に重要なリポジトリガイドの詳細が 2 つあります。指摘がない場合 schemaFindings キー自体が存在しないため、フィルターは省略可能な形式を使います。また、厳格な検査はスキーマを生成しているサーバーの CI で実行する価値があります。依存関係の更新で、誰もスキーマを編集していないのに出力形状が変わることがあるからです。

引数にも同じ注意が必要です。--tool-arg key=value は値が JSON として解析できる場合に解析するため、数値に見える値が数値としてサーバーに届くことがあります。--tool-args-json はオブジェクト全体をそのまま渡します。ZIP コードや注文 ID など型を持つ値には JSON 形式を優先し、引数の確認はスキーマの確認と同じテスト実行に含めます。

コントラクトテストと受け入れテストでは何を確認する?

コントラクトテストは、製品が依存する 1 つの動作をサーバーが止めたときに失敗する、最小のテストです。リポジトリのスモークテストガイドがその形を定義しています。接続し、MCP を話すことを証明し、依存する 1 つか 2 つの動作がまだ機能することを証明し、機能しなければジョブを失敗させます。適合性テストスイートではない点が重要です。

次の 4 つの手順をこの順で実行します。

  1. ハンドシェイク: initialize がプロトコルバージョンを返すことをアサートします。
  2. 公開サーフェス: 依存するすべてのツール名が tools/list に現れることをアサートし、リソースとプロンプトについても同様に確認します。
  3. 動作: 繰り返し呼んでも安全な代表ツールを 1 つ呼びます。つまり読み取り専用・冪等・低コストなツールです。スモークテストはコミットごとに実行するため、メールを送信するツールの出番ではありません。
  4. ペイロード: 終了コードが 0 であることだけでなく、構造化コンテンツのフィールドやテキストコンテンツの部分文字列をアサートします。
npx --yes @modelcontextprotocol/inspector@2.5.0 --cli \
  --transport http --server-url "$SERVER_URL" \
  --connect-timeout 10000 --stored-auth-only --format json \
  --method initialize | jq -e '.result.protocolVersion' > /dev/null

jq -e は出力から独自の終了ステータスを設定するため、フィールドの欠落やアサーションの偽は追加のシェルなしでステップを失敗させます。stdout は結果、stderr は診断なので分けたままにしてください。jq にマージすると解析が壊れます。バージョンも厳密に固定します。npx は実行のたびに最新リリースを解決するため、同じコミットが後日には別の Inspector で実行される可能性があります。

Playwright がこのセクションに関係するのは、サーバーの役割にブラウザが含まれる場合だけです。Playwright のテストドキュメントでは、各テストが新しいブラウザコンテキスト(新しいブラウザプロファイルに相当)を取得するため、ページはテスト間で分離されると説明されています。その分離はリグレッションテストにとって利点であり、Playwright のスイートが通ってもログイン状態の動作を証明できない理由でもあります。サーバーの価値が既存のサインイン済みセッションに依存する場合、エンドツーエンドの確認は別の場所で行う必要があります。これについては CI のセクションで戻ります。

エラー・タイムアウト・リトライの経路をテストするには?

エラー動作も API の一部です。Inspector CLI は安定した語彙を提供します。非ゼロの終了はすべて失敗クラスに対応し、CLI は 1 行の JSON エラーエンベロープを stderr に書き出します。

終了コード意味
0成功
1使用方法または予期しないエラー
2--app-info プローブが報告する、ツールに MCP App が見つからない状態
3サーバーが 401、403、OAuth チャレンジなどの認証を要求している
4サーバーに到達できない。DNS、接続拒否、タイムアウトなど
5ツールエラー。tools/call が isError true を返したか、ツールが見つからない
6リポジトリのスモークテストガイドによる、error 重大度の strict スキーマ指摘
OpenCode セッションがコントラクトをクロスチェックする中、MCP Inspector CLI ドキュメントの終了コードのセクションを閲覧している ego (lite) Space
可視の ego (lite) Space で CLI の終了コードのコントラクトをクロスチェック。公開ドキュメントをブラウザに開いたままセッションが各コードを検証し、Space では Agent is in control・Take over・Stop をすぐに使えます。

これらのコードを網羅性に変えるプラクティスが 3 つあります。1 つ目は接続に上限を設けることです。--connect-timeout はアドホックな対象では 15000 ミリ秒がデフォルトで、0 にすると無効になります。CI ジョブが無効化されたタイムアウトを引き継いではいけません。応答のないホストはジョブ自身の制限に殺されるまでランナーを止めてしまうからです。

2 つ目は拒否をアサートすることです。サーバーがルート外のパスを拒否すべきなら、その呼び出しをテストで実行し、失敗を要求します。isError true は終了コード 5 なので、「失敗したか」だけを問う確認では拒否とクラッシュを区別できません。区別が必要な場合はステータスを取得し、正確に 5 を要求してください。

3 つ目は jq の前にステータスを取得することです。pipefail は右端の非ゼロステータスを報告するため、アサーションも失敗して tools/call が 5 で終了すると 1 として現れ、失敗クラスが失われます。副作用のあるツールでは、リトライの契約をランナーではなくテストで決めます。意図した 1 回の試行のあとは停止して報告し、黙ってリトライを繰り返さないことです。

認証・権限・インジェクションの境界をテストするには?

テストが通ったことに意味があるかを決める境界の問いが 2 つあります。サーバーが持つ権限は何か、そして信頼できないコンテンツがそれを別の方向へ向けようとしたときに何が起きるかです。

認証: 正常系ではなく、チャレンジを証明する。 CI では、対話型の OAuth フローはデフォルトで不適切です。CLI はブラウザを開き、最大 15 分間ループバックコールバックを待つことがあります。--stored-auth-only は対話型 OAuth を開始せず、ブラウザも開かず、適切なトークンがストアになければ即座に失敗します。ストアはジョブごとに MCP_STORAGE_DIR と MCP_INSPECTOR_OAUTH_STATE_PATH で分離し、この優先順序に従います。そして微妙な点を忘れないでください。このフラグはチャレンジを返さないサーバーに対しては何もしないため、成功した実行は認証が行われた証拠にはなりません。認証をアサートするには、分離したストアで有効なトークンなしに 1 回実行し、終了コード 3 を要求します。

CI で最も扱いやすい認証情報は、多くの場合 OAuth ではありません。シークレットストアから静的な Authorization ヘッダーを渡します。サーバーの URL や stdio の引数に認証情報を埋め込まないでください。CLI はそこをマスクしません。

権限の境界: サーバーは、自分宛てに発行されていないトークンを受け入れてはいけません。MCP のセキュリティベストプラクティス文書はトークンパススルーを禁止し、オーディエンス検証を要求しています。外部のトークンを受け入れると OAuth の境界が壊れ、サーバーが他者の認証情報の中継地点になってしまうからです。同じ文書はスコープの最小化も求めています。最小のスコープ集合から始め、操作が必要とするときだけ昇格させ、包括的なスコープを避けます。ステートハンドルにも同じ規律が必要です。ハンドルの所持を認証として扱ってはならず、ハンドルはサーバー側で認証済みユーザーに紐づけるべきです。

プロンプトインジェクションとツールの悪用: サーバーが処理する必要のあるフィクスチャに、無害な矛盾する指示を仕込み、出力をサーバーの要約ではなく元の文書と照合します。与えられた指示よりもファイル内のテキストに従うサーバーは、このチェックポイントで失敗します。キャプチャした出力には粗いシークレットスキャンも追加してください。ツールの結果やエラーメッセージに認証情報がそのまま返るのは、実際の漏えいクラスです。ネットワーク側では、悪意あるサーバーが OAuth メタデータを内部アドレスやクラウドメタデータのエンドポイントに向けられることを忘れないでください。サーバー上に配備するクライアントは HTTPS を要求し、プライベートアドレス範囲をブロックし、リダイレクト先を検証すべきです。最後に、ローカルサーバーのインストールはコード実行として扱います。ワンクリック設定フローは実行されるコマンドを正確に表示し、明示的な承認を求め、起動するものをサンドボックス化すべきです。

テスト実行中に何をログに残すべき?

深夜 2 時に確認が失敗したとき、残るのはログです。ログの出力先はトランスポートが決めます。ローカルの stdio サーバーは stderr にログを出すべきで、ホストアプリケーションが自動的に収集します。stdout に出してはいけません。プロトコルの動作を妨げるからです。Streamable HTTP のサーバーにはそのような収集がありません。stderr はクライアントに収集されないため、独自の集約や OpenTelemetry を使い、リクエストとレスポンスの確認には標準的な HTTP ツールを使います。notifications/message によるプロトコルレベルのログはプロトコルバージョン 2026-07-28 で非推奨となったため、新しいログ基盤をそれに載せないでください。

インシデントレビューで必ず求められるイベントを記録します。起動ステップ、リソースアクセス、ツール実行、エラー条件、パフォーマンス指標です。トランスポートが提供する場合は、それぞれにタイムスタンプとリクエスト ID を付けます。保存前にかならずサニタイズし、認証情報・個人データ・生のセッション状態がログやチケット、スクリーンショットに残らないようにします。

クライアント側では Inspector が記録装置になります。Protocol タブは JSON-RPC の記録を、Network タブは HTTP と SSE サーバーの HTTP ビューを、Console タブは stdio サーバーの stderr を保持し、エントリはクリアまたはエクスポートできます。CLI 自身の出力も証跡に加えます。stdout の JSON 結果と stderr の 1 行エラーエンベロープを実行と一緒に保存してください。障害をレビューするときは、サーバーの要約ではなく生のやり取りを読みます。

もう 1 つ、スイートに入れるべきログ確認があります。プロトコルの互換性です。デバッグガイドは、サーバーが対応するプロトコルバージョンを確認するために server/discover を呼ぶことを勧めています。未対応バージョンのエラーは data フィールドにバージョン一覧を返すからです。また、すべてのリクエストはプロトコルバージョンとクライアントケイパビリティのメタデータを運ぶ必要があり、どちらか欠けたリクエストは無効なパラメータとして拒否されると注記しています。

CI でデプロイをゲートするには?

ゲートは、手元で実行したのと同じスモークスクリプトです。Inspector のバージョンを固定し、最小権限のランナーを使い、対応できる失敗クラスを返します。

smoke:
  runs-on: ubuntu-latest
  permissions:
    contents: read
  steps:
    - uses: actions/checkout@v7
      with:
        persist-credentials: false
    - uses: actions/setup-node@v7
      with:
        node-version: "22.x"
    - run: bash smoke.sh
      env:
        SERVER_URL: ${{ vars.MCP_SERVER_URL }}
        MCP_TOKEN: ${{ secrets.MCP_TOKEN }}

そのジョブを信頼できるものにする習慣が 3 つあります。Inspector を固定して --yes を渡し、無人ランナーが初回実行のプロンプトで止まらないようにします。ジョブは npm からパッケージをダウンロードして実行するため、permissions ブロックを最小限にし、persist-credentials を false にします。そして失敗クラスを報告します。pipefail は右端の非ゼロステータスを報告し、クラスが失われるため、パイプライン内のどの jq よりも前に CLI の終了コードを取得してください。

ゲートが終わる場所から、最後の一マイルが始まります。Inspector が証明するのはプロトコル、スキーマ、ツール呼び出し、失敗クラスです。レンダリングされた UI は再現できず、ブラウザを動かすサーバーに実際のサインイン済みセッションを渡すこともできません。ブラウザ向けの MCP サーバーがまさにそのケースです。サーバーの品質は、引き継ぐブラウザ状態に依存します。その最終確認に使うブラウザが ego (lite) です。既存のログインを引き継ぐローカルの Chromium で、各エージェントタスクは専用の Space(可視の作業スペース)で動くため、実行を眺め、ログインや確認のプロンプトを自分で完了し、同じセッションのままエージェントに続行させられます。具体的な確認手順はこうです。ego-browser スキルでエージェントを接続し、サインイン済みサイト上のサーバーのエンドツーエンドシナリオを指示し、サイトが人を求めたタイミングで実行中に引き継ぎます。

複数のエージェントタスクが並行して動作する ego (lite) のマルチ Space グリッド
ego (lite) はエージェントのタスクをそれぞれ可視の Space に保ちます。ここでは複数のブラウザタスクが並行して動作し、それぞれを眺めたり中断したりできます。

ego (lite) が不要な場面も明確にしておきます。プロトコルのハンドシェイク、ツール一覧、スキーマ検証、stdio サーバー、CI ゲートそのものには Inspector だけで十分であり、そこに実ブラウザを加えてもテストが遅く、不安定になるだけです。ego (lite) を使うのは、サーバーの正しさが新しいプロファイルでは作れない状態に依存する場合だけです。既存のログイン、目視したい実行、エージェントだけでは完了できない引き継ぎのいずれかです。

ブラウザを動かすケースでは、そのエンドツーエンドの Space を先に用意してください。ego (lite) と Playwright MCP のルートを機能ごとに比較できます。または Mac 版の ego (lite) をダウンロードしてください。

FAQ

デプロイ前に MCP サーバーをテストする最適なツールは?

MCP Inspector は MCP サーバーのテストとデバッグにおけるリファレンス開発ツールで、MCP のデバッグガイドも最初に確認すべきものとしています。1 つのパッケージに Web UI、スクリプトと CI 向けの CLI、ブラウザのない環境向けのターミナル UI が含まれ、Node 22.19.0 以降が必要です。

MCP Inspector はブラウザなしで CI で実行できる?

はい。CLI クライアントはまさにそのために作られています。アサーションごとに 1 プロセス、--format json による機械可読な結果、認証・到達不能・ツールエラーを区別する安定した終了コードです。--stored-auth-only を付ければ、対話型 OAuth のコールバックを待たずに即座に失敗します。npx は指定しないと最新リリースを解決するため、バージョンは厳密に固定してください。

MCP のツールスキーマを検証するには?

ツールを一覧表示し、厳格に検査します。tools/list はクライアントが受け取る内容を示し、厳格な検査はパス・問題・推奨される修正方法とともに移植性の指摘を報告します。JSON 出力では指摘は schemaFindings 配列で届き、リポジトリのスモークテストガイドでは error 重大度の指摘は終了コード 6 になると記載されています。

MCP サーバーのエラーとタイムアウトの扱いをテストするには?

まず --connect-timeout で接続に上限を設け、期待する失敗をアサートします。拒否は偶発的に成功するのではなく終了コード 5 で失敗すべきで、到達不能なサーバーは 4、認証チャレンジは 3 を返すべきです。pipefail は右端の非ゼロステータスを報告し失敗クラスが失われるため、パイプライン内のどの jq よりも前に CLI の終了コードを取得してください。

MCP サーバーのプロンプトインジェクションとツール悪用を確認するには?

サーバーが処理する必要のあるファイルに無害な矛盾指示を仕込み、出力をサーバーの要約ではなく元の文書と照合します。キャプチャしたツール出力とエラーメッセージには粗いシークレットスキャンを追加し、正常系が動くことだけでなく、範囲外の要求が拒否されることをアサートします。MCP のセキュリティベストプラクティス文書は周辺の制御も扱っています。トークンパススルーは禁止され、スコープは最小から始めるべきで、ローカルサーバーは実行を選ぶコードとして扱うべきです。

MCP サーバーのテストに ego (lite) は必要?

プロトコル、スキーマ、stdio、CI の確認には不要です。それが MCP Inspector の役割です。ego (lite) が重要になるのは、サーバーの正しさが実際のサインイン済みブラウザに依存する最後の一マイルだけです。既存のログインを持つローカルの Chromium の Space、目視できる実行、ログインや確認ステップでの人の引き継ぎが該当します。新しいブラウザプロファイルではサーバーが必要とする状態を再現できない場合に使ってください。