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 |
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。