Skip to content

techflowswork/l402-mcp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

l402-mcp

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.

Por que existe

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 protocol parsea el reto WWW-Authenticate: L402 y formatea el Authorization. Cero side effects.
  • El modulo payer es una interfaz pluggable. Ship con MockPayer (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.

Arquitectura

                   ┌─────────────────────────────┐
                   │       MCP server stdio       │
                   │                              │
   agente ───────► │  l402_probe / pay / fetch    │
                   │                              │
                   └──┬───────────────────────┬───┘
                      │                       │
                      ▼                       ▼
              protocol.py               payer.py
              (parse + format)          (LightningPayer)
                                            │
                              ┌─────────────┼──────────────┐
                              ▼             ▼              ▼
                          MockPayer   BlinkSendPayer   AlbyNwcPayer
                          (default)      (stub)          (stub)

Tools expuestos

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.

Configuracion (.env)

L402_MAX_SATS_PER_INVOICE=1000   # cap hard-coded, NO sobreescribible por el LLM
L402_PAYER=mock                   # mock | blink_send | alby_nwc

Solo mock esta implementado. Los otros stubs lanzan NotImplementedError al construir — son placeholders deliberados que documentan el roadmap como codigo.

Quick start

git clone https://github.com/techflowswork/l402-mcp
cd l402-mcp
python3 -m venv .venv
.venv/bin/pip install -e ".[dev]"
.venv/bin/pytest -v

Salida esperada: 35 passed.

Probar el dance completo (probe → pay → fetch)

.venv/bin/python scripts/test_dance.py --local

Arranca un servidor L402 de prueba en localhost:19402 y ejercita el cliente completo con MockPayer (sin gastar sats reales).

Arrancar el MCP standalone

.venv/bin/python -m l402_mcp

Habla 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"
      }
    }
  }
}

Defensa anti-jailbreak

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:

  1. Cap por invoice hard-coded en init del payer. El LLM puede pedir amount_sats=N, pero el payer rechaza N > max_sats_per_invoice con CapExceeded. No hay prompt que lo bypasee.
  2. 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.
  3. Payer pluggable. Cambiar de mock a un adapter que mueve sats reales es una decision explicita por env var, no un side effect.

Roadmap

  • 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

Related work / prior art

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.

Referencias

Licencia

MIT — ver LICENSE.

About

MCP server (Python): cliente L402 outbound para agentes IA, con cap de gasto anti-jailbreak

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages