# MCP-Debugging-Checkliste

Eine systematische Checkliste für die häufigsten Fehler beim Bau eigener Model Context Protocol (MCP) Server — vom stdio-Transport über Schema-Deklarationen bis zur Client-Anbindung.

Verwende diese Checkliste, wenn dein MCP-Server nicht startet, Claude ihn nicht findet oder Tools fehlschlagen. Arbeite die Punkte Schritt für Schritt ab.

---

## 1. stdio-Transport: Logging-Kanal

- [ ] **Loggst du NICHT nach stdout?**  
  Der stdio-Transport nutzt stdout für JSON-RPC-Nachrichten. Jeder `console.log()`, `print()` oder ähnlicher Output korrumpiert das Protokoll und führt zu Parsing-Fehlern.  
  **Lösung:** Alle Logs nach **stderr** umleiten (`console.error()` in Node.js, `sys.stderr.write()` in Python).

- [ ] **Nutzt du strukturiertes Logging?**  
  Falls du ein Logging-Framework verwendest (z. B. Winston, Pino, Python logging), konfiguriere es explizit auf stderr statt stdout.  
  **Tipp:** In der Entwicklung kannst du Logs in eine Datei schreiben, im Produktionsbetrieb auf stderr.

---

## 2. Transport-Wahl: stdio vs. SSE/HTTP

- [ ] **Hast du den richtigen Transport gewählt?**  
  - **stdio:** Für lokale Tools und Desktop-Integration (Claude Desktop, Claude Code). Der Server läuft als Subprocess des Clients.  
  - **SSE (Server-Sent Events):** Für remote-MCP-Server, die von mehreren Clients erreichbar sein sollen. Benötigt einen HTTP-Endpunkt.  
  **Faustregel:** Entwickelst du ein lokales Tool → stdio. Baust du einen Cloud-Service → SSE.

- [ ] **Ist dein Transport in der Client-Config korrekt?**  
  In `claude_desktop_config.json` (Claude Desktop) oder `.claude/settings.json` (Claude Code) muss der Transport-Typ zum Server passen:  
  - stdio: `"command": "node", "args": ["server.js"]`  
  - SSE: `"url": "http://localhost:3000/sse"`

---

## 3. Async-Initialisierung / Server startet nicht

- [ ] **Wartet dein Server auf async-Initialisierungen?**  
  Viele MCP-Server müssen DB-Verbindungen, API-Clients oder Caches initialisieren, bevor sie Requests beantworten. Stelle sicher, dass alle `await`-Statements abgeschlossen sind, bevor der Server "ready" meldet.  
  **Typischer Fehler:** Server sendet `initialize`-Response, bevor die DB-Verbindung steht → spätere Tool-Calls crashen.

- [ ] **Läuft dein Server überhaupt?**  
  Bei stdio: Der Prozess muss kontinuierlich laufen (kein `process.exit(0)` nach Initialisierung). Bei SSE: Der HTTP-Server muss auf dem konfigurierten Port lauschen.  
  **Debug-Tipp:** Schreibe beim Start eine Zeile nach stderr wie `"Server ready on stdio"`.

---

## 4. Tool-Schema / Parameter falsch deklariert

- [ ] **Ist dein Tool-Schema JSON-Schema-konform?**  
  MCP-Tools nutzen JSON-Schema für Parameter-Deklaration. Häufige Fehler:  
  - Fehlende `"type"` (z. B. `"type": "object"` für strukturierte Parameter).  
  - `required`-Array enthält Properties, die im Schema nicht existieren.  
  - Verschachtelte Objekte ohne eigenes `properties`-Feld.  
  **Lösung:** Validiere dein Schema mit einem JSON-Schema-Validator (z. B. https://www.jsonschemavalidator.net/).

- [ ] **Sind deine Tool-Namen eindeutig und sprechend?**  
  Tool-Namen müssen innerhalb des Servers eindeutig sein. Verwende kebab-case und beschreibende Namen (`read-file` statt `tool1`).  
  **Claude-Tipp:** Claude wählt Tools basierend auf Namen + Beschreibung. Präzise Beschreibungen erhöhen die Erfolgsrate.

- [ ] **Parst du Parameter korrekt?**  
  Der Client sendet Parameter als JSON-Objekt. Stelle sicher, dass du fehlende optionale Parameter abfängst und Required-Parameter validierst.  
  **Typischer Fehler:** `args.path` ist undefined, weil der User den Parameter nicht übergeben hat → Server crasht.

---

## 5. JSON-RPC-Framing-Fehler

- [ ] **Sendest du valides JSON-RPC 2.0?**  
  Jede Nachricht braucht: `jsonrpc: "2.0"`, `id` (für Requests/Responses), `method` (für Requests) oder `result`/`error` (für Responses).  
  **Häufiger Fehler:** Vergessenes `id`-Feld → Client kann Response nicht zuordnen.

- [ ] **Nutzt du Content-Length-Header bei stdio?**  
  Bei stdio-Transport muss jede Nachricht als `Content-Length: N\r\n\r\n{JSON}` geframet werden.  
  **Lösung:** Verwende eine MCP-SDK-Bibliothek (z. B. `@modelcontextprotocol/sdk` für Node.js), die das Framing übernimmt.

- [ ] **Hast du trailing Newlines oder Whitespace?**  
  Zusätzliche Leerzeichen oder Zeilenumbrüche nach dem JSON korrumpieren das Framing.  
  **Debug:** Schreibe eingehende/ausgehende Nachrichten roh nach stderr, um Whitespace sichtbar zu machen.

---

## 6. Client-Anbindung: Config-Fehler

- [ ] **Ist die Pfadangabe korrekt?**  
  In der Client-Config muss der Pfad zu deinem Server absolut oder relativ zum Client korrekt sein.  
  **Windows-Falle:** Backslashes müssen escaped werden: `"C:\\Users\\...\\server.js"` oder als Forward-Slashes: `"C:/Users/.../server.js"`.

- [ ] **Ist die Ausführungsumgebung korrekt?**  
  - Node.js: `"command": "node"` muss in PATH sein. Bei lokaler Node-Installation absolute Pfade nutzen.  
  - Python: `"command": "python"` (Windows) oder `"python3"` (Linux/macOS).  
  **Tipp:** Teste den Befehl manuell im Terminal: `node server.js` muss ohne Fehler starten.

- [ ] **Hast du die Config neu geladen?**  
  Nach Änderungen an `claude_desktop_config.json` oder `.claude/settings.json` musst du Claude Desktop neu starten oder Claude Code neu laden.  
  **Claude Code:** `Cmd/Ctrl+Shift+P` → "Reload Window".

---

## 7. Prozess- / Umgebungsprobleme

- [ ] **Sind alle Dependencies installiert?**  
  Bei Node.js: `npm install` ausgeführt? Bei Python: `pip install -r requirements.txt`?  
  **Falle:** Du entwickelst in einem venv, aber der Client startet den Server außerhalb → Module fehlen.

- [ ] **Stimmt die Node.js- / Python-Version?**  
  Manche MCP-SDKs erfordern Node.js ≥ 18 oder Python ≥ 3.10. Prüfe: `node --version` / `python --version`.  
  **Lösung:** Version-Manager (nvm, pyenv) oder absolute Pfade zur richtigen Runtime in der Client-Config.

- [ ] **Sind Umgebungsvariablen gesetzt?**  
  Falls dein Server API-Keys oder DB-Credentials aus `.env` liest, stelle sicher, dass sie im Client-Prozess verfügbar sind.  
  **Claude Desktop-Falle:** GUI-Apps erben nicht automatisch die Shell-Umgebung. Setze Vars explizit in der Config: `"env": {"API_KEY": "..."}`.

- [ ] **Läuft der Prozess überhaupt?**  
  Bei hartnäckigen Fehlern: Öffne den Task-Manager (Windows) / Activity Monitor (macOS) / `ps aux` (Linux) und prüfe, ob `node server.js` oder `python server.py` läuft.  
  **Wenn nicht:** Der Client kann den Server nicht starten → zurück zu Punkt 6 (Config).

---

## Weiterführende Ressourcen

- **[MCP-Server Starter-Kit](https://flowki-club.de/freebies/mcp-server-starter)** — Vorlagen und Code-Beispiele für Node.js und Python
- **[KI-Security-Kit](https://flowki-club.de/freebies/ki-security-kit)** — Sichere Patterns für LLM-Integration (auch MCP-Server)

---

*Erstellt von der FlowKI-Community. Für Feedback und Ergänzungen: https://flowki-club.de/community*
