Skip to main content

Lightning Enable MCP - Complete Guide

The Lightning Enable MCP (Model Context Protocol) server enables AI agents to interact with the Lightning Network. It's free and open source with comprehensive Lightning wallet capabilities.

Open Source

The MCP server is fully open source: github.com/refined-element/lightning-enable-mcp. Available on NuGet, PyPI, and Docker.

Overviewโ€‹

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Lightning Enable MCP โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ AI Agent (Claude, etc.) โ”‚
โ”‚ โ†“ โ”‚
โ”‚ MCP Server (wallet priority: LND > NWC > Strike > OpenNode) โ”‚
โ”‚ โ†“ โ”‚
โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚ โ”‚ LND โ”‚ โ”‚ NWC โ”‚ โ”‚ Strike โ”‚ โ”‚ OpenNode โ”‚ โ”‚
โ”‚ โ”‚ Wallet โ”‚ โ”‚ Wallet โ”‚ โ”‚ Wallet โ”‚ โ”‚ Wallet โ”‚ โ”‚
โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ”‚ โ†“ โ†“ โ†“ โ†“ โ”‚
โ”‚ Lightning Network โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Wallet Priority: When multiple wallets are configured, the MCP server selects them in order: LND > NWC > Strike > OpenNode. This order is optimized for L402 compatibility (LND and NWC always return preimages). Override with the WALLET_PRIORITY environment variable or the priority field in your config file.

Installationโ€‹

.NET (Windows, Linux, macOS)โ€‹

dotnet tool install -g LightningEnable.Mcp

Python (All Platforms)โ€‹

pip install lightning-enable-mcp

Or use uvx for no-install execution:

uvx lightning-enable-mcp
NWC wallets

The base install works on every platform (including Windows) with no build toolchain. If you connect a Nostr Wallet Connect (NWC) wallet, install the optional extra: pip install lightning-enable-mcp[nwc]. Other wallet types (LND, Strike, OpenNode) don't need it. (.NET is unaffected โ€” it uses managed crypto.)

Quick Startโ€‹

Claude Code users: register the server with claude mcp add --transport stdio lightning-enable --env STRIKE_API_KEY=your-key -- lightning-enable-mcp (or a project .mcp.json) โ€” see Claude Code Setup. Claude Code does not read claude_desktop_config.json.

Claude Desktop users: add to your Claude Desktop config:

Windows: %APPDATA%\Claude\claude_desktop_config.json macOS: ~/Library/Application Support/Claude/claude_desktop_config.json Linux: ~/.config/claude/claude_desktop_config.json

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

All Available Toolsโ€‹

Tool Profilesโ€‹

The MCP server ships three tool profiles, selected once at startup with LIGHTNING_ENABLE_TOOL_PROFILE:

export LIGHTNING_ENABLE_TOOL_PROFILE=standard   # default โ€” omit this line to get the same result
ProfileSurfaceUse it when
litePay, check the wallet, budget, receipts, wallet setupYou want the smallest possible footprint โ€” an agent that can pay and check its own wallet, and nothing else.
standard (default)Every current tool (listed below)The current, canonical surface. Everything the server can do, addressed through a small number of action-based tools instead of one tool per operation.
fullstandard plus every pre-consolidation name as a deprecated aliasYou're running a prompt or integration written against the old per-operation tool names (configure_budget, create_l402_challenge, โ€ฆ). Aliases forward to the new tools and keep working, but are removed in v3.0.0 โ€” migrate when you can.

lite: pay_invoice, access_l402_resource, get_balance, budget, receipts, setup_wallet

standard (default): access_l402_resource, pay_invoice, pay_l402_challenge, test_l402_payment, get_balance, budget, receipts, create_invoice, check_invoice_status, verify_confirmation_code, discover_api, create_lightning_enable_account, setup_wallet, wallet_ops, l402_producer, agent_services

The lists above are the source of truth; other pages link here rather than restating counts, which drift. The server's own tool listing is authoritative for the installed version.

Tool Availability by Walletโ€‹

ToolStrikeOpenNodeLNDNWC (CoinOS/CLINK)NWC (Alby)NWC (Primal)API key
pay_invoiceโœ…โœ…โœ…โœ…โœ…โœ…No
access_l402_resourceโœ…โŒโœ…โœ…โœ…โŒNo
pay_l402_challengeโœ…โŒโœ…โœ…โœ…โŒNo
test_l402_paymentโœ…โŒโœ…โœ…โœ…โŒNo
get_balanceโœ… (multi-currency)โœ…โœ…โœ…โœ…โœ…No
budget (action=status|tighten)โœ…โœ…โœ…โœ…โœ…โœ…No
receipts (source=durable|session)โœ…โœ…โœ…โœ…โœ…โœ…No
create_invoiceโœ…โœ…โœ…โœ…*โœ…*โœ…*No
check_invoice_statusโœ…โœ…โœ…โŒโŒโŒNo
verify_confirmation_codeโœ…โœ…โœ…โœ…โœ…โœ…No
discover_apiโœ…โœ…โœ…โœ…โœ…โœ…No
create_lightning_enable_accountโœ…โŒโœ…โœ…โœ…โŒNo
setup_walletโœ…โœ…โœ…โœ…โœ…โœ…No
wallet_ops (action=price|exchange|send_onchain)โœ…โŒ**โœ… (send_onchain only)โŒ**โŒ**โŒ**No
l402_producer (action=create|verify|configure_receive|status|create_proxy|add_endpoint|publish|list_challenges)โœ…โœ…โœ…โœ…โœ…โœ…Yes, every action
agent_services (action=discover|request|settle|publish|unpublish|attest|reputation)โœ…โœ…โœ…โœ…โœ…โœ…Partial โ€” see ASA tools

*NWC invoice creation depends on wallet support. **price and exchange are Strike-only regardless of wallet; send_onchain also works on LND.

L402 requires preimage return: LND always works, Strike works, CoinOS/CLINK work, Alby works, OpenNode/Primal don't return preimage.

Deprecated aliasesโ€‹

Two generations of renames, both kept working so an old prompt still makes sense โ€” the mapping is what changed, not the behavior:

Deprecated nameCurrent callSince
check_wallet_balance, get_all_balancesget_balancev1.17.0
confirm_paymentverify_confirmation_codev1.17.0
get_payment_historyreceipts(source="session")Tool consolidation
get_receiptsreceipts(source="durable")Tool consolidation
get_budget_statusbudget(action="status")Tool consolidation
configure_budgetbudget(action="tighten")Tool consolidation
get_btc_pricewallet_ops(action="price")Tool consolidation
exchange_currencywallet_ops(action="exchange")Tool consolidation
send_onchainwallet_ops(action="send_onchain")Tool consolidation
create_l402_challengel402_producer(action="create")Tool consolidation
verify_l402_paymentl402_producer(action="verify")Tool consolidation
discover_agent_servicesagent_services(action="discover")Tool consolidation
request_agent_serviceagent_services(action="request")Tool consolidation
settle_agent_serviceagent_services(action="settle")Tool consolidation
publish_agent_capabilityagent_services(action="publish")Tool consolidation
unpublish_agent_capabilityagent_services(action="unpublish")Tool consolidation
publish_agent_attestationagent_services(action="attest")Tool consolidation
get_agent_reputationagent_services(action="reputation")Tool consolidation

The 16 "Tool consolidation" rows are available under LIGHTNING_ENABLE_TOOL_PROFILE=full only โ€” standard and lite expose just the current names on the left of the "Current call" column above. All 18 aliases are scheduled for removal in v3.0.0.

This page is the canonical, authoritative tool list โ€” other docs pages link here rather than repeat tool counts.


Onboardingโ€‹

setup_walletโ€‹

Configures a wallet into ~/.lightning-enable/config.json without hand-editing JSON โ€” usually the first tool call of a session on a fresh machine, and the one the producer-setup skill opens with (see Sell With Your Agent).

Parameters:

ParameterTypeRequiredDescription
walletTypestringYesstrike, opennode, nwc, or lnd
credentialstringYesThe API key (Strike/OpenNode), the nostr+walletconnect://... string (NWC), or the LND macaroon (LND)
lndRestHoststringIf walletType=lndLND REST API host
maxPerPaymentSats / maxPerSessionSatsintNoSats-native spend ceiling โ€” see sats-native budgets below. Omit to keep the existing config-file limits (USD or sats) untouched

The tool applies the same first-run file lockdown as any other config write (chmod 0600 on POSIX, icacls /inheritance:r /grant {user}:F on Windows โ€” see Config file perms) and never echoes the credential back in its result โ€” the response confirms what was configured (wallet type, provider) without repeating the secret.

Never returns the credential

Like every other part of the MCP server, setup_wallet's response never contains the value you passed in credential โ€” only whether the write succeeded and which wallet type is now active.

Core Tools (All Wallets)โ€‹

pay_invoiceโ€‹

Pay any Lightning invoice and get the preimage as proof of payment.

Parameters:

ParameterTypeRequiredDefaultDescription
invoicestringYes-BOLT11 Lightning invoice
max_satsintNo1000Maximum payment allowed (Python package; the .NET tool relies on budget-service limits)
confirmationNoncestringNo-Confirmation code from the server console (confirmation_nonce in Python). Required on the retry when the first call returned requiresConfirmation=true โ€” see Out-of-Band Confirmation

Example:

User: Pay this invoice: lnbc500n1p3...

Claude: [Uses pay_invoice]

Payment successful!
- Amount: 500 sats
- Preimage: 7f8a9b2c3d4e5f...
- Provider: Strike

Response:

{
"success": true,
"provider": "Strike",
"payment": {
"preimage": "7f8a9b2c3d4e5f...",
"amountSats": 500
},
"message": "Payment successful! Paid 500 sats."
}

get_balanceโ€‹

Get the connected wallet's balance: the sats balance plus, where available, all currency balances (multi-currency for Strike, a single BTC entry otherwise) and the session spend summary. Supersedes the old check_wallet_balance and get_all_balances tools (v1.17.0) โ€” it returns the superset of what both returned, and the old names keep working as deprecated aliases until v3.0.0.

Parameters: None required

Example:

User: What's my wallet balance?

Claude: [Uses get_balance]

Wallet Balance: 50,000 sats (~$50 USD)
Provider: Strike
Strike balances: $127.45 USD ยท 0.00050000 BTC

Response:

{
"success": true,
"provider": "Strike",
"balance": {
"sats": 50000,
"btc": 0.0005
},
"balances": [
{ "currency": "USD", "available": 127.45, "formatted": "127.45 USD" },
{ "currency": "BTC", "available": 0.0005, "formatted": "0.00050000 BTC (50,000 sats)" }
],
"message": "Balance: 50,000 sats"
}

receiptsโ€‹

Read the payment record, from either of two sources selected with source. Replaces the two formerly separate tools get_payment_history (now source="session") and get_receipts (now source="durable").

Parameters:

ParameterTypeRequiredDefaultDescription
sourcestringNodurabledurable โ€” the persistent receipt log (lightning-enable://receipts, survives restarts). session โ€” recent payments made in this running process only (in-memory, cleared on restart).
limitintNo10Maximum records to return

Example:

User: Show my recent payments

Claude: [Uses receipts with source="session"]

Recent Payments:
1. 500 sats - lnbc500n1... - 5 min ago
2. 100 sats - lnbc100n1... - 1 hour ago
3. 1000 sats - lnbc1u1... - 2 hours ago

Total: 1,600 sats across 3 payments
Also readable as an MCP Resource

The durable log is also exposed as an MCP Resource at lightning-enable://receipts, so a client that reads resources rather than calling tools can pull the same data without a tool call.


budgetโ€‹

Read or tighten spending limits, selected with action. Replaces the two formerly separate tools get_budget_status (now action="status") and configure_budget (now action="tighten").

Parameters:

ParameterTypeRequiredDescription
actionstringYesstatus (read-only) or tighten (lower a runtime cap)
maxPerPaymentSats / maxPerSessionSatsintOnly for action="tighten"New, lower sats caps. Rejected if either value is above the current effective cap โ€” this action can never raise a limit. Parameter names: per_request / per_session in the Python package, perRequest / perSession in .NET, still accepted as aliases.

status is read-only โ€” limits can only be raised by editing the config file directly; budget(action="tighten") can only ever lower the runtime sats caps.

Example โ€” status:

User: What are my spending limits?

Claude: [Uses budget with action="status"]

Budget Configuration (READ-ONLY):
- Config file: ~/.lightning-enable/config.json
- Auto-approve: up to $0.10
- Log & approve: $0.10 - $1.00
- Requires out-of-band confirmation code: above $1.00
- Maximum per payment: $500.00
- Maximum per session: $100.00

Session:
- Spent: $0.45 (4,500 sats)
- Remaining: $99.55

Note: AI cannot RAISE budget limits. budget(action="tighten") can only
tighten the runtime sats caps; edit config.json to raise limits.

Example โ€” tighten:

User: Lower my per-request cap to 5,000 sats for this session.

Claude: [Uses budget with action="tighten", maxPerPaymentSats=5000]

Runtime per-payment cap tightened to 5,000 sats for this session.
(This cannot be undone by calling budget again with a higher value โ€”
only editing config.json can raise it back.)

See sats-native budgets below for maxPerPaymentSats / maxPerSessionSats as operator config-file keys, which is a different (higher-authority) thing from this tool's runtime tightening.


verify_confirmation_codeโ€‹

Verify whether a payment confirmation code (relayed by the human from the server console) is still valid and what it authorizes. Verification only โ€” it never executes a payment. To actually pay, re-call the original payment tool with the confirmationNonce (.NET) / confirmation_nonce (Python) parameter. Renamed from confirm_payment in v1.17.0 (the old name still works as a deprecated alias until v3.0.0).

Parameters:

ParameterTypeRequiredDescription
noncestringYesThe confirmation code the human read from the server console

Response (valid):

{
"valid": true,
"amount_sats": 2500,
"tool": "pay_invoice",
"message": "Code verified โ€” NOTHING HAS BEEN PAID. To execute, call pay_invoice again with confirmation_nonce=<code>."
}

Invoice Tools (Strike, OpenNode, LND)โ€‹

create_invoiceโ€‹

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

Parameters:

ParameterTypeRequiredDefaultDescription
amountSatslongYes-Amount to receive in satoshis
memostringNonullDescription for the invoice
expirySecsintNo3600Invoice expiry (default 1 hour)

Example:

User: Create an invoice for 1000 sats for "Coffee payment"

Claude: [Uses create_invoice]

Invoice Created!
- Amount: 1,000 sats
- Memo: Coffee payment
- Expires: 1 hour
- Invoice ID: inv_abc123...

BOLT11 Invoice (share with payer):
lnbc10u1p3xyza...

Share this invoice with the payer, or display as a QR code.

Response:

{
"success": true,
"provider": "Strike",
"invoice": {
"id": "inv_abc123",
"bolt11": "lnbc10u1p3xyza...",
"amountSats": 1000,
"expiresAt": "2024-01-15T14:30:00Z"
},
"message": "Invoice created for 1000 sats. Share the bolt11 string with the payer."
}

check_invoice_statusโ€‹

Check if a previously created invoice has been paid.

Parameters:

ParameterTypeRequiredDescription
invoiceIdstringYesInvoice ID from create_invoice

Example:

User: Has the coffee invoice been paid?

Claude: [Uses check_invoice_status with invoiceId="inv_abc123"]

Invoice Status: PAID! โœ…
- Amount: 1,000 sats
- Paid at: 2024-01-15 13:45:22 UTC

Response:

{
"success": true,
"provider": "Strike",
"invoice": {
"id": "inv_abc123",
"state": "paid",
"isPaid": true,
"isPending": false,
"amountSats": 1000,
"paidAt": "2024-01-15T13:45:22Z"
},
"message": "Invoice inv_abc123 has been PAID!"
}

wallet_opsโ€‹

Strike- and LND-specific operations. One consolidated tool for the operations that only some wallets support, selected with action. Replaces the three formerly separate tools get_btc_price (now action="price"), exchange_currency (now action="exchange"), and send_onchain (now action="send_onchain").

price and exchange are Strike-only regardless of wallet. send_onchain works with Strike and LND.

action="price"โ€‹

Get the current Bitcoin price in USD.

Parameters: action="price" only โ€” no other parameters

Example:

User: What's the current Bitcoin price?

Claude: [Uses wallet_ops with action="price"]

Current BTC Price: $97,500.00 USD
Source: Strike
Timestamp: 2024-01-15 13:30:00 UTC

Response:

{
"success": true,
"provider": "Strike",
"ticker": {
"btcUsd": 97500.00,
"timestamp": "2024-01-15T13:30:00Z"
},
"message": "Current BTC price: $97,500.00 USD"
}

action="exchange"โ€‹

Convert between USD and BTC within your Strike wallet.

Parameters:

ParameterTypeRequiredDescription
sourceCurrencystringYesCurrency to convert from: USD or BTC
targetCurrencystringYesCurrency to convert to: BTC or USD
amountdecimalYesAmount in source currency

Example โ€” Buy Bitcoin:

User: Convert $50 to Bitcoin

Claude: [Uses wallet_ops with action="exchange", sourceCurrency=USD, targetCurrency=BTC, amount=50]

Exchange Complete!
- Converted: $50.00 USD
- Received: 0.00051282 BTC (51,282 sats)
- Rate: $97,500/BTC
- Fee: $0.25

Example โ€” Sell Bitcoin:

User: Sell 0.001 BTC for dollars

Claude: [Uses wallet_ops with action="exchange", sourceCurrency=BTC, targetCurrency=USD, amount=0.001]

Exchange Complete!
- Converted: 0.001 BTC (100,000 sats)
- Received: $97.00 USD
- Rate: $97,500/BTC
- Fee: $0.50

action="send_onchain"โ€‹

Send an on-chain Bitcoin payment to a Bitcoin address (not Lightning). Works with Strike and LND.

Parameters:

ParameterTypeRequiredDescription
addressstringYesBitcoin address (bc1q..., 3..., or 1...)
amountSatslongYesAmount to send in satoshis
confirmationNoncestringNoConfirmation code from the server console (confirmation_nonce in Python). Omit on the first call to request one; always required to actually send
Always Confirmed

On-chain payments are irreversible, so wallet_ops(action="send_onchain") always requires an out-of-band confirmation code โ€” even for small amounts โ€” and fails closed if the budget service is unavailable. See Out-of-Band Confirmation.

Example:

User: Send 50000 sats to bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh

Claude: [Uses wallet_ops with action="send_onchain"]

On-Chain Payment Sent!
- Amount: 50,000 sats (0.0005 BTC)
- Address: bc1qxy2kg...
- Network Fee: 500 sats
- Status: COMPLETED
- Transaction ID: abc123def456...
On-Chain vs Lightning

On-chain payments are slower (10+ minutes) and have higher fees than Lightning. Use Lightning (pay_invoice) when possible.


L402 Tools (Free)โ€‹

These tools are included for free with the MCP server. No license purchase or subscription required.

L402-Compatible Wallets Required

L402 requires a wallet that returns the payment preimage:

  • LND (self-hosted) - Always works, guaranteed L402
  • CoinOS - Free, easy, works for L402
  • CLINK - Nostr-native, works for L402
  • Strike - Returns preimage, works for L402
  • Alby - โœ… Works

OpenNode and Primal don't return preimages and cannot be used for L402.

access_l402_resourceโ€‹

Fetch a URL with automatic L402 payment handling. When the API returns 402 Payment Required, the MCP automatically pays the invoice and retries with the L402 credential.

Parameters:

ParameterTypeRequiredDefaultDescription
urlstringYes-URL to fetch
methodstringNoGETHTTP method
headersstringNonullJSON object of headers
bodystringNonullRequest body
maxSatsintNo1000Maximum payment allowed
confirmationNoncestringNo-Confirmation code from the server console (confirmation_nonce in Python). Required on the retry when the first call returned requiresConfirmation=true

Example:

User: Fetch premium data from https://api.example.com/l402/data

Claude: [Uses access_l402_resource]

The API required a 50 sat payment which was automatically paid.

Response:
{
"premium": "data...",
"analysis": "..."
}

Payment Details:
- Amount: 50 sats ($0.05)
- L402 token cached for future requests

pay_l402_challengeโ€‹

Manually pay an L402 (or MPP) invoice when you have the invoice โ€” and, for L402, the macaroon โ€” as separate components.

Parameters:

ParameterTypeRequiredDefaultDescription
invoicestringYes-BOLT11 Lightning invoice
macaroonstringNo-Base64-encoded macaroon. Optional โ€” omit for MPP mode
maxSatsintNo1000Maximum payment allowed
confirmationNoncestringNo-Confirmation code from the server console (confirmation_nonce in Python). Required on the retry when confirmation was requested

Returns: L402 credential in format macaroon:preimage (L402 mode), the bare preimage (legacy MPP mode), or a single-use Authorization: Payment <base64url(JSON)> credential (modern MPP draft-00 mode)

MPP support: the macaroon parameter is optional. When you omit it, the tool operates in MPP (Machine Payments Protocol) mode โ€” some paid APIs issue a plain Lightning invoice and accept the payment preimage alone as the access token, with no macaroon involved. Provide the macaroon for standard L402 challenges; omit it when the challenge only gave you an invoice.

Modern Payment challenges (v1.24.0+): for APIs using the current MPP draft-00 wire format (draft-httpauth-payment-00), pass the raw challenge header via the optional challengeHeader (.NET) / challenge_header (Python) parameter. The tool runs client-side safety checks before paying (expiry, intent: charge, sat currency, declared amount must agree with the invoice) and returns the single-use modern credential, which is never cached or replayed. access_l402_resource handles modern Payment challenges automatically and surfaces the server's Payment-Receipt header in its result (paymentReceipt โ€” payment hash only, never the preimage).


discover_apiโ€‹

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

Parameters:

ParameterTypeRequiredDefaultDescription
querystringNo-Search the registry by keyword (e.g., "weather", "ai")
categorystringNo-Filter registry results by category
urlstringNo-Fetch a specific API's manifest directly
budgetAwareboolNotrueAnnotate results with affordable call counts

Example โ€” Search the registry:

User: Find me some weather APIs I can pay for

Claude: [Uses discover_api with query="weather"]

Found 3 weather APIs in the L402 registry:

1. Weather Data API โ€” 5 sats/request (1,600 calls affordable)
2. Storm Tracker Pro โ€” 25 sats/request (320 calls affordable)
3. Climate Analytics โ€” 100 sats/request (80 calls affordable)

Want me to get full details on any of these?

Example โ€” Get full manifest:

User: Show me the full details for Weather Data API

Claude: [Uses discover_api with url="https://api.lightningenable.com/l402/proxy/weather-api/.well-known/l402-manifest.json"]

Weather Data API โ€” 3 endpoints:
- GET /v1/current โ€” Current weather (5 sats)
- GET /v1/forecast โ€” 7-day forecast (10 sats)
- GET /v1/historical โ€” Historical data (25 sats)

Registry URL: Defaults to https://api.lightningenable.com. Override with L402_REGISTRY_URL or LIGHTNING_ENABLE_API_URL environment variable.

Manifest probing (v1.24.1+): when you pass a base url, the tool probes /.well-known/l402-manifest.json, /.well-known/l402.json, /l402-manifest.json, and /l402.json in order, and only accepts documents that actually describe a service or its endpoints (protocol signposts are skipped).


l402_producerโ€‹

Agentic Commerce producer tool. One consolidated tool for the entire producer side of L402 โ€” everything your agent needs to charge other agents and users, configure a receive lane, and stand up a monetized endpoint โ€” selected with action. Requires LIGHTNING_ENABLE_API_KEY with an Agentic Commerce subscription for every action; there is no free tier of this tool.

Agents That Earn

The consumer tools above let agents spend. l402_producer lets an agent earn โ€” including setting up the whole receive path itself. Together, they enable true agent-to-agent commerce โ€” AI agents that autonomously buy and sell services using Lightning payments. See Sell With Your Agent for the full end-to-end walkthrough that chains every action below.

actionReplacesDoes
createcreate_l402_challengeMint a Lightning invoice + macaroon to charge for a resource
verifyverify_l402_paymentVerify an L402 token (macaroon + preimage) before granting access
configure_receive(new)Save a receive-side credential (NWC connection string, or Strike/OpenNode key) and switch the account onto that lane
status(new)Confirm the receive lane is live and reachable before minting anything against it
create_proxy(new)Wrap an existing API in an L402-gated proxy
add_endpoint(new)Register a specific path, method, price, and description in the proxy's manifest
publish(new)Enable the manifest and, optionally, list the proxy in the public L402 registry
list_challenges(new)Read back the challenge feed โ€” what's been minted and what's been paid

action="create"โ€‹

Create an L402 payment challenge (Lightning invoice + macaroon) to charge another agent or user.

Parameters:

ParameterTypeRequiredDefaultDescription
resourcestringYes-Resource identifier (URL, service name, or description)
priceSatslongYes-Price in satoshis to charge
descriptionstringNonullDescription shown on the Lightning invoice

Example:

User: Charge 50 sats for access to the forecast data

Claude: [Uses l402_producer with action="create"]

L402 challenge created!
- Invoice: lnbc500n1p3xyza...
- Price: 50 sats
- Resource: /api/weather/forecast

Share the invoice with the payer. After they pay,
use l402_producer with action="verify" to confirm before granting access.

Response:

{
"success": true,
"challenge": {
"invoice": "lnbc500n1p3xyza...",
"macaroon": "AgELbGlnaHRuaW5n...",
"paymentHash": "abc123def456...",
"expiresAt": "2026-03-13T14:30:00Z"
},
"resource": "/api/weather/forecast",
"priceSats": 50,
"message": "L402 challenge created for 50 sats. Share the invoice with the payer."
}

action="verify"โ€‹

Verify an L402 token (macaroon + preimage) to confirm payment was made before granting access.

Parameters:

ParameterTypeRequiredDefaultDescription
macaroonstringYes-Base64-encoded macaroon from the L402 token
preimagestringYes-Hex-encoded preimage (proof of payment)

Example:

User: The agent sent this L402 token โ€” verify it

Claude: [Uses l402_producer with action="verify"]

Payment verified! The payer paid 50 sats for /api/weather/forecast.
Granting access now.

Response (valid):

{
"success": true,
"valid": true,
"resource": "/api/weather/forecast",
"message": "Payment verified. The payer has paid โ€” you can now grant access to the resource."
}

Response (invalid):

{
"success": true,
"valid": false,
"message": "Payment verification failed. The token is invalid or the invoice has not been paid. Do NOT grant access."
}
Always Verify

Never grant access based on a payer claiming they paid. Always call l402_producer with action="verify" to cryptographically confirm payment before granting access.

action="configure_receive", "status", "create_proxy", "add_endpoint", "publish", "list_challenges"โ€‹

These six actions are new โ€” there is no legacy single-purpose tool they rename. Together they let an agent take an API from "not connected to Lightning Enable at all" to "live, priced, and discoverable" without the dashboard:

  • configure_receive โ€” wraps PUT /api/merchant/nwc-connection (or the Strike/OpenNode key endpoint) plus PUT /api/merchant/payment-provider.
  • status โ€” wraps GET /api/merchant/quickstart; confirm the receive lane actually took before anything downstream depends on it.
  • create_proxy โ€” wraps POST /api/proxy.
  • add_endpoint โ€” wraps POST /api/proxy/{proxyId}/manifest/endpoints.
  • publish โ€” wraps PUT /api/proxy/{proxyId}/manifest/settings.
  • list_challenges โ€” wraps GET /api/l402/challenges.

Full parameters, request/response shapes, and a worked example chaining all eight actions (including create/verify above) are in Sell With Your Agent; the underlying REST contract for each is in the Producer API Reference and Proxy Configuration.

See L402 Producer API for the complete producer guide with end-to-end examples.


agent_servicesโ€‹

Agent Service Agreements (ASA) tool. ASA shipped 2026-04-18 and are live at wss://agents.lightningenable.com / nostrwolfe.com. They let agents discover each other, request services, settle via L402 payment over Nostr, and build on-protocol reputation (flow: discover โ†’ request โ†’ settle โ†’ attest). One consolidated tool, agent_services, now covers all seven actions โ€” selected with action. Discovery, reputation reads, and L402 settlement (action="discover", action="reputation", action="settle") work against the public registry with just a wallet; requesting, publishing, and unpublishing (action="request", action="publish", action="unpublish", action="attest") require LIGHTNING_ENABLE_API_KEY. Wallet type never affects the API-key check.

actionReplacesPurposeAPI key
requestrequest_agent_serviceEntry point. Sends a service request (kind 38401 event) referencing the provider's capability.Required
discoverdiscover_agent_servicesDiscover agent capabilities on Nostr by category, hashtag, or keyword (kind 38400 events).โ€”
settlesettle_agent_serviceSettle an agreement via L402 payment (consumer/requester side) using the same auto-pay flow as access_l402_resource.โ€”
publishpublish_agent_capabilityAdvertise your agent's service so other agents can discover it (kind 38400 event; optionally auto-creates an L402 proxy).Required
unpublishunpublish_agent_capabilityTake a published listing down: retires the L402 proxy and publishes a NIP-09 deletion plus a status=removed replacement, so other agents stop seeing a dead listing.Required
attestpublish_agent_attestationPublish a review (rating 1โ€“5) for an agent after a completed agreement (kind 38403 event) to build its reputation.Required
reputationget_agent_reputationFetch an agent's reputation score and reviews (queries kind 38403 attestations for a pubkey).โ€”

action="request"โ€‹

Sends a service request (kind 38401 event) referencing the provider's capability. The full ASA flow is discover โ†’ request โ†’ settle โ†’ attest. If the provider has an L402 endpoint, you can skip this step and use action="settle" directly.

ParameterTypeRequiredDefaultDescription
capabilityEventIdstringYes-Event ID of the capability to request
budgetSatsintYes-Maximum budget in satoshis
parametersstringNo-Additional parameters as JSON

action="discover"โ€‹

ParameterTypeRequiredDefaultDescription
categorystringNo-Filter by service category (e.g., ai, data, translation)
hashtagsstring[]No-Filter by hashtags
querystringNo-Search query
limitintNo20Maximum results to return

action="settle"โ€‹

Pays the L402 endpoint specified in the agreement, completing the service transaction. If you are the provider (selling a service), use l402_producer with action="create" to generate an invoice and action="verify" to confirm payment instead.

ParameterTypeRequiredDefaultDescription
l402EndpointstringYes-L402 endpoint URL from the service agreement
methodstringNoGETHTTP method (GET, POST)
bodystringNo-Optional request body for POST requests
agreementIdstringNo-Agreement event ID for tracking
maxSatsintNo1000Maximum satoshis to pay

action="publish"โ€‹

ParameterTypeRequiredDefaultDescription
serviceIdstringYes-Unique service identifier (used as d-tag)
categoriesstring[]Yes-Service categories (e.g., ['ai', 'translation'])
contentstringYes-Description of the service
priceSatsintYes-Price per request in satoshis
l402EndpointstringNo-L402 endpoint URL for payment settlement
targetUrlstringNo-Target API URL (if auto-creating an L402 proxy via Lightning Enable)
hashtagsstring[]No-Hashtags for discoverability

action="unpublish"โ€‹

Works for marketplace listings created via the L402 proxy/dashboard pipeline.

ParameterTypeRequiredDefaultDescription
serviceIdstringYes-The listing's identifier โ€” its Nostr d-tag / proxy id
reasonstringNo-Optional free-text reason recorded on the removal event

action="attest"โ€‹

ParameterTypeRequiredDefaultDescription
subjectPubkeystringYes-Pubkey of the agent being reviewed
agreementIdstringYes-Event ID of the agreement this review is for
ratingintYes-Rating from 1โ€“5
contentstringYes-Free-text review content

action="reputation"โ€‹

ParameterTypeRequiredDefaultDescription
pubkeystringYes-Pubkey of the agent to query reputation for
limitintNo20Maximum number of attestations to return

Wallet Configurationโ€‹

Best for users who want USD balance management, BTC price tracking, and easy on/off ramps.

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

Setup:

  1. Create account at https://strike.me
  2. Get API key from https://dashboard.strike.me
  3. Fund your account with BTC
Strike Payment Polling

Strike payments are polled with exponential backoff (1s, 1s, 1s, 2s, 2s, 2s, 4s cap) to minimize API calls while detecting completion quickly.

Available Tools: All tools including L402 (Strike returns preimage via lightning.preImage)


Good for L402 auto-pay. CoinOS, CLINK, and Alby Hub return preimage which is required for L402.

{
"mcpServers": {
"lightning-enable": {
"command": "dotnet",
"args": ["tool", "run", "lightning-enable-mcp"],
"env": {
"NWC_CONNECTION_STRING": "nostr+walletconnect://..."
}
}
}
}

Setup:

  1. Create wallet at https://coinos.io (free, recommended) or https://clink.tools (Nostr)
  2. Go to Settings โ†’ NWC โ†’ Create connection
  3. Enable auto-pay for the connection
  4. Copy connection string Available Tools: All tools including L402 (CoinOS/CLINK confirmed working)

NWC (Nostr Wallet Connect)โ€‹

Best when you hold the keys to your own wallet. L402 support depends on wallet.

{
"mcpServers": {
"lightning-enable": {
"command": "dotnet",
"args": ["tool", "run", "lightning-enable-mcp"],
"env": {
"NWC_CONNECTION_STRING": "nostr+walletconnect://pubkey?relay=wss://relay.example.com&secret=xxx"
}
}
}
}

Setup:

  1. Use a compatible wallet (CoinOS, CLINK, Alby Hub, or Primal)
  2. Create NWC connection in wallet settings
  3. Copy connection string
NWC Connection Timeouts

The MCP server uses tuned WebSocket timeouts for NWC: 3 seconds for the NIP-47 INFO encryption auto-detect, then roughly 30 seconds (.NET) or 60 seconds (Python) waiting for a payment response. If your relay is slow or unreachable, the connection fails gracefully rather than hanging.

L402 Compatibility:

WalletL402 WorksCost
CoinOSโœ… YesFree
CLINKโœ… YesFree (Nostr users)
Alby Hubโœ… YesSelf-host or paid cloud
PrimalโŒ NoFree (no preimage)
CoinOS or CLINK for Free L402

CoinOS and CLINK are completely free and return preimages, so L402 works! Strike also returns preimages. OpenNode and Primal don't return preimages.


Budget Configurationโ€‹

Spending limits are configured in ~/.lightning-enable/config.json (created automatically on first run, or written by setup_wallet):

{
"currency": "USD",
"tiers": {
"autoApprove": 0.10,
"logAndApprove": 1.00,
"formConfirm": 10.00,
"urlConfirm": 100.00
},
"limits": {
"maxPerPayment": 500.00,
"maxPerSession": 100.00
},
"session": {
"cooldownSeconds": 2,
"requireApprovalForFirstPayment": false
},
"confirmation": {
"channel": "stderr"
}
}

(The session values shown are the defaults: a 2-second cooldown between payments, and no forced confirmation on the first payment of a session โ€” set requireApprovalForFirstPayment to true to opt in.)

Approval Tiersโ€‹

Amount (USD)Behavior
โ‰ค $0.10Auto-approved silently
$0.10 - $1.00Approved but logged
$1.00 - $500.00Out-of-band confirmation required (see below)
> $500.00Blocked entirely (maxPerPayment)

Sats-Native Budgetsโ€‹

limits.maxPerPayment / limits.maxPerSession and tiers.autoApprove above are USD, converted to sats at call time from a live BTC price feed. If you'd rather set the ceiling directly in sats โ€” no price feed involved for that comparison โ€” set the sats-native equivalents alongside or instead of the USD ones:

{
"limits": {
"maxPerPaymentSats": 50000,
"maxPerSessionSats": 200000
},
"tiers": {
"autoApproveSats": 1000
}
}

Whichever pair is present for a given check wins for that check; the two are not summed. The system as a whole still fails closed if the BTC price feed is unavailable for any USD-denominated threshold that needs conversion โ€” a sats-native limit has nothing to convert, so it is unaffected by a price-feed outage, but a payment gated by a USD tier is refused (not approved) while the feed is down. budget(action="tighten") (see above) accepts maxPerPaymentSats / maxPerSessionSats for runtime tightening regardless of which pair the operator configured.

Out-of-Band Confirmationโ€‹

When a payment exceeds the auto-approve threshold, the server delivers a confirmation code over one of four channels, set with confirmation.channel in the config file:

confirmation.channelWhere the code goesUse it when
stderr (default)The server's console/stderr โ€” the channel a human operator watching the terminal seesInteractive local use โ€” Claude Code, Claude Desktop, a terminal session
refuseNowhere โ€” the payment is refused outright rather than printed anywhereNon-interactive / hosted contexts where nothing reads stderr, so printing a code there would be silently lost (or worse, readable by the wrong process)
webhookPOSTed to a configured webhook URLA human is notified out-of-band (chat app, pager) rather than watching a terminal
fileWritten to a local file the human can read on their own scheduleHeadless or scheduled runs where no one is watching in real time

LIGHTNING_ENABLE_HOSTED=1 changes the default: when set, and the process is not attached to a TTY, the channel defaults to refuse instead of stderr โ€” because in a hosted, non-interactive context there is no guarantee a human (rather than the very agent process, or something it can read) is the one watching stderr. Set confirmation.channel explicitly to opt back into webhook or file in that environment. In every case the code is never returned in a tool result, so a prompt-injected agent can't read its own code and self-approve.

The flow (channels other than refuse):

  1. The agent calls the payment tool (pay_invoice, access_l402_resource, pay_l402_challenge, or wallet_ops with action="send_onchain"); the response says confirmation is required โ€” without the code.
  2. The server delivers the code over the configured channel, where you read it.
  3. You give the code to the AI, which re-calls the original payment tool with the confirmationNonce (.NET) / confirmation_nonce (Python) parameter. The separate verify_confirmation_code tool only verifies a code โ€” it never executes a payment.

Codes are bound to the exact amount, tool, and destination (invoice / URL / on-chain address) โ€” a code can't be reused for a different payment or redirected to a different destination (v1.12.13). wallet_ops with action="send_onchain" always requires a code (irreversible) and fails closed if the budget service is unavailable.

Why This is AI-Proofโ€‹

  • Config file lives in your home directory, not environment variables
  • The only budget tool, budget, is tighten-only for action="tighten" โ€” it can lower the runtime sats caps but can never raise any limit above your config file
  • Only you can edit the config file
  • Payments above the auto-approve threshold require the out-of-band confirmation code that only the human (or the channel you configured for them) can see โ€” and in a hosted/non-TTY context, LIGHTNING_ENABLE_HOSTED=1 refuses by default rather than guessing at a safe channel

Environment Variables Referenceโ€‹

VariableRequiredDefaultDescription
STRIKE_API_KEYIf using Strike-Strike API key
OPENNODE_API_KEYIf using OpenNode-OpenNode API key
OPENNODE_ENVIRONMENTNoproductionproduction or dev
NWC_CONNECTION_STRINGIf using NWC-Nostr Wallet Connect URI
LND_REST_HOSTIf using LND-LND REST API host
LND_MACAROON_HEXIf using LND-LND admin macaroon in hex
LND_SKIP_TLS_VERIFYNofalseSet true to skip LND TLS verification (development only)
LND_TLS_CERT_PATHNo-Path to LND tls.cert for remote connections (.NET package)
WALLET_PRIORITYNolnd > nwc > strike > opennodeForce a specific wallet when several are configured (e.g., nwc)
LIGHTNING_ENABLE_API_KEYFor l402_producer + some agent_services actions-Lightning Enable API key โ€” required by every l402_producer action, and by the agent_services actions request/publish/unpublish/attest (discover/settle/reputation work without it). No key? create_lightning_enable_account provisions one for ~100 sats over Lightning
LIGHTNING_ENABLE_API_URLNohttps://api.lightningenable.comAPI base URL
L402_REGISTRY_URLNofalls back to LIGHTNING_ENABLE_API_URLRegistry endpoint used by discover_api
LIGHTNING_ENABLE_TOOL_PROFILENostandardlite, standard, or full โ€” see Tool Profiles
LIGHTNING_ENABLE_HOSTEDNounsetSet to 1 in a non-interactive/hosted deployment โ€” changes the out-of-band confirmation default to refuse when the process isn't attached to a TTY. See Out-of-Band Confirmation
L402 Tools

L402 tools are free and don't require an API key or license purchase. Just configure a compatible wallet and all L402 tools are available immediately.


Security Best Practicesโ€‹

  1. Use a dedicated wallet - Never use your main wallet or business funds for AI spending
  2. Configure budget limits - Edit ~/.lightning-enable/config.json before first use
  3. Review payment history - Check receipts (with source="session" or source="durable") after sessions
  4. Rotate API keys - Monthly rotation recommended
  5. Never commit keys - Keep API keys out of version control
  6. Preimage log safety - Preimage values are automatically truncated in logs (first 8 characters only), preventing full preimage exposure in log files or debug output

See AI Spending Security for detailed security guidance.


Troubleshootingโ€‹

"Wallet not configured"โ€‹

Set one of: STRIKE_API_KEY, NWC_CONNECTION_STRING, LND_REST_HOST+LND_MACAROON_HEX, or OPENNODE_API_KEY

"Budget limit exceeded"โ€‹

Payment exceeds your limits. Use budget with action="status" to see current limits, edit config file to adjust.

"Tool not found" after upgradingโ€‹

If a prompt or integration calls an old name like configure_budget or create_l402_challenge directly, either switch it to the new consolidated tool (budget(action="tighten"), l402_producer(action="create"), โ€ฆ) or set LIGHTNING_ENABLE_TOOL_PROFILE=full to keep every legacy name available as a deprecated alias until v3.0.0. See Tool Profiles and Deprecated aliases.

"License required for L402 features" (pre-v1.6.0 only)โ€‹

This error only occurs on versions before v1.6.0. All L402 consumer tools are free in v1.6.0 and later. If you see this error, update your MCP server to the latest version.

"Feature not supported"โ€‹

Some features are wallet-specific (e.g., BTC price is Strike-only). Check the compatibility table above.

"L402 payment succeeded but access failed"โ€‹

Your wallet doesn't return preimage. Use LND, CoinOS, CLINK, Alby Hub, or Strike. OpenNode and Primal don't work for L402 (no preimage return).


Try It: Lightning Enable Storeโ€‹

The Lightning Enable Store is a live L402-powered web store where AI agents can purchase physical merchandise using Bitcoin Lightning payments.

Ask Claude: "Buy me a Lightning Enable t-shirt from store.lightningenable.com"

This demonstrates the full L402 flow:

  1. Browse catalog โ€” GET /api/store/catalog
  2. Checkout โ€” POST /api/store/checkout (returns HTTP 402 with invoice + macaroon)
  3. Pay invoice โ€” Use pay_invoice with the BOLT11 string
  4. Claim order โ€” POST /api/store/claim with L402 credential

Next Stepsโ€‹