@harpd/mcp-paid-tool-starter
v0.1.0
Published
Starter SDK for building MCP tools that require payment before they run. definePaidTool + enforcePayment + runPaidTool. Zero runtime deps.
Maintainers
Readme
@harpd/mcp-paid-tool-starter
A starter SDK for MCP (Model Context Protocol) tools that require payment
before they run. Define a tool with a price, gate it with enforcePayment,
and run it through runPaidTool. Zero runtime dependencies — drop it into
any MCP server (the official @modelcontextprotocol/sdk is a peer, not a dep).
Part of Harpd's open-source agent-commerce toolkit. Pairs with
@harpd/x402-logging-middleware(log the payment) and@harpd/agent-transaction-audit-schema(normalize it into an audit record).
Install
npm install @harpd/mcp-paid-tool-starter
# optional, in your server:
npm install @modelcontextprotocol/sdkDefine a paid tool
import { definePaidTool } from '@harpd/mcp-paid-tool-starter'
const weatherTool = definePaidTool({
name: 'get_weather',
description: 'Get current weather. Costs $0.01 per call.',
inputSchema: { type: 'object', properties: { city: { type: 'string' } }, required: ['city'] },
price: { usd: 0.01, asset: 'eip155:8453/erc20:0xUSDC' },
handler: async ({ args }) => ({
content: [{ type: 'text', text: `Sunny in ${args.city}, 24°C.` }],
}),
})definePaidTool returns a normal MCP tool object, just augmented with a
pricing field. Register it with your MCP server exactly as you would any tool.
Gate it
import { runPaidTool } from '@harpd/mcp-paid-tool-starter'
// In your server's tools/call handler:
const result = await runPaidTool({
tool: weatherTool,
args: request.params.arguments,
// `payment` is the x402 proof the client attached to the transport.
payment: request.payment ?? null,
})
if (result.isError) {
// 402-style denial: result.content[0].text explains the reason
return result
}
// otherwise result is your handler's outputenforcePayment checks, in order: a payment was presented, it covers the
tool's usd price, the asset matches (if the tool pins one), it hasn't
expired, and an optional verify(payment) callback passes (use it to validate
signatures / on-chain settlement).
import { enforcePayment } from '@harpd/mcp-paid-tool-starter'
const decision = enforcePayment({ tool: weatherTool, payment, verify: myX402Verifier })Run the starter example
node starter/paid-tool-example.mjsIt shows a call without payment being denied, and a call with a valid payment succeeding — no external dependencies required.
Why a starter (not a full server)
MCP servers differ in transport, auth, and framework. This package owns the one piece that's annoying to get right — the price + payment gate — and stays out of your server's way. Wire the gate into whatever MCP SDK you already use.
License
MIT © Harpd. Issues and PRs welcome at github.com/harpd-dev/mcp-paid-tool-starter.
