MCP · Lektion 02 · Der Wire
JSON-RPC & der initialize-Handshake
In Lektion 1 war Architektur ein Diagramm. Jetzt schauen wir auf die echten Bytes, die zwischen Client und Server fließen — damit du im Workshop sagen kannst „so sieht das auf dem Draht aus“ und nicht nur „irgendwie reden die“.
initialize →
initialize result → notifications/initialized — und
erklären, warum Capability Negotiation das Herz davon ist.
1. MCP ist JSON-RPC 2.0 — nicht mehr, nicht weniger
Jede MCP-Nachricht ist eine JSON-RPC-2.0-Message, UTF-8 kodiert.1 Drei Sorten, mehr gibt es nicht:
- Request — hat
id+method, erwartet Antwort. - Response — hat dieselbe
id+result(odererror). - Notification — hat
method, keineid, erwartet keine Antwort.
Das ist die ganze Grammatik. „MCP lernen“ heißt zu großen Teilen: lernen,
welche method-Namen es gibt (tools/list,
tools/call, resources/read …) und welche Parameter sie tragen.
2. Der Handshake: drei Nachrichten, immer zuerst
Die Initialisierung MUSS die allererste Interaktion sein.1
Der Client schickt initialize mit seiner Protokoll-Version, seinen
Capabilities und clientInfo:
// Client → Server
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-06-18",
"capabilities": { "roots": { "listChanged": true }, "sampling": {} },
"clientInfo": { "name": "ExampleClient", "version": "1.0.0" }
}
}
Der Server antwortet mit seinen Capabilities und serverInfo —
hier deklariert er, dass er Tools/Resources/Prompts kann:
// Server → Client
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": "2025-06-18",
"capabilities": {
"tools": { "listChanged": true },
"resources": { "subscribe": true, "listChanged": true },
"prompts": { "listChanged": true }
},
"serverInfo": { "name": "ExampleServer", "version": "1.0.0" },
"instructions": "Optional instructions for the client"
}
}
Erst dann meldet der Client „bereit“ — als Notification (keine id):
// Client → Server
{ "jsonrpc": "2.0", "method": "notifications/initialized" }
Ab hier ist die Session offen und „operational“. Genau diese drei Nachrichten
laufen gerade auch zwischen Claude Code und deinem
forgejo-Server.1
3. Warum der ganze Tanz? Capability Negotiation
Der Sinn des Handshakes: beide Seiten sagen vorher, was sie können.
Ein Server, der tools nicht deklariert, wird nie nach Tools gefragt.
Ein Client, der sampling nicht kann, bekommt keine Sampling-Anfragen.
So bleibt das Protokoll erweiterbar: neue Features werden über neue
Capabilities eingeführt, ohne alte Implementierungen zu brechen.1
Workshop-Bild: Der Handshake ist wie zwei Geräte, die per USB-C aushandeln, ob sie Strom, Video und Daten können — bevor irgendwas fließt.
Auch die Versionsverhandlung steckt hier: Der Client schickt die neueste
Version, die er kann; passt sie dem Server nicht, antwortet der Server mit einer
Version, die er kann. Über HTTP wandert die ausgehandelte Version danach in
jedem Request als MCP-Protocol-Version-Header mit.1
4. Mini-Check (aus dem Kopf!)
id?5. Primärquelle
📖 MCP Specification — Lifecycle. Enthält genau diese JSON-Beispiele plus die MUST/SHOULD-Regeln. Lies Initialization und Capability Negotiation.
1 — MCP Specification, Lifecycle & Transports (2025-06-18): …/basic/lifecycle