Skip to main content
ClaudeWave

Generic Lightning-paywall sidecar for any stdio MCP server: wraps an upstream, requires a paid invoice (via NWC) before forwarding priced tool calls. Per-tool pricing, replay protection, audit log.

MCP ServersRegistry oficial0 estrellas0 forksTypeScriptMITActualizado today
Install in Claude Code / Claude Desktop
Method: NPX · paywall-mcp
Claude Code CLI
claude mcp add paywall-mcp -- npx -y paywall-mcp
claude_desktop_config.json (Claude Desktop)
{
  "mcpServers": {
    "paywall-mcp": {
      "command": "npx",
      "args": ["-y", "paywall-mcp"]
    }
  }
}
1. Run the command above in your terminal (Claude Code), or paste the JSON config into claude_desktop_config.json (Claude Desktop).
2. Replace any <placeholder> values with your API keys or paths.
3. Restart Claude. The MCP server and its tools appear automatically.
Casos de uso

Resumen de MCP Servers

# paywall-mcp

**Paywall ANY stdio MCP server with Lightning, without modifying it.** `paywall-mcp` is a generic sidecar: configure it with an upstream MCP server command and a per-tool price map, and it transparently:

- Forwards `tools/list` from the upstream to the LLM client, with prices appended to each tool's description.
- Intercepts `tools/call`: free tools pass through; priced tools require a paid Lightning invoice (via Nostr Wallet Connect / NIP-47) before the call is forwarded.

No code changes to the upstream server. Works with Anthropic's reference MCP servers, your own, or any third-party MCP server that speaks stdio.

> **v0.1 — proxy + payment gate complete.** Spawns a stdio upstream as a child process; per-tool pricing via env; in-memory invoice cache + replay protection; audit log; read-only mode. Persistent cache + HTTP/SSE upstream transport deferred to v0.2.

---

## Why this exists

Modern paid-API patterns (Lightning paywall, L402, micropayments) exist for HTTP but the MCP ecosystem has no standard for paid tool calls. Building it into each individual server is repetitive and error-prone. `paywall-mcp` is the missing sidecar: write your tools as a normal MCP server, then wrap it with `paywall-mcp` to charge sats per call.

## How the dual-call pattern works

For any priced tool:

1. **First call** — LLM calls `priced_tool({...args})` *without* `payment_hash`. paywall-mcp issues a bolt11 invoice through your NWC wallet and returns:
   ```json
   {
     "error": "payment_required",
     "invoice": "lnbc...",
     "payment_hash": "abc123...",
     "amount_sats": 21,
     "expires_in_seconds": 600,
     "next_step": "Pay this bolt11 ..."
   }
   ```
2. **Payment** — the LLM (or its operator) pays the invoice. Easiest path: use [`nwc-mcp`](https://npmjs.com/package/nwc-mcp) — the same LLM can call `nwc_pay_invoice` to settle.
3. **Second call** — LLM calls `priced_tool({...args, payment_hash: "abc123..."})`. paywall-mcp verifies settlement via NWC `lookup_invoice`, strips `payment_hash` from the args, forwards the original call to the upstream, returns the upstream's result.

Replay protection: the same `payment_hash` cannot be redeemed twice. Buyers pay a fresh invoice for each call.

---

## What you can build with it

- **Charge sats for premium tools** in an MCP server you already have, by adding one wrapper process.
- **Per-tool pricing tiers** — `free_lookup: 0`, `premium_analysis: 100`, `rare_alpha_signal: 5000`. Buyers see prices in tool descriptions.
- **Bundle-and-resell third-party MCP servers** — wrap someone else's open-source MCP server with your paywall and offer it as a managed paid service.
- **A/B test pricing** — adjust `PAYWALL_PRICE_MAP` in env, restart, you're at the new price.
- **Time-limited promotional pricing** — start at 21 sats, raise to 100 sats once usage proves the value.

---

## Requirements

- Node 20+
- An existing stdio MCP server to wrap (paywall-mcp doesn't host tools itself; it gates an upstream's tools).
- A NIP-47 NWC connection string for the **seller's** receive wallet. `make_invoice` + `lookup_invoice` are the only permissions paywall-mcp needs. **A receive-only NWC connection is perfectly fine and recommended** — paywall-mcp never spends.

## Install

```bash
# From npm
npx -y paywall-mcp

# From source
git clone <repo>
cd paywall-mcp
corepack enable pnpm
pnpm install
pnpm build
```

## Configure

```bash
cp .env.example .env
# edit .env: set PAYWALL_UPSTREAM_COMMAND/ARGS, NWC_CONNECTION_STRING, prices
```

The server auto-loads `.env` from its own directory (next to `dist/`) — deliberately NOT from cwd, to avoid env collisions when running multiple MCP servers in the same Claude Code session.

### Required

| Var | Purpose |
|---|---|
| `PAYWALL_UPSTREAM_COMMAND` | Executable to spawn as the upstream MCP server (e.g., `node`). |
| `PAYWALL_UPSTREAM_ARGS` | JSON array of args passed to the upstream command (e.g., `["/path/to/upstream/dist/index.js"]`). |

### Required when any tool has a non-zero price

| Var | Purpose |
|---|---|
| `NWC_CONNECTION_STRING` | NIP-47 NWC URI for the seller's RECEIVE wallet. `make_invoice` + `lookup_invoice` permissions sufficient. paywall-mcp never spends. |

### Pricing

| Var | Default | Purpose |
|---|---|---|
| `PAYWALL_DEFAULT_PRICE_SATS` | `0` | Default price for any tool not in the price map. `0` = free passthrough. |
| `PAYWALL_PRICE_MAP` | `{}` | JSON object mapping tool names to sat prices. Per-tool 0 = free; missing = use default. Example: `{"premium_compliment":21,"rare_alpha_signal":5000}`. |

### Optional

| Var | Default | Purpose |
|---|---|---|
| `PAYWALL_UPSTREAM_CWD` | (parent cwd) | Working directory for the upstream child process. |
| `PAYWALL_UPSTREAM_ENV` | (inherits) | JSON object of env-var overrides for the upstream. |
| `PAYWALL_READ_ONLY` | `false` | Disables all paid tool calls (`tools/list` still works). Useful for maintenance. |
| `PAYWALL_INVOICE_TTL_SECONDS` | `600` | Invoice TTL. Past this, `payment_hash` is forgotten from cache and the buyer must re-issue. |
| `PAYWALL_PRICE_LABEL_TEMPLATE` | `"(💰 {price} sats)"` | Label appended to each priced tool's description in `tools/list`. `{price}` is substituted with the sat amount. |
| `PAYWALL_LOG_PATH` | `./paywall-mcp.log` | Server log. |
| `PAYWALL_AUDIT_PATH` | `./paywall-mcp-audit.log` | NDJSON audit log (one line per call). |

---

## End-to-end example: paywall the bundled `paywall-mcp-test` server

The companion `paywall-mcp-test` package exposes a single tool — `premium_compliment`. It already implements its own paywall pattern internally, but it's also a convenient stand-in for "any upstream MCP server" to demonstrate paywall-mcp itself.

`.env`:

```
PAYWALL_UPSTREAM_COMMAND=node
PAYWALL_UPSTREAM_ARGS=["/abs/path/to/paywall-mcp-test/dist/index.js"]

NWC_CONNECTION_STRING=nostr+walletconnect://...

PAYWALL_DEFAULT_PRICE_SATS=21
PAYWALL_PRICE_MAP={"premium_compliment":21}
```

Wire `paywall-mcp` (not the upstream directly) into your MCP client:

```json
{
  "mcpServers": {
    "paywall": {
      "command": "npx",
      "args": ["-y", "paywall-mcp"],
      "env": {}
    }
  }
}
```

Now from your agent:

```
1. tools/list  → premium_compliment ... (💰 21 sats) This tool requires ...
2. premium_compliment({})  → returns invoice + payment_hash
3. nwc_pay_invoice(invoice)  → buyer pays
4. premium_compliment({ payment_hash: "..." })  → upstream's result returned
```

---

## Safety model

```
tools/list      → upstream.listTools() → augment descriptions with prices → return
tools/call:
  if price == 0           → upstream.callTool(args)                  (passthrough)
  elif PAYWALL_READ_ONLY  → refuse with paywall_read_only            (block)
  elif no payment_hash    → gate.issue() → return bolt11 + hash      (issue)
  elif bad hash format    → refuse with invalid_payment_hash         (block)
  else (have hash):
      gate.verify() ──┬─ unknown_payment_hash         → block
                      ├─ payment_hash_already_redeemed → block (replay)
                      ├─ payment_hash_tool_mismatch    → block
                      ├─ payment_not_settled           → block
                      └─ ok → strip hash → upstream.callTool()      (paid passthrough)
```

Audit log entries (NDJSON, one per request):

- **`outcome: "ok"`** — invoice issued, free passthrough, or paid passthrough completed
- **`outcome: "blocked"`** — read-only refusal, invalid hash, replay, mismatch, not-settled
- **`outcome: "error"`** — upstream call failed, NWC `lookup_invoice` failed, etc.

Tail the audit log for ground truth — independent of whatever the LLM tells you.

```bash
tail -f paywall-mcp-audit.log | jq .
```

---

## Wire into Claude Desktop / Claude Code / Cursor

```json
{
  "mcpServers": {
    "paywall": {
      "command": "npx",
      "args": ["-y", "paywall-mcp"],
      "env": {}
    }
  }
}
```

Same `.env`-via-binary-dir pattern as the rest of the substrate — leave `env` empty in the client config; secrets stay in `paywall-mcp/.env`.

---

## Testing

```bash
pnpm typecheck
pnpm test        # 13 vitest cases (config resolution + payment-gate state machine)
pnpm build       # ~18 KB ESM bundle
```

---

## Companion servers

- [`nwc-mcp`](https://npmjs.com/package/nwc-mcp) — Lightning wallet for the **buyer**. Lets the agent pay the invoices paywall-mcp issues. The matching half of the agent-pays-a-paid-tool loop.
- [`nostr-ops-mcp`](https://npmjs.com/package/nostr-ops-mcp) — NOSTR identity, publishing, encrypted DMs.
- [`marketplace-mcp`](https://npmjs.com/package/marketplace-mcp) — Run a NIP-15 / Shopstr storefront from an agent.
- [`albyhub-admin-mcp`](https://npmjs.com/package/albyhub-admin-mcp) — Alby Hub node-admin via HTTP API.

---

## License

MIT — see [`LICENSE`](./LICENSE).

## Contact / Issues

Built by **LLMOps.Pro**.

- **NOSTR:** [`npub1hdg932jvwc3jdvkqywgqv0ue4nn60exrf92asy8mtazt3hjg7d2s2yw0nw`](https://njump.me/npub1hdg932jvwc3jdvkqywgqv0ue4nn60exrf92asy8mtazt3hjg7d2s2yw0nw) — follow, DM, zap.
- **Lightning Address:** `sovereigncitizens@getalby.com` — for support zaps and "this was useful" tips.
- **Bug reports / feature requests:** open a GitHub issue (link forthcoming).
- **Security issues:** please disclose privately via NOSTR DM before opening a public issue.

Lo que la gente pregunta sobre paywall-mcp

¿Qué es llmops-pro/paywall-mcp?

+

llmops-pro/paywall-mcp es mcp servers para el ecosistema de Claude AI. Generic Lightning-paywall sidecar for any stdio MCP server: wraps an upstream, requires a paid invoice (via NWC) before forwarding priced tool calls. Per-tool pricing, replay protection, audit log. Tiene 0 estrellas en GitHub y se actualizó por última vez today.

¿Cómo se instala paywall-mcp?

+

Puedes instalar paywall-mcp clonando el repositorio (https://github.com/llmops-pro/paywall-mcp) o siguiendo las instrucciones del README en GitHub. ClaudeWave también te ofrece bloques de instalación rápida en esta misma página.

¿Es seguro usar llmops-pro/paywall-mcp?

+

llmops-pro/paywall-mcp aún no ha sido auditado por nuestro agente de seguridad. Revisa el repositorio original en GitHub antes de usarlo en producción.

¿Quién mantiene llmops-pro/paywall-mcp?

+

llmops-pro/paywall-mcp es mantenido por llmops-pro. La última actividad registrada en GitHub es de today, con 0 issues abiertos.

¿Hay alternativas a paywall-mcp?

+

Sí. En ClaudeWave puedes explorar mcp servers similares en /categories/mcp, ordenados por popularidad o actividad reciente.

Despliega paywall-mcp en tu cloud

Lleva este repo a producción en minutos. Cada plataforma genera su propio entorno con variables de entorno editables.

¿Mantienes este repo? Añade un badge a tu README

Pega el badge en tu README de GitHub para mostrar que está auditado por ClaudeWave. Cada badge enlaza de vuelta a esta página y muestra el Trust Score actual.

Featured on ClaudeWave: llmops-pro/paywall-mcp
[![Featured on ClaudeWave](https://claudewave.com/api/badge/llmops-pro-paywall-mcp)](https://claudewave.com/repo/llmops-pro-paywall-mcp)
<a href="https://claudewave.com/repo/llmops-pro-paywall-mcp"><img src="https://claudewave.com/api/badge/llmops-pro-paywall-mcp" alt="Featured on ClaudeWave: llmops-pro/paywall-mcp" width="320" height="64" /></a>

Más MCP Servers

Alternativas a paywall-mcp