Inspiration
Coding and ops agents can now buy things: API credits, domains, datasets, GPU hours. Today the choice is all-or-nothing. Either the agent holds your card, or every $12 purchase waits on you. Companies already pay for spend control for human employees, with tools like Ramp and Brex. Agents need the same thing, written the way people actually think about money: in sentences. PayPal joining the x402 Foundation is a sign that agent checkout is becoming a standard. Allowance is the spend-policy layer on top of that checkout.
What it does
You write your agents' spending rules in plain English. Allowance turns that into typed rules you can review, each one tied to the words it came from. Agents ask before they buy, through an MCP server (Claude Code, Cursor) or a REST endpoint with a per-agent key. Each request is approved, denied, or sent to you for a PayPal approval.
When a purchase is over the limit, you get an approval card. Approve opens PayPal's own page. After you confirm, Allowance captures the payment and can refund it. This path was run end to end in the PayPal sandbox: an over-limit purchase was approved, captured, and refunded.
When a purchase is denied, nothing is charged, and the agent is told the exact rule and sentence that blocked it.
In-policy auto-charge from a saved PayPal method is built in the product, but it is not verified live yet, because the sandbox app still lacks PayPal Vault permission.
A budget meter, an 80% alert, a full audit ledger (classifier output, deciding rule, PayPal order and capture ids) and one-click refunds complete it.
How we built it
The server is TypeScript (Hono) with Node's built-in SQLite, and the UI is React + Vite.
- PayPal is called directly over REST in sandbox: Orders v2 create and capture with payer-action approval links, and Payments v2 capture refunds, all with PayPal-Request-Id idempotency. Vault v3 setup and saved-method charges are implemented in code. Live sandbox Vault calls are not verified yet, because this sandbox app has not been granted the vault scope.
- Claude Sonnet compiles the policy into a zod-validated rule schema, and every rule must quote a real substring of your text. Haiku extracts only the facts the rules need (category, recurring or not, vendor class) and treats request text as untrusted.
- The decision itself is a pure, unit-tested function. The LLM never decides whether money moves.
- The MCP server uses the official MCP SDK (streamable HTTP).
Challenges
The hard part was keeping AI out of the money decision. The classifier can be wrong or prompt-injected through a purchase description, so blocked-category checks also run on the agent's declared category. Budget reservation happens under a lock, and an owner-approved request is re-checked against the budget at approval and again before capture.
Accomplishments
Every denial is explainable by a quoted sentence. The over-limit PayPal path was proven live in sandbox, including capture and refund.
What we learned
The money decision has to stay out of the model. Once the owner approves on PayPal's own page, capture and refund are straightforward. Saved-method auto-charge still depends on PayPal granting Vault on the app.
What's next
- Per-agent allowances and team approvers.
- PayPal webhooks for capture and refund events.
- Payouts, so an agent can also pay people (bounties, contractors) under the same policy.
- A hosted version.
Testing instructions (judges)
- Clone the repo and run
npm install. - Copy
.env.exampleto.envand add sandbox PAYPAL_CLIENT_ID / PAYPAL_CLIENT_SECRET (free at developer.paypal.com, Apps and Credentials, Sandbox), plus ANTHROPIC_API_KEY or OPENAI_API_KEY. With no AI key, a structured no-LLM mode still works. - Run
scripts/serve.shand open http://localhost:4320. - Run
npm run paypal:selftestto verify PayPal in one command. - Run
npm run demo:agentto fire three agent purchases.
Built With
- anthropic-claude
- hono
- model-context-protocol
- node-sqlite
- paypal
- paypal-orders-v2
- paypal-vault-v3
- react
- typescript
- vite
- vitest
- zod