feat(mcp): single-env onboarding, --help prerequisites, and error classification#1175
Open
feat(mcp): single-env onboarding, --help prerequisites, and error classification#1175
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests.
... and 7 files with indirect coverage changes 🚀 New features to boost your workflow:
|
Contributor
There was a problem hiding this comment.
Pull request overview
Adds “single-environment onboarding mode” to the Recce MCP server to allow starting when target-base/ artifacts are missing, and expands test coverage around MCP tools and DB error classification.
Changes:
- Add
single_envmode to MCP server, including_warninginjection into diff tool responses and tool description hints. - Centralize DB error classification indicators and extend rowcount/sqlmesh error handling + summary rendering (
N/A). - Add new MCP E2E test suite (direct tool calls + full protocol) and CLI tests for single-env auto-detection.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
recce/mcp_server.py |
Adds single_env flag, warning injection, and centralized error classification/logging. |
recce/cli.py |
Documents prerequisites in --help and auto-enables single-env mode when target-base/ missing. |
recce/tasks/rowcount.py |
Extracts shared DB error indicator lists; improves sqlmesh error classification behavior. |
recce/summary.py |
Returns "N/A" when row count is unavailable due to known statuses (table missing/permission/etc.). |
recce/run.py |
Improves logging/handling for schema-diff auto-approval when expected DB errors occur. |
tests/test_mcp_e2e.py |
Adds E2E tests for MCP tools (DuckDB) and protocol wiring. |
tests/test_mcp_server.py |
Adds unit tests for single-env warnings, tool descriptions, and DB error classification. |
tests/test_cli.py |
Adds CLI tests ensuring single-env auto-detection + messaging. |
tests/test_summary.py |
Adds coverage for new "N/A" behavior under specific meta statuses. |
tests/test_rowcount_sqlmesh.py |
Adds sqlmesh rowcount error classification tests. |
pyproject.toml |
Pins sentry-sdk minimum version. |
Makefile |
Adds an mcp target (currently with a hard-coded local path). |
Comments suppressed due to low confidence (3)
recce/mcp_server.py:41
sentry_sdkis imported but never used in this module (onlysentry_metricsis referenced). This will fail flake8 with an unused import (F401); remove the unused import or use it explicitly.
try:
import sentry_sdk
from sentry_sdk import metrics as sentry_metrics
except ImportError:
sentry_sdk = None
sentry_metrics = None
recce/tasks/rowcount.py:337
_classify_sqlmesh_errorre-raises unknown exceptions viaraise error, which discards the original traceback and makes debugging harder. Prefer re-raising withraisefrom the originalexceptblock (or preserve the traceback withraise error.with_traceback(...)).
# Unknown error — re-raise
raise error
Makefile:155
- The
mcpmake target hard-codes a developer-specific absolute path (/Users/kent/...). This will break for other contributors and in CI, and it also leaks a local filesystem path into the repo. Please remove this target or refactor it to use a configurable env var (with a safe default) and document it outside the tracked Makefile if it’s only for local use.
JAFFLE_SHOP_DIR := /Users/kent/Project/recce/jaffle_shop_golden
mcp:
@dotenv -f $(JAFFLE_SHOP_DIR)/.env run python -m recce.cli mcp-server --sse \
--project-dir $(JAFFLE_SHOP_DIR) \
--profiles-dir $(JAFFLE_SHOP_DIR) \
--target-path $(JAFFLE_SHOP_DIR)/target \
--target-base-path $(JAFFLE_SHOP_DIR)/target-base \
--config $(JAFFLE_SHOP_DIR)/recce.yml \
--port 8000
When target-base/ directory is missing, MCP server now starts in single-env mode instead of crashing. Diff tools include _warning fields and tool descriptions note single-env limitations. Closes DRC-2794 Closes DRC-2795 Closes DRC-2796 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Kent <iamcxa@gmail.com>
- Unit tests for single-env passthrough, descriptions, CLI detection - E2E tests with DuckDB-backed fixtures (Layer 1 + Layer 2) - Skip MCP CLI tests when mcp package not installed DRC-2795, DRC-2796 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Kent <iamcxa@gmail.com>
Classify expected DB errors (table_not_found, permission_denied, syntax_error) as warnings with Sentry metrics instead of error events. Consolidate error indicator constants in rowcount.py as single source of truth. Fix schema_diff, sqlmesh, and summary error handling. - Central handler: classify → warning+metrics / error → re-raise - Remove duplicate logging from tool handlers - Upgrade sentry-sdk >= 2.44.0 for metrics API Closes DRC-2754 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Kent <iamcxa@gmail.com>
- Priority-order test: permission_denied wins over table_not_found - Sqlmesh error classification tests - Summary N/A detection and non-dict meta defensive tests DRC-2754 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Kent <iamcxa@gmail.com>
9980380 to
8e2dc61
Compare
- Use Union[] instead of PEP 604 syntax for Python 3.9 compatibility - Remove unused sentry_sdk import (only sentry_metrics is used) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Kent <iamcxa@gmail.com>
…ication - Add TestSchemaDiffShouldBeApproved: cover error classification in run.py - Add TestCallToolHandler: test call_tool error handler via MCP Server internals including sentry_metrics emission and classified/unclassified error logging Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Kent <iamcxa@gmail.com>
Add 7 tests covering uncovered patch lines: - lineage_diff missing base env, schema_diff removed/modified columns - run_check missing check_id and RecceException path - _query_row_count dbt path permission_denied and table_not_found Remove dead hasattr branches in test_mcp_e2e.py, add pragma: no cover to sentry import fallback. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Kent <iamcxa@gmail.com>
Add project-level skill for MCP server development guidance. Update AGENTS.md with coverage command and skills directory. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Kent <iamcxa@gmail.com>
iamcxa
added a commit
to DataRecce/recce-docs
that referenced
this pull request
Mar 4, 2026
Update prerequisites, server modes, and troubleshooting to reflect the new single-env onboarding mode where the MCP server starts without target-base/ artifacts. Depends on DataRecce/recce#1175 (DRC-2795). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
5 tasks
Adds a project-level skill for full-stack verification of all 8 MCP tools against a real dbt project. Includes a reusable Python test template that auto-discovers models and validates both full mode (8 tools) and single-env mode (5 warning checks). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Kent <iamcxa@gmail.com>
Remove local JAFFLE_SHOP_DIR and mcp target that were accidentally included in the PR. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Kent <iamcxa@gmail.com>
iamcxa
commented
Mar 5, 2026
Contributor
Author
iamcxa
left a comment
There was a problem hiding this comment.
Self-review: inline comments explaining design rationale for each DRC issue area.
…o dev skill - Restructure Testing section into Three Layers table (Unit/Integration/Smoke) - Add Test Coverage Gap Analysis: proactive scan across all three layers - Add E2E Verification Gate: interactive prompt to invoke /recce-mcp-e2e - Both gates share consistent exclusion rules (test-only, docs, imports) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Kent <iamcxa@gmail.com>
Use MCP protocol's `instructions` field to inform agents about single-environment mode during the initialize handshake, so they know the server state before calling any tools. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Kent <iamcxa@gmail.com>
- Remove overly broad "CATALOG ERROR" from TABLE_NOT_FOUND_INDICATORS; "DOES NOT EXIST" already catches DuckDB missing-table errors - Fix _classify_sqlmesh_error docstring to document raise behavior - Preserve exception chain: raise ValueError(str(e)) from e - Fix misleading "synchronously" comment on run_in_executor call - Clarify SKILL.md: priority order enforced by _classify_db_error(), sentry_metrics guarded by sentry_sdk availability - Add reference comment to unavailable_statuses in summary.py Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Kent <iamcxa@gmail.com>
iamcxa
added a commit
to DataRecce/recce-docs
that referenced
this pull request
Mar 6, 2026
Update prerequisites, server modes, and troubleshooting to reflect the new single-env onboarding mode where the MCP server starts without target-base/ artifacts. Depends on DataRecce/recce#1175 (DRC-2795). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
wcchang1115
reviewed
Mar 7, 2026
wcchang1115
requested changes
Mar 7, 2026
- Rename _maybe_add_warning → _maybe_add_single_env_warning for clarity - Show unavailable status reason in N/A display: "N/A (table_not_found)" Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Kent <iamcxa@gmail.com>
Contributor
Author
|
All review feedback addressed — please see individual thread replies for details. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
target-base/is missing — no longer throws rawFileNotFoundErrortarget-base/is missing, usestarget/for both environments with_warningin diff responses and description hints--helpprerequisites section documenting required dbt artifactslogger.warning()+ Sentry metrics, unclassified →logger.error()+ tracebackReviewer Guide
Quick mapping from issue → code area. Start here if you're reviewing file-by-file.
target-base/recce/cli.py→mcp_server()detects missing dir, setssingle_env=True_warningin single-env moderecce/mcp_server.py→_maybe_add_warning(), diff tool descriptions--helpshows prerequisitesrecce/cli.py→mcp_server()epilog textrecce/mcp_server.py→_classify_db_error()incall_tool;recce/tasks/rowcount.py→ shared indicator constantsDesign notes for reviewers:
_maybe_add_warning()only applies to 3 diff tools (row_count_diff,query_diff,profile_diff) —lineage_diffandschema_diffwork without base env, so no warning neededpermission_denied>table_not_found>syntax_error(first match wins) — this matches severity orderisError=Truerun.py:schema_diff_should_be_approved()try/except is intentional — ensures check creation even on errorChanges
Single-env onboarding (DRC-2794 + DRC-2795)
target-base/and setssingle_env=True(fixes DRC-2794 crash)_maybe_add_warning()adds_warningfield to diff tool resultsHelp text prerequisites (DRC-2796)
recce mcp-server --helpshows prerequisites section before examplesError classification (DRC-2754)
recce/tasks/rowcount.py_classify_db_error()in MCP central handler: permission_denied > table_not_found > syntax_errorlogger.warning()+sentry_metrics.count(); unclassified →logger.error()run.pyschema_diff_should_be_approved()and sqlmesh pathTest coverage
_query_row_countdbt path permission_denied and table_not_found branchesDocs
.claude/skills/recce-mcp-dev/).claude/skills/recce-mcp-e2e/)Demo
https://www.loom.com/share/91c92e56501d460d95b421e6a2ce1649
DRC-2795 single-env onboarding + MCP E2E auto test
Test plan
python -m pytest tests/test_mcp_server.py tests/test_mcp_e2e.py -v— 71 tests passpython -m pytest tests/test_run.py tests/test_summary.py tests/test_rowcount_sqlmesh.py— 40 tests passmake flake8— cleanCloses DRC-2794, DRC-2795, DRC-2796, DRC-2754
🤖 Generated with Claude Code