Monetize seu servidor MCP em 10 minutos.
Instale @blockchain0x/mcp e, dentro de uma ferramenta premium, chame requirePayment quando o chamador não tiver pago - isso gera um desafio x402 402 com uma URL de checkout hospedada, que você retorna. Assim que o webhook payment.received confirmar o acerto, você marca o chamador como pago em sua própria loja e a ferramenta é executada. Ferramentas gratuitas continuam gratuitas. Para um servidor HTTP simples, o adaptador x402 do lado de recebimento faz o mesmo trabalho.
Antes de você começar.
- Um servidor MCP funcional usando o SDK oficial Model Context Protocol em Node ou Python. Se você ainda não tiver um, crie um com o template upstream primeiro.
- Uma conta Blockchain0x e um perfil de agente (veja o guia de adicionar pagamentos ao agente para a configuração de 5 minutos).
- Uma chave de API (use
sk_test_para este guia). - Uma pequena loja para lembrar quem pagou (uma linha de banco de dados ou uma chave Redis) - seu código possui isso, atualizado pelo webhook de pagamento.
- Uma noção clara de quais ferramentas você deseja cobrar e o preço por chamada. Veja a entrada do glossário de ferramentas MCP pagas para padrões de design.
Instale o pacote.
@blockchain0x/mcp exports requirePayment, a pure function that mints an x402 402 challenge for a tool. It is npm (TypeScript) only. If you run a plain HTTP server instead of an MCP one, install the receive-side x402 adapter and gate routes with it.
# Gate your own MCP tools with the requirePayment 402 builder:
npm install @blockchain0x/mcp
# Or gate a plain HTTP server with the receive-side x402 adapter + SDK:
npm install @blockchain0x/x402 @blockchain0x/nodeBloqueie uma ferramenta com requirePayment.
Inside the tool, check your own paid-state for the caller. If they have not paid, call requirePayment and return the resulting 402 body; if they have, run the work. requirePayment is a pure builder - it does not wrap the handler and does not track payment, so the gating policy stays in your code.
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { requirePayment } from "@blockchain0x/mcp";
import { z } from "zod";
const server = new McpServer({ name: "premium-data-mcp", version: "1.0.0" });
server.tool(
"get_quote_realtime",
"Real-time quote (paid)",
{ ticker: z.string() },
async ({ ticker }, extra) => {
if (!hasPaid(extra)) {
// Pure function: mint an x402 402 challenge and hand the body back.
const { body } = requirePayment({
amountUsdc: "0.005",
payTo: "0xYourWallet",
hostedUrl: "https://pay.blockchain0x.com/checkout/abc",
});
return { content: [{ type: "text", text: JSON.stringify(body) }], isError: true };
}
const quote = await fetchLiveQuote(ticker);
return { content: [{ type: "text", text: JSON.stringify(quote) }] };
},
);import express from "express";
import { createX402Middleware } from "@blockchain0x/x402/server/express";
import { createClient } from "@blockchain0x/node";
const sdk = createClient({ apiKey: process.env.BLOCKCHAIN0X_API_KEY! });
const app = express();
// Not an MCP server? Gate a plain HTTP route the same way. The middleware
// answers unpaid requests with a 402 and lets paid ones through.
// Configure the price and recipient per the x402 docs.
app.use("/quote", createX402Middleware({ sdk }));O corpo 402 requirePayment retorna para um chamador não pago:
// requirePayment returns { status: 402, body }. The body an unpaid caller sees:
{
"error": "payment_required",
"amountUsdc": "0.005",
"payTo": "0xYourWallet",
"hostedUrl": "https://pay.blockchain0x.com/checkout/abc",
"network": "mainnet"
}Confirme o pagamento e, em seguida, lembre-se de quem pagou.
When a caller pays the checkout, Blockchain0x POSTs a signed payment.received event to your webhook. Verify it with webhooks.verify from @blockchain0x/node, then write the paid state to a store you control - a database row, a Redis key, your call. That store is what the tool checks in Step 2. There is no shipped receipt cache; you own where paid-state lives and how long it lasts.
import express from "express";
import { webhooks } from "@blockchain0x/node";
const app = express();
app.use(express.raw({ type: "application/json" }));
app.post("/webhooks/payment", (req, res) => {
const result = webhooks.verify({
headers: req.headers,
rawBody: req.body, // RAW bytes
secret: process.env.BLOCKCHAIN0X_WEBHOOK_SECRET!,
});
if (!result.ok) return res.status(400).json({ code: result.code });
if (result.eventType === "payment.received") {
// Remember the payer however you like - a DB row, a Redis key, your call.
markPaid(result.eventId);
}
res.status(200).send("ok");
});Quanto tempo um pagamento concede acesso é sua decisão - uma única chamada, uma sessão, uma hora. Defina uma expiração na chave de estado pago que corresponda a como você precifica a ferramenta. Longo o suficiente para que uma sessão normal reutilize um pagamento, curto o suficiente para que o abuso seja contido.
Implante e verifique.
Envie o servidor. Ferramentas gratuitas ainda devem retornar seu resultado imediatamente; ferramentas restritas devem retornar o corpo 402 na primeira chamada de um cliente novo, depois executar uma vez que esse chamador é marcado como pago. Verifique ambos os caminhos em uma chave sk_test_ contra a Base Sepolia antes de ir ao vivo.
Dois sinais para observar no primeiro dia: a contagem de 402s retornados (seu topo de funil) e a contagem de execuções bem-sucedidas de ferramentas após um 402 (sua conversão). Se a conversão for muito menor do que o esperado, o preço provavelmente está errado. Observe também a taxa de acertos do seu armazenamento de estado pago - se estiver perto de zero, sua janela de acesso é muito curta e os chamadores pagantes estão sendo solicitados a pagar novamente.
Cinco coisas que prejudicam os monetizadores do MCP pela primeira vez.
Liberar as ferramentas gratuitas por acidente
É tentador restringir cada ferramenta 'apenas por precaução'. Não faça isso. Todo o valor dos servidores MCP pagos é que ferramentas gratuitas coexistem com as pagas no mesmo servidor, para que o cliente possa usar as ferramentas gratuitas de descoberta e metadados sem pagar. Gere um 402 apenas para as ferramentas que realmente consomem recursos premium; deixe o restante como resultados simples.
requirePayment é um construtor, não middleware
requirePayment é uma função pura: você a chama quando uma ferramenta não é paga, ela retorna { status: 402, body }, e você devolve o corpo. Não envolve seu manipulador e não rastreia quem pagou. Ela aceita amountUsdc, payTo, hostedUrl e uma rede e descrição opcionais - nada mais. Se um chamador pagou é uma verificação que você faz contra sua própria loja.
Não há cache de recibos enviado
Blockchain0x envia o construtor 402 e o webhook de liquidação, não um helper de armazenamento de recibos. Você decide onde 'este chamador pagou' reside - uma linha de banco de dados, uma chave Redis, um mapa em memória para um único processo - e você altera isso quando o webhook payment.received chega. Isso mantém a política (quanto tempo um pagamento concede acesso) totalmente em suas mãos.
Confiando em um recibo que o cliente afirma ter
Não deixe o chamador afirmar que pagou. A fonte da verdade é o webhook payment.received, verificado com webhooks.verify (ou o HMAC documentado) contra seu segredo de webhook. Marque o pagador como pago apenas após um evento verificado, e controle a ferramenta com esse estado do lado do servidor - nunca em algo que o cliente envia.
Sem métricas sobre latência de ferramentas pagas
Colocar um passo de pagamento entre o cliente e a execução da ferramenta adiciona o tempo que o chamador leva para pagar e liquidar na primeira chamada, depois quase zero uma vez que você os marcou como pagos. Instrumente ambos os ramos para que você possa distinguir 'ferramenta é lenta' de 'pagamento é lento' quando um cliente reclama. Sem a métrica, você irá diagnosticar mal o gargalo.
Uma vez que o tráfego pago esteja fluindo.
Com a monetização em vigor, os seguimentos mais úteis são a manipulação confiável de webhook (para que você não perca eventos de pagamento), controles de gastos (para que um servidor MCP que você constrói que também paga outros agentes permaneça limitado) e um fluxo primeiro para testnet (para que você possa enviar mudanças de preços sem queimar dinheiro real).
Os padrões de webhook que os desenvolvedores mais perguntam
Configure controles de gastos do agente que sobrevivem à injeção de prompt
Teste pagamentos de agentes sem dinheiro real
Referência completa da API em docs.blockchain0x.com. Superfície de produto relacionada: Integração MCP.