BotSupply
by iambrettforbes · remote · no sign-in to list tools · v1.1.0 · published by GitHub user iambrettforbes
Verifiable purchase receipts for agents: record approval and proof. Wallets and escrow (test mode).
13 tools: 2 do something that can't be undone, 7 change things and 4 only read.
Scanned Oct 21, 2026
- Deletes or cancels0Claude Code: deny
- Can't be undone2Claude Code: ask: see these tools
- Changes things7Claude Code: ask: see these tools
- Only reads4Claude Code: allow: see these tools
No check matched anything in the tool definitions. No finding is not a safety guarantee. How the checks work.
claude mcp add --transport http botsupply https://botsupply.onrender.com/mcpTools
Open a tool for its reasons and full description. Descriptions are the publisher's own words, shown as they are.
13 tools
Can't be undone 2Claude Code: ask
purchaseBuy one live catalog SKU with prepaid credits.No findings
Why it is in this group
- The name "purchase" says "purchase": a word that usually means money moves, which cannot be taken back.
Description, as the server wrote it Buy one live catalog SKU with prepaid credits. Sends { sku } to POST /v1/purchase and returns that JSON, including the pack or recipe payload. Does not place a reservation. recipe.book-table is documentation the buying agent runs itself. An unknown SKU is rejected. Insufficient balance returns an error and does not deduct credits.
Annotations the server declares
- readOnlyHint: false
- destructiveHint: false
- idempotentHint: false
- openWorldHint: false
refund_jobReturn held escrow credits to the payer when the work is not delivered or the job is cancelled.No findings
Why it is in this group
- The name "refund_job" says "refund": a word that usually means money moves, which cannot be taken back.
Description, as the server wrote it Return held escrow credits to the payer when the work is not delivered or the job is cancelled. The payer or the payee can refund, and only while the job is held. The full hold goes back to the payer; no platform fee is taken. Refunding twice, or refunding after release, is rejected and does not move credits again. Same as POST /v1/jobs/:id/refund.
Annotations the server declares
- readOnlyHint: false
- destructiveHint: false
- idempotentHint: false
- openWorldHint: false
Changes things 7Claude Code: ask
attach_proofAttach proof of delivery to a receipt.No findings
Why it is in this group
- The name "attach_proof" says "attach": a word for a change.
Description, as the server wrote it Attach proof of delivery to a receipt. Requires the edit_token from record_approval. Moves approved to delivered, or to disputed when status is disputed. over_cap is true when actual_amount exceeds the price cap. Does not move money. Same as POST /v1/receipts/:id/proof.
Annotations the server declares
- readOnlyHint: false
- destructiveHint: false
- idempotentHint: false
- openWorldHint: false
create_checkoutStart a Stripe Checkout credit top-up.No findings
Why it is in this group
- The name "create_checkout" says "create": a word for a change.
Description, as the server wrote it Start a Stripe Checkout credit top-up. Same as POST /v1/wallets/:id/checkout. Returns the checkout url (open that URL; it keeps Stripe's hosted-page fragment). credits is an integer from 500 to 100000 ($5 minimum). Credits are applied only after Stripe reports the session paid. Returns the API error when Stripe is not configured.
Annotations the server declares
- readOnlyHint: false
- destructiveHint: false
- idempotentHint: false
- openWorldHint: true
create_jobHold credits in escrow for a job another agent will do; release when the work is delivered, refund if not.No findings
Why it is in this group
- The name "create_job" says "create": a word for a change.
Description, as the server wrote it Hold credits in escrow for a job another agent will do; release when the work is delivered, refund if not. Debits amount_credits from the authenticated payer wallet and marks the job held. payee_wallet_id receives the credits on release. Rejects amount_credits below 1, a payer equal to the payee, a missing or other-mode payee wallet, and insufficient balance. idempotency_key makes a retry return the same job without debiting twice. Same as POST /v1/jobs.
Annotations the server declares
- readOnlyHint: false
- destructiveHint: false
- idempotentHint: true
- openWorldHint: false
open_walletCreate a wallet and return wallet_id plus api_key once, with balance_credits 0.No findings
Why it is in this group
- The name "open_wallet" says "open": a word for a change.
Description, as the server wrote it Create a wallet and return wallet_id plus api_key once, with balance_credits 0. Same as POST /v1/wallets. This does not look up an existing wallet. Keep the api_key; later tools need it as Authorization: Bearer or as api_key.
Annotations the server declares
- readOnlyHint: false
- destructiveHint: false
- idempotentHint: false
- openWorldHint: false
record_approvalRecord a human's approval of a purchase on any payment rail.No findings
Why it is in this group
- Nothing in its name or description says what it does, so it is counted as a write.
Description, as the server wrote it Record a human's approval of a purchase on any payment rail. BotSupply does not hold or move the money. Returns receipt_id, a public receipt_url, and an edit_token shown once. No wallet or API key. Rate limited per IP. Same as POST /v1/receipts.
Annotations the server declares
- readOnlyHint: false
- destructiveHint: false
- idempotentHint: false
- openWorldHint: false
release_jobRelease held escrow credits to the payee when the work is delivered.No findings
Why it is in this group
- Nothing in its name or description says what it does, so it is counted as a write.
Description, as the server wrote it Release held escrow credits to the payee when the work is delivered. Only the payer can release, and only while the job is held. ESCROW_FEE_BPS (default 0) is withheld on release, recorded on the job, and credited to nobody; the payee receives amount_credits minus that fee. Releasing twice, or releasing after a refund, is rejected and does not move credits again. Same as POST /v1/jobs/:id/release.
Annotations the server declares
- readOnlyHint: false
- destructiveHint: false
- idempotentHint: false
- openWorldHint: false
verify_receiptRecompute the receipt hash chain and HMAC signature.No findings
Why it is in this group
- Nothing in its name or description says what it does, so it is counted as a write.
- The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.
Description, as the server wrote it Recompute the receipt hash chain and HMAC signature. valid is true when the stored receipt matches the chain and the server signature. valid is false when a row was altered. Same as GET /v1/receipts/:id/verify.
Annotations the server declares
- readOnlyHint: true
- destructiveHint: false
- idempotentHint: true
- openWorldHint: false
Only reads 4Claude Code: allow
get_balanceReturn the authenticated wallet id and prepaid credit balance.No findings
Why it is in this group
- The name "get_balance" says "get": a word for reading.
Description, as the server wrote it Return the authenticated wallet id and prepaid credit balance. Same as GET /v1/balance. Does not return the API key.
Annotations the server declares
- readOnlyHint: true
- destructiveHint: false
- idempotentHint: true
- openWorldHint: false
get_jobReturn an escrow job's status (held, released, or refunded), the held amount, any release fee, and the payer and payee wallets.No findings
Why it is in this group
- The name "get_job" says "get": a word for reading.
Description, as the server wrote it Return an escrow job's status (held, released, or refunded), the held amount, any release fee, and the payer and payee wallets. The caller must be the payer or the payee. A job from another Stripe mode is not visible. Same as GET /v1/jobs/:id.
Annotations the server declares
- readOnlyHint: true
- destructiveHint: false
- idempotentHint: true
- openWorldHint: false
get_receiptRead a public purchase receipt: approval, scope, price cap, merchant, proofs, and content hash.No findings
Why it is in this group
- The name "get_receipt" says "get": a word for reading.
Description, as the server wrote it Read a public purchase receipt: approval, scope, price cap, merchant, proofs, and content hash. No API key. The approver contact and the edit token are not included. Same as GET /v1/receipts/:id.
Annotations the server declares
- readOnlyHint: true
- destructiveHint: false
- idempotentHint: true
- openWorldHint: false
list_catalogList live BotSupply SKUs, credit prices, short descriptions, and what a purchase does not include.No findings
Why it is in this group
- The name "list_catalog" says "list": a word for reading.
Description, as the server wrote it List live BotSupply SKUs, credit prices, short descriptions, and what a purchase does not include. Payloads stay behind purchase. recipe.book-table, when listed, is recipe documentation only and does not place a reservation.
Annotations the server declares
- readOnlyHint: true
- destructiveHint: false
- idempotentHint: true
- openWorldHint: false
This is not a safety rating, and no finding is not a safety guarantee. The groups and findings come from fixed checks of the tool definitions the server returned on the date shown, not from its code or what it does when called. How the checks work.
Install
Pinned to version 1.1.0. Values in angle brackets are yours to fill in.
claude mcp add --transport http botsupply https://botsupply.onrender.com/mcpRun in a terminal.
Claude Code permissions
Allow the reads, ask before a change, deny the deletes. Paste into .claude/settings.json.
{
"permissions": {
"allow": [
"mcp__botsupply__list_catalog",
"mcp__botsupply__get_balance",
"mcp__botsupply__get_job",
"mcp__botsupply__get_receipt"
],
"ask": [
"mcp__botsupply__open_wallet",
"mcp__botsupply__purchase",
"mcp__botsupply__create_checkout",
"mcp__botsupply__create_job",
"mcp__botsupply__release_job",
"mcp__botsupply__refund_job",
"mcp__botsupply__record_approval",
"mcp__botsupply__attach_proof",
"mcp__botsupply__verify_receipt"
],
"deny": []
}
}Tools that only read are allowed, tools that change things ask first, tools that delete or cancel are denied. It assumes the server is installed as botsupply. Review it before you use it.
