This guide is for AI assistants and human operators who want fast, high-quality code understanding with CodeGraph MCP tools. Canonical MCP tool names are short (
search,context,node, etc.); legacycodegraph_*aliases still work.
CodeGraph is best when you use it as a semantic graph interface for code structure and relationships, not as a plain text search replacement.
It helps you answer:
- Where is behavior implemented?
- What calls this symbol?
- What does this symbol call?
- What is the impact radius of changing this?
- What is the shortest path from user input to effect?
- Start graph-first, not file-first.
- Scope queries early (path/language/kind) to reduce noise.
- Disambiguate symbols explicitly (
kind,pathHint) when names collide. - Retrieve code only when needed (
includeCode=truelate, not early). - Prefer iterative narrowing over broad exploratory dumps.
CodeGraph now works best with two explicit approaches:
- Use broad intent queries first.
- Allow file nodes and mixed kinds.
- Do not over-constrain too early.
search(query="architecture overview entry points", limit=15)
context(task="Give me a high-level module map and likely entry points", maxNodes=30, includeCode=false)
- Constrain by
kind,pathHint, and optionallylanguage. - Prefer
includeFiles=false. - Use callers/callees/impact to produce evidence-backed flow.
search(query="submitPrompt", kind="method", pathHint="sdk/js/src/v2/gen", limit=10)
context(task="Trace TUI submit to server processing", kind="function", pathHint="packages/opencode/src", includeFiles=false, includeCode=false)
If unsure, start in discovery mode for 1-2 calls, then switch to focused tracing.
set_root(path="/absolute/path/to/project")
status()
If indexing is stale:
- Run
codegraph syncfor incremental updates - Run
codegraph indexfor full rebuild
search(query="session", kind="function", language="typescript", pathHint="cli/cmd/tui", includeFiles=false, limit=10)
node(symbol="Session", kind="function", pathHint="cli/cmd/tui", includeCode=false)
callers(symbol="Session", kind="function", pathHint="cli/cmd/tui", limit=20)
callees(symbol="Session", kind="function", pathHint="cli/cmd/tui", limit=20)
context(
task="Trace TUI input to server handling and streaming updates",
maxNodes=30,
kind="function",
language="typescript",
pathHint="packages/opencode/src",
includeFiles=false,
includeCode=false
)
| Tool | Best use | Key params | Notes |
|---|---|---|---|
search |
Candidate discovery | query, kind, language, pathHint, includeFiles, limit |
Fastest first pass |
node |
Symbol details | symbol, kind, pathHint, includeCode |
Use includeCode=true only for finalists |
callers |
Upstream impact/use sites | symbol, kind, pathHint, limit |
Great for entrypoints and usage |
callees |
Downstream flow | symbol, kind, pathHint, limit |
Great for data/control flow tracing |
impact |
Change blast radius | symbol, kind, pathHint, depth |
Start with depth=2 |
context |
Task-level grounding | task, maxNodes, kind, language, pathHint, includeFiles, includeCode |
Use scoped context to avoid noise |
status |
Index sanity check | none | Always check before deep analysis |
If a symbol name is common (Session, start, loop, run), assume ambiguity.
node(symbol="Session", includeCode=true)
node(symbol="Session", kind="function", pathHint="cli/cmd/tui", includeCode=false)
- Add
kind. - Add
pathHint. - Add
languageat search stage. - Increase
limitand inspect candidates.
context(
task="Map request path from route handlers to persistence",
maxNodes=35,
kind="function",
language="typescript",
pathHint="src/server",
includeFiles=false,
includeCode=false
)
Then refine with targeted node/callers/callees lookups.
search(query="validateToken", kind="function", language="typescript", pathHint="src/auth", limit=10)
callers(symbol="validateToken", kind="function", pathHint="src/auth", limit=20)
callees(symbol="validateToken", kind="function", pathHint="src/auth", limit=20)
impact(symbol="validateToken", kind="function", pathHint="src/auth", depth=2)
search(query="session.ts", includeFiles=true, pathHint="cli/cmd/tui", limit=10)
Use file nodes when path/file intent is explicit.
Use this when you want strict graph-only investigation (no shell fallback).
set_root(...)status()context(...)withkind/language/pathHint/includeFiles=falsesearch(...)for missing anchorsnode(...)withincludeCode=falsecallers(...)andcallees(...)- Re-run
node(..., includeCode=true)on final symbols only - Produce final flow with exact symbol + file evidence
Goal: understand how user input in TUI becomes server execution and streams back.
set_root(path="/Volumes/Terra/Users/rick/Projects/openfork-1.0")
status()
context(
task="Trace TUI input -> SDK call -> server route -> prompt loop -> streaming updates back to TUI",
maxNodes=30,
kind="function",
language="typescript",
pathHint="packages/opencode/src",
includeFiles=false,
includeCode=false
)
search(query="Session", kind="function", language="tsx", pathHint="cli/cmd/tui", limit=10)
node(symbol="Session", kind="function", pathHint="cli/cmd/tui", includeCode=true)
search(query="prompt", kind="function", language="typescript", pathHint="server/routes", limit=10)
search(query="start", kind="function", language="typescript", pathHint="session/prompt", limit=10)
Deliverable format:
- Step-by-step flow (6-10 steps)
- For each step: symbol, file path, role in flow
- Explicit unresolved ambiguities
Actions:
- Add
pathHintto target the subsystem. - Add
languagefilter. - Add
kindfilter (function,method, etc.). - Set
includeFiles=falseunless file intent is explicit. - Reduce context scope (
maxNodes) and iterate.
Actions:
- Re-run with
kind+pathHint. - Use
searchfirst and inspect top candidates. - Use
node(..., includeCode=false)before full code extraction.
Actions:
- Rewrite task with specific subsystem nouns.
- Add
pathHintandlanguage. - Limit to function/method kinds first.
- Increase precision before increasing breadth.
Actions:
status()codegraph sync- Full
codegraph indexif needed
Bad:
context(task="learn this project")
Better:
context(
task="Trace OAuth login callback handling and token persistence",
kind="function",
language="typescript",
pathHint="src/auth",
includeFiles=false,
includeCode=false
)
Bad:
node(symbol="handler", includeCode=true)
Better:
search(query="handler", kind="function", pathHint="server/routes", limit=10)
node(symbol="authHandler", kind="function", pathHint="server/routes", includeCode=false)
Reading one symbol rarely explains behavior. Always place it in a graph neighborhood.
depth > 3 often becomes noisy. Start at depth=2.
Use CodeGraph first for:
- Symbol discovery and disambiguation
- Relationship tracing (callers/callees/impact)
- Task context assembly
- Scoped subsystem exploration
Use direct file/content tools when:
- You need exact literal text/strings not represented as symbols
- You need non-code files not indexed into the graph
- You need bulk text operations unrelated to symbol structure
Before finalizing analysis, verify:
- Root is set to the intended project
- Index is current enough for the task
- Ambiguous symbols were disambiguated with
kind/pathHint - Claims are backed by symbol+file evidence
includeCode=truewas used only where needed
Use ONLY CodeGraph MCP tools for this investigation (no shell/grep/glob/read fallback).
Project: /absolute/path/to/project
Task: <specific task>
Rules:
- Set root and verify status first.
- Prefer scoped queries (kind, language, pathHint, includeFiles=false).
- If symbol is ambiguous, retry with kind + pathHint.
- Use includeCode=true only on final symbols.
Deliverable:
- 6-10 step flow with exact symbols
- For each step: file path + role
- Explicit unknowns/ambiguities
CodeGraph is generally fast for iterative exploration, but speed depends on project size, language mix, and machine resources.
Practical guidance:
- Keep queries specific.
- Avoid broad context calls without filters.
- Use
search -> node(no code) -> callers/callees -> node(with code)as default loop.
# Project and index
set_root(path="/path/to/project")
status()
# If stale: sync() / index()
# Search and details
search(query="symbol", kind="function", language="typescript", pathHint="src/auth", includeFiles=false, limit=10)
node(symbol="symbol", kind="function", pathHint="src/auth", includeCode=false)
# Graph relationships
callers(symbol="symbol", kind="function", pathHint="src/auth", limit=20)
callees(symbol="symbol", kind="function", pathHint="src/auth", limit=20)
impact(symbol="symbol", kind="function", pathHint="src/auth", depth=2)
# Task context
context(task="specific engineering task", maxNodes=30, kind="function", language="typescript", pathHint="src/auth", includeFiles=false, includeCode=false)
This workflow consistently improves precision for both AI and human consumers.