Muninn is a Model Context Protocol (MCP) server that indexes TypeScript repositories and exposes code-navigation tools over stdio. It stores local SQLite indexes under the Muninn project directory and lets MCP clients search symbols, inspect symbol links, and summarize file-level dependencies.
- Indexes TypeScript source files with Tree-sitter.
- Stores symbols, imports, and indexed file metadata in per-repository databases under
.muninn-indexes/. - Exposes MCP tools for architecture exploration and symbol lookup.
- Rebuilds the index on demand so results reflect the current repository state.
Muninn is an early-stage local MCP server. The current implementation is useful for exploring TypeScript repositories, but it intentionally keeps the first version small: it extracts function and class declarations, records import statements, and rebuilds indexes on demand. Broader declaration coverage, resolved import graphs, stale-index detection, pagination, and automated tests are tracked as follow-up work.
- Bun for dependency installation and script execution.
- Node.js compatible with the generated ESM output.
- A TypeScript repository to index.
bun installMuninn currently runs from a local clone. Generated dependencies and build output are intentionally ignored by Git; recreate them locally with bun install and bun run build.
Run the TypeScript source directly:
bun run devBuild the JavaScript output:
bun run buildRun the built server:
bun run startbun run build writes generated JavaScript, declarations, and source maps to dist/. That directory is ignored because it can be recreated from src.
Run the local verification command before opening a change:
bun run verifyMuninn runs as an stdio MCP server. Build the server before using it from an LLM client:
bun run buildFor Claude Desktop or another MCP client, add Muninn to the client's MCP server configuration:
{
"mcpServers": {
"muninn": {
"command": "node",
"args": [
"/home/esprazj/Documents/Projects/muninn/dist/index.js"
]
}
}
}The built config is the recommended setup for normal use. During local development, you can point the client at the dev script, which rebuilds Muninn and then starts the compiled server with Node:
{
"mcpServers": {
"muninn": {
"command": "bun",
"args": ["run", "dev"],
"cwd": "/home/esprazj/Documents/Projects/muninn"
}
}
}- Start Muninn from an MCP client.
- Call
index_repofor the repository you want to inspect, or callexplore_architecturewithreindex: truewhen you want indexing and a summary in one request. - Use
search_symbolto find definitions by partial symbol name. - Use
get_symbol_linksto inspect definitions and imports for a specific symbol.
The first indexing run creates a database for that repository under .muninn-indexes/ in the Muninn working directory. Re-run indexing after source changes when you need fresh results.
- Indexes live under Muninn's working directory instead of the target repository, so exploring a project does not write into that project.
- Reindexing currently clears and rebuilds a repository database. This is simple and predictable, but incremental indexing will scale better for large repositories.
- Import dependencies are stored from import declarations, not resolved through TypeScript module resolution yet.
- Lookup tools read the last index. Run
index_repoagain when source files change.
These are the tools registered by the server entry point in src/index.ts.
Indexes a TypeScript repository and stores the result in a per-repository database under .muninn-indexes/.
Inputs:
repo_path: absolute path to the repository root.
Output:
- Text summary with the number of indexed files and the database path.
Example input:
{
"repo_path": "/absolute/path/to/project"
}Summarizes a TypeScript repository and can optionally rebuild the index first.
Inputs:
repo_path: absolute path to the repository root.reindex: optional boolean. Set totrueto rebuild that repository's database before reading results.
Output:
- Number of indexed files.
- List of discovered symbols.
- File dependency graph based on import declarations.
Example input:
{
"repo_path": "/absolute/path/to/project",
"reindex": true
}Searches the indexed symbols table by partial name.
Inputs:
repo_path: absolute path to the indexed repository root.query: partial symbol name to search for.
Output:
- Matching symbol names, kinds, files, and line numbers.
Finds symbol definitions and import references in the index.
Inputs:
repo_path: absolute path to the indexed repository root.symbol_name: exact symbol name to inspect.
Output:
- Matching definitions from the symbols table.
- Import records whose text references the symbol name.
index_repo and explore_architecture with reindex: true call the same indexer for the target repository. The indexer:
- Opens or creates a per-repository database under
.muninn-indexes/in the Muninn working directory. - Clears existing index rows.
- Finds
**/*.tsfiles while ignoringnode_modulesanddist. - Parses each file with Tree-sitter TypeScript.
- Stores declarations and import statements in SQLite.
The database is local runtime state and is intentionally ignored by Git.
Muninn stores three tables in each repository database:
symbols: discovered declarations withname,kind,file, andline.dependencies: import statements with source file, imported path, and import text.files: indexed file paths and the timestamp for the indexing run.
The current parser records function and class declarations, plus import statements. Interfaces and variables are represented in the TypeScript types but are not fully extracted yet.
src/
index.ts MCP server entry point
indexer/
db.ts SQLite schema and repository indexing
parser.ts Tree-sitter parsing for symbols and imports
tools/
explore_architecture.ts MCP architecture/indexing tool
get_symbol_links.ts MCP symbol reference tool
index_repo.ts MCP indexing tool
search_symbol.ts MCP symbol search tool
See docs/ARCHITECTURE.md for a deeper description of module responsibilities and runtime flow.
The repository ignores local dependencies, generated build output, logs, editor settings, secrets, and SQLite runtime files. Keep bun.lock, source files, and documentation tracked. Do not commit:
.muninn.db,.muninn-indexes/, or other generated databases.node_modules.distbuild output unless the release process explicitly requires it..envfiles or credentials.
If these files were committed before .gitignore existed, remove them from the Git index while keeping local copies:
git rm --cached -r node_modules dist .muninn.db .muninn-indexesPull requests and pushes to main run the GitHub Actions verification workflow. Run the same checks locally before opening a pull request:
bun install
bun run check
bun run test
bun run buildOr run the combined verification command:
bun run verifybun run verify runs type checking, tests, and the build in the same order used for local validation. CI installs dependencies with bun install --frozen-lockfile and caches Bun's package cache from bun.lock.
Run bun run build first. dist is generated output and is not tracked.
Index the target repository first:
{
"repo_path": "/absolute/path/to/project"
}Run index_repo again, or run explore_architecture with reindex: true. The SQLite index is rebuilt from the current TypeScript files.
MIT License. See LICENSE.