JSON-RPC — das Wire-Format
MCP ist nicht selbst ein Protokoll — es ist eine Reihe von Methoden und Datentypen, die über JSON-RPC 2.0 transportiert werden. JSON-RPC ist alt, simpel, und tut nur eins: strukturierte Anfragen und Antworten mit IDs durch einen beliebigen Kanal schicken.
Message-Player
{
"jsonrpc": "2.0",
"id": 42,
"method": "tools/call",
"params": {
"name": "create_issue",
"arguments": {
"title": "Bug in Slider"
}
}
}Die ID — der Sortierungs-Trick
Eine TCP-Verbindung ist ein Stream: Bytes fließen rein, Bytes fließen raus. Ohne IDs hätte der Client keine Chance, zwei Antworten den richtigen Requests zuzuordnen — denn JSON-RPC erlaubt async und out-of-order. Mit IDs ist die Zuordnung trivial:
Client → { id: 1, method: "tools/list" }
Client → { id: 2, method: "resources/list" }
Server ← { id: 2, result: [...] } ← Antwort auf #2 zuerst!
Server ← { id: 1, result: [...] } ← Antwort auf #1 späterStandardisierte Fehler-Codes
-32700-32600-32601-32602-32603Eigene Codes vergibst du in -32000 bis -32099 — das ist der Server-Error-Range, den JSON-RPC für Anwendungs-Fehler offenlässt.
Batch — mehrere Requests gleichzeitig
JSON-RPC erlaubt ein Array statt eines Objekts als Payload. Der Server verarbeitet alle und gibt ein Array von Responses zurück. Praktisch für Setup-Phase, wenn der Client zur gleichen Zeit nach Tools, Resources und Prompts fragt:
[
{ "jsonrpc": "2.0", "id": 1, "method": "tools/list" },
{ "jsonrpc": "2.0", "id": 2, "method": "resources/list" },
{ "jsonrpc": "2.0", "id": 3, "method": "prompts/list" }
]Warum eigentlich? — Warum JSON-RPC und nicht REST oder gRPC?
Häufiger Denkfehler — id=0 vergessen
0 ist eine gültige ID. Wenn dein Client mit if (msg.id) filtert, übersieht er Request mit id=0. Stattdessen: if (msg.id !== undefined). Klassischer Bug, der nur in 1 von 10000 Sessions auftritt — und dann stundenlang unverständlich ist.