feat: add v2 navigation tools (PR-V2-1)#49
Conversation
Implement the v2 search/find/describe/neighbors surface alongside v1 with shared filter models and parity-focused tests so migration can proceed with confidence. Co-authored-by: Cursor <cursoragent@cursor.com>
Review: PR-V2-1 — feat: add v2 navigation toolsVerdict: Approved ✅ PR is on-spec for Scope discipline (out-of-scope checks)
Plan compliance
TestsDelta vs baseline (master at Manual evidence reproducedRebuilt the fixture graph at from mcp_v2 import find_v2, describe_v2, neighbors_v2
from kuzu_queries import KuzuGraph
g = KuzuGraph('/tmp/v21_check')
hits = find_v2('symbol', {'role': 'SERVICE'}, limit=3, offset=0, graph=g)
sid = hits.results[0].id
rec = describe_v2(sid, graph=g)
edges = neighbors_v2(sid, direction='in', edge_types=['CALLS'], limit=10, offset=0, filter=None, graph=g)Output: ✅ Sentinel sanity: Notes that earned my trust
Observations (non-blocking)
Plan deltas neededNone. The plan is internally consistent with what shipped; the +1 bonus test is a quality improvement, not a deviation worth re-recording. Ready to merge. Next: PR-V2-2 ( |
|
Thanks — captured the non-blocking review notes as explicit follow-ups: Follow-ups (deferred intentionally)
No blockers for this PR; keeping current scope unchanged. |
Scope
Implement
plans/PLAN-MCP-API-V2.md§ PR-V2-1 by adding v2 navigation tools (search,find,describe,neighbors) alongside the existing v1 surface.Plan link: plans/PLAN-MCP-API-V2.md § PR-V2-1
What Changed
mcp_v2.pywith sharedNodeFilter, output DTOs,_node_kind_from_id, andsearch_v2/find_v2/describe_v2/neighbors_v2handlers.server.pyafter v1 registrations:search,find,describe,neighbors.README.mdsubsection### v2 navigation tools (preview)right after the v1 tool reference.tests/test_mcp_v2.pywith PR-V2-1 unit coverage plus one extra regression test for requiredfind.filtervalidation.tests/test_mcp_v2_equivalence.pywith the 14 prescribed v1↔v2 equivalence tests.Semantics / Non-Goals
describe_v2.edge_summaryremainsNonein this PR (PR-V2-2 scope).search_v2.symbol_idconsistency improvements beyond current behavior are deferred to PR-V2-2 scope._graph_meta_outputper-edge-type count expansion is not included (PR-V2-2 scope).Validation
Lint
Tests
python -m pytest tests -q✅360 passed, 4 skippedtests/test_mcp_v2.py+19,tests/test_mcp_v2_equivalence.py+14). The extra +1 test is an intentional regression guard for missingfind.filtervalidation.Additional checks
python -m pytest tests/test_mcp_v2.py tests/test_mcp_v2_equivalence.py -q✅ (33 passed)python build_ast_graph.py --source-root tests/bank-chat-system --kuzu-path /tmp/mcp_v2_pr_graph --verbose✅Sentinel checks
rg "trace_v2|ask_v2|impact_v2" mcp_v2.py-> no matchesrg "@mcp\.tool" server.py-> 27 registrationsrg "def (describe_v2|neighbors_v2)\(" mcp_v2.py-> both handlers present, nokindargumentManual evidence
rg "@mcp\.tool" server.py | wc -l27rg "def (describe_v2|neighbors_v2)\(" mcp_v2.pydef describe_v2(id: str, graph: KuzuGraph | None = None)anddef neighbors_v2(ids: str | list[str], ...)python -c "from mcp_v2 import find_v2, describe_v2, neighbors_v2; from kuzu_queries import KuzuGraph; g=KuzuGraph('/tmp/mcp_v2_pr_graph'); hits=find_v2('symbol', {'role':'SERVICE'}, limit=3, offset=0, graph=g); sid=hits.results[0].id; print('symbol_id:', sid); rec=describe_v2(sid, graph=g); print('kind:', rec.record.kind, 'fqn:', rec.record.fqn); edges=neighbors_v2(sid, direction='in', edge_types=['CALLS'], limit=10, offset=0, filter=None, graph=g); print('callers:', len(edges.results))"symbol_id,kind/fqn, and caller count shape as expected.Out of Scope Confirmed
Did not implement:
describe_v2.edge_summarypopulationsearch_v2full symbol-id consistency sweep_graph_meta_outputedge-type count expansionuser_rag/cli.py,pyproject.tomlpackaging changes)Definition of Done
masterwith agreed title and branch naming.Made with Cursor