Transport — wie die Bytes fließen

MCP-Messages sind JSON-RPC — aber wie kommen sie vom Client zum Server? Drei Transports stehen zur Wahl. Jeder für ein anderes Setup: lokal, gehostet (alt), gehostet (neu).

Entscheidungs-Regel: Läuft der Server auf demselben Rechner wie der Nutzer? → stdio. Wird er als Service angeboten, neu deployed? → Streamable HTTP. Ältere SaaS-Server? → SSE.

Vergleichs-Switcher

Wo läuft der Server?
Sub-Prozess des Clients, auf demselben Rechner.
Verbindungs-Aufbau
Client startet den Prozess, pipt stdin/stdout.
Server → Client Push (Notifications)
Über stdout — funktioniert sofort.
Authentifizierung
Keine — wer den Prozess starten kann, vertraut man.
Latenz
Mikrosekunden — kein Netzwerk dazwischen.
Wer hostet?
Nutzer hat den Server-Code lokal installiert.

Wofür stdio passt

  • Filesystem-Server für lokale Dateien
  • Git-Server für lokales Repo
  • Postgres-Server mit lokaler DB-Verbindung
  • Allgemein: alles was Maschinen-Zugriff braucht

So sieht die Config aus

In Claude Desktop liegt sie in claude_desktop_config.json. Die Form unterscheidet sich klar nach Transport:

stdio

{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/home/jere"],
      "env": { "DEBUG": "1" }
    }
  }
}

SSE / Streamable HTTP

{
  "mcpServers": {
    "notion": {
      "url": "https://mcp.notion.com/sse",
      "headers": {
        "Authorization": "Bearer ntn_xxxxx"
      }
    }
  }
}
Warum eigentlich?Warum überhaupt drei? Reicht nicht einer?
Weil drei sehr verschiedene Welten existieren. Lokale Tools brauchen Filesystem-Zugriff und sollen sofort starten — da ist HTTP overkill, stdio passt perfekt. SaaS-Server brauchen Netzwerk und Auth — da passt HTTP. Und Streamable HTTP gibt es, weil SSE zwei Endpunkte verlangte (einer für Push, einer für Requests) — das ließ sich in Serverless-Architekturen kaum mappen. Streamable HTTP hat nur einen Endpunkt und ist einfacher zu deployen.
Häufiger Denkfehlerstdio-Server haben fast-zero Auth
Es gibt keinen Token, keine Berechtigungs-Schicht zwischen Client und stdio-Server. Wer den Server starten kann, kann ihn auch alles tun lassen, wofür der Server-Code Rechte hat. Das ist nicht zwangsläufig schlecht — der Nutzer hat den Server ja selbst installiert. Aber: schadhafte stdio-Server haben dieselben Rechte wie der Nutzer-Account. Genau wie eine NPM-Package. Daher: installiere nur Server aus vertrauenswürdigen Quellen.
Tiefer reinWas stdout darf — und was nicht
Beim stdio-Transport ist stdout für JSON-RPC reserviert. Das heißt: ein print("debug") im Server-Code würde der Client als Müll-JSON-RPC parsen und die Verbindung crashen. Logging muss über stderr gehen. Klassischer Anfänger-Bug: Python-Server, der irgendwo print(...) hat — der MCP-Inspector zeigt rätselhafte „Invalid JSON"-Errors.