How to Use query_graph_tool in code-review-graph: A Complete Guide

The query_graph_tool is an MCP tool in code-review-graph that lets AI assistants query structural relationships like callers, callees, imports, and tests by pattern-matching against a SQLite-backed code graph.

The code-review-graph (CRG) project provides a Model Context Protocol (MCP) server that exposes the query_graph_tool for navigating source-code relationships. This tool allows MCP clients to ask specific questions about your codebase—such as "who calls this function" or "which tests cover this module"—by traversing a pre-built SQLite graph store.

Where query_graph_tool Lives in the Source Code

The tool is registered as an MCP endpoint in code_review_graph/main.py (lines 247–254), which forwards incoming arguments to the core query engine implemented in code_review_graph/tools/query.py (lines 229–236 for the definition, and lines 255–318 for the execution logic).

Supported Query Patterns

The pattern parameter accepts the following values (defined in the tool signature in main.py and documented in docs/COMMANDS.md):

  • callers_of: Functions that call the target (with built-in call noise filtered).
  • callees_of: Functions called by the target.
  • references_to: Any node that references the target (e.g., variable uses).
  • imports_of: Import statements inside the target file or module.
  • importers_of: Files that import the target.
  • children_of: Nodes that are children of a class or file (e.g., methods inside a class).
  • tests_for: Test nodes that exercise the target.
  • inheritors_of: Classes that inherit from the target class.
  • file_summary: All nodes contained within a specific file.

Enabling the Tool

By default, the tool is exposed when the CRG server starts unless you restrict the tool list via environment variables or CLI flags.

Using the environment variable:

CRG_TOOLS=query_graph_tool code-review-graph serve

Using the CLI flag:

code-review-graph serve --tools query_graph_tool

How to Call query_graph_tool

From Python Using the Client Stub

Import the function from code_review_graph/main.py and pass the required arguments:

from code_review_graph.main import query_graph_tool

# Find who calls utils.py::process_data

resp = query_graph_tool(
    pattern="callers_of",
    target="utils.py::process_data",
    detail_level="standard",   # or "minimal"

    max_results=20
)

print(resp["status"])          # -> "ok"

print(resp["result_count"])    # number of callers returned

for node in resp["results"]:
    print(node["qualified_name"], node["kind"])

Over HTTP via MCP JSON-RPC

Send a POST request to the MCP server endpoint:

curl -X POST http://localhost:4000 \
  -H "Content-Type: application/json" \
  -d '{
        "jsonrpc":"2.0",
        "id":1,
        "method":"query_graph_tool",
        "params":{
          "pattern":"tests_for",
          "target":"auth/login",
          "detail_level":"minimal",
          "max_results":5
        }
      }'

Typical response structure:

{
  "jsonrpc":"2.0",
  "id":1,
  "result":{
    "status":"ok",
    "pattern":"tests_for",
    "target":"auth/login",
    "result_count":3,
    "results":[
      {"qualified_name":"tests/auth_test.py::test_login_success","kind":"Test"},
      {"qualified_name":"tests/auth_test.py::test_login_failure","kind":"Test"}
    ],
    "edges":[]
  }
}

Handling Ambiguous Targets

If the target matches multiple nodes, the tool returns status: "ambiguous" with a ranked candidate list:

resp = query_graph_tool(pattern="callers_of", target="handle", detail_level="standard")
if resp["status"] == "ambiguous":
    print("Choose one of these candidates:")
    for cand in resp["candidates"]:
        print(f"- {cand['qualified_name']} ({cand['kind']})")

Re-run the query using the fully-qualified name from the candidate list to disambiguate.

Using Minimal Detail Mode

Set detail_level="minimal" to cap visible results at five items and receive an omission count:

resp = query_graph_tool(
    pattern="callers_of",
    target="utils.py::process_data",
    detail_level="minimal",
    max_results=100
)
print(resp["summary"])          # short human-readable description

print(f"Omitted: {resp['results_omitted']} out of {resp['result_count']}")

Summary

  • The query_graph_tool is registered in code_review_graph/main.py (lines 247–254) and implemented in code_review_graph/tools/query.py.
  • It supports nine core patterns including callers_of, tests_for, and imports_of.
  • Enable it via CRG_TOOLS=query_graph_tool or the --tools CLI flag when starting the server.
  • Responses include status (ok, error, ambiguous, not_found), results, and edges; handle ambiguous status by selecting from the candidate list.
  • Use detail_level="minimal" for chat-oriented interfaces that need concise summaries with capped output.

Frequently Asked Questions

What is the difference between callers_of and references_to?

The callers_of pattern specifically traverses CALLS edges to find functions that invoke the target, filtering out built-in noise, while references_to returns any node that references the target—including variable reads, imports, or other usages—providing a broader but less specific relationship map.

How does target resolution work if I provide a partial name?

According to the implementation in code_review_graph/tools/query.py, the tool attempts resolution in three stages: first as an exact node name, then as an absolute file path, and finally via fuzzy search including Java Fully Qualified Name (FQN) candidates. If multiple nodes match, it returns an ambiguous status with ranked candidates rather than guessing.

Can I use query_graph_tool without starting the full MCP server?

No, the tool is exposed exclusively through the MCP server interface defined in main.py. However, you can filter to expose only this tool using CRG_TOOLS=query_graph_tool to minimize the surface area while still allowing graph queries.

What happens if max_results is set higher than available matches?

The tool returns all available matches up to the limit specified by max_results. If detail_level is set to "minimal", the visible list is further capped at five items, with the total count reflected in result_count and the overflow reported in results_omitted.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →