
MCP向けWireshark。AIクライアントとMCPサーバーの間の透過プロキシ。すべての呼び出しをターミナルでライブ監視し、検出結果に基づいてCIを失敗させ、OpenTelemetryスパンをエクスポートします。
<p align="center"> <img src="https://assets.kitploit.com/production/public/readmes/9109/91d664ea266713affb29238906792777021b43fa6627b13f46382f48ad340a61.png" alt="mcpsnoop" width="440"> </p> **MCP 版 Wireshark。** mcpsnoop は AI クライアントと MCP サーバーの間に位置し、両者がやり取りするすべての JSON-RPC フレームを、どちら側にも変更を加えることなく記録します。ターミナルでライブに監視したり、検出結果に基づいて CI を失敗させたり、OpenTelemetry スパンとしてトレーシングバックエンドに送信したりできます。 [](https://github.com/kerlenton/mcpsnoop/actions/workflows/ci.yml) [](https://pkg.go.dev/github.com/kerlenton/mcpsnoop) [](LICENSE) [](https://github.com/marketplace/actions/mcpsnoop) <p align="center"> <img src="https://assets.kitploit.com/production/public/readmes/9109/30466d77be15250e4bab6639e48a4cd5b0d44cd96e48606b60c6bacb67c15c3d.gif" alt="mcpsnoop demo"> </p> ## 課題 公式の [MCP Inspector](https://github.com/modelcontextprotocol/inspector) は独自のクライアントとして接続するため、*あなたの*クライアント(Cursor、Claude Code、Codex)が実際にサーバーへ送信している内容を目にすることはありません。また、リクエストの到着を待つ仕組みでは、モデルが呼び出さなかった呼び出しや、誤った引数で行った呼び出しを表示することはできません。ツールが黙って呼び出されない、ケイパビリティが噛み合わない、呼び出しが単にハングする——そんなとき、あなたはログを掘り返して推測するしかありません。 **mcpsnoop は代わりに実際のデータパスに位置します。** サーバーコマンドをこれでラップすれば、実際のクライアントとサーバーが通信する様子を、すべての JSON-RPC フレームについてライブで監視できます。 ## CI での利用 このページは [mcpsnoop GitHub Action](https://github.com/marketplace/actions/mcpsnoop) のリスティングも兼ねているため、その全容をここに示します。キャプチャしたセッションを検査し、すべての検出結果をコードスキャンアラートとして記録し、ゲート条件に該当した場合にジョブを失敗させます。 ```yaml permissions: security-events: write contents: read steps: - uses: kerlenton/[email protected] with: session: artifacts/session.jsonl ``` キャプチャを手元に用意できませんか?一度だけ自分のクライアントでセッションを記録してコミットすれば、あとはアクションがすべてのビルドに対してその記録をリプレイします。CI ではモデルも API キーも実行されません。リプレイは他のキャプチャと同様に検証され、サーバーが記録時よりも悪化した場合にはジョブも失敗します。Streamable HTTP 経由で到達するサーバーには、そのエンドポイントを指定した `target` が設定され、記録はどちらのトランスポートでもリプレイできます。 ```yaml steps: - uses: kerlenton/[email protected] with: replay: tests/mcp/claude-code-session.jsonl server: node dist/index.js ``` [releases ページ](https://github.com/kerlenton/mcpsnoop/releases)から、任意のリリースを固定して使用できます。すべての入力と出力は後述の[GitHub Action](#the-github-action)に記載されており、チェックが失敗しうるすべてのシグナルは[docs/CI.md](https://github.com/kerlenton/mcpsnoop/blob/main/docs/CI.md)に記載されています。 ## OpenTelemetry MCP リビジョン 2026-07-28 では、プロトコルレベルの Logging が非推奨となり、実装は stdio 上の `stderr`、または構造化された可観測性のための OpenTelemetry へ移行することが推奨されています。mcpsnoop はクライアントやサーバーに手を加えることなく、その両方をカバーします。stdio サーバーの `stderr` 行はそのフレームの隣にストリーム内で表示され、すべてのリクエストは[MCP 向け OpenTelemetry セマンティック規約](https://github.com/open-telemetry/semantic-conventions-genai/tree/main/model/mcp)に従うスパンになります。 ```bash mcpsnoop export -T otlp -o trace.json # spans from a capture mcpsnoop --otlp-endpoint http://localhost:4318/v1/traces -- node build/index.js # spans as calls complete ``` ツール呼び出しは `tools/call search` という名前のスパンとして到着し、 `mcp.method.name`、`gen_ai.tool.name`、`error.type` を伴うため、mcpsnoop 向けに構築されたダッシュボードではなく、MCP 向けに構築されたダッシュボードに収まります。Prometheus 向けのライブツールメトリクスはフラグ1つで有効になります。どちらも [docs/OPENTELEMETRY.md](https://github.com/kerlenton/mcpsnoop/blob/main/docs/OPENTELEMETRY.md) に記載されています。 ## クイックスタート 何も設定せずに、すぐに試せます。 ```bash mcpsnoop demo ``` 実際に使用するには、サーバーをクライアントのMCP設定でラップしてください。 ```json { "mcpServers": { "my-server": { "command": "mcpsnoop", "args": ["--", "node", "build/index.js"] } } } ``` `--` 以降は、通常サーバーを起動するコマンドです。すでに使用しているもの、例えば `python server.py`、`npx -y @scope/server`、またはコンパイル済みバイナリに置き換えてください。 Claude Desktop では、その編集を手動で行う必要はありません。 ```bash mcpsnoop wrap my-server # route my-server through mcpsnoop mcpsnoop unwrap my-server # put it back ``` `wrap` は `claude_desktop_config.json` を見つけ、初回に `claude_desktop_config.json.mcpsnoop.bak` へコピーし、そのサーバーの エントリだけを書き換えるため、あなたのフォーマットや他のすべてのサーバーはそのまま残ります。 書き換えられたエントリ内では、キーはアルファベット順に並びます。`unwrap` はファイルを復元し、ラップされたサーバーがなくなるとバックアップを削除します。 MCP サーバーは起動時に一度だけ起動されるため、どちらの後でも Claude Desktop を再起動してください。 その後は通常どおりクライアントを使用し、UI を開いてください。 ```bash mcpsnoop ``` フラグもソケットパスも起動順序も覚える必要はありません。shimとUIは自動的に互いを見つけ、UIはディスクから過去のセッションをバックフィルします。 ストリーミング可能なHTTPサーバーの場合は、mcpsnoopをリバースプロキシとして実行します。 ```bash mcpsnoop http --target http://localhost:3000/mcp --listen :7000 ``` すべてのレスポンスの HTTP ステータスがストリームに表示されるため、それ自体では JSON-RPC メッセージを持たないレスポンスも、何もないのではなく可視のフレームとして表示されます。これには、401 チャレンジ、拒否された Origin に対する 403、通知を確認応答する 202、そしてターゲットにまったく到達できない場合の 502 が含まれます。401 の `WWW-Authenticate` ヘッダーはそのまま保持され、インスペクターに表示されます。これは認証スキームと次に参照すべきリソースメタデータを示すためです。TUI で `status:401` によりステータスでフィルタリングするか、`status:err` で任意の失敗によりフィルタリングできます。4xx または 5xx はエラーとしてカウントされるため、デフォルトの `mcpsnoop check` 実行はそれで失敗し、それが応答した呼び出しは、まだ待機中のものではなく失敗したものとして扱われます。 自分のサーバーがない場合は?公開テストサーバーに対して、自分のクライアントで駆動して[実際に試す](https://github.com/kerlenton/mcpsnoop/blob/main/docs/TRY_IT.md)ことができます。セッションが発生した後に検査するには、[ログから過去のセッションをレビューする](https://github.com/kerlenton/mcpsnoop/blob/main/docs/POST_MORTEM.md)を参照してください。 ## インストール ### npm Go ツールチェーンは不要です。ほとんどの MCP サーバーは Node または Python で書かれているため、これが最も手軽な導入方法です。 ```bash npx mcpsnoop -- node build/index.js ``` npm パッケージ自体にはコードは含まれていません。6つのプラットフォームパッケージがそれぞれ1つのビルドを収めており、npm はお使いのマシンに一致する1つだけをインストールするため、インストール時にダウンロードするものも、プロキシでブロックを解除するものもありません。毎回取得するのではなく手元に保持しておくには、`npm i -g mcpsnoop` を実行してください。 ### Homebrew ```bash brew install mcpsnoop ``` ### Go ```bash go install github.com/kerlenton/mcpsnoop/cmd/mcpsnoop@latest ``` 各プラットフォーム向けのビルド済みバイナリは [Releases](https://github.com/kerlenton/mcpsnoop/releases) ページにあります。 mcpsnoop は bash、zsh、fish、PowerShell 向けの補完を提供しています。セットアップ手順については `mcpsnoop completion <shell> --help` を実行してください。補完の有効化と、お使いの OS でのインストールパスについて説明しています。 ## コマンド | コマンド | 機能 | |---|---| | `mcpsnoop -- <server>` | stdio サーバーを透過的なシムとしてラップする | | `mcpsnoop` | ライブ TUI を開く | | `mcpsnoop --metrics-listen <addr>` | ヘッドレスハブを実行し、ライブ Prometheus メトリクスを公開する | | `mcpsnoop http --target <url>` | streamable-HTTP サーバーをプロキシする | | `mcpsnoop export` | セッションを json、html、text、har、otlp としてレンダリングする | | `mcpsnoop check` | エラー、無効なフレーム、ツール結果が自身の outputSchema に違反するなどの警告、ルーティングの不一致、ハングした呼び出し、遅延した結果、二重に実行された可能性のある呼び出し、ツールのドリフト、緩和された、または何も示さないアノテーション、レイテンシ予算のいずれかで CI を失敗させる | | `mcpsnoop baseline` | 信頼済みのツール定義を検査、承認、またはリセットする | | `mcpsnoop diff` | 2 つのキャプチャ済みセッション間でツールと呼び出しを比較する | | `mcpsnoop open` | 保存済みセッションを TUI で開く | | `mcpsnoop mock <session>` | キャプチャ済みセッションを stdio MCP サーバーとして再生する | | `mcpsnoop replay <session> -- <server>` | stdio または Streamable HTTP 経由で、記録済みセッションのクライアント側を使ってサーバーを駆動し、結果を記録と比較する | | `mcpsnoop inventory` | このマシン上で mcpsnoop を通じて実行されたすべてのサーバーを一覧表示する | | `mcpsnoop stats` | 保存されたすべてのキャプチャをサーバーとツールごとに 1 行に集約する | | `mcpsnoop clients` | 各 MCP クライアントが実際にワイヤー上で何を行ったかを、名前とバージョンごとに表示する | | `mcpsnoop prune` | 指定したカットオフより古い保存済みセッションログを削除する | | `mcpsnoop wrap <server>` | Claude Desktop のサーバーの 1 つを mcpsnoop 経由でルーティングする | | `mcpsnoop unwrap <server>` | そのサーバーのエントリを元の状態に戻す | | `mcpsnoop remote <user@host>` | SSH トンネルコマンドを出力する | | `mcpsnoop demo` | スクリプト化されたセッションを再生する | 完全なリストについては `mcpsnoop help` を、特定のコマンドのフラグについては `mcpsnoop help <command>` を実行してください。 ## 比較 これらのツールはそれぞれ異なる問いに答えるものであり、ツールがどこに位置するかによって、どの問いに答えられるかが決まります。 | ツール | 位置 | 用途 | |---|---|---| | [MCP Inspector](https://github.com/modelcontextprotocol/inspector) | 独自のクライアントとして、あなたのサーバーに接続 | ブラウザまたはスクリプト可能な CLI から、サーバーを手動で試す | | [Snyk Agent Scan](https://github.com/snyk/agent-scan) | 独自のクライアントとして、設定内のサーバーを起動または接続してツールを読み取る | マシン上のエージェント、MCP サーバー、スキルをプロンプトインジェクションや脆弱性についてスキャンする | | [MCP Observatory](https://github.com/KryptosAI/mcp-observatory) | 独自のクライアントとして、サーバーを起動してテスト、記録、検証する | 攻撃シミュレーション、スキーマドリフト、記録・再生・検証を備えた、CI でのセキュリティおよびリグレッションテスト | | [mcprec](https://github.com/erphq/mcprec) | ワイヤー上、クライアントとサーバーの間 | セッションを一度記録し、ネットワークなしでテストフィクスチャとして再生する | | mcpsnoop | ワイヤー上、クライアントとサーバーの間 | 実際のクライアントとサーバーが何を言っているかを監視し、実際のクライアントのセッションを各ビルドに対して再生し、それで CI を失敗させ、OpenTelemetry としてエクスポートする | 独自のクライアントであるツールは、自分が行う呼び出しは見えますが、あなたのクライアントが行う呼び出しは見えません。そのため、モデルが決して行わなかった呼び出しや、誤った引数で行った呼び出しを表示することはできません。スキャナーは、あなたが信頼する前に定義を読み取ります。mcpsnoop は、信頼した後に何が起こるかを監視します。定義が後で変更されるかどうかも含めて。 ## 仕組み <p align="center"> <picture> <source media="(prefers-color-scheme: dark)" srcset="assets/architecture-dark.svg"> <img alt="mcpsnoop は AI クライアントと MCP サーバーの間のパイプに位置し、すべての JSON-RPC フレームをライブターミナル UI にコピーする" src="https://raw.githubusercontent.com/kerlenton/mcpsnoop/HEAD/assets/architecture-light.svg" width="760"> </picture> </p> mcpsnoop は 1 つのバイナリに 2 つの役割を備えています。`mcpsnoop -- <server>` はクライアントが起動する透過的なシムであり、バイト列をそのまま転送しつつ、すべてのフレームのコピーをハブへ送り出します。引数なしの `mcpsnoop` はそのハブとライブ TUI です。両者は既知のソケットとオンディスクのログを介してペアになるため、どちらを先に起動する必要もありません。 Inspector のように脇に置かれるのではなく実際のパイプの中に位置するため、サーバーがどの言語で書かれていようと、実際のクライアントとサーバーが交わす内容を正確に見ることができます。そのメモリとディスクを何が制限しているかは [docs/HOW_IT_WORKS.md](https://github.com/kerlenton/mcpsnoop/blob/main/docs/HOW_IT_WORKS.md) に記載されています。 ## GitHub Action 以下はすべて、このアクションがあなたに代わって行うことです。mcpsnoop をインストールし、キャプチャを検査し、検出結果を Security タブに記録し、ゲート条件に該当した場合にジョブを失敗させます。 ```yaml permissions: security-events: write contents: read steps: - uses: kerlenton/[email protected] with: session: artifacts/session.jsonl ``` リリースを固定してください。どのリリースでも構いません。最新のものは [releases page](https://github.com/kerlenton/mcpsnoop/releases)にあります。意図的に 浮動の`v1`はありません。固定したリリースはアクションがインストールするバイナリでもあるため、 両者が食い違うことはなく、古くなるバージョンのデフォルトも存在しません。 | 入力 | | |---|---| | `session` | チェックする`.jsonl`キャプチャ、またはそのディレクトリ。リポジトリルートからの相対パス。これか`replay`のどちらかを指定 | | `replay` | コミット済みの記録を`server`または`target`に対してリプレイし、そのキャプチャをチェックする。リグレッションがあればジョブも失敗する | | `server` | テスト対象のサーバーを起動するコマンド。コマンドライン上と同様に引用符で囲む。stdioサーバーでは`replay`と併せて必須。`target`と併用する場合は先にHTTPサーバーを起動し、すでに起動済みなら省略可能 | | `target` | リプレイ先のStreamable HTTPエンドポイント。例: `http://localhost:3000/mcp`。認証情報は`replay-args`に`--header`として渡し、ステップログではその値が隠されて表示される | | `replay-args` | その他の`replay`フラグ。例: `--read-only`。`--out`は拒否される。キャプチャの保存先はアクションが決めるため | | `fail-on` | `--fail-on`と同様。デフォルトはCLIのデフォルトと同じ | | `args` | その他の`check`フラグ。コマンドライン上と同様に引用符で囲む。`--format`は拒否される。レポートはアクションが読み取るため | | `upload-sarif` | レポートをコードスキャンに送信する。`true` | | `category` | コードスキャンの名前空間。`mcpsnoop`。マトリックスのレグごとに変えないと、レグ同士が上書きし合う | | `fail-on-findings` | 検出結果があればジョブを失敗させる。`true`。`false`にするとアラートを登録し、コードスキャンの必須チェックに判断を委ねる | | `version` | インストールするmcpsnoop。デフォルトは固定したリリース | | `install` | mcpsnoopがすでにPATH上にある場合は`false`。リリースがビルドされていないプラットフォームでの導入方法 | 出力は`outcome`、`sarif`、`exit-code`、`capture`です。`capture`はチェックしたキャプチャのパスで、 `replay`の場合はリプレイが書き出したものであり、アーティファクトとして保持する価値があります。`outcome`は`passed`、 `findings`、`error`のいずれかで、3つ目は個別に扱う価値があります。これは何もチェックされなかったことを意味し、 何も見つからなかったこととは異なります。**チェックできなかった実行は`fail-on-findings`の設定にかかわらずジョブを失敗させます**。 何も検証せずにグリーンになるパイプラインは、失敗するパイプラインより悪いためです。 ジョブには`security-events: write`が必要です。ない場合、アップロードは403を返します。コードスキャンのないリポジトリでは `upload-sarif: false`を設定してください。アクションを使わずに同じチェックを実行する方法、失敗の原因となりうるシグナル、終了コードについては [docs/CI.md](https://github.com/kerlenton/mcpsnoop/blob/main/docs/CI.md)に記載されています。 ## ドキュメント | ページ | 内容 | |---|---| | [Checking sessions in CI](https://github.com/kerlenton/mcpsnoop/blob/main/docs/CI.md) | すべてのビルドに対する記録のリプレイ、`check`が失敗しうるすべてのシグナル、終了コード、アサーション、JUnitおよびSARIFレポート、2つのセッションの比較、アクションを使わない場合の設定方法 | | [OpenTelemetry and Prometheus](https://github.com/kerlenton/mcpsnoop/blob/main/docs/OPENTELEMETRY.md) | スパンとそれが運ぶ内容、コレクターへのストリーミング、ライブのツールメトリクス | | [Using mcpsnoop](https://github.com/kerlenton/mcpsnoop/blob/main/docs/USING.md) | キー、フィルタリング、エクスポート形式、リプレイ、サーバーがユーザーに要求した内容、コンテキスト内のコスト、キャプチャ全体の統計、各クライアントが実際に送信する内容、サーバーインベントリ、リモートマシン、設定ファイル | | [Redaction](https://github.com/kerlenton/mcpsnoop/blob/main/docs/REDACTION.md) | キャプチャ中、またはすでに持っているキャプチャからのシークレットの除去 | | [How it works](https://github.com/kerlenton/mcpsnoop/blob/main/docs/HOW_IT_WORKS.md) | メモリの上限、履歴の制限、古いログの削除 | | [Try it for real](https://github.com/kerlenton/mcpsnoop/blob/main/docs/TRY_IT.md) | 公開テストサーバーを自分のクライアントで操作する | | [Review past sessions](https://github.com/kerlenton/mcpsnoop/blob/main/docs/POST_MORTEM.md) | セッションログの保存場所と、事後に開く方法 | | [The capture format](https://github.com/kerlenton/mcpsnoop/blob/main/docs/CAPTURE_FORMAT.md) | セッションログの各行が保持する内容と決して変わらない点、キャプチャを読み取るツール向けのJSON Schema | ## セキュリティ mcpsnoopはラップしたサーバーコマンドを実行するため、信頼できるサーバーだけをラップし、 信頼できないものはコンテナ内で実行してください。クライアント設定に入れていないものを実行することは決してありません。 リモートワークフローでは、SSHトンネリングまたはSSHファイル転送を使用して、トランスポート認証、暗号化、ホスト検証、鍵ローテーション、監査ポリシーを既存のSSH設定内に維持してください。 ### キャプチャがターミナルに及ぼしうる影響 キャプチャとは、相手側が選んだデータです。フレームやstderrの行にはターミナルエスケープシーケンスが含まれる可能性があり、ターミナルは渡されたものにそのまま反応します。その影響は表示の乱れから、OSC 52によるシステムクリップボードへの書き込みまで及びます。mcpsnoopは自身が生成する色シーケンスのみを保持し、フレームがターミナルに届く前にその他のエスケープをすべて破棄します。テーブルのセルは制御文字を引用して存在を可視化し、インスペクターはそれらを完全に明示し、クリップボードへのコピーはエスケープされた形式を保持するため、何も隠されず、何も実行されません。 ### キャプチャに含まれるもの キャプチャされたフレームには、プロンプト、ツール引数、認証情報、ツール結果が含まれる場合があります。[docs/REDACTION.md](https://github.com/kerlenton/mcpsnoop/blob/main/docs/REDACTION.md)では、キャプチャ中またはキャプチャ後のそれらの除去について説明しています。脆弱性を報告するには、[SECURITY.md](https://github.com/kerlenton/mcpsnoop/blob/main/SECURITY.md)を参照してください。 ## コントリビューション Issueとプルリクエストを歓迎します。詳細は[CONTRIBUTING.md](https://github.com/kerlenton/mcpsnoop/blob/main/CONTRIBUTING.md)を参照してください。 ## ライセンス [MIT](https://github.com/kerlenton/mcpsnoop/blob/main/LICENSE)