mcp-l402-gate-example
README.md
# mcp-l402-gate-example
Minimal MCP server showing [`@powforge/mcp-l402-gate`](https://www.npmjs.com/package/@powforge/mcp-l402-gate) in action.
One tool, `bitcoin_data`, fetches current BTC/USD price plus recommended mempool fees from mempool.space. Each call is gated by:
1. An L402 Lightning invoice (the caller pays sats per call).
2. A Depth-of-Identity score lookup against the public PowForge oracle. Below the threshold, paying does not get you through.
L402 alone proves a caller paid. L402 + DoI proves they paid *and* carry a per-pubkey reputation that survives across sessions and costs irreversible work to fake. That second half is the part most MCP billing kits skip.
## Quickstart
```bash
git clone https://github.com/zekebuilds-lab/mcp-l402-gate-example
cd mcp-l402-gate-example
cp .env.example .env # fill in GATE_HMAC_SECRET and LNBits creds
npm install
npm start
```
Server logs the tool URL and oracle on boot. Default port is 3100.
## Test it with curl
First call has no auth, so the gate returns a 402 with an invoice:
```bash
curl -i -X POST http://localhost:3100/tools/bitcoin_data \
-H 'Content-Type: application/json' \
-H 'X-Caller-Pubkey: 02a1b2c3...your-hex-pubkey' \
-d '{}'
```
Expected response:
```
HTTP/1.1 402 Payment Required
WWW-Authenticate: L402 macaroon="...", invoice="lnbc1..."
Content-Type: application/json
{
"error": "payment required",
"macaroon": "...",
"invoice": "lnbc1...",
"payment_hash": "..."
}
```
Pay the `invoice` field (any LN wallet), capture the preimage, then retry:
```bash
curl -i -X POST http://localhost:3100/tools/bitcoin_data \
-H 'Content-Type: application/json' \
-H 'X-Caller-Pubkey: 02a1b2c3...your-hex-pubkey' \
-H 'Authorization: L402 <macaroon>:<preimage>' \
-d '{}'
```
You get back the BTC price, mempool fee estimates, and the caller's DoI score.
The manifest is also exposed for MCP clients that introspect tool catalogs:
```bash
curl http://localhost:3100/manifest.json
```
## Configuration
| Variable | Description | Required | Default |
|---|---|---|---|
| `GATE_HMAC_SECRET` | HMAC key for signing L402 macaroons. Generate with `openssl rand -hex 32`. | yes | - |
| `LNBITS_URL` | Your LNBits instance base URL. | yes | - |
| `LNBITS_INVOICE_KEY` | LNBits invoice/read key. Never use the admin key. | yes | - |
| `ORACLE_URL` | DoI oracle base URL. | no | `https://identity.powforge.dev` |
| `PORT` | HTTP port. | no | `3100` |
| `SATS_AMOUNT` | Sats charged per call. | no | `1` |
| `MIN_SCORE` | Minimum DoI composite score to pass the gate. `0` disables identity gating. | no | `0` |
## DoI score thresholds
These are the same buckets the oracle returns as `rank`. Pick the one that matches how expensive a wrong call is:
| `MIN_SCORE` | Rank | Fits |
|---|---|---|
| 0 | unknown | Pure paywall. Identity does not matter. |
| 10 | emerging | First-call abuse hurts. Sensible default for most public MCP tools. |
| 40 | active | The tool burns real GPU or has expensive side effects. |
| 100 | established | Compliance-sensitive or single-tenant SaaS-style endpoints. |
| 200 | trusted | High-trust admin tooling. |
## How the gate works
Without the gate, a 402 + macaroon flow proves the caller paid 10 sats. A fresh attacker wallet pays the same 10 sats. That is fine wire format and weak abuse control.
`@powforge/mcp-l402-gate` keeps the L402 invoice and adds a second check: when the macaroon verifies, the gate calls the DoI oracle for the caller's pubkey, gets back a Schnorr-signed score, and compares to `MIN_SCORE`. The score is composed from observable irreversible work across four dimensions (social, access, vouch, economic), so a fresh sybil cannot grind it in a minute.
The full failure-mode table is in [`@powforge/mcp-l402-gate` README](https://www.npmjs.com/package/@powforge/mcp-l402-gate).
## Files
- `server.js` - the MCP server, ~110 lines.
- `.env.example` - copy to `.env` and fill in.
- `package.json` - depends on `express` and `@powforge/mcp-l402-gate`.
## Links
- npm: [@powforge/mcp-l402-gate](https://www.npmjs.com/package/@powforge/mcp-l402-gate)
- Docs and pricing: [powforge.dev/mcp](https://powforge.dev/mcp)
- Public DoI oracle: [identity.powforge.dev](https://identity.powforge.dev)
## License
MIT.
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues