Skip to main content
Most AI agents and MCP clients (like Claude Desktop) don’t have x402 payment support built in yet. To use paywalled MCP servers, you need to run a local proxy that handles the payment part for you. The proxy sits between your agent and the MCP server, automatically paying for each request before forwarding it to the server.

Installation

npm install express @faremeter/payment-solana @faremeter/fetch @faremeter/info @solana/web3.js

MCP Proxy

Create a local proxy that pays for paywalled MCP servers on your behalf:
import express from "express";
import { Keypair, PublicKey, VersionedTransaction, Connection } from "@solana/web3.js";
import { createPaymentHandler } from "@faremeter/payment-solana/exact";
import { wrap } from "@faremeter/fetch";
import { lookupKnownSPLToken } from "@faremeter/info/solana";
import * as fs from "fs";

const app = express();
app.use(express.json());

// Load keypair and setup payment handler
const keypairData = JSON.parse(fs.readFileSync("./payer-wallet.json", "utf-8"));
const keypair = Keypair.fromSecretKey(Uint8Array.from(keypairData));

const network = "mainnet-beta";
const connection = new Connection("https://api.mainnet-beta.solana.com");
const usdcInfo = lookupKnownSPLToken(network, "USDC");
const usdcMint = new PublicKey(usdcInfo.address);

const wallet = {
  network,
  publicKey: keypair.publicKey,
  updateTransaction: async (tx: VersionedTransaction) => {
    tx.sign([keypair]);
    return tx;
  },
};

const paymentHandler = createPaymentHandler(wallet, usdcMint, connection);
const fetchWithPayer = wrap(fetch, { handlers: [paymentHandler] });

// Proxy MCP requests
app.all("/mcp", async (req, res) => {
  const mcpServerUrl = "https://your-mcp-server.com/mcp";

  // Bypass payment for MCP protocol methods
  const bypassMethods = ["initialize", "tools/list", "prompts/list", "resources/list"];
  const shouldBypassPayment = req.body?.method && bypassMethods.includes(req.body.method);

  const fetchFn = shouldBypassPayment ? fetch : fetchWithPayer;

  const response = await fetchFn(mcpServerUrl, {
    method: req.method,
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(req.body),
  });

  const data = await response.text();
  res.status(response.status).send(data);
});

app.listen(8402, () => {
  console.log("MCP proxy running on http://localhost:8402/mcp");
});
Now point your MCP client (e.g., Claude Desktop) to http://localhost:8402/mcp - the proxy automatically pays for tool calls.

View Full MCP Demo

Complete MCP server and proxy implementation

Build your own MCP products