AIエージェントが自律支払いするMCPサーバーを作った(Claude → MCP → x402 USDC)
MCPサーバーのデフォルト モデルは「ツール公開 + 呼び出し側を信頼」です。ローカルSQLiteを叩くツールならそれでOKですが、有料データを叩く瞬間に 誰か が上流に支払う必要が出ます。ChainAnalyzerは3番目の道を選びました — MCP設定に静的APIキーを焼き込まず、MCPツール側で x402 を喋らせる。Claude (またはあらゆるMCP対応エージェント)が1コール毎に $1.00 USDC をBase上で署名支払い。アカウント不要。キー不要。エージェントは欲しいものを正確に得て、上流は支払いを受け、人間はloopの外。
ハイライト
- 静的APIキー不要 — ユーザーはウォレット(USDC float on Base)を1つ用意するだけ
- 1コール = 1 USDC支払い — エージェントが自律的に署名、人間の介在ゼロ
- 支払いプランビング不可視 — LLMは
scan_addressを呼んでJSONを受け取るだけ - 自然な予算境界 — ウォレット残高が尽きたら自然に止まる
ほとんどのMCPサーバーが課金できない理由
Claude DesktopにMCPサーバーを入れると見慣れた設定があります — 静的APIキー、レート制限、月初に発見するbilling。エージェントが1セッションで50回ツールを呼んでも誰も気付かない。これは「本当に無料のツール」(Postgres, ファイルシステム, GitHub)には機能しますが、1コール毎にコストがかかる上流をラップするツールには機能しません。
ChainAnalyzerが実現したかったのは 「エージェントが呼んだ分だけ、その瞬間に、リアルマネーで払う」世界です。
x402を4行で説明
x402 はHTTP 402ステータス コードをstablecoin支払いに繋いだプロトコル:
- エージェントが
GET /api/risk-score?address=0xabcを呼ぶ - サーバーは
HTTP 402+ 価格($1.00 USDC) + asset (USDC on Base) + 受取アドレス + 署名用nonceを返す - エージェントのウォレットがEIP-3009
transferWithAuthorizationをその金額分だけ署名、base64エンコードしてX-PAYMENTヘッダ付きで再リクエスト - サーバーは署名検証 → ハンドラ実行 → Coinbase CDP facilitator経由でUSDCをon-chain settle →
X-PAYMENT-RESPONSE(オンチェーン領収書)付きでレスポンス
プロトコル自体はサブセカンド。Base上のon-chain settleは数秒。エージェント視点では「402が返ってきた → 支払って再試行 → 200 OK」だけ。
MCP × x402が自然にハマる理由
MCP (Model Context Protocol)はLLMにツールを公開する標準。ツールにschema, name, callableが付与され、モデルが呼び出しタイミングを判断します。実行パスは:
LLM
├─→ MCP client
│ └─→ MCP server (chainanalyzer-mcp)
│ ├─→ HTTP GET /api/risk-score ← 402 + price
│ ├─→ wallet.sign(EIP-3009) ← per-call payment
│ ├─→ HTTP GET /api/risk-score ← retry with X-PAYMENT
│ │ [verify → handler → settle]
│ └─→ 200 OK + risk JSON
└─← result returned to LLM x402は「MCPサーバーがハンドラを実行する」内側に収まります。MCPツール実装は上流(ChainAnalyzer API)にHTTP呼び出しをする → 402が返る → MCPサーバーはユーザー所有のウォレット鍵にアクセスがある → 支払い署名 → リプレイ → データ取得 → LLMに返す。LLMは支払いプランビングを見ません。
ユーザー側の準備はAPIキー版より少ない: ChainAnalyzerへの登録は不要です。ウォレット = アカウント。
MCPサーバー側で何が変わったか
ChainAnalyzerの @chainanalyzer/mcp-server は以前APIキーが必要でした。新版(paid mode)はユーザーのウォレットを使います:
{
"mcpServers": {
"chainanalyzer": {
"command": "npx",
"args": ["-y", "@chainanalyzer/mcp-server"],
"env": {
"CHAINANALYZER_X402_PRIVATE_KEY": "0x...",
"CHAINANALYZER_X402_NETWORK": "base"
}
}
}
} 秘密鍵 = ユーザーの支払いウォレット(Base上にUSDCを保持)。MCPサーバーは内部で x402-fetch を使って402ハンドリングを処理:
import { wrapFetchWithPayment } from "x402-fetch"
import { createWalletClient, http, privateKeyToAccount } from "viem"
import { base } from "viem/chains"
const account = privateKeyToAccount(process.env.CHAINANALYZER_X402_PRIVATE_KEY)
const wallet = createWalletClient({ account, chain: base, transport: http() })
const fetch402 = wrapFetchWithPayment(fetch, wallet)
// Inside the MCP tool handler:
const res = await fetch402(
`https://chain-analyzer.com/api/v1/x402/address/${addr}/risk-score?chain=${chain}`,
{ method: "POST" }
)
return await res.json() // automatically retried with payment LLM視点では、ツールはデータを返した(= 支払い済)か、「ウォレット残高不足」エラーを返した(= 残高切れ)のどちらか。後者は自然な予算シグナルになり、Claudeが「スキャン予算が尽きました」と能動的にユーザーに伝えます。
ハマった点
1. MCPはstdio JSON、HTTPリクエストはそのモデルに合わない
MCPの通信はstdio。発信HTTPリクエストがstdioフレーミングを破壊しないよう、別のHTTPクライアントを使い、MCPに返す前に明示的にJSONシリアライズが必要。
2. EIP-3009の validAfter / validBefore が現実のクロックずれを許容する必要
Facilitatorはネットワーク時刻と大きくdriftしたタイムスタンプをrejectします。ノートPCが起動直後でNTP未補正のとき、署名が全部rejectされます。validAfter に60秒、validBefore に5分のバッファを入れて回避。
3. Self-paymentガード
ユーザーが payTo と署名鍵を同じアドレスに設定すると、毎回self-loop transferになりfacilitatorはreject。クライアント側で即時throwするガードを追加。
4. 小残高UX
$1.00/コールなので、$5 USDCのfloatでは5コールで枯渇します。単発の調査なら問題ありませんが、バッチ スクリーニング(数百アドレス)では途中で止まってしまう。そこで chainanalyzer.check_my_balance ツールを追加し、モデルがバッチ開始前に残高と実行可能コール数を確認できるようにしました。
ユーザーが負担するコスト
- ウォレット セットアップ: 無料(Base互換ウォレット任意)
- 初期入金: $5 USDC on Base + 数十セントのETH (ガス代、L2なので激安)
- 1コール毎: $1.00 USDC + ガス代はfacilitator持ち、ユーザー負担はゼロ
- サブスク無し / 月額最小なし
比較のため: ChainAnalyzerの最安Proプランは$19.99/月。~2,500スキャン/月以下ならx402が完全に安い。それ以上ならProが安く、AI Analysisも使い放題。エージェントworkloadにはx402が明白な選択。エージェントはクレジットカードを持たない。SaaSにサインアップしない。エージェントは ウォレットを持つ。
使ってみる
npx -y @chainanalyzer/mcp-server 上記のウォレットenv varsを設定済みで実行。詳細は chainanalyzer-mcp GitHub repo のREADME (90秒セットアップ動画付き)。
上流のx402エンドポイント セットは姉妹記事で: Coinbase x402 BazaarにAML APIを出した話。
クリプトを超えた意味
パターン — MCPツールがx402課金HTTP APIをラップ、エージェントがウォレットを持つ、コール毎にリアルマネー — は「エージェントが買いたいもの」全般に通用します。画像生成。航空券価格。アドレス リスク データ。翻訳。
AIエージェントの自律性は現在「経済」がボトルネック: ブラウズ・推論・計画はできても、トランザクションができない。MCP + x402はこれを「エージェントが個人クレジットカードを持つ必要なく、ユーザーが渡す必要もない」形で閉じます。エージェントはウォレットを持つ。ウォレットはUSDCを持つ。それで十分。
リンク
- MCP server (npm + GitHub)
- Glama listing (AAA quality / security / license)
- 姉妹記事: Coinbase x402 BazaarへのAML API投入
- x402 spec
- MCP spec