| name | atcode |
| description | Advanced code exploration using AtCode knowledge graph with qualified_name-based workflow. Use for cross-file analysis, call tracing, and semantic search. |
| version | 2.6.0 |
| author | zijing team |
AtCode Code Explorer
AtCode provides advanced code exploration through a knowledge graph. It complements Claude Code's native file reading capabilities.
Critical: Understanding qualified_name
ALL AtCode tools use qualified_name to identify code elements.
Format: project_name.module.path.ClassName.method_name
Examples:
- Function:
vllm.worker.worker.execute_model
- Class method:
vllm.attention.PagedAttention.forward
- Class:
vllm.modeling_models.llama_llm_LlamaForCausalLM
Key Rules:
- Always start with
find_nodes() to get the qualified_name
- Use that qualified_name with other tools
- The project_name prefix is auto-added based on
set_project()
Getting Started
Step 1: Check Health (if errors occur)
check_health()
Step 2: List Available Projects
list_repos()
Step 3: Set Project Context
set_project(project_name="vllm")
Important: Use the exact name returned by list_repos(). Projects may or may not have suffixes depending on how they were built.
Step 4: Find Code
find_nodes("attention")
Step 5: Get Details
get_code_snippet(qualified_name="vllm.attention.PagedAttention.forward")
find_calls(qualified_name="vllm.attention.PagedAttention.forward",
direction="incoming")
explore_code(identifier="vllm.attention.PagedAttention.forward")
Standard Workflow
┌─────────────────────────────────────────────────────────────┐
│ 1. list_repos() → discover available projects │
│ ↓ │
│ 2. set_project("exact_name") → set context │
│ ↓ │
│ 3. find_nodes("keyword") → get qualified_name │
│ ↓ │
│ 4. Use qualified_name with: │
│ - get_code_snippet(qualified_name="...") │
│ - find_calls(qualified_name="...", direction="...") │
│ - explore_code(identifier="...") │
│ - find_class_hierarchy(class_qualified_name="...") │
│ - trace_dependencies(start_qualified_name="...") │
└─────────────────────────────────────────────────────────────┘
When to Use AtCode vs Native Tools
| Use AtCode MCP for: | Use Claude Code Native for: |
|---|
| Cross-file relationship analysis | Reading a single file |
| Call tracing ("who calls this") | Simple "show me this function" |
| Large-scale discovery (100+ files) | Small projects, simple questions |
| Class hierarchy analysis | Single class inspection |
| Dependency chain tracing | Direct imports only |
Available Tools
Discovery
find_nodes - Find Code by Name
START HERE - Search for functions, classes, methods.
Syntax:
- Single keyword:
"attention" (RECOMMENDED)
- OR pattern:
"flash|attn"
- Glob:
"get_*_config"
Returns: List of nodes with qualified_name that you use with other tools.
find_nodes("main")
find_nodes("cache|config")
Analysis
find_calls - Trace Call Relationships
AtCode superpower - trace who calls what.
Requires: qualified_name from find_nodes()
find_calls(
qualified_name="vllm.worker.worker.execute_model",
direction="incoming"
)
find_calls(
qualified_name="vllm.worker.worker.execute_model",
direction="outgoing",
depth=2
)
Response Structure:
{
"success": true,
"results": [
{
"qualified_name": "vllm.engine.run",
"name": "run",
"type": ["Function"],
"path": "vllm/engine.py"
}
],
"count": 1,
"summary": "Found 1 function(s) that call..."
}
explore_code - Complete Context
Get source + callers + dependencies in ONE call.
explore_code(identifier="vllm.worker.worker.execute_model")
Returns:
- Source code
- All callers (incoming)
- All dependencies (outgoing)
- Dependency tree
find_class_hierarchy - Class Inheritance Analysis
Find parent classes and child classes of a class.
find_class_hierarchy(class_qualified_name="vllm.attention.PagedAttention")
Response Structure:
{
"success": true,
"results": [{
"class_name": "vllm.attention.PagedAttention",
"parents": ["vllm.attention.BaseAttention"],
"children": ["vllm.attention.FlashAttention"]
}],
"summary": "Found inheritance hierarchy..."
}
Use Cases:
- Understanding class relationships before refactoring
- Checking impact of base class changes
- Analyzing inheritance patterns
trace_dependencies - Dependency Chain Analysis
Trace paths between code elements and detect circular dependencies.
trace_dependencies(
start_qualified_name="vllm.main",
end_qualified_name="vllm.database.connect",
max_depth=5
)
trace_dependencies(
start_qualified_name="vllm.main",
max_depth=3
)
Response Structure:
{
"chain": [
{"from": "vllm.main", "to": "vllm.engine.run", "type": "CALLS"},
{"from": "vllm.engine.run", "to": "vllm.database.connect", "type": "CALLS"}
],
"depth": 2,
"total_elements": 3,
"has_circular": false,
"circular_paths": [],
"summary": "Found path from vllm.main to vllm.database.connect..."
}
Use Cases:
- Finding how function A eventually calls function B
- Detecting circular dependencies
- Impact analysis before refactoring
Retrieval
get_code_snippet - Get Source Code
get_code_snippet(qualified_name="vllm.attention.PagedAttention.forward")
Response Structure:
{
"found": true,
"qualified_name": "vllm.attention.PagedAttention.forward",
"file_path": "vllm/attention.py",
"line_start": 100,
"line_end": 150,
"source_code": "def forward(self, ...):\n ...",
"docstring": "Forward pass documentation..."
}
get_children - Navigate Structure
Get children of any node type.
Special identifier values:
"." - Current project from set_project()
Identifier types:
"auto" - Auto-detect (recommended)
"project" - By project name
"folder" - By file path
"file" - By file path or qualified_name
"class" - By qualified_name
get_children(identifier=".", identifier_type="auto", depth=2)
get_children(identifier="vllm.modeling_models.LlamaModel",
identifier_type="class")
get_children(identifier="src/models/llama.py", identifier_type="file")
Graph Management
build_graph - Build Knowledge Graph
build_graph(project_path="/path/to/project", project_name="myproject")
refresh_graph - Update After Changes
refresh_graph(project_name="myproject")
clean_graph - Remove Graph
clean_graph(project_name="myproject")
Workflows
Workflow 1: Understanding a Function
find_nodes("calculate_attention")
explore_code(identifier="vllm.attention.calculate_attention")
Workflow 2: Refactoring - Who Uses This?
find_nodes("deprecated_function")
find_calls(
qualified_name="vllm.utils.deprecated_function",
direction="incoming",
depth=3
)
get_code_snippet(qualified_name="...")
Workflow 3: Project Overview
list_repos()
build_graph(project_path=".", project_name="myproject")
set_project(project_name="myproject_claude")
get_children(identifier=".", depth=2)
find_nodes("main|cli|start")
Workflow 4: Troubleshooting
check_health()
Workflow 5: Class Hierarchy Analysis
find_nodes("BaseAttention")
find_class_hierarchy(class_qualified_name="vllm.attention.BaseAttention")
get_code_snippet(qualified_name="vllm.attention.FlashAttention")
Workflow 6: Circular Dependency Detection
find_nodes("process_request")
trace_dependencies(
start_qualified_name="vllm.engine.process_request",
max_depth=10
)
Error Handling
Common Errors and Solutions
| Error | Cause | Solution |
|---|
| "No project context" | set_project() not called | Call set_project(project_name="...") first |
| "Cannot connect to Memgraph" | Database not running | Run docker ps | grep memgraph to check |
| "Code not found" | Invalid qualified_name | Use find_nodes() first to get valid names |
| "Project not found" | Wrong project name | Use list_repos() to see available names |
Error Recovery Workflow
result = check_health()
if result["database"]["status"] == "error":
pass
if result["project_context"]["status"] == "not_set":
list_repos()
set_project(project_name="...")
Best Practices
- Always start with
find_nodes() - Get qualified_name first
- Use single keywords -
"flops" not "flops calculation"
- Use
| for variants - "torch|cuda" not "torch cuda"
- Use
explore_code for deep dives - One call vs many
- Check
list_repos() first - Avoid rebuilding existing graphs
- Run
check_health() on errors - Diagnose connection issues
- Use
find_class_hierarchy for OOP analysis - Understand inheritance
- Use
trace_dependencies for impact analysis - Before refactoring
Performance Tips
- find_calls depth: Keep depth ≤ 3 for interactive use; depth 5 can be slow
- trace_dependencies: Use smaller max_depth (3-5) for faster results
- find_nodes: Single keywords are faster than complex patterns
- sync tools: Use
skip_embeddings=True for faster updates if semantic search not needed
Filtering Search Results
Excluding Test Files
Search results often include test files. Use path patterns to focus on main code:
find_nodes("generate")
find_nodes("entrypoints.*generate")
find_nodes("LLM.generate")
Path-based Filtering Tips
- Prefix with module path:
"project.engine.generate" vs "generate"
- Use glob patterns:
"worker*execute" matches worker-related execute functions
- Combine with type:
node_type="Code" excludes File/Folder nodes
Limitations & Known Issues
Call Relationships May Be Empty
find_calls() and trace_dependencies() may return empty results for some functions:
Causes:
- C++/CUDA code: Call relationships are only tracked for Python code
- Dynamic dispatch: Calls through
getattr(), decorators, or metaclasses may not be captured
- External libraries: Calls to third-party packages aren't tracked
- Incomplete graph build: The graph may not have analyzed all call sites
Workaround:
explore_code(identifier="project.module.function")
get_code_snippet(qualified_name="project.module.function")
explore_code Source Code May Be Null
The code_snippet field in explore_code() results may be null if:
- The file path cannot be resolved
- The project_root is not correctly set
- The file exists but reading failed
Workaround:
result = explore_code(identifier="project.module.function")
if result.get("code_snippet") is None:
get_code_snippet(qualified_name="project.module.function")
get_code_snippet Returns Empty source_code
The source_code field may be empty even when metadata (path, line numbers) is correct:
- File may have been moved or deleted since graph build
- project_root may not match actual file locations
Workaround:
result = get_code_snippet(qualified_name="...")
if not result.get("source_code"):
print(f"File: {result['file_path']}, lines {result['line_start']}-{result['line_end']}")
File Children May Return Empty
get_children(identifier="path/to/file.py", identifier_type="file") may return empty:
- Not all files have their internal structure indexed
- Some files may only be indexed at the file level
Workaround:
find_nodes("filename.ClassName")
Duplicate qualified_name Prefixes
Some graphs may have duplicate entries like:
project.module.function
project.project.module.function
Best Practice: Always copy the exact qualified_name from find_nodes() results.
Tool Reference
| Tool | Input | Returns | Use When |
|---|
check_health | - | System status | Diagnosing errors |
list_repos | - | Project names | Discover available graphs |
set_project | project_name | Success | Set context for queries |
find_nodes | query | qualified_name list | Find code by name |
find_calls | qualified_name | Callers/Callees | Trace relationships |
explore_code | qualified_name | Full context | Deep analysis |
get_code_snippet | qualified_name | Source code | Get implementation |
get_children | identifier | Child nodes | Navigate structure |
find_class_hierarchy | class_qualified_name | Parents/Children | Class inheritance |
trace_dependencies | start_qualified_name | Dependency chain | Path finding, cycles |
build_graph | project_path | Job ID | Create new graph |
refresh_graph | project_name | Job ID | Update graph |
clean_graph | project_name | Success | Remove graph |
start_sync | project_name, repo_path | Status | Start real-time monitoring |
stop_sync | project_name | Status | Stop monitoring |
sync_now | project_name | Statistics | One-shot update |
get_sync_status | project_name | Status | Check sync state |
Real-time Sync Tools
start_sync - Enable File Watching
Start continuous monitoring for code changes.
start_sync(
project_name="myproject",
repo_path="/path/to/project",
skip_embeddings=False,
subdirs="backend,frontend"
)
Response Structure:
{
"success": true,
"project_name": "myproject",
"status": "started",
"message": "Sync started for 'myproject'"
}
sync_now - One-time Update
Update the graph without continuous monitoring.
sync_now(project_name="myproject")
Response Structure:
{
"success": true,
"project_name": "myproject",
"added": 5,
"modified": 3,
"deleted": 1,
"duration_ms": 1500
}
stop_sync - Disable Monitoring
stop_sync(project_name="myproject")
get_sync_status - Check Status
get_sync_status(project_name="myproject")
Response Structure:
{
"success": true,
"project_name": "myproject",
"is_watching": true,
"is_processing": false,
"pending_changes": 0,
"latest_result": {
"added": 2,
"modified": 1,
"deleted": 0
}
}
Sync Workflow
start_sync(project_name="myproject", repo_path="/path/to/project")
get_sync_status(project_name="myproject")
stop_sync(project_name="myproject")
One-shot Sync (Alternative)
sync_now(project_name="myproject")