mcpprobe について
mcpprobeは、開発者やセキュリティチーム向けのローカル読み取り専用MCPサーバースキャナーです。標準ではツールを呼び出さずにプロトコルやメタデータのリスクを調べ、証拠付きのJSON、SARIF、ターミナルレポートを出力します。
主な機能
- 01認証とトランスポートの検査
- 02ツールメタデータの汚染検査
- 03OWASPリスクへの対応付け
- 04JSON、SARIF、ターミナルレポート
- 05SHA-256ベースラインによる変更検出
- 06テレメトリーなしのローカル実行
活用シーン
- 01リリース前のMCPサーバー確認
- 02CIでのセキュリティ検査
- 03ツールメタデータと承認済み基準の比較
- 04許可されたサーバーの検出結果と網羅状況の確認
MCP 対応
リモートHTTPおよびローカルstdioのMCPサーバーをスキャンします。標準のパッシブモードではツールを呼び出さず、アクティブ検査には認可と所有権の確認が必要です。
設定
リモートサーバーはインストール不要です。クライアントを選んで設定をコピーするか、ワンクリックで導入できます。
https://mcpprobe.tech/mcpclaude mcp add --transport http tech-mcpprobe-scanner https://mcpprobe.tech/mcp{"mcpServers":{"tech-mcpprobe-scanner":{"type":"http","url":"https://mcpprobe.tech/mcp"}}}Cursor で開く{"servers":{"tech-mcpprobe-scanner":{"type":"http","url":"https://mcpprobe.tech/mcp"}}}VS Code で開く{"mcpServers":{"tech-mcpprobe-scanner":{"type":"http","url":"https://mcpprobe.tech/mcp"}}}{"mcpServers":{"tech-mcpprobe-scanner":{"serverUrl":"https://mcpprobe.tech/mcp"}}}コマンドはターミナルで実行し、JSON は各クライアントの MCP 設定に貼り付けて再起動します。認可が必要なサーバーは初回接続時にログインを求めます。
ツール
詳細
mcpprobe
Model Context Protocol サーバー向けのセキュリティスキャナーです。 認証、OAuth メタデータ、トランスポートの適合性、ツールの説明文へのポイズニング、ラグプル、メタデータ内のシークレット、詳細すぎるエラー、基本的なリソース制限をチェックし、検出結果を OWASP MCP、Agentic、LLM Top 10 の各リストに対応付けて、JSON、SARIF 2.1.0、読みやすいターミナル要約を出力します。
ローカルで実行され、テレメトリーは送信せず、デフォルトモードではツールを呼び出しません。
自分が所有するサーバー、またはテストの明示的な許可を得ているサーバーのみをスキャンしてください。 所有権のルールを参照してください。
60秒で始める
$ pipx run --spec mcpprobe-scanner mcpprobe https://your-server.example/mcp
またはインストールします。
$ pipx install mcpprobe-scanner # or: pip install mcpprobe-scanner; the command is `mcpprobe`
$ mcpprobe https://your-server.example/mcp --sarif mcpprobe.sarif --json mcpprobe.json
自分で実行するローカルの stdio サーバー:
$ mcpprobe --stdio "npx -y @your-scope/[email protected]"
自分が所有するベアラートークンを渡す場合(認証が必要なサーバーのチェック用):
$ mcpprobe https://your-server.example/mcp --header "Authorization: Bearer $MCP_TEST_TOKEN"
要約には各検出結果の重大度、チェック ID、信頼度、OWASP との対応付け、証拠の抜粋、平易な修正方法が表示され、その後に、実行したチェック、スキップしたチェックとその理由を示すカバレッジ表が続きます。すべてのチェックは mcpprobe checks で確認できます。各チェックの詳細は CHECKS.md に記載されています。
チェック項目
| 分野 | チェック | 例 |
|---|---|---|
| 認証 | AUTH-01..06 | 認証情報なしでエンドポイントが応答する;RFC 9728 の保護リソースメタデータがない;PKCE S256 がない;誤った audience を持つ自己署名 JWT を受け入れる;クエリ文字列内のトークンを受け入れる;2026-07-28:認可サーバーが RFC 9207 iss を通知しない、Client ID Metadata Documents を使わない非推奨の Dynamic Client Registration |
| トランスポート | TRANS-01..09 | Origin が検証されない(DNS リバインディング);無効な MCP-Protocol-Version が受け入れられる;脆弱または偽造可能な Mcp-Session-Id;非推奨の HTTP+SSE が引き続き提供される;平文 HTTP、脆弱な TLS、不足しているヘッダー;2026-07-28:不完全な server/discover の結果、サーバーが通知していないバージョンが受け入れられる(ダウングレード)、Mcp-Method ヘッダーと本文の不一致に対して -32020 で拒否しない、不足または無効な ttlMs/cacheScope |
| ツールのメタデータ | META-01..07 | モデルに向けた指示(「常に最初にこれを呼び出す」「ユーザーには伝えない」)、会話、システムプロンプト、シークレットを外部へ送信する要求、ツール間のシャドーイング、認証情報のパス、URL、base64、HTML コメント、ゼロ幅文字/双方向制御文字/同形異字 Unicode;保存済み SHA-256 ベースラインとのラグプル差分;任意のコマンド実行またはファイルアクセスの告知(重大、未認証の場合は緊急);スキーマの衛生状態;説明文または stdio 環境変数内のシークレット;ツールに関するツールアノテーションの欠落または矛盾(readOnlyHint、destructiveHint、idempotentHint、openWorldHint、title);1つのサーバー上にプライベートデータ、信頼できないコンテンツ、外向きのチャネルがそろう「致命的な三要素」 |
| 堅牢性 | ERR-01、DOS-01 | エラー内のスタックトレースとバージョン情報;サイズ超過の引数1つ、深さ64のネストプローブ1回、ペースを調整した tools/list 呼び出し20回。これ以上は実行しません |
| アクティブ(ゲート付きスタブ) | INJ-01..05、SUPPLY-01/02、SANDBOX-01 | 登録済みですが、このリリースでは not_implemented として報告されます |
| ガバナンス | GOV-01..05 | アテステーション専用として記載:スキャンでは評価できず、合格としてマークされることはありません |
24件のパッシブチェック(さらに8件のゲート付きアクティブスタブと5件のアテステーション専用ガバナンス項目)があります。mcpprobe checks で一覧を確認できます。
プロトコルリビジョン:スキャナーはまず server/discover(2026-07-28)を試し、次に 2025-11-25 と 2025-06-18 で initialize を試した後、非推奨の 2024-11-05 HTTP+SSE トランスポートを試し、どれが応答したかを記録します。2026-07-28 でのみ存在するルールのチェックは、それ以前のリビジョンに対応するサーバーでは、ネゴシエートされたリビジョンを理由として「該当なし」と報告されます。
ディレクトリへの登録準備状況
すべての JSON レポートには、スキャン結果を Anthropic、OpenAI、HubSpot の MCP ディレクトリへの登録要件(OAuth 2.0、完全かつ正確なツールの注釈、隠された指示がないこと、未解決の重大/高リスクの検出事項がないこと、情報漏えいとポイズニングのリスクが低いこと、HTTPS)に照らし合わせた readiness リストが含まれます。各項目は met、not_met、not_assessable のいずれかで、根拠となる情報源とチェック項目を示します。このリストは実際に実行されたチェックのみから導出されます。エンドポイントの所有権の証明など、スキャンで判断できない項目は、理由を添えて not_assessable となります。docs/report-schema.md を参照してください。
対象へのレート制限
HTTP 429 は尊重されます。リクエストは Retry-After に従って再試行され(ヘッダーがない場合は 1 秒後)、スキャン全体の待機時間の上限(デフォルトは 30 秒、--rate-limit-wait で設定)内で実行されます。上限に達した場合、スロットリングされたリクエストに関するチェックは、スロットリングされた応答から結論を導くのではなく、適用対象外として報告されます。例外は DOS-01 のバーストで、ここでは 429 が確認対象の証拠となります。
パッシブとアクティブ
**パッシブ(デフォルト)**では、通常の MCP クライアントが送信するもの(ネゴシエーション、*/list メソッド、well-known メタデータドキュメント)に加えて、悪意のない不正形式のリクエストを少数送信します(不正な Origin、偽のバージョンヘッダー、偽造されたセッション ID、自作の不正な audience を持つ JWT、不完全な JSON、サイズ超過のリクエスト 1 件と深くネストされたリクエスト 1 件)。ツールは一切呼び出しません。
アクティブ(--active)は、非破壊的なカナリアを使ってツールを呼び出すチェック向けです。0.1.0 ではこれらはスタブですが、ゲートは実際に機能し、コードで強制されます。以下をすべて指定しない限り、アクティブモードは拒否されます。
--authorised-by "<who approved this, e.g. name/role/ticket>"--scope "<what is in scope>"--verify dns-txt(HTTP ターゲットの場合)または--verify local(自分で実行している stdio サーバーの場合)
dns-txt の場合は、トークンを生成して公開します。
$ mcpprobe token your-server.example
Publish this DNS TXT record, then run with --active --verify dns-txt:
_mcpprobe.your-server.example. TXT "mcpprobe-verification=<token>"
$ mcpprobe https://your-server.example/mcp --active --verify dns-txt \
--authorised-by "platform security, CHG-1234" --scope "https://your-server.example/mcp" \
--json scan.json
アクティブ実行では毎回、認可記録(レポートと同じ場所にある scan.authorisation.json)が作成されます。記録には、認可した人、スコープ、検証の証明、レート上限、除外されたツールが含まれます。呼び出しを絶対に避ける必要があるツールには、--exclude-tool NAME を指定してください。
所有権のルール
自分が所有または運用している MCP サーバー、あるいはテストについて明示的な書面による許可を得ている MCP サーバーのみをスキャンしてください。パッシブモードにも適用されます。システムが自分のものでない場合、悪意のないリクエストであっても不正アクセスにあたります。mcpprobe はすべてのリクエストで自身を識別し、オプトアウト(下記)を尊重しますが、これらは礼儀としての仕組みであり、許可の代わりにはなりません。
スキャナーの識別、オプトアウト、レート制限
- User-Agent:
mcpprobe/<version> (+https://mcpprobe.tech/scanning-policy)。 - オプトアウト。MCP リクエストの送信前に確認され、上書きできません。
_mcpprobe.<host>(または親ドメイン)の DNS TXTmcpprobe-opt-out=all。ホストにパケットが届く前に確認されます。/.well-known/mcpprobe-opt-outへの HTTP200。
- レート:デフォルトは毎秒 5 リクエスト(
--rate)、上限は 10。
終了コード
| コード | 意味 |
|---|---|
0 | --fail-on(デフォルトは high)以上の検出事項なし |
1 | --fail-on 以上の検出事項が少なくとも 1 件ある |
2 | エラー:対象に到達できない、引数が不正、所有権の検証に失敗、認可が拒否された、または対象がオプトアウトした |
3 | 対象から応答があったものの、MCP サーバーではない(通常の Web サイトなど)。すべてのチェックは適用対象外として報告され、合格するものはありません |
SARIF と GitHub コードスキャン
GitHub Action として使用する場合(Docker コンテナーアクションのため、Python のセットアップは不要です)。
name: MCP security
on: [push, pull_request]
permissions:
contents: read
security-events: write
jobs:
mcpprobe:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: mcpprobe-dev/[email protected]
id: scan
with:
target: https://staging.your-server.example/mcp
fail-on: high
sarif-output: mcpprobe.sarif
sarif-location: src/server.py # optional: anchor alerts to a repo file
# Upload only when the scan ran (exit 0 or 1). Exit 2 (error) and 3 (not an MCP
# server) produce SARIF with no results, which would close every open alert.
- uses: github/codeql-action/upload-sarif@v3
if: ${{ !cancelled() && (steps.scan.outputs.exit-code == '0' || steps.scan.outputs.exit-code == '1') }}
with:
sarif_file: mcpprobe.sarif
category: mcpprobe
入力、出力、終了コード、手動ディスパッチの例については、docs/github-action.md を参照してください。
または、CLI を使って任意の CI から実行します。
$ pipx run --spec mcpprobe-scanner mcpprobe https://staging.your-server.example/mcp --sarif mcpprobe.sarif --fail-on high
結果では、重大/高リスクに error、中リスクに warning、低リスク/情報に note を使用します。各ルールには GitHub の security-severity と OWASP ID がタグとして付与されます。スキャン対象のエンドポイントはファイルではないため、--sarif-location を指定しない限り、結果は対象の URL を参照します。
Rug-pull の検出
$ mcpprobe https://your-server.example/mcp --baseline .mcpprobe/baseline.json
初回実行時に、すべてのツール、プロンプト、リソース、サーバーの指示の正規 SHA-256 ハッシュが保存されます。以降の実行では、追加、削除、変更された項目がすべて報告され(承認後に説明が変更されるのは、典型的な Rug-pull です)、ファイルが更新されます。更新せずに比較するには、--no-write-baseline を使用してください。
レポートと証跡
--json FILE:すべてのリクエスト/レスポンスのペア(タイムスタンプ、メソッド、ステータス、すべてのヘッダー、最大 64 KiB の本文)を含む完全なレポートです。認証情報のヘッダーと、認識されたシークレットのパターンは秘匿化されます。各検出結果には、解析済みデータから作成されたproofの抜粋、実行可能なverify行、確信度が高くない場合はconfidence_reasonが含まれます。前提条件が満たされていないチェックは、理由とともにnot_applicableとして報告され、合格としてカウントされることはありません。スキーマはdocs/report-schema.mdに記載されています。--sarif FILE:SARIF 2.1.0 形式です。-v:説明とスキャンの注記をターミナルに表示します。-q:ターミナルには何も出力しません。
サーバーから提供されたテキストは、制御文字が見える形で表示され、ターミナルのマークアップとして解釈されることはありません。
META-01 用のオプションの分類器
$ pip install 'mcpprobe-scanner[hf]' # transformers, torch, safetensors
$ mcpprobe https://your-server.example/mcp --judge hf:/path/to/local/model
$ mcpprobe https://your-server.example/mcp --judge hf:<hub-model-id> --judge-download
デフォルトでは無効です。ローカルのプロンプトインジェクション分類器が META-01 にセカンドオピニオンを提供し、説明にフラグを立てた場合は、中程度の重大度を示す指標を追加します。.safetensorsの重みのみが読み込まれ、モデルコードが実行されることはありません。また、--judge-downloadを渡さない限り、何もダウンロードされません。モデルのライセンスはそれぞれ異なるため、まずdocs/judges.mdをお読みください。ヒューリスティックの検出数値はdocs/benchmark.mdに記載されています。
Python API と LLM ジャッジ用フック
import asyncio
from mcpprobe.checks import JudgeVerdict, ScanOptions
from mcpprobe.scanner import ScanConfig, run_scan
def judge(text: str, task: str) -> JudgeVerdict | None:
return None # plug in your own model here; mcpprobe makes no LLM calls
report, evidence = asyncio.run(
run_scan(ScanConfig(target="https://your-server.example/mcp", options=ScanOptions(judge=judge)))
)
print(report.counts())
開発
$ pip install -e ".[dev]"
$ ruff check . && ruff format --check . && mypy && pytest
$ python -m tests.fake_server --preset vulnerable --port 8765 # deliberately vulnerable local server
$ mcpprobe http://127.0.0.1:8765/mcp
セキュリティ上の問題については、SECURITY.mdをご覧ください。ライセンス:0.2.0 からApache-2.0(NOTICEを参照)。0.1.0 は MIT のもとでリリースされました。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。