Skip to content

MCP server

Tuppence runs a remote MCP server at https://api.tuppence.ai/mcp (streamable HTTP). Add it to Claude or ChatGPT and sign in, with no key (below), or connect a developer’s agent with an API key as a bearer token. Either way the assistant gets only the tools its access allows, acting as your account.

Agent / MCP clientClaude, Cursor, …@tuppence/mcpstdio bridgeMCP serverapi.tuppence.ai/mcpTuppence APIyour accountA personapprove_urlBearer rk_…stdioHTTPtool callapproval

To run your business from your own assistant, add Tuppence as a connector with the URL and no key. Tuppence signs you in and asks what the assistant may do; you can take that back at any time.

  1. In Claude, open Settings → Connectors → Add custom connector. In ChatGPT, turn on developer mode and create a connector. Enter https://api.tuppence.ai/mcp and leave any key or client fields empty.
  2. Tuppence opens in your browser. Sign in, pick the account and the mode (test, or live on a live account with a fresh code or Face ID), and untick anything you don’t want the assistant to have. It never gets more than your role allows.
  3. Back in the assistant, ask: “show me this week’s online orders”, “take the oat latte off sale”.
URL: https://api.tuppence.ai/mcp
Key: none (Tuppence signs you in)
Reads and changesRun straight away, as you, within what you allowed. Every store change is on your change history with its undo.
Money, and anything that can’t be undoneRefunds, labels and archiving a product never run on the connection alone. Tuppence answers approval_required, and the change waits in the dashboard’s Store → Assistant → Approvals until someone on your team approves it with a fresh code or Face ID. It then runs once, as them.
More accessWhen a tool needs access you didn’t allow, Tuppence tells the assistant which, and it asks you to connect again with it.
On the recordRequest logs, the audit log and the change history name the app and the person, for example Claude, for Mo Khan.
Taking it backSettings → Connected apps lists each app with its access and when it last acted. Remove access stops it on its next request. Owners see everyone’s apps; everyone else sees their own. Someone who leaves the team takes their apps’ access with them.

A developer’s agent, or a client without sign-in, uses a key instead:

Give an agent a restricted key (rk_…, Developers → API keys → Restricted) with only the scopes it needs. It sees only the tools those scopes allow: a key without refunds:write has no create_refund. Add an IP allowlist if the agent runs at a fixed address.

get_card_details needs card_details:read. A key has it only if you add it by name when you create the key. A secret key never has it.

Clients that support remote MCP take the URL and an Authorization: Bearer <key> header. Stdio-only clients run @tuppence/mcp, a small local server that forwards to the remote one.

Terminal window
claude mcp add tuppence --env TUPPENCE_API_KEY=rk_test_… -- npx -y @tuppence/mcp

Use the TUPPENCE_API_KEY environment variable rather than --api-key, because other processes can read command lines. TUPPENCE_ACCOUNT=acct_… (or --account) makes every tool act as one connected account.

Rule
idempotency_keyRequired on every tool that moves money, and on create_booking. Use a unique string per operation and resend it unchanged on a retry, so a retry doesn’t pay twice. Tuppence doesn’t derive one for the agent, because MCP request ids are small per-session numbers that unrelated calls would share.
ErrorsA refused call returns the API’s error (code, message, param) for the agent to read and correct.
AuditTool calls appear in your request logs and audit log as made by an agent (by a key), or by the app and its person (signed in).
People decideNo tool moves pending money, switches next-day payouts or submits a dispute on its own. It returns an approve_url or approval_id for a person. Tuppence staff decide Direct Debit applications.
search_docsNeeds no scope. Any key can search these docs, so an agent can look up how to integrate Tuppence as it works.
ToolDoes
create_payment_link, get_payment_link, list_payment_links, update_payment_link, expire_payment_linkPayment links
create_payment, get_payment, list_paymentsPayments. create_payment returns an approval_url for a person to pay
capture_paymentCaptures a held payment (requires_capture, from capture_method: manual), in full or up to amount, before capture_before
cancel_paymentCancels a payment that has not succeeded and releases a held payment’s money. Destructive
charge_saved_cardAn off-session charge under a customer’s mandate
create_refundRefunds. Marked destructive for the client
create_customerCustomers
create_plan, create_subscription, get_subscription, cancel_subscriptionSubscriptions: a plan’s price never changes; a subscription needs a saved card; cancelling is at period end unless now: true
record_usage, get_credit_balance, create_credit_topupPrepaid credit and metering
get_direct_debit, apply_for_direct_debitDirect Debit: status, limits, usage, price, and applying with a reason. Tuppence staff decide; no tool approves, declines or changes limits
list_payment_method_domains, add_payment_method_domain, remove_payment_method_domainDomains your checkout runs on, for Apple Pay and Google Pay (wallets on your own domain)

A platform’s agent acts as one of its connected accounts through any tool’s account argument (acct_…). It works like the Tuppence-Account header on the REST API, with the same refusals:

{ "name": "create_booking", "arguments": { "account": "acct_…", "items": [{ "service": "svc_…" }], "starts_at": "…", "idempotency_key": "…" } }
CaseAnswer
An account the key cannot act asaccount_invalid
account on the platform’s own Connect tools (accounts, links, transfers, fees)connected_account_not_allowed
A Connect tool about an accountIt takes connected_account instead

The Connect tools need the connected_accounts scopes (account_links:write for onboarding links, transfers:write for transfers, application_fees:read for the fees).

An agent’s card works wherever the merchant charges it without asking the cardholder (API and SaaS billing, subscriptions, top-ups) and at most low-value checkouts (in the UK, under £30).

To enter the card at a checkout, the agent needs its number. get_card_details returns an active virtual card’s number, CVC and expiry (your business’s own, or an agent’s; a request an agent signs reads only that agent’s cards) to a key made with card_details:read, where the account’s owner has allowed it. Use a single-use card locked to the merchant, send the details only to the merchant’s payment form, and never store, print or log them. Every read is audited and sent as card.details_retrieved. See See a card’s details.

An agent prepares a card dispute. A person submits it.

  1. draft_card_dispute takes card_transaction (a capture, ctx_…) and reason, and optionally explanation, evidence and amount. When the agent made the purchase, the evidence is prefilled from its records: the person’s approval, the cart and the mandate.
  2. add_card_dispute_evidence (dispute, plus reason, explanation, evidence or amount) adds what the reason still needs. Files go through POST /v1/card_disputes/{id}/files or the dashboard, not MCP.
  3. submit_card_dispute (dispute) checks the evidence and reports anything missing. It then opens an approval and returns object: "card_dispute_submission", status: "pending_approval" and the approval_id (apr_…).
  4. Poll get_approval with that id until a person approves in the dashboard or app. The dispute is submitted in their name. If they decline, the draft is unchanged.

A dispute is submitted once, as the business’s statement to the card network. Submitting the same dispute again returns the same approval.

create_agent_card is subject to the account’s card limits. When a limit blocks it, the error carries limit, used, max, resets_at and increase_url, and a retry gets the same answer. Use a card the agent already has, wait until resets_at, or ask a person to request higher limits. get_issuing_limits shows the numbers up front.

  • Agent frameworks: the same tools in OpenAI Agents, LangChain and the Claude Agent SDK.
  • HTTP 402: charge agents for your own API.

Docs assistant

Open as a page
Loading the assistant…