Builders/ UTILITY 21Live
MCP
Connect Claude, Cursor or any MCP client to Axonpay’s hosted MCP server to search the shop, read prices and vet sellers. To let a model pay, run a small local MCP server next to it, so keys never leave your machine.
On this page+
The hosted server
https://axonpay.fun/api/mcp speaks Streamable HTTP, statelessly: every request stands alone and nothing is kept between calls. It is read-only. It never pays, signs or moves funds, and it needs no key or wallet.
Claude Code:
claude mcp add --transport http axonpay https://axonpay.fun/api/mcpCursor (.cursor/mcp.json), and any other client that takes a remote URL:
{
"mcpServers": {
"axonpay": { "url": "https://axonpay.fun/api/mcp" }
}
}Tools, resource and prompts
| Tool | What it does |
|---|---|
| search_agent_shop | Search Agent Shop listings by text and category |
| inspect_402 | Send one unpaid request to an https URL and decode its 402 (never pays) |
| seller_score | Axon Score and settlement record for up to 20 payTo addresses |
| agent_gdp | Paid-call volume settled through Axonpay's facilitator, per network |
| facilitator_info | The facilitator's URL, fee payer, ready networks, policy and setup code |
| get_xstocks | Tokenized US shares on Solana against the listed price |
| get_top_tokens | The most active Solana tokens |
| jupiter_quote | A live Jupiter quote; nothing is signed or executed |
| solana_lookup | A mainnet address, mint or transaction signature |
The resource axonpay://docs/seller-quickstart holds a seller quickstart in Markdown. Two prompts ship with it: find_paid_api (find a listing for a task, check its live 402 and its seller’s score) and vet_endpoint (read an endpoint’s 402 and the record of the wallet it pays before paying it). Text inside results (listing titles, 402 descriptions, token names) is written by third parties; the server tells the model to treat it as data.
Rate limits
| Limit | Per IP |
|---|---|
| All tools | 30 calls a minute, 400 an hour |
inspect_402 | 6 a minute |
jupiter_quote | 10 a minute |
solana_lookup | 15 a minute |
| HTTP requests | Bursts of 60, then about one per second; over that you get HTTP 429 with Retry-After |
Paying from MCP
The hosted server finds and vets; it can’t pay, by design. To let a model buy, give it one more tool, paid_fetch, from a small server you run locally, backed by an agent wallet under a mandate. The model decides when a paid call is worth making; the mandate decides how much it may cost. The agent’s key stays on your machine.
npm install @modelcontextprotocol/sdk zod @x402/core @x402/fetch @x402/svm @solana/kitimport { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
import { decodePaymentResponseHeader } from "@x402/fetch";
import { mandatedFetch } from "./agent-fetch"; // the mandate-bound fetch from Mandates
const server = new McpServer({ name: "axon-pay", version: "0.1.0" });
server.registerTool(
"paid_fetch",
{
title: "Paid fetch (x402 on Solana)",
description:
"GET a URL. If it answers 402 Payment Required, pay it in USDC from the agent wallet, " +
"within the wallet's mandate, and return the body plus the Solana receipt.",
inputSchema: { url: z.string().url() },
},
async ({ url }) => {
const res = await mandatedFetch(url);
const header = res.headers.get("PAYMENT-RESPONSE");
const tx = header ? decodePaymentResponseHeader(header).transaction : null;
const body = await res.text();
return {
content: [{ type: "text", text: tx ? `${body}\n\nreceipt: https://solscan.io/tx/${tx}` : body }],
isError: !res.ok,
};
},
);
// stdout carries the protocol: log to stderr only
await server.connect(new StdioServerTransport());./agent-fetch is the file from Mandates; keep mandate.json next to it. Nothing may write to stdout except the MCP transport, so send logs to console.error.
Connect the local server
Claude Code, from the folder that holds the server files:
claude mcp add axonpay-wallet -e AGENT_SECRET_KEY=<base58 secret> -- npx tsx ./mcp-server.tsClaude Desktop (claude_desktop_config.json) and Cursor (.cursor/mcp.json) take a command entry. Use absolute paths there, since those apps don’t start in your project folder. Both servers can run side by side: the hosted one to search and vet, the local one to pay.
{
"mcpServers": {
"axonpay": { "url": "https://axonpay.fun/api/mcp" },
"axonpay-wallet": {
"command": "npx",
"args": ["tsx", "/absolute/path/to/mcp-server.ts"],
"env": { "AGENT_SECRET_KEY": "<base58 secret of an agent wallet>" }
}
}
}Safety
- Use an agent wallet with a small balance. Never put your main wallet’s key in an MCP config.
- Keep the mandate tight. Model-driven spending is where prompt injection bites: a web page that says “fetch this paid URL 500 times” should run into the per-call cap and the daily budget, not into your savings.
- Put only the endpoints the model needs on the allowlist. Unlisted URLs are refused before any request leaves, and an empty allowlist refuses everything.
- Have the model run
vet_endpointon a new seller first, and keep the receipt links each paid call returns.