l402-search-mcp
by llmops-pro
README.md
# l402-search-mcp
**No-KYC web search for AI agents — paid per query in Lightning sats, via MCP.**
This is an MCP *client-side* server for [L402](https://docs.lightning.engineering/the-lightning-network/l402)-paywalled search endpoints. It gives any MCP-capable agent (Claude Desktop, Claude Code, Cursor, [nostr-merchant](https://github.com/llmops-pro/nostr-merchant), …) a `search` tool that costs sats instead of an API key:
1. `search(query)` → returns a bolt11 **Lightning invoice** + `payment_hash`
2. The agent pays the invoice **with its own wallet** — e.g. [`nwc-mcp`](https://github.com/llmops-pro/nwc-mcp)'s `nwc_pay_invoice`, under the agent's own budget caps
3. `search(query, payment_preimage)` → JSON results
No account. No API key. No KYC. Each payment buys exactly one search.
By default it points at **https://llmops-search.fly.dev** (50 sats/search, run by us), but `SEARCH_SERVICE_URL` works with any endpoint speaking the same L402 dialect.
## The trust model (read this)
**This server holds NO keys.** Not a wallet connection, not an nsec, nothing. Payment happens in the *agent's* wallet, where the agent's own budget caps, allowlists, and audit logs apply. l402-search-mcp only:
- relays the L402 challenge (invoice) to the agent,
- remembers which macaroon belongs to which `payment_hash` (so the agent only handles the preimage its wallet already returned),
- makes the authorized retry.
Worst-case compromise of this process leaks pending search queries — never money.
## Install
```bash
npx -y l402-search-mcp
```
Claude Code (project scope):
```bash
claude mcp add l402-search -s project -- npx -y l402-search-mcp
```
Claude Desktop (`claude_desktop_config.json`):
```json
{
"mcpServers": {
"l402-search": { "command": "npx", "args": ["-y", "l402-search-mcp"] }
}
}
```
Pair it with a wallet server (e.g. `nwc-mcp`) so the agent can actually pay.
## Tools
| Tool | Price | What it does |
|------|-------|--------------|
| `search` | sats (set by the endpoint; 50 on the default) | First call returns the invoice; the call with `payment_preimage` returns results. |
| `search_service_info` | free | Endpoint reachability, pending challenges, flow explainer. |
## Configuration
Everything is optional — the defaults work. Set in the environment or a `.env` next to the install (never read from cwd):
```bash
SEARCH_SERVICE_URL=https://llmops-search.fly.dev # any L402 search endpoint
CHALLENGE_TTL_SECONDS=900 # match the endpoint's macaroon TTL
AUDIT_LOG_PATH=./l402-search-mcp-audit.log # NDJSON, append-only
HTTP_TIMEOUT_MS=15000
```
## The flow, end to end
```
agent l402-search-mcp endpoint agent's wallet
│ search("foo") │ │ │
│ ────────────────────────► │ GET /search?q=foo │ │
│ │ ───────────────────────► │ │
│ │ 402 {macaroon, invoice} │ │
│ {invoice, payment_hash} │ ◄─────────────────────── │ │
│ ◄──────────────────────── │ (macaroon cached) │ │
│ nwc_pay_invoice(invoice) │ │ │
│ ──────────────────────────┼──────────────────────────┼─────────────────────► │
│ {preimage} │ │ │
│ ◄─────────────────────────┼──────────────────────────┼────────────────────── │
│ search("foo", preimage) │ │ │
│ ────────────────────────► │ GET + Authorization: │ │
│ │ L402 macaroon:preimage │ │
│ │ ───────────────────────► │ │
│ {results} │ 200 {results} │ │
│ ◄──────────────────────── │ ◄─────────────────────── │ │
```
The macaroon never round-trips through the LLM — the agent only sees the invoice and hands back the preimage its wallet returned. `sha256(preimage) = payment_hash` recovers the rest.
## Audit log
NDJSON, one line per event: `startup`, `challenge_received`, `results_received`, `unknown_preimage`, `endpoint_error`. Same shape as the other servers in the kit.
## Part of the LLMOps.Pro agent-payments kit
`nwc-mcp` (wallet) · `nostr-ops-mcp` (NOSTR identity/publishing) · `marketplace-mcp` (storefront) · `albyhub-admin-mcp` (node admin) · `paywall-mcp` (sell YOUR tools for sats) · **`l402-search-mcp`** (buy search with sats)
MIT. Built by [LLMOps.Pro](https://njump.me/npub1hdg932jvwc3jdvkqywgqv0ue4nn60exrf92asy8mtazt3hjg7d2s2yw0nw) · ⚡ sovereigncitizens@getalby.com
TDQS
A4.1/5.0
Scored across 2 tools
Disambiguation5/5
The two tools have clearly distinct purposes: 'search' performs a paid query, while 'search_service_info' provides free metadata about the service. There is no overlap in functionality.
Naming Consistency4/5
Both tools start with 'search', but one is a single verb while the other is a compound noun. The pattern is mostly consistent, though not fully uniform.
Tool Count3/5
With only 2 tools, the surface is minimal. For the niche L402 search domain, it may be sufficient, but it feels slightly thin compared to typical integration scopes.
Completeness3/5
The set covers the core workflow: check service status and perform a paid search. However, missing features like invoice management or search history create minor gaps for advanced use cases.