MCP server
@usethrottle/mcp connects Throttle to
AI assistants that speak the Model Context Protocol — Claude Code, Claude
Desktop, Cursor, and anything else with an MCP client. It reads your
commerce data, diagnoses failing checkouts, searches these docs, and
checks request bodies against the published contract before you write
code against it.
Install
The server runs locally over stdio and authenticates with a secret sk_ API key, exactly like the CLI.
# Claude Code
claude mcp add throttle -e THROTTLE_API_KEY=sk_uat_... -- npx -y @usethrottle/mcp
For Claude Desktop or any client that reads an mcpServers config:
{
"mcpServers": {
"throttle": {
"command": "npx",
"args": ["-y", "@usethrottle/mcp"],
"env": { "THROTTLE_API_KEY": "sk_uat_..." }
}
}
} pk_) keys are rejected:
they carry only browser-safe compute scopes and cannot read data.
Hosted / remote server
For clients that speak MCP over HTTP instead of stdio — n8n's MCP
Client Tool node, for example — connect directly to https://mcp.usethrottle.dev/mcp
(Streamable HTTP) instead of running
@usethrottle/mcp
locally. Send the same secret key as an Authorization: Bearer sk_... header
— no separate provisioning, no OAuth. The tool surface, scopes, and
read-only behavior are identical to the local server; the only
difference is transport.
curl https://mcp.usethrottle.dev/mcp \
-X POST \
-H "Authorization: Bearer sk_uat_..." \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' A session is created on your first call and reused for the rest of the connection; it is torn down after 30 minutes of inactivity or an explicit client disconnect.
Claude's custom-connector
static_headers
auth type (Bearer token, no OAuth) works with this endpoint but is
currently rolled out selectively by Anthropic. ChatGPT's Developer
Mode does not support API-key auth for custom connectors at all — only
OAuth or no auth — so it cannot use this endpoint yet.
As of this change, the server also supports real OAuth 2.1
(authorization_code + PKCE +
refresh) for both platforms' native connector/directory flows,
once each platform's OAuth client is registered. This is in
addition to, not instead of — the
static_headers
path above still works too.
customers:read and payments:read are OAuth-grantable,
so search_customers, get_customer, search_payments and get_payment
register on hosted/OAuth sessions too, not only on sk_ API keys.
What it can do
Tools are registered per session based on what your key is actually allowed to do, so a read-only key produces a read-only toolset rather than tools that fail when called.
- whoami — which workspace, application and environment this key is pinned to, and whether it is production.
- search_docs — full-text search over these docs, with canonical links.
- describe_endpoint and validate_payload — the request shape of any endpoint, and a pre-flight check of a body against the published OpenAPI contract.
- api_get — a GET-only escape hatch for any
/api/v1path the curated tools do not cover. It cannot write. - get_order, get_customer, search_orders, search_customers, list_subscriptions, search_quotes, list_invoices, receivables_aging —
commerce reads, with related records inlined where an answer usually
needs them. search_orders, search_customers, list_subscriptions
and search_quotes also accept
createdAfter/createdBefore(ISO 8601; both bounds are exclusive). - explain_checkout_failure — session state, cart, emitted events and recent webhook deliveries for one failing checkout, in a single call.
- get_integration_status — connectors, webhook endpoints and delivery health: “am I ready to go live?”
- search_discounts, get_discount — discount codes: value, conditions, usage limits and redemption count.
- search_payments, get_payment — payments as a standalone search, with full transaction history on the by-id read.
- get_invoice — a single issued invoice by id.
- list_abandoned_carts — carts started but never finalized, with recovery status and a summary.
- list_extension_installations — extensions installed on this application, with status and configuration.
- get_connector_routing — payment-routing cascade, active routing connectors, and card/other decline rules.
- get_workspace_settings, get_audit_log — workspace identity/branding/net30 defaults, and recent admin actions on this workspace.
- list_applications — every application in this
workspace you have access to, so an agent can pass one of their
ids as
applicationIdon the read and analytics tools above to read a sibling application instead of the one this connection was authorized for. - get_sales_timeseries — order count and gross revenue bucketed by day, week or month over any date range, in the merchant's timezone, optionally compared to the previous period or the same range last year.
- get_business_summary — orders/revenue, subscription
MRR, receivables and quotes pipeline over a date range, compared to
the prior window of equal length.
periodmeans the trailing 7/30/90 days, not a calendar period — passfrom/to/timezonefor calendar months. - get_attention_digest — open disputes, subscriptions in dunning, overdue Net-N invoices, and webhooks with degraded delivery health, all in one call.
- get_top_products — best sellers by gross revenue or units sold over a date range, identified by external reference id when the line item carries one, by name otherwise.
- get_customer_growth — signups per day, week or month, the split between first-time and returning-customer orders, and the highest-value customers in the window.
- get_revenue_breakdown — gross revenue split by payment method, order source, or currency over a date range.
- get_funnel_conversion — carts created, checkout sessions started and orders completed over a date range, with the drop-off between each stage.
- get_subscription_movement — new subscriptions, cancellations and net MRR change per day, week or month.
- get_discount_performance — redemptions, gross revenue on discounted orders, and total discount given, per code, over a date range.
- search_events, list_webhook_deliveries, get_webhook_delivery — the event log and outbound delivery records, including the payload we sent and the response we got.
- seed_test_data — a customer, cart, line items and a finalized draft order so a fresh integration has something to read. Refuses to run against production.
Catching field-name mistakes before they 400
Throttle's public API is strict camelCase and rejects retired aliases. Those aliases are exactly what a model tends to guess, so the server names the replacement instead of letting you find out from a 400.
// The assistant checks a body before writing integration code.
validate_payload({
method: 'POST',
path: '/api/v1/carts/{id}/items',
body: { name: 'Widget', unit_price: 2500, storeId: 'store_123' }
})
// →
{
"ok": false,
"matched": "POST /api/v1/carts/{id}/items",
"errors": [
{ "field": "unit_price", "problem": "retired public field name — the API rejects it",
"suggestion": "use \"unitPrice\"" },
{ "field": "storeId", "problem": "retired public field name — the API rejects it",
"suggestion": "use \"applicationId\"" },
{ "field": "unitPrice", "problem": "required field is missing" }
]
} Writes
Five write tools are available behind an explicit --allow-writes flag (a second --allow-live-writes gate is
required for production keys), each with an idempotency key on every
call. Holding a write scope means the key may write; the
flag is how you say you intended it to.
- seed_test_data — sandbox only, refused outright on a production credential, no flag needed.
- send_test_webhook, replay_webhook_delivery — synthetic and re-sent deliveries. Safe on Throttle's side; a replay only carries real risk if the receiving endpoint isn't idempotent.
- manage_subscription — pause or resume. A fully reversible pair; nothing about it is buyer-visible in a way that can't be undone.
- create_quote — drafts a quote. Nothing is sent to
the buyer until a future release adds
send_quote.
refund_payment, cancel_subscription, and send_quote move real money, end a
paying customer's billing, or email a real buyer — all
irreversible or externally-visible. They're held for a follow-up
release with a code-enforced confirmation step, not just a prompt-level
warning.
Options
-
--api-key <key>— or theTHROTTLE_API_KEYenvironment variable. -
--api <url>— orTHROTTLE_API_URL. Defaults tohttps://api.usethrottle.dev. -
--allow-writes,--allow-live-writes— reserved for the write tools described above.