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 | 2025-11-25 |
| Auth | Authorization: <token>, raw — no Bearer prefix. PAT (pat-…) or JWT. This is the opposite of the MCP spec, which requires the Bearer form: on this server Bearer is accepted by tools/list and rejected by tools/call with -32001, so send it raw. |
GET or HEAD on the endpoint returns 405. That is
the server working correctly, not an outage. Use POST.
Handshake
curl -s -X POST https://mcp-server.metadata.io/mcp \
-H "Authorization: $METADATA_PAT" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize",
"params":{"protocolVersion":"2025-11-25","capabilities":{},
"clientInfo":{"name":"my-agent","version":"1.0"}}}'
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:
curl -s -X POST https://mcp-server.metadata.io/mcp \
-H "Authorization: $METADATA_PAT" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "MCP-Protocol-Version: 2025-11-25" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call",
"params":{"name":"get_current_date","arguments":{}}}'
The response, verbatim from the server:
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"content": [ { "type": "text", "text": "{
\"current_date\": \"2026-09-05\",
\"current_quarter\": \"Q3\",
\"timezone\": \"UTC\"
}" } ],
"isError": false
}
}
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.