Skip to content

[MCP T4] index_repo MCP tool #652

Description

@DvirDukhan

Phase 1 ticket T4. Depends on #648 (T1 scaffold), #650 (T3 fixture), #651 (T17 per-branch graphs).

Context

First real MCP tool. index_repo is what every agent calls reflexively at the start of every interaction to ensure freshness — so it has to be branch-aware (T17) and (eventually) incremental-by-default (T18). This ticket implements branch awareness; T18 layers incremental on top.

Scope

In:

  • api/mcp/tools/structural.py::index_repo(path_or_url, branch=None, incremental=True, ignore=None).
  • Wraps Project.from_git_repository() (api/project.py:50-60) and Project.from_local_directory() + Project.analyze_sources() (api/project.py:79-94). All sync; the MCP wrapper calls them via asyncio.get_event_loop().run_in_executor(None, ...).
  • When branch is None, auto-detects from git rev-parse --abbrev-ref HEAD in the target path (delegated to the helper added in T17). For non-git paths, uses _default.
  • The incremental parameter is accepted now and forwarded to Project.analyze_sources(incremental=...). Until T18 lands, the underlying API ignores it and always does a full re-index — that is fine. T18 makes the parameter actually do something.
  • Tool registration via @app.tool() in api/mcp/tools/structural.py. Tool registered with app from api/mcp/server.py.
  • Returns:
    {
      "project_name": "...",
      "branch": "...",
      "num_nodes": 123,
      "num_edges": 456,
      "languages_detected": ["python", "java"],
      "mode": "full" | "incremental"
    }
  • Tests in tests/mcp/test_index_repo.py:
    • Unit: mocks Project, asserts argument routing and output shape, including the branch auto-detection branch (mock git rev-parse).
    • Integration: indexes the T3 fixture, asserts node/edge counts match expected.yaml, verifies graph name follows code:{project}:{branch} pattern via FalkorDB.list_graphs().
    • Branch override: explicit branch="custom" writes to code:{project}:custom.
    • Non-git path: indexing a tempdir writes to code:{project}:_default.
    • Protocol round-trip: spawns cgraph-mcp via the mcp SDK stdio client, calls session.list_tools() and asserts index_repo is registered with the right input schema, then calls session.call_tool("index_repo", {...}) and asserts a non-error response.

Out:

  • Other structural tools (T5–T8)
  • GraphRAG init (T9)
  • ask tool (T11)
  • Auto-init / auto-index on first tool call (T12)
  • The actual incremental skip-unchanged logic (T18) — only the parameter plumbing lives here.

Files to create / modify

  • new api/mcp/tools/__init__.py
  • new api/mcp/tools/structural.py
  • modified api/mcp/server.py — register the tool module on app startup
  • new tests/mcp/test_index_repo.py

Acceptance criteria

  • Tool registered with FastMCP and discoverable via session.list_tools().
  • Tool input schema declares path_or_url: str, branch: str | None = None, incremental: bool = True, ignore: list[str] | None = None.
  • Unit test asserts argument routing and output shape with mocked Project.
  • Unit test for branch auto-detection: mocked subprocess.run(['git', 'rev-parse', '--abbrev-ref', 'HEAD']) is called for git paths and the result is used as the branch.
  • Integration test indexes the T3 fixture and asserts node/edge counts from expected.yaml.
  • Integration test verifies the FalkorDB graph name is code:{project}:{branch} (use FalkorDB.list_graphs() to confirm).
  • Branch-override test: index_repo(path, branch="custom") writes to code:{project}:custom.
  • Non-git-path test: indexing a non-git tempdir writes to code:{project}:_default.
  • Protocol round-trip test calls the tool via the stdio client and asserts a non-error response.
  • CI workflow [MCP T2] CI workflow with FalkorDB service for MCP tests #649 runs all of the above green.

Dependencies

Out of scope (do NOT do in this PR)

  • The actual incremental skip logic (T18 implements; this ticket only forwards the flag).
  • Any other tool.
  • Cloning to a different remote, branch checkout for remote URLs, or git fetch/pull behavior beyond what Project.from_git_repository already does.
  • Telemetry / progress reporting.

Notes for the implementer

  • Keep the wrapper paper-thin. Real work belongs in api/project.py.
  • For branch auto-detection, prefer the helper added in T17 ([MCP T17] Per-branch graph identity (multi-branch indexing) #651) over re-implementing git rev-parse. If T17 didn't expose one, add it there in a follow-up — do not duplicate the logic in api/mcp/.
  • The incremental flag is in the schema today even though it's a no-op until T18 lands. This avoids a breaking schema change later.
  • Use a small _run_protocol_test helper (copy from T1's smoke test) for the round-trip assertion. Subsequent tool tickets will reuse the same helper.
  • Reference for sync→async wrapping: see api/llm.py:271-273 for the existing run_in_executor pattern around _ask_sync.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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