You wired up payment on your MCP server. Sats settle in seconds. Auth0 just GA'd Auth for MCP so you know which agent is calling. Both real wins. Neither one fixes the thing that's actually breaking your bill.
An agent with a fresh pubkey and zero history pays your tool the same rate as one with two years of on-chain history and vouches from real builders. A scraper with a thousand sats gets the same access as a credible agent that earned its way in. The gap isn't auth and it isn't payment. It's that the price ought to know who's paying.
Two halves, no whole
Look at what shipped this month.
Auth0 Auth for MCP (GA May 6). OAuth, on-behalf-of tokens, fleet client registration. They tell you which agent is calling. They do not bill it.
Mycelia Signal / Sovereign Lightning Oracle. Lightning-gated MCP, macaroons, the L402 transport done right. They charge the call. They do not score the caller.
x402 Foundation. A payment transport spec for HTTP. Beautiful work. Identity is out of scope, on purpose.
Half the room is auth and the other half is billing. The bot pays the same rate as the builder in both halves, because neither half looks at depth.
One config object, multiple thresholds
@powforge/mcp-l402-gate@0.3.0 shipped last night. The new thing is minScores, a config object that gates a tool call on multiple identity axes at the same time. Composite plus any individual depth axis. AND across all of them. One trip is enough to deny.
const { mcpL402Middleware } = require('@powforge/mcp-l402-gate');
app.use('/mcp', mcpL402Middleware({
secret: process.env.GATE_HMAC_SECRET,
lnbitsUrl: process.env.LNBITS_URL,
lnbitsApiKey: process.env.LNBITS_INVOICE_KEY,
satsAmount: 10,
minScores: {
composite: 10, // emerging tier overall
'depth.social': 5, // some social weight
'depth.economic': 3, // some economic skin in the game
},
}));
A caller who paid 10 sats but came in with a 4-day-old pubkey and zero economic history hits a 403 even though the invoice settled. A 200-composite that scored zero on social weight also hits 403, because the AND is honest. The body tells the agent which axis tripped, so a well-behaved client can self-improve and retry.
{
"error": "score_too_low",
"score": 2,
"min": 5,
"field": "depth.social",
"rank": "emerging",
"failed": [{ "field": "depth.social", "value": 2, "min": 5 }]
}
That failed array is what agent runtimes can actually loop on. Most rejections today are binary "denied" with no path forward. This one says: you're short on the social axis by three points. Go earn them and come back.
See it fail without paying for it
The 0.3.0 release ships a demo binary that walks the five-step flow against a live endpoint in 90 seconds. There's a flag for forcing the low-score path so you can watch the rejection happen without needing a fresh sybil pubkey.
npx -y @powforge/mcp-l402-gate-demo \
--target https://image.powforge.dev/mcp \
--tool image_render \
--simulate-low-score
You'll watch the agent request the tool, get a 402, pay the invoice, look up its own score, retry the call, and hit the 403 with the failed array. That's the whole loop. No SDK, no signup, no email.
For the success path, drop --simulate-low-score and pass --pubkey <hex64> plus LNBits creds. The endpoint is a live image-render tool with a 10-sat price and a 10-composite floor.
Under the hood
Three moving parts. The Depth-of-Identity oracle at identity.powforge.dev returns a score envelope for any Nostr pubkey across composite, depth.social, depth.access, depth.economic, and depth.vouch. The L402 layer mints macaroons and verifies preimages against LNBits. The gate sits in front of your handler, runs resolveScoreThresholds() against minScores, and 403s with the failure detail when any axis trips.
Fail-closed by default. Oracle down means 503 with {mode: "fail_closed"}, not unscored traffic through. Flip it for dev if you want.
Where this is going
There's a pending spec proposal at x402-foundation/x402 PR #1311 to add bip122 as a payment scheme alongside the existing evm schemes. If that lands, Lightning becomes a first-class settlement layer for the spec the rest of the agent ecosystem is converging on. The minScores gate is already the natural reference for what a bip122-mode x402 server looks like when it also wants to discriminate by caller depth.
Identity scoring without billing is a directory. Billing without identity scoring is a toll booth that lets anyone with a quarter through. The gate is what happens when you put them in the same middleware and let the price know who's paying.
npm i @powforge/mcp-l402-gate. Three minutes from clean install to a gated tool. Public source mirror at github.com/zekebuilds-lab/mcp-l402-gate. Live endpoint at captcha.powforge.dev if you want a feel for the rejection shape before you wire it into your own server.
Build something that knows who's calling.
Top comments (0)