402-mcp 3.0.0 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -9,6 +9,72 @@ L402 + x402 client MCP that gives AI agents economic agency. Discover, pay for,
9
9
 
10
10
  Works with **any L402-compliant server** (toll-booth, Aperture, or any future implementation), with bonus features when talking to a [toll-booth](https://github.com/TheCryptoDonkey/toll-booth) instance.
11
11
 
12
+ ## Architecture
13
+
14
+ ```mermaid
15
+ graph TB
16
+ Agent["AI Agent<br/>(Claude, Cursor, etc.)"]
17
+ MCP["402-mcp<br/>MCP Server"]
18
+
19
+ subgraph Wallets["Payment Rails"]
20
+ NWC["NWC<br/>(Lightning)"]
21
+ Cashu["Cashu<br/>(Ecash)"]
22
+ Human["Human-in-the-loop<br/>(QR code)"]
23
+ end
24
+
25
+ subgraph Storage["Local Storage"]
26
+ Creds["Credential Store<br/>(AES-256-GCM)"]
27
+ Tokens["Cashu Token Store"]
28
+ end
29
+
30
+ subgraph Servers["Any L402 Server"]
31
+ TB["toll-booth"]
32
+ Aperture["Aperture"]
33
+ Other["Any L402<br/>implementation"]
34
+ end
35
+
36
+ Nostr["Nostr Relays<br/>(Service Discovery)"]
37
+
38
+ Agent <-->|"MCP protocol<br/>(stdio / HTTP)"| MCP
39
+ MCP --> NWC
40
+ MCP --> Cashu
41
+ MCP --> Human
42
+ MCP <--> Creds
43
+ MCP <--> Tokens
44
+ MCP <-->|"HTTP + L402"| TB
45
+ MCP <-->|"HTTP + L402"| Aperture
46
+ MCP <-->|"HTTP + L402"| Other
47
+ MCP <-->|"kind 31402"| Nostr
48
+ ```
49
+
50
+ ## Payment flow
51
+
52
+ ```mermaid
53
+ sequenceDiagram
54
+ participant Agent as AI Agent
55
+ participant MCP as 402-mcp
56
+ participant API as L402 API
57
+ participant Wallet as Wallet (NWC/Cashu)
58
+
59
+ Agent->>MCP: l402_discover(url)
60
+ MCP->>API: GET /endpoint
61
+ API-->>MCP: 402 + invoice + macaroon
62
+ MCP-->>Agent: price: 10 sats, server: toll-booth
63
+
64
+ Agent->>Agent: Reason about pricing
65
+
66
+ Agent->>MCP: l402_fetch(url)
67
+ MCP->>API: GET /endpoint
68
+ API-->>MCP: 402 + invoice + macaroon
69
+ MCP->>MCP: Amount ≤ MAX_AUTO_PAY_SATS?
70
+ MCP->>Wallet: Pay invoice
71
+ Wallet-->>MCP: preimage
72
+ MCP->>MCP: Store credential
73
+ MCP->>API: GET /endpoint + Authorization: L402
74
+ API-->>MCP: 200 OK + data
75
+ MCP-->>Agent: Response data + balance
76
+ ```
77
+
12
78
  ## Quick start
13
79
 
14
80
  ```bash
@@ -57,6 +123,7 @@ Add to your MCP configuration:
57
123
  | `l402_pay` | Pay a specific invoice (NWC, Cashu, or human-in-the-loop) |
58
124
  | `l402_credentials` | List stored credentials and cached balances |
59
125
  | `l402_balance` | Check cached credit balance for a server |
126
+ | `l402_search` | Discover L402 services on Nostr relays (kind 31402 announcements) |
60
127
 
61
128
  ### toll-booth extensions
62
129
 
@@ -65,8 +132,36 @@ Add to your MCP configuration:
65
132
  | `l402_buy_credits` | Browse and purchase volume discount tiers |
66
133
  | `l402_redeem_cashu` | Redeem Cashu tokens directly (avoids Lightning round-trip) |
67
134
 
135
+ ## Service discovery
136
+
137
+ Agents can discover paid APIs without knowing URLs upfront. `l402_search` queries Nostr relays for kind 31402 service announcements — the decentralised registry for L402 services.
138
+
139
+ ```mermaid
140
+ sequenceDiagram
141
+ participant Agent as AI Agent
142
+ participant MCP as 402-mcp
143
+ participant Relay as Nostr Relays
144
+
145
+ Agent->>MCP: l402_search("routing")
146
+ MCP->>Relay: Subscribe kind 31402
147
+ Relay-->>MCP: Matching service events
148
+ MCP-->>Agent: Services with URLs, pricing, capabilities
149
+ Agent->>MCP: l402_discover(service_url)
150
+ Note over Agent: Continue with payment flow...
151
+ ```
152
+
68
153
  ## Payment methods
69
154
 
155
+ ```mermaid
156
+ graph TD
157
+ Pay["Pay Invoice"]
158
+ Pay --> NWC{"NWC configured?"}
159
+ NWC -->|Yes| NWCPay["Pay via Lightning wallet<br/>(fully autonomous)"]
160
+ NWC -->|No| CashuQ{"Cashu tokens<br/>available?"}
161
+ CashuQ -->|Yes| CashuPay["Melt ecash tokens<br/>(fully autonomous)"]
162
+ CashuQ -->|No| HumanPay["Present QR code<br/>(human pays)"]
163
+ ```
164
+
70
165
  Three payment rails, tried in priority order:
71
166
 
72
167
  1. **NWC** (Nostr Wallet Connect) - fully autonomous; pays from your connected wallet
@@ -77,6 +172,17 @@ The agent can override the method per-call, or you can configure only the method
77
172
 
78
173
  ## How it works
79
174
 
175
+ ```mermaid
176
+ graph LR
177
+ A["1. l402_config()"] --> B["2. l402_discover(url)"]
178
+ B --> C["3. Agent reasons<br/>about pricing"]
179
+ C --> D["4. l402_buy_credits()<br/>or l402_fetch()"]
180
+ D --> E["5. l402_fetch(url)<br/>with credentials"]
181
+ E --> F["6. Data returned<br/>+ balance cached"]
182
+ ```
183
+
184
+ **Example session:**
185
+
80
186
  ```
81
187
  Agent: "I need routing data from routing.trotters.cc"
82
188
 
@@ -125,7 +231,8 @@ Use Lightning Labs' tools if you want agents that **run their own Lightning node
125
231
  |---------|------|
126
232
  | [toll-booth](https://github.com/TheCryptoDonkey/toll-booth) | Payment-rail agnostic HTTP 402 middleware |
127
233
  | [satgate](https://github.com/TheCryptoDonkey/satgate) | Pay-per-token AI inference proxy (built on toll-booth) |
128
- | **[402-mcp](https://github.com/TheCryptoDonkey/402-mcp)** | **MCP client - AI agents discover, pay, and consume L402 + x402 APIs** |
234
+ | **[402-mcp](https://github.com/TheCryptoDonkey/402-mcp)** | **MCP client AI agents discover, pay, and consume L402 + x402 APIs** |
235
+ | [402-announce](https://github.com/TheCryptoDonkey/402-announce) | Publish L402 services on Nostr for decentralised discovery |
129
236
 
130
237
  ---
131
238
 
@@ -1,2 +1,7 @@
1
1
  import type { SearchDeps } from './search.js';
2
+ /** Optional tag filters to pass to relays, reducing bandwidth by filtering server-side. */
3
+ export interface SubscribeFilters {
4
+ '#t'?: string[];
5
+ '#pmi'?: string[];
6
+ }
2
7
  export declare function createNostrSubscriber(): SearchDeps['subscribeEvents'];
@@ -5,7 +5,7 @@
5
5
  */
6
6
  const MAX_EVENTS = 1000;
7
7
  export function createNostrSubscriber() {
8
- return async (relays, kinds, timeout) => {
8
+ return async (relays, kinds, timeout, filters) => {
9
9
  const { Relay } = await import('nostr-tools/relay');
10
10
  const { verifyEvent } = await import('nostr-tools/pure');
11
11
  const events = [];
@@ -21,7 +21,12 @@ export function createNostrSubscriber() {
21
21
  ]);
22
22
  connections.push(relay);
23
23
  return new Promise((resolve) => {
24
- const sub = relay.subscribe([{ kinds }], {
24
+ const filter = { kinds };
25
+ if (filters?.['#t']?.length)
26
+ filter['#t'] = filters['#t'];
27
+ if (filters?.['#pmi']?.length)
28
+ filter['#pmi'] = filters['#pmi'];
29
+ const sub = relay.subscribe([filter], {
25
30
  onevent: (event) => {
26
31
  if (events.length < MAX_EVENTS && verifyEvent(event)) {
27
32
  events.push(event);
@@ -1 +1 @@
1
- {"version":3,"file":"nostr-subscribe.js","sourceRoot":"","sources":["../../src/tools/nostr-subscribe.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,MAAM,UAAU,GAAG,IAAI,CAAA;AAEvB,MAAM,UAAU,qBAAqB;IACnC,OAAO,KAAK,EAAE,MAAgB,EAAE,KAAe,EAAE,OAAe,EAAyB,EAAE;QACzF,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,mBAAmB,CAAC,CAAA;QACnD,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAA;QACxD,MAAM,MAAM,GAAiB,EAAE,CAAA;QAC/B,MAAM,WAAW,GAA6B,EAAE,CAAA;QAEhD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CACtC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;YACvB,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC1D,OAAM;YACR,CAAC;YAED,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC;oBAC/B,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;oBAClB,IAAI,OAAO,CAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAC/B,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,CACvD;iBACF,CAAC,CAAA;gBACF,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;gBAEvB,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;oBACnC,MAAM,GAAG,GAAG,KAAK,CAAC,SAAS,CACzB,CAAC,EAAE,KAAK,EAAE,CAAC,EACX;wBACE,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;4BACjB,IAAI,MAAM,CAAC,MAAM,GAAG,UAAU,IAAI,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;gCACrD,MAAM,CAAC,IAAI,CAAC,KAAmB,CAAC,CAAA;4BAClC,CAAC;wBACH,CAAC;wBACD,MAAM,EAAE,GAAG,EAAE;4BACX,GAAG,CAAC,KAAK,EAAE,CAAA;4BACX,OAAO,EAAE,CAAA;wBACX,CAAC;qBACF,CACF,CAAA;oBAED,+CAA+C;oBAC/C,UAAU,CAAC,GAAG,EAAE;wBACd,GAAG,CAAC,KAAK,EAAE,CAAA;wBACX,OAAO,EAAE,CAAA;oBACX,CAAC,EAAE,OAAO,CAAC,CAAA;gBACb,CAAC,CAAC,CAAA;YACJ,CAAC;YAAC,MAAM,CAAC;gBACP,mCAAmC;YACrC,CAAC;QACH,CAAC,CAAC,CACH,CAAA;QAED,8BAA8B;QAC9B,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;YAC/B,IAAI,CAAC;gBACH,IAAI,CAAC,KAAK,EAAE,CAAA;YACd,CAAC;YAAC,MAAM,CAAC;gBACP,sBAAsB;YACxB,CAAC;QACH,CAAC;QAED,0BAA0B;QAC1B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAA;QAC9B,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;YACzB,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;gBAAE,OAAO,KAAK,CAAA;YAChC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;YACd,OAAO,IAAI,CAAA;QACb,CAAC,CAAC,CAAA;IACJ,CAAC,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"nostr-subscribe.js","sourceRoot":"","sources":["../../src/tools/nostr-subscribe.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,8 @@
1
1
  import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
2
  import type { NostrEvent } from 'nostr-tools/core';
3
+ import type { SubscribeFilters } from './nostr-subscribe.js';
3
4
  export interface SearchDeps {
4
- subscribeEvents: (relays: string[], kinds: number[], timeout: number) => Promise<NostrEvent[]>;
5
+ subscribeEvents: (relays: string[], kinds: number[], timeout: number, filters?: SubscribeFilters) => Promise<NostrEvent[]>;
5
6
  }
6
7
  export interface ParsedService {
7
8
  name: string | undefined;
@@ -50,9 +50,15 @@ export async function handleSearch(args, deps) {
50
50
  const timeout = args.timeout ?? 5000;
51
51
  const maxResults = args.maxResults ?? 20;
52
52
  const queryLower = args.query.toLowerCase();
53
- const events = await deps.subscribeEvents(relays, [KIND_L402_ANNOUNCE], timeout);
53
+ // Build relay-side tag filters — relays handle topic and payment method filtering
54
+ const relayFilters = {};
55
+ if (args.topics?.length)
56
+ relayFilters['#t'] = args.topics;
57
+ if (args.paymentMethod)
58
+ relayFilters['#pmi'] = [args.paymentMethod];
59
+ const events = await deps.subscribeEvents(relays, [KIND_L402_ANNOUNCE], timeout, relayFilters);
54
60
  let services = events.map(parseAnnounceEvent);
55
- // Filter by query text — match against name, about, and capability descriptions
61
+ // Filter by query text — relays cannot do substring search so this remains client-side
56
62
  if (queryLower) {
57
63
  services = services.filter(svc => {
58
64
  const searchable = [
@@ -64,15 +70,6 @@ export async function handleSearch(args, deps) {
64
70
  return searchable.includes(queryLower);
65
71
  });
66
72
  }
67
- // Filter by payment method
68
- if (args.paymentMethod) {
69
- services = services.filter(svc => svc.paymentMethods.includes(args.paymentMethod));
70
- }
71
- // Filter by topics — service must have at least one matching topic
72
- if (args.topics && args.topics.length > 0) {
73
- const topicSet = new Set(args.topics.map(t => t.toLowerCase()));
74
- services = services.filter(svc => svc.topics.some(t => topicSet.has(t.toLowerCase())));
75
- }
76
73
  // Limit results
77
74
  const results = services.slice(0, maxResults);
78
75
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/tools/search.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/tools/search.ts"],"names":[],"mappings":"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"}
package/llms-full.txt ADDED
@@ -0,0 +1,399 @@
1
+ # 402-mcp — Full Technical Reference
2
+
3
+ > For a concise overview, see [llms.txt](llms.txt). This document provides the complete technical reference for integrating with, building on, or contributing to 402-mcp.
4
+
5
+ ## What is 402-mcp?
6
+
7
+ 402-mcp is an MCP (Model Context Protocol) server that gives AI agents economic agency — the ability to discover, pay for, and consume any L402 or x402 payment-gated API without human registration, API keys, or middlemen.
8
+
9
+ It implements the client side of the L402 protocol: when an API responds with HTTP 402 (Payment Required), 402-mcp automatically parses the challenge, pays the Lightning invoice, stores the credential, and retries the request — all within a single tool call from the agent's perspective.
10
+
11
+ ## Architecture Overview
12
+
13
+ ```
14
+ ┌─────────────────────────────────────────────────────────────┐
15
+ │ AI Agent (Claude, Cursor, GPT, custom) │
16
+ │ Communicates via MCP protocol (stdio or HTTP transport) │
17
+ └──────────────────────┬──────────────────────────────────────┘
18
+ │ MCP tool calls
19
+ ┌──────────────────────▼──────────────────────────────────────┐
20
+ │ 402-mcp MCP Server │
21
+ │ │
22
+ │ ┌──────────┐ ┌──────────┐ ┌─────────────┐ │
23
+ │ │ Tools │ │ Wallets │ │ Stores │ │
24
+ │ │ │ │ │ │ │ │
25
+ │ │ config │ │ NWC │ │ Credentials │ │
26
+ │ │ discover │ │ Cashu │ │ (AES-256) │ │
27
+ │ │ fetch │ │ Human │ │ │ │
28
+ │ │ pay │ │ │ │ Cashu │ │
29
+ │ │ creds │ │ │ │ Tokens │ │
30
+ │ │ balance │ │ │ │ │ │
31
+ │ │ search │ │ │ │ │ │
32
+ │ │ buy_cred │ │ │ │ │ │
33
+ │ │ redeem │ │ │ │ │ │
34
+ │ └──────────┘ └──────────┘ └─────────────┘ │
35
+ │ │
36
+ │ ┌──────────────┐ ┌──────────────┐ ┌───────────────┐ │
37
+ │ │ L402 Protocol│ │ Resilient │ │ Spend │ │
38
+ │ │ parse, detect│ │ Fetch │ │ Tracker │ │
39
+ │ │ cache, bolt11│ │ SSRF, retry │ │ atomic caps │ │
40
+ │ └──────────────┘ └──────────────┘ └───────────────┘ │
41
+ └──────────────────────┬──────────────────────────────────────┘
42
+ │ HTTP + L402 / Nostr
43
+ ┌─────────────┼─────────────┐
44
+ ▼ ▼ ▼
45
+ ┌─────────┐ ┌──────────┐ ┌──────────┐
46
+ │toll-booth│ │ Aperture │ │ Nostr │
47
+ │ server │ │ server │ │ Relays │
48
+ └─────────┘ └──────────┘ └──────────┘
49
+ ```
50
+
51
+ ## Source Structure
52
+
53
+ ```
54
+ src/
55
+ index.ts # Entry point: config, wiring, transport setup
56
+ config.ts # Environment variable parsing with validation
57
+ spend-tracker.ts # Atomic rolling-window spend limiter
58
+ tools/
59
+ config.ts # l402_config — introspect capabilities
60
+ discover.ts # l402_discover — probe pricing without paying
61
+ fetch.ts # l402_fetch — full L402 payment flow
62
+ pay.ts # l402_pay — explicit invoice payment
63
+ credentials.ts # l402_credentials — list stored credentials
64
+ balance.ts # l402_balance — check cached credit balance
65
+ search.ts # l402_search — discover services on Nostr
66
+ buy-credits.ts # l402_buy_credits — toll-booth credit tiers
67
+ redeem-cashu.ts # l402_redeem_cashu — direct ecash redemption
68
+ nostr-subscribe.ts # Nostr relay subscription for search
69
+ safe-error.ts # Error sanitisation (strips internal details)
70
+ safe-headers.ts # Header sanitisation (strips auth tokens)
71
+ wallet/
72
+ types.ts # WalletProvider interface
73
+ resolve.ts # Priority-ordered wallet resolution
74
+ nwc.ts # NWC (Nostr Wallet Connect) implementation
75
+ cashu.ts # Cashu ecash melt implementation
76
+ human.ts # Human-in-the-loop (QR code + polling)
77
+ l402/
78
+ parse.ts # Parse WWW-Authenticate L402 challenges
79
+ detect.ts # Detect toll-booth vs generic L402 servers
80
+ bolt11.ts # Decode BOLT11 invoices (amount extraction)
81
+ challenge-cache.ts # Cache parsed challenges for l402_pay
82
+ store/
83
+ credentials.ts # Encrypted credential persistence (JSON)
84
+ cashu-tokens.ts # Cashu token store (add/remove/balance)
85
+ encryption.ts # AES-256-GCM encryption (keychain or file key)
86
+ fetch/
87
+ resilient-fetch.ts # Timeout, retry, response size limits
88
+ ssrf-guard.ts # Block requests to private/internal IPs
89
+ errors.ts # Fetch error types
90
+ tests/ # Mirrors src/ structure
91
+ e2e/ # Integration tests against in-process toll-booth
92
+ ```
93
+
94
+ ## Complete Tool Reference
95
+
96
+ ### l402_config
97
+
98
+ **Purpose:** Introspect the agent's payment capabilities and current configuration.
99
+
100
+ **Parameters:** None.
101
+
102
+ **Returns:**
103
+ - `nwcConfigured` (boolean) — whether an NWC wallet URI is set
104
+ - `cashuConfigured` (boolean) — whether Cashu tokens are loaded with balance > 0
105
+ - `cashuBalanceSats` (number) — total Cashu token balance in satoshis
106
+ - `maxAutoPaySats` (number) — per-payment safety cap
107
+ - `credentialCount` (number) — number of stored L402 credentials
108
+
109
+ **When to use:** Call first in any session to understand what the agent can do autonomously.
110
+
111
+ ---
112
+
113
+ ### l402_discover
114
+
115
+ **Purpose:** Probe an endpoint to discover pricing without paying.
116
+
117
+ **Parameters:**
118
+ - `url` (string, required) — the endpoint to probe
119
+ - `method` (string, optional) — HTTP method (default: GET)
120
+ - `headers` (object, optional) — additional headers
121
+
122
+ **Returns:**
123
+ - `amountSats` (number) — price in satoshis
124
+ - `server` (string) — detected server type ("toll-booth" or null)
125
+ - `hasTiers` (boolean) — whether credit tiers are available
126
+ - `challenge` — cached for subsequent `l402_pay`
127
+
128
+ **When to use:** Before committing to a purchase, so the agent can reason about value.
129
+
130
+ ---
131
+
132
+ ### l402_fetch
133
+
134
+ **Purpose:** Make an HTTP request with automatic L402 payment handling.
135
+
136
+ **Parameters:**
137
+ - `url` (string, required) — the endpoint to fetch
138
+ - `method` (string, optional) — HTTP method (default: GET)
139
+ - `headers` (object, optional) — additional headers
140
+ - `body` (string, optional) — request body
141
+ - `paymentMethod` (string, optional) — force a specific payment rail
142
+
143
+ **Behaviour:**
144
+ 1. Checks for existing credential for the origin
145
+ 2. Makes the HTTP request (with credential if available)
146
+ 3. If 402 received: parses challenge, checks amount against `MAX_AUTO_PAY_SATS` and rolling spend cap
147
+ 4. If within budget: pays invoice, stores credential, retries request
148
+ 5. If over budget: returns the price and asks for human approval
149
+ 6. Returns response body, status, headers, and remaining credit balance
150
+
151
+ **When to use:** Primary tool for consuming L402 APIs. Handles the entire flow.
152
+
153
+ ---
154
+
155
+ ### l402_pay
156
+
157
+ **Purpose:** Pay a specific Lightning invoice.
158
+
159
+ **Parameters:**
160
+ - `invoice` (string, required) — BOLT11 invoice to pay
161
+ - `paymentMethod` (string, optional) — force a specific payment rail
162
+ - `challengeId` (string, optional) — ID from a previous `l402_discover` to associate the payment
163
+
164
+ **Returns:**
165
+ - `paid` (boolean)
166
+ - `preimage` (string) — payment proof
167
+ - `method` (string) — which wallet paid
168
+
169
+ **When to use:** When you have an invoice from a non-L402 source, or want explicit control.
170
+
171
+ ---
172
+
173
+ ### l402_credentials
174
+
175
+ **Purpose:** List all stored L402 credentials.
176
+
177
+ **Parameters:** None.
178
+
179
+ **Returns:** Array of credentials with:
180
+ - `origin` — server origin
181
+ - `creditBalance` — cached balance (if known)
182
+ - `server` — detected server type
183
+ - `storedAt` / `lastUsed` — timestamps
184
+
185
+ **When to use:** Auditing spend, checking which servers have been paid.
186
+
187
+ ---
188
+
189
+ ### l402_balance
190
+
191
+ **Purpose:** Check cached credit balance for a server.
192
+
193
+ **Parameters:**
194
+ - `url` (string, required) — server URL to check
195
+
196
+ **Returns:**
197
+ - `balance` (number | null) — credits remaining, or null if unknown
198
+
199
+ **When to use:** Before calling `l402_fetch` to confirm sufficient balance.
200
+
201
+ ---
202
+
203
+ ### l402_search
204
+
205
+ **Purpose:** Discover L402 services on Nostr relays.
206
+
207
+ **Parameters:**
208
+ - `query` (string, required) — search text to match against service names, descriptions, capabilities
209
+ - `relays` (string[], optional) — Nostr relay URLs (defaults to damus, primal, nos.lol)
210
+ - `topics` (string[], optional) — filter by topic tags (e.g. ["ai", "data"])
211
+ - `paymentMethod` (string, optional) — filter by payment method (e.g. "bitcoin-lightning-bolt11")
212
+ - `maxResults` (number, optional) — max results (default 20)
213
+ - `timeout` (number, optional) — relay timeout in ms (default 5000)
214
+
215
+ **Returns:** Array of services with:
216
+ - `name`, `url`, `about` — service metadata
217
+ - `pricing` — array of `{ capability, amount, unit }`
218
+ - `paymentMethods` — supported payment methods
219
+ - `topics` — topic tags
220
+ - `capabilities` — array of `{ name, description }`
221
+
222
+ **When to use:** When the agent needs a paid API but doesn't know the URL. Searches the decentralised Nostr network for kind 31402 service announcements.
223
+
224
+ ---
225
+
226
+ ### l402_buy_credits (toll-booth only)
227
+
228
+ **Purpose:** Browse and purchase volume discount credit tiers.
229
+
230
+ **Parameters:**
231
+ - `url` (string, required) — toll-booth server URL
232
+ - `amountSats` (number, optional) — specific tier to purchase
233
+ - `paymentMethod` (string, optional) — force a specific payment rail
234
+
235
+ **Behaviour:** Fetches available tiers, purchases the specified tier, stores the credential with the credit balance.
236
+
237
+ **When to use:** When multiple requests are needed — buying a tier upfront is cheaper than paying per-request.
238
+
239
+ ---
240
+
241
+ ### l402_redeem_cashu (toll-booth only)
242
+
243
+ **Purpose:** Redeem Cashu ecash tokens directly with the server.
244
+
245
+ **Parameters:**
246
+ - `url` (string, required) — toll-booth server URL
247
+ - `token` (string, required) — Cashu token to redeem
248
+
249
+ **Behaviour:** Sends the raw Cashu token to the toll-booth's redemption endpoint. The server credits the balance immediately without a Lightning round-trip.
250
+
251
+ **When to use:** When both agent and server support Cashu — faster and cheaper than melting tokens to pay an invoice.
252
+
253
+ ## L402 Protocol Flow
254
+
255
+ The L402 protocol is an extension of HTTP 402 (Payment Required):
256
+
257
+ 1. **Client** sends a request to a protected endpoint
258
+ 2. **Server** responds with `402 Payment Required` and headers:
259
+ - `WWW-Authenticate: L402 macaroon="<base64>", invoice="<bolt11>"`
260
+ 3. **Client** decodes the BOLT11 invoice, pays it via Lightning, receives a preimage
261
+ 4. **Client** retries the request with:
262
+ - `Authorization: L402 <base64-macaroon>:<hex-preimage>`
263
+ 5. **Server** validates the macaroon + preimage and returns the data
264
+
265
+ 402-mcp handles steps 2–5 automatically within `l402_fetch`.
266
+
267
+ ## Wallet Priority and Resolution
268
+
269
+ Wallets are tried in order: NWC → Cashu → Human. The first wallet that succeeds is used.
270
+
271
+ | Wallet | Autonomy | Requirements | Speed |
272
+ |--------|----------|-------------|-------|
273
+ | NWC | Fully autonomous | `NWC_URI` env var pointing to a Lightning wallet | ~2-5 seconds |
274
+ | Cashu | Fully autonomous | `CASHU_TOKENS` file with ecash tokens | ~3-8 seconds |
275
+ | Human | Requires human | None — always available as fallback | Minutes |
276
+
277
+ The agent can force a specific method per-call using the `paymentMethod` parameter.
278
+
279
+ ## Safety and Spend Limits
280
+
281
+ ### Per-payment cap
282
+
283
+ `MAX_AUTO_PAY_SATS` (default: 1000) caps any single payment. If an invoice exceeds this:
284
+ - The agent is told the price and asked to seek human approval
285
+ - The human wallet (QR code) is used for the actual payment
286
+ - The credential is stored normally after payment
287
+
288
+ ### Rolling spend cap
289
+
290
+ `MAX_SPEND_PER_MINUTE_SATS` (default: 10000) caps total spend in any 60-second window. This prevents:
291
+ - Rapid successive small payments exceeding a total budget
292
+ - Runaway loops where the agent keeps buying credits
293
+ - Both caps use atomic `tryRecord()` to prevent TOCTOU race conditions
294
+
295
+ ### SSRF Protection
296
+
297
+ All outbound HTTP requests pass through an SSRF guard:
298
+ - Blocks requests to private IP ranges (10.x, 172.16-31.x, 192.168.x, 127.x, ::1)
299
+ - Blocks requests to link-local, loopback, and metadata service IPs
300
+ - `SSRF_ALLOW_PRIVATE=true` disables this for local development only
301
+
302
+ ### Credential Security
303
+
304
+ - Credentials encrypted with AES-256-GCM
305
+ - Encryption key stored in OS keychain (macOS Keychain, Windows Credential Vault, Linux Secret Service) when available
306
+ - Falls back to file-based key at `~/.402-mcp/encryption.key` with a console warning
307
+ - Preimages validated as hex before storage to prevent header injection
308
+ - Credential store path must be within the home directory (path traversal protection)
309
+
310
+ ## Transport Modes
311
+
312
+ ### stdio (default)
313
+
314
+ Standard MCP transport — used by Claude Desktop, Cursor, and most MCP clients. The server reads JSON-RPC from stdin and writes to stdout.
315
+
316
+ ```bash
317
+ npx 402-mcp
318
+ ```
319
+
320
+ ### HTTP
321
+
322
+ StreamableHTTP transport for network access. Useful for remote agents, multi-client setups, or deployment behind a reverse proxy.
323
+
324
+ ```bash
325
+ TRANSPORT=http PORT=3402 npx 402-mcp
326
+ ```
327
+
328
+ HTTP transport includes:
329
+ - Rate limiting: 100 requests per 60 seconds per IP
330
+ - Security headers: CSP, X-Frame-Options, X-Content-Type-Options, Cache-Control
331
+ - Loopback-only binding by default (`BIND_ADDRESS=127.0.0.1`)
332
+ - Health endpoint at `GET /health`
333
+ - Graceful shutdown on SIGTERM/SIGINT
334
+
335
+ ## Configuration Reference
336
+
337
+ | Variable | Default | Description |
338
+ |----------|---------|-------------|
339
+ | `NWC_URI` | — | Nostr Wallet Connect URI for autonomous Lightning payments. Cleared from env after reading. |
340
+ | `CASHU_TOKENS` | — | Path to Cashu token store file. Must be within home directory. |
341
+ | `MAX_AUTO_PAY_SATS` | 1000 | Per-payment safety cap (satoshis). 0 disables autonomous payments. |
342
+ | `MAX_SPEND_PER_MINUTE_SATS` | 10000 | Rolling 60-second spend cap (satoshis). |
343
+ | `CREDENTIAL_STORE` | `~/.402-mcp/credentials.json` | Path to encrypted credential store. Must be within home directory. |
344
+ | `TRANSPORT` | `stdio` | Transport mode: `stdio` or `http`. |
345
+ | `PORT` | 3402 | HTTP server port (when `TRANSPORT=http`). |
346
+ | `BIND_ADDRESS` | `127.0.0.1` | HTTP bind address. Warning emitted for non-loopback addresses. |
347
+ | `CORS_ORIGIN` | disabled | CORS origin for HTTP transport. |
348
+ | `FETCH_TIMEOUT_MS` | 30000 | HTTP request timeout in milliseconds. |
349
+ | `FETCH_MAX_RETRIES` | 2 | Maximum retry attempts for failed requests. Money-mutating POSTs use 0. |
350
+ | `FETCH_MAX_RESPONSE_BYTES` | 10485760 | Maximum response body size (10 MB). |
351
+ | `HUMAN_PAY_TIMEOUT_S` | 600 | Timeout for human payment (seconds). |
352
+ | `HUMAN_PAY_POLL_S` | 3 | Initial polling interval for human payment (seconds). |
353
+ | `SSRF_ALLOW_PRIVATE` | false | Allow requests to private IP ranges. Local development only. |
354
+ | `NODE_TLS_REJECT_UNAUTHORIZED` | — | Warning emitted if set to "0" (disables TLS validation). |
355
+
356
+ ## Ecosystem
357
+
358
+ | Project | Role | URL |
359
+ |---------|------|-----|
360
+ | **402-mcp** | MCP client — AI agents discover, pay, and consume L402 APIs | https://github.com/TheCryptoDonkey/402-mcp |
361
+ | **toll-booth** | L402 payment middleware for any Node.js server | https://github.com/TheCryptoDonkey/toll-booth |
362
+ | **satgate** | Pay-per-token AI inference proxy (built on toll-booth) | https://github.com/TheCryptoDonkey/satgate |
363
+ | **402-announce** | Publish L402 services on Nostr for decentralised discovery | https://github.com/TheCryptoDonkey/402-announce |
364
+
365
+ ## Integration Patterns
366
+
367
+ ### Agent discovers and consumes a paid API
368
+
369
+ ```
370
+ 1. l402_config() → Understand capabilities
371
+ 2. l402_search("routing") → Find services on Nostr
372
+ 3. l402_discover(service_url) → Check pricing
373
+ 4. l402_fetch(service_url, ...) → Pay and consume
374
+ ```
375
+
376
+ ### Agent buys credits for repeated access
377
+
378
+ ```
379
+ 1. l402_discover(url) → Detect toll-booth, check tiers
380
+ 2. l402_buy_credits(url, 500) → Buy 500-sat tier (555 credits)
381
+ 3. l402_fetch(url, ...) × N → Use credits (no payment per-request)
382
+ 4. l402_balance(url) → Check remaining credits
383
+ ```
384
+
385
+ ### Agent redeems Cashu tokens directly
386
+
387
+ ```
388
+ 1. l402_discover(url) → Confirm toll-booth server
389
+ 2. l402_redeem_cashu(url, token) → Direct ecash redemption
390
+ 3. l402_fetch(url, ...) → Use credits from redemption
391
+ ```
392
+
393
+ ### Agent with no wallet (human-in-the-loop)
394
+
395
+ ```
396
+ 1. l402_fetch(url) → 402 received, amount shown
397
+ 2. Agent presents QR code to user → Human pays via wallet app
398
+ 3. Poll detects payment → Credential stored, data returned
399
+ ```
package/llms.txt ADDED
@@ -0,0 +1,148 @@
1
+ # 402-mcp
2
+
3
+ > 402-mcp is an MCP server that gives AI agents economic agency — the ability to discover, pay for, and consume any L402 or x402 payment-gated API without human registration, API keys, or middlemen. It speaks the L402 protocol natively, carries its own payment methods, and makes autonomous purchasing decisions within human-set safety limits.
4
+
5
+ 402-mcp is protocol-loyal: it works with any L402-compliant server (toll-booth, Aperture, or any conforming implementation), not just a specific vendor's stack. Bonus features activate automatically when talking to a toll-booth server. Three payment rails are supported — NWC (Nostr Wallet Connect), Cashu ecash, and human-in-the-loop — tried in that priority order so the agent picks the most autonomous option available.
6
+
7
+ Agents can also discover paid APIs without knowing URLs upfront. The `l402_search` tool queries Nostr relays for kind 31402 service announcements — a decentralised registry of L402-enabled services.
8
+
9
+ ## Getting Started
10
+
11
+ Run instantly with no configuration required:
12
+
13
+ ```bash
14
+ npx 402-mcp
15
+ ```
16
+
17
+ For HTTP transport (useful for remote agents or multi-client setups):
18
+
19
+ ```bash
20
+ TRANSPORT=http npx 402-mcp
21
+ ```
22
+
23
+ ### Claude Desktop / Cursor
24
+
25
+ Add to your MCP configuration:
26
+
27
+ ```json
28
+ {
29
+ "mcpServers": {
30
+ "l402": {
31
+ "command": "npx",
32
+ "args": ["402-mcp"],
33
+ "env": {
34
+ "NWC_URI": "nostr+walletconnect://...",
35
+ "MAX_AUTO_PAY_SATS": "1000"
36
+ }
37
+ }
38
+ }
39
+ }
40
+ ```
41
+
42
+ ### Configuration
43
+
44
+ | Variable | Default | Description |
45
+ |----------|---------|-------------|
46
+ | `NWC_URI` | — | Nostr Wallet Connect URI for autonomous Lightning payments |
47
+ | `CASHU_TOKENS` | — | Path to Cashu token store file |
48
+ | `MAX_AUTO_PAY_SATS` | 1000 | Safety cap; payments above this require human confirmation |
49
+ | `MAX_SPEND_PER_MINUTE_SATS` | 10000 | Rolling 60-second spend cap across all payments |
50
+ | `CREDENTIAL_STORE` | `~/.402-mcp/credentials.json` | Persistent macaroon/credential storage |
51
+ | `TRANSPORT` | `stdio` | Transport mode: `stdio` or `http` |
52
+ | `PORT` | 3402 | HTTP server port (when `TRANSPORT=http`) |
53
+
54
+ ## Key Concepts
55
+
56
+ - **L402** — an HTTP payment protocol where a server responds to unauthenticated requests with HTTP 402, a Lightning invoice, and a macaroon. The client pays the invoice, then sends `Authorization: L402 <macaroon>:<preimage>` to access the API.
57
+ - **Economic agency** — the agent discovers a service, reads the price, pays the invoice, and retrieves the data, all within a single tool call. No human registration required.
58
+ - **Safety cap** — `MAX_AUTO_PAY_SATS` sets the maximum any single autonomous payment can be. Above this limit, the agent asks for human approval. A rolling 60-second spend cap (`MAX_SPEND_PER_MINUTE_SATS`) prevents runaway spending.
59
+ - **Credential store** — paid macaroons are persisted locally and encrypted with AES-256-GCM. Subsequent requests to the same server reuse credentials rather than paying again.
60
+ - **Credit balance** — many L402 servers (including toll-booth) grant a credit balance after payment. 402-mcp tracks and caches that balance so the agent can reason about remaining capacity.
61
+ - **Service discovery** — agents can search for L402 services on Nostr relays by querying kind 31402 announcements, finding paid APIs by topic, capability, or payment method.
62
+
63
+ ## Core L402 Tools
64
+
65
+ These tools work with any L402-compliant server.
66
+
67
+ ### `l402_config`
68
+
69
+ Introspect the agent's payment capabilities and current configuration. Returns wallet status (NWC connected, Cashu tokens loaded), the `MAX_AUTO_PAY_SATS` limit, and the number of stored credentials. Call this first so the agent knows what it can do autonomously.
70
+
71
+ ### `l402_discover`
72
+
73
+ Probe an endpoint to discover its pricing without making a payment. Returns the invoice amount in satoshis, the macaroon challenge, and whether the server is a toll-booth instance (which enables extension tools). Use this before committing to a purchase so the agent can reason about value.
74
+
75
+ ### `l402_fetch`
76
+
77
+ Make an HTTP request to an L402-protected endpoint. Handles the full payment flow automatically: detects 402 responses, pays the invoice if the amount is within the `MAX_AUTO_PAY_SATS` budget and the rolling spend cap, stores the credential, and retries the request. Returns the response body on success. This is the primary tool for consuming L402 APIs.
78
+
79
+ ### `l402_pay`
80
+
81
+ Pay a specific Lightning invoice directly. Tries payment methods in priority order: NWC, Cashu, human-in-the-loop. Use this when you have an invoice from a source other than `l402_fetch`, or when you want explicit control over the payment step.
82
+
83
+ ### `l402_credentials`
84
+
85
+ List all stored L402 credentials and their cached credit balances. Shows which servers the agent has already paid and what capacity remains. Useful for auditing spend and avoiding redundant payments.
86
+
87
+ ### `l402_balance`
88
+
89
+ Check the cached credit balance for a specific server URL. Returns the number of credits remaining without making a network request. Use this before calling `l402_fetch` to confirm there is sufficient balance before consuming credits.
90
+
91
+ ### `l402_search`
92
+
93
+ Search for L402 services on Nostr relays. Queries kind 31402 announcement events and returns matching services with their names, URLs, pricing, capabilities, and supported payment methods. Filter by query text, topics (e.g. "ai", "data"), or payment method. Use the returned URL with `l402_discover` or `l402_fetch` to interact with the service. This enables agents to find paid APIs without knowing URLs upfront — a decentralised alternative to API directories.
94
+
95
+ ## toll-booth Extension Tools
96
+
97
+ These tools activate automatically when the target server is a toll-booth instance (detected via `l402_discover`).
98
+
99
+ ### `l402_buy_credits`
100
+
101
+ Browse and purchase volume discount credit tiers offered by the server. toll-booth servers can expose multiple tiers (e.g. 100 sats for 110 credits, 500 sats for 555 credits). The agent can inspect the tiers, reason about how many requests it needs, and buy the best-value tier upfront rather than paying per-request.
102
+
103
+ ### `l402_redeem_cashu`
104
+
105
+ Redeem Cashu ecash tokens directly with the toll-booth server, bypassing the Lightning round-trip. toll-booth accepts raw ecash tokens and credits the balance immediately. This is faster and cheaper than melting tokens to pay a Lightning invoice when both sides support Cashu.
106
+
107
+ ## Payment Methods
108
+
109
+ Three payment rails are tried in priority order:
110
+
111
+ 1. **NWC (Nostr Wallet Connect)** — fully autonomous. The agent pays invoices directly from a connected Lightning wallet via the NWC protocol. Configure with `NWC_URI`. No human interaction required.
112
+
113
+ 2. **Cashu** — fully autonomous. The agent melts ecash tokens to pay invoices. Configure with `CASHU_TOKENS` pointing to a token store file. No Lightning node required on the agent side.
114
+
115
+ 3. **Human-in-the-loop** — fallback when no autonomous payment method is configured or when a payment exceeds the `MAX_AUTO_PAY_SATS` cap. The agent presents a payment QR code and polls for settlement. Control returns to the agent once the human has paid.
116
+
117
+ The agent can override the payment method per-call, or you can configure only the methods you want available.
118
+
119
+ ## Safety Model
120
+
121
+ Two safety primitives protect against runaway spending:
122
+
123
+ 1. **`MAX_AUTO_PAY_SATS`** — caps any single autonomous payment. Above this threshold, the agent must ask for human approval.
124
+ 2. **`MAX_SPEND_PER_MINUTE_SATS`** — rolling 60-second window cap across all payments. Prevents rapid successive payments from exceeding a total budget even if each individual payment is below the per-payment cap.
125
+
126
+ The human stays in control of three things: the safety caps, which payment methods are available, and credential visibility. The agent operates within those boundaries, not around them.
127
+
128
+ ## Security
129
+
130
+ - **SSRF protection** — all outbound requests pass through an SSRF guard that blocks private/internal IP ranges by default. Set `SSRF_ALLOW_PRIVATE=true` only for local development.
131
+ - **Credential encryption** — stored credentials are encrypted with AES-256-GCM. The encryption key is stored in the OS keychain when available, falling back to a file-based key with a warning.
132
+ - **Preimage validation** — preimages are validated as hex before storage to prevent header injection.
133
+ - **Spend tracking** — atomic `tryRecord()` prevents TOCTOU race conditions in concurrent spend checks.
134
+ - **HTTP transport hardening** — rate limiting (100 req/60s per IP), security headers (CSP, X-Frame-Options, nosniff), and loopback-only binding by default.
135
+
136
+ ## Ecosystem
137
+
138
+ **toll-booth** is the server counterpart to 402-mcp. It is L402 payment middleware that embeds into any Node.js application (Express 5, Deno, Bun, Cloudflare Workers), gates endpoints behind Lightning or Cashu payments, and supports credit tiers and free tiers. Any server protected by toll-booth automatically gets the full set of 402-mcp tools including the extension tools.
139
+
140
+ https://github.com/TheCryptoDonkey/toll-booth
141
+
142
+ **satgate** demonstrates the AI inference use case: a proxy that gates access to AI model endpoints (Ollama, vLLM, llama.cpp) behind L402 payments. Agents use 402-mcp to discover pricing, pay per-request or buy credit tiers, and consume inference capacity without pre-provisioned API keys.
143
+
144
+ https://github.com/TheCryptoDonkey/satgate
145
+
146
+ **402-announce** publishes HTTP 402 services on Nostr as kind 31402 events, making them discoverable by `l402_search`. Operators run it alongside their L402 server to announce capabilities, pricing, and payment methods to the decentralised network.
147
+
148
+ https://github.com/TheCryptoDonkey/402-announce
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "402-mcp",
3
- "version": "3.0.0",
3
+ "version": "3.1.0",
4
4
  "description": "L402 + x402 client MCP - AI agents discover, pay for, and consume any payment-gated API",
5
5
  "type": "module",
6
6
  "bin": {
@@ -71,7 +71,9 @@
71
71
  "files": [
72
72
  "build",
73
73
  "LICENSE",
74
- "README.md"
74
+ "README.md",
75
+ "llms.txt",
76
+ "llms-full.txt"
75
77
  ],
76
78
  "license": "MIT"
77
79
  }