Referencia de las herramientas MCP
@burnbound/mcp es el servidor MCP que permite a un agente pagar APIs x402 bajo su política de Burnbound. Funciona por stdio con npx -y @burnbound/mcp@latest, expone siete herramientas (fetch_paid, get_budget, propose_rule, list_payments, get_approval_status, search_paid_apis y diagnose_payment) e incluye una CLI wallet para la firma en el cliente y una CLI doctor que explica por qué falla un pago. Esta página documenta la versión 0.7.0.
¿Cómo configuro el servidor?
El servidor se configura solo con variables de entorno en la configuración de tu cliente MCP. BURNBOUND_KEY es la única obligatoria. El servidor comprueba la configuración antes de arrancar y, si falta algo o algo no es seguro, se cierra con un mensaje en stderr.
| Variable | Obligatoria | Significado |
|---|---|---|
BURNBOUND_KEY |
sí | La clave del agente (bb_agent_…). |
BURNBOUND_API |
no | URL base de la API de Burnbound. Por defecto, https://app.burnbound.dev. Tiene que ser https:// (http:// solo para un host de loopback). |
BURNBOUND_AGENT_ID |
solo con una clave de organización | El agente en cuyo nombre actúan las herramientas. Se ignora con una clave de agente, que ya indica su agente. |
BURNBOUND_MAX_RESPONSE_BYTES |
no | Tope del cuerpo de respuesta que devuelve fetch_paid. Por defecto, 1048576 (1 MiB); como máximo, 10485760 (10 MiB). Los cuerpos más largos se truncan. |
BURNBOUND_FETCH_TIMEOUT_MS |
no | Plazo para todo el intercambio con la URL en fetch_paid. Por defecto, 30000; de 1000 a 120000. |
BURNBOUND_APP_URL |
no | Origen del panel de Burnbound, con el que se construye approvalUrl para un pago retenido. Por defecto, el origen de BURNBOUND_API cuando es https://; con una API en loopback no hay valor por defecto ni enlace. Solo un origen, sin ruta. Tiene que ser https:// (http:// solo para un host de loopback). |
BURNBOUND_APPROVAL_WAIT_MS |
no | Cuánto espera fetch_paid la decisión de la persona después de que el usuario abra la página de aprobación desde el chat. Por defecto, 40000; de 0 a 50000. Con 0, devuelve pending_approval sin esperar. |
BURNBOUND_BASE_RPC_URL |
no | RPC que usa diagnose_payment para leer el saldo en USDC de la cartera que paga en Base. Por defecto, https://mainnet.base.org. Tiene que ser https://; un valor no válido solo desactiva la comprobación de saldo en esa red, con un aviso en stderr. |
BURNBOUND_BASE_SEPOLIA_RPC_URL |
no | Lo mismo para Base Sepolia. Por defecto, https://sepolia.base.org. |
BURNBOUND_ALLOW_PRIVATE_HOSTS |
no | Con 1, fetch_paid puede llegar a loopback y a redes privadas, y usar http:// en loopback. Solo para desarrollo local. Las direcciones link-local siguen bloqueadas. |
BURNBOUND_WALLET_PROFILE |
no | Cartera local que se usa para la firma en el cliente. Por defecto, default. De 1 a 32 caracteres entre a-z, 0-9, _ y -. |
BURNBOUND_HOME |
no | Cambia de sitio el directorio ~/.burnbound, donde se guardan las carteras en fichero. |
El servidor no arranca si alguna variable BURNBOUND_* parece una clave privada: las claves de cartera nunca van en la configuración MCP. Una clave de organización sigue funcionando junto con BURNBOUND_AGENT_ID, con un aviso en stderr: las claves de organización tienen alcance de administrador, así que usa una clave de agente.
¿Qué hace fetch_paid?
fetch_paid pide una URL de uno de los hosts permitidos del agente y, si la URL responde HTTP 402 con un challenge x402, la paga bajo la política del agente y devuelve la respuesta pagada. Es la única herramienta que puede gastar dinero, y se declara al cliente MCP como no de solo lectura y de mundo abierto.
| Entrada | Tipo | Notas |
|---|---|---|
url |
string, obligatoria | URL https://, de hasta 2048 caracteres, en uno de los hosts permitidos del agente. |
method |
string | GET (por defecto), HEAD, POST, PUT, PATCH o DELETE. |
headers |
objeto de strings | Hasta 32 cabeceras adicionales. Se rechazan Authorization, las cabeceras de pago (PAYMENT-SIGNATURE, X-PAYMENT…), x-org-api-key, Host, proxy-* y las cabeceras hop-by-hop. |
body |
string | Hasta 256 KB. No se admite con GET ni con HEAD. |
idempotencyKey |
string | Solo para reintentar una compra: la clave de un resultado pending_approval o de un error payment_outcome_unknown anteriores. De 8 a 128 caracteres entre letras, dígitos, ., _, : y -. |
maxAmountUsd |
string o número | No pagar más de estos USD en esta llamada, por ejemplo "0.05". Tu política de Burnbound se sigue aplicando encima. |
origin |
string | De dónde salió la URL: user (la pidió la persona), catalog (un resultado de search_paid_apis), tool_output (el resultado de otra herramienta) o web (una página que leyó el agente). Cualquier otro valor se rechaza. |
origin solo sirve para la auditoría. Burnbound lo guarda en el registro de auditoría y con la aprobación, pero nunca lo usa para decidir: un pago declarado user pasa exactamente por las mismas reglas que uno declarado web, y un agente que no lo indica o lo declara mal no gana nada.
maxAmountUsd se compara con el challenge del vendedor antes de autorizar nada, y de nuevo con lo que se firma. Se aplica al precio que Burnbound puede pagar: USDC exact en Base o Base Sepolia. Los precios en otras cadenas, en otros tokens o en otros esquemas se ignoran, porque nunca se pagan.
¿Qué resultados puede devolver fetch_paid?
fetch_paid devuelve uno de tres estados. Todo lo demás (una denegación, un límite, un problema de red) vuelve como error de herramienta con un código.
status |
Significado y campos |
|---|---|
ok |
No hacía falta pagar. httpStatus, host, body. |
paid |
Pagado. httpStatus, host, intentId, idempotencyKey, replayed (se volvió a responder la misma compra y no se cobró nada nuevo), mode (server_signed o client_signs), amountUsd, network, payTo, receipt.state (settled, pending, failed o unknown), receipt.txHash, body. |
pending_approval |
Antes tiene que aprobarlo una persona. approvalId, amountUsd, reason (ver más abajo), thresholdUsd, host, idempotencyKey y next (lo que debe hacer el agente). Cuando el servidor conoce la dirección del panel, también approvalUrl y approvalPrompt (ver aprobar desde el chat). Consulta get_approval_status; cuando esté en approved, vuelve a llamar a fetch_paid con los mismos url, method, headers, body e idempotencyKey. |
body es { untrusted: true, contentType, encoding, bytes, truncated, text }. Los tipos de contenido binarios vuelven codificados en base64. En el resultado de la herramienta, el cuerpo va en un bloque de texto aparte, delimitado y etiquetado como contenido de terceros no fiable, nunca mezclado con los metadatos. Las cabeceras de la respuesta nunca se devuelven.
status solo es paid cuando el vendedor respondió a la petición pagada con un 2xx y no informó de que la liquidación hubiera fallado. Cualquier otra respuesta después de pagar (otro 402, una redirección, un error) es un error de herramienta, payment_rejected_by_seller o payment_not_completed, nunca paid. fetch_paid envía un pago firmado una sola vez por llamada y nunca vuelve a firmar por su cuenta.
receipt.state es unknown cuando no se pudo registrar el recibo; el pago se hizo igualmente si status es paid. Si no se pudo leer el cuerpo de la respuesta pagada, bodyError dice por qué, y el pago se informa igual.
¿Por qué un pago espera una aprobación?
reason, en un resultado pending_approval, dice por qué una persona tiene que aprobar este pago. Un pago que incumple una regla se deniega, nunca se manda a aprobación; estas retenciones llegan después de que pasen todas las reglas.
reason |
Cuándo |
|---|---|
instruction_like_description |
La descripción o el texto error del 402 parece dar instrucciones al agente ("ignore previous instructions…"), sea cual sea el importe e incluso si ya se pagó antes a esa dirección. Aprobarlo nunca añade el host a los hosts permitidos. |
catalog_new_host |
El primer pago a un host del catálogo admitido por la regla de hosts del catálogo del agente, sea cual sea el importe. |
new_pay_to |
El primer pago de la organización a esta dirección de cobro en este host y esta red, sea cual sea el importe. No se aplica a un vendedor listado en el catálogo al que se paga en una dirección que Burnbound tiene fijada para él, ni a uno que rota su dirección. Los pagos siguientes pasan. |
rule |
Coincidió una regla propia en vigor con la acción de pedir aprobación: del agente, de su subequipo o de la organización. rules las nombra y ruleScopes dice de quién es cada una (agent, team u org). Ver reglas propias. |
threshold |
El importe es igual o superior al umbral de aprobación del agente, en thresholdUsd. |
Un pago retenido tiene un único motivo: el primero que aplica, en el orden de la tabla. thresholdUsd es null para todos los motivos menos threshold. new_pay_to e instruction_like_description se aplican a todos los agentes y no necesitan ajuste; el umbral, la regla de hosts del catálogo y las reglas propias se configuran en el panel. Las versiones de @burnbound/mcp anteriores a la 0.4.0 informan new_pay_to e instruction_like_description como threshold.
¿Puede el usuario aprobar desde el chat?
En parte: el chat puede abrir la página de aprobación, pero la decisión la toma siempre una persona con sesión iniciada en el panel de Burnbound.
Cuando el servidor conoce la dirección del panel (BURNBOUND_APP_URL, o el origen de BURNBOUND_API cuando es https://), un resultado pending_approval lleva approvalUrl, la página de esa aprobación en el panel. El enlace solo lleva el id de la aprobación; sin una sesión de la organización no muestra nada. El agente debe dárselo al usuario y nunca abrirlo él mismo.
Si el cliente MCP admite la elicitación en modo URL (protocolo MCP 2025-11-25 o 2026-07-28), fetch_paid también pide al cliente que ofrezca esa página al usuario, como mucho una vez por llamada:
- El usuario acepta abrir la página. Aceptar solo la abre; no aprueba nada.
fetch_paidespera hastaBURNBOUND_APPROVAL_WAIT_MS(40 segundos por defecto) y consulta la aprobación cada 2 segundos.- Si una persona aprueba a tiempo, la misma llamada paga, con la misma
idempotencyKeyy después de repetir todas las comprobaciones: hosts permitidos,maxAmountUsd, el 402 del vendedor y la cartera. Si la persona lo rechaza, o la aprobación caduca, la llamada termina enapproval_deniedoapproval_expired. - Si nadie decide a tiempo, la llamada devuelve
pending_approvaly el agente consultaget_approval_statuscomo siempre.
approvalPrompt dice qué pasó con la página:
approvalPrompt |
Significado |
|---|---|
opened |
El usuario abrió la página y no llegó ninguna decisión durante la espera. |
declined |
El usuario no la abrió. No es una denegación: el pago sigue pendiente. |
cancelled |
El usuario o el cliente cerró la petición. Tampoco es una denegación. |
failed |
El cliente no respondió a la petición. |
unsupported |
El cliente no admite la elicitación en modo URL. El agente muestra approvalUrl y consulta el estado. |
El servidor nunca envía un formulario y nunca aprueba ni rechaza: nada de lo que responda el cliente puede decidir un pago, y la clave del agente no puede aprobar. Con el protocolo 2026-07-28, el cliente reintenta la llamada con los mismos argumentos después de la página; un reintento con otros argumentos falla con invalid_input (approval_state_mismatch).
Qué clientes abren la página, a 7 de octubre de 2026:
| Cliente | Abre la página de aprobación desde el chat |
|---|---|
| VS Code 1.107 o posterior, con GitHub Copilot | Sí. |
| Claude Code (CLI) | Todavía no: no anuncia la elicitación en modo URL, así que el resultado dice unsupported. |
| Extensión de Claude Code para VS Code | No: anuncia el modo pero no muestra la página, así que la llamada vuelve a pending_approval. |
| Cursor, Claude Desktop | Sin confirmar. |
En todos los clientes, el agente puede mostrar approvalUrl al usuario y consultar get_approval_status. Algunos clientes cortan una llamada a una herramienta al cabo de un minuto más o menos, así que mantén BURNBOUND_APPROVAL_WAIT_MS por debajo del límite de tu cliente.
¿Cómo gestiona fetch_paid las redirecciones?
Antes del 402 se siguen las redirecciones al mismo origen, hasta 3. Una redirección a otro origen se devuelve tal cual, con redirectNotFollowed: true. Una redirección después de pagar tampoco se sigue: termina en un error payment_not_completed con redirectNotFollowed: true. Un pago nunca se envía a ningún sitio que no sea la URL que lo pidió.
¿Qué devuelve get_budget?
get_budget devuelve el presupuesto del agente para hoy. No recibe entrada y es de solo lectura; los agentes deberían llamarla antes de pagar algo.
| Campo | Significado |
|---|---|
agentId |
El agente al que pertenece la clave. |
spentTodayUsd |
USD gastados hoy (día UTC). |
dailyCapUsd |
El tope diario. |
remainingTodayUsd |
Lo que queda hoy bajo el tope diario, o bajo el subtope de la persona cuando es menor. |
maxUsdPerTx |
El máximo por pago. |
stepUpThresholdUsd |
Los pagos de este importe o más esperan la aprobación de una persona; null cuando el step-up está desactivado. |
allowHosts |
Los hosts a los que puede pagar el agente. |
catalogHosts |
Hosts verificados del catálogo fuera de allowHosts a los que el agente también puede pagar cuando su regla de hosts del catálogo está activada: el primer pago a cada uno espera la aprobación de una persona y después el host se suma a allowHosts. Vacío cuando la regla está desactivada. |
capLevel |
ok, warning (a partir del 80 % del tope diario) o exhausted. |
network, asset |
La red y el activo del agente: eip155:8453 (Base) o eip155:84532 (Base Sepolia), y USDC. |
dayResetsAt |
Cuándo vuelve a 0 el gasto de hoy: la próxima medianoche UTC, como marca de tiempo ISO 8601. |
member |
Cuando el agente pertenece a una persona de la organización: el subtope diario de esa persona sumando todos sus agentes, como dailyCapUsd, spentTodayUsd y remainingTodayUsd. capSet es false cuando ningún admin ha fijado todavía un subtope: el agente no puede pagar hasta que se fije. null para un agente de la organización. |
chatRules |
Las reglas propuestas desde el chat con propose_rule que siguen aplicándose: id, action, hosts, limit, expiresAt y una note fija. Desde la 0.5.0. |
effectiveCap |
Lo que el agente aún puede gastar antes de que algo rechace un pago: remainingUsd, el menor entre el tope diario, el subtope de la persona y las reglas de límite que se aplican a todos los pagos; limitedBy (daily_cap, member_cap o rule), el ruleId de esa regla y resetsAt. Desde la 0.5.0; null con una API más antigua. |
ruleLimits |
Cada regla de límite en vigor del agente: ruleId, source (panel o chat), appliesTo (all, o matching para una regla con condiciones), hosts, limit (por ejemplo at most 30 USD per UTC week), remainingUsd o remainingCount en la ventana actual, y resetsAt. Una regla con un total por host o por payee no tiene una cifra única (null). Desde la 0.5.0. |
Desde @burnbound/mcp 0.7.0, una organización puede fijar reglas de gasto para un subequipo (un grupo de sus agentes, ver Conceptos) o para toda la organización, y se aplican al agente además de las suyas: gana la más restrictiva. Entonces effectiveCap también las cuenta y, cuando una de ellas lo marca, effectiveCap.scope es team u org (limitedBy sigue siendo rule). scopeLimits enumera esas reglas con la misma forma que ruleLimits, más scope, con las cifras del grupo en el que caen los pagos del agente (su subequipo, su persona, él mismo o todo el ámbito); no aparece cuando no hay ninguna. El agente nunca recibe el id ni el nombre del subequipo. Solo un owner o un admin de la organización puede cambiar una regla de subequipo o de organización, en el panel.
Los agentes nuevos empiezan con una regla de este tipo, tope-semanal: el gasto total del agente por semana UTC (de lunes a domingo) no puede pasar de 5 veces su tope diario. Es una regla normal que una persona puede cambiar o borrar en el panel, y no sigue los cambios posteriores del tope diario.
¿Qué hace propose_rule?
propose_rule añade una regla de gasto que solo restringe los pagos del propio agente, cuando el usuario la pide en la conversación, por ejemplo "no gastes más de 2 USD al día en api.dune.com". No es de solo lectura, pero nunca puede ampliar lo que el agente puede pagar. Disponible desde @burnbound/mcp 0.5.0.
| Entrada | Notas |
|---|---|
action |
Obligatoria. deny bloquea los pagos que coinciden, limit les pone un tope y alert solo los registra en la auditoría. |
hosts |
Hasta 10 hosts, con la sintaxis de allowHosts (api.example.com, *.example.com). Si se omite: todos los hosts. |
pathPrefixes |
Hasta 10 rutas que empiecen por /. |
payeeAddresses |
Hasta 10 direcciones payTo. |
amountOverUsd |
Solo los pagos de más de estos USD. |
maxUsd, maxCount |
Solo con limit: el máximo de USD (por encima de 0) o de pagos por ventana. |
per |
Solo con limit: day, week (desde el lunes) o month, en UTC. |
groupBy |
Solo con limit: un tope para todo el agente (agentId, por defecto), o uno por host o por payeeAddress. |
expiresInMinutes |
De 15 a 1440; por defecto, 240. |
El resultado tiene ruleId (chat- y 8 caracteres hexadecimales), expiresAt y un message fijo. Burnbound lo decide todo por su lado: la regla está en vigor, es solo de este agente y nunca pide una aprobación; un deny necesita una condición; como mucho se aplican a la vez 10 reglas propuestas desde el chat, y un agente puede proponer 20 por hora. Una regla idéntica a otra activa no se vuelve a añadir. No hay forma de cambiar, alargar ni borrar una regla desde el chat, ni siquiera una que haya propuesto el agente: solo puede hacerlo una persona, en el panel de Burnbound, y cada regla añadida así queda en la auditoría (policy.chat_rule_added). Los errores son los de cualquier herramienta, más rule_rejected (reason, fields) y rule_limit_reached (max).
¿Qué devuelve list_payments?
list_payments devuelve los pagos más recientes del agente, del más nuevo al más antiguo. Es de solo lectura.
| Entrada | Notas |
|---|---|
limit |
De 1 a 50; por defecto, 10. |
status |
Solo los pagos en este estado: created, authorized, submitted, settlement_pending, settled, failed o expired. |
El resultado es { agentId, payments }. Cada pago tiene intentId, status, amountUsd, network, asset, host, transactionHash (una vez liquidado) y createdAt. Devuelve el host al que se pagó, no la URL completa.
¿Qué devuelve get_approval_status?
get_approval_status le dice al agente si una persona ha decidido sobre un pago que necesitaba aprobación. Recibe el approvalId de un resultado pending_approval y es de solo lectura.
Devuelve approvalId, status (pending, approved, denied o expired), intentId (presente cuando ya se hizo el pago aprobado), amountUsd, host, createdAt, decidedAt y expiresAt. Una clave de agente solo ve las aprobaciones de su propio agente; cualquier otro id da approval_not_found.
¿Qué devuelve search_paid_apis?
search_paid_apis busca en el catálogo de APIs x402 verificadas de Burnbound y dice, para cada una, si fetch_paid la pagaría bajo la política del agente. Es de solo lectura. Disponible desde @burnbound/mcp 0.3.0. Las personas pueden explorar el mismo catálogo en /apis (en inglés), con una página por API.
| Entrada | Notas |
|---|---|
query |
Obligatoria, de 1 a 200 caracteres: lo que debe hacer la API, por ejemplo crypto prices. |
category |
Solo esta categoría, por ejemplo search, market-data, onchain-data o scraping. |
network |
Solo APIs que se pueden pagar en eip155:8453 (Base) o eip155:84532 (Base Sepolia). |
limit |
De 1 a 10; por defecto, 5. |
El resultado es { agentId, query, total, results }. Cada resultado tiene:
| Campo | Significado |
|---|---|
id, name, host, category |
El vendedor. host es el host exacto que cobra. |
summary |
Una descripción breve escrita por Burnbound. |
url, method, exampleBody |
La petición de ejemplo de Burnbound, siempre en host. Pásalos a fetch_paid. |
priceUsd, network, testnet |
El precio por llamada en USDC y la red en la que pagaría fetch_paid: la red del agente cuando el vendedor la acepta. |
verifiedAt |
Cuándo comprobó Burnbound por última vez, sin pagar, que la URL responde un challenge x402 válido que puede pagar. Nunca aparecen resultados de hace más de 24 horas. |
payToMode |
pinned: Burnbound conoce las direcciones de cobro del vendedor y lo suspende si cambian. rotating: el vendedor usa una nueva cada vez. |
reliability |
{ sample, successRate }. La tasa de éxito de los pagos reales a través de Burnbound en 30 días, solo cuando al menos 5 organizaciones hicieron al menos 20 pagos; si no, sample es insufficient y successRate es null. |
quality |
{ window, probes, availability, price, payTo }, de las sondas propias de Burnbound, sin pagar, durante 7 días. availability es la proporción que respondió un 402 pagable (null con menos de 4 sondas). price y payTo son stable, changed (compáralos antes de pagar), insufficient (muy pocas sondas) o, para payTo, rotating. null cuando la API no tiene ninguna. |
allowedByPolicy, requiresApproval, policyBlockers |
Si la política del agente deja que fetch_paid la pague, si antes tiene que aprobarlo una persona y los códigos de política que la bloquean (host_not_allowed, network_not_allowed, amount_exceeds_per_transaction…). |
sellerDescription |
{ untrusted: true } cuando el vendedor se describe a sí mismo. El texto solo va en un bloque aparte, delimitado y etiquetado como no fiable. |
El catálogo nunca amplía por sí solo lo que un agente puede pagar. Un agente sin política también recibe resultados, cada uno con policyBlockers: ["no_policy"]: no puede pagar a nadie hasta que se configure su política en el panel. Un resultado con host_not_allowed sigue bloqueado en fetch_paid hasta que una persona añada el host a los hosts permitidos del agente o active su regla de hosts del catálogo (allowCatalogHosts): entonces un vendedor listado queda permitido con requiresApproval: true, porque su primer pago siempre espera a una persona. Con la regla de solo vendedores verificados (verifiedSellersOnly), policyBlockers también lleva seller_not_verified o pay_to_not_verified (ver Conceptos). El orden de los resultados solo usa el texto propio de Burnbound, la política del agente, la fiabilidad medida, la frescura y el precio; no hay posiciones de pago.
¿Qué devuelve diagnose_payment?
diagnose_payment explica por qué falla el pago de una URL: una frase con la causa y qué hacer, el error que devolvería fetch_paid y un informe que una persona puede pegar en un reporte de errores. Nunca firma ni paga, no toca el presupuesto del agente y se declara al cliente MCP como de solo lectura. Disponible desde @burnbound/mcp 0.4.0. El agente debería llamarla cuando fetch_paid falla con invalid_payment_required, no_payable_entry, resource_mismatch, insufficient_funds o payment_rejected_by_seller.
| Entrada | Notas |
|---|---|
url |
Obligatoria. La URL https:// cuyo pago falla. No tiene que estar en los hosts permitidos del agente, porque no se paga nada. |
method |
GET (por defecto), POST, PUT, PATCH o DELETE. Algunos vendedores solo cobran en POST. |
wallet |
La dirección de la cartera que paga, para comprobar su saldo en USDC. Por defecto, la cartera registrada del agente o, si no, la cartera local, si existe. |
Pide la URL una vez, sin cabecera de pago y con las mismas protecciones que fetch_paid (solo https://, direcciones privadas bloqueadas, solo redirecciones al mismo origen). Lee el 402 y, cuando conoce una cartera, su saldo en USDC desde el RPC de la red del pago (BURNBOUND_BASE_RPC_URL, BURNBOUND_BASE_SEPOLIA_RPC_URL). La URL solo va al vendedor y la dirección de la cartera solo al RPC. A la API de Burnbound solo se le pide la cartera registrada del agente y sus reglas (una lectura de su presupuesto), y nunca se le dice la URL.
Las comprobaciones se hacen en el orden en que las aplica fetch_paid, así que la causa es el primer error con el que se toparía un intento real:
cause.code |
cause.fetchPaidError |
Causa |
|---|---|---|
invalid_402 |
invalid_payment_required |
El 402 no tiene lista accepts, o no se puede leer. |
x402_version_mismatch |
invalid_payment_required o no_payable_entry |
El vendedor mezcla campos de x402 v1 y v2, o solo habla v1. |
unsupported_payment_option |
no_payable_entry |
Ninguna opción es USDC exact en Base o Base Sepolia; accepts[].reasons dice por qué para cada opción. |
insufficient_balance |
insufficient_funds |
La cartera tiene menos USDC que el precio en esa red. |
resource_host_mismatch |
resource_mismatch |
El 402 pide que se le pague por un recurso de otro host, o redirige a otro origen. |
seller_unreachable, seller_error, served_free, not_402 |
seller_unreachable, seller_timeout o null |
El vendedor está caído o fallando, sirve la URL gratis o no responde 402. |
no_payable_offer |
no_payable_offer |
Después de la 0.5.0: el 402 solo ofrece MPP (WWW-Authenticate: Payment) y ninguna opción x402, y Burnbound todavía no paga MPP. otherOffers las enumera. |
El resultado tiene status (problem o no_problem_found), summary (la causa y qué hacer), explanation, action, cause (code, reasons, fetchPaidError; null cuando no se encontró ningún problema), warnings, request (método, URL sin la query string, estado HTTP, versión de x402), resourceHost, accepts (cada opción de pago y si Burnbound puede pagarla), wallet (dirección, de dónde salió, saldo, importe necesario, host del RPC), chatRules (reglas propuestas desde el chat que pueden bloquear o limitar un pago a ese host), ruleBlocks (desde la 0.5.0: las reglas de límite del agente que rechazarían ahora este pago, porque dejan menos que su precio o ningún pago; cada una identificada por ruleId, con limit, lo que deja y resetsAt) e issueReport, un informe en Markdown sin la query string y con la cartera abreviada. Una regla en ruleBlocks hace que status sea problem aunque el 402 en sí esté bien, y entonces doctor sale con 2.
Los warnings nunca bloquean un pago: no_wallet, balance_not_checked, instruction_like_text (el texto del 402 parece dar instrucciones a un agente), mixed_mainnet_testnet, x402_version_mismatch y some_entries_unpayable.
No vuelve ningún texto del vendedor: la descripción y el error del 402 se descartan, y cualquier campo del vendedor que no sea un token simple aparece como [unreadable]. Los errores son los de cualquier herramienta, más invalid_input (https_required, invalid_url, contains_credential, invalid_wallet) y private_address_blocked.
¿Qué errores puede devolver una herramienta?
Los errores vuelven como un error de herramienta MCP cuyo contenido es {"error": {"code", "message", …}}. El código es estable; el mensaje es un texto fijo escrito por el servidor, nunca copiado de la API de Burnbound ni del vendedor. Los campos adicionales son solo ids, importes y códigos que el servidor ha validado, y texto que el servidor escribe a partir de ellos (summary). La única excepción es sellerReason, las palabras del propio vendedor, que siempre llega delimitado y etiquetado como no fiable (igual que las descripciones de los vendedores en search_paid_apis).
{
"error": {
"code": "policy_denied",
"message": "The agent's spending policy denied this payment, so nothing was paid. See reasons.",
"reasons": ["daily_cap_exceeded"],
"policyVersion": 4
}
}
Cualquier herramienta:
| Código | Significado |
|---|---|
invalid_input |
La entrada no es válida. reason dice por qué (ver más abajo). |
unauthorized |
La API rechazó BURNBOUND_KEY. |
forbidden |
La clave no tiene permiso para hacer esto. |
not_found |
La API no encontró el recurso. |
agent_not_found |
El agente configurado no existe para esta clave. |
approval_not_found |
No hay ninguna aprobación con ese id para este agente. |
rate_limited |
La API está limitando las peticiones. Reintenta más tarde. |
api_unavailable, api_unreachable, api_timeout, api_error |
La API de Burnbound no pudo responder. Reintenta más tarde. |
invalid_response, response_too_large |
No se pudo leer la respuesta de la API. |
config_invalid |
El servidor está mal configurado. |
internal_error |
Error inesperado en el servidor. |
Entre los motivos de invalid_input de fetch_paid están https_required, invalid_url, url_credentials, burnbound_api_url (la URL es la propia API de Burnbound), contains_credential (la entrada contiene la clave de Burnbound o una clave de cartera), body_not_allowed, body_too_large, too_many_headers, invalid_header, reserved_header, invalid_max_amount, y approval_state_mismatch o invalid_approval_state (un reintento después de la página de aprobación que no coincide con la llamada retenida).
fetch_paid, no se envió nada:
| Código | Significado |
|---|---|
host_not_allowed |
El host de la URL no está en los hosts permitidos del agente ni en sus catalogHosts. host. |
private_address_blocked |
La URL resuelve a una dirección privada, de loopback o link-local. |
control_plane_unavailable |
No se pudieron cargar los hosts permitidos del agente, así que no se pidió nada. |
fetch_paid, no se pagó nada:
| Código | Significado |
|---|---|
seller_unreachable, seller_timeout |
No se pudo llegar a la URL, o no respondió a tiempo. |
invalid_payment_required |
La URL respondió 402 sin una cabecera PAYMENT-REQUIRED legible. |
no_payable_offer |
Después de la 0.5.0: el 402 solo ofrece protocolos de pago que Burnbound todavía no paga (MPP, WWW-Authenticate: Payment) y ninguna opción x402, así que no se firmó nada. protocols, methods. |
no_payable_entry |
Ningún precio del 402 es USDC exact en Base o Base Sepolia con un importe entero. reason. |
amount_exceeds_max |
El precio supera maxAmountUsd. maxAmountUsd, amountUsd. |
resource_mismatch |
El vendedor pidió que se le pagara por un host distinto del solicitado. |
policy_denied |
La política denegó el pago. reasons (ver Conceptos) y policyVersion. reasons puede llevar pay_to_not_verified para cualquier agente (el vendedor está en el catálogo de Burnbound con direcciones de cobro fijadas en esta red y pidió que se le pagara en otra) y, con la regla de solo vendedores verificados, seller_not_verified (el host no es un vendedor listado del catálogo). hint llega cuando un motivo necesita a una persona; ver más abajo. Desde la 0.5.0, rules nombra las reglas del agente que lo denegaron (con rule_denied o rule_limit_exceeded), y chatRules las reglas propuestas desde el chat que pueden bloquear ese host. |
plan_limit_reached |
La organización alcanzó un límite del plan. plan, limit (agents o monthly_managed_spend), max, current, upgradeUrl. |
approval_required |
El pago necesita una aprobación que esta API no puede seguir. |
approval_denied |
Una persona rechazó el pago. No lo reintentes. |
approval_expired |
La aprobación caducó. Llama a fetch_paid sin idempotencyKey para volver a pedirla. |
approval_consumed |
Esa aprobación ya se usó para un pago. Revisa list_payments. |
approval_queue_full |
Hay demasiados pagos esperando aprobación. Reintenta más tarde. |
idempotency_key_reused |
Esa idempotencyKey pertenece a otra petición. |
intent_not_replayable |
El pago de esa idempotencyKey falló o caducó. Omite la clave para empezar un pago nuevo. |
payment_in_progress |
Hay otro pago de este agente en curso. Reintenta en breve con la misma idempotencyKey. |
payment_request_rejected |
La API rechazó la petición de pago. apiCode. |
client_signing_unavailable |
El agente usa firma en el cliente, y este servidor no pudo prepararla. |
insufficient_funds |
La cartera que paga tiene menos USDC que el pago en esa red. summary, payer, network, networkName, balanceUsdc, amountUsdc. No se firmó nada. Ver más abajo. |
hint es un texto fijo junto a reasons, para una denegación que solo puede resolver una persona. member_cap_exceeded: el agente pertenece a una persona de la organización, y esa persona alcanzó su subtope diario sumando todos sus agentes, o todavía no tiene ninguno. El agente no debería reintentarlo hoy; una persona le pide a un admin de la organización que fije o suba el subtope. get_budget muestra el subtope en member. rule_denied y rule_limit_exceeded: una regla de gasto que se aplica al agente, nombrada en rules, rechazó el pago. Desde la 0.7.0, ruleScopes dice de quién es cada regla (agent, team para su subequipo, u org) cuando la API la nombra; un pending_approval retenido por una regla (reason: "rule") lleva los mismos dos campos. get_budget muestra lo que deja cada regla de límite (ruleLimits, y scopeLimits para el subequipo y la organización) y cuándo se reinicia; solo una persona puede cambiar una regla, en el panel.
Con una regla del catálogo activada, la API lee el catálogo antes de decidir. Si no puede, no decide nada y responde catalog_unavailable, que fetch_paid informa como api_unavailable: reintenta más tarde. Sin ninguna regla del catálogo, la API sigue adelante sin el catálogo cuando no puede leerlo, y una dirección de cobro a la que la organización no ha pagado antes espera aprobación (new_pay_to).
insufficient_funds sale de una comprobación de saldo que la API de Burnbound hace antes de reservar o firmar nada, cuando tiene un RPC para la red del pago y conoce la dirección de la cartera que paga. summary dice, por ejemplo, Wallet 0x1234…5678 has 0.00 USDC on Base; this payment needs 0.01 USDC. Nothing was signed or paid. Añade USDC a esa cartera en esa red y vuelve a llamar a fetch_paid. La comprobación es orientativa: el saldo puede cambiar entre la comprobación y la liquidación del vendedor, así que un pago que la pasa todavía puede ser rechazado por el vendedor. Si el RPC falla, la API se salta la comprobación y sigue adelante.
fetch_paid con firma en el cliente, no se pagó nada:
| Código | Significado |
|---|---|
client_wallet_not_initialized |
No hay cartera local. Ejecuta npx -y @burnbound/mcp@latest wallet init y registra la dirección. |
client_wallet_unavailable |
No se pudo abrir la cartera local (reason: llavero no disponible, insecure_permissions…). |
client_wallet_mismatch |
La cartera local no es la registrada para el agente. localAddress, registeredAddress. |
client_sign_refused |
El firmante local se negó a firmar lo que se le pidió. reason, por ejemplo agent_key_required con una clave de organización. |
fetch_paid, después de pagar:
| Código | Significado |
|---|---|
payment_outcome_unknown |
Se envió el pago firmado, pero se perdió la respuesta del vendedor. intentId, idempotencyKey. Revisa list_payments; reintentar con la misma idempotencyKey nunca cobra dos veces. |
payment_rejected_by_seller |
El vendedor rechazó el pago firmado: respondió a la petición pagada con otro 402, o informó de que la liquidación falló. El recurso no se sirvió. httpStatus, host, intentId, idempotencyKey, mode, amountUsd, network, payTo, receipt, txHash y sellerReason cuando el vendedor dio uno. No se reintenta. |
payment_not_completed |
Se envió el pago firmado, pero el vendedor respondió con un estado distinto de 2xx o 402 (una redirección, un error) en lugar de servir el recurso. Los mismos campos que arriba, más redirectNotFollowed en caso de redirección. Puede que aún se liquide: revisa list_payments; reintentar con la misma idempotencyKey nunca cobra dos veces. |
sellerReason es la explicación del propio vendedor, leída de su cabecera PAYMENT-RESPONSE o PAYMENT-REQUIRED o de su cuerpo de error JSON, por ejemplo Facilitator validation failed: Invalid payment. Es texto de terceros: en el resultado de la herramienta llega en un bloque aparte, delimitado y etiquetado como no fiable, nunca en message, y structuredContent lo lleva como sellerReason: { untrusted: true, text }. En ambos casos, fetch_paid informa a Burnbound del recibo como fallido, con el estado y el motivo del vendedor, así que el registro del pago y el registro de auditoría guardan lo que salió mal. Un recibo fallido no libera el tope diario: el pago cuenta hasta que caduca sin liquidarse.
¿Qué comandos de cartera hay?
La CLI wallet gestiona la cartera local que se usa para la firma en el cliente. Ejecútala con npx -y @burnbound/mcp@latest wallet <command>; nunca arranca el servidor MCP. La clave privada se guarda en el llavero de macOS, en el Secret Service de Linux (GNOME Keyring, KWallet) cuando hay un bus de sesión disponible o, si no, en un fichero dentro de ~/.burnbound/wallets/ (directorio 0700, fichero 0600).
| Comando | Qué hace |
|---|---|
wallet init |
Crea una cartera e imprime su dirección. Se niega si el perfil ya tiene una. |
wallet address [--all] |
Imprime la dirección (--all: también las retiradas). No desbloquea la clave. |
wallet import [--from-env VAR] |
Guarda una clave existente, leída de stdin (oculta en una terminal) o una sola vez de la variable VAR. Borra la variable después. |
wallet export [--address ADDR] |
Imprime la clave, solo en una terminal interactiva (nunca a una tubería ni a un fichero), después de que escribas export <address> para confirmar. |
wallet rotate |
Cambia a una clave nueva y conserva la antigua para que puedas mover sus fondos (wallet export --address <old>). Registra la dirección nueva. |
wallet prove "<challenge>" |
Firma el challenge de propiedad de una línea que muestra el panel cuando registras la dirección, e imprime la firma. No firma nada más y no se mueve ningún fondo. |
Opciones:
--profile <name>: perfil de la cartera. Por defecto,BURNBOUND_WALLET_PROFILEo, si no,default. Usa un perfil por agente.--backend <kind>: parainiteimport, el almacenamiento:macos-keychain,secret-serviceofile. El almacenamiento se elige una vez, eninit; las ejecuciones siguientes nunca recurren a otro. En Windows solo está disponiblefile, y es experimental.
npx -y @burnbound/mcp@latest wallet init
npx -y @burnbound/mcp@latest wallet address
¿Cómo compruebo desde una terminal un pago que falla?
doctor hace las mismas comprobaciones que diagnose_payment desde una terminal. No necesita cuenta de Burnbound, ni clave, ni cliente MCP, nunca llama a la API de Burnbound y nunca firma ni paga.
npx -y @burnbound/mcp@latest doctor https://api.example.com/paid --wallet 0xYourWallet
Imprime la causa, qué hacer, los avisos que haya y un informe para pegar en una incidencia, sin la query string y con la cartera abreviada.
| Opción | Significado |
|---|---|
--wallet <address> |
Cartera cuyo saldo en USDC se comprueba. Por defecto, la dirección de la cartera local, si existe. Su clave nunca se carga. |
-X, --method <M> |
GET (por defecto), POST, PUT, PATCH o DELETE. |
--profile <name> |
Perfil de la cartera local. Por defecto, BURNBOUND_WALLET_PROFILE o, si no, default. |
--base-rpc <url> |
RPC para Base. Por defecto, BURNBOUND_BASE_RPC_URL o, si no, https://mainnet.base.org. |
--base-sepolia-rpc <url> |
RPC para Base Sepolia. Por defecto, BURNBOUND_BASE_SEPOLIA_RPC_URL o, si no, https://sepolia.base.org. |
--json |
Imprime todo el informe como JSON, con los campos de diagnose_payment. |
-h, --help |
Muestra la ayuda. |
| Código de salida | Significado |
|---|---|
0 |
No se encontró ningún problema. |
2 |
Se encontró un problema; la salida dice cuál. |
1 |
La comprobación no pudo hacerse: argumentos incorrectos, una URL de RPC no válida o una dirección privada. |