Zum Inhalt springen
← Alle Beiträge
· 4 Min. Lesezeit· Von

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.

MCPModel Context ProtocolAPIMigrationAI ToolingDeveloper ToolsPython

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).

Projekt besprechen