# MCP for AI agents

> Connect AI assistants and IDEs straight to your Soca account over the Model Context Protocol: the /api/mcp remote server, OAuth 2.1 or API-key auth, and the tools it exposes for invoices, plans, usage, credits, and entitlements.

Part of the Soca documentation (https://soca.finance/docs). Human version: https://soca.finance/docs/developers/mcp
The Model Context Protocol (MCP) is an open standard that lets AI clients, including Claude, IDEs, and agent frameworks, call external tools directly. Soca ships a remote MCP server that exposes the developer API as tools, so an AI can create invoices and plans and read your payment data on your behalf, with your approval.

## Connecting

Add a remote MCP connector pointing at:

```text
https://soca.to/api/mcp
```

The path is always `/api/mcp` on whatever host serves your Soca deployment. If you self-host, use your own origin. The server speaks Streamable HTTP: JSON-RPC 2.0 over `POST /api/mcp`, with single responses returned as plain JSON.

## Authentication

There are two options. Both end up scoped to exactly one merchant and one mode, the same isolation as the [REST API](/docs/developers/authentication):

- **OAuth 2.1 (recommended for AI clients).** The client discovers the authorization server at `/.well-known/oauth-authorization-server`, registers itself (dynamic client registration is supported), and walks you through a consent screen; PKCE with S256 is required. An unauthenticated request to `/api/mcp` returns `401` with a `WWW-Authenticate` header pointing at the resource metadata (`/.well-known/oauth-protected-resource`), which is how OAuth-capable clients find the flow on their own.
- **Static API key.** Send `Authorization: Bearer sk_live_...` (or `sk_test_...`): the same secret key as the REST API. Simpler for server-side agents you run yourself.

## The tools

| Tool | What it does |
| --- | --- |
| `create_invoice` | Create a one-time USDC invoice (`amount`, `description`, …) and get a hosted `checkout_url` to send the customer. |
| `create_plan` | Create a subscription plan and get a hosted `checkout_url`. Fixed, or `usage_type: "metered"` to auto-charge usage each period up to a cap. |
| `create_meter` | Create a meter (`key`, `display_name`, `aggregation`) — the named thing usage is recorded against. |
| `create_feature` | Create a feature to gate with entitlements (`boolean` or `metered`). |
| `create_meter_event` | Record one usage event against a meter (`event_name`, `customer_id`, `value`, `idempotency_key`). |
| `grant_credits` / `debit_credits` | Top up or draw down a customer's prepaid balance. Idempotent. |
| `get_credit_balance` | Read a customer's balance plus lifetime granted/consumed. |
| `grant_entitlement` / `check_entitlement` | Grant a feature to a customer, and ask yes/no whether they may use it now. |
| `list_payments` | List recent payments, newest first (`limit`, `before`). |
| `list_subscriptions` | List subscriptions, newest first (`limit`, `before`). |
| `list_invoices` | List invoices, newest first (`limit`, `before`). |
| `list_events` | List the event feed, newest first (`limit`, `before`). |
| `list_meters` | List your meters, newest first (`limit`, `before`). |

Every tool runs through the exact same validation and creation code as its [REST endpoint](/docs/developers/api-reference) — one implementation serves both surfaces, so they cannot drift. Amounts are USDC base units here too. For a usage-based plan, `create_meter` first, then reference its id as `create_plan`’s `meter`.

## What it looks like in practice

Once connected, you work in plain language. Ask your AI client:

- "Invoice Acme $250 for the March retainer and give me the payment link.": the agent calls `create_invoice` and hands back the `checkout_url`.
- "Set up a $9/month Pro plan.": `create_plan`, returning the subscription checkout link.
- "What did we collect this week?": `list_payments`, summarized by the model.
- "Did invoice INV-1041 get paid?": `list_invoices` / `list_events`.

## Properties worth knowing

- **Stateless.** No sessions or server-initiated SSE stream. Each request stands alone (`GET /api/mcp` returns 405). Any number of clients can connect concurrently.
- **Mode-scoped.** A test credential can only ever touch test data. Connect with an `sk_test_` key first to try things safely.
- **Rate limited.** 120 requests per minute, like the REST read endpoints.
- **Money-safe by design.** The tools create payable objects and read state; they cannot move funds, change your settlement wallet, or issue refunds.

> AI tools that just want documentation rather than a live connection can read [/llms.txt](/llms.txt) and [/llms-full.txt](/llms-full.txt): machine-readable versions of this documentation.
