Menu

Explorer & Settings

Tempo Explorer Submit Project
Back to all projects

x402-mcpc-demo

by MQ37 · Updated 4 months ago

A demo MCP server with paid tools. Built to showcase the experimental x402 agentic payments in mcpc, the Apify-maintained MCP CLI client.

In the AI payments ecosystem

x402-mcpc-demo is an early-stage TypeScript project in the AI payments / x402 ecosystem. It currently has 0 GitHub stars and 0 forks.

README.md View on GitHub →

x402-mcpc-demo

A demo MCP server with paid tools. Built to showcase the experimental x402 agentic payments in mcpc, the Apify-maintained MCP CLI client.

mcpc | x402 Protocol


This is a companion server for mcpc's --x402 flag. When an AI agent calls a paid tool, mcpc automatically signs a USDC payment on Base and retries — no human needed. This server is the other side of that handshake.

  • MCP server with one free tool and one paid tool over Streamable HTTP
  • x402 payment gate — paid tool calls return 402 Payment Required with on-chain payment instructions
  • Verify → Settle — payment signatures are verified and settled via a facilitator before returning data
  • _meta signaling — tool definitions advertise payment requirements so mcpc can pay proactively

It's a single index.ts. Read it.


How mcpc --x402 talks to this server

mcpc (--x402)                   this server                    Facilitator
  │                               │                               │
  ├─ tools/list ─────────────────►│                               │
  │◄─ free-tool, paid-tool ──────┤  (paid-tool._meta has x402)   │
  │                               │                               │
  ├─ tools/call paid-tool ───────►│                               │
  │◄─ 402 + PAYMENT-REQUIRED ────┤                               │
  │                               │                               │
  │  (mcpc auto-signs payment)    │                               │
  │                               │                               │
  ├─ tools/call paid-tool ───────►│                               │
  │  + PAYMENT-SIGNATURE header   ├─ verify(signature) ──────────►│
  │                               │◄─ { isValid: true } ─────────┤
  │                               ├─ settle(signature) ──────────►│
  │◄─ 200 + premium data ────────┤◄─ { tx: 0x… } ───────────────┤

Three things happen on a paid tool call:

  1. No payment? → Express middleware short-circuits with 402 + base64-encoded payment requirements in the PAYMENT-REQUIRED header
  2. Has PAYMENT-SIGNATURE header? → Middleware decodes it and injects the payment payload into params._meta on the JSON-RPC message
  3. Inside the tool handler → verify with facilitator, return data, fire-and-forget settlement

When tools advertise pricing in _meta.x402, mcpc can proactively sign on the first request, skipping the 402 round-trip.


Quick start

1. Start the server

git clone <this-repo>
cd demo-x402
cp .env-local .env
# Set EVM_ADDRESS in .env
npm install
npm run dev

Server starts at http://localhost:4021/mcp.

2. Connect with mcpc

npm install -g @apify/mcpc

# Set up an x402 wallet (one-time)
mcpc x402 init
# Fund the wallet with USDC on Base Sepolia

# Connect with x402 enabled
mcpc localhost:4021/mcp connect @demo --x402

# Call the free tool — no payment
mcpc @demo tools-call free-tool name:=World

# Call the paid tool — mcpc auto-pays $0.001 USDC
mcpc @demo tools-call paid-tool query:="hello world"

That's it. mcpc sees the 402, signs payment, retries, and returns the result.


Tools

Tool Cost What it does
free-tool Free Returns a greeting
paid-tool $0.001 USDC Returns premium search results — requires x402 payment on Base Sepolia

_meta signaling

Tool definitions include payment info in _meta so mcpc knows what to pay before calling:

{
  "name": "paid-tool",
  "_meta": {
    "x402": {
      "paymentRequired": true,
      "scheme": "exact",
      "network": "eip155:84532",
      "amount": "1000",
      "asset": "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
      "payTo": "0x…"
    }
  }
}

Free tools signal "paymentRequired": false. Start the server with ?nometa query param to disable _meta — payment is still enforced via the HTTP 402 middleware, but mcpc won't pre-sign.


Payment details

402 Response

HTTP/1.1 402 Payment Required
PAYMENT-REQUIRED: <base64-encoded JSON>

Decoded:

{
  "x402Version": 2,
  "accepts": [{
    "scheme": "exact",
    "network": "eip155:84532",
    "amount": "1000",
    "asset": "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
    "payTo": "0x…"
  }],
  "error": "Payment required"
}

Paid response

{
  "query": "hello world",
  "results": [
    { "id": 1, "title": "Premium Result A", "score": 0.97 },
    { "id": 2, "title": "Premium Result B", "score": 0.91 }
  ],
  "metadata": {
    "paymentVerified": true,
    "cost": "$0.001",
    "network": "eip155:84532"
  }
}

Stack

Network identifiers use CAIP-2:

  • eip155:84532 — Base Sepolia (testnet, used here)
  • eip155:8453 — Base Mainnet (production)

Configuration

EVM_ADDRESS=0x…               # Required — your payment receiving address
PAYAI_API_KEY_ID=…            # Optional — for authenticated facilitator access
PAYAI_API_KEY_SECRET=…        # Optional — get keys at merchant.payai.network

Going to production

Create a merchant account at merchant.payai.network, set your API key env vars, and switch the network from eip155:84532 to eip155:8453. No code changes needed.


Dev

npm run dev          # start server with tsx
npm run lint         # eslint
npm run format       # prettier

Related

All MCP projects →