Probleme bei der MCP-Server-Integration: Protokoll, Transport, Rechte und Schema

Eine schichtweise Anleitung zur MCP-Server-Diagnose: Protokollversion, Transport, Laufzeit, Autorisierung, Tool-Schema und sicherer Inspector-Test.

Wenn sich ein MCP-Server nicht verbindet oder ein Tool Call fehlschlägt, ändern Sie nicht gleichzeitig Client-Konfiguration, Servercode und Berechtigungen. Bestimmen Sie zuerst die fehlerhafte Schicht. Arbeiten Sie in dieser Reihenfolge: Protokollversion → Transport → Start und Umgebung → permissions/auth → inputSchema → ein read-only Aufruf.

Am 23. August 2026 ist 2026-07-28 die aktuelle verifizierte MCP-Spezifikation. Sie verlangt nicht mehr den alten obligatorischen Handshake über initialize: Ein Client kann server/discover verwenden, während Protokollversion, Client-Informationen und Capabilities in _meta mit den Requests übertragen werden. Legacy-Implementierungen mit 2025-11-25 oder älter verwenden eine andere Abfolge: initialize, Serverantwort und danach notifications/initialized. Vermischen Sie diese beiden Protokollgenerationen niemals in einem Austausch.

Trennen Sie MCP von Anfang an von der Modell-API. MCP verbindet den Client mit Tools und Kontext; der Modellaufruf kann über einen anderen Pfad und mit anderen Credentials laufen. Isolieren Sie die Modellschicht mit der BetterToken-Anleitung: Ein eigener API Key und die gewählte OpenAI-compatible oder Anthropic-compatible Schnittstelle ergeben einen separaten, prüfbaren Pfad. So suchen Sie einen Modellfehler nicht innerhalb von MCP. Dieser Key ist kein Credential des MCP-Servers, und BetterToken ist weder MCP Host noch MCP Transport.

Fehler schnell einordnen

Notieren Sie vor dem Start von Inspector genau ein Symptom und den letzten bestätigten Punkt:

  • der Prozess startet überhaupt nicht;
  • der Prozess läuft, aber der Client empfängt kein JSON-RPC;
  • der Transport antwortet, aber Version oder Capabilities stimmen nicht überein;
  • der Server gibt 401 oder 403 zurück;
  • tools/list funktioniert, doch das erwartete Tool fehlt;
  • das Tool ist sichtbar, aber tools/call lehnt die Arguments ab;
  • der Aufruf läuft durch, doch das Ergebnis lässt sich nicht verifizieren.

Schreiben Sie keinen API Key, Bearer Token, Cookie, vollständigen Prompt oder Inhalt privater Dateien in Ihre Notizen. Für die Korrelation genügen Zeitpunkt, Servername, Methode, JSON-RPC-id, Fehlercode und eine bereinigte Meldung.

1. Protokollgeneration feststellen

Ermitteln Sie, welche Version Client, Server und SDK unterstützen. Die Meldung Connected bestätigt Transport und einen Teil des Discovery, beweist allein aber keine Einigung auf 2026-07-28.

Prüfen Sie bei einer modernen Implementierung drei Merkmale:

  1. Das SDK oder seine Release Notes nennen ausdrücklich Unterstützung für 2026-07-28.
  2. Der Trace enthält server/discover oder einen anderen vom SDK vorgesehenen Discovery-Pfad.
  3. Die Requests enthalten korrektes _meta mit Version, Client-Informationen und Capabilities.

Kopieren Sie die Form von _meta nicht manuell aus einem anderen SDK. Das genaue Wire-Format muss ein kompatibler Client oder das offizielle SDK erzeugen. Wenn der Server auf initialize wartet, der Client aber eigenständige 2026-07-28-Requests sendet, liegt eine nicht passende Protokollgeneration vor, kein Fehler im Tool-Schema.

Legacy-initialize: nur für 2025-11-25 und älter

Dies ist ein minimaler Legacy-Request. Fügen Sie ihn nicht „zur Sicherheit“ in einen modernen 2026-07-28-Flow ein.

{ "jsonrpc": "2.0", "id": 1, "method": "initialize", "params": { "protocolVersion": "2025-11-25", "capabilities": {}, "clientInfo": { "name": "mcp-diagnostic-client", "version": "1.0.0" } } }

Nach einer erfolgreichen Antwort sendet der Legacy-Client notifications/initialized. Bricht dieser Austausch ab, vergleichen Sie zuerst Versionen und Capabilities-Liste. Für tools/list ist es noch zu früh.

2. Transport getrennt von der MCP-Semantik prüfen

MCP definiert Methoden und Daten; der Transport übernimmt Start, Framing, Zustellung und Abbruch von Requests. Ein Wechsel von stdio zu HTTP repariert kein falsches inputSchema.

stdio

Bei stdio startet der Client den Server als Kindprozess. Nachrichten laufen über stdin und stdout als durch Zeilenumbrüche getrennte UTF-8-JSON-RPC-Dokumente.

Prüfen Sie:

  1. command existiert und läuft unter demselben Benutzer.
  2. Arguments werden als getrennte Elemente übergeben und hängen nicht von Shell-Aliases ab.
  3. Das Arbeitsverzeichnis enthält die benötigten Dateien, oder Pfade sind absolut.
  4. Die erforderlichen Variablen stehen dem Kindprozess tatsächlich zur Verfügung.
  5. stdout enthält weder Banner noch Debug-Zeilen oder Stack Trace; Logs gehen an stderr.

Ein einziges versehentliches console.log() auf stdout kann das Framing zerstören, bevor der Client eine JSON-RPC-Antwort sieht.

Streamable HTTP

Bei Streamable HTTP sendet der Client POST-Nachrichten an genau einen MCP Endpoint. Die Antwort kann normales JSON oder request-scoped SSE sein. Prüfen Sie genaue URL, HTTP-Methode, Content-Type, TLS, Redirects, Proxy und Authentifizierungsart.

Führen Sie den Transporttest über Loopback oder in einer isolierten Testumgebung aus. Scannen Sie keinen öffentlichen Production Endpoint ohne Erlaubnis. Liefert POST eine HTML-Anmeldeseite, einen 301/302 zu einem anderen Host oder eine Reverse-Proxy-Antwort, haben Sie MCP noch nicht erreicht.

3. Start in derselben Umgebung reproduzieren

Führen Sie bei stdio zuerst den Serverbefehl direkt aus demselben Verzeichnis und unter demselben Benutzer wie der MCP-Client aus. Ein Start aus der IDE ist kein Ersatz: PATH, cwd, Runtime und Berechtigungen können abweichen.

Prüfen Sie:

node --version pwd node ./dist/server.js

pwd verrät allein kein Secret. Veröffentlichen Sie den Pfad trotzdem nicht, wenn er einen Benutzernamen oder den Namen eines privaten Projekts enthält. Der Serverbefehl sollte entweder auf JSON-RPC an stdin warten oder mit einer klaren Fehlermeldung auf stderr enden. Ein sofortiger Exit ohne Meldung deutet meist auf einen falschen Entrypoint, eine fehlende Abhängigkeit oder einen ohne Log behandelten Startfehler hin.

Die am 23. August 2026 geprüfte offizielle Inspector-CLI-Dokumentation verlangt Node.js 22.19.0 oder neuer. Ist die Version niedriger, stoppen Sie und wechseln Sie die Runtime, bevor Sie weiterdiagnostizieren.

4. Permissions und Authentication trennen

Der Response-Code bestimmt die nächste Prüfung:

  • 401 Unauthorized: Das Credential fehlt, ist abgelaufen oder wird abgelehnt;
  • 403 Forbidden: Die Identity wurde erkannt, besitzt aber nicht das erforderliche Permission oder Scope;
  • 404: Häufig ist der Endpoint oder die Route falsch, nicht die Berechtigung zu gering;
  • Timeout: Server, Proxy oder Tool wurden nicht rechtzeitig fertig; das beweist keinen Auth-Fehler.

Deaktivieren Sie Permissions nicht für einen Smoke Test. Erstellen Sie eine eigene Test-Identity mit minimalem Scope und wählen Sie ein read-only Tool ohne externe Wirkung. Der Client muss einem Menschen die Ablehnung des Aufrufs ermöglichen; Tool-Annotations sind nicht vertrauenswürdige Daten und ersetzen keine Policy.

Speichern Sie in Logs die Auth-Entscheidung (allowed/denied), den Scope-Namen und die Correlation ID. Das Credential selbst, den Authorization-Header und Cookies müssen Sie entfernen oder maskieren.

5. Capability und inputSchema validieren

Der Server muss die Capability tools deklarieren, bevor er tools/list bedient. Jedes Tool benötigt einen eindeutigen Namen und ein gültiges JSON-Schema-Objekt in inputSchema. Die Arguments für tools/call müssen diesem Schema entsprechen.

Minimale Deklaration eines read-only Tools:

{ "name": "echo", "description": "Gibt den übergebenen Text unverändert zurück", "inputSchema": { "type": "object", "properties": { "text": { "type": "string" } }, "required": ["text"], "additionalProperties": false } }

Typische Fehler sind einfach: Der Wurzeltyp type: object fehlt, ein Pflichtfeld steht nicht in properties, der Client sendet eine Zahl statt eines Strings, die Groß-/Kleinschreibung eines Argumentnamens weicht ab oder der Server bewirbt zwei Tools mit demselben Namen.

Wenn Version und Transport übereinstimmen, testen Sie die Methode mit diesem JSON-RPC-Payload:

{ "jsonrpc": "2.0", "id": 2, "method": "tools/list", "params": {} }

Rufen Sie danach genau ein Tool auf:

{ "jsonrpc": "2.0", "id": 3, "method": "tools/call", "params": { "name": "echo", "arguments": { "text": "MCP_OK_2026" } } }

Diese Ausschnitte zeigen Methoden-Payloads, nicht den vollständigen Verbindungs-Bootstrap. In einem 2026-07-28-Flow ergänzt ein kompatibler Client die erforderlichen Request-Metadaten in _meta; im Legacy-Flow kommt zuerst initialize. Senden Sie diese JSON-Ausschnitte nicht ohne Erlaubnis manuell an einen Production Endpoint.

6. Sicheren Test mit MCP Inspector CLI ausführen

Installieren Sie Inspector zuerst als festgeschriebene Projektabhängigkeit aus einem vertrauenswürdigen Lockfile. Der folgende Schalter --no-install verhindert, dass während der Diagnose eine beliebige aktuelle Version geladen wird.

Tools eines lokalen stdio-Servers auflisten:

npx --no-install @modelcontextprotocol/inspector --cli node ./dist/server.js --method tools/list

Einmal echo aufrufen:

npx --no-install @modelcontextprotocol/inspector --cli node ./dist/server.js \ --method tools/call \ --tool-name echo \ --tool-arg text=MCP_OK_2026

Für einen Streamable-HTTP-Testendpoint über Loopback:

npx --no-install @modelcontextprotocol/inspector --cli \ http://127.0.0.1:3000/mcp \ --transport http \ --method tools/list

Schreiben Sie keinen Token in Shell-History, URL oder Artikel. Benötigt der Endpoint Auth, konfigurieren Sie das Credential über den vorgesehenen Inspector-Weg in der lokalen Umgebung. Andernfalls stoppen Sie den Test und fordern beim Server-Eigentümer eine Test-Identity an. Die Befehle enthalten absichtlich keinen echten Key.

Symptom → Prüfung → Behebung

SymptomZuerst prüfenMinimale Behebung
spawn ENOENT oder Prozess nicht gefundenAbsoluter Pfad zu command, Runtime und PATH des Client-ProzessesVorhandenes Executable angeben oder Startumgebung korrigieren
Prozess endet sofortcwd, Entrypoint, Abhängigkeiten und Fehler auf stderrIm richtigen Verzeichnis starten und einen klaren Non-zero Exit liefern
Client meldet JSON Parse ErrorFremdausgabe auf stdout, UTF-8 und ZeilenumbruchNur JSON-RPC auf stdout lassen und Logs nach stderr senden
HTTP liefert HTML oder RedirectMCP-URL, Proxy, TLS und POST-RouteEinen korrekten MCP Endpoint verwenden und Proxy-Regel korrigieren
Versionsfehler vor tools/listProtokollgeneration und SDK-UnterstützungInkompatible Seite aktualisieren oder Legacy-Pfad explizit behalten; Handshakes nicht mischen
401 UnauthorizedVorhandensein und Ablauf des CredentialsSeparates Test-Credential über den genehmigten Prozess beziehen
403 ForbiddenScope, Resource Policy und IdentityDer Test-Identity nur den erforderlichen Scope geben
tools/list → Methoden-/Capability-FehlerOb Capability tools deklariert istDeklaration vor der Tool-Registrierung korrigieren
Tool fehlt in der ListeEindeutiger Name und tatsächliche RegistrierungEin Tool registrieren und Server neu starten
tools/call lehnt Arguments abinputSchema, Typen, required und NamensschreibungArguments ans Schema anpassen; nicht zu einem beliebigen Objekt lockern
Aufruf hängtTimeout, Cancellation und externe Tool-AbhängigkeitTest durch lokales read-only echo ersetzen, danach Abhängigkeit separat prüfen

Abnahmekriterien

Die Integration besteht die minimale Abnahme nur, wenn alle fünf Bedingungen erfüllt sind:

  1. Logs oder Telemetry zeigen die erwartete ausgehandelte Protokollversion.
  2. Der Transport bewahrt das Framing: stdio enthält keine zusätzliche Ausgabe auf stdout, und HTTP antwortet vom MCP Endpoint.
  3. tools/list gibt ein erwartetes Tool mit gültigem inputSchema zurück.
  4. tools/call wird tatsächlich mit text=MCP_OK_2026 aufgerufen und gibt MCP_OK_2026 unverändert zurück.
  5. Der Test hat keine Permissions deaktiviert, keine Credentials offengelegt und keinen externen Seiteneffekt ausgelöst.

MCP_OK_2026 lediglich in einer Modellantwort zu sehen, reicht nicht. Erforderlich ist ein aufgezeichneter Tool Call mit passender JSON-RPC-id oder ein Inspector-Protokoll zusammen mit einem bereinigten Serverlog.

Stop Conditions

Stoppen Sie die Diagnose und wechseln Sie nicht zur nächsten Schicht, wenn:

  • unbekannt ist, welche Protokollgeneration mindestens eine Seite unterstützt;
  • Inspector eine nicht festgeschriebene Paketversion ungeprüft installieren will;
  • der Test ein Production Credential, deaktivierte Authentifizierung oder erweiterten Scope verlangt;
  • das einzige verfügbare Tool in eine Datenbank schreibt, Nachrichten sendet, Dateien ändert oder Befehle ausführt;
  • der HTTP Endpoint einem Dritten gehört und die Testerlaubnis nicht bestätigt ist;
  • Key, Token, Cookie, personenbezogene Daten oder Inhalte privater Ressourcen in Logs auftauchen;
  • tools/list instabil ist oder bei Wiederholungen unterschiedliche Schemas zurückgibt;
  • der Server abstürzt, bevor eine gültige JSON-RPC-Antwort erscheint.

Bewahren Sie in diesen Fällen das bereinigte Symptom, Client-/Server-/SDK-Versionen, Transport, Correlation ID und einen minimalen Fehlerausschnitt auf. Das genügt, um das Problem ohne unnötige Rechte oder Secrets an den Eigentümer der richtigen Schicht zu übergeben.

Quellen

Spezifikationsversion, Transportdetails und minimale Node.js-Version wurden am 23. August 2026 verifiziert. Prüfen Sie die aktuelle offizielle Dokumentation erneut, bevor Sie die Diagnose nach einem Update von Client, Server, SDK oder Inspector wiederholen.

Bereit, Ihren LLM-Workflow zu optimieren?

Verbinden Sie Modelle über eine API, verwalten Sie Schlüssel und behalten Sie KI-Kosten im Blick.