x402
The x402 plugin enables tool monetization through the HTTP 402 payment protocol using USDC on Base.
Overview
The x402 plugin integrates the x402 payment protocol with your xmcp server, enabling you to charge USDC micropayments for tool usage on the Base blockchain.
Installation
Install the x402 plugin:
pnpm add @xmcp-dev/x402Set up your wallet
Before integrating the plugin, you need a wallet address to receive payments:
- Create or use an existing Ethereum-compatible wallet (e.g., Coinbase Wallet, MetaMask)
- Get your wallet's public address (starts with
0x) - For testing, use Base Sepolia testnet and get test USDC from the Coinbase Developer Platform under Wallets > Faucet
The x402 protocol uses USDC stablecoin for payments. On Base mainnet, 1 USDC = 1 USD.
Environment Variables
Create a .env file in the root of your project and configure the following environment variables:
Set up the Provider
Create a middleware.ts file in your xmcp app's src directory and import the provider from the package:
Configuration Options
wallet: Your wallet address that receives paymentsfacilitator: (Optional) Facilitator URL (defaults tohttps://x402.org/facilitator)debug: (Optional) Enable debug loggingdefaults: (Optional) Default values for all paid toolsprice: Price in USDC (default:0.01)currency: Currency code (default:"USDC")network: Blockchain network -"base"or"base-sepolia"(default:"base")maxPaymentAge: Maximum payment age in seconds (default:300)
Monetize a Tool
Wrap your tool functions with paid() to require payment:
Pricing
You can set a custom price for each tool by passing a price option to paid(). If not specified, the tool will use the default price from your provider configuration. If the provider doesn't specify a default price either, the tool will cost 0.01 USDC per call.
Tool Options
price: Price in USDC for this tool (falls back to provider default, then 0.01 USDC)network: Override default networkmaxPaymentAge: Override maximum payment agedescription: Description used in payment requirements
Get Payment Details
Access payment details inside your tool using the payment() function:
Networks
The plugin supports two networks:
| Network | Chain ID | Use Case |
|---|---|---|
base | 8453 | Production with real USDC |
base-sepolia | 84532 | Testing with testnet USDC |
Troubleshooting
Payment Required Response
If clients receive a 402 response, they need to:
- Extract payment requirements from
result.structuredContent.accepts - Sign a payment authorization using their wallet
- Retry with payment in
params._meta["x402/payment"]
Payment Verification Failed
If payment verification fails:
- Ensure the payment amount matches the tool price
- Check that the payment is recent (within
maxPaymentAgeseconds) - Verify the correct network is being used (base vs base-sepolia)
Settlement Errors
If settlement fails after tool execution:
- Check the facilitator URL is correct and reachable
- Verify your wallet address is valid
- Ensure the payer has sufficient USDC balance
Missing Payment Context
If payment() throws "x402 context not initialized":
- Ensure
x402Provideris exported as default frommiddleware.ts - Only call
payment()inside paid tool handlers - Don't call
payment()at module load time