# Connect an AI agent (MCP)

Spicy API runs a remote MCP server so a coding agent or assistant can quote prices, check the balance, hand the user a top-up link, generate images and video, and watch spend on the user's account. The human approves each spend in the chat. Endpoint: `https://www.spicyapi.com/api/mcp` (Streamable HTTP, stateless).

## Install

### Claude Code

```bash
claude mcp add --transport http spicyapi https://www.spicyapi.com/api/mcp --header "Authorization: Bearer sk-spicy-..."
```

Or leave the header off and run `/mcp` to sign in with OAuth.

### Cursor

```json
{
  "mcpServers": {
    "spicyapi": {
      "url": "https://www.spicyapi.com/api/mcp",
      "headers": { "Authorization": "Bearer sk-spicy-..." }
    }
  }
}
```

### Codex

```toml
[mcp_servers.spicyapi]
url = "https://www.spicyapi.com/api/mcp"
bearer_token_env_var = "SPICYAPI_KEY"
```

### Claude custom connectors, ChatGPT and other OAuth clients

Paste the URL `https://www.spicyapi.com/api/mcp` and nothing else. The client discovers the authorization server, opens https://www.spicyapi.com/oauth/authorize, and the user signs in (or creates the account there) and clicks Allow. OAuth 2.1 with dynamic client registration and PKCE; no client secret.

## Two ways to authenticate, one kind of credential

- **API key**: `Authorization: Bearer sk-spicy-...`, the same keys as the REST API, from https://www.spicyapi.com/dashboard/api-keys.
- **OAuth 2.1**: metadata at `https://www.spicyapi.com/.well-known/oauth-authorization-server`, registration at `POST https://www.spicyapi.com/oauth/register`, token at `POST https://www.spicyapi.com/oauth/token` (authorization_code with PKCE S256). The access token it returns is an API key named "OAuth: <app>", so it shows up in the dashboard and is revoked there. On the consent screen the user can tick "Sandbox only" to grant a token that can never spend.

## Tools

| Tool | What it does | Needs approval |
|---|---|---|
| `list_models` | Models with prices, limits and example clips | no |
| `estimate_cost` | Price a request from the billing table | no |
| `get_account` | Balance, month-to-date spend, spend limit | no |
| `list_images` | The account's generated images (valid inputs for edits and video) | no |
| `generate_image` | Text to image, returns CDN URLs | yes |
| `edit_image` | Prompt-driven edit of the account's own images | yes |
| `generate_video` | Image to video or text to video, returns a task | yes |
| `get_job` | Poll a video task | no |
| `list_jobs` | Recent requests with status and cost | no |
| `get_usage` | Calls and cost by model over N days | no |
| `create_api_key` | Mint a key (live or sandbox), shown once | yes |
| `revoke_api_key` | Revoke a key | yes |
| `get_topup_link` | Checkout URL (card or crypto) for the user to pay in the browser | no |
| `set_spend_limit` | Monthly cap enforced at debit time | raising it, yes |
| `read_acceptable_use` | The acceptable use policy as markdown | no |

Every tool carries `readOnlyHint`, `destructiveHint` and `openWorldHint` annotations. The same tools are plain REST at `POST https://www.spicyapi.com/api/v1/tools/{tool_name}` (list with `GET https://www.spicyapi.com/api/v1/tools`), described in https://www.spicyapi.com/openapi.json.

## Approvals

A guarded tool called without `approval_token` spends nothing and returns:

```json
{"error": "approval_required", "summary": "Generate 1 image on spicy-image-1 for $0.06", "approval_token": "...", "expires_in_seconds": 900}
```

The agent shows the summary to the user, gets a yes, and calls again with the same arguments plus the token. Tokens are bound to the account, the tool and the exact arguments, and expire in 15 minutes. Accounts that run agents unattended can turn approvals off at https://www.spicyapi.com/dashboard/api-keys; moderation, provenance, balance and the spend limit still apply.

## Sandbox

A sandbox key (tick Sandbox when creating a key, or on the OAuth consent screen) answers every tool and every REST endpoint from fixtures flagged `sandbox: true`. Nothing is generated or billed and no balance is needed. Build against it, then swap the key.

## A first prompt to try

> Use the spicyapi tools. Read the acceptable use policy, list the video models with prices, estimate 10 five-second clips at 720P, and tell me what it would cost. Do not generate anything yet.

## Paying

The agent never handles payment details. `get_topup_link` returns a hosted checkout URL (minimum $50); the user pays in the browser; `get_account` confirms the new balance.

## Skills

Ready-made SKILL.md workflows (integrate the API, image to video, control spend, choose a model): https://www.spicyapi.com/skills/index.json, mirrored at https://github.com/Wayfinity/spicyapi-skills. Registry name: `com.spicyapi/mcp`.

## Limits and logging

60 requests per minute per key. Each tool call is logged as tool name, key id, success or error code, latency and the sandbox flag. Prompts, arguments and outputs are never stored in that log.
