mit einem Klick
recce-mcp-dev
// Use when modifying recce/mcp_server.py, MCP tool handlers, error classification, or MCP-related tests. Also use when adding new MCP tools or changing tool response formats.
// Use when modifying recce/mcp_server.py, MCP tool handlers, error classification, or MCP-related tests. Also use when adding new MCP tools or changing tool response formats.
Use when consolidating open Dependabot PRs into a single branch. Fetches all open Dependabot PRs from the repo, applies dependency updates locally, tests for breakage, and creates a single PR that closes all Dependabot PRs.
Use when given a Linear issue ID, URL, identifier, or project name/URL to analyze and plan work. For issues, fetches the issue, classifies it, explores relevant code, proposes an approach, and orchestrates the right skills. For projects, fetches the project with milestones and issues, builds a prioritized execution plan, and systematically works through issues respecting project structure and dependencies.
Use when MCP server code is modified and needs full E2E verification against a real dbt project. Triggers after changes to recce/mcp_server.py, MCP tool handlers, single-env logic, or error classification. Also use before merging MCP PRs.
| name | recce-mcp-dev |
| description | Use when modifying recce/mcp_server.py, MCP tool handlers, error classification, or MCP-related tests. Also use when adding new MCP tools or changing tool response formats. |
RecceMCPServer registers list_tools/call_tool handlers via MCP SDK Server. call_tool dispatches to _tool_* methods, classifies errors, logs/emits metrics, re-raises.
Entry point run_mcp_server() pops single_env before passing kwargs to load_context().
Error classification — Shared indicator lists defined in recce/tasks/rowcount.py. Priority order (PERMISSION_DENIED > TABLE_NOT_FOUND > SYNTAX_ERROR) enforced by _classify_db_error() in mcp_server.py and _query_row_count() in rowcount.py. Classified → logger.warning() + sentry_metrics.count() (when sentry_sdk available). Unclassified → logger.error() + traceback.
MCP SDK quirk — Handler must raise for SDK to set isError=True.
Response contracts — See CLAUDE.md. Additive _meta only. summary.py: guard with is None, not dict.get(key, 0). N/A display includes reason: "N/A (table_not_found)".
Single-env — _maybe_add_single_env_warning() adds _warning to diff results. Descriptions get conditional note.
| Layer | File | Data Source | Runs In | Purpose |
|---|---|---|---|---|
| Unit | tests/test_mcp_server.py | Mock RecceContext | CI (pytest) | Logic correctness — tool handlers, error classification, response format |
| Integration | tests/test_mcp_e2e.py | DbtTestHelper + DuckDB (fixed data) | CI (pytest) | MCP protocol works end-to-end via anyio memory streams |
| Smoke (E2E) | /recce-mcp-e2e skill | User's real dbt project + real database | Manual | All 8 tools return valid results against real data |
Each new MCP feature or behavior change should be covered at all three layers.
After completing a round of MCP changes (see E2E Gate below for definition), proactively scan for missing test coverage across the three layers before asking about E2E verification.
How to check:
tests/test_mcp_server.py have a test case for the new behavior? (happy path + error path)tests/test_mcp_e2e.py exercise the new tool/feature via MCP protocol?/recce-mcp-e2e template cover the new tool? (If a new tool was added, the template may need updating)If gaps are found, report them to the user before the E2E gate prompt:
Test coverage gaps found:
- Unit: missing test for
_tool_fooerror path when table not found- Integration:
test_mcp_e2e.pydoes not exercisefootool- Smoke:
/recce-mcp-e2etemplate does not includefootoolWant to fill these gaps before running E2E?
Do NOT scan after: test-only changes, comment/doc edits, import reordering.
After each meaningful round of MCP changes, you MUST ask the user:
MCP changes complete for this round. Run
/recce-mcp-e2eto verify?
If the user says yes, invoke /recce-mcp-e2e. If a dbt project path was used earlier in this session, reuse it automatically; otherwise ask.
What counts as "a round":
Do NOT ask after: test-only changes, comment/doc edits, import reordering.
This is separate from tests/test_mcp_e2e.py — that file tests with DbtTestHelper + DuckDB in CI. /recce-mcp-e2e verifies all 8 tools against a real dbt project with a real database.
sentry_sdk import: # pragma: no cover on except (CI always has it)Union[X, Y] not X | Yrun.py schema_diff_should_be_approved() try/except is intentional (ensures check creation)recce/mcp_server.py (server + handlers), recce/tasks/rowcount.py (error indicators, RowCountStatus), recce/run.py (CLI preset), recce/summary.py (display logic), recce/event/__init__.py (Sentry)