Recce MCP Server Entwicklung
Architektur
RecceMCPServer registriert list_tools/call_tool-Handler über das MCP SDK Server. call_tool leitet an _tool_*-Methoden weiter, klassifiziert Fehler, protokolliert/emittiert Metriken und wirft erneut.
Der Einstiegspunkt run_mcp_server() entfernt single_env, bevor die kwargs an load_context() übergeben werden.
Wichtige Muster
Fehlerklassifizierung – Gemeinsame Indikatorlisten definiert in recce/tasks/rowcount.py. Prioritätsreihenfolge (PERMISSION_DENIED > TABLE_NOT_FOUND > SYNTAX_ERROR) wird durch _classify_db_error() in mcp_server.py und _query_row_count() in rowcount.py erzwungen. Klassifiziert → logger.warning() + sentry_metrics.count() (wenn sentry_sdk verfügbar). Nicht klassifiziert → logger.error() + Traceback.
MCP SDK Eigenheit – Handler muss werfen, damit das SDK isError=True setzt.
Antwortverträge – Siehe CLAUDE.md. Nur additives _meta. summary.py: mit is None prüfen, nicht dict.get(key, 0). N/A-Anzeige enthält Grund: "N/A (table_not_found)".
Single-Env – _maybe_add_single_env_warning() fügt _warning zu Diff-Ergebnissen hinzu. Beschreibungen erhalten bedingte Notiz.
Testen (Drei Schichten)
| Schicht | Datei | Datenquelle | Läuft in | Zweck |
|---|---|---|---|---|
| Unit | tests/test_mcp_server.py | Gemockter RecceContext | CI (pytest) | Logik-Korrektheit – Tool-Handler, Fehlerklassifizierung, Antwortformat |
| Integration | tests/test_mcp_e2e.py | DbtTestHelper + DuckDB (feste Daten) | CI (pytest) | MCP-Protokoll funktioniert Ende-zu-Ende über anyio Memory Streams |
| Smoke (E2E) | /recce-mcp-e2e Skill | Echtes dbt-Projekt + echte Datenbank | Manuell | Alle 8 Tools liefern gültige Ergebnisse gegen reale Daten |
Jede neue MCP-Funktion oder Verhaltensänderung sollte auf allen drei Schichten abgedeckt sein.
Analyse der Testabdeckungslücken
Nach Abschluss einer Runde von MCP-Änderungen (siehe E2E-Gate unten für Definition) proaktiv nach fehlender Testabdeckung in den drei Schichten suchen, bevor nach E2E-Überprüfung gefragt wird.
So prüfen Sie:
- Identifizieren, was sich geändert hat – neuer Tool-Handler? neuer Fehlerpfad? neues Antwortfeld?
- Für jede Änderung prüfen, ob auf jeder Schicht Abdeckung vorhanden ist:
- Unit: Enthält
tests/test_mcp_server.pyeinen Testfall für das neue Verhalten? (Happy Path + Fehlerpfad) - Integration: Übt
tests/test_mcp_e2e.pydas neue Tool/Feature über das MCP-Protokoll aus? - Smoke: Deckt die
/recce-mcp-e2e-Vorlage das neue Tool ab? (Wenn ein neues Tool hinzugefügt wurde, muss die Vorlage möglicherweise aktualisiert werden)
- Unit: Enthält
Wenn Lücken gefunden werden, melden Sie sie dem Benutzer vor der E2E-Gate-Aufforderung:
Testabdeckungslücken gefunden:
- Unit: Fehlender Test für den Fehlerpfad von
_tool_foobei nicht gefundener Tabelle- Integration:
test_mcp_e2e.pyübt dasfoo-Tool nicht aus- Smoke: Die
/recce-mcp-e2e-Vorlage enthält dasfoo-Tool nichtMöchten Sie diese Lücken vor dem Ausführen des E2E-Tests schließen?
NICHT scannen nach: Nur-Test-Änderungen, Kommentar-/Dokumentationsänderungen, Import-Neuordnungen.
E2E-Überprüfungs-Gate
Nach jeder sinnvollen Runde von MCP-Änderungen MÜSSEN Sie den Benutzer fragen:
MCP-Änderungen für diese Runde abgeschlossen.
/recce-mcp-e2eausführen, um zu überprüfen?
Wenn der Benutzer ja sagt, /recce-mcp-e2e aufrufen. Wenn in dieser Sitzung bereits ein dbt-Projektpfad verwendet wurde, diesen automatisch wiederverwenden; andernfalls nachfragen.
Was als "eine Runde" zählt:
- Ein Tool-Handler wurde hinzugefügt oder geändert + seine Unit-Tests bestehen
- Die Fehlerklassifizierungslogik wurde geändert + Tests bestehen
- Single-Env oder Antwortformat wurde geändert + Tests bestehen
NICHT fragen nach: Nur-Test-Änderungen, Kommentar-/Dokumentationsänderungen, Import-Neuordnungen.
Dies ist getrennt von tests/test_mcp_e2e.py – diese Datei testet mit DbtTestHelper + DuckDB in CI. /recce-mcp-e2e überprüft alle 8 Tools gegen ein echtes dbt-Projekt mit einer echten Datenbank.
Fallstricke
sentry_sdk-Import:# pragma: no coverauf except (CI hat es immer)- Python 3.9:
Union[X, Y]nichtX | Y - Pre-commit: black/isort können umformatieren – erneut stagen und committen
run.pyschema_diff_should_be_approved()try/except ist beabsichtigt (stellt sicher, dass die Prüfung erstellt wird)
Dateizuordnung
recce/mcp_server.py (Server + Handler), recce/tasks/rowcount.py (Fehlerindikatoren, RowCountStatus), recce/run.py (CLI-Voreinstellung), recce/summary.py (Anzeigelogik), recce/event/__init__.py (Sentry)