{"id":46044613,"url":"https://github.com/breca/mcp-codemap","last_synced_at":"2026-04-18T13:00:42.830Z","repository":{"id":338555170,"uuid":"1158253928","full_name":"breca/mcp-codemap","owner":"breca","description":"Automatic, contextual awareness of your codebase for LLM coding buddies. Gives coding agents a mental map of your codebase with progressive disclosure, like foldable code sections in an IDE, but for LLMs. Helps keep context window clean and bloat free!","archived":false,"fork":false,"pushed_at":"2026-02-18T07:56:24.000Z","size":808,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-01T08:25:44.688Z","etag":null,"topics":["code-search","context-engineering","entity-relation-modeling","mcp","mcp-server","model-context-protocol"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/breca.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-15T03:29:44.000Z","updated_at":"2026-02-18T07:56:15.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/breca/mcp-codemap","commit_stats":null,"previous_names":["breca/mcp-codemap"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/breca/mcp-codemap","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/breca%2Fmcp-codemap","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/breca%2Fmcp-codemap/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/breca%2Fmcp-codemap/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/breca%2Fmcp-codemap/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/breca","download_url":"https://codeload.github.com/breca/mcp-codemap/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/breca%2Fmcp-codemap/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31969772,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-18T00:39:45.007Z","status":"online","status_checked_at":"2026-04-18T02:00:07.018Z","response_time":103,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["code-search","context-engineering","entity-relation-modeling","mcp","mcp-server","model-context-protocol"],"created_at":"2026-03-01T07:10:07.444Z","updated_at":"2026-04-18T13:00:42.789Z","avatar_url":"https://github.com/breca.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# mcp-codemap\n\n[![Release](https://github.com/breca/mcp-codemap/actions/workflows/release.yml/badge.svg)](https://github.com/breca/mcp-codemap/actions/workflows/release.yml)\n[![Latest Release](https://img.shields.io/github/v/release/breca/mcp-codemap)](https://github.com/breca/mcp-codemap/releases/latest)\n\nMCP server that gives coding agents a mental map of your codebase with\nprogressive disclosure - like foldable code sections in an IDE, but for\nLLMs.\n\nThe first run parses every source file using tree-sitter and builds a\ngraph of entities (classes, functions, interfaces, etc.) and their\nrelationships (imports, extends, implements). This is stored in a local\nSQLite database (`.codemap/graph.db`) so subsequent sessions read from\nthe index instantly - no re-parsing needed.\n\nIt exposes three tools. `map` builds the big picture - every file, class,\nand function at a chosen detail level, from a quick outline to full\nsignatures with docstrings and dependency edges. `query` zooms into\na single entity for its source code, members, and relationships without\na separate file read. `reindex` keeps things fresh after edits,\nauto-detecting changes via git diff.\n\n**Supported languages:**\\\n![TypeScript](https://img.shields.io/badge/TypeScript-3178C6?logo=typescript\u0026logoColor=white)\n![JavaScript](https://img.shields.io/badge/JavaScript-F7DF1E?logo=javascript\u0026logoColor=black)\n![Python](https://img.shields.io/badge/Python-3776AB?logo=python\u0026logoColor=white)\n![Rust](https://img.shields.io/badge/Rust-000000?logo=rust\u0026logoColor=white)\n![Go](https://img.shields.io/badge/Go-00ADD8?logo=go\u0026logoColor=white)\n![Ruby](https://img.shields.io/badge/Ruby-CC342D?logo=ruby\u0026logoColor=white)\n![Java](https://img.shields.io/badge/Java-ED8B00?logo=openjdk\u0026logoColor=white)\n![C#](https://img.shields.io/badge/C%23-512BD4?logo=dotnet\u0026logoColor=white)\n![PHP](https://img.shields.io/badge/PHP-777BB4?logo=php\u0026logoColor=white)\n![Kotlin](https://img.shields.io/badge/Kotlin-7F52FF?logo=kotlin\u0026logoColor=white)\n![C](https://img.shields.io/badge/C-A8B9CC?logo=c\u0026logoColor=black)\n![C++](https://img.shields.io/badge/C%2B%2B-00599C?logo=cplusplus\u0026logoColor=white)\n![Lua](https://img.shields.io/badge/Lua-2C2D72?logo=lua\u0026logoColor=white)\n![Zig](https://img.shields.io/badge/Zig-F7A41D?logo=zig\u0026logoColor=black)\n\n## Why\n\nTypical exploration to understand a backend directory (44 files, ~420 entities):\n\n**Without codemap** - Glob/Read/Grep or an Explore subagent:\n\n| Step | Tool calls | Chars consumed |\n|---|---|---|\n| Glob to find files | 1 | ~500 |\n| Read models.py (572 lines) | 1 | ~15K |\n| Read world_service.py (628 lines) | 1 | ~18K |\n| Read ws.py (570 lines) | 1 | ~15K |\n| Read events.py (299 lines) | 1 | ~8K |\n| Read 4-5 API route files | 4-5 | ~60K |\n| Grep for cross-file imports/usage | 3-5 | ~10K |\n| **Total** | **~12-15 calls** | **~125K+** |\n\nAnd that's optimistic - an Explore subagent often does 15-25 tool calls\nacross multiple turns, each with its own overhead, and still misses things.\n\n**With codemap** - one or two calls:\n\n| Level | Tool calls | Chars consumed |\n|---|---|---|\n| `names` (quick orient) | 1 | ~6K |\n| `signatures` (working knowledge) | 1 | ~25K |\n\nThat's **5-6x fewer tokens**, **12-20x fewer tool calls**, and complete\ncoverage - every entity in every file, not just the ones the agent guessed to read.\n\n## Setup\n\n### Claude Code\n\n```bash\n# npx\nclaude mcp add codemap -- npx mcp-codemap\n\n# docker\nclaude mcp add codemap -- docker run --rm -i -v .:/project:z ghcr.io/breca/mcp-codemap\n```\n\nThe project directory is auto-detected via [MCP roots](https://modelcontextprotocol.io/specification/2025-06-18/client/roots). To set it explicitly:\n\n```bash\nnpx mcp-codemap serve -p /path/to/your/project\n```\n\nThe first run indexes the project automatically. The index is stored in\n`.codemap/graph.db` inside the project directory. Subsequent calls to `map`\nor `query` auto-detect changed files via `git diff` and refresh the index\nbefore returning results — no manual reindexing needed.\n\n### Other clients\n\nAdd the MCP server config to your client's config file:\n\n| Client | Config file |\n|---|---|\n| Claude Code | `.mcp.json` in project root |\n| Cursor | `.cursor/mcp.json` in project root |\n| Crush | `.crush.json` in project root |\n| Continue | `.continue/config.yaml` |\n| OpenCode | `opencode.json` in project root |\n\n**.mcp.json** (Claude Code, Cursor):\n```json\n{\n  \"mcpServers\": {\n    \"codemap\": {\n      \"command\": \"npx\",\n      \"args\": [\"mcp-codemap\"]\n    }\n  }\n}\n```\n```json\n{\n  \"mcpServers\": {\n    \"codemap\": {\n      \"command\": \"docker\",\n      \"args\": [\"run\", \"--rm\", \"-i\", \"-v\", \".:/project:z\", \"ghcr.io/breca/mcp-codemap\"]\n    }\n  }\n}\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eCrush / OpenCode / Continue configs\u003c/summary\u003e\n\n**.crush.json:**\n```json\n{\n  \"mcp\": {\n    \"codemap\": {\n      \"type\": \"stdio\",\n      \"command\": \"npx\",\n      \"args\": [\"mcp-codemap\"]\n    }\n  }\n}\n```\n```json\n{\n  \"mcp\": {\n    \"codemap\": {\n      \"type\": \"stdio\",\n      \"command\": \"docker\",\n      \"args\": [\"run\", \"--rm\", \"-i\", \"-v\", \".:/project:z\", \"ghcr.io/breca/mcp-codemap\"]\n    }\n  }\n}\n```\n\n**opencode.json:**\n```json\n{\n  \"mcp\": {\n    \"codemap\": {\n      \"type\": \"local\",\n      \"command\": [\"npx\", \"mcp-codemap\"]\n    }\n  }\n}\n```\n```json\n{\n  \"mcp\": {\n    \"codemap\": {\n      \"type\": \"local\",\n      \"command\": [\"docker\", \"run\", \"--rm\", \"-i\", \"-v\", \".:/project:z\", \"ghcr.io/breca/mcp-codemap\"]\n    }\n  }\n}\n```\n\n**.continue/config.yaml:**\n```yaml\nmcpServers:\n  - name: codemap\n    command: npx\n    args:\n      - mcp-codemap\n```\n```yaml\nmcpServers:\n  - name: codemap\n    command: docker\n    args:\n      - run\n      - --rm\n      - -i\n      - -v\n      - .:/project:z\n      - ghcr.io/breca/mcp-codemap\n```\n\u003c/details\u003e\n\n## Tools\n\n**Response structure:**\n\n| Element | Meaning |\n|---|---|\n| Header line | `PROJECT: \u003cfiles\u003e \\| \u003centities\u003e \\| \u003clanguages\u003e` - project summary |\n| `=== dir/ [N files, M entities] ===` | Directory section with aggregate counts |\n| `C`/`F`/`M`/`I`/`P`/`E` | Kind prefix: Class, Function, Method, Interface, Property, Enum |\n| `:10-342` | Line range (start-end) |\n| `exp` | Exported / public symbol |\n| `\u003e imports:` | Files this file imports from (resolved paths) |\n| `\u003e used-by:` | Files that import from this file |\n\n### `map` - structural overview\n\nReturns files, entities, signatures, and relationships as a compact text map.\n\n```\nmap(scope?, detail?, max_depth?)\n```\n\n**`detail`** controls output density (default: `\"signatures\"`):\n\n| Level | Content | Relative size |\n|---|---|---|\n| `\"outline\"` | Files + entity counts | ~1% |\n| `\"names\"` | Entity names, kinds, line ranges + docstrings on top-level entities | ~8% |\n| `\"signatures\"` | Full signatures, docstrings, imports/used-by | ~25% |\n| `\"full\"` | Signatures + cross-file relationships | ~40% |\n\n**`scope`** limits output to a directory or file prefix (e.g., `\"src/api\"`).\n\nTypical workflow:\n```\nmap(detail=\"names\")                          # orient on the whole project\nmap(scope=\"src/api\", detail=\"signatures\")    # drill into a module\nmap(detail=\"full\")                           # inspect dependency graph\n```\n\n#### Example: `map(scope=\"src/tools\", detail=\"names\")`\n\n```\nPROJECT: 53 files | 642 entities | csharp/go/java/javascript/kotlin/php/python/ruby/rust/typescript\nINDEXED: just now\nC=class F=function M=method I=interface P=property E=enum V=variable T=type N=namespace\n\n=== src/tools/ [5 files, 13 entities] ===\n\n  src/tools/describe-entity.ts\n    I DescribeEntityParams :6-9\n      \"Parameters for the describe-entity tool.\"\n    F describeEntity :12-27\n      \"Generate or retrieve a natural-language description for a named entity.\"\n    F formatDescribeResult :29-37\n\n  src/tools/get-context.ts\n    I GetContextParams :5-9\n      \"Parameters for the map tool: optional scope, depth limit, and detail level.\"\n    F getContext :12-18\n      \"Build and return the compact text map of the codebase.\"\n\n  src/tools/query.ts\n    I QueryParams :6-8\n      \"Parameters for the query tool: entity name or qualified name.\"\n    F queryEntity :11-104\n      \"Deep-dive on a single entity: signature, source, callers, callees, and members.\"\n\n  src/tools/reindex.ts\n    I ReindexParams :6-9\n      \"Parameters for the reindex tool: optional file paths and force flag.\"\n    F reindex :12-52\n      \"Re-index changed files; auto-detects via git diff when no paths given.\"\n\n  src/tools/update-context.ts\n    I UpdateContextParams :6-10\n      \"Parameters for the update-context tool.\"\n    F updateContext :13-55\n      \"Incrementally update the index; falls back to full rescan if requested.\"\n```\n\n#### Detail levels\n\n**`outline`** - file list with entity counts:\n\n```\nPROJECT: 53 files | 642 entities | csharp/go/java/javascript/kotlin/php/python/ruby/rust/typescript\nINDEXED: just now\nC=class F=function M=method I=interface P=property E=enum V=variable T=type N=namespace\n\n=== src/parser/languages/ [11 files, 162 entities] ===\n\n  src/parser/languages/base.ts (10 entities)\n  src/parser/languages/python.ts (12 entities)\n  src/parser/languages/typescript.ts (10 entities)\n```\n\n**`names`** - adds entity names with kind prefix, line ranges, and docstrings on top-level entities:\n\n```\n  src/parser/languages/base.ts\n    I ExtractedEntity :4-17\n      \"A code entity (class, function, variable, etc.) extracted from a parse tree.\"\n    I FileParseResult :29-33\n      \"Complete extraction output for a single source file.\"\n    I LanguageExtractor :45-50\n      \"Contract for language-specific extractors that turn parse trees into entities.\"\n    F getDocComment :53-68\n      \"Extract a JSDoc-style comment immediately preceding a node.\"\n    F getSignature :82-140\n      \"Build a human-readable signature string from a class, function, or interface node.\"\n```\n\n**`signatures`** - adds full signatures, docstrings, export markers, and dependency info:\n\n```\n  src/parser/languages/python.ts\n    C class PythonExtractor implements LanguageExtractor :11-343  exp\n      \"Extracts classes, functions, and imports from Python source files.\"\n      P language :12-12\n      P extensions :13-13\n      M extract(tree: Parser.Tree, sourceCode: string, filePath: string): FileParseResult :15-23\n      M walkNode(\n    node: Parser.SyntaxNode,\n    sourceCode: string,\n    filePath: string,\n    entities: ExtractedEntity[],\n    ...\n  ): void :25-97\n      M extractEntity(...): ExtractedEntity | null :99-171\n    \u003e imports: src/parser/languages/base.ts\n\n  src/parser/languages/typescript.ts\n    C class TypeScriptExtractor implements LanguageExtractor :15-352  exp\n      \"Extracts classes, functions, interfaces, and relationships from TypeScript/TSX files.\"\n      ...\n    \u003e imports: src/parser/languages/base.ts\n    \u003e used-by: src/parser/languages/javascript.ts\n```\n\n**`full`** - adds a cross-file relationships section:\n\n```\n=== RELATIONSHIPS ===\nsrc/parser/languages/javascript.ts -\u003e src/parser/languages/typescript.ts [extends: TypeScriptExtractor]\nsrc/parser/languages/python.ts -\u003e src/parser/languages/base.ts [implements: LanguageExtractor]\nsrc/parser/languages/typescript.ts -\u003e src/parser/languages/base.ts [implements: LanguageExtractor]\n```\n\n### `query` - deep dive on one entity\n\nReturns signature, source code, callers, callees, and members for a single\nclass, function, or method. Accepts simple or qualified names.\n\n```\nquery(entity)\n```\n\n```\nquery(entity=\"UserService\")             # find by name\nquery(entity=\"UserService.createUser\")  # find by qualified name\n```\n\nOutput includes the actual source code, so the agent doesn't need a separate\nfile read to see the implementation.\n\n#### Example output\n\n```\nclass PythonExtractor [exported]\nsrc/parser/languages/python.ts:10-342\n\nSIGNATURE: class PythonExtractor implements LanguageExtractor\n\nMEMBERS:\n  property language :11-11\n  property extensions :12-12\n  method extract(tree, sourceCode, filePath): FileParseResult :14-22\n  method walkNode(...): void :24-96\n  method extractEntity(...): ExtractedEntity | null :98-170\n  method extractDocstring(...): string | null :172-187\n\nDEPENDS ON:\n  imports ExtractedEntity (src/parser/languages/base.ts:3)\n  imports FileParseResult (src/parser/languages/base.ts:26)\n  implements LanguageExtractor (src/parser/languages/base.ts:40)\n\nUSED BY:\n  imports ScanResult (src/parser/pipeline.ts:15)\n\nSOURCE:\n  10 | export class PythonExtractor implements LanguageExtractor {\n  11 |   language = 'python';\n  12 |   extensions = ['.py'];\n  ...\n```\n\n**Response structure:**\n\n| Section | Content |\n|---|---|\n| Header | Entity kind, name, export status, file location |\n| `SIGNATURE` | Full type signature |\n| `MEMBERS` | Properties and methods with signatures and line ranges |\n| `DEPENDS ON` | Entities this one imports, extends, or implements (with source locations) |\n| `USED BY` | Entities that depend on this one |\n| `SOURCE` | Full source code with line numbers |\n\n### `reindex` - refresh after edits\n\nNote: `map` and `query` automatically refresh the index before returning\nresults, so explicit reindexing is only needed for a forced full rescan.\n\nRe-indexes changed files. Auto-detects changes via git diff when called\nwith no arguments.\n\n```\nreindex(paths?, force?)\n```\n\n```\nreindex()                               # auto-detect via git diff\nreindex(paths=[\"src/foo.ts\"])           # specific files\nreindex(force=true)                     # full rescan, ignore cache\n```\n\n#### Example output\n\n```\nGit diff update (30 changed files)\n  Processed: 18\n  Skipped (unchanged): 11\n  Errors: 1\n    src/broken.js: TypeError: Cannot read properties of undefined\n```\n\n## Configuration\n\nPlace a `config.json` in the `.codemap/` directory to override defaults:\n\n```json\n{\n  \"excludePatterns\": [\n    \"**/node_modules/**\",\n    \"**/dist/**\",\n    \"**/build/**\",\n    \"**/.git/**\",\n    \"**/vendor/**\",\n    \"**/__pycache__/**\",\n    \"**/target/**\",\n    \"**/*.min.js\",\n    \"**/*.bundle.js\",\n    \"**/*.generated.*\",\n    \"**/.codemap/**\"\n  ],\n  \"maxFileSize\": 1000000\n}\n```\n\n| Option | Type | Default | Description |\n|---|---|---|---|\n| `excludePatterns` | `string[]` | See above | Glob patterns for files/directories to skip |\n| `includePatterns` | `string[]` | `[\"**/*.{ts,tsx,js,...,c,h,cpp,hpp,...}\"]` | Glob patterns for files to include (non-git repos only) |\n| `languages` | `string[]` | `[]` (all supported) | Restrict parsing to specific languages |\n| `maxFileSize` | `number` | `1000000` | Skip files larger than this (bytes) |\n| `updateGitignore` | `boolean` | `true` | Auto-add `.codemap/` to `.gitignore` on init |\n\nIn git repos, file discovery uses `git ls-files` and respects `.gitignore`\nautomatically - `includePatterns` is only used in non-git repos as a\nfallback. The exclude patterns act as a secondary filter in both cases.\n\n## CLI\n\nThe same binary works as a standalone CLI:\n\n```bash\n# npx\nnpx mcp-codemap map [-s scope] [--detail level]     # print the map\nnpx mcp-codemap query \u003centity\u003e                      # inspect an entity\nnpx mcp-codemap reindex [paths...]                  # re-index\nnpx mcp-codemap stats                               # show project stats\nnpx mcp-codemap web [--port 3333]                   # interactive web UI\nnpx mcp-codemap install-hooks                       # git hooks for auto re-indexing\nnpx mcp-codemap uninstall-hooks                     # remove installed git hooks\n\n# docker (mount your project at /project)\ndocker run --rm -v .:/project:z ghcr.io/breca/mcp-codemap map -p /project\ndocker run --rm -v .:/project:z ghcr.io/breca/mcp-codemap stats -p /project\ndocker run --rm -v .:/project:z ghcr.io/breca/mcp-codemap query \u003centity\u003e -p /project\ndocker run --rm -v .:/project:z -p 3333:3333 ghcr.io/breca/mcp-codemap web -p /project\n```\n\n## Web UI\n\n`codemap web` launches an interactive graph explorer in your browser - a\nvisualization of every entity and relationship in the index.\n\n![Web UI](https://raw.githubusercontent.com/breca/mcp-codemap/assets/webui.png)\n\n```\ncodemap web [--port 3333]\n```\n\nFeatures:\n- **Graph canvas** - entities rendered as color-coded nodes (red = class,\n  blue = function, purple = interface, green = enum), sized by kind, with\n  edges drawn between them. Pan, zoom, and drag nodes to explore.\n- **Layout modes** - switch between five layouts via the top-right toolbar:\n  **Force** (default), **Clustered** (grouped by file), **Radial**\n  (most-connected at center), **Columns** (by directory), and\n  **Hierarchy** (dependency depth top-to-bottom). Transitions are animated.\n- **Sidebar** - searchable file tree with kind filters. Type a path prefix\n  in the exclude input to hide irrelevant directories (e.g., `tests`).\n- **Detail panel** - click any node or file to open a right-side panel\n  showing its signature, file location, docstring, members, and\n  incoming/outgoing edges. Click linked entities to navigate the graph.\n\n## Design decisions\n\nOnly path-resolved relationships (imports, extends, implements) are included\nin output. Name-based \"calls\" edges are excluded because global name lookup\nproduces too many false positives (`get`, `split`, etc. matching unrelated\nsymbols). See [CONSTRAINTS.md](CONSTRAINTS.md) for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbreca%2Fmcp-codemap","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbreca%2Fmcp-codemap","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbreca%2Fmcp-codemap/lists"}