Analyze C++ Codebases with Semantic Understanding
MCP server that analyzes C++ codebases with libclang so an assistant can find classes, functions, inheritance and call graphs instead of grepping.
1.0.0Add to Favorites
Why it matters
Leverage semantic analysis of C++ codebases through AST parsing to understand code structure, navigate inheritance, and track function calls. This asset enables deeper code comprehension beyond simple text search.
Outcomes
What it gets done
Search for classes, functions, and symbols within C++ codebases.
Analyze class hierarchies, inheritance, and function call graphs.
Extract detailed information about classes, methods, and function signatures.
Facilitate project-wide code exploration and dependency analysis.
Source
Get it from source
Spark does not host a copy of it.
Open sourceReports
Agent outcome reports
No reports yet
Capabilities
Tools your agent gets
Search for classes by name pattern in C++ codebase
Search for functions by name pattern in C++ codebase
Get detailed class information including methods, members, and inheritance
Get function signatures with parameter types and names
Search for symbols in specific files
Get complete inheritance hierarchy for a class
Find all classes that inherit from a base class
Find all functions that call a specific function
Overview
This is an MCP server for analyzing C++ codebases using libclang. It provides semantic understanding of code: it understands C++ syntax, inheritance hierarchies and call graphs, so Claude can navigate a codebase the way an IDE would instead of grepping through files. Use it when an assistant works in a C++ project and needs to find classes and functions, check signatures, follow inheritance or trace who calls what. Large projects take several minutes to index the first time, and results are cached afterwards.
What it does
This MCP server analyzes C++ codebases using libclang. Instead of having Claude grep through your C++ code trying to understand its structure, the server provides semantic understanding. Claude can instantly find classes, functions and their relationships without getting lost in thousands of files. It understands C++ syntax, inheritance hierarchies and call graphs, giving Claude the ability to navigate a codebase like an IDE would.
It uses libclang for accurate C++ parsing, caches the parsed AST for performance and supports incremental analysis and project-wide search. It provides detailed symbol information: function signatures with parameter types and names, class members, methods and inheritance, call graph analysis for understanding code flow, and file locations for easy navigation.
When to use - and when NOT to
Use it when an assistant works on C++ code and would otherwise fall back to grep or glob. Typical requests are "Find all classes containing 'Actor'", "Show me the Component class details", "What's the signature of BeginPlay function?", "Show me the inheritance hierarchy for GameObject", "Find all functions that call Update()" and "What functions does Render() call?".
Set the project directory first, by asking Claude to use the cpp-analyzer tool to set the project directory to your C++ project. The initial indexing can take a long time for very large projects, several minutes for codebases with thousands of files, and the server caches the results so later queries are faster.
Claude may still reach for grep or glob. Be explicit in prompts ("use the cpp-analyzer to..."), or add instructions to the project's CLAUDE.md file to prefer the cpp-analyzer for C++ symbol searches. The analyzer is much faster than grep for finding classes and functions and understanding code structure.
Capabilities
search_classes: find classes by name pattern.search_functions: find functions by name pattern.get_class_info: detailed class information with methods, members and inheritance.get_function_signature: function signatures and parameters.find_in_file: search symbols within specific files.get_class_hierarchy: the complete inheritance hierarchy for a class.get_derived_classes: all classes that inherit from a base class.find_callers: all functions that call a specific function.find_callees: all functions called by a specific function.get_call_path: call paths from one function to another.
Behavior is configured in cpp-analyzer-config.json. exclude_directories lists directories to skip while scanning, exclude_patterns lists file patterns to leave out, dependency_directories marks directories with third-party dependencies, include_dependencies decides whether files in them are analyzed, and max_file_size_mb skips larger files:
{
"exclude_directories": [".git", ".svn", "node_modules", "build", "Build"],
"exclude_patterns": ["*.generated.h", "*.generated.cpp", "*_test.cpp"],
"dependency_directories": ["vcpkg_installed", "third_party", "external"],
"include_dependencies": true,
"max_file_size_mb": 10
}
How to install
Prerequisites are Python 3.9 or higher, pip, Git and LLVM's libclang, which the setup scripts attempt to download as a portable build. Clone the repository and run the setup script for your platform: server_setup.bat on Windows or ./server_setup.sh on Linux and macOS. It creates a virtual environment, installs dependencies and fetches libclang if possible. Then run scripts/test_installation.py from the activated virtual environment to verify the components.
Add the server to Claude's configuration under mcpServers as cpp-analyzer, running python with the arguments -m mcp_server.cpp_mcp_server, with cwd and PYTHONPATH set to the absolute installation path, then restart Claude Desktop. For the OpenAI Codex CLI, create a .mcp.json in the project you open with Codex, with a stdio entry that points command at the virtual environment's Python (mcp_env/bin/python, or mcp_env\Scripts\python.exe on Windows), then restart Codex or run codex reload.
If a "libclang not found" error appears, rerun the setup script or download the LLVM release for your system manually and copy the library to lib\windows\libclang.dll, lib\macos\libclang.dylib or lib\linux\libclang.so. If Claude does not recognize the server, make sure the paths in .claude.json are absolute and restart Claude Desktop.
Source README
C++ MCP Server
An MCP (Model Context Protocol) server for analyzing C++ codebases using libclang.
Why Use This?
Instead of having Claude grep through your C++ codebase trying to understand the structure, this server provides semantic understanding of your code. Claude can instantly find classes, functions, and their relationships without getting lost in thousands of files. It understands C++ syntax, inheritance hierarchies, and call graphs - giving Claude the ability to navigate your codebase like an IDE would.
Features
Context-efficient C++ code analysis:
- search_classes - Find classes by name pattern
- search_functions - Find functions by name pattern
- get_class_info - Get detailed class information (methods, members, inheritance)
- get_function_signature - Get function signatures and parameters
- find_in_file - Search symbols within specific files
- get_class_hierarchy - Get complete inheritance hierarchy for a class
- get_derived_classes - Find all classes that inherit from a base class
- find_callers - Find all functions that call a specific function
- find_callees - Find all functions called by a specific function
- get_call_path - Find call paths from one function to another
Prerequisites
- Python 3.9 or higher
- pip (Python package manager)
- Git (for cloning the repository)
- LLVM's libclang (the setup scripts will attempt to download a portable build)
Setup
- Clone the repository:
git clone <repository-url>
cd CPlusPlus-MCP-Server
Run the setup script for your platform (this creates a virtual environment, installs dependencies, and fetches libclang if possible):
- Windows
server_setup.bat - Linux/macOS
./server_setup.sh
- Windows
Test the installation (recommended):
# Activate the virtual environment first
mcp_env\Scripts\activate
# Run the installation test
python scripts\test_installation.py
This will verify that all components are properly installed and working. The test script lives at scripts/test_installation.py.
Configuring Claude Code
To use this MCP server with Claude Code, you need to add it to your Claude configuration file.
Find and open your Claude configuration file. Common locations include:
C:\Users\<YourUsername>\.claude.json C:\Users\<YourUsername>\AppData\Roaming\Claude\.claude.json %APPDATA%\Claude\.claude.jsonThe exact location may vary depending on your Claude installation.
Add the C++ MCP server to the
mcpServerssection:{ "mcpServers": { "cpp-analyzer": { "command": "python", "args": [ "-m", "mcp_server.cpp_mcp_server" ], "cwd": "YOUR_INSTALLATION_PATH_HERE", "env": { "PYTHONPATH": "YOUR_INSTALLATION_PATH_HERE" } } } }IMPORTANT: Replace
YOUR_INSTALLATION_PATH_HEREwith the actual path where you cloned this repository.Restart Claude Desktop for the changes to take effect.
Configuring Codex CLI
To use this MCP server inside the OpenAI Codex CLI:
Make sure the virtual environment is created (see setup above).
Create a
.mcp.jsonfile in the project you open with Codex. The CLI reads this file to discover MCP servers.Add an entry that points to the Python module inside the virtual environment. Replace
YOUR_REPO_PATHwith the absolute path to this repository.{ "mcpServers": { "cpp-analyzer": { "type": "stdio", "command": "YOUR_REPO_PATH/mcp_env/bin/python", "args": [ "-m", "mcp_server.cpp_mcp_server" ], "env": { "PYTHONPATH": "YOUR_REPO_PATH" } } } }On Windows change
commandtoYOUR_REPO_PATH\\mcp_env\\Scripts\\python.exe.Restart the Codex CLI (or run
codex reload) so it picks up the new server definition.Inside Codex, use the MCP palette or prompt instructions (for example, "use the cpp-analyzer tool to set the project directory to ...") to start indexing your C++ project.
If you keep the .mcp.json file inside this repository you can also add a "cwd": "YOUR_REPO_PATH" entry so Codex launches the server from the correct directory.
Usage with Claude
Once configured, you can use the C++ analyzer in your conversations with Claude:
First, ask Claude to set your project directory using the MCP tool:
"Use the cpp-analyzer tool to set the project directory to C:\path\to\your\cpp\project"Note: The initial indexing might take a long time for very large projects (several minutes for codebases with thousands of files). The server will cache the results for faster subsequent queries.
Then you can ask questions like:
- "Find all classes containing 'Actor'"
- "Show me the Component class details"
- "What's the signature of BeginPlay function?"
- "Search for physics-related functions"
- "Show me the inheritance hierarchy for GameObject"
- "Find all functions that call Update()"
- "What functions does Render() call?"
Architecture
- Uses libclang for accurate C++ parsing
- Caches parsed AST for improved performance
- Supports incremental analysis and project-wide search
- Provides detailed symbol information including:
- Function signatures with parameter types and names
- Class members, methods, and inheritance
- Call graph analysis for understanding code flow
- File locations for easy navigation
Configuration Options
The server behavior can be configured via cpp-analyzer-config.json:
{
"exclude_directories": [".git", ".svn", "node_modules", "build", "Build"],
"exclude_patterns": ["*.generated.h", "*.generated.cpp", "*_test.cpp"],
"dependency_directories": ["vcpkg_installed", "third_party", "external"],
"include_dependencies": true,
"max_file_size_mb": 10
}
- exclude_directories: Directories to skip during project scanning
- exclude_patterns: File patterns to exclude from analysis
- dependency_directories: Directories containing third-party dependencies
- include_dependencies: Whether to analyze files in dependency directories
- max_file_size_mb: Maximum file size to analyze (larger files are skipped)
Troubleshooting
Common Issues
"libclang not found" error
- Run
server_setup.bat(Windows) or./server_setup.sh(Linux/macOS) to let the project download libclang automatically - If automatic download fails, manually download libclang:
- Go to: https://github.com/llvm/llvm-project/releases
- Download the appropriate file for your system:
- Windows:
clang+llvm-*-x86_64-pc-windows-msvc.tar.xz - macOS:
clang+llvm-*-x86_64-apple-darwin.tar.xz - Linux:
clang+llvm-*-x86_64-linux-gnu-ubuntu-*.tar.xz
- Windows:
- Extract and copy the libclang library to the appropriate location:
- Windows: Copy
bin\libclang.dlltolib\windows\libclang.dll - macOS: Copy
lib\libclang.dylibtolib\macos\libclang.dylib - Linux: Copy
lib\libclang.so.*tolib\linux\libclang.so
- Windows: Copy
- Run
Server fails to start
- Check that Python 3.9+ is installed:
python --version - Verify all dependencies are installed:
pip install -r requirements.txt - Run the installation test to identify issues:
mcp_env\Scripts\activate python -m mcp_server.test_installation
- Check that Python 3.9+ is installed:
Claude doesn't recognize the server
- Ensure the paths in
.claude.jsonare absolute paths - Restart Claude Desktop after modifying the configuration
- Ensure the paths in
Claude uses grep/glob instead of the C++ analyzer
- Be explicit in prompts: Say "use the cpp-analyzer to..." when asking about C++ code
- Add instructions to your project's
CLAUDE.mdfile telling Claude to prefer the cpp-analyzer for C++ symbol searches - The cpp-analyzer is much faster than grep for finding classes, functions, and understanding code structure
scripts/test_installation.py
#!/usr/bin/env python3
"""
Test script to verify C++ MCP Server installation
"""
import sys
import os
def test_imports():
"""Test that all required packages can be imported"""
print("Testing package imports...")
try:
import mcp
print("✓ MCP package imported successfully")
except ImportError as e:
print(f"✗ Failed to import MCP: {e}")
return False
try:
import clang.cindex
print("✓ libclang Python bindings imported successfully")
except ImportError as e:
print(f"✗ Failed to import clang: {e}")
return False
return True
def test_libclang_library():
"""Test that libclang library can be found and loaded"""
print("\nTesting libclang library...")
try:
from clang.cindex import Config
# Get the parent directory path
current_dir = os.path.dirname(os.path.abspath(__file__))
parent_dir = os.path.dirname(current_dir)
# Check for bundled libclang
libclang_paths = []
if sys.platform == "win32":
libclang_paths.append(os.path.join(parent_dir, "lib", "windows", "libclang.dll"))
elif sys.platform == "darwin":
libclang_paths.append(os.path.join(parent_dir, "lib", "macos", "libclang.dylib"))
else:
libclang_paths.extend([
os.path.join(parent_dir, "lib", "linux", "libclang.so.1"),
os.path.join(parent_dir, "lib", "linux", "libclang.so")
])
bundled_found = False
for path in libclang_paths:
if os.path.exists(path):
print(f"✓ Found bundled libclang at: {path}")
bundled_found = True
Config.set_library_file(path)
break
if not bundled_found:
print("⚠ No bundled libclang found, will use system library")
# Try to create an index (this will fail if libclang can't be loaded)
from clang.cindex import Index
index = Index.create()
print("✓ libclang library loaded successfully")
return True
except Exception as e:
print(f"✗ Failed to load libclang: {e}")
return False
def test_server_import():
"""Test that the MCP server can be imported"""
print("\nTesting MCP server import...")
try:
# We need to test this in a subprocess to avoid libclang conflicts
import subprocess
current_dir = os.path.dirname(os.path.abspath(__file__))
parent_dir = os.path.dirname(current_dir)
# Run a simple import test in a clean Python process
test_code = f"""
import sys
sys.path.insert(0, r'{parent_dir}')
from mcp_server import cpp_mcp_server
print("SUCCESS")
"""
result = subprocess.run(
[sys.executable, "-c", test_code],
capture_output=True,
text=True,
cwd=parent_dir
)
if result.returncode == 0 and "SUCCESS" in result.stdout:
print("✓ MCP server module imported successfully")
return True
else:
error_msg = result.stderr.strip() if result.stderr else "Unknown error"
print(f"✗ Failed to import MCP server: {error_msg}")
return False
except Exception as e:
print(f"✗ Failed to test MCP server import: {e}")
return False
def test_basic_parsing():
"""Test basic C++ parsing functionality"""
print("\nTesting basic C++ parsing...")
try:
from clang.cindex import Index, TranslationUnit
# Create a simple test file content
test_code = """
class TestClass {
public:
void testMethod() {}
};
"""
# Create index and parse
index = Index.create()
tu = TranslationUnit.from_source(
'test.cpp',
args=['-x', 'c++'],
unsaved_files=[('test.cpp', test_code)]
)
# Check if parsing succeeded
if tu:
print("✓ Basic C++ parsing works")
return True
else:
print("✗ Failed to parse test C++ code")
return False
except Exception as e:
print(f"✗ C++ parsing test failed: {e}")
return False
def main():
"""Run all tests"""
print("C++ MCP Server Installation Test")
print("=" * 40)
all_passed = True
# Run tests
if not test_imports():
all_passed = False
if not test_libclang_library():
all_passed = False
if not test_server_import():
all_passed = False
if not test_basic_parsing():
all_passed = False
# Summary
print("\n" + "=" * 40)
if all_passed:
print("✓ All tests passed! The C++ MCP Server is ready to use.")
print("\nNext steps:")
print("1. Configure Claude Desktop (see README)")
print("2. Start Claude and set a C++ project directory")
return 0
else:
print("✗ Some tests failed. Please check the errors above.")
print("\nCommon fixes:")
print("- Run server_setup.bat (Windows) or server_setup.sh (Linux/macOS)")
print("- Make sure you're in the virtual environment")
print("- Check that libclang exists in the lib/<platform>/ directory")
return 1
if __name__ == "__main__":
sys.exit(main())
FAQ
Common questions
Trust
How it checks out
Discussion
Questions & comments · 0
Sign In Sign in to leave a comment.