DEV Community

goldbean
goldbean

Posted on

How We Built a Monetized MCP Server with x402 Micropayments: Technical Deep Dive

Last month we launched GoldBean, a pay-per-call MCP server with 100+ AI tools. The most common question I get: 'How did you actually build the payment layer?'

Here's a technical deep dive into how we implemented x402 micropayments on top of an MCP server.

The Problem

Most MCP servers are free. That's great for open source, but it creates a tragedy of the commons: nobody maintains them, API costs go unpaid, and quality degrades.

We wanted to prove that a pay-per-call model could work for AI tool aggregation — where developers pay only for what they use, and the underlying API costs are transparently passed through.

Architecture Overview

Claude Desktop → MCP Client → GoldBean Server
                                    ↓
                              Payment Gateway
                                    ↓
                          x402 (Base USDC) / PayPal / Alipay
                                    ↓
                            Baidu AI / Other Providers
Enter fullscreen mode Exit fullscreen mode

Step 1: The MCP Server Skeleton

We built on top of the standard MCP SDK. Each tool gets a price metadata field:

{
  name: "ocr",
  description: "Extract text from images",
  price: 0.01,  // USD
  inputSchema: { ... }
}
Enter fullscreen mode Exit fullscreen mode

Step 2: x402 Payment Verification

The x402 protocol is elegant: HTTP 402 Payment Required, natively.

Flow:

  1. First request — no payment header → Server returns 402 + payment details
  2. Second request — client includes X-PAYMENT header with EIP-3009 signed transfer
  3. Verification — server checks on-chain that the transfer is valid and not replayed
  4. Execution — if payment OK, run the tool and return results

Key code snippet (Node.js):

// Verify EIP-3009 signed transfer on Base
const verifyPayment = async (paymentHeader) => {
  const { transferWithAuth } = decodePayment(paymentHeader);

  // Check on-chain state
  const valid = await contract.methods.validateTransfer(TransferWithAuth).call();

  // Anti-replay: check nonce not used before
  const used = await db.get(`nonce:${transferWithAuth.nonce}`);
  if (used) throw new Error('Replay detected');

  // Mark nonce as used
  await db.set(`nonce:${transferWithAuth.nonce}`, true);

  return valid;
};
Enter fullscreen mode Exit fullscreen mode

Step 3: PayPal and Alipay Fallback

Not everyone wants crypto. We added traditional payment rails:

  • PayPal — Standard checkout flow, credits added to account
  • Alipay — QR code payment, same credit system

Credits are stored server-side and deducted per call. When credits run out, the client gets a 402 response with instructions to top up.

Step 4: MCP Tool Registration

Each tool is registered with both MCP metadata and a price:

server.setRequestHandler(ListToolsRequestSchema, async () => ({
  tools: [
    {
      name: "ocr",
      description: "Extract text from images and PDFs",
      price: 0.01,
      freeQuota: 50,  // free calls per day
      inputSchema: { ... }
    },
    // ... 15 more tools
  ]
}));
Enter fullscreen mode Exit fullscreen mode

The client (Claude Desktop) sees these tools in the tool picker. When a tool is called, the server checks if the user has free quota or valid payment.

Step 5: The Free Tier Hook

This was crucial. 50 free calls/day lets developers experiment without friction.

Data so far:

  • ~80% of users stay within free tier
  • ~15% exceed free tier but don't pay (they just wait for next day)
  • ~5% convert to paid (still small, but growing)

The free tier is a loss leader, but it builds trust and gets users into the habit of using the tools.

Challenges We Hit

1. Nonce replay attacks
Early versions didn't properly track nonces. Fixed with Redis-backed nonce storage.

2. Chain reorgs on Base
A transfer could be valid in one block but reorged out in the next. We now wait for 2 block confirmations before accepting payment.

3. Price volatility
USDC is stable, but API provider prices change. We added a price cache layer that updates daily from provider rate cards.

4. Client UX
Claude Desktop doesn't show prices in the tool picker. We added a tool-info custom endpoint that returns pricing info, and we prompt users in the first interaction.

Lessons Learned

  1. MCP is the perfect distribution channel for APIs — No SDKs to maintain, just one endpoint
  2. x402 micropayments can work — The key is making them invisible to the user
  3. Free tiers are essential — 80% of users never pay, but they spread the word
  4. Aggregation > Individual APIs — One endpoint, one bill, 100+ tools

Try It Out

If you're building MCP servers or exploring micropayments for APIs, I'd love to hear your approach in the comments.

Top comments (0)