Kodama MCP
AST-aware code exploration MCP server for AI agents, optimized for token efficiency.
README
<p align="center"> <img src="assets/banner.svg" alt="Kodama MCP" width="100%" /> </p>
Kodama MCP
木霊 — tree spirit
AST-aware code exploration MCP server for AI agents, optimized for token efficiency.
Why Kodama?
AI agents waste tokens reading entire files and guessing code structure. Kodama parses your code with tree-sitter, indexes it into SQLite, and serves precisely what agents need — nothing more.
- 3-strategy search — symbol names, docstrings, and full source searched simultaneously with Reciprocal Rank Fusion (RRF), plus import-aware re-ranking
- < 25 tokens per result — compact, structured output tuned for LLM consumption
- Monorepo-aware — automatically detects workspaces (npm, pnpm, Go, Cargo, SPM, Xcode, CocoaPods) and searches across all packages
- Zero config — auto-indexes on first query, re-indexes incrementally on changes
- 17 languages — TypeScript, Python, Swift, Go, Rust, Java, Kotlin, C, C++, C#, Objective-C, Ruby, PHP, Lua, Shell, Elixir, Scala
Installation
Kodama runs under the Bun runtime (≥ 1.2). It is not compatible with Node.js — Kodama uses bun:sqlite and explicit .ts import extensions, neither of which Node supports.
If you don't have Bun: https://bun.sh
bunx kodama-mcp # one-off run from npm
bun add -g kodama-mcp # global install
MCP client config
Use bun x (with a space) rather than bunx. MCP host launchers (Claude Desktop, Cursor, etc.) inherit a minimal PATH that often does not include ~/.bun/bin, so bunx may not resolve while bun itself usually does. If neither works, fall back to an absolute path — see Troubleshooting.
{
"mcpServers": {
"kodama": {
"command": "bun",
"args": ["x", "kodama-mcp"]
}
}
}
To use global storage mode (one DB shared across all projects):
{
"mcpServers": {
"kodama": {
"command": "bun",
"args": ["x", "kodama-mcp"],
"env": { "KODAMA_STORAGE": "global" }
}
}
}
Run from source (development)
git clone https://github.com/krazke/kodama-mcp.git
cd kodama-mcp
bun install
bun run start
Then point your MCP client at bun run /absolute/path/to/kodama-mcp/src/index.ts.
Tools
Kodama exposes 5 MCP tools. Claude Code auto-defers MCP tool schemas — they are loaded on demand from the deferred catalog rather than living in the live system prompt.
kodama_explore
Explore code structure at four detail levels.
| Parameter | Type | Required | Description |
|---|---|---|---|
path |
string |
no | Path to explore (omit for overview, directory for tree, file for outline) |
level |
"overview" | "tree" | "outline" | "detail" |
no | Detail level |
- overview (no path) — project stats: file count, symbol count, languages
- tree (directory path) — file listing with symbol counts
- outline (file path) — symbols in a file with signatures and line numbers
- detail (file path) — full source code of a file
kodama_search
Search code by name, content, or concept. Auto-classifies query intent and selects the best search strategy.
| Parameter | Type | Required | Description |
|---|---|---|---|
query |
string |
yes | Identifier name, code fragment, or natural language |
scope |
"all" | "symbols" | "source" | "docs" |
no | Restrict search to a specific index |
filters |
object |
no | language, kind, path (glob), limit (int) |
context_file |
string |
no | Current file path for import-aware ranking (see below) |
kodama_index
Index or re-index a project. Usually auto-triggered on first explore/search call.
| Parameter | Type | Required | Description |
|---|---|---|---|
path |
string |
no | Project root path |
full |
boolean |
no | Force full re-index (default: false) |
For monorepos, kodama_index auto-detects workspace packages and indexes each one. Output shows per-package breakdown:
Indexed 3 workspace packages (73 files, 161 symbols, 340ms)
packages/core: 25 files, 62 symbols
packages/server: 15 files, 28 symbols
packages/shared: 4 files, 15 symbols
kodama_get_symbol
Get full source code of one or more symbols by ID.
| Parameter | Type | Required | Description |
|---|---|---|---|
ids |
string[] |
yes | Symbol IDs from explore or search results |
context |
integer |
no | Lines of surrounding context, 0–30 (default: 0) |
kodama_relationships
Get callers, callees, inheritance, conformances, and more for a symbol.
| Parameter | Type | Required | Description |
|---|---|---|---|
symbol_id |
string |
yes | Symbol ID |
kinds |
string[] |
no | Relationship types to include (see below) |
traversal_depth |
integer |
no | 1 = direct, 2+ = transitive (default: 1) |
min_confidence |
number |
no | Minimum confidence 0.0–1.0 (default: 0.3) |
Relationship kinds: calls, called_by, inherits, inherited_by, conforms, conformed_by, implements, implemented_by, overrides, overridden_by, contains, contained_in
Example Workflow
explore (overview) → see project stats, confirm indexing
↓
search "AuthManager" → find symbols by name
↓
get_symbol [id] → read full source of a match
↓
relationships [id] → see what calls it, what it inherits
Supported Languages
Phase 1 — TypeScript (.ts, .tsx), Python (.py), Swift (.swift)
Phase 2 — Go (.go), Rust (.rs), Java (.java), Kotlin (.kt, .kts), C (.c), C++ (.cpp, .cxx, .cc, .hpp, .hxx), C# (.cs), Objective-C (.m, .mm, .h)
Phase 3 — Ruby (.rb, .rake), PHP (.php), Lua (.lua), Shell (.sh, .bash, .zsh), Elixir (.ex, .exs), Scala (.scala)
Special support: Swift protocols/extensions/actors, Objective-C categories, Python method vs function detection, Kotlin data classes.
How It Works
+--------------+ +---------------+ +-----------------+
| MCP Client |---->| Tool Router |---->| Auto-Indexer |
| (AI Agent) |<----| (5 tools) | | (on first use) |
+--------------+ +-------+-------+ +--------+--------+
| |
+-------v-------+ +---------v--------+
| SearchEngine | | tree-sitter |
| (RRF Fusion) | | (17 languages) |
+---+-------+---+ +---------+--------+
| | |
+------v--+ | +--------------v--------+
| Import | | | SQLite (WAL mode) |
| Graph | | | +----------+--------+ |
| (BFS) | +--->| |fts_symbol|fts_docs| |
+---------+ | | unicode61| porter | |
| +----------+--------+ |
| |fts_src |file_import| |
| | trigram| graph | |
| +--------+-----------+ |
+------------------------+
Search Pipeline
- Intent classification — queries are classified as
symbol_name(CamelCase, snake_case),literal(quoted strings, paths), orconcept(natural language) - 3-index query — each query runs against up to three FTS5 indexes:
fts_symbols— unicode61 tokenizer, matches symbol names and signaturesfts_docs— porter stemming, matches docstrings and summariesfts_source— trigram tokenizer, matches raw source content
- RRF fusion — results are merged with intent-tuned weights:
| Intent | Symbols | Docs | Source |
|---|---|---|---|
symbol_name |
0.7 | 0.1 | 0.2 |
concept |
0.2 | 0.7 | 0.1 |
literal |
0.05 | 0.05 | 0.9 |
Import-Aware Scoring
When context_file is provided to kodama_search, results are re-ranked based on import graph proximity. Files that are directly imported by (or import) the context file get boosted; distant files get dampened.
The boost uses a decay function: boost(d) = max(0.3, 0.7^d) where d is the shortest path distance in the import graph:
| Distance | Boost | Meaning |
|---|---|---|
| 0 | 1.0 | Same file |
| 1 | 0.7 | Direct import/importer |
| 2 | 0.49 | Two hops away |
| 3 | 0.343 | Three hops |
| 4+ | 0.3 | Floor — prevents burying relevant distant results |
Import extraction is currently supported for TypeScript and Python. Other languages work normally — they just don't contribute import edges, so no boost is applied.
Monorepo / Workspace Support
Kodama automatically detects and indexes monorepo workspace packages. When you index a monorepo root, all packages are discovered and indexed as separate projects grouped by their shared git root.
Supported workspace types:
| Ecosystem | Detection File | What's Parsed |
|---|---|---|
| npm/yarn | package.json |
workspaces field |
| pnpm | pnpm-workspace.yaml |
packages: globs |
| Go | go.work |
use directives |
| Cargo | Cargo.toml |
[workspace] members |
| Swift PM | Package.swift |
.package(path:) deps |
| Xcode | *.xcworkspace |
group: file refs |
| CocoaPods | Podfile |
:path => local pods |
All search and explore commands automatically span all packages in the workspace. Standalone (non-workspace) projects work identically to before.
Known limitations:
- Import graph stays per-project (cross-project edges planned for Phase 6b)
- No TOML/YAML/XML parser deps — all manifest parsing uses regex/line-by-line
Incremental Indexing
Kodama avoids full re-indexing when possible:
- Git diff (preferred) — compares HEAD SHAs to detect added/modified/deleted files
- Hash diff (fallback for non-git repos) — SHA-256 comparison of stored vs current file hashes
- Full index (cold start) — only when no prior index exists
Design Notes
- Test files show 0 symbols by design. Test framework calls (
describe,test,it) arecall_expressionAST nodes, not declarations — they aren't extracted as indexable symbols. Test files are still indexed for source search: usekodama_searchwithscope: "source"to find code inside test bodies. - Unresolved cross-package relationships show no line number. When a callee is external or unresolved (not found in any indexed project), its target cannot be looked up — the relationship is shown by name only, without a file path or line reference.
- Module-level variable declarations (e.g., Zod schemas, arrow-function components, exported constants) are not extracted as symbols. These are
variable_declarationAST nodes — only named declarations (functions, classes, types, interfaces) are indexed. Usekodama_searchwithscope: "source"to find variable-based definitions.
File Watching
A file watcher monitors source files with 300ms debounce, triggering incremental re-index on changes. Standard directories (node_modules, .git, build, dist, __pycache__, target, etc.) are excluded.
Performance
| Metric | Target |
|---|---|
| Cold start | < 100ms |
| Symbol lookup by ID | < 1ms |
| FTS search (1K files) | < 50ms |
| FTS search (40K files) | < 200ms |
| Index 10K files (full) | < 30s |
| Incremental re-index (10 files) | < 1s |
| Token overhead per result | < 25 tokens |
Real-world example: A 775-file iOS project — 10,499 symbols indexed in ~1s.
Benchmarked on Apple M4 Max, 64 GB RAM, SSD.
Run benchmarks on your machine:
bun run benchmark # Default benchmarks
bun run benchmark -- --project . # Benchmark against current directory
bun run benchmark:scale # Large-scale benchmarks
Security
Kodama includes FileGuard, a security layer that protects against unsafe file access:
- Binary detection — 75 blocked extensions (executables, images, archives, fonts, compiled bytecode, etc.) plus content-based binary detection
- Symlink escape prevention — all symlinks are resolved and validated to stay within the project root
- Secret file filtering —
.envfiles, SSH keys, credentials, certificates, and other sensitive files are excluded from indexing - File size limit — files over 1MB are skipped
- Path validation — all
detail-level reads are validated against the security policy
Storage
Kodama persists indexes to disk so subsequent sessions skip re-indexing. Three storage modes are available:
| Mode | DB Location | Use Case |
|---|---|---|
project (default) |
{projectRoot}/.kodama/index.db |
Per-project isolation, survives across sessions |
global |
~/.kodama/index.db |
Single DB for all projects, minimal footprint |
memory |
:memory: |
Testing, throwaway sessions |
Configuration
| Variable | Default | Description |
|---|---|---|
KODAMA_STORAGE |
project |
Storage mode: memory, global, or project |
KODAMA_DB_PATH |
— | Explicit DB path (overrides KODAMA_STORAGE) |
Add .kodama/ to your project's .gitignore:
.kodama/
Schema versioning
Kodama tracks a schema version in the database. On startup, if the stored version doesn't match the current code, all tables are dropped and a full re-index runs automatically. No manual migration is needed.
Stale index warning
If the index hasn't been updated in over 24 hours, kodama_explore and kodama_search prepend a warning to their output. Run kodama_index to refresh.
MCP Client Setup
Claude Desktop
Add to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"kodama": {
"command": "bun",
"args": ["x", "kodama-mcp"]
}
}
}
Claude Code
Add to .mcp.json in your project root:
{
"mcpServers": {
"kodama": {
"command": "bun",
"args": ["x", "kodama-mcp"]
}
}
}
Running from a local clone
If you cloned the repo and want to point your client at the source directly (instead of the published npm package), use:
{
"mcpServers": {
"kodama": {
"command": "bun",
"args": ["run", "/absolute/path/to/kodama-mcp/src/index.ts"]
}
}
}
Optionally add to your project's CLAUDE.md to improve tool routing:
## Code Exploration
Use kodama tools (kodama_explore, kodama_search, kodama_get_symbol) for code discovery,
symbol lookup, and understanding code structure. Use built-in Read/Grep for reading
specific known files.
Troubleshooting
"Failed to spawn process: No such file or directory"
This usually means the MCP host can't find the bun binary. MCP clients don't inherit your full shell PATH — they typically only see /usr/local/bin, /opt/homebrew/bin, /usr/bin, /bin, /usr/sbin, /sbin.
If you installed Bun via the official installer, it lives at ~/.bun/bin/bun, which isn't in those paths.
Fix: use the absolute path to bun in your config.
Find your bun path:
which bun
Then update your MCP config (npm install path):
{
"mcpServers": {
"kodama": {
"command": "/Users/yourname/.bun/bin/bun",
"args": ["x", "kodama-mcp"]
}
}
}
Or for a local clone:
{
"mcpServers": {
"kodama": {
"command": "/Users/yourname/.bun/bin/bun",
"args": ["run", "/absolute/path/to/kodama-mcp/src/index.ts"]
}
}
}
Alternative: symlink bun into a standard PATH directory:
sudo ln -s $(which bun) /usr/local/bin/bun
Server starts then immediately disconnects
Check that:
- Your Bun version is ≥ 1.2 (
bun --version) - For npm install: the package resolved correctly (
bunx kodama-mcp --helpfrom a terminal should not error) - For local clone: you ran
bun installinsidekodama-mcp/, and the path inargspoints to the actualsrc/index.tsfile (not a directory)
Development
bun run start # Start MCP server (stdio transport)
bun run dev # Start with --watch
bun test # Run tests (296 tests across 27 files)
bun run lint # Biome check
bun run lint:fix # Biome auto-fix
bun run typecheck # TypeScript type check
bun run benchmark # Performance benchmarks
bun run benchmark:scale # Large-scale benchmarks
Tech Stack
| Component | Technology |
|---|---|
| Runtime | Bun (>=1.2) |
| Language | TypeScript (strict mode) |
| Storage | SQLite via bun:sqlite (WAL mode) |
| Parser | web-tree-sitter (WASM) |
| Search | 3x FTS5 indexes + RRF fusion |
| Protocol | MCP SDK (@modelcontextprotocol/sdk) |
| Validation | Zod |
| Linter | Biome |
| Tests | bun:test |
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.