Veyra (veyra.money)

Límites de gasto para agentes de IA que pagan: USDC no custodial en Base con topes por pago y diarios, bandas de aprobación y una lista de permitidos, aplicados del lado del servidor.

Servidor MCP alojado

npx add-mcp 'https://veyra.money/api/mcp'

Se instala en Claude Code, Codex, Cursor y más

Documentación

Veyra — give AI agents a wallet with a spending limit

veyra-mcp

Dale a tu agente de IA una cartera con un límite de gasto.
Servidor MCP + cliente tipado para Veyra: pagos USDC no custodiales en Base, con límites por pago, límites diarios, bandas de aprobación humana y una lista blanca de destinatarios, todo aplicado en el servidor, nunca por el modelo.

npm CI MIT Docs


El problema

Los agentes necesitan cada vez más pagar cosas: una llamada a una API, un conjunto de datos, una recompensa, otro agente. Hoy las opciones son malas:

  • Darle al agente una clave privada. Una sola inyección de prompt y la cartera queda vacía.
  • Darle una tarjeta. Sin límites por llamada, sin lista blanca, y tu banco no te dirá qué llamada de herramienta gastó el dinero.
  • Aprobar cada pago a mano. Entonces no es realmente un agente.

Veyra es la capa intermedia. Conectas una cartera que ya posees, estableces cuánto puede gastar un agente y le das al agente un único endpoint MCP. El agente obtiene herramientas como create_payment. Nunca ve una clave y no puede exceder los límites que estableciste porque los límites los aplica el servidor de Veyra, no el modelo siguiendo instrucciones.

  agent  ──MCP──▶  veyra.money  ──policy──▶  your wallet  ──USDC on Base──▶  recipient
                    │
                    ├─ under auto-max      → executes from your capped on-chain allowance
                    ├─ in the ask band     → you approve in your own wallet (one link)
                    └─ over the limits     → blocked, agent is told why

Configuración en 60 segundos

  1. Regístrate en veyra.money, conecta una cartera (o comienza con la fuente simulada, que no mueve dinero).
  2. Crea un endpoint MCP con límites. Copia la credencial (empieza con veyra_).
  3. Añádela a tu host:
Claude Code
claude mcp add --transport http veyra https://veyra.money/api/mcp \
  --header "Authorization: Bearer veyra_..."
Cursor (.cursor/mcp.json)
{
  "mcpServers": {
    "veyra": {
      "url": "https://veyra.money/api/mcp",
      "headers": { "Authorization": "Bearer veyra_..." }
    }
  }
}
OpenAI Codex
export VEYRA_TOKEN=veyra_...
codex mcp add veyra --url https://veyra.money/api/mcp --bearer-token-env-var VEYRA_TOKEN
Claude Desktop y cualquier host que no pueda enviar un encabezado bearer (claude_desktop_config.json)
{
  "mcpServers": {
    "veyra": {
      "command": "npx",
      "args": ["-y", "veyra-mcp"],
      "env": { "VEYRA_TOKEN": "veyra_..." }
    }
  }
}

El binario veyra-mcp es un puente stdio: guarda la credencial localmente y retransmite cada llamada al endpoint alojado. Ninguna política vive en el puente.

Cualquier otra cosa (JSON-RPC simple)
curl -s https://veyra.money/api/mcp \
  -H "Authorization: Bearer veyra_..." \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"get_budget","arguments":{}}}'

Luego pídele al agente que haga algo que cueste dinero y observa cómo la política decide.

Herramientas que recibe el agente

HerramientaQué hace
get_capabilitiesRedes, redes de pago, activos, límites y la lista blanca de destinatarios vigentes en este momento
get_budgetLímite diario, gastado hoy, límite por pago, bandas automáticas y de consulta
list_payment_sourcesFuentes enmascaradas y si cada una puede liquidar sin un humano
create_paymentCrea una intención de pago. La política se aplica en el servidor y el resultado dice qué pasó
get_paymentEstado canónico de un pago, incluida la red de pago que lo liquidó
list_paymentsPagos recientes para este endpoint
cancel_paymentCancela mientras aún sea cancelable

Cada pago reporta uno de estos estados:

EstadoSignificado
confirmedValor movido en la cadena
confirmed_simulatedLiquidado en la red simulada. No se movió dinero. El agente recibe esta información explícitamente
awaiting_approvalEn la banda de consulta. next_action.url es un enlace de un solo uso que el propietario abre en su propia cartera
submittedTransacción enviada, esperando el recibo de la cadena
pendingCreado, aún no evaluado ni ejecutado
failed / cancelled / expiredTerminal. Los pagos bloqueados por política son failed con un policy_reason

Úsalo desde código

npm install veyra-mcp
import {
  VeyraClient,
  VeyraToolError,
  idempotencyKey,
  movedRealMoney,
  paymentOutcome,
} from "veyra-mcp";

const veyra = new VeyraClient({ token: process.env.VEYRA_TOKEN! });

const budget = await veyra.getBudget();
console.log(`spent ${budget.spent_today} of ${budget.daily_limit} USDC today`);

const payment = await veyra.createPayment({
  amount: "1.25",
  recipient: "0x1234…abcd",          // USDC on Base
  reason: "Weather API, 500 calls",
  idempotency_key: idempotencyKey("weather"),
});

switch (paymentOutcome(payment)) {
  case "settled":
    // The only case where value actually moved.
    console.log("paid —", (await veyra.getPayment(payment.payment_id)).tx_ref);
    break;
  case "simulated":
    console.log("settled on the simulated rail; no money moved");
    break;
  case "awaiting_approval": {
    console.log("owner must approve:", payment.next_action?.url);
    const settled = await veyra.waitForPayment(payment.payment_id);
    console.log(movedRealMoney(settled) ? "paid" : paymentOutcome(settled));
    break;
  }
  case "blocked":
    console.log("policy refused it:", payment.policy_reason);
    break;
}

Los rechazos de política no son excepciones

Esto es lo único que vale la pena leer dos veces. Un pago que la política rechaza vuelve como un resultado ordinario con status: "failed" — la llamada hizo lo que se le pidió y la respuesta fue no. Solo un argumento mal formado, una credencial incorrecta o un id desconocido lanza una excepción.

Así que try/catch es la herramienta equivocada para detectar rechazos: omite cada pago bloqueado y lo lee como un éxito. Usa paymentOutcome, y usa movedRealMoney antes de decirle a alguien que el valor se movió — devuelve false para una liquidación simulada aunque el estado comience con "confirmado".

Reserva catch para lo que realmente falló:

try {
  await veyra.createPayment({ /* … */ });
} catch (e) {
  if (e instanceof VeyraToolError) {
    console.log(e.code, e.message);   // VALIDATION_ERROR, UNKNOWN_CREDENTIAL, NOT_FOUND
  } else throw e;
}

Nunca reintentes porque no estés seguro

Si no puedes saber si un pago funcionó, léelo — no crees otro. getPayment devuelve tx_ref una vez que un pago real se ha liquidado, lo cual es tanto tu confirmación como lo que muestras al destinatario como prueba. Reutilizar el mismo idempotency_key devuelve el pago original; una clave nueva gasta de nuevo. Veyra también establece possible_duplicate_of cuando un pago idéntico al mismo destinatario ya está activo.

VEYRA_TOOLS exporta las definiciones de herramientas como JSON Schema, para que puedas registrarlas con el Vercel AI SDK, LangChain o llamadas a funciones simples sin un viaje de red. Consulta veyra-examples para ver agentes completos construidos con el Claude Agent SDK y el Vercel AI SDK.

En qué confías

Vale la pena ser directo, porque esto es dinero.

  • Veyra nunca retiene tus fondos. Los pagos van de tu cartera al destinatario. No hay saldo de Veyra en el medio.
  • Por encima de tu límite de aprobación automática nada está delegado. Firmas cada transferencia en tu propia cartera desde el enlace de aprobación. Veyra verifica que el recibo en la cadena coincida con la solicitud.
  • Dentro de tu límite de aprobación automática otorgas una asignación ERC-20 limitada a un relayer que opera Veyra, el mismo primitivo approve que usa toda aplicación DeFi. El contrato de token aplica el límite. El motor de políticas de Veyra decide el destino dentro de ese límite, así que dimensiona la asignación como un flotante que podrías perder y usa la lista blanca de destinatarios cuando sepas a quién debería pagar el agente. Revócala en cualquier momento.
  • La red simulada existe para que puedas conectar todo antes de tocar fondos reales. Está etiquetada en todas partes: estado confirmed_simulated, simulated: true.
  • Cada decisión está en el registro de auditoría, incluidos los cambios de límites y las rotaciones de credenciales.

Detalles completos: Cómo se mueve realmente un pago y En qué confías, exactamente.

Preguntas frecuentes

¿Qué redes y activos? USDC en Base. Una stablecoin mantiene los límites en dólares exactos sin un feed de precios, y Base es donde el ecosistema de pagos de agentes ya liquida. Hay más redes en la hoja de ruta; abre un issue si necesitas una.

¿Funciona con x402 o APIs de pago por llamada? Sí, en el sentido que importa: el agente le pide a Veyra que pague la dirección del vendedor y recibe un recibo. Veyra es la política de gasto, no el protocolo en el otro extremo.

¿Puedo autoalojarlo? Hoy no. Este repositorio es el cliente y el puente; el motor de políticas es el servicio alojado en veyra.money. La ruta de aprobación de cartera es totalmente no custodial de todos modos.

¿Cuánto cuesta? Hay un plan gratuito. Consulta precios.

¿Dónde reporto una mala decisión de política? Desde el panel, para que el soporte pueda ver tu registro de auditoría. Los issues de este repositorio son para el cliente y el puente.

Desarrollo

npm install
npm test     # builds, then runs the suite against a local mock of the endpoint

Consulta CONTRIBUTING.md y SECURITY.md.

Enlaces

MIT © Veyra