Skip to main content

Overview

This example demonstrates how to use the Model Context Protocol (MCP) with x402 payments to enable AI agents to make paid API calls to Snack Money.

Features

  • JSON-RPC 2.0 protocol implementation
  • x402 payment integration
  • Support for Base (EVM) and Solana networks
  • Tool discovery and invocation
  • Automatic payment handling

Installation

Clone the example repository:
git clone https://github.com/snack-money/snack-money-examples.git
cd snack-money-examples/mcp
yarn install

Configuration

Create a .env file with your credentials:
# For Base (EVM) network
EVM_PRIVATE_KEY=0x...

# For Solana network
SVM_PRIVATE_KEY=...base58...

# Common settings
RECEIVER=username
AMOUNT=0.01
PLATFORM=twitter  # twitter, farcaster, email, github, web
API_URL=https://api.snack.money

Usage

List Available Tools

Discover all available MCP tools:
yarn list-tools
Output:
{
  "tools": [
    {
      "name": "pay_twitter",
      "description": "Send USDC to a Twitter/X user",
      "inputSchema": { ... }
    },
    {
      "name": "pay_farcaster",
      "description": "Send USDC to a Farcaster user",
      "inputSchema": { ... }
    },
    // ... more tools
  ]
}

Send Payment via Base Network

yarn base
This will:
  1. Call the MCP endpoint to send payment
  2. Receive payment requirements (error -32402)
  3. Sign the payment with x402 EVM client
  4. Retry with signed payment
  5. Display transaction receipt

Send Payment via Solana Network

yarn solana
Similar flow to Base, but using Solana blockchain.

Code Example

Here’s a simplified example of making an MCP call with payment:
import { X402 } from '@x402/core';
import { createEvmClient } from '@x402/evm';

// Initialize x402 client
const x402 = createEvmClient({
  privateKey: process.env.EVM_PRIVATE_KEY,
  chainId: 8453 // Base mainnet
});

// Make MCP call
async function callMcpTool(toolName: string, args: any) {
  // First attempt - will require payment
  const response = await fetch(`${API_URL}/mcp`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      jsonrpc: '2.0',
      method: 'tools/call',
      params: {
        name: toolName,
        arguments: args
      },
      id: 1
    })
  });

  const result = await response.json();

  // Check if payment required
  if (result.error?.code === -32402) {
    const { taskId, paymentRequired } = result.error.data;

    // Sign payment
    const signedPayment = await x402.createPaymentPayload(
      paymentRequired
    );

    // Retry with payment
    const paidResponse = await fetch(`${API_URL}/mcp`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        jsonrpc: '2.0',
        method: 'tools/call',
        params: {
          name: toolName,
          arguments: args,
          _meta: {
            taskId,
            x402Payment: signedPayment
          }
        },
        id: 2
      })
    });

    return paidResponse.json();
  }

  return result;
}

// Use the function
const result = await callMcpTool('pay_twitter', {
  receiver: 'alice',
  amount: 0.01,
  description: 'Thanks for the help!'
});

console.log('Payment sent:', result.result);

Protocol Flow

The MCP payment flow follows this sequence:
  1. Initial Call - Client calls MCP tool without payment
  2. Payment Required - Server returns error -32402 with:
    • taskId - Unique identifier for this task
    • paymentRequired - x402 payment requirements
  3. Sign Payment - Client signs payment using x402 client
  4. Retry with Payment - Client retries with:
    • Original parameters
    • _meta.taskId - Task identifier
    • _meta.x402Payment - Signed payment proof
  5. Success - Server returns result with receipt

Error Handling

Common error codes:
CodeDescriptionAction
-32402Payment requiredSign and retry with payment
-32600Invalid requestCheck request format
-32601Method not foundVerify method name
-32602Invalid paramsCheck parameter format
-32603Internal errorRetry or contact support

Supported Networks

  • Base (Chain ID: 8453) - USDC on Base mainnet
  • Base Sepolia (Chain ID: 84532) - USDC on Base testnet
  • Solana - USDC on Solana mainnet
  • Solana Devnet - USDC on Solana devnet

Integration with AI Agents

This MCP implementation is compatible with:

Full Example

View the complete working example: GitHub: snack-money-examples/mcp