Monetiza tu servidor MCP en 10 minutos.
Instala @blockchain0x/mcp, y dentro de una herramienta premium llama a requirePayment cuando el llamador no ha pagado - crea un desafío x402 402 con una URL de pago alojada, que devuelves. Una vez que el webhook payment.received confirma el asentamiento, marcas al llamador como pagado en tu propia tienda y la herramienta se ejecuta. Las herramientas gratuitas permanecen gratuitas. Para un servidor HTTP simple, el adaptador x402 del lado de recepción hace el mismo trabajo.
Antes de comenzar.
- Un servidor MCP funcional utilizando el SDK oficial Model Context Protocol en Node o Python. Si aún no tienes uno, primero crea uno con la plantilla de upstream.
- Una cuenta de Blockchain0x y un perfil de agente (consulta la guía para agregar pagos al agente para la configuración de 5 minutos).
- Una clave de API (usa
sk_test_para esta guía). - Una pequeña tienda para recordar quién ha pagado (una fila de base de datos o una clave de Redis) - tu código posee esto, actualizado por el webhook de pago.
- Una clara comprensión de qué herramientas deseas cobrar y el precio por llamada. Consulta la entrada del glosario de herramientas MCP pagadas para patrones de diseño.
Instala el paquete.
@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/nodeRestringe una herramienta con 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 }));El cuerpo 402 requirePayment devuelve a un llamador no pagado:
// 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 el pago, luego recuerde quién pagó.
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");
});Cuánto tiempo otorga acceso un pago es tu decisión - una sola llamada, una sesión, una hora. Establece una fecha de caducidad en la clave de estado pagado que coincida con cómo estableces el precio de la herramienta. Lo suficientemente largo como para que una sesión normal reutilice un pago, lo suficientemente corto como para que el abuso esté limitado.
Despliega y verifica.
Envía el servidor. Las herramientas gratuitas aún deben devolver su resultado de inmediato; las herramientas restringidas deben devolver el cuerpo 402 en la primera llamada de un cliente nuevo, luego ejecutarse una vez que ese llamador esté marcado como pagado. Verifica ambos caminos con una clave sk_test_ contra Base Sepolia antes de ir en vivo.
Dos señales a observar en el primer día: el conteo de 402s devueltos (tu embudo superior) y el conteo de ejecuciones exitosas de herramientas después de un 402 (tu conversión). Si la conversión es mucho más baja de lo esperado, el precio probablemente esté mal. Observa también la tasa de aciertos de tu tienda de estado pagado - si está cerca de cero, tu ventana de acceso es demasiado corta y se está pidiendo a los llamadores que paguen nuevamente.
Cinco cosas que afectan a los monetizadores de MCP por primera vez.
Controlando las herramientas gratuitas por accidente
Es tentador restringir cada herramienta 'por si acaso'. No lo hagas. Todo el valor de los servidores MCP de pago es que las herramientas gratuitas coexisten con las de pago en el mismo servidor, por lo que el cliente puede usar las herramientas de descubrimiento y metadatos gratuitas sin pagar. Crea un 402 solo para las herramientas que realmente consumen recursos premium; deja el resto como resultados simples.
requirePayment es un constructor, no middleware
requirePayment es una función pura: la llama cuando una herramienta no está pagada, devuelve { status: 402, body }, y le entrega el cuerpo de vuelta. No envuelve su controlador y no rastrea quién pagó. Toma amountUsdc, payTo, hostedUrl y una red y descripción opcionales - nada más. Si un llamador ha pagado es una verificación que usted realiza contra su propia tienda.
No hay caché de recibos enviado
Blockchain0x envía el constructor 402 y el webhook de liquidación, no un ayudante de almacenamiento de recibos. Usted decide dónde vive 'este llamador pagó' - una fila de base de datos, una clave de Redis, un mapa en memoria para un solo proceso - y lo cambia cuando llega el webhook payment.received. Eso mantiene la política (cuánto tiempo un pago otorga acceso) completamente en sus manos.
Confiando en un recibo que el cliente afirma tener
No permita que el llamador afirme que pagó. La fuente de verdad es el webhook payment.received, verificado con webhooks.verify (o el HMAC documentado) contra su secreto de webhook. Marque al pagador como pagado solo después de un evento verificado, y controle la herramienta en ese estado del lado del servidor - nunca en algo que envíe el cliente.
Sin métricas sobre la latencia de herramientas pagadas
Poner un paso de pago entre el cliente y la ejecución de la herramienta añade el tiempo que el llamador tarda en pagar y liquidar en la primera llamada, luego casi cero una vez que los has marcado como pagados. Instrumenta ambas ramas para que puedas distinguir 'la herramienta es lenta' de 'el pago es lento' cuando un cliente se queja. Sin la métrica, diagnosticarás mal el cuello de botella.
Una vez que el tráfico pagado esté fluyendo.
Con la monetización en su lugar, los seguimientos más útiles son el manejo confiable de webhooks (para que no te pierdas eventos de pago), controles de gasto (para que un servidor MCP que construyas que también pague a otros agentes se mantenga limitado) y un flujo primero en testnet (para que puedas enviar cambios de precios sin gastar dinero real).
Los patrones de webhook sobre los que los desarrolladores preguntan más
Configurar controles de gasto del agente que sobrevivan a la inyección de prompts
Pruebe los pagos de agentes sin dinero real
Referencia completa de la API en docs.blockchain0x.com. Superficie de producto relacionada: integración MCP.