---
title: "MCP reference. Metadata Developer Docs"
url: https://metadata.io/developers/mcp
description: "Transport, handshake, capabilities and error handling for the Metadata MCP server, plus the raw JSON-RPC calls behind every client."
source: metadata.io
---

# MCP reference

What the server speaks, what it advertises, and the raw calls your client is making on your behalf.

## Endpoint and transport

| Endpoint | `https://mcp-server.metadata.io/mcp` |
|---|---|
| Transport | Streamable HTTP. `POST` JSON-RPC 2.0; responses arrive as `text/event-stream`, so send `Accept: application/json, text/event-stream`. |
| Protocol version | `2024-11-05` |
| Auth | `Authorization: <token>`, raw. PAT (`pat-…`) or JWT. |

## Handshake

The server replies with its capabilities and version. Capabilities advertised today: `tools`, `prompts`, `resources` and `logging`, with `listChanged` on tools, prompts and resources.

## Calling a tool

Every tool is `tools/call` with a name and an arguments object matching that tool's JSON Schema. This one takes no arguments and changes nothing, which makes it the right first call:

The response, verbatim from the server:

Results come back as `content` blocks. Text blocks hold a JSON string, so most tools need one more parse after the envelope.

## Errors

| What you see | What it means |
|---|---|
| `401` / `Unauthorized` | The token is missing, wrong, or being sent with a `Bearer` prefix it does not want. Test with the `tools/list` curl above before debugging your client. |
| `405` | You used `GET`. The endpoint is POST-only. |
| `"isError": true` | Transport succeeded, the tool refused. The content block says why; it is usually a missing required argument or an id that does not resolve in this account. |
| Client says unauthorized, curl works | The fault is your client, not the server or the key. A client reads its config once at startup, so a config edit needs a restart to take effect. |

## Account scope

Every call acts on one account. Read which with `get_account_details`, list what you can reach with `list_user_accounts`, and switch with `impersonate_account` — the platform enforces entitlement and rejects a switch you are not allowed to make. `stop_impersonation` switches back.
