
x402 × Solana実装ガイド | 支払い対応MCPサーバーをTypeScriptで構築する
x402 V2プロトコルのSolana実装を徹底解説。SVM exact schemeの仕組みから、@x402/mcpパッケージを使った支払い対応MCPサーバーの構築まで、実際のコードとともにステップバイステップで解説します。
公開日2026.02.26
更新日2026.02.26
はじめに
前回の記事でx402プロトコルの全体像を、V2解説記事でマルチチェーン対応やExtensions機構を紹介しました。
この記事では、実際に手を動かします。x402 V2のSolana実装(SVM exact scheme)の仕組みを理解し、支払い対応のMCPサーバーをTypeScriptで構築するところまでを、コードとともに解説します。
この記事で作るもの
Solana USDC で課金できるMCPサーバーとクライアントを、TypeScript + @x402/mcp で構築します。
| コンポーネント | 内容 |
|---|---|
MCPサーバー | 無料ツール( ping)と有料ツール(premium_weather / $0.001 USDC)を提供。StreamableHTTPトランスポートで動作 |
MCPクライアント | サーバーに接続し、有料ツール呼び出し時にSolana Devnet上のUSDCで自動決済を実行 |
決済フロー | クライアントが402レスポンスを受信 → トランザクションを構築・部分署名 → Coinbase Facilitatorが検証・最終署名・送信 |
完成すると、以下のように動作します。
x402未対応のクライアントでは、有料ツールは402 Payment Requiredで止まります。
x402対応クライアント(@x402/mcp)を使うと、同じ呼び出しに対して自動決済 → 結果取得が裏で実行されます。
ソースコードはデモリポジトリ(GitHub)で公開しています。
対象読者
- x402の概要を理解済みで、Solana上での実装に進みたいエンジニア
- MCPサーバーにマネタイズ機能を追加したい方
- AIエージェントの自律的な決済フローをプロダクションで試したい方
前提知識
- x402プロトコルの基本概念(入門記事参照)
- Solanaの基礎(トランザクション、SPLトークン)
- TypeScript / Node.js の開発経験
目次
目次
Part 1: SVM Exact Schemeを理解する
x402 V2では、チェーンごとに「スキーム(scheme)」と呼ばれる決済メカニズムが定義されています。Solanaで使われるのがSVM exact schemeです。EVMのEIP-3009 transferWithAuthorizationとは根本的にアプローチが異なります。
EVMとSolanaの決済アプローチの違い
| 項目 | EVM(Base等) | Solana |
|---|---|---|
署名対象 | EIP-3009 authorization(オフチェーン署名) | VersionedTransaction(部分署名) |
ガス代負担 | Facilitatorが transferWithAuthorizationを実行 | Facilitatorが feePayerとして最終署名 |
トークン送金命令 | transferWithAuthorization | TransferChecked(SPL Token / Token-2022) |
ペイロード形式 | signature + authorization JSON | Base64エンコードされた部分署名済みトランザクション |

EVMではオフチェーンの「認可署名」をFacilitatorが代行実行しますが、Solanaではクライアントが実際のトランザクションを構築・部分署名し、Facilitatorがガス代を負担して最終署名・送信するモデルです。
SVM Exact Schemeの14ステップ
SVM exact schemeの決済フローは、4つのアクター間で14のステップに分かれます。
SVM Exact Scheme 決済フロー
クリックで拡大EVMとの最大の違いはステップ3〜5です。クライアントがSolanaのVersionedTransactionを自分で構築し、TransferChecked命令を含む形でトランザクションを組み立てます。
PaymentRequirementsの構造(Solana)
サーバーが402レスポンスで返す支払い条件は以下の形式です。
{
"scheme": "exact",
"network": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
"amount": "1000",
"asset": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
"payTo": "2wKupLR9q6wXYppw8Gr2NvWxKBUqm4PPJKkQfoxHDBg4",
"maxTimeoutSeconds": 60,
"extra": {
"feePayer": "EwWqGE4ZFKLofuestmU4LDdK7XM1N4ALgdZccwYugwGd"
}
}| フィールド | 説明 |
|---|---|
network | CAIP-2形式のSolanaネットワーク識別子 |
amount | 支払い金額(トークンの最小単位。USDCなら6桁 = 1000 = $0.001) |
asset | トークンのMintアドレス(USDC: EPjFWdd5...) |
payTo | リソースサーバーの受取ウォレット |
extra.feePayer | ガス代を負担するFacilitatorのアドレス |
EVM版との大きな違いはextra.feePayerフィールドです。Solanaではトランザクション手数料を別アカウントが支払えるため、クライアントはSOLを持っていなくても決済が可能です。
PaymentPayloadの構造(Solana)
クライアントが送信する決済ペイロードは以下の形式です。
{
"x402Version": 2,
"resource": {
"url": "https://example.com/api/data",
"description": "Access to protected content",
"mimeType": "application/json"
},
"accepted": {
"scheme": "exact",
"network": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
"amount": "1000",
"asset": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
"payTo": "2wKupLR9q6wXYppw8Gr2NvWxKBUqm4PPJKkQfoxHDBg4",
"maxTimeoutSeconds": 60,
"extra": {
"feePayer": "EwWqGE4ZFKLofuestmU4LDdK7XM1N4ALgdZccwYugwGd"
}
},
"payload": {
"transaction": "base64-encoded-partially-signed-versioned-transaction"
}
}payload.transactionは部分署名済みのVersionedTransactionをBase64エンコードしたものです。EVMのsignature + authorization構造とは異なり、Solanaではトランザクション全体が格納されます。
トランザクション構造の検証ルール
Facilitatorがトランザクションを検証する際、以下の厳格なルールが適用されます。
命令の構成(3〜5命令):
| 順番 | 命令 | 必須 | 説明 |
|---|---|---|---|
1 | ComputeBudget SetLimit | 必須 | 計算ユニット上限の設定 |
2 | ComputeBudget SetPrice | 必須 | 計算ユニット単価の設定 |
3 | TransferChecked | 必須 | SPLトークン送金 |
4 | Lighthouse | 任意 | Phantomウォレットの保護命令 |
5 | Lighthouse | 任意 | Solflareウォレットの保護命令 |
セキュリティ検証:
- feePayer保護: feePayerのアドレスが送金命令のaccountsに含まれてはならない。feePayerが自分の資金を移動させられるトランザクションを拒否
- 計算ユニット単価の上限: 5 lamports/CU以下に制限し、ガス代の悪用を防止
- 送金先の検証: TransferCheckedの送金先がAssociated Token Account PDA(
owner = payTo, mint = asset)と一致すること - 金額の完全一致: TransferCheckedのamountがPaymentRequirements.amountと一致すること
- シミュレーション: 決済前にトランザクションをシミュレーションし、実行可能性を確認
これらの検証はFacilitatorが自動で行うため、リソースサーバーの開発者がブロックチェーンの知識を持つ必要はありません。
Part 2: SDKのアーキテクチャ
実装に入る前に、x402 TypeScript SDKのSolana関連パッケージを整理します。
パッケージ構成
@x402/core ← プロトコル共通型・ユーティリティ
@x402/svm ← Solana決済メカニズム (mechanisms/svm)
├── ExactSvmScheme ← クライアント/ファシリテーター実装
├── signer ← トランザクション署名
└── utils ← RPC・トランザクション操作
@x402/mcp ← MCPトランスポート
├── server/ ← createPaymentWrapper
└── client/ ← createX402MCPClient
@x402/express ← Express用ミドルウェア
@x402/hono ← Hono用ミドルウェア
@x402/next ← Next.js用ミドルウェアクライアント側の処理フロー
ExactSvmSchemeクラスのcreatePaymentPayloadメソッドが、Solanaトランザクションの構築を担います。
ステップ1と5でSolana RPCへの通信が発生しますが、この一連の処理はすべて@x402/svmパッケージが内部で行うため、開発者が直接Solanaのトランザクションを組み立てる必要はありません。
Facilitator側の処理フロー
FacilitatorのExactSvmSchemeはverifyとsettleの2つのメソッドを持ちます。
verify(検証): トランザクションをデコードし、前述の6つの検証ルールを順に適用。最後にシミュレーションで実行可能性を確認します。
settle(決済): feePayerとして最終署名を行い、Solanaネットワークに送信。30回までのリトライでトランザクション確認を待ちます。
Part 3: 支払い対応MCPサーバーを構築する
ここからが本題です。@x402/mcpパッケージを使って、AIエージェントがSolana USDCで支払いを行うMCPサーバーを構築します。
プロジェクトのセットアップ
mkdir x402-mcp-server && cd x402-mcp-server
pnpm init
pnpm add @x402/mcp @x402/core @x402/svm \
@modelcontextprotocol/sdk express zod \
@solana/kit @scure/base
pnpm add -D typescript tsx @types/node @types/expresspackage.jsonに"type": "module"を追加します。
{
"type": "module",
"scripts": {
"server": "tsx src/server.ts",
"client": "tsx src/client.ts"
}
}ディレクトリ構成
x402-mcp-server/
├── src/
│ ├── server.ts # MCPサーバー(x402 + StreamableHTTP)
│ └── client.ts # MCPクライアント(x402決済対応)
├── .env # SOLANA_WALLET_ADDRESS, SOLANA_PRIVATE_KEY
└── package.json環境変数と支払い設定
.envファイルに以下を設定します。
SOLANA_WALLET_ADDRESS=your-solana-wallet-address
SOLANA_PRIVATE_KEY=your-base58-encoded-private-key
FACILITATOR_URL=https://x402.org/facilitatorx402 SDKは定数とビルダーを提供しているため、Mint アドレスやネットワークIDを手動で定義する必要はありません。
import { SOLANA_DEVNET_CAIP2, USDC_DEVNET_ADDRESS } from "@x402/svm";
// SOLANA_DEVNET_CAIP2 = "solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1"
// USDC_DEVNET_ADDRESS = "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU"支払い条件はbuildPaymentRequirementsで動的に構築されます。price: "$0.001"と指定するだけで、USDC decimals(6桁)を考慮したamount: "1000"に自動変換されます。さらに、Facilitatorのextra.feePayerも自動設定されます。
Solana Devnetで試す場合、以下の2つのFaucetからテストトークンを取得してください。
- SOL(ガス代): Solana Faucet —
solana airdrop 2コマンドでも取得可能 - USDC(決済用): Circle Testnet Faucet — Solana Devnetを選択し、ウォレットアドレスを入力(2時間ごとに最大20 USDC)
Import Pathの注意点
x402のSVMパッケージにはサーバー用とクライアント用の2つのExactSvmSchemeが存在します。
// サーバー側: parsePrice, enhancePaymentRequirements 等を持つ
import { ExactSvmScheme } from "@x402/svm/exact/server";
// クライアント側: createPaymentPayload, sign 等を持つ
import { ExactSvmScheme } from "@x402/svm";間違えるとparsePrice is not a function等の実行時エラーになります。これはx402実装で最も多い落とし穴です。
MCPサーバーの構築
@x402/mcpのcreatePaymentWrapperを使って、ツールに決済を組み込みます。MCP SDK v1.27+ではStreamableHTTPトランスポートが推奨されており、セッション管理付きのステートフルサーバーを構築します。
Import pathに注意: サーバー側のExactSvmSchemeは@x402/svm/exact/serverからインポートします。デフォルトの@x402/svmはクライアント専用で、parsePrice等のサーバーメソッドがありません。
// src/server.ts
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js";
import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
import { createPaymentWrapper, x402ResourceServer } from "@x402/mcp";
import { HTTPFacilitatorClient } from "@x402/core/server";
import { ExactSvmScheme } from "@x402/svm/exact/server";
import { SOLANA_DEVNET_CAIP2, USDC_DEVNET_ADDRESS } from "@x402/svm";
import { z } from "zod";
import { randomUUID } from "node:crypto";
const facilitatorUrl = process.env.FACILITATOR_URL
?? "https://x402.org/facilitator";
const solanaAddress = process.env.SOLANA_WALLET_ADDRESS!;
async function main() {
// 1. x402リソースサーバーを初期化
const facilitatorClient = new HTTPFacilitatorClient({
url: facilitatorUrl,
});
const resourceServer = new x402ResourceServer(facilitatorClient);
resourceServer.register(SOLANA_DEVNET_CAIP2, new ExactSvmScheme());
await resourceServer.initialize();
// 2. 支払い条件を構築($0.001 → amount: "1000"に自動変換)
const paymentAccepts = await resourceServer.buildPaymentRequirements({
scheme: "exact",
network: SOLANA_DEVNET_CAIP2,
payTo: solanaAddress,
price: "$0.001",
});
// 3. セッション管理
const transports: Record<string, StreamableHTTPServerTransport> = {};
function createMcpServer() {
const server = new McpServer({
name: "x402-solana-mcp-server",
version: "1.0.0",
});
const wrapWithPayment = createPaymentWrapper(resourceServer, {
accepts: paymentAccepts,
});
// 無料ツール
server.tool("ping", "Health check (free)", {}, async () => ({
content: [{ type: "text", text: "pong" }],
}));
// 有料ツール(Payment Wrapperで包む)
server.tool(
"premium_weather",
"Premium weather data ($0.001 USDC)",
{ city: z.string().describe("City name") },
wrapWithPayment(async (args: { city: string }) => ({
content: [{
type: "text" as const,
text: JSON.stringify({
city: args.city,
temperature: Math.round(Math.random() * 30 + 10),
condition: ["sunny", "cloudy", "rainy"][
Math.floor(Math.random() * 3)
],
}, null, 2),
}],
})),
);
return server;
}
// 4. Express app(SDK helperを使用)
const app = createMcpExpressApp();
app.post("/mcp", async (req, res) => {
const sessionId = req.headers["mcp-session-id"] as string | undefined;
try {
let transport: StreamableHTTPServerTransport;
if (sessionId && transports[sessionId]) {
transport = transports[sessionId];
} else if (!sessionId && isInitializeRequest(req.body)) {
transport = new StreamableHTTPServerTransport({
sessionIdGenerator: () => randomUUID(),
onsessioninitialized: (sid) => {
transports[sid] = transport;
},
});
transport.onclose = () => {
const sid = transport.sessionId;
if (sid && transports[sid]) delete transports[sid];
};
const server = createMcpServer();
await server.connect(transport);
await transport.handleRequest(req, res, req.body);
return;
} else {
res.status(400).json({
jsonrpc: "2.0",
error: { code: -32000, message: "Bad Request" },
id: null,
});
return;
}
await transport.handleRequest(req, res, req.body);
} catch (error) {
if (!res.headersSent) {
res.status(500).json({
jsonrpc: "2.0",
error: { code: -32603, message: "Internal server error" },
id: null,
});
}
}
});
app.get("/mcp", async (req, res) => {
const sessionId = req.headers["mcp-session-id"] as string;
if (!sessionId || !transports[sessionId]) {
res.status(400).send("Invalid or missing session ID");
return;
}
await transports[sessionId].handleRequest(req, res);
});
app.delete("/mcp", async (req, res) => {
const sessionId = req.headers["mcp-session-id"] as string;
if (!sessionId || !transports[sessionId]) {
res.status(400).send("Invalid or missing session ID");
return;
}
await transports[sessionId].handleRequest(req, res);
});
const port = process.env.PORT ?? 4022;
app.listen(port, () => {
console.log(`x402 MCP Server running on http://localhost:${port}/mcp`);
});
}
main().catch(console.error);ポイントは以下の通りです。
createMcpExpressApp(): MCP SDKが提供するExpressアプリファクトリ。express.json()とDNS rebinding保護が設定済みisInitializeRequest(): セッション開始リクエストの判定。新規クライアントか既存セッションかで処理を分岐req.bodyを第3引数で渡す:handleRequest(req, res, req.body)— ミドルウェアでパース済みのボディを渡す必要があるbuildPaymentRequirementsでprice: "$0.001"と指定すると、トークンのdecimalsに応じたamountが自動計算される(6桁 →"1000")createPaymentWrapperがツールハンドラーをラップし、決済の検証・実行を透過的に処理
処理の流れ
Payment Wrapperが行う処理を整理します。
@x402/mcp Payment Wrapper 処理フロー
クリックで拡大重要なポイントは、ツールハンドラー自体は決済ロジックを一切含まないことです。createPaymentWrapperがミドルウェアとして決済の検証・実行をすべて担い、ハンドラーはビジネスロジックだけに集中できます。
Part 4: エージェントクライアントの実装
Part 3で構築したサーバーに対して、x402対応のMCPクライアントを作成します。このクライアントがAIエージェントの「財布」として機能し、402レスポンスを受け取ったら自動的にSolana USDCで決済を行います。
クライアントの作成
src/client.tsを作成します。ポイントは3つです。
- Import pathの使い分け — クライアント側の
ExactSvmSchemeは@x402/svm(デフォルトexport)からインポート。サーバー側の@x402/svm/exact/serverとは別物 createx402MCPClient(小文字のxに注意)— 標準MCPクライアントをラップし、402レスポンスの自動処理を追加autoPayment: true— 402を受け取ったら自動的にトランザクション構築・リトライ
// src/client.ts
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
import { createx402MCPClient } from "@x402/mcp";
import { ExactSvmScheme, SOLANA_DEVNET_CAIP2 } from "@x402/svm";
import { createKeyPairSignerFromBytes } from "@solana/kit";
async function main() {
// 1. Solanaウォレットのセットアップ
const { base58 } = await import("@scure/base");
const signer = await createKeyPairSignerFromBytes(
base58.decode(process.env.SOLANA_PRIVATE_KEY!),
);
console.log(`Address: ${signer.address}`);
// 2. x402対応MCPクライアントを作成
const client = createx402MCPClient({
name: "my-ai-agent",
version: "1.0.0",
schemes: [
{
network: SOLANA_DEVNET_CAIP2,
client: new ExactSvmScheme(signer),
},
],
autoPayment: true,
onPaymentRequested: async (context) => {
const price = context.paymentRequired.accepts?.[0];
console.log(`Payment: ${price?.amount} on ${price?.network}`);
return true; // trueを返すと自動支払い
},
});
// 3. MCPサーバーに接続(StreamableHTTPトランスポート)
const transport = new StreamableHTTPClientTransport(
new URL("http://localhost:4022/mcp"),
);
await client.connect(transport);
// 4. ツール一覧の取得
const tools = await client.listTools();
console.log("Available tools:", tools.tools.map(t => t.name));
// 5. 無料ツールの呼び出し
const pingResult = await client.callTool("ping", {});
console.log("Ping:", pingResult);
// → { content: [{ text: "pong" }], paymentMade: false }
// 6. 有料ツールの呼び出し(自動決済フロー)
const weatherResult = await client.callTool(
"premium_weather",
{ city: "Tokyo" },
);
console.log("Weather:", weatherResult);
// → paymentMade: true(決済が試行された)
await client.close();
}
main().catch(console.error);実行
サーバーとクライアントを別ターミナルで起動し、決済フローを確認します。
export SOLANA_WALLET_ADDRESS="your-solana-wallet-address"
npx tsx src/server.tsexport SOLANA_PRIVATE_KEY="your-base58-encoded-private-key"
npx tsx src/client.ts結果の読み方
無料ツールpingはpaymentMade: falseでそのまま結果が返り、有料ツールpremium_weatherでは以下が自動実行されます。
- サーバーが402 Payment Requiredを返却
- クライアントがSolana USDCトランザクションを構築・署名
- Facilitatorが検証・決済完了
- リトライで結果取得 →
paymentMade: true
DevnetではクライアントウォレットにSOL(ガス代)とUSDC(決済用)の両方が必要です。
- SOL:
solana airdrop 2または Solana Faucet - USDC: Circle Testnet Faucet でSolana Devnetを選択
USDC残高がない場合、Facilitatorのシミュレーションでtransaction_simulation_failedとなります。これは正常な動作で、決済フロー自体は正しく動作していることを示します。
Part 5: MCPクライアントのx402対応状況
Part 4では@x402/mcpのcreatex402MCPClientを使って決済フローが動くことを確認しました。では、Claude CodeやCursorといった既存のMCPクライアントからはどうでしょうか。
現状: ネイティブ対応はまだない
2026年2月時点で、主要なMCPクライアント(Claude Code, Cursor, Gemini等)はx402の決済フローにネイティブ対応していません。MCPツールの発見と呼び出しはできますが、サーバーが402 Payment Requiredを返した時点で止まります。
これはMCPプロトコル自体に決済の概念がないためです。x402の決済処理 — 402レスポンスの解析、Solanaトランザクションの構築・署名、リトライ — はPart 4で実装したcreatex402MCPClientのようなx402対応レイヤーが必要です。
MCPプラグインによる拡張
ネイティブ対応を待たずとも、MCPプラグインやプロキシを経由して既存クライアントにx402決済機能を追加できます。
| ツール | 方式 | 概要 |
|---|---|---|
Payments MCP (Coinbase) | MCPサーバー | Claude Code, Cursor, Gemini等にウォレット・決済機能を付与。Solana対応。 npx @coinbase/payments-mcp で導入可能 |
Proxy | 402レスポンスを透過処理するプロキシ。現時点ではEVMのみ(Part 7で詳述) | |
MCPサーバー | 70以上のx402対応APIをMCP経由で検出・決済・利用 | |
ClawRouter (OpenClaw) | LLMルーター | OpenClaw向け。x402マイクロペイメントでLLM推論費用を支払い |
各プラグインのセットアップ手順はそれぞれのドキュメントを参照してください。記事で個別に解説するとかなり長くなってしまうため、今回はスコープ外とします。本記事ではPart 4のcreatex402MCPClientによる動作確認をもってx402決済フローの検証としています。
今後の展望
MCPプロトコル自体にネイティブ決済サポートの提案(SEP-2007)が提出されています。payments/listメソッドで支払い方法を発見し、エラーコード-32803で支払い要求を返却する設計で、x402 V2が最初のサポート対象プロトコルとして想定されています。
これが採用されれば、Claude CodeやCursorといったメジャーなMCPクライアントがプロトコルレベルでx402決済をネイティブ処理できるようになります。そうなったとき、Part 3で構築したサーバーはコードを一切変更せずに、あらゆるAIエージェントから決済付きで利用可能になります。
Part 6: 本番デプロイに向けて
Devnetからメインネットへ
// config.ts - メインネット設定
export const paymentRequirements: PaymentRequirements[] = [
{
scheme: "exact",
network: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp", // メインネット
amount: "10000", // 0.01 USDC
asset: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", // USDC メインネット
payTo: process.env.SOLANA_WALLET_ADDRESS!,
maxTimeoutSeconds: 60,
extra: {},
},
];複数ネットワーク対応
V2のResourceInfo分離により、同一ツールに複数の支払い方法を提示できます。
const paymentRequirements: PaymentRequirements[] = [
// Solana USDC
{
scheme: "exact",
network: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
amount: "10000",
asset: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
payTo: "your-solana-wallet",
maxTimeoutSeconds: 60,
extra: {},
},
// Base USDC
{
scheme: "exact",
network: "eip155:8453",
amount: "10000",
asset: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
payTo: "your-evm-wallet",
maxTimeoutSeconds: 60,
extra: { name: "USDC", version: "2" },
},
];Facilitatorの選択肢
Solanaをサポートするx402 Facilitatorは複数存在します。
| Facilitator | URL | 特徴 |
|---|---|---|
Coinbase CDP | https://x402.org/facilitator | 公式。月1,000tx無料。Devnet/Mainnet対応 |
Thirdweb | https://api.thirdweb.com/v1/payments/x402/ | Solana Mainnet/Devnet対応。統一API |
PayAI | https://facilitator.payai.network | Solana特化。ガスレス体験 |
Kora | Solana Foundation推奨 |
Hooksによる拡張
createPaymentWrapperはライフサイクルフックをサポートしています。
const wrapWithPayment = createPaymentWrapper(resourceServer, {
accepts: paymentRequirements,
hooks: {
// 決済検証後、ツール実行前
onBeforeExecution: async ({ payment, args }) => {
console.log("Payment verified, executing tool...");
// falseを返すとツール実行をキャンセル
return true;
},
// ツール実行後、決済前
onAfterExecution: async ({ payment, result }) => {
console.log("Tool executed, settling payment...");
},
// 決済完了後
onAfterSettlement: async ({ settlement }) => {
console.log("Settlement:", settlement.transaction);
// 売上レコードの保存、メトリクスの記録等
},
},
});Part 7: MCPエコシステムとx402
@x402/mcp以外にも、x402 × MCPの実装は急速にエコシステムが広がっています。
主要な実装
| パッケージ/プロジェクト | 言語 | 特徴 |
|---|---|---|
TypeScript | Coinbase公式。サーバー/クライアント両方 | |
TypeScript | Proxy対応。Claude Desktopとの統合 | |
Go | mcp-go拡張。Solana/EVM両対応 | |
TypeScript | MetaMask提供のMCPサーバー | |
TypeScript | MCP × x402インフラ |
@civic/x402-mcp のProxy機能
@civic/x402-mcpは、x402に対応していないMCPクライアント(Claude Desktop等)でも支払い対応MCPサーバーを利用できるProxy機能を提供しています。
- Client Proxy: クライアント側にProxyを立て、402レスポンスを透過的に処理
- Server Proxy: 既存のMCPサーバー(APIキー認証)の前段にProxyを立て、x402決済でアクセス制御
SEP-2007: MCPネイティブの決済サポート
MCPプロトコルレベルでの決済標準化については、Part 5で詳しく解説しています。
実装時のハマりどころ
この記事のコードは実際に動作確認済みのデモリポジトリに基づいています。実装中に遭遇した落とし穴をまとめます。
| 問題 | 原因 | 解決策 |
|---|---|---|
parsePrice is not a function | サーバーで @x402/svmのクライアント用ExactSvmSchemeを使用 | @x402/svm/exact/serverからインポート |
getSupported is not a function | x402ResourceServerに生のURLを渡した | HTTPFacilitatorClientインスタンスを渡す |
Cannot POST /mcp (404) | Express 5 + StreamableHTTPの組み合わせ | createMcpExpressApp() + isInitializeRequest() + req.bodyを第3引数で渡す |
@solana/kitの鍵が抽出不可 | generateKeyPairSigner()はnon-extractableなCryptoKeyを生成 | @solana/web3.js v1のKeypair.generate()を使用 |
まとめ
この記事では、x402 V2のSolana実装を3つのレベルで解説しました。
- プロトコルレベル: SVM exact schemeの14ステップ、PaymentPayload構造、Facilitator検証ルール
- SDKレベル:
@x402/svmのトランザクション構築、@x402/mcpのPayment Wrapper - 実装レベル: 支払い対応MCPサーバーとクライアントの構築、実際のDevnet接続テスト
Solanaの低コスト・高速決済とx402のHTTPネイティブ設計が組み合わさることで、AIエージェントが1回のツール呼び出しに$0.001から課金できる世界が現実になっています。Facilitatorがガス代を負担するモデルにより、クライアントはSOLすら持つ必要がありません。
参考リンク
デモリポジトリ
- hanzochang/x402-solana-mcp-sample — この記事のサーバー/クライアント実装の動作確認済みリポジトリ
公式ソース
- coinbase/x402 GitHub
- SVM Exact Scheme Specification
- @x402/mcp README
- x402 MCP Server Guide - Coinbase
Solana x402ガイド
- How to get started with x402 on Solana - Solana Foundation
- x402 Integration with Kora - Solana
- X402 Next.js Solana Template
MCP × x402
- @civic/x402-mcp - npm
- mcp-go-x402 - GitHub
- SEP-2007: Payment Support for MCP Servers
- Introducing x402-mcp - Vercel Blog
シリーズ記事
- x402とは? AIエージェント × MCP × 暗号資産が交差するHTTP自動決済プロトコル
- x402 V2 解説 | Solana等マルチチェーン対応・OpenClawの自動売買にも利用されるHTTP決済プロトコル
この記事が参考になったら
最新の記事

x402 V2 解説 | Solana等マルチチェーン対応・OpenClawの自動売買にも利用されるHTTP決済プロトコル
累計$600M超のボリュームを記録するHTTP決済プロトコルx402がV2で大幅進化。Solana等のマルチチェーン対応、Extensions拡張機構、Discovery APIを解説。OpenClaw FoundryやClawRouterなどAIエージェントの自動売買での採用事例も紹介します。

x402とは? AIエージェント × MCP × 暗号資産が交差するHTTP自動決済プロトコル
HTTP 402を活用した決済プロトコル「x402」の入門ガイド。暗号資産(USDC)即時決済、AIエージェントによるMCP経由の自動購入、マルチチェーン対応まで、全体像を解説します。

ClaudeCode スマホでリモート接続 - OpenClawはもう不要?! RemoteControlを使おう
Claude Code Remote Controlを使えば、PCで動作中のセッションをスマホやタブレットからそのまま操作できます。QRコード接続、セキュリティ設定、トラブルシューティングまで解説します。

OpenClaw × Solana 事例まとめ - 公式スキル・周辺プロダクト・使いどころ
OpenClawとSolanaが交わる実例(公式スキル、周辺プラグイン、取引・監視系プロジェクト、ハッカソン)を一次ソースのリンク付きで一覧にまとめます。

OpenClaw APIトークン節約 - Happy + Claude Codeで出先から開発・指示出し
Happyのプロセス切断をOpenClawで復帰させ、出先からいつでもClaude Code / Codexにリモートアクセスする方法を解説。APIトークンの節約と、スマホ1台で完結するAI開発ワークフローを紹介します。

FDE(Forward Deployed Engineering)とは - 中小企業のAI導入で活きる場面
FDE(Forward Deployed Engineering)はPalantirが体系化した顧客現場型エンジニアリング手法です。中小企業のAI導入においてFDEが活きる具体的な場面と、従来のSIer・コンサル・SaaSとの違いを解説します。
