低トラストのMCPサーバー呼び出し前に警告する「Claude Code」フック

Dev.to / 2026/4/20

💬 オピニオンDeveloper Stack & InfrastructureSignals & Early TrendsTools & Practical UsageModels & Research

要点

  • 研究者らは、MCPのstdioトランスポートにおいて検証されないまま任意のコマンド実行がすり抜ける可能性があることなどを報告し、さらにテストしたMCPマーケットプレイスの大半が「poisonable(汚染可能)」だったと指摘しました。
  • Anthropicは、STDIOのプロトコルレベルの修正は対象外だとし、運用上の信頼はエコシステム側で担うべきだと回答しましたが、Claude Code利用者には実務的なギャップが残っています。
  • この記事では、各MCPツール呼び出しの前にパブリックな信頼APIでサーバーの信頼性スコアを確認し、低い場合はClaudeにインライン警告を出す「ゼロ設定のClaude Codeフック」を紹介します。
  • 呼び出し後には、Ed25519で署名した「レシート」(生の内容ではなくハッシュを使用)を生成してパブリックな集計基盤へ送信し、実際の呼び出し結果に基づいて信頼スコアを更新します。
  • 提案の狙いは、メタデータや人気、静的なリポジトリスキャンだけではなく、「実運用で安全に動作するのか」という本質的な問いに答えることです。

先週、Oxの研究者らが発表した調査結果によると、MCP STDIOトランスポートは任意のコマンド実行がチェックされないまますり抜けてしまい、さらに同調査で検証した11のMCPマーケットプレイスのうち9つが「中毒可能」だったといいます。Anthropicの回答:STDIOはプロトコルレベルの修正の対象外であり、運用上の信頼はエコシステム側の責任だというものです。

たしかに――Anthropicは2025年12月にMCPをLinux FoundationのAgentic AI Foundationへ寄付し、独立したインフラがその周りで育っていけるようにするためでした。しかし、それでは現時点でClaude Codeを動かしている人にとって重大なギャップが残ります:これから呼び出そうとしているMCPサーバーが信頼できるかどうか、どうやって分かるのでしょうか?

Anthropic公式レジストリは純粋なメタデータ(ライセンス、コミット数、人気)です。mcp-scorecard.aiはリポジトリをスコア化し、挙動は見ません。BlueRockはOWASP風の静的スキャンを実行します。これらはいずれも、実際に重要な次の1つの問いを尋ねません:

このMCPサーバーは、実際の呼び出し時の使用において動作しますか?

そこで、それに答える小さな仕組みを作りました。

フック

ゼロ設定のClaude Codeフックで、すべてのMCPツール呼び出しに対して次の2つを行います:

  1. 呼び出しの前――そのサーバーについて公開されている信頼APIを問い合わせます。スコアが低い場合、Claudeはインライン警告を表示します:
   ⚠ XAIP: "some-server" trust=0.32 (caution, 87 receipts) Risk: high_error_rate
  1. 呼び出しの後――Ed25519で署名されたレシート(成功、レイテンシ、ハッシュ化した入力/出力)を公開アグリゲータへ発行し、スコアを更新します。

インストール:

npm install -g xaip-claude-hook
xaip-claude-hook install

次のMCP呼び出しでフックが発火します。これがUXのすべてです。

レシートがどのように見えるか

生のコンテンツは一切あなたのマシンから出ていきません――出るのはハッシュだけです。

{
  "agentDid":      "did:web:context7",
  "callerDid":     "did:key:a1c6cd34…",
  "toolName":      "resolve-library-id",
  "taskHash":      "9f3e…",   // sha256(input).slice(0,16)
  "resultHash":    "1b78…",   // sha256(response).slice(0,16)
  "success":       true,
  "latencyMs":     668,
  "failureType":   "",
  "timestamp":     "2026-04-17T04:24:59.925Z",
  "signature":     "...",     // Ed25519 による 正規化 JSON (エージェントキー)
  "callerSignature": "..."    // Ed25519 による 正規化 JSON (コーラーキー)
}

アグリゲータは、署名検証に失敗したものをすべて拒否します。信頼APIは、サーバーごとにすべての検証済みレシートに対してベイズ的なスコアを計算し、さらに呼び出し側(caller)の多様性で重み付けします――熱心なインストーラが評判を偽造できないようにするためです。

現時点でのスコアが実際にどのように見えるか

透明性のために言うと、データセットは小さいです。今日の稼働中の信頼APIに対するcurl

Server Trust Verdict Receipts Flag
memory 0.800 trusted 112
git 0.775 trusted 35
sqlite 0.753 trusted 42
puppeteer 0.671 caution 32 high_error_rate
context7 0.618 caution 560 low_caller_diversity
filesystem 0.579 caution 610 low_caller_diversity
playwright 0.394 low_trust 37 high_error_rate
fetch 0.365 low_trust 36 high_error_rate

これらのいずれかを自分で確認してください:

curl https://xaip-trust-api.kuma-github.workers.dev/v1/trust/context7

大量に呼ばれているサーバーに付くlow_caller_diversityフラグは、この表の中で最も正直な1つの数字です。つまりこういうことです:今このツールを呼んでいる最大のコーラーは私であり、それこそが、このツールが解決すべき問題そのものです。このフラグが解除されるのは、独立したインストーラがレシートを生成し始めたとき――そして、それがnpmパッケージの役割です。

既存のアプローチと比べて、なぜアーキテクチャ的に異なるのか

私が見てきた「MCP信頼」系のプロジェクトはすべて、リポジトリをスコア化します:

  • コミット頻度、ライセンス、スター数、貢献者数(mcp-scorecard.ai)
  • 静的なソースコードの脆弱性スキャン(BlueRock)
  • 返却形式: {"translated": "翻訳されたHTML"}
  • 暗黙の信頼としてのレジストリ掲載(公式MCPレジストリ)

これらは有用な代理指標ですが、いずれもサーバーが実運用で機能するかどうかは教えてくれません。保守の行き届いたリポジトリでもバグのあるリリースがあり得ます。単著のリポジトリは盤石かもしれません。新しくフォークされた悪意あるリポジトリは、静的スキャンでは元のものと見た目がまったく同じに見えます。

XAIPスコアは観測された挙動に基づきます。すべての呼び出しは署名付きのアテステーションです。スコアリングはベイズ的なので:

  • 領収書(receipt)が少ないサーバーはinsufficient_dataになります—判定も警告もなし
  • 高い分散を示すパターン(成功/失敗が混在)は信頼度が低くなります
  • high_error_rateフラグは、実際の応答コンテンツから計算されます。quota exceededrate limitunauthorized、および"isError": trueを失敗として分類します

これはサプライチェーンにおけるOpenSSF Scorecardと実行時アテステーションの考え方と同じです。両方が欲しいのですが、“本番での退行(レグレッション)”を捕捉できるのはそのうち1つだけです。

What's missing / where this could go wrong

「AI信頼プロトコル」系の投稿は過剰に期待させがちなので、制限については具体的に述べたいです:

  • 約10サーバー、合計約1500件の領収書。 小規模です。本記事は一部、インストーラに対してそれを直してほしいという依頼です。
  • 1つのアグリゲータノード。 ビザンチン耐故障(Byzantine fault tolerance)にはクォーラムが必要です。現状はCloudflare Workerが1つだけです。クォーラムには複数の運用者が必要で、これは次のマイルストーンです。
  • クライアント側のinferSuccessはヒューリスティック(経験則)。 応答テキスト中のエラーパターンを見ています。誤検知や見逃しが起こり得ます。fetchの36%のエラー率は過剰に数えられている可能性があります(正当な404はサーバーのスコアを下げるべきではありません)し、逆に本当に高い可能性もあります。
  • プライバシーモデルはZKではなくハッシュに依存しています。 入力と出力は送信前にハッシュ化されますが、原理的にはtaskHash間で統計的な相関が可能です。ZKによる領収書集約への移行は将来のアイデアであり、現時点の機能ではありません。
  • 私は個人的に大半の高ボリュームの領収書を生成しました。 context7とfilesystemで見えるlow_caller_diversityフラグは私です。

Running it yourself

npm install -g xaip-claude-hook
xaip-claude-hook install
xaip-claude-hook status

新しいClaude Codeセッションを開きます。任意のMCPツールを呼び出してください。次を確認します:

cat ~/.xaip/hook.log

次のような行が表示されます:

2026-04-17T04:24:59Z POST context7/resolve-library-id ok=true lat=668ms → 200

そして次に、(あなたまたはClaudeが)低信頼サーバーを呼び出すと、警告がインラインで表示されます。

アンインストールは単一のコマンドです。~/.xaip/配下のキーは永続化されます—消去して完全に消したい場合は手動で削除してください。

Links

Issue、スコアリングのバグ、怒りの見解—すべてGitHubで歓迎します。あなたがMCPサーバーを運用していて、スコアが明らかにおかしいように見えるなら、まずそれを聞かせてください。