MCP server

Connect any agent to CashSDK with the hosted MCP server at https://mcp.cashsdk.com/mcp: Streamable HTTP, OAuth 2.1 or a bearer token.

The CashSDK Model Context Protocol server is hosted, so there is nothing to install. It's a thin, stateless proxy over the CashSDK REST API: every tool maps to an API call made with the token you send, so an agent can create apps, manage catalog, build paywalls, wire webhooks and read revenue without ever holding your dashboard session.

URLhttps://mcp.cashsdk.com/mcp
TransportStreamable HTTP (remote)
AuthOAuth 2.1, or Authorization: Bearer csk_mcp_…
CostFree on every plan, including the sandbox

Choose how to authenticate#

OAuth, no token to manage

For OAuth-capable clients, including Codex, Claude Code, Claude on the web, and Claude Desktop. Add the URL, sign in and approve in the browser.

MCP token, one header

For a client or environment without browser sign-in, create a scoped token in the dashboard and use an Authorization header.

Get an MCP token#

Dashboard → Settings → MCP → Create token. Copy it immediately; the full value is shown once and stored only as a hash.

  • Workspace-wide by default, so an agent can call list_apps and create_app before any app exists.
  • Narrow it to one app if you'd rather it could only touch that one. The restriction is real. A narrowed token gets 403 on a sibling app in the same workspace.
  • Choose Read only for analytics, diagnostics, and support agents that should inspect state without changing it. Read-only tokens receive 403 for every mutating API call, including calls made through MCP tools.
  • It does not expire. Revoke it in the dashboard when you're done, and any agent using it stops on its next call.

Any CashSDK token grants API access. Never commit one. If a config file is checked into your repo, put a placeholder there and have each developer supply their own.

Or use the setup token#

Quickstart’s Generate Prompt defaults to browser sign-in and contains no token. Choose Generate token fallback only when needed: it issues a csk_st_… token restricted to one app and provisioning actions. It expires in 24 hours; issuing another revokes the last. Other integration-prompt entry points may still issue this token directly. Use OAuth or an csk_mcp_… token for an ongoing connection.

Browser approval is not proof of tool access. After signing in and approving the intended workspace/app, call get_setup_checklist for that app. OAuth can permit broader operations than a setup token; review permissions and restrict access to the app. The user, not the agent, must approve consent.

Client configuration#

Header-based clients need the URL and an Authorization header:

json
{
  "mcpServers": {
    "cashsdk": {
      "url": "https://mcp.cashsdk.com/mcp",
      "headers": { "Authorization": "Bearer csk_mcp_..." }
    }
  }
}

The exact file differs per client. See Claude Code, Cursor and Codex. For Claude on the web or Claude Desktop, add a custom connector and paste https://mcp.cashsdk.com/mcp; you'll be asked to sign in and pick a workspace.

Verify it's connected#

bash
curl -s https://mcp.cashsdk.com/mcp \
  -H "Authorization: Bearer csk_mcp_..." \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | head -c 400

A list of tools comes back. Without a valid credential you get 401 with a WWW-Authenticate header carrying resource_metadata. That pointer is what tells an OAuth client where to authenticate, and what tells a token client its token has been revoked or has expired.

If the connection works but newer platform tools are missing, refresh the client's MCP tool list or disconnect and reconnect CashSDK, then start a new agent conversation. Some clients keep the tool schema loaded when the conversation began. Reconnecting an existing client updates that catalog; reinstalling an SDK does not. Confirm that get_integration_snippets is available before setting up web, direct macOS, Chrome extensions or standalone Stripe. If it is still missing, check the configured server URL and report the missing tool with your client version.

What an agent can't do#

Some of the API is refused for every MCP token, at every role, regardless of what the person who created it can do in the dashboard. An agent reads store listings, webhook payloads and READMEs, any of which can try to steer it, so the boundary is drawn in code rather than left to a prompt:

RefusedWhy
Billing, partner payouts, revenue-history importMoves real money, or what you're billed
Team members, invitations, SSO, SCIMDecides who can get in
Deleting a workspace, closing an accountIrreversible
Uploading store credentials (.p8, service-account JSON)A human step; the raw file shouldn't pass through a model
Rotating the ingest tokenSilently breaks store notifications until a human repastes the URL
Reading or rotating the user-token signing secretLets its holder impersonate any app customer
Bulk data exportBulk PII egress
Creating another MCP token or a setup credentialOtherwise a token can extend or widen its own delegation

Within what's left, a token can never exceed the member who created it, and every call passes the same AccessService and role checks a dashboard session does. The token's own read/write permission is enforced in addition to those checks.

An app-scoped token cannot call workspace-wide routes, including listing or creating apps. Use a workspace token when those operations are intended. Setup tokens can only be issued by an owner/admin and act as that issuer while their membership remains active and privileged. They cannot create/rotate SDK keys or register webhook endpoints; add those in the dashboard.

Every change an agent makes lands in your workspace audit log with actorType: "agent" (or agent_setup for the onboarding setup token), alongside the member whose credential it used, so "was that change mine or my agent's?" has an answer. Reads are not logged, on MCP or anywhere else.

Rate limits#

EndpointLimit
POST /mcp1000 requests/min per IP
POST /oauth/register20/hour per IP
POST /oauth/token120/min per IP

Set well above what a working agent does (a busy setup session bursts dozens of tool calls a minute) so you should never see one. They exist because these endpoints are unauthenticated by construction and would otherwise be free database load.

Every platform, including Stripe only#

Call list_supported_platforms for the current choices and distribution status: ios, macos (Mac App Store), android, web, macos-direct, chrome-extension and stripe. Create apps with platforms; a bundle ID is only required when a native store is selected. update_app_settings accepts the full platform list when adding a channel.

ToolPurpose
get_integration_snippetsPlatform-specific code; pass any platform ID
get_macos_integration_snippetsMac App Store Swift integration
get_web_integration_snippetsBrowser, React and server integration
get_macos_direct_integration_snippetsNative Swift with Stripe
get_chrome_extension_integration_snippetsManifest V3 extension integration
get_stripe_integration_snippetsExisting Stripe Checkout and server access, no client SDK
get_commerce_configurationOrigins, session settings and whether checkout is available
configure_commerceSave origins and turn sessions on or off; a change to either revokes existing sessions in the environment
list_marketplace_user_linksInspect provider-to-user mappings
list_unlinked_subscriptionsFind subscriptions waiting for an app-user identity
link_marketplace_userAssign a verified identity and replay pending state; can move access

Commerce configuration and identity writes require owner/admin OAuth or a write-enabled MCP token. Setup tokens may read commerce configuration and snippets; they cannot change origins, install provider credentials, import Stripe prices, sync provider history or reassign customer access. Use the dashboard for those steps when working with a setup token.

Read the platform guides for package availability and verification. A sandbox check does not certify production: follow Go live with Stripe before taking real payments.

Tools#

Tools are grouped by what they touch. Each maps directly onto a REST endpoint, so results are the same JSON your backend would receive.

Workspace

| Tool | Description | | --- | --- | | list_apps | Every app in the workspace. Start here with no app id. | | create_app | Create an app with its platform choices and any required store identifiers. | | get_app | Fetch an app's configuration. | | update_app_settings | Change app-level settings. |

Setup & diagnostics

| Tool | Description | | --- | --- | | get_setup_checklist | The live go-live checklist and what's outstanding. | | get_setup_diagnostics | Store-side problems, each with its fix. | | get_ios_integration_snippets | Ready-to-paste iOS integration code. | | get_android_integration_snippets | The same for Android. |

Catalog

| Tool | Description | | --- | --- | | get_catalog | List products and entitlements. | | create_product | Create a product (subscription or one-time). | | create_entitlement | Create an entitlement. | | grant_entitlement | Grant an entitlement to a customer. | | sync_catalog_from_app_store | Pull catalog data from the App Store or Google Play. | | push_catalog_to_app_store | Push your CashSDK catalog to the store. |

Paywalls, placements & experiments

| Tool | Description | | --- | --- | | list_templates | List available paywall templates. | | list_paywalls | List existing paywalls. | | get_paywall | One paywall's config, published and draft. | | create_paywall | Create a paywall from scratch. | | create_paywall_from_template | Create a paywall from a template. | | generate_paywall | Generate a paywall from a natural-language brief (draft only). | | publish_paywall | Publish the draft so devices receive it. | | list_placements | List placements. | | create_placement | Create a placement. | | list_campaigns | List campaigns. | | create_campaign | Create a campaign, or an A/B split with a holdout. | | get_experiment_results | Per-variant conversion, revenue and significance. |

Customers, revenue & keys

| Tool | Description | | --- | --- | | get_customer | Fetch a customer and their entitlements. | | list_transactions | List transactions. | | tail_recent_events | The most recent events. | | get_revenue_overview | Revenue, active subscriptions, trials and churn. | | list_api_keys | Key ids and masked values, never a raw secret. | | create_api_key | Create a new API key. | | rotate_api_key | Rotate an existing API key. |

Store notifications & webhooks

| Tool | Description | | --- | --- | | get_store_notification_urls | The ASSN (Apple) / RTDN (Play) URL to paste into the console. | | request_apple_test_notification | Ask the store to send a test notification. | | list_webhook_endpoints | Endpoints registered for an app. | | register_webhook_endpoint | Register a webhook endpoint URL. | | send_test_webhook | Send a test event to a webhook endpoint. |

Marketplace

| Tool | Description | | --- | --- | | list_marketplace_apps | Every connector this workspace can connect. | | list_marketplace_connections | What's connected, with lifecycle status. | | get_marketplace_status | One connection in full. | | connect_marketplace_app | Connect a billing backend or integration. | | start_marketplace_oauth | Begin a “Connect with X” OAuth flow. | | map_marketplace_catalog | Map a provider's plans to CashSDK products. | | list_stripe_prices | The connected Stripe account's prices, and which can be imported. | | import_stripe_prices | Create products from Stripe prices. | | sync_stripe | Pull existing Stripe subscriptions, payments and refunds. | | get_stripe_sync | Progress and counts of the latest Stripe sync. | | validate_marketplace_connection | Check credentials, secret and mappings. | | activate_marketplace_connection | Start events flowing into the ledger. | | pause_marketplace_connection | Pause without disconnecting. | | disconnect_marketplace_app | Disconnect and wipe stored credentials. |

OAuth details#

For anyone implementing against it directly:

Endpoint
Protected-resource metadata/.well-known/oauth-protected-resource (RFC 9728)
Authorization-server metadata/.well-known/oauth-authorization-server (RFC 8414)
Dynamic client registrationPOST /oauth/register (RFC 7591)
AuthorizationGET /oauth/authorize
TokenPOST /oauth/token
RevocationPOST /oauth/revoke (RFC 7009)

PKCE is required and only S256 is accepted. Access tokens live one hour; refresh tokens live 30 days and rotate on every use. Redirect URIs are matched exactly against what the client registered, with a loopback exception for native clients (RFC 8252 §7.3).

Per-client setup#

Next steps#