How a paid MCP server can charge AI agents safely (what we learned building one) The maker of AwesomeVideo, a hosted captioning API and MCP server, detailed a billing design that lets AI agents pay for tool calls with prepaid credits while preventing runaway spend. The server exposes free quote and plan endpoints plus an estimate MCP tool so agents can price work before running it, returns HTTP 402 with balance and shortfall details when funds are insufficient, and enforces per-call maxCredits, per-key monthly spend caps, idempotency keys and conditional balance updates to block double charges. The developer acknowledged a tradeoff: per-step rounding to whole cents makes short clips pay a premium, with an 8-second caption costing 2 credits versus 5 for a full minute. I'm the maker of AwesomeVideo, a hosted captioning API and MCP server that agents pay for with prepaid credits. This post is about the billing side, not the video side. Everything below is how our server behaves today, including the parts I'm not sure we got right. When your tool costs real money per call, the caller isn't a person reading a pricing page. It's a model that will retry on a timeout, misread a number, or chain two calls you hoped it would keep apart. Here's the design we ended up with, in the order a request goes through it. Our first rule: an agent should never have to spend money to learn what something costs. We have two free endpoints that need no key at all: POST /v1/quote for a single operation and POST /v1/plan for a whole pipeline. Over MCP, the same thing is the estimate tool. A real response for an 8-second clip: { "operation": "caption", "audioSeconds": 8, "costCents": 2, "breakdown": { "transcribe": 1, "burn": 1 }, "centsPerMinute": 5, "charged": false } plan also returns limitViolations too long, too big, unknown duration before anything runs. Paid tools check the same limits and return 422 limit exceeded with charged: false instead of failing halfway. We chose a separate tool called estimate over a dryRun flag on each paid tool. Our bet: a model follows "call estimate first" more reliably than it remembers an optional flag. Tradeoff: each step is rounded up to a whole cent on its own. An 8 s caption costs 2 credits 1 for transcription, 1 for the burn , while a full minute costs 5. Short clips pay a rounding premium. We'd rather be predictable than charge fractions, but it's a real cost to small jobs. 1 credit = 1 cent, bought ahead of time. The agent has no way to charge a card. That's the most important safety property we have, and it follows from "agent spends, human funds": When the balance is short, the paid call fails before a job starts, with HTTP 402. This is the shape our code builds trimmed, the checkout link is a placeholder : { "error": "insufficient balance", "message": "Captions transcribe + burn costs 2 cents. This key has 0 cents. No job was started and nothing was charged. Open