MCP Hub
Back to servers

codeTree

MCP server with 23 tools for structured code understanding via tree-sitter. 10 languages. 999 tests. One-command install.

GitHub
Stars
10
Forks
1
Updated
Mar 10, 2026
Validated
Mar 12, 2026

codetree

Tests PyPI Python License: MIT

Stop feeding entire files to your AI agent.

codetree is an MCP server that gives coding agents structured code understanding via tree-sitter — so they ask precise questions instead of reading thousands of lines. 30 tools, 10 languages, ~1 second startup. No vector DB, no embedding model, no config.

Quick Start

Prerequisite: Install uv if you don't have it (curl -LsSf https://astral.sh/uv/install.sh | sh).

Then cd into any project and run:

claude mcp add codetree -- uvx --from mcp-server-codetree codetree --root .

That's it. The . means "this project." Your agent now has structured code understanding.

Not using Claude Code? See Editor Setup for Cursor, VS Code, Windsurf, and Claude Desktop.

Before / After

Before codetree — agent reads the raw file:

$ cat calculator.py
import math
from typing import Optional

class Calculator:
    """A scientific calculator with memory."""

    def __init__(self):
        self.memory = 0
        self.history = []

    def add(self, a: float, b: float) -> float:
        """Add two numbers."""
        result = a + b
        self.history.append(('add', a, b, result))
        return result

    def divide(self, a: float, b: float) -> Optional[float]:
        """Divide a by b, returns None on zero division."""
        if b == 0:
            return None
        result = a / b
        self.history.append(('divide', a, b, result))
        return result

    # ... 200 more lines of methods ...

Tokens consumed: ~2,000+ for the full file

After codetree — agent asks for the skeleton:

class Calculator → line 4
  "A scientific calculator with memory."
  def __init__(self) (in Calculator) → line 7
  def add(self, a: float, b: float) (in Calculator) → line 11
    "Add two numbers."
  def divide(self, a: float, b: float) (in Calculator) → line 17
    "Divide a by b, returns None on zero division."
  def sqrt(self, x: float) (in Calculator) → line 24
    "Square root using math.sqrt."

Tokens consumed: ~80. That's a 25x reduction.

The agent sees every class, method, and docstring — with line numbers — without reading a single function body. When it needs the full source of divide, it calls get_symbol("calculator.py", "divide") and gets just those 6 lines.

30 Tools

Understand Structure

ToolPurpose
get_file_skeleton(file_path)Classes, functions, methods with line numbers + doc comments
get_symbol(file_path, symbol_name)Full source of a function or class
get_skeletons(file_paths)Batch skeletons for multiple files
get_symbols(symbols)Batch source for multiple symbols
get_imports(file_path)Import statements with line numbers

Navigate Relationships

ToolPurpose
find_references(symbol_name)All usages of a symbol across the repo
get_call_graph(file_path, function_name)What a function calls + what calls it
get_blast_radius(file_path, symbol_name)Transitive impact — what breaks if you change this
rank_symbols(top_n?, file_path?)PageRank importance — which symbols matter most

Analyze Quality

ToolPurpose
get_complexity(file_path, function_name)Cyclomatic complexity breakdown
find_dead_code(file_path?)Symbols defined but never referenced
detect_clones(file_path?, min_lines?)Duplicate / near-duplicate functions

Inspect & Search

ToolPurpose
search_symbols(query?, type?, parent?)Flexible symbol search with filters
get_ast(file_path, symbol_name?, max_depth?)Raw AST as S-expression
find_tests(file_path, symbol_name)Find test functions for a symbol
get_variables(file_path, function_name)Local variables and parameters

Onboarding & Graph

ToolPurpose
index_status()Graph index freshness and stats
get_repository_map(max_items?)Compact repo overview: languages, entry points, hotspots
resolve_symbol(query, kind?, path_hint?)Disambiguate short name into ranked qualified matches
search_graph(query?, kind?, file_pattern?)Graph search with degree filters and pagination

Change & Dataflow

ToolPurpose
get_change_impact(symbol_query?, diff_scope?)Impact analysis via symbol or git diff, with risk levels
get_dataflow(file_path, function_name)Intra-function variable dataflow tracing
get_taint_paths(file_path, function_name)Security taint analysis: untrusted sources to dangerous sinks
get_cross_function_taint(file_path, function_name, depth?)Cross-file taint tracing through call boundaries

Visualization & History

ToolPurpose
find_hot_paths(top_n?)High-complexity × high-call-count optimization targets
get_dependency_graph(file_path?, format?)File-level dependency graph as Mermaid or list
get_blame(file_path)Per-line git blame with author summary
get_churn(top_n?, since?)Most-changed files by commit count
get_change_coupling(file_path?, top_n?, min_commits?)Files that change together (temporal coupling)
suggest_docs(file_path?, symbol_name?)Find undocumented functions with context for doc generation

get_file_skeleton, get_skeletons, and search_symbols accept format="compact" for even fewer tokens.

Supported Languages

LanguageExtensions
Python.py
JavaScript.js, .jsx
TypeScript.ts
TSX.tsx
Go.go
Rust.rs
Java.java
C.c, .h
C++.cpp, .cc, .cxx, .hpp, .hh
Ruby.rb

Editor Setup

The --root flag tells codetree which project to analyze. Use . for the current directory, or a full path.

Claude Code

cd into your project, then:

claude mcp add codetree -- uvx --from mcp-server-codetree codetree --root .

Cursor

Add to .cursor/mcp.json in your project:

{
  "mcpServers": {
    "codetree": {
      "command": "uvx",
      "args": ["--from", "mcp-server-codetree", "codetree", "--root", "${workspaceFolder}"]
    }
  }
}

VS Code (Copilot)

Add to .vscode/mcp.json in your project:

{
  "servers": {
    "codetree": {
      "command": "uvx",
      "args": ["--from", "mcp-server-codetree", "codetree", "--root", "${workspaceFolder}"]
    }
  }
}

Windsurf

Add to ~/.codeium/windsurf/mcp_config.json:

{
  "mcpServers": {
    "codetree": {
      "command": "uvx",
      "args": ["--from", "mcp-server-codetree", "codetree", "--root", "${workspaceFolder}"]
    }
  }
}

Claude Desktop

Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "codetree": {
      "command": "uvx",
      "args": ["--from", "mcp-server-codetree", "codetree", "--root", "/path/to/your/project"]
    }
  }
}

Claude Desktop doesn't support ${workspaceFolder}, so use a full path here.

Why codetree?

AlternativeLimitationcodetree
Reading files directlyBurns tokens, no structure, no relationships25x token reduction, structured output
grep / ripgrepText only, no AST awareness, no call graphsUnderstands code structure, not just text
LSP serversHeavyweight, stateful, language-specific setupOne command, 10 languages, stateless MCP
SCIP / LSIF indexersSlow builds, complex setup, huge indexes~1s startup, JSON cache, zero config
AST-only toolsRaw trees are verbose and hard for agentsPre-structured output designed for agents

Architecture

Agent (Claude, Copilot, Cursor, etc.)
    │ MCP (stdio)
    ▼
codetree server (FastMCP)
    │
    ├── Indexer → LanguagePlugin → tree-sitter → structured results
    │   Cache (.codetree/index.json, mtime-based)
    │
    └── Graph Layer → SQLite (.codetree/graph.db)
        Persistent symbols + edges, incremental updates
        Change impact, dataflow, taint analysis
ModuleResponsibility
server.pyFastMCP server — defines all 30 tools
indexer.pyFile discovery, plugin dispatch, definition index
cache.pySkeleton cache with mtime invalidation
registry.pyMaps file extensions to language plugins
languages/One plugin per language (Python, JS, TS, Go, Rust, Java, C, C++, Ruby)
graph/store.pySQLite persistence for symbols and edges
graph/builder.pyIncremental graph builder (sha256 change detection)
graph/queries.pyRepository map, symbol resolution, change impact, hot paths, dependency graph, doc suggestions
graph/dataflow.pyIntra- and cross-function dataflow and taint analysis
graph/git_analysis.pyGit blame, churn, change coupling analysis

Adding a Language

  1. pip install tree-sitter-LANG and add to pyproject.toml
  2. Copy src/codetree/languages/_template.py to languages/yourlang.py
  3. Implement the abstract methods
  4. Register extensions in registry.py
  5. Add tests

Development

git clone https://github.com/ThinkyMiner/codeTree.git
cd codeTree
python -m venv .venv
source .venv/bin/activate
pip install -e .
pip install pytest

# Run all tests (~1070 tests, ~35s)
pytest

# Run a single test file
pytest tests/languages/test_python.py -v

Contributing

Contributions welcome! See CONTRIBUTING.md for setup instructions and guidelines.

Reviews

No reviews yet

Sign in to write a review