*MCP › Reference*

# Protocol reference

> What a client needs to talk to the server without a ready-made one.

## Endpoint and transport

`POST https://app.filmo.io/api/v1/mcp`. There is no workspace segment: the account comes from the credential. The transport is Streamable HTTP, POST only and stateless: the server assigns no `Mcp-Session-Id`. A GET answers HTTP 405 with a JSON-RPC error `-32000`.

## Methods

| Method | What it does |
| --- | --- |
| `initialize` | Negotiates the protocol. The server answers the revision the client asks for when it accepts it (see Protocol revisions below), otherwise `2025-06-18`, with the capability `tools` and `listChanged: false`, and its instructions. |
| `notifications/initialized` | Acknowledged by the client after `initialize`. A request that holds only notifications gets a `202` with no body. |
| `tools/list` | The catalogue. Public without a credential; with one, only the tools it can call. |
| `tools/call` | Runs a tool. Needs a credential. |
| `ping` | Answers `{}`. Public. |
| Anything else | Prompts and resources are not offered: the server answers `-32601`. A batch holds at most 20 messages and runs them in order. |

## Headers

- `Content-Type: application/json` and an `Accept` that lists `application/json` and `text/event-stream`, as the specification requires of a client.
- `Authorization: Bearer <key or access token>` for `tools/call`.
- `MCP-Protocol-Version` on every request after `initialize`, with the negotiated version (the specification asks it of a client).

## HTTP statuses

| Status | When | Body |
| --- | --- | --- |
| 200 | A JSON-RPC message was processed, including a tool error | JSON-RPC response |
| 401 | `tools/call` without a valid credential, or `initialize` or `tools/list` with a credential that is not valid | RFC 9457 problem, with `WWW-Authenticate` (`resource_metadata`, `scope`) |
| 405 | GET | JSON-RPC error `-32000` |
| 308 | A production host that is not `app.filmo.io` | A JSON-RPC error that names the canonical URL |
| 500 | An unexpected failure | JSON-RPC error `-32603` |

A limit imposed by the platform (413, 502, 504) is not a problem document.

## JSON-RPC errors

A protocol failure is a JSON-RPC error with the standard codes (`-32700` parse, `-32600` invalid request, `-32601` method not found, `-32602` invalid params or unknown tool, `-32603` internal). Messages are in English. A failed call is not one of these: see below.

## The result of a tool

Every tool declares an `outputSchema`, open to new fields. A success returns `structuredContent` with `data` (and `pagination` in lists) and `meta`:

| `meta` field | When |
| --- | --- |
| `idempotencyKey` | A write that takes a key: yours; on the four tools that duplicate something irreversible on a blind retry, the one the server generated if you sent none |
| `idempotentReplay` | `true` when the call repeats an earlier one with the same key and nothing ran again |
| `rateLimit` | Always: `{ limit, remaining, reset }`, what the `RateLimit-*` headers say over REST |
| `etag` | A detail read: pass it as `ifMatch` on the next write |

A failure is a result with `isError: true` and the RFC 9457 problem as JSON in `content[0].text`, with no `structuredContent`. A 429 problem carries `retryAfter` and the `detail` “Rate limit exceeded: retry in N seconds”. See [Errors](https://docs.filmo.io/mcp/guides/errors).

## Annotations and `_meta`

`tools/list` returns the four annotations (`readOnlyHint`, `destructiveHint`, `idempotentHint`, `openWorldHint`) and, on 25 tools, `_meta["anthropic/requiresUserInteraction"]: true`. They are hints that the server declares, not guarantees.

## What the official SDKs do

| Result | TypeScript SDK `callTool` | Python SDK `call_tool` |
| --- | --- | --- |
| Success with `meta` | Returns the result | Returns the result |
| Tool error (`isError`) | Returns the result; read `content[0].text` | Returns the result; read `content[0].text` |
| A 429 | Returns the result; `retryAfter` in the problem | Returns the result; `retryAfter` in the problem |
| Unknown tool, bad request | Throws (JSON-RPC error) | Throws |

Filmo ran seven cases against the real route (a read, a write with `idempotencyKey`, a replay with the same key, a 400, a 403 `insufficient_scope`, a 404 and a 429) with the TypeScript SDK `@modelcontextprotocol/sdk` 1.26.0 and 1.32.1, the TypeScript client `@modelcontextprotocol/client` 2.3.1 and the Python SDK `mcp` 1.27.1 and 2.3.0. None raises `-32602` and the 429 problem arrives readable. `Client` and `StreamableHTTPClientTransport` are used the same way in both TypeScript lines; only the package and the import change. Other versions were not tried.

- A tool error has no `structuredContent` because the TypeScript 1.x SDK (`callTool`, from 1.20 to 1.32.1) validates it against the `outputSchema` even when `isError` is `true`. The 2.x client and the Python SDK do not validate it when `isError` is `true`; the error shape passes in all of them.
- A success is validated against the `outputSchema` in both TypeScript lines, and an extra field raises `-32602 Structured content does not match the tool's output schema`. That is why the `outputSchema` of every tool is open to new fields.
- The errors of the TypeScript 2.x SDK are `ProtocolError` (with a `code`); in 1.x they were `McpError`. If you catch by class, check the name when you migrate.
- Not tried with the 2.x client: the OAuth flow, the caching of `tools/list` and the other changes of that line. The seven cases ran against doubles of the REST handlers, not against a deployed server.

## Protocol revisions

| Revision | Notes |
| --- | --- |
| `2025-06-18` | The default: the server answers it when the client asks for it or for a revision the server does not know. |
| `2025-03-26`, `2024-11-05` | Accepted: the server answers the same revision the client asked for. |
| `2025-11-25` | Not on the server's list, so it answers `initialize` with the default, as the lifecycle of that revision allows; a client that cannot use the default disconnects. |
| `2026-07-28` | The current revision of the specification. It is stateless and has no `initialize`; most clients still use the earlier handshake. |

The server does not announce client ID metadata documents (CIMD), which the newer specification prefers over dynamic registration. Sources: modelcontextprotocol.io/specification/versioning and /specification/2026-07-28/basic/versioning, checked on 2026-10-25.

---

Canonical URL: https://docs.filmo.io/mcp/reference/protocol  
Last updated: 2026-10-25