Skip to content

[MCP T6] impact_analysis MCP tool (variable-depth Cypher) #654

@DvirDukhan

Description

@DvirDukhan

Phase 1 ticket T6. Depends on #652 (T4 index_repo).

Context

impact_analysis answers the refactoring question "what breaks if I change this symbol?" via transitive upstream traversal. This is the only MCP tool with no existing backing implementation in api/graph.py — it requires a new variable-depth Cypher query.

Scope

In:

  • New helper in api/graph.py (sync) and api/graph.py async (AsyncGraphQuery):
    def impact_analysis(self, symbol_id: str, direction: str = "IN", depth: int = 3) -> list[dict]: ...
    Cypher pattern (upstream / IN direction):
    MATCH (n {id: $id})<-[:CALLS*1..$depth]-(impacted)
    RETURN DISTINCT impacted
    For OUT direction, flip the arrow. DISTINCT provides cycle safety.
  • Defaults: direction="IN" (upstream callers), depth=3. Hard cap depth to 10 to prevent runaway queries — pass higher values silently clamp with no error.
  • New MCP tool registration in api/mcp/tools/structural.py:
    @app.tool()
    async def impact_analysis(symbol_id: str, direction: str = "IN", depth: int = 3) -> list[dict]: ...
  • Tests in tests/mcp/test_impact_analysis.py:
    • Unit (mocked graph): depth clamp test (depth=999 → 10), direction validation (only IN and OUT accepted).
    • Cycle test: graph with A → B → A returns each node exactly once.
    • Linear chain: on a fixture with A→B→C→D, asserts impact_analysis("D", depth=3) returns {A, B, C}.
    • Depth boundary: same chain, impact_analysis("D", depth=2) returns {B, C}.
    • Integration: against the T3 fixture using expected.yaml impact assertions.
    • Protocol round-trip.

Out:

  • Cross-rel impact (only CALLS traversal in v1; future: CALLS|EXTENDS|IMPLEMENTS)
  • Weighted ranking
  • Cross-repo / cross-branch impact

Files to create / modify

  • api/graph.py — new Graph.impact_analysis() and AsyncGraphQuery.impact_analysis() methods
  • api/mcp/tools/structural.py — tool registration
  • new tests/mcp/test_impact_analysis.py
  • tests/mcp/fixtures/expected.yaml (T3) — extend with impact assertions for at least one symbol (this might already be in T3 if planned ahead; otherwise add here)

Acceptance criteria

  • Graph.impact_analysis and AsyncGraphQuery.impact_analysis methods exist and execute correct Cypher.
  • MCP tool registered with input schema symbol_id: str, direction: "IN"|"OUT" = "IN", depth: int = 3.
  • Linear chain test: on A→B→C→D, impact_analysis("D", depth=3, direction="IN") returns exactly {A, B, C}.
  • Linear chain test: direction="OUT" from A returns {B, C, D}.
  • Cycle test: A↔B returns each node exactly once (no infinite loop, no duplicates).
  • Depth clamp: depth=999 does not error; effective depth is 10. A unit test asserts the clamped Cypher parameter.
  • Direction validation: invalid values (e.g. "BOTH") raise a clear error before any query executes.
  • Integration test against T3 fixture using contract assertions.
  • Protocol round-trip test.
  • CI workflow [MCP T2] CI workflow with FalkorDB service for MCP tests #649 green.

Dependencies

Out of scope (do NOT do in this PR)

  • Multi-relation traversal (only CALLS for v1).
  • Ranking by call-frequency or path weight.
  • Cross-branch or cross-repo impact analysis.

Notes for the implementer

  • Variable-depth Cypher in FalkorDB: [:CALLS*1..$depth] is supported. Pass $depth as a query parameter.
  • Use DISTINCT impacted in the RETURN to handle cycles and diamond dependencies in one shot. No need to track visited nodes manually.
  • Document the depth clamp in the tool docstring so the agent understands the limit.
  • Reuse the protocol-test helper from T4.
  • For the cycle test fixture, create a small temporary graph at test time rather than adding cycles to the main T3 fixture (cycles in the shared fixture would complicate other tests).

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestmcpMCP server (model context protocol) work

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions