x402 Doctor について
x402 Doctorは、未払いリクエストを模擬し、返された402チャレンジを調べるx402販売者向けエンドポイント診断ツールです。販売者側エンドポイントの開発者を対象に、検出事項と根拠、修正案を示します。
主な機能
- 01未払いのGETハンドシェイクを模擬
- 02402チャレンジ本文を検査
- 03検出事項の根拠を表示
- 04不備への修正案を提示
- 05複数のプロトコル項目を検査
活用シーン
- 01無効なx402チャレンジを返すエンドポイントの調査
- 02決済チャレンジ内のフィールド不備の特定
- 03チャレンジがキャッシュされる可能性の確認
- 04MCP経由でエンドポイント診断や検査項目の確認
MCP 対応
ステートレスなStreamable HTTPのMCPサーバーは、エンドポイント診断、個別の不備の説明、検査項目一覧のツールを提供します。facilitator経由の検証や支払いは行いません。
設定
リモートサーバーはインストール不要です。クライアントを選んで設定をコピーするか、ワンクリックで導入できます。
https://x402-doctor.tsharpe.workers.dev/mcpclaude mcp add --transport http com-twelvepermissions-x402-doctor https://x402-doctor.tsharpe.workers.dev/mcp{"mcpServers":{"com-twelvepermissions-x402-doctor":{"type":"http","url":"https://x402-doctor.tsharpe.workers.dev/mcp"}}}Cursor で開く{"servers":{"com-twelvepermissions-x402-doctor":{"type":"http","url":"https://x402-doctor.tsharpe.workers.dev/mcp"}}}VS Code で開く{"mcpServers":{"com-twelvepermissions-x402-doctor":{"type":"http","url":"https://x402-doctor.tsharpe.workers.dev/mcp"}}}{"mcpServers":{"com-twelvepermissions-x402-doctor":{"serverUrl":"https://x402-doctor.tsharpe.workers.dev/mcp"}}}コマンドはターミナルで実行し、JSON は各クライアントの MCP 設定に貼り付けて再起動します。認可が必要なサーバーは初回接続時にログインを求めます。
ツール
3| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| url | string | はい | 調査するエンドポイント。http(s) のみ。プライベートアドレスとループバックアドレスは拒否されます。 |
詳細
x402 Doctor
x402 の販売者エンドポイントを無料で診断します。支払いが必要なエンドポイントを指定すると、支払いを行うクライアントと同じハンドシェイクを実行します。つまり、X-PAYMENT ヘッダーなしで GET リクエストを送り、返された 402 チャレンジの何が問題なのか、何を変更すべきかを報告します。
公開中:https://x402-doctor.tsharpe.workers.dev
curl -s -X POST https://x402-doctor.tsharpe.workers.dev/probe \
-H 'Content-Type: application/json' \
-d '{"url":"https://your-service.example/paid-endpoint"}'
販売者側を対象とする理由
購入者側の x402 は、公式 SDK で十分に対応されています。問題が起きやすいのは販売者側です。見通せないファシリテーターの内部で障害が発生するためです。エンドポイントには問題がないように見えるのに、支払いが決済されず、自分では制御できない場所でエラーが表面化します。
各チェックには provenance フィールドがあるため、すべての指摘について根拠を確認できます。
spec— x402 仕様で必須とされています。observed (source)— 実際のファシリテーターが拒否することを確認済みで、根拠となる情報源を明記しています。
返される内容
{
"target": "https://your-service.example/paid-endpoint",
"finalUrl": "https://your-service.example/paid-endpoint",
"status": "advisories",
"http": { "status": 402, "contentType": "application/json" },
"findings": [
{
"id": "challenge-cacheable",
"severity": "warn",
"title": "402 challenge is cacheable",
"why": "…",
"fix": "…",
"provenance": "observed (ours, 2026-08-15)",
"evidence": "cache-control: public, max-age=300"
}
],
"checksRun": 16,
"bodyTruncated": false,
"bodyChecksSkipped": 0,
"bodySkipReason": null
}
status は次のいずれかです。
| status | 意味 |
|---|---|
healthy | 報告事項はありません |
advisories | 確認する価値のある注意事項がありますが、エラーはありません |
defects_found | error が少なくとも 1 つあります |
not_x402 | エンドポイントは x402 チャレンジを返しませんでした |
unreachable | プローブを完了できませんでした。reason を確認してください |
本文が切り詰められていた場合や解析できなかった場合、本文のチェックはスキップされ、その旨がレポートに記載されます(bodyChecksSkipped、bodySkipReason)。実行されなかったチェックが、合格したチェックとして報告されることはありません。
16 個のチェック
| id | 重大度 | チェック | 根拠 |
|---|---|---|---|
no-402 | error | エンドポイントは支払いなしで 402 を返しませんでした | spec |
body-not-json | error | 402 の本文を JSON として解析できません | spec |
oversized-body | warn | 402 の本文が読み取り上限を超えました | observed (this probe) |
missing-x402-version | error | x402Version が存在しないか、1 ではありません | spec |
accepts-empty | error | accepts が存在しない、配列ではない、または空です | spec |
output-schema-null | error | outputSchema が明示的に null です | observed (Coinbase CDP facilitator, 2026-07-17) |
amount-not-atomic-string | error | maxAmountRequired が最小通貨単位の文字列ではありません | spec |
asset-network-mismatch | warn | asset がこのネットワークの USDC コントラクトではありません | spec |
missing-eip712-extra | error | scheme が "exact" なのに、extra に EIP-712 ドメインがありません | spec |
unknown-network-name | info | ネットワーク名がこのプローブで認識されているものではありません | spec |
payto-not-an-address | error | payTo がこのネットワークで有効なアドレスではありません | spec |
payto-not-checksummed | info | payTo がチェックサム付きアドレスではありません | spec |
no-timeout-declared | info | maxTimeoutSeconds がありません | spec |
challenge-cacheable | warn | 402 チャレンジがキャッシュ可能です | observed (ours, 2026-08-15) |
cors-headers-not-exposed | info | ブラウザーのクライアントでは、決済応答で支払いヘッダーを公開する必要があります | observed (x402-foundation/x402#2112) |
bazaar-ext-inside-accepts | warn | Bazaar 拡張が accepts エントリー内で宣言されています | observed (ours, 2026-08-14) |
MCP サーバーとしても利用可能
POST /mcp、ステートレスな Streamable HTTP です。ツールは 3 つあります。
| ツール | 機能 |
|---|---|
probe_x402_endpoint | URL に対して診断を実行します |
explain_defect | id で指定したチェックについて詳しく説明します |
list_checks | 根拠を含むルール表全体を表示します |
意図的に行わないこと
- ファシリテーターを介した検証は行いません。 そうすると、お客様のトラフィックが他者のファシリテーター認証情報を通ることになります。ここで行うチェックはすべて、実際に返されたチャレンジに基づいています。
- 支払いを送信することはなく、キー、シード、ウォレットを求めることもありません。
- 認識していないネットワークは判定しません。 認識できないネットワーク名は、このプローブのリストに限界があることを示す
infoの注意事項であり、お客様のネットワークに誤りがあるという意味ではありません。アドレス形式のルールは、形式が判明している場合にのみ適用されます。
知っておくべき制限
- 本文は上限まで読み取られます。上限を超えると、本文のチェックはスキップされ、推測で結果を出すのではなく、その旨がレポートに表示されます。
- リダイレクトは深さ 3 まで追跡され、各ホップで SSRF ガードが再実行されます。
- 指定された URL をサービスが取得するため、IP アドレスごとに毎時 20 リクエスト、全体で毎時 300 リクエストに制限されています。
- 保存されるのは、このレート制限用の IP アドレスごとのリクエストカウンターのみで、2 時間以内に期限切れになります。分析データは収集せず、プローブ対象がログに記録されることもありません。
セキュリティ対策と、修正ではなく受け入れた残存リスクについては、SECURITY.md に記載されています。
ソースの確認と実行
cd doctor
npm test # 163 tests, no dependencies of any kind
ランタイム依存関係も開発依存関係もありません。テストスイートは node --test で実行できます。ルールは I/O を伴わない純粋関数であり、ネットワークアクセスはすべて src/probe.js に集約されています。SSRF ガードもここにあります。
上記のホスト型サービスは無料で利用でき、ライセンスも不要です。ソースは、検査と検証のために、このリポジトリの他の部分と同じ条件で公開されています。現時点ではライセンスは付与されず、すべての権利が留保されています。再利用またはセルフホストをご希望の場合は、お問い合わせください。
T w e l v e P e r m i s s i o n s が開発しました。無料で利用でき、同サイトで販売されているものとは無関係です。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。