Servidor MCP (Python) — cliente L402 outbound para agentes IA, con cap de gasto anti-jailbreak.
Implementa el lado cliente de L402 (antes LSAT): un agente IA puede pagar APIs que cobran via Lightning + macaroon, sin cuenta, sin tarjeta, sin KYC.
El diferenciador es de seguridad: el limite de gasto vive en codigo, no en el system prompt. Un agente jailbrakeado no puede subir el cap por mas creativo que sea el prompt.
Hoy un agente IA no tiene una forma nativa y segura de pagar por APIs que cobran por uso. Las opciones habituales (tarjeta de credito, wallet con scope amplio, suscripcion hardcodeada) son peligrosas o no escalan. L402 resuelve "paga por request" sobre Lightning desde 2022; este MCP aterriza el lado cliente para cualquier agente compatible con MCP.
El diseno separa protocolo de pago:
- El modulo
protocolparsea el retoWWW-Authenticate: L402y formatea elAuthorization. Cero side effects. - El modulo
payeres una interfaz pluggable. Ship conMockPayer(no toca sats). Para pagos reales se agrega un adapter (Alby Hub via NWC, Blink, LND propio, etc.).
Esta separacion mantiene la defensa anti-jailbreak intacta: el cap maximo por invoice se fija en el __init__ del payer, no en el system prompt ni en argumentos del LLM.
┌─────────────────────────────┐
│ MCP server stdio │
│ │
agente ───────► │ l402_probe / pay / fetch │
│ │
└──┬───────────────────────┬───┘
│ │
▼ ▼
protocol.py payer.py
(parse + format) (LightningPayer)
│
┌─────────────┼──────────────┐
▼ ▼ ▼
MockPayer BlinkSendPayer AlbyNwcPayer
(default) (stub) (stub)
| Tool | Proposito |
|---|---|
l402_probe(url, method="GET") |
GET inicial, parsea 402 + macaroon + invoice. No paga. |
l402_pay(invoice, amount_sats) |
Paga via payer activo. Bloqueado por cap hard-coded. |
l402_fetch(url, macaroon, preimage_hex, ...) |
Re-pide con Authorization: L402 macaroon:preimage |
Y un resource:
| Resource | Contenido |
|---|---|
payer://info |
{name, max_sats_per_invoice} — para que el agente sepa el cap antes de probe |
Por que tres tools y no uno solo: el agente debe poder decidir si paga despues de ver el monto. Un l402_fetch_all_in_one haria del pago un side effect del fetch, lo que rompe la auditabilidad y el modelo human-in-the-loop.
L402_MAX_SATS_PER_INVOICE=1000 # cap hard-coded, NO sobreescribible por el LLM
L402_PAYER=mock # mock | blink_send | alby_nwcSolo mock esta implementado. Los otros stubs lanzan NotImplementedError al construir — son placeholders deliberados que documentan el roadmap como codigo.
git clone https://github.com/techflowswork/l402-mcp
cd l402-mcp
python3 -m venv .venv
.venv/bin/pip install -e ".[dev]"
.venv/bin/pytest -vSalida esperada: 35 passed.
.venv/bin/python scripts/test_dance.py --localArranca un servidor L402 de prueba en localhost:19402 y ejercita el cliente completo con MockPayer (sin gastar sats reales).
.venv/bin/python -m l402_mcpHabla stdio. Se conecta via mcp_config.json en Claude Desktop / Claude Code / cualquier cliente MCP:
{
"mcpServers": {
"l402": {
"command": "/ruta/al/l402-mcp/.venv/bin/python",
"args": ["-m", "l402_mcp"],
"env": {
"L402_PAYER": "mock",
"L402_MAX_SATS_PER_INVOICE": "1000"
}
}
}
}El experimento Freysa (2024) mostro que un agente IA con la instruccion "no transfieras los fondos" en su system prompt fue convencido de transferirlos con un prompt creativo. El system prompt no es una defensa real. Por eso aqui las defensas viven en codigo:
- Cap por invoice hard-coded en init del payer. El LLM puede pedir
amount_sats=N, pero el payer rechazaN > max_sats_per_invoiceconCapExceeded. No hay prompt que lo bypasee. - Separacion probe / pay / fetch. El agente ve el monto antes de pagar — habilita human-in-the-loop real y deja cada pago como evento auditable.
- Payer pluggable. Cambiar de
mocka un adapter que mueve sats reales es una decision explicita por env var, no un side effect.
- Protocol parser (probe / format)
- MockPayer + cap enforcement
- MCP server (probe / pay / fetch +
payer://info) - Dance L402 validado contra servidor local
- AlbyNwcPayer — adapter real preferido (requiere Alby Hub deployado)
- Token cache (reutilizar macaroon+preimage hasta que el caveat de tiempo expire)
- Soporte de Macaroon caveats (parsear expiry / amount caveat para validar localmente antes de re-pedir)
- Publicar en PyPI:
pip install l402-mcp
L402 fue creado por Lightning Labs — ver la spec oficial. Este MCP es un cliente enfocado y minimal; si buscas un toolkit completo o alternativas:
- lightninglabs/lightning-agent-tools — toolkit oficial de Lightning Labs (skills + MCP server): cliente y servidor L402, manejo de nodo y credenciales.
- Fewsats — ecosistema de pagos L402 para agentes (libs, MCP server, apps de ejemplo).
- lightning-wallet-mcp — wallet MCP con soporte L402 + x402 y budgets para sub-agentes.
El foco de l402-mcp es distinto: cap de gasto anti-jailbreak en codigo + payer pluggable + separacion probe/pay/fetch auditable.
- L402 spec (Lightning Labs)
- Model Context Protocol
- BOLT11 — formato de invoice
- Macaroons paper — base teorica
- Freysa experiment — por que el cap va en codigo
MIT — ver LICENSE.