MCP-Server auf Spec 2026-07-28 migrieren: initialize weg, server/discover Pflicht
MCP 2026-07-28 bricht die Abwärtskompatibilität: initialize-Handshake entfällt, server/discover wird verpflichtend, subscriptions/listen löst resources/subscribe ab. Migrationsanleitung mit Python-SDK.
Das Model Context Protocol (MCP) ist der offene Standard, über den KI-Clients — Claude, IDEs, Agenten-Frameworks — auf externe Tools, Ressourcen und Prompts zugreifen. Am 28. Juli 2026 hat die MCP-Arbeitsgruppe die neue stabile Revision 2026-07-28 veröffentlicht, die die Vorgängerversion 2025-11-25 ablöst. Die Änderungen sind breaking: bestehende Server müssen migriert werden. Clients, die die neue Revision sprechen, senden bei einem Versionskonflikt den JSON-RPC-Fehler -32022 UnsupportedProtocolVersion.
Dieser Artikel zeigt die wichtigsten Brüche und einen minimalen Migrationspfad für eine typische Python-Server-Implementierung.
Warum der Handshake entfällt
Der bisherige initialize-Handshake war stateful: Er verknüpfte eine HTTP-Session-ID mit verhandelten Capabilities. Das macht horizontales Skalieren aufwändig — ein Load-Balancer müsste alle Requests einer Session zur selben Instanz routen. Die neue Revision macht den Core vollständig stateless: Jeder Request trägt Protokollversion und Capabilities direkt im _meta-Feld mit. Ein Load-Balancer kann Requests beliebig verteilen, ohne Sitzungsaffinität.
Die drei wichtigsten Breaking Changes
1. initialize und notifications/initialized entfallen
Bislang startete jede MCP-Session mit einem Zwei-Schritt-Handshake:
Client --> Server: initialize { protocolVersion, capabilities }
Server --> Client: InitializeResult
Client --> Server: notifications/initialized
In 2026-07-28 entfallen beide Methoden sowie der Mcp-Session-Id-Header vollständig. Stattdessen überträgt der Client bei jedem Request die benötigten Metadaten im _meta-Feld der Params:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list",
"params": {
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientCapabilities": {
"roots": false,
"sampling": false
},
"io.modelcontextprotocol/clientInfo": { "name": "my-client", "version": "1.0" }
}
}
}
Für HTTP-Transporte kommen außerdem zwei neue Pflicht-Header bei jedem POST hinzu: Mcp-Method und Mcp-Name. Der Mcp-Session-Id-Header entfällt.
Server-Code, der Capabilities im initialize-Handler speichert und später aus dem Session-Kontext liest, muss umgestellt werden: Capabilities sind jetzt pro Request aus params._meta zu lesen.
2. server/discover ist verpflichtend
Jeder Server MUSS server/discover implementieren — der einzige Endpunkt, den ein Client ohne vorherigen Handshake aufrufen darf:
{ "jsonrpc": "2.0", "id": 0, "method": "server/discover" }
Die Antwort enthält protocolVersion, capabilities und serverInfo. Clients, die erst die Protokollversion prüfen wollen, rufen server/discover vor dem ersten echten Request auf. Fehlt die Methode, antwortet der Server mit MethodNotFound; viele Clients brechen dann die Verbindung ab.
3. subscriptions/listen ersetzt resources/subscribe
resources/subscribe, resources/unsubscribe und der HTTP-GET-Endpunkt für SSE-Streams sind entfernt. Stattdessen gibt es einen einzelnen Long-Running-Request subscriptions/listen, über den der Client mehrere Event-Typen gleichzeitig abonniert:
{
"jsonrpc": "2.0",
"id": 2,
"method": "subscriptions/listen",
"params": {
"subscriptions": [
"toolsListChanged",
"resourcesListChanged",
"resourceSubscriptions"
],
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28"
}
}
}
Ebenfalls entfällt SSE-Resume via Last-Event-ID. Bricht der Stream ab, kann er nicht wiederaufgenommen werden — der Client muss einen neuen Request mit einer neuen Request-ID stellen.
Weitere Änderungen im Überblick
| Bereich | Alt | Neu |
|---|---|---|
| Ping | ping-Methode |
entfällt |
| Roots-Änderung-Notify | notifications/roots/list_changed |
entfällt |
| Log-Level setzen | logging/setLevel |
_meta-Feld io.modelcontextprotocol/logLevel |
| Tasks (experimentell) | im Core-Protokoll | Extension io.modelcontextprotocol/tasks |
| Ergebnis-Typ | — | resultType: "complete" / "input_required" Pflichtfeld |
| List-Caching | — | ttlMs, cacheScope Pflichtfelder auf list-Responses |
| Roots, Sampling, Logging | aktiv | deprecated (12 Monate Übergangsfrist) |
Zu Roots, Sampling und Logging: Diese Features sind offiziell als deprecated markiert, bleiben aber für mindestens zwölf Monate funktionsfähig. Für Roots empfiehlt die Spec Tool-Parameter oder Resource-URIs als Ersatz; Sampling soll direkt über Provider-APIs laufen; Logging über stderr (STDIO) oder OpenTelemetry.
Migration mit dem Python-SDK
Das offizielle Python-SDK mcp 2.0.0 (stabil, veröffentlicht am 28. Juli 2026) unterstützt die neue Spec vollständig:
pip install "mcp>=2.0.0"
Wer bislang FastMCP aus mcp 1.x verwendet, wechselt zu MCPServer. Der stdio-Transport wird direkt über die Instanzmethode run() gestartet:
from mcp.server import MCPServer
server = MCPServer("mein-server", version="1.0.0")
@server.tool()
async def begruessung(name: str) -> str:
return f"Hallo, {name}!"
if __name__ == "__main__":
server.run() # startet den stdio-Transport
Für HTTP-Deployments stellt streamable_http_app() ein ASGI-kompatibles Objekt bereit, das sich direkt an uvicorn übergeben lässt:
import uvicorn
from mcp.server import MCPServer
server = MCPServer("mein-server", version="1.0.0")
# @server.tool() ... Registrierungen hier
app = server.streamable_http_app()
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000)
mcp 1.x ist in den Wartungsmodus übergegangen (Sicherheits-Patches only). Das TypeScript-SDK v2 ist ebenfalls verfügbar; den Migrationsleitfaden finden Sie im offiziellen Repository (Link unten).
Drei typische Stolperfallen
1. server/discover fehlt in manuellen Implementierungen. Wer die JSON-RPC-Schicht selbst baut statt ein SDK zu verwenden, muss server/discover explizit registrieren. Das SDK liefert es automatisch mit; wer ohne SDK arbeitet, vergisst es leicht — und Clients brechen dann vor dem ersten echten Call ab.
2. Session-State aus initialize beibehalten. Code, der im initialize-Handler Capabilities oder Versions-Informationen in einem Session-Dictionary speichert, liest beim nächsten Request veraltete oder leere Daten. Capabilities kommen jetzt ausschließlich aus params._meta und gelten nur für den jeweiligen Request.
3. Proxy-Konfiguration für neue HTTP-Header. Reverse-Proxies wie nginx oder HAProxy, die bestimmte Header-Namen filtern oder auf eine Whitelist setzen, müssen für Mcp-Method und Mcp-Name aktualisiert werden. Fehlen diese Header am Server, antwortet er mit HeaderMismatch (JSON-RPC-Code -32020), was sich in Client-Logs als generischer Verbindungsfehler tarnen kann.
Wie es weitergeht
Den vollständigen Changelog mit allen Änderungen finden Sie unter modelcontextprotocol.io/specification/2026-07-28/changelog. Die Python-SDK-Migrationsdokumentation ist auf github.com/modelcontextprotocol/python-sdk zu finden, den TypeScript-Migrationsleitfaden unter github.com/modelcontextprotocol/typescript-sdk. Die vollständige Spezifikation aller MCP-Versionen liegt auf spec.modelcontextprotocol.io.
Hinweis: Die Beiträge dieses Blogs werden unter Einsatz von KI erstellt und vor der Veröffentlichung redaktionell geprüft. Die redaktionelle Verantwortung trägt Emre Yurtbay (siehe Impressum).