# MCP: Scarleta API reference

Page: https://www.scarleta.ai/docs/reference/mcp
Base URL: https://api.scarleta.ai. Authentication: `Authorization: Bearer $SCARLETA_API_KEY`.
Operations: 2.

## GET /v1/mcp/rpc

Operation id: `open_mcp_event_stream`

**Open the MCP event stream**

Opens the Server-Sent Events channel of the MCP transport. Send `Accept: text/event-stream` and your API key. The answer is `200` with `Content-Type: text/event-stream` and stays open; the server does not send events on it today, because every request is answered on its own. Most clients do not need it: use `POST /v1/mcp/rpc`. Without `text/event-stream` in `Accept` the answer is `406`.

Access: API key required; free and paid accounts. Cost: no token cost.

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `Accept` | header | string | yes | Must list `text/event-stream`. |

### Responses

200: The stream is open (`Content-Type: text/event-stream`). The response has no body to read; it ends when you close it.

```text
(empty body)
```

401: The Authorization header is missing, not a Bearer key, or the key is unknown or revoked. A challenge header `WWW-Authenticate: Bearer` is sent. No tool runs and nothing is charged.

```json
{
  "error": {
    "message": "Authorization header required"
  }
}
```

406: The `Accept` header does not list `text/event-stream`.

```json
{
  "jsonrpc": "2.0",
  "error": {
    "code": -32000,
    "message": "Not Acceptable: Client must accept text/event-stream"
  },
  "id": null
}
```

429: Too many requests from your IP address in the hour. Wait for the `Retry-After` header, then retry.

```json
{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Rate limit exceeded. You can make 300 requests per hour. Please try again later.",
    "request_id": "req_5b1c0f3e-2d41-4a8e-9a57-0c1b2d3e4f50",
    "docs_url": "https://www.scarleta.ai/docs/errors#rate_limit_exceeded"
  }
}
```

### Error codes

[`rate_limit_exceeded`](https://www.scarleta.ai/docs/errors#rate_limit_exceeded), [`rate_limit_unavailable`](https://www.scarleta.ai/docs/errors#rate_limit_unavailable)

### Example

```bash
curl "https://api.scarleta.ai/v1/mcp/rpc" \
  -H "Authorization: Bearer $SCARLETA_API_KEY" \
  -H "Accept: text/event-stream" \
  -i \
  --max-time 5
```

## POST /v1/mcp/rpc

Operation id: `mcp_rpc_request`

**Send an MCP request**

The Model Context Protocol endpoint for AI clients. Send one JSON-RPC 2.0 message per request: `initialize`, then `tools/list` to see the tools and `tools/call` to run one. It is stateless: there are no sessions, so every request stands alone and answers with plain JSON. The request must send `Accept: application/json, text/event-stream`. Authenticate with your API key as `Authorization: Bearer <key>` like every other route. This endpoint is switched on in production. The tools are listed on the [MCP tools page](/docs/reference/mcp-tools); a long-running tool answers with a `job_id` that you read with the `get_analysis_result` tool. Protocol failures are JSON-RPC errors, often with HTTP `200`. Failures before the protocol (sign-in, bad `Content-Type`, bad `Accept`, unreadable JSON) are HTTP errors whose body is documented below; they do not use the standard error body. Requests are also limited per IP address: at most 300 per hour, then `429 rate_limit_exceeded`. A notification (a message with no `id`) is answered `202` with no body.

Access: API key required; free and paid accounts. Cost: uses tokens. Initializing, listing tools and reading a result are free. Calling an audio tool uses tokens at the same rate as the matching analysis: 1 token is 1 second of audio..

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `Accept` | header | string | yes | Must list both `application/json` and `text/event-stream`, for example `application/json, text/event-stream`. |

### Request body

| Field | Type | Description |
| --- | --- | --- |
| `jsonrpc` | "2.0" |   |
| `id` | string \| number | Request id echoed in the answer. Leave it out to send a notification, which gets no answer body. |
| `method` | string | The method: `initialize`, `tools/list`, `tools/call`, `resources/list` or `notifications/initialized`. |
| `params` | object | Method parameters. `tools/call` takes `{ name, arguments }`. |

### Response fields (inside `data`)

| Field | Type | Description |
| --- | --- | --- |
| `jsonrpc` | "2.0" |   |
| `id` | string \| number \| null | The `id` of the request this answers; null when the request could not be read. |
| `result` | object | The result of the method, present when the call succeeded. |
| `error` | object | Present when the call failed at the protocol level. |
| `error.code` | integer | A JSON-RPC error code, for example `-32601` for an unknown method. Allowed: -9007199254740991 to 9007199254740991. |
| `error.message` | string |   |
| `error.data` | any |   |

### Responses

200: A JSON-RPC answer: `result` on success, `error` for a protocol failure such as an unknown method. A `tools/call` that fails inside the tool answers a `result` with `isError: true`.

```json
{
  "result": {
    "protocolVersion": "2025-03-26",
    "capabilities": {
      "tools": {},
      "resources": {}
    },
    "serverInfo": {
      "name": "Scarleta Audio MCP",
      "version": "1.0.0"
    }
  },
  "jsonrpc": "2.0",
  "id": 1
}
```

202: A notification was accepted. The body is empty.

```text
(empty body)
```

400: The body is not valid JSON.

```json
{
  "jsonrpc": "2.0",
  "error": {
    "code": -32700,
    "message": "Parse error: Invalid JSON"
  },
  "id": null
}
```

401: The Authorization header is missing, not a Bearer key, or the key is unknown or revoked. A challenge header `WWW-Authenticate: Bearer` is sent. No tool runs and nothing is charged.

```json
{
  "error": {
    "message": "Authorization header required"
  }
}
```

406: The `Accept` header does not list both `application/json` and `text/event-stream`.

```json
{
  "jsonrpc": "2.0",
  "error": {
    "code": -32000,
    "message": "Not Acceptable: Client must accept both application/json and text/event-stream"
  },
  "id": null
}
```

415: The `Content-Type` is not `application/json`.

```json
{
  "jsonrpc": "2.0",
  "error": {
    "code": -32000,
    "message": "Unsupported Media Type: Content-Type must be application/json"
  },
  "id": null
}
```

429: Too many requests from your IP address in the hour. Wait for the `Retry-After` header, then retry.

```json
{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Rate limit exceeded. You can make 300 requests per hour. Please try again later.",
    "request_id": "req_5b1c0f3e-2d41-4a8e-9a57-0c1b2d3e4f50",
    "docs_url": "https://www.scarleta.ai/docs/errors#rate_limit_exceeded"
  }
}
```

### Error codes

[`rate_limit_exceeded`](https://www.scarleta.ai/docs/errors#rate_limit_exceeded), [`rate_limit_unavailable`](https://www.scarleta.ai/docs/errors#rate_limit_unavailable)

### Example

```bash
curl -X POST "https://api.scarleta.ai/v1/mcp/rpc" \
  -H "Authorization: Bearer $SCARLETA_API_KEY" \
  -H "Accept: application/json, text/event-stream" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "initialize",
    "params": {
      "protocolVersion": "2025-03-26",
      "capabilities": {},
      "clientInfo": {
        "name": "example-client",
        "version": "1.0.0"
      }
    }
  }'
```
