Content
# Tool List
> C++ Semantic Graph — Let AI Precisely Understand Your C++ Codebase
Builds a semantic knowledge graph for C++ code for AI programming assistants (Claude Code, Cursor, Windsurf, etc.) through [MCP protocol](https://modelcontextprotocol.io/), exposing 9 query tools, allowing AI to directly search class definitions, check inheritance relationships, track call chains, analyze impact surfaces — no need to flip through files or grep.
## Why Do We Need It?
Common pain points for AI programming assistants to understand C++ code:
| Pain Point | Solution by cpp-semantic-graph |
|------|--------------------------|
| "Where is this class defined?" | `cpp_search_class("SocUpdate")` → Namespace + file location |
| "Who called this function?" | `cpp_get_callers("GetSocBootChain")` → All callers |
| "What if I change this header file?" | Incremental update automatically recursively includes dependencies, only re-parsing affected TUs |
| "What are the overrides for this virtual function?" | `cpp_get_overrides("PerformUpgrade", "BasePeriUpdate")` → All implementations |
| "What is the architecture of this module?" | `cpp_traverse_graph("SocUpdate")` → Multi-hop traversal of associated nodes |
## ✨ Core Features
- **9 MCP Tools**: Class search, function search, inheritance relationship, call chain (caller/callee), override, file symbols, multi-hop traversal, document search
- **Incremental Update**: Based on include dependency graph, changing a `.cpp` file updates in seconds (16× faster than full rebuild)
- **Document Fusion**: Project documentation and code are bidirectionally associated, automatically locating related code when searching documents
- **Out-of-the-Box**: One YAML configuration + `compile_commands.json` to get started, MCP Server automatically registered to AI tools
- **Project-Agnostic**: Table structure and tool definitions do not contain any project-specific hardcoding, can be migrated to any C++ project
## 🚀 Quick Start
### Prerequisites
- Python 3.10+
- libclang (matching your LLVM version)
- `compile_commands.json` (generated by CMake/Bear)
### 1. Installation
```bash
git clone https://github.com/your-org/cpp-semantic-graph.git
cd cpp-semantic-graph
# Create virtual environment
python3 -m venv .venv
source .venv/bin/activate
# Install dependencies
pip install -r requirements.txt
```
### 2. Prepare `compile_commands.json`
If your project uses CMake:
```bash
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ...
```
If not using CMake, use [Bear](https://github.com/rizsotto/Bear) to intercept compilation commands:
```bash
bear -- make
```
### 3. Write Configuration File
Create `cpp_semantic_graph.yaml` (the only file you need to modify):
```yaml
project:
name: "your_project"
compile_commands: "/path/to/your/project/compile_commands.json"
# Code scope — decide which code is considered "project code"
source_paths:
- "src"
- "include"
# Generated code paths (e.g., ARA COM src-gen, protobuf)
generated_paths:
- "src-gen"
# Paths to completely ignore
exclude_paths:
- "thirdparty"
- "build"
- "test/mock"
# libclang path (adjust according to your system)
libclang_path: "/usr/lib/llvm-18/lib/libclang.so.1"
parse_options:
skip_function_bodies: false # false to extract call relationships
max_workers: 4 # number of parallel parsing processes
```
### 4. Full Parse
```bash
python3 -m cpp_semantic_graph full-parse \
--config cpp_semantic_graph.yaml \
--db semantic_graph_full.db
```
After parsing, the database contains:
- **Nodes**: Classes, structs, functions (including signatures, namespaces, file locations)
- **Edges**: Inheritance, calls, overrides, belongs_to, type aliases, using declarations, friend relationships, etc.
- **Include Dependencies**: Include relationship graph between translation units
- **Document Associations**: Document slices ↔ code entities (optional)
### 5. Start MCP Server
```bash
# Set database path
export CPP_GRAPH_DB=/path/to/semantic_graph_full.db
# Start MCP Server (stdio transport)
python3 -m cpp_semantic_graph.mcp_server.server
```
### 6. Register to AI Tools
#### Claude Code
Edit `~/.claude.json`, add to `mcpServers`:
```json
{
"mcpServers": {
"cpp-semantic-graph": {
"type": "stdio",
"command": "python3",
"args": ["/absolute/path/to/cpp-semantic-graph/mcp_server/run_server.py"],
"env": {
"CPP_GRAPH_DB": "/absolute/path/to/semantic_graph_full.db"
}
}
}
}
```
#### Cursor
Edit `.cursor/mcp.json`:
```json
{
"mcpServers": {
"cpp-semantic-graph": {
"command": "python3",
"args": ["/absolute/path/to/cpp-semantic-graph/mcp_server/run_server.py"],
"env": {
"CPP_GRAPH_DB": "/absolute/path/to/semantic_graph_full.db"
}
}
}
}
```
#### Windsurf / Other MCP Clients
Configuration is similar, refer to each tool's MCP documentation. Core parameters:
- **command**: `python3`
- **args**: `["/path/to/mcp_server/run_server.py"]`
- **env.CPP_GRAPH_DB**: Absolute database path
> 💡 **Tip**: `CPP_GRAPH_PROJECT` environment variable can specify the project name (for MCP instructions), defaults to automatic inference from DB path if not set.
---
## 🛠️ 9 MCP Tools
| # | Tool Name | Purpose | Typical Scenario |
|---|--------|------|---------|
| 1 | `cpp_search_class` | Search class definition by name | "Where is the `SocUpdate` class defined?" |
| 2 | `cpp_search_function` | Search function definition by name | "What is the signature of `PerformUpgrade`?" |
| 3 | `cpp_get_inheritance` | Query class inheritance relationship | "What are the subclasses of `BasePeriUpdate`?" |
| 4 | `cpp_get_callers` | Query who called a specific function | "Who called `GetSocBootChain`?" |
| 5 | `cpp_get_callees` | Query what functions are called by a specific function | "What functions are called by `PerformUpgrade`?" |
| 6 | `cpp_get_overrides` | Query all overrides of a virtual function | "What are the overrides of `PerformUpgrade`?" |
| 7 | `cpp_get_file_symbols` | Query all symbols in a file | "What symbols are in `soc_update.cpp`?" |
| 8 | `cpp_traverse_graph` | Multi-hop traverse graph | "What are the impacts of modifying `SocUpdate`?" |
| 9 | `cpp_search_docs` | Search project documentation | "What is the design document for OTA upgrade flow?" |
### Tool Details
#### `cpp_search_class(name, exact=False)`
Search C++ class definition by name. Supports fuzzy matching.
```
cpp_search_class("SocUpdate")
→ ## Search result: class "SocUpdate" (1 result)
### update::SocUpdate
- File: soc_update.h:15-120
```
#### `cpp_search_function(name, class_name="")`
Search function definition by name. Can be limited to a specific class name.
```
cpp_search_function("PerformUpgrade", class_name="SocUpdate")
→ ## Search result: function "PerformUpgrade" (1 result)
### SocUpdate::PerformUpgrade [virtual, override]
- Signature: void PerformUpgrade() override
- File: soc_update.cpp:45
```
#### `cpp_get_inheritance(class_name, direction="down", depth=1)`
Query class inheritance relationship. `direction="down"` for subclasses, `"up"` for superclasses. `depth=-1` for recursive all.
```
cpp_get_inheritance("BasePeriUpdate", direction="down", depth=-1)
→ ## Subclasses of BasePeriUpdate (4 results)
- update::SocUpdate --public--> BasePeriUpdate
- update::McuUpdate --public--> BasePeriUpdate
- ...
```
#### `cpp_get_callers(function_name, class_name="")`
Query who called a specific function (impact analysis).
```
cpp_get_callers("GetSocBootChain")
→ ## Code calling "GetSocBootChain" (3 results)
### OtaManager::CheckBootChain
- File: ota_manager.cpp:128
- Call type: calls_direct
```
#### `cpp_get_callees(function_name, class_name="")`
Query what functions are called by a specific function (call chain analysis).
```
cpp_get_callees("PerformUpgrade", class_name="SocUpdate")
→ ## Code called by "PerformUpgrade" (8 results)
...
```
#### `cpp_get_overrides(function_name, class_name)`
Query all overrides of a virtual function. `class_name` is the base class name declaring the virtual function (required).
```
cpp_get_overrides("PerformUpgrade", class_name="BasePeriUpdate")
→ ## Overrides of "PerformUpgrade" (4 results)
### update::SocUpdate::PerformUpgrade
- Signature: void PerformUpgrade() override
- File: soc_update.cpp:45
- Override base class: BasePeriUpdate
```
#### `cpp_get_file_symbols(file_path)`
Query all class and function symbols in a file. `file_path` supports partial matching.
```
cpp_get_file_symbols("soc_update.h")
→ ## File symbols: soc_update.h (12 results)
### Classes/structs (2 results)
1. ### [class] update::SocUpdate
### Functions (10 results)
...
```
#### `cpp_traverse_graph(start, relation_types=None, direction="outgoing", depth=3, max_results=50)`
Multi-hop traverse graph, the most flexible query. Traverse associated nodes along specified relationship types.
Common relationship types: `inherits_public`, `inherits_protected`, `overrides`, `belongs_to`, `calls_direct`, `calls_virtual`, `calls_callback`, `doc_describes_code`, `code_refers_to_doc`
```
cpp_traverse_graph("SocUpdate", depth=2, max_results=30)
→ ## Traversal result: from "SocUpdate" (18 results)
Depth: 2, edges traversed: 22
### Associated nodes
- [class] update::SocUpdate (soc_update.h)
- [class] update::BasePeriUpdate (base_peri_update.h)
- [function] update::SocUpdate::PerformUpgrade (soc_update.cpp)
...
```
#### `cpp_search_docs(keyword, tag="", max_results=10, min_confidence=0.0)`
Search project documentation, returning document slices + associated code.
```
cpp_search_docs("upgrade", tag="architecture design")
→ ## Search result: "upgrade" (3 results)
### OTA Complete Upgrade Flow
- File: docs/OTA_flow/OTA_COMPLETE_FLOW.md
- Word count: 2450
- Tags: architecture design, OTA
Associated code:
- [class] BasePeriUpdate confidence=0.92
- [class] SocUpdate confidence=0.88
```
---
## 📖 CLI Usage
In addition to MCP tools, CLI is also provided for direct queries:
```bash
# Search class
python3 -m cpp_semantic_graph search-class "SocUpdate"
# Check inheritance
python3 -m cpp_semantic_graph inheritance "BasePeriUpdate" --direction down --depth -1
# Search function
python3 -m cpp_semantic_graph search-func "PerformUpgrade"
# Check file symbols
python3 -m cpp_semantic_graph file-symbols "soc_update.cpp"
# Check include dependencies
python3 -m cpp_semantic_graph include "base_peri_update.h" --mode all
# Database statistics
python3 -m cpp_semantic_graph stats
```
### Incremental Update
After code modification, incremental update only re-parses affected translation units:
```bash
# Based on git diff (default HEAD~1)
python3 -m cpp_semantic_graph incremental --base HEAD~1
# Manually specify files
python3 -m cpp_semantic_graph incremental --files soc_update.cpp,base_peri_update.h
# Dry run only
python3 -m cpp_semantic_graph incremental --files soc_update.cpp --dry-run
# Skip document association rebuild (faster)
python3 -m cpp_semantic_graph incremental --files soc_update.cpp --skip-associations
```
## 📐 Architecture
```
┌─────────────────────────────────────────────────┐
│ AI Tool Layer │
│ Claude Code / Cursor / Windsurf / Other MCP Clients │
└────────────────────┬────────────────────────────┘
│ MCP Protocol (stdio)
┌────────────────────▼────────────────────────────┐
│ MCP Server (9 Tools) │
│ FastMCP + Lazy Init DB Connection + Markdown Formatting │
└────────────────────┬────────────────────────────┘
│ Python API
┌────────────────────▼────────────────────────────┐
│ Query Layer (query/) │
│ GraphQuery │ CallQuery │ PolymorphismQuery │
│ TraverseQuery │ DocQuery │ IncludeQuery │
└────────────────────┬────────────────────────────┘
│
┌────────────────────▼────────────────────────────┐
│ Data Layer (db/) │
│ SQLite + 9 Indexes + CASCADE Constraints │
│ node │ edge │ include_dep │ parse_status │
└─────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────┐
│ Parser Layer (parser/) │
│ AST Visitor (libclang) │ CompileDB │ Config │
│ ChangeDetector │ ImpactAnalyzer │
└─────────────────────────────────────────────────┘
```
### Core Data Models
**Node (node table)**: Classes, structs, functions, including namespace, file location, signature, etc.
**Edge (edge table)**: Relationships between nodes, direction specified:
- `inherits`: from=child class → to=parent class
- `calls`: from=caller → to=callee
- `belongs_to`: from=function → to=owning class
- `overrides`: from=derived class function → to=base class function
**include_dep table**: Include dependencies of translation units, core basis for incremental updates
---
## 🧩 Complex Scenario Description (Templates / Aliases / Friends)
| Feature | Relationship Edge | Status | Description |
|------|--------|------|------|
| Type alias `using Alias = T` | `type_alias` | ✅ Enabled | Alias node stored + edge associated with target; target from external library may have dangling edge, alias node still retains `target_type` metadata |
| using declaration `using B::func` | `using_decl` | ✅ Enabled | Subclass function → base class function; no regular using declaration in this project source code, only 1 literal operator not extracted |
| Friend `friend class F` | `friend_of` | ✅ Enabled | friend → host class; no friend declaration in this project source code, 0 edges match expectation |
| Template instantiation | `instantiates` | ⏸️ Not enabled | libclang does not produce independent CLASS_DECL node for template specialization (specialization name only appears in CONSTRUCTOR/TYPE_REF spelling), `walk_preorder` cannot find class declaration with `<`, extraction yields no output. Extractor code reserved, to be re-enabled with LibTooling or TYPE_REF-based reconstruction |
> This part had an issue where "extractor written but not integrated into pipeline" (dead code), now AliasExtractor/FriendExtractor integrated into `SemanticExtractor.parse()`, verified with clangd.
---
## 🔄 Incremental Update Mechanism
```
1. ChangeDetector ──→ Detect file changes (git diff / manual specification)
2. ImpactAnalyzer ──→ Analyze impact scope (.h → recursive includer)
3. Delete old data ──→ Delete edges (not delete shared nodes) + include_dep + parse_status
4. Re-parse ──→ SemanticExtractor.parse() × affected TU
5. Upsert new data ──→ Node update / edge deduplication
6. Clean up residual nodes ──→ Delete functions/classes disappeared from files
7. Rebuild documentation associations ──→ content_scan (optional embedding)
```
**Deletion strategy core**: Only delete edges (from_id in this file), keep incoming edges; nodes updated with upsert. This ensures header file shared class/function nodes not deleted by mistake.
| Scenario | Affected TU | Update time |
|------|----------|---------|
| Single .cpp change | 1 TU | ~11s |
| Single .h change | Recursive includer | Depends on TU number (7 TU ~76s) |
| Idempotence (second execution) | Unchanged | Edge number stable ✅ |
> **Note**: git diff auto-detection mode (`--base HEAD~1`) may not work under Android repo tool-managed repositories (`_ensure_repo_root` finds repo top-level .git instead of sub-repo). Recommend using `--files` to manually specify changed files, more controllable.
---
## 📚 Documentation Fusion
Bidirectional association between project documentation (Markdown) and code entities, enabling AI search documentation to automatically locate relevant code.
**This project has documentation fusion configured**: 58 docs → 546 slices → 1,756 association edges (doc_describes_code + code_refers_to_doc). `cpp_search_docs` can be used directly.
### Configuration
Create `config/doc_config.yaml`:
```yaml
doc_dirs:
- "docs/"
exclude_patterns:
- "*.html"
- "*/build/*"
# Auto-tag by directory
tag_rules:
- path_pattern: "architecture/**"
tags: ["Architecture Design"]
- path_pattern: "api/**"
tags: ["Interface Specification"]
section_split:
min_level: 2 # Slice by ##
min_word_count: 20 # Merge slices with less than 20 words
# Manual precise association (not intrusive to documentation)
manual_links:
- doc: "architecture/OTA_FLOW.md"
heading: "Upgrade Flow"
code:
- "BasePeriUpdate"
- "SocUpdate"
- "PerformUpgrade"
```
### Embedding Association (Optional)
Install `sentence-transformers` for semantic similarity-based association:
```bash
pip install sentence-transformers
```
Default using `all-MiniLM-L6-v2` model. For Chinese projects, consider `bge-small-zh-v1.5` or `multilingual-e5-small`.
---
## 🧪 Verification
Run correctness verification after full parsing (cross-comparison with clangd):
```bash
python3 -m cpp_semantic_graph full-parse \
--config cpp_semantic_graph.yaml \
--validate \
--baseline validation/clangd_baseline.json
```
---
## 📋 Dependencies
### Core (Mandatory)
| Package | Version | Usage |
|----|------|------|
| `clang` | ≥18 | libclang Python binding, AST parsing |
| `PyYAML` | ≥6.0 | Configuration file parsing |
| `mcp` | ≥1.0 | MCP protocol implementation (FastMCP) |
### Documentation Fusion (Optional)
| Package | Version | Usage |
|----|------|------|
| `sentence-transformers` | ≥2.0 | Document-code semantic association |
| `torch` | ≥2.0 | sentence-transformers dependency |
### Installation
```bash
# Core dependencies
pip install clang PyYAML mcp
# Documentation fusion (optional)
pip install sentence-transformers
```
or using requirements.txt:
```bash
pip install -r requirements.txt # Core
pip install -r requirements-docs.txt # Documentation fusion (optional)
```
---
## 🗂️ Project Structure
```
cpp_semantic_graph/
├── __init__.py # Package declaration
├── __main__.py # python -m entry
├── cli.py # CLI tool (search/inheritance/incremental/...)
├── pipeline.py # Full parsing pipeline
├── incremental_updater.py # Incremental update orchestrator
│
├── parser/ # Parser layer
│ ├── ast_visitor.py # AST extractor (libclang)
│ ├── config.py # Project configuration loading
│ ├── compile_db.py # compile_commands.json parsing
│ ├── change_detector.py # File change detection (git diff)
│ ├── impact_analyzer.py # Impact scope analysis
│ ├── doc_parser.py # Documentation parser
│ ├── doc_association.py # Documentation-code association
│ ├── association_ingester.py # Association edge ingestion
│ └── models.py # Data models
│
├── query/ # Query layer
│ ├── graph_query.py # Class/function/file symbol query
│ ├── call_query.py # Call relationship query
│ ├── polymorphism_query.py # Polymorphism system query
│ ├── traverse.py # Multi-hop traversal query
│ ├── doc_query.py # Documentation fusion query
│ ├── include_query.py # Include dependency query
│ ├── architecture_query.py # Architecture overview query
│ └── fusion_query.py # Fusion query
│
├── db/ # Data layer
│ ├── graph_db.py # SQLite operations
│ ├── importer.py # JSON→SQLite import
│ ├── schema.sql # Table + index creation
│ └── relation_types.py # Relationship type enumeration
│
├── mcp_server/ # MCP Server
│ ├── server.py # FastMCP Server + 9 tools
│ └── run_server.py # Startup script
│
├── validation/ # Correctness verification
│ ├── accuracy_validator.py # Accuracy validator
│ └── clangd_baseline.py # clangd baseline
│
├── config/ # Configuration templates
│ ├── doc_config.yaml # Documentation configuration example
│ └── template_whitelist.yaml # Template whitelist
│
└── cpp_semantic_graph.yaml # Project configuration (user-written)
```
---
## ❓ FAQ
### Q: What LLVM/libclang version is required?
Match the LLVM version used for project compilation. Check method:
```bash
# Check clang version
clang --version
# Corresponding libclang path
ls /usr/lib/llvm-*/lib/libclang.so*
```
Specify `libclang_path` in the configuration file.
### Q: How to generate compile_commands.json?
- **CMake project**: `cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ...`
- **Make project**: `bear -- make`
- **Ninja project**: `bear -- ninja`
- **Bazel project**: Use [bazel-compile-commands](https://github.com/kiron1/bazel-compile-commands)
### Q: Is incremental update safe?
Yes. Deletion strategy only deletes edges (from_id in this file), not nodes. Shared header file class/function nodes updated with upsert, not deleted by mistake. Extreme cases (e.g., class renaming) suggest full rebuild.
### Q: Which AI tools are supported?
All AI tools supporting MCP protocol: Claude Code, Cursor, Windsurf, Continue, etc. MCP Server uses stdio transmission, the most widely supported.
### Q: How large is the database?
Typical C++ project (~100 translation units): about 1500 nodes / 5000 edges / 20000 include relationships, SQLite file about 5-10 MB. With documentation fusion, node and edge numbers double, DB about 5-15 MB.
### Q: What's the difference from clangd?
| | cpp-semantic-graph | clangd |
|---|---|---|
| Data storage | Offline SQLite graph | Real-time AST |
| Query scope | Cross-file, cross-module | Single file + index |
| Call chain | Complete call graph + multi-hop traversal | Single-hop reference |
| Documentation association | Supported | Not supported |
| Incremental update | Based on include dependency graph | Real-time |
| Suitable scenarios | Architecture understanding, impact analysis | Real-time editing, signature viewing |
**Complementary**: Use clangd for daily editing, cpp-semantic-graph for architecture understanding and impact analysis.
---
## 📄 License
MIT License
---
## 📋 Test Report
| Report | Description |
|------|------|
| [TEST_REPORT.md](tests/TEST_REPORT.md) | Comprehensive test report (functionality/accuracy/efficiency/bug fixes) |
| [TEST_CASES.md](tests/TEST_CASES.md) | Specific test cases (62 cases, 98.4% pass) |
| [TEST_THREE_LAYERS.md](tests/TEST_THREE_LAYERS.md) | Three-layer test (issue→tool call→code verification, 25 real issues) |
| [TEST_DOC_FUSION.md](tests/TEST_DOC_FUSION.md) | Documentation fusion special test (27 cases, 89% pass) |
| [PROJECT_EVALUATION.md](tests/PROJECT_EVALUATION.md) | Project overall evaluation (six-dimensional scoring + comparison + conclusion) |
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
No recommendations available