Tools

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.

bash
# 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:

json
{
  "mcpServers": {
    "throttle": {
      "command": "npx",
      "args": ["-y", "@usethrottle/mcp"],
      "env": { "THROTTLE_API_KEY": "sk_uat_..." }
    }
  }
}
Mint a dedicated key
The key pins the workspace, application and environment — there is no way to switch from inside a tool call. Create a key that holds only the scopes the assistant needs, and start with a non-production environment. Publishable (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.

bash
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 and ChatGPT connectors

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/v1 path 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 applicationId on 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. period means the trailing 7/30/90 days, not a calendar period — pass from/to/timezone for 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.

javascript
// 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.
Refunds, cancellations and sending a quote aren't available yet
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 the THROTTLE_API_KEY environment variable.
  • --api <url> — or THROTTLE_API_URL. Defaults to https://api.usethrottle.dev.
  • --allow-writes, --allow-live-writes — reserved for the write tools described above.
Two environments means two entries
A key belongs to one environment. To let an assistant see both your production and a sandbox environment, add two server entries with different keys and distinct names.