Skip to main content
Glama
Lightning Enable MCP

Lightning Enable MCP

Part of Lightning Enable — infrastructure for agent commerce over Lightning.

Lightning Enable MCP Server

Discord PyPI downloads NuGet downloads Docker pulls

Monetize your own API — 30-day free trial

Agents pay your API per request over Lightning — flat subscription at $49/mo, and you keep 100% of every sat.

Or sign up without leaving your agent: call the create_lightning_enable_account tool.

An open-source MCP (Model Context Protocol) server that enables AI agents to make Lightning Network payments and participate in agent-to-agent commerce. Wallet, invoice, L402, budget, and API-discovery tools work out of the box with just a wallet. Producer tools (sell access via L402) and Agent Service Agreement (ASA) tools (agent-to-agent discovery, request, settlement, and attestation over Nostr) unlock with an Agentic Commerce subscription. See the full tool list.

Available in .NET and Python.

Related MCP server: Lightning Tools MCP Server

What It Does

Give your AI agent a Lightning wallet and it can:

  • Pay invoices — Send Bitcoin via Lightning to any BOLT11 invoice

  • Access L402 APIs — Automatically pay L402 challenges for seamless API access

  • Discover APIs — Search the L402 API registry to find paid APIs by keyword or category, or fetch a specific API's manifest for full endpoint details and pricing

  • Track spending — Budget limits, a durable receipt log, and balance checks

  • Create invoices — Generate invoices to receive payments

  • Run wallet operations — BTC price, currency exchange, and on-chain sends (Strike; on-chain also LND)

  • Self-bootstrap a Lightning Enable account — create_lightning_enable_account pays a ~100-sat activation fee over L402 and returns a merchant API key: the free→paid signup form that is the protocol, unlocking the producer + ASA tools with no browser or checkout page.

  • Sell services (L402 Producer) — Set up the seller account, put an API behind L402, price its routes, list it publicly, mint payment challenges and verify payer tokens — all from one tool, so an agent can go from an API key to a paid endpoint without touching REST

  • Agent commerce (ASA) — Discover, request, settle, and review agent-to-agent services on Nostr

Quick Start

1. Install

# .NET
dotnet tool install -g LightningEnable.Mcp

# Python
pip install lightning-enable-mcp

# Python (no install)
uvx lightning-enable-mcp

# Docker
docker pull refinedelement/lightning-enable-mcp:latest

2. First run — setup_wallet

Nothing else works without a wallet, so start there. Ask your agent:

Run setup_wallet

With no arguments it reports which wallet is configured and where the credential came from — the provider and the source, never the credential itself. If there is no wallet, it hands back the setup steps.

The shortest path is NWC. In your wallet app (Alby Hub, CoinOS, or any NIP-47 wallet) create a Nostr Wallet Connect connection, copy the nostr+walletconnect:// string, and give it to the agent:

Run setup_wallet with this connection string: nostr+walletconnect://...

setup_wallet validates the string, connects to the wallet to prove it answers, then writes it to ~/.lightning-enable/config.json with the file's permissions restricted to your user. It reports the wallet's declared methods and balance. Restart the server afterwards so it picks up the new wallet.

Or set an environment variable (in the Claude Desktop config below, say). L402 — the whole point of this server — needs a wallet that returns the payment preimage:

  • Strike — STRIKE_API_KEY, from https://dashboard.strike.me

  • NWC — NWC_CONNECTION_STRING, from CoinOS / CLINK / Alby Hub

  • LND (your own node — always returns a preimage) — LND_REST_HOST + LND_MACAROON_HEX

    • Self-signed node cert? Set LND_TLS_CERT_PATH to the node's tls.cert (pins TLS to that cert). LND_SKIP_TLS_VERIFY=true is the escape hatch, not the recommendation. Optional: LND_FEE_LIMIT_SATS, LND_PAYMENT_TIMEOUT_SECONDS.

⚠️ OpenNode (OPENNODE_API_KEY) works for invoicing / direct payments only — it never returns a preimage, so it cannot pay L402 challenges. Don't make it your only wallet if you want L402 (the core use case).

If several are set, priority is: LND > NWC > Strike > OpenNode, and environment variables win over the config file — setup_wallet refuses to write a connection string that an env var would override, and tells you which variable to unset. See Supported Wallets for the full compatibility matrix.

3. Prove the whole loop works — test_l402_payment

Ask your agent:

Run test_l402_payment

This pays a public 1-sat L402 endpoint end to end, proving your wallet is connected, returns a preimage, and can complete a real L402 payment. It's the one-line answer to "is my wallet actually working?" — and it costs about 1 satoshi.

4. Then have some fun — buy a t-shirt

Once the loop works, try the Lightning Enable Store, a live L402-powered web store. Ask Claude:

Buy me a Lightning Enable t-shirt from store.lightningenable.com

(This one needs a funded wallet and a shipping address, which is why test_l402_payment — one sat, no shipping — is the faster first proof.)

Claude Desktop manual install (MCPB bundle)

For a one-click install with no config-file editing, grab the packaged MCPB bundle from the mcpb/ directory instead of hand-editing JSON: build it locally with npx -y @anthropic-ai/mcpb pack mcpb lightning-enable-mcp.mcpb (or download the .mcpb artifact from a mcpb.yml CI run), then double-click the resulting .mcpb file or drag it into Claude Desktop's Settings → Extensions — Claude Desktop prompts for your wallet credentials (Strike, NWC, or LND) and optional Lightning Enable API key through its own settings UI instead of a text config file. See mcpb/README.md for what's in the bundle and mcpb/SUBMISSION.md for its Anthropic MCP Directory submission status.

Claude Desktop Config

Add to your claude_desktop_config.json:

.NET:

{
  "mcpServers": {
    "lightning-enable": {
      "command": "lightning-enable-mcp",
      "env": {
        "STRIKE_API_KEY": "your-strike-api-key"
      }
    }
  }
}

dotnet tool install -g LightningEnable.Mcp puts the lightning-enable-mcp command on your PATH. If Claude Desktop can't find it, set command to the full path: "C:\\Users\\<you>\\.dotnet\\tools\\lightning-enable-mcp.exe" on Windows (JSON needs the doubled backslashes), /Users/<you>/.dotnet/tools/lightning-enable-mcp on macOS, or /home/<you>/.dotnet/tools/lightning-enable-mcp on Linux. The config file doesn't expand environment variables such as %USERPROFILE% or $HOME.

Python:

{
  "mcpServers": {
    "lightning-enable": {
      "command": "uvx",
      "args": ["lightning-enable-mcp"],
      "env": {
        "STRIKE_API_KEY": "your-strike-api-key"
      }
    }
  }
}

Config file locations:

  • Windows: %APPDATA%\Claude\claude_desktop_config.json

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

  • Linux: ~/.config/claude/claude_desktop_config.json

Deploying hosted

A payment above your auto-approve threshold needs a human's approval: the server mints a short confirmation code, sends it to you, and the agent can only proceed once you read it back. The code never appears in a tool result, so a prompt-injected agent can't approve its own spending by reading the result.

Treat this as an operator confirmation aid on a trusted local host, not as an independent approval boundary: if the agent's host can read the server's console, log stream, approval file, or webhook destination, it can read the code too.

That only works if the code reaches a human. On your laptop it goes to the server's console (stderr) and you read it there. On a hosted server — a claude.ai connector, a Docker container, a fleet — nobody is watching stderr, and on a shared host the agent might read it itself. So you choose the approval channel.

Channel

What happens above the threshold

Use it when

stderr (default)

The code is printed to the server console.

You run the server locally and watch its output.

refuse

The payment is refused. No code is minted at all.

You run it hosted and no one can receive a code.

webhook

The pending confirmation is POSTed to your URL, HMAC signed. You relay the code to the agent.

You have an ops channel — chat, pager, an approval app.

file

The same JSON line is appended to a file you tail.

You collect approvals from logs.

Whatever the channel, two rules hold: the code is never returned to the agent, and a payment is never approved because its notification failed to send — a delivery failure refuses the payment and withdraws the code.

Codes are 6 characters, one-time use, and bound to the exact amount, tool, and destination. At most 3 codes can be outstanding at once, and 5 invalid code attempts in a row revoke every pending code. A code lives 120 seconds by default; set confirmation.ttlSeconds (or LIGHTNING_ENABLE_CONFIRMATION_TTL_SECONDS) to change it, clamped to 30-900. For the asynchronous webhook and file channels, 300-600 is a practical value.

Choosing a channel

Precedence: environment variable, then config file, then automatic.

{
  "confirmation": {
    "channel": "webhook",
    "webhookUrl": "https://ops.example.com/lightning-approvals",
    "webhookSecret": "<shared secret>",
    "filePath": "/var/log/lightning-enable/confirmations.jsonl",
    "ttlSeconds": 600
  }
}

Environment variable

Overrides

LIGHTNING_ENABLE_CONFIRMATION_CHANNEL

confirmation.channel (stderr | refuse | webhook | file)

LIGHTNING_ENABLE_CONFIRMATION_WEBHOOK_URL

confirmation.webhookUrl

LIGHTNING_ENABLE_CONFIRMATION_WEBHOOK_SECRET

confirmation.webhookSecret

LIGHTNING_ENABLE_CONFIRMATION_FILE

confirmation.filePath (default ~/.lightning-enable/confirmations.jsonl)

LIGHTNING_ENABLE_HOSTED

Set to 1 to declare a hosted deployment (see below)

With no channel set, the server decides:

stdin

LIGHTNING_ENABLE_HOSTED

Channel

Startup warning

A TTY

anything

stderr

none

Not a TTY

unset or 0

stderr

yes — nobody may be reading it

Not a TTY

1

refuse

yes — over-threshold payments are refused

An stdio MCP server always has a piped stdin, so the warning is a nudge, not a diagnosis: if a human really is watching the console, ignore it. LIGHTNING_ENABLE_HOSTED=1 is the explicit opt-in that turns the safe posture on — nothing flips your behavior automatically.

A channel name the server can't parse fails closed to refuse and says so at startup, so a typo never silently restores a code nobody reads.

The webhook payload

POST with Content-Type: application/json and an HMAC-SHA256 signature over {timestamp}.{body}, the same scheme the Lightning Enable API signs merchant webhooks with:

X-LightningEnable-Signature: t=1757203200,v1=9f86d081...
{
  "type": "payment.confirmation_required",
  "nonce": "AB12CD",
  "tool": "pay_invoice",
  "amountSats": 50000,
  "amountUsd": 12.34,
  "destination": "lnbc500u1pj9npjpp5abcdefghijklmnopqr...",
  "description": "lnbc500u1pj9npjpp5...",
  "summary": "pay_invoice — $12.34 (50,000 sats), invoice lnbc500u1pj9npjpp5...",
  "createdAt": "2026-09-07T12:00:00Z",
  "expiresAt": "2026-09-07T12:02:00Z",
  "expiresInSeconds": 120
}

The file channel writes this exact object, one JSON line per confirmation, and pins the file to 0600 on POSIX — it holds live approval codes.

Two things to know about the webhook:

  • The URL must be public. It goes through the same connect-time SSRF guard as agent-supplied URLs, so a private, loopback, or metadata address is refused at startup.

  • Redirects are never followed. A 3xx answer is a delivery failure, so a signed approval only ever reaches the URL you configured.

Codes expire after 120 seconds and are bound to the exact amount, tool, and destination they were approved for.

Supported Wallets

Wallet

Setup

L402 Support

Strike

API key

Yes

LND

REST + macaroon

Yes (guaranteed)

NWC (CoinOS)

Connection string

Yes

NWC (CLINK)

Connection string

Yes

NWC (Alby Hub)

Connection string

Yes

OpenNode

API key

No (no preimage)

Spending limits

Limits live in ~/.lightning-enable/config.json and are read-only at runtime — an agent can tighten its own caps but never raise them. You can set them in USD, in satoshis, or both.

{
  "limits": {
    "maxPerPayment": 500.00,
    "maxPerSession": 100.00,
    "maxPerPaymentSats": 5000,
    "maxPerSessionSats": 50000,
    "autoApproveSats": 100
  }
}

Key

Env var

Meaning

maxPerPayment

—

Max USD per payment

maxPerSession

—

Max USD per session

maxPerPaymentSats

LIGHTNING_ENABLE_MAX_PER_PAYMENT_SATS

Max satoshis per payment

maxPerSessionSats

LIGHTNING_ENABLE_MAX_PER_SESSION_SATS

Max satoshis per session

autoApproveSats

LIGHTNING_ENABLE_AUTO_APPROVE_SATS

Satoshis a payment may spend without confirmation while the BTC price is unavailable

Defaults. On first run both ports write the same file: approval tiers autoApprove $0.10, logAndApprove $1.00, formConfirm $10.00 and urlConfirm $100.00; maxPerPayment $500.00 and maxPerSession $100.00; requireApprovalForFirstPayment: true; cooldownSeconds 2. A key you leave out of an existing file takes the same default.

An omitted USD limit is not "no limit". If you set only the sats limits, maxPerPayment and maxPerSession still apply at $500.00 and $100.00. To rely on the sats limits alone, set the USD keys to null:

{ "limits": { "maxPerPayment": null, "maxPerSession": null, "maxPerSessionSats": 50000 } }

Tiers must ascend. If a tier is above the tier over it, it is lowered to that tier's value, never raised: {"tiers": {"autoApprove": 2}} with the default logAndApprove of $1.00 auto-approves up to $1.00, not $2.00. Set the tiers above it too to raise it.

Why set the sats ones. A USD limit has to be converted at the current BTC price, so when every price source is down the payment cannot be checked and is refused — correct, but it stops the agent. A satoshi limit needs no conversion, so a sats-budgeted agent keeps working through a price outage. Set both maxPer…Sats keys to close every gap.

When both denominations are set, the stricter cap wins on every check. budget(action="status") reports which one is binding (bindingDenomination), the effective cap in sats, whether a price was available, and whether outage mode is active.

What happens during a price outage

The satoshi ceilings still bound the spend. But a ceiling says "never more than this" — it does not say "this much is fine unattended", and the USD tier ladder that normally says the second thing cannot be evaluated without a price. So approval fails closed:

  • autoApproveSats set — payments at or below it are auto-approved; anything above takes the normal confirmation flow (the agent asks the human for the code printed to the server console).

  • autoApproveSats not set — every payment needs confirmation until a price source recovers.

autoApproveSats is a tier, not a ceiling: it can never widen maxPerPaymentSats or maxPerSessionSats, which are checked first. It is ignored entirely while a price is available — then the USD tiers decide as usual.

The auto-pay paths (L402 auto-payment, send_onchain, agent_services action=settle) refuse anything that needs confirmation rather than prompting. During an outage that means they only proceed under autoApproveSats.

Tools

Canonical inventory: the table below. Tools marked Free work out of the box with just a wallet (docs needs nothing at all); tools marked Agentic Commerce require LIGHTNING_ENABLE_API_KEY (an Agentic Commerce subscription). The table is pinned to the code by the tool-inventory guard tests in both ports (ToolInventoryTests.cs, test_server.py), so drift fails CI; quote counts from those tests, never from prose.

Some of these are action tools: pass action (or source for receipts) to pick the operation. All but docs replace a family of single-purpose tools whose schemas used to be loaded into the agent's context on every session — see Tool profiles and old tool names. Every old name still works.

ASA availability note. Against the hosted Lightning Enable API, agent_services actions discover, request, settle, publish, unpublish, and reputation work. attest is refused, because the hosted API has no route that accepts attestations, so you can't leave a review through it. See Agent Service Agreements.

Tool

Access

What it does

setup_wallet

Free

Report the configured wallet, or connect one by pasting an NWC connection string

pay_invoice

Free

Pay a BOLT11 Lightning invoice directly, get the preimage

pay_l402_challenge

Free

Pay an L402 challenge (invoice + macaroon), get the token

access_l402_resource

Free

Fetch a URL, auto-paying any L402 challenge

test_l402_payment

Free

Self-test the wallet against a public 1-sat L402 endpoint

discover_api

Free

Search the L402 API registry / fetch an API manifest

docs

Free

action: search (ranked sections for a query) or read (a page or one section by path). Reads the Lightning Enable docs without web access; no wallet or API key

create_invoice

Free

Create a BOLT11 invoice to receive payment

check_invoice_status

Free

Check whether a created invoice was paid

get_balance

Free

Wallet balance: sats, all currencies (Strike), and wallet info

budget

Free

action: status (read limits and session spend) or tighten (lower the runtime caps)

receipts

Free

source: durable (the append-only receipt log) or session (this session's payments)

wallet_ops

Free

action: price, exchange, or send_onchain (Strike; send_onchain also LND). send_onchain takes address, amountSats, confirmationNonce, and an optional intentId (supply a new one only to pay the same address the same amount again; a repeat is reported as status, never re-sent)

verify_confirmation_code

Free

Verify an out-of-band payment confirmation code (verification only — never pays)

create_lightning_enable_account

Free

Self-bootstrap signup: pay ~100 sats, get a merchant API key

l402_producer

Agentic Commerce

action: sell_url (no key needed: pays a one-time claim), configure_receive, status, create_proxy, add_endpoint, publish, list_challenges, create, verify (a payment, or with proxy_id ownership of your API), verification_token — the whole seller side, including getting listed

agent_services

Agentic Commerce

action: discover, request, settle, publish, unpublish, attest, reputation

renew_lightning_enable_subscription

Agentic Commerce

Pay the server-priced L402 invoice that buys or extends 30 days of Agentic Commerce for the configured API key (maxSats defaults to 50,000)

create_lightning_enable_account is free and self-provisions the API key the Agentic Commerce tools need — an agent with a wallet pays a ~100-sat activation fee and unlocks them on the spot.

docs reads llms-full.txt, the whole docs site in one file, and keeps it in memory for an hour. If a refresh fails it serves the cached copy and marks the result stale. Set LIGHTNING_ENABLE_DOCS_URL to read another copy (https://, http:// on localhost, or a local file:// path; network shares are refused). Redirects are not followed: point the variable at the final URL.

Every tool carries MCP annotations: a human-readable title and an explicit readOnlyHint, plus destructiveHint on anything that can spend the wallet. Action tools are annotated for their widest action, so budget is not read-only (because tighten writes) and wallet_ops is destructive (because send_onchain is).

Resources

The durable receipt log is also exposed as MCP resources, so a client can attach or display it without the model spending a turn on a tool call:

URI

Contents

lightning-enable://receipts

The most recent 200 receipts as JSONL (application/x-ndjson), oldest first

lightning-enable://receipts/{paymentHash}

Every receipt recorded for one payment hash

Both read through the same path as the receipts tool, which redacts credential-shaped fields at the read boundary — a preimage never leaves the process. The payment hash is the safe reference; the preimage is the proof of payment and is not a receipt field. Resources are unaffected by the tool profile: they cost no schema bytes in the model's context.

Tool profiles and old tool names

Every advertised tool's JSON schema is loaded into the agent's context at the start of each session, so the tool surface is a token cost on every turn. Pick how much of it to advertise with LIGHTNING_ENABLE_TOOL_PROFILE:

Profile

Tools

Use it when

lite

setup_wallet, pay_invoice, access_l402_resource, get_balance, budget, receipts

The agent only needs to get a wallet, spend, and stay inside its budget

standard (default)

The table above

Everything, with less schema than the old one-tool-per-operation surface

full

standard plus every pre-consolidation name

You have prompts or scripts written against the old tool names

{
  "mcpServers": {
    "lightning-enable": {
      "command": "uvx",
      "args": ["lightning-enable-mcp"],
      "env": {
        "STRIKE_API_KEY": "your-strike-api-key",
        "LIGHTNING_ENABLE_TOOL_PROFILE": "lite"
      }
    }
  }
}

Profiles are listing-only. A tool the profile does not advertise is still callable by name, and every old name still dispatches, under every profile. Narrowing the profile trims the schemas pushed into the model's context; it never removes capability.

Old name → new call

Old names are accepted but unadvertised (except under full). Each forwards to the new tool and its result carries a deprecated marker naming the replacement. Removed in v3.0.0 — move to the new names.

Old tool

New call

get_budget_status

budget(action="status")

configure_budget

budget(action="tighten")

get_receipts

receipts(source="durable")

get_payment_history

receipts(source="session")

get_btc_price

wallet_ops(action="price")

exchange_currency

wallet_ops(action="exchange")

send_onchain

wallet_ops(action="send_onchain")

create_l402_challenge

l402_producer(action="create")

verify_l402_payment

l402_producer(action="verify")

discover_agent_services

agent_services(action="discover")

request_agent_service

agent_services(action="request")

settle_agent_service

agent_services(action="settle")

publish_agent_capability

agent_services(action="publish")

unpublish_agent_capability

agent_services(action="unpublish")

publish_agent_attestation

agent_services(action="attest")

get_agent_reputation

agent_services(action="reputation")

confirm_payment

verify_confirmation_code

check_wallet_balance

get_balance

get_all_balances

get_balance

The last three predate this consolidation and stay hidden in every profile, full included.

Documentation

Repository Structure

lightning-enable-mcp/
├── dotnet/
│   ├── src/LightningEnable.Mcp/         # .NET MCP server
│   ├── tests/LightningEnable.Mcp.Tests/  # .NET tests
│   └── LightningEnable.Mcp.sln          # Solution file
├── python/
│   └── lightning-enable-mcp/             # Python MCP server
├── .github/workflows/publish-mcp.yml     # CI/CD
├── LICENSE                               # MIT
└── README.md                             # This file

Selling with L402 (the l402_producer tool)

The whole seller side behind one tool. Pass action to pick the operation. sell_url needs no account: it pays a one-time claim from your wallet, through the same budget and confirmation rules as every other payment. Every other action needs LIGHTNING_ENABLE_API_KEY (an Agentic Commerce subscription) and none of them can spend your wallet.

API version. create, verify, create_proxy, add_endpoint and publish work against every Lightning Enable API build. configure_receive needs the NWC receiving lane and list_challenges needs the challenge-listing route, both of which ship with the API release this version targets. Run l402_producer(action="status") first — it degrades gracefully and tells you what the deployment you are pointed at supports.

Action

Arguments

What it does

sell_url

target_url, lightning_address, default_price_sats (per-call price buyers pay), name, description, recovery_email or recovery_nostr_pubkey, list_publicly, accept_terms, confirmation_nonce

Charge for your API in one call: a URL and a Lightning Address become a paid endpoint and a new account (pays the claim)

configure_receive

nwc_connection_string (optional)

Point L402 payouts at a wallet you control

status

limit

Plan, receiving wallet, onboarding checklist, recent mints (read-only)

create_proxy

name, target_base_url, description, default_price_sats

Put an existing API behind L402

add_endpoint

proxy_id, endpoint_id, path, http_method, summary, price_sats

Price one route

publish

proxy_id, service_name, service_description, categories

List the service so other agents can find it

list_challenges

challenge_status, limit, offset

Read back what you minted (read-only)

create

resource, price_sats, description

Mint a one-off invoice + macaroon challenge

verify

macaroon, preimage

Check a payer's token before granting access

verify

proxy_id, method (optional)

Check that you own the API behind a proxy, so it can be listed

verification_token

proxy_id, method (optional), reissue

Get the ownership token to publish (shown once, stored beside config.json)

From a URL and a Lightning Address to a paid endpoint

For an operator with no account who wants to charge for an API they already run:

  1. Read the quote. l402_producer(action="sell_url", target_url="https://api.example.com", lightning_address="you@wallet.example") — without accept_terms the tool only reads the free quote: the claim price, what it covers, the renewal, and the terms version and link. Nothing is posted or charged. Show the operator the quote and get an explicit yes.

  2. Claim it. Call again with the same arguments plus accept_terms="<terms.version>". The tool posts the claim, pays its invoice from this wallet (over-threshold amounts ask the operator for a confirmation code, as pay_l402_challenge does; pass it back as confirmation_nonce with the same arguments), and redeems the paid token. It returns the proxy URL, the manifest URL, paid-through date, renewal endpoint, recovery binding, listing status and warnings.

  3. The API key, once. The new account's key is returned in that one result and stored in your config.json as lightningEnableApiKey, or, when another account's key is already configured, in claim-<proxyId>.key beside it (owner-only). The result says which. If a replay rotates the key, the new key replaces this claim's old one where it was stored.

name defaults to the target's hostname, and default_price_sats (the per-call price buyers pay) defaults to the server's. The claim body is written once and sent twice; the payment is bound to the target URL, the Lightning Address, and the recovery binding. If you give a recovery_email, use one that is not registered yet: an email that already belongs to an account is refused only after payment.

The tool keeps one state file per claim in a claim/ folder beside your config.json (owner-only), written before paying. Calling sell_url again with the same arguments is always safe:

  • Paid but not yet redeemed: it redeems the saved token without paying again.

  • Already claimed: it answers from a marker with the proxy URL and where the key is stored. It does not mint or pay a second claim.

  • Payment outcome unknown (the wallet may have paid but gave no answer): it reports payment_state_unknown with the payment hash and never pays that claim again. Check the wallet's payment history and contact support.

Until a claim is redeemed, its state file holds the paid token, which can rotate the account's key, so treat it like the key file. A refusal before payment costs nothing.

From an API key to a paid endpoint

No dashboard, no REST client, no human in the loop. Each step is one tool call:

  1. Get an API key. create_lightning_enable_account — pays a ~100-sat activation fee from your wallet and writes the key to ~/.lightning-enable/config.json. Restart the server so the gated tools unlock. (Skip if you already have a key.)

  2. Point payouts at your own wallet. l402_producer(action="configure_receive") — with no argument it reuses the NWC wallet this server already pays with; pass nwc_connection_string to use a different one. The string is never echoed back, only <set>.

  3. Check where you stand. l402_producer(action="status") — plan, receiving wallet, and the onboarding checklist, so the agent can see what is still missing.

  4. Put your API behind L402. l402_producer(action="create_proxy", name="Weather API", target_base_url="https://api.example.com", default_price_sats=25) — returns a proxy_id and the public base URL. Every request under it now answers 402 until it is paid.

  5. Price each route. l402_producer(action="add_endpoint", proxy_id="weather-api", endpoint_id="forecast", path="/forecast", http_method="GET", price_sats=10) — repeat per route.

  6. List it. l402_producer(action="publish", proxy_id="weather-api", service_description="Five-day forecasts for agents", categories=["weather"]) — returns the OpenAPI and manifest URLs. Other agents find it through discover_api.

  7. Watch the money arrive. l402_producer(action="list_challenges", challenge_status="paid") — payment hash, resource, amount and status. Never a macaroon, never a preimage.

For a resource you are not proxying — a file, a report, a one-off answer — skip steps 4-6 and use create / verify directly.

Payouts settle on your wallet. Lightning Enable does not hold the funds.

Get listed: verify ownership of your API

Anyone can put a proxy in front of any public URL, so only a proxy whose owner has proved control of the target is listed publicly. An unverified proxy keeps working and taking payments by its direct URL.

  1. Get a token. l402_producer(action="verification_token", proxy_id="weather-api") returns the token once, with the exact file URL, DNS TXT record name and header for this proxy. The tool also stores it, owner-only, in verification-<proxyId>.json beside config.json. A sell_url claim returns a token the same way, so skip this step after sell_url. Issuing a token for a proxy that is already verified needs reissue=true, because the new token unverifies and unlists it until you verify again.

  2. Publish it by one method. A well-known file proves you control the web root of the target host, a DNS TXT record proves you control its DNS zone, and a response header proves only that you control the API's responses. method="dns-txt" (or well-known, header) only filters the instructions shown.

  3. Run the check. l402_producer(action="verify", proxy_id="weather-api") returns the state and plain-language next steps for each failure reason. A slow check comes back pending; the tool retries a few times, waiting as the server asks (at most 10 seconds each), before handing back. If you stored a token earlier, verify points at it rather than at a new one.

  4. List it. Once verified, l402_producer(action="publish", proxy_id="weather-api").

publish_agent_capability (and agent_services(action="publish")) follows the same rule: the result says published: false and returns the one-time token, and the listing goes up after verify succeeds.

Agent Service Agreements (the agent_services tool)

Agent-to-agent commerce on Nostr, behind one tool. Pass action to pick the operation. agent_services requires LIGHTNING_ENABLE_API_KEY (an Agentic Commerce subscription); action="settle" additionally spends your wallet balance, subject to budget limits.

The hosted Lightning Enable API refuses attest, because it has no route that accepts attestations, so you can't leave a review through it; discover, request, settle, publish, unpublish, and reputation work.

Action

Description

discover

Search for agent capabilities by category, hashtag, or keyword

publish

Publish your agent's services to the Nostr network (kind 38400). Publish once: each call creates a new listing and L402 proxy. To change a listing, unpublish it and publish again, or edit it in the Lightning Enable dashboard. Listing waits for ownership verification: the result says published: false, returns a one-time token, and points at l402_producer(action="verify")

unpublish

Take a published listing down: retire the L402 proxy and emit a NIP-09 removal

request

Request a service from another agent (kind 38401)

settle

Pay for an agent service via L402 Lightning settlement

attest

Leave a review/rating for an agent after service completion (kind 38403)

reputation

Check an agent's reputation score from on-protocol attestations

How Agent Commerce Works

  1. Discover — agent_services(action="discover", category="translation") finds agents offering translation

  2. Request — agent_services(action="request", capability_event_id=..., budget_sats=100) sends a service request

  3. Settle — agent_services(action="settle", l402_endpoint=...) pays via Lightning and receives the result

  4. Review — agent_services(action="attest", subject_pubkey=..., agreement_id=..., rating=5) builds on-protocol reputation (the hosted API refuses this action)

For dynamic pricing, providers use l402_producer(action="create") to generate invoices at the agreed price. Requesters pay and providers verify with l402_producer(action="verify").

The seven old tool names (discover_agent_services, settle_agent_service, …) still work — see Old name → new call.

Privacy

Lightning Enable does not hold funds — the connected wallet or payment provider (Strike, OpenNode, LND, or an NWC wallet) does. The MCP server runs locally and talks to the wallet/provider you configure and, for L402 discovery, the L402 API registry. Wallet credentials you supply stay on your machine (or, for the hosted API, are encrypted at rest). See the full Privacy Policy for what data is collected, third parties involved, retention, and contact (privacy@lightningenable.com).

Support

If something's broken or not working, email support@lightningenable.com — a real person reads it. For general questions, join the Discord: https://discord.gg/rX7NxHY8vx. Bug reports and feature requests: open an issue on this repo.

License

MIT — see LICENSE.

Available Tools

17 tools
access_l402_resourceA

Fetch a URL with automatic L402 payment handling. If the server returns a 402 Payment Required response, the invoice will be automatically paid and the request retried.

Inputs: url (required), method, headers, body, +2 more.

check_invoice_statusB

Check if a Lightning invoice has been paid. Use the invoice ID from create_invoice.

Inputs: invoice_id (required).

check_wallet_balanceB

Check the connected Lightning wallet balance via NWC.

Inputs: no named parameters.

configure_budgetC

Set spending limits for the session.

Inputs: per_request, per_session.

confirm_paymentA

Confirm a pending payment using the nonce code from a previous payment request. Call this after a payment tool returns requiresConfirmation=true with a nonce.

Inputs: nonce (required).

create_invoiceB

Create a Lightning invoice to receive a payment. Returns a BOLT11 invoice string to share with the payer.

Inputs: amount_sats (required), memo, expiry_secs.

create_l402_challengeA

Create an L402 payment challenge to charge another agent or user for accessing a resource. Returns a Lightning invoice and macaroon. The payer must pay the invoice and present the L402 token (macaroon:preimage) back to you for verification. Requires LIGHTNING_ENABLE_API_KEY with an Agentic Commerce subscription.

Inputs: resource (required), price_sats (required), description.

discover_apiA

Discover L402-enabled APIs. Use 'query' to search the registry for available APIs by keyword, or use 'url' to fetch a specific API's manifest with full endpoint details and pricing. Use 'category' to browse by category. With budget_aware=true, shows how many calls you can afford.

Inputs: url, query, category, budget_aware.

exchange_currencyB

Exchange currency within your wallet (USD to BTC or BTC to USD). Currently only available with Strike wallet.

Inputs: source_currency (required), target_currency (required), amount (required).

get_all_balancesB

Get all currency balances from your wallet (USD, BTC, etc.). Most useful with Strike wallet which supports multiple currencies.

Inputs: no named parameters.

get_btc_priceA

Get the current Bitcoin price in USD. Only available with Strike wallet.

Inputs: no named parameters.

get_budget_statusB

View current budget status and spending limits (read-only). Edit ~/.lightning-enable/config.json to change limits.

Inputs: no named parameters.

get_payment_historyC

List recent L402 payments made during this session.

Inputs: limit, since.

pay_invoiceA

Pay a Lightning invoice directly and get the preimage as proof of payment. Use this to pay any BOLT11 Lightning invoice without L402 protocol overhead.

Inputs: invoice (required), max_sats, confirmed.

pay_l402_challengeB

Manually pay an L402 or MPP invoice and receive the authorization token. Use this if you need to handle the L402/MPP flow yourself. Omit macaroon for MPP (Machine Payments Protocol) mode.

Inputs: invoice (required), macaroon, max_sats.

send_onchainC

Send an on-chain Bitcoin payment to a Bitcoin address. Currently only available with Strike wallet.

Inputs: address (required), amount_sats (required).

verify_l402_paymentA

Verify an L402 token (macaroon + preimage) to confirm payment was made. Use this after receiving an L402 token from a payer to validate they paid before granting access to the resource. Requires LIGHTNING_ENABLE_API_KEY with an Agentic Commerce subscription.

Inputs: macaroon (required), preimage (required).

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.7/5.0

    Scored across 17 tools

    Disambiguation4/5

    Most tools have distinct purposes, such as access_l402_resource for automated payments, pay_invoice for direct payments, and create_l402_challenge for charging others. However, some overlap exists between check_invoice_status and verify_l402_payment, which both involve payment verification but target different contexts, potentially causing minor confusion.

    Naming Consistency5/5

    Tool names consistently follow a verb_noun pattern with snake_case throughout, such as access_l402_resource, check_invoice_status, and configure_budget. This uniformity makes the set predictable and easy to understand, with no deviations in naming conventions.

    Tool Count4/5

    With 17 tools, the count is slightly high but reasonable for the server's scope in Lightning payments and L402 protocol management. It covers various aspects like payments, invoices, budgets, and API discovery, though it might feel a bit heavy compared to more focused servers.

    Completeness5/5

    The tool set provides comprehensive coverage for Lightning and L402 operations, including creating and paying invoices, managing budgets, verifying payments, and handling on-chain transactions. No obvious gaps are present; it supports full workflows from payment initiation to confirmation and resource access.

    Maintenance

    ActivityActive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      B
      quality
      F
      maintenance
      Enables interaction with lightning addresses and common lightning tools via your LLM, providing Lightning Network functionality through natural language.
      3
      7 npm
      1
      MIT
    • A
      license
      Not graded
      quality
      C
      maintenance
      MCP server for AgentPay — the payment gateway for autonomous AI agents. Fund a wallet once, give your agent the key, and it discovers, provisions, and pays for tool APIs on its own. One key, every tool.
      112 npm
      1
      MIT
    • A
      license
      A
      quality
      B
      maintenance
      L402 + x402 client MCP. AI agents discover, pay for, and consume any payment-gated API autonomously. Supports Lightning (NWC), Cashu ecash, stablecoins, and human-in-the-loop payments.
      14
      141 npm
      MIT