
Security News
Ruby's Bundler 4.0.18 Extends Cooldown to bundle lock and bundle cache
The supply chain control that delays freshly published gems now covers lockfile generation and gem vendoring in Ruby projects.
spawnpay-paywall
Advanced tools
Charge AI agents per-call for any function. Drop-in wrapper for MCP tools, REST endpoints, or any async function. Settles in USDC on Base L2.
Charge AI agents per-call for any async function. Drop-in wrapper for MCP tools, REST handlers, or any function the agent might call. Settles in USDC on Base L2.
You shipped an MCP server. Agents are calling it. You're eating LLM costs, scraping costs, or just compute, and there's no way to charge for it without forcing every user to sign up for Stripe and paste a credit card. Paywall solves that. Calling agents already have wallets, you just declare a price.
npm install spawnpay-paywall
import { paywall } from 'spawnpay-paywall';
// Your existing tool implementation
async function fetchTweet({ url }) {
const r = await fetch(url);
return await r.text();
}
// Wrap it. Done.
export const fetchTweetPaid = paywall(
{
price: 0.01, // USDC per call
vendor: 'SP_yourCode', // your spawnpay referral code (or 0x wallet)
description: 'fetch_tweet',
},
fetchTweet,
);
The calling agent needs SPAWNPAY_API_KEY in its env. Every call charges them 0.01 USDC, sends it to your wallet, then runs the original function. If the charge fails, the original never runs.
Wrap each paid tool's handler. The MCP framework doesn't know paywall exists.
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { CallToolRequestSchema } from '@modelcontextprotocol/sdk/types.js';
import { paywall } from 'spawnpay-paywall';
const server = new Server({ name: 'my-mcp', version: '1.0.0' }, { capabilities: { tools: {} } });
const decompile = paywall(
{ price: 0.10, vendor: 'SP_yourCode', description: 'decompile_binary' },
async ({ binary_path }) => {
/* ... real work ... */
return { code: '...', symbols: [...] };
},
);
server.setRequestHandler(CallToolRequestSchema, async (req) => {
if (req.params.name === 'decompile') {
const result = await decompile(req.params.arguments);
return { content: [{ type: 'text', text: JSON.stringify(result) }] };
}
});
The agent calling your MCP needs a spawnpay key. Cheapest path: install spawnpay-mcp, run spawnpay_signup once, get $5 USDC credit free.
{
"mcpServers": {
"spawnpay": { "command": "npx", "args": ["-y", "spawnpay-mcp"] },
"your-mcp": {
"command": "npx",
"args": ["-y", "your-mcp"],
"env": { "SPAWNPAY_API_KEY": "spk_caller_key_here" }
}
}
}
Paywall throws PaywallError with a .code you can branch on:
| Code | Means |
|---|---|
NO_API_KEY | Caller didn't set SPAWNPAY_API_KEY |
INSUFFICIENT_BALANCE | Caller's wallet is empty |
CREDIT_LOCKED | Signup credit not yet unlocked |
DAILY_LIMIT | Caller hit their daily spend ceiling |
BAD_VENDOR | Your vendor SP_ code isn't registered |
NETWORK | Spawnpay backend unreachable |
BACKEND | 5xx from spawnpay |
CHARGE_FAILED | Catch-all 4xx |
Each error has .message and an optional .hint you can show the user.
Paywall auto-generates an idempotency key per (description, input, ~minute) — re-runs of the same call within ~60s don't double-charge, but a distinct call later does. Override via your own retry layer if you need a different policy.
Every successful charge calls your onCharge hook (if provided) and passes a receipt object to the wrapped function as the second argument:
const myTool = paywall(
{ price: 0.01, vendor: 'SP_x', onCharge: (r) => console.log('paid:', r.txHash) },
async (input, ctx) => {
// ctx.receipt = { txHash, amount, vendor, currency, status, deduplicated }
return doWork(input);
},
);
| Cost shape | Suggested price |
|---|---|
| Calls a paid LLM API | LLM cost × 1.2 |
| Scrape / API proxy | $0.001 – $0.01 |
| Compute-heavy (decompile, parse, transcribe) | $0.05 – $1.00 |
| Curated data lookup | $0.01 – $0.10 |
Spawnpay takes 0.5%. You keep 99.5%.
| Example | Tool | Price |
|---|---|---|
paid-search-mcp | web_search (Wikipedia + HN, swap to Brave/Tavily/Serper) | $0.005 |
tweet-fetcher-mcp | fetch_tweet (fxtwitter API) | $0.001 |
MIT
FAQs
Charge AI agents per-call for any function. Drop-in wrapper for MCP tools, REST endpoints, or any async function. Settles in USDC on Base L2.
The npm package spawnpay-paywall receives a total of 2 weekly downloads. As such, spawnpay-paywall popularity was classified as not popular.
We found that spawnpay-paywall demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
The supply chain control that delays freshly published gems now covers lockfile generation and gem vendoring in Ruby projects.

Security News
During a UK cyber test, a Mythos 5 agent used sockpuppets, social engineering, and prompt injection to try to get a maintainer to merge malware.

Company News
Socket is now in the AWS Security Hub Extended plan. Adopt it through AWS, apply committed spend, and block malicious open source packages.