codemap
README.md
# codemap
Local-first code intelligence that gives AI agents and people **structural awareness** of
codebases — combining a code graph (LSP + parsers) with semantic retrieval
(local veclite, with an optional one-hop vecgrep CLI fallback or owner), exposed through a **CLI**
and an **MCP server**.
> Working on the code? Read [AGENTS.md](./AGENTS.md) first — it is the source of truth for
> conventions, architecture, and gotchas.
codemap answers questions that grep and a single LSP call can't: *who calls this function and
which tests cover it*, *what's the blast radius of changing this type*, *find auth-like code and
then show me everything that calls into it*. It precomputes the
structure once, then serves narrow, structured answers — so an agent spends a few tool calls
instead of dozens of file reads.
<!-- BENCH:START -->
> **DIRECTIONAL** — go-git/go-git @ `48a1ae05eec4`, claude-sonnet-5, N=3 (mean ± σ), api-key auth, playbook-injected, 2026-07-13. Not a controlled study; see [bench/README.md](bench/README.md).
>
> | metric (mean ± σ, per session) | baseline (Read/Grep/Glob) | with codemap | Δ |
> |---|---|---|---|
> | tool calls | 7.1 ± 6.9 | 4.0 ± 4.5 | -44% |
> | mcp tool calls | 0.0 ± 0.0 | 1.8 ± 3.4 | — |
> | sessions using codemap tools | 0/30 | 14/30 | — |
> | input tokens (incl. cache reads) | 56k ± 92k | 70k ± 75k | +25% |
> | output tokens | 2k ± 2k | 923 ± 1k | -47% |
> | wall-clock (s) | 29.9 ± 31.7 | 17.8 ± 17.8 | -40% |
> | cost (USD) | $0.063 ± $0.083 | $0.055 ± $0.059 | -13% |
> | tasks correct | 8/10 | 8/10 | +0 |
>
> One-time codemap index cost (disclosed, not per-session): **7s**. codemap is modelled as pre-indexed (the daemon keeps it fresh in real use), so the codemap arm pays query time, not index time.
<!-- BENCH:END -->
## Features
- **Structural code graph** — files, functions, types, methods, and tests as nodes; **call** edges
(name-based by default for Go, exact via `go/types` with `--precise`) and **defines** edges
(file → symbol). Test coverage is derived by walking the call graph to test nodes. The graph is
stored in pure-Go SQLite and remains queryable offline. **Go**, **Ruby**, **Lua**, **GDScript**, and **CSS/HTML** use
built-in pure-Go backends with language-specific relationships and no server needed.
With the listed language server installed, **TypeScript + JavaScript** and **Python** provide
symbols + structure and a **precise call graph** under `--precise`; one
`typescript-language-server` resolves calls across the `.ts`↔`.js` boundary. Base (non-precise)
TS/JS indexing additionally extracts name-based **import edges**, **JSX component-usage edges**
(`<Foo/>` in `.tsx`/`.jsx` — rendering *is* invocation for a function component, so React
codebases no longer read as disconnected), and **Next.js framework-wiring references** (App
Router special files, `route.ts` HTTP verbs, middleware, Pages Router), so framework-invoked
symbols stop appearing as orphans. **Vue SFCs** route
`<script>`/`<script setup>` blocks through that TS/JS server and currently provide symbols +
`defines` edges only, with source lines mapped back to the original `.vue` file. Semantic search
is language-agnostic.
- **Data and documentation** — SQL tables, views, and queries expose candidate read/write dependencies; sqlc maps generated Go methods to named queries. YAML exposes key paths and explicit task/service/job dependencies. Markdown exposes sections and local links. HTML adds local asset links and embedded styles. These relationships stay separate from calls. See [the format guide](docs/data-and-docs.md).
- **Optional semantic search** — with the local/fallback backend and embeddings enabled, node
source is embedded through the configured Ollama-compatible endpoint (`nomic-embed-text`,
768-dim by default) into [veclite](https://github.com/abdul-hamid-achik/veclite), then searched
with vector + BM25 hybrid retrieval. `--no-embed` keeps codemap's own index structure-only.
- **Impact analysis** — `impact` returns a symbol's definition sites, direct callers, the
transitive blast radius (everything affected by a change), and which tests cover those
paths (flagging untested code).
- **Built for agent harnesses** — `context <symbol>` bundles definition + callers + callees +
value-reference wiring + tests + blast radius in **one call** (no multi-round-trip stitching),
and `status` reports index
*freshness* (files changed since indexing) so an agent reindexes before trusting a stale answer.
- **Exact, reusable source selectors** — every symbol result already carries `file`, `start_line`,
`fqn`, and `kind`. Agents project those fields into a `selector` for `source`/`context`/`callers`/
`callees`/`references`/`impact`/`risk` (or paired path selectors), while people use
`--at file:line`. This picks
one same-named definition without persisting reindex-volatile database IDs.
- **Multi-project registry** — one shared store indexes all your repos; `projects` lists what's
indexed, and any query targets one project (resolved from cwd, or `--path`).
- **Annotations** — pin notes and external data (DB rows from mongosh/postgres, vidtrace/vecgrep
findings, …) to a symbol or a call path; they persist across reindex. A knowledge layer over the
graph for agent harnesses (`annotate` / `annotations`, also on MCP) and people.
- **Precise call resolution** — the fast name-based graph over-matches same-named methods
(`x.Close()` links to *every* `Close`). `codemap index --precise` attempts to resolve each call to
the one it actually invokes and records successful precise coverage per file. A query is reported
`resolved` only when every matched definition file completed that pass; partial failures remain
honestly `name`/`unresolved` instead of upgrading the whole project. It's the unified exact-resolution pass across languages: an in-process, pure-Go
`go/types` pass for **Go**, and the language server's `callHierarchy` for the **LSP languages**
(TypeScript, JavaScript, Python — which have no name-based call edges, so `--precise` is what gives
them a call graph at all). Opt-in and additive (name-based stays the default for Go); the Go pass
degrades to name-based **with a note**
when the `go` toolchain or module isn't available. For a one-off exact answer without reindexing,
`callers`/`callees` also take `--precise` (language-server `callHierarchy`). CLI + MCP.
- **Incremental** — hash-based reindex; an embedding-profile guard forces a rebuild when the
provider, model, dimensions, or distance changes instead of corrupting the vector space.
- **Two surfaces, one structural store** — a Cobra **CLI** (with `--json` for agents) and a stdio **MCP server**.
- **Graph analytics** — `map` (subsystems, directed bridges, entrypoints, hubs), `hotspots`
(hubs), `orphans` (dead-code candidates), `explore` (intent → bounded exact neighborhoods),
`traverse` (typed, heterogeneous graph walks), `task-context` (one-call, mode-scoped
orientation for a task: freshness + neighborhoods + impact + related files), and `path`
(shortest call path between two symbols).
- **Local-first by default** — the structural graph, local vectors, and default Ollama endpoint stay
on your machine. If you explicitly configure a remote Ollama-compatible endpoint, codemap sends
the source text being embedded to that endpoint; see the [configuration guide](docs/configuration.md).
- **Single core binary** — codemap is pure-Go (`CGO_ENABLED=0`), cross-compiled, and shipped via
Homebrew. Optional LSP-backed indexing and embeddings use separately installed language servers
or Ollama.
## Surfaces
codemap ships as a **CLI** and an **MCP server** (`codemap serve`). Use `--json` on CLI commands for machine output. The former Studio TUI is not shipped — see [docs/studio.md](docs/studio.md).
## Installation
### Homebrew (recommended)
```bash
brew install abdul-hamid-achik/tap/codemap
```
### Prerequisites
- **Go 1.25+** (only to build from source)
- **[Ollama](https://ollama.com)** with the embedding model:
`ollama pull nomic-embed-text` (optional — without it, indexing is structure-only)
- **[gopls](https://pkg.go.dev/golang.org/x/tools/gopls)** — optional, for one-off `callers`/`callees --precise` Go results
- Optional: **[Task](https://taskfile.dev)** for the dev workflow
**Supported language paths** — Go, Ruby, Lua, GDScript, SQL, YAML, Markdown, and CSS/SCSS/Sass/Less/HTML work with built-in pure-Go backends. TypeScript,
JavaScript, Python, and Vue require the language server listed below on `PATH`; without it, codemap
recognizes and reports those files but skips their structural extraction. Semantic retrieval is
language-agnostic once symbols are indexed. A precise call graph
(`callers`/`callees`/`impact`/`hotspots`/`path`) needs `--precise`:
| Language | How | Extensions | Call graph |
|---|---|---|---|
| **Go** | stdlib `go/parser` (pure Go, always) · `--precise` adds exact edges via in-process `go/types` | `.go` | name-based by default; exact via `--precise` |
| **TypeScript / JavaScript** | `typescript-language-server` (one server, JSX/TSX-aware, resolves across the `.ts`↔`.js` boundary) + a name-based scan for imports, JSX component usage, and Next.js framework wiring | `.ts` `.tsx` `.mts` `.cts` `.js` `.jsx` `.mjs` `.cjs` | name-based JSX/import/framework edges by default; plain function calls via `--precise` only |
| **Python** | `pyright-langserver` | `.py` `.pyw` `.pyi` | `--precise` only |
| **Ruby** | built-in pure-Go scanner (modules/classes/defs incl. `def self.x`, endless defs, `private def`; heredoc-, `=begin`-, and string-safe) | `.rb` | name-based (calls + `require`/`require_relative` imports) |
| **Lua** | built-in pure-Go scanner (`function M.foo()`/`M:foo()`/`local function` and function assignments; long-string- and comment-safe) | `.lua` | name-based (calls + `require` imports) |
| **Vue SFC** | `typescript-language-server` via `vuesrc` — `<script>`/`<script setup>` block content is extracted and routed to the TS/JS delegate; symbol lines are mapped back onto the original `.vue` file | `.vue` | symbols + `defines` edges only (no `--precise` call graph yet) |
| **CSS / SCSS / Sass / Less** | built-in pure-Go scanner — selector nodes per class/id token, SCSS/Less nesting flattened, at-rule- and interpolation-safe; `className`/`class=` references from TSX/JSX and HTML resolve to selectors as `styles` edges | `.css` `.scss` `.sass` `.less` | `styles` + import edges (no call graph — not applicable) |
| **HTML** | HTML tokenizer — static class/id references, embedded style selectors, and local asset links | `.html` | `styles` + import edges |
| **SQL / sqlc** | Offline declarations and query references; configured sqlc Go mapping | `.sql` | `reads`, `writes`, `depends_on`; no calls |
| **YAML** | Key paths and explicit Task/Compose/workflow dependencies | `.yaml` `.yml` | `depends_on`; no calls |
| **Markdown** | CommonMark sections and local links | `.md` `.markdown` | `documents`; no calls |
> Vue SFCs: a `.vue` file's `<script>`/`<script setup>` block (with `lang="ts"` routing to TypeScript, unmarked/`lang="js"` to JavaScript) is delegated to the same `typescript-language-server` connection that indexes plain `.ts`/`.js` files. Template/style blocks are not indexed. A project with only `.vue` files (no plain `.ts`/`.js`) spawns the server itself to serve the script blocks.
The language servers auto-enable when installed — run [`codemap doctor`](docs/cli.md) to see which are
detected, or `--no-lsp` to skip. The next waves are tracked honestly at **T0 recognized**:
Rust; Java/Kotlin/Scala; C/C++/CUDA; C#/VB; PHP; Dart; Swift; Elixir;
Svelte/Astro/Razor; shell; HCL/Terraform. T0 means the file is detected
and reported with a planned/missing backend, but produces no graph nodes yet. Public support
advances per relation domain (symbols, references/imports, resolved calls) only after its
fixture and accuracy gates pass; optional SCIP import is the project-level path for several waves.
See the [language support plan](docs/languages.md) for the T0–T4 admission gates,
the Rust pilot, and the project-level SCIP importer design.
### From source
```bash
git clone https://github.com/abdul-hamid-achik/codemap
cd codemap
task build # → ./bin/codemap (or: go build ./cmd/codemap)
```
### Go install
```bash
go install github.com/abdul-hamid-achik/codemap/cmd/codemap@latest
```
### Changelog
Release notes are generated per tag by GoReleaser (`.github/workflows/release.yml`) — see the
[GitHub releases page](https://github.com/abdul-hamid-achik/codemap/releases) for what changed
in each version.
## Quick start
```bash
# 1. Register and index a project
codemap init # registers the current directory
codemap index # extract graph + attempt embeddings (incremental)
codemap index --no-embed # structure only (no Ollama needed)
codemap index --precise # exact call edges (Go via go/types; TS/JS/Python via callHierarchy)
codemap index --watch # index once, then hand off to the background daemon
# Indexes your code, not your dependencies: node_modules, venv, vendor, dist, build,
# __pycache__, .git (and any dotdir) are skipped by default — configurable via `exclude`.
# 2. Check the environment and inspect config
codemap doctor
codemap config show
# 3. Orient on a symbol — everything in one call (definition, callers, callees, tests)
codemap context authenticateUser # the one-call overview (agents: codemap_context)
codemap context --at auth.go:42 # exactly one same-named definition
# 4. Navigate the call graph
codemap callers authenticateUser # who calls it (fast, name-based)
codemap callers authenticateUser --precise # exact one-off callers via the language server
codemap callers --at auth.go:42 # exact definition from the indexed graph
codemap callees authenticateUser # what it calls
codemap references authenticateUser # where it is stored/passed as a callback or handler
codemap path Handler Login # shortest call path between two symbols
codemap traverse --at auth.go:42 --direction both --edge-types calls,references --depth 2
# 5. Analyze impact and structure
codemap impact authenticateUser --depth 3 # callers + blast radius + tests
codemap map # architecture: subsystems + bridges + entrypoints + hubs
codemap hotspots --top 20 # most-referenced symbols (hubs)
codemap orphans # functions with no callers (dead-code candidates)
codemap review # diff-scoped impact + tests to run
codemap status # bounded-memory stats + warns if the index is stale
codemap status --full # include the local vector count (may use substantial memory)
# 6. Search by meaning (needs an embedded index)
codemap semantic "jwt validation middleware" --top 10
codemap semantic "jwt validation middleware" --backend vecgrep # one semantic owner
codemap explore "jwt validation middleware" --seeds 5 --edges 5 --depth 2
codemap task-context "jwt validation middleware" --mode change # freshness + contexts + impact + related files in one call
# 7. Inspect a symbol neighborhood
codemap context main.go:42 --json
```
Add `--json` to any query command for machine-readable output (for agents/scripts).
The flagship `impact` answers *what breaks if I change this, and what do I run to check?* in one call
(real output, from codemap on itself):
```
$ codemap impact BlastRadius --depth 2
Impact of BlastRadius (codemap)
defined: internal/graph/queries.go:140
direct callers: 4
blast radius: 22 (depth ≤ 2)
tests covering: 11
covering tests (run these):
graph.TestBlastRadius internal/graph/graph_test.go:377
graph.TestBlastRadiusCycleSafe internal/graph/graph_test.go:419
app.TestQueryResultsCarrySignature internal/app/app_test.go:226
app.TestImpactSurfacesAnnotations internal/app/app_test.go:394
app.TestImpactWarnsOnAmbiguousName internal/app/app_test.go:1309
app.TestServiceImpact internal/app/app_test.go:1486
app.TestImpactHeuristicTestCoverage internal/app/app_test.go:1693
app.TestImpactBlankSymbolRejected internal/app/app_test.go:1871
app.TestSecretImpact internal/app/secret_impact_test.go:79
app.TestSecretImpactOrphanKey internal/app/secret_impact_test.go:100
… (1 more — use --json for all)
affected (blast radius):
[1] app.Service.SecretImpact internal/app/secret_impact.go:50
[1] app.Service.Impact internal/app/service_impact.go:49
✓ [1] graph.TestBlastRadius internal/graph/graph_test.go:377
✓ [1] graph.TestBlastRadiusCycleSafe internal/graph/graph_test.go:419
[2] main.runImpact cmd/codemap/query.go:218
[2] main.runSecretImpact cmd/codemap/query.go:667
✓ [2] app.TestQueryResultsCarrySignature internal/app/app_test.go:226
✓ [2] app.TestImpactSurfacesAnnotations internal/app/app_test.go:394
✓ [2] app.TestImpactWarnsOnAmbiguousName internal/app/app_test.go:1309
✓ [2] app.TestServiceImpact internal/app/app_test.go:1486
✓ [2] app.TestImpactHeuristicTestCoverage internal/app/app_test.go:1693
✓ [2] app.TestImpactBlankSymbolRejected internal/app/app_test.go:1871
[2] app.Service.FileImpact internal/app/file_impact.go:39
[2] app.Service.Review internal/app/review.go:69
[2] app.Service.Risk internal/app/risk.go:37
✓ [2] app.TestSecretImpact internal/app/secret_impact_test.go:79
✓ [2] app.TestSecretImpactOrphanKey internal/app/secret_impact_test.go:100
✓ [2] app.TestSecretImpactNoValueLeak internal/app/secret_impact_test.go:114
[2] app.Service.Context internal/app/service_context.go:69
[2] mcp.Server.handleImpact internal/mcp/server.go:633
… (2 more — use --json for all, or lower --depth)
Long lists are capped for readability (the nearest blast-radius nodes and the
first covering tests, with a `… (N more)` line); `--json` always carries the
complete set.
## Commands
| Group | Command | What it does |
|---|---|---|
| Project | `init` / `index` / `status` | register, index (`--reindex`, `--no-embed`, `--no-lsp`, `--precise`), show stats + freshness + per-language precise coverage |
| Project | `doctor` | check the environment — toolchains, language servers, embeddings — with install hints |
| Project | `projects` | list all registered projects and their index sizes |
| Project | `config path` / `config show` | resolved config file path and values (`--json`) |
| Navigate | `callers` / `callees` | call-graph navigation (`--at file:line` selects one definition; `--precise` resolves on demand) |
| Navigate | `references` | where a function/method is used as a value (callbacks, handlers, registrations); partial-coverage confidence is explicit |
| Navigate | `path` | shortest call path; unique FQNs select exact endpoints and every result states call-graph confidence |
| Navigate | `symbols` / `symbol-at <file>:<line>` / `find` | outline a file, resolve a position, or find symbols by name |
| Navigate | `source` | print a symbol's source code |
| Navigate | `context` | **one call, everything about a symbol**: definition, callers, callees, value references, tests, blast radius |
| Navigate | `read-order` / `map` / `explore` / `task-context` | ranked reading list, bounded architecture overview, intent-to-structure orientation, or one-call mode-scoped task orientation (`--mode understand\|change\|debug`, alias `brief`) |
| Navigate | `traverse --at <file>:<line>` | bounded walk from one exact definition across selected edge types and directions |
| Analyze | `impact` / `dependencies` / `file-impact` / `review` | exact symbol impact (repeat `impact --at` for a partial-success frame batch; `--batch` stabilizes the one-item envelope), file dependency evidence, or diff-scoped tests |
| Analyze | `hotspots` / `orphans` | hubs / dead-code candidates |
| Analyze | `coverage` | per-file precise call-graph coverage: rollups by language/directory + bounded per-file detail |
| Analyze | `risk` | 0..1 change-risk score with factors |
| Analyze | `secret-impact` / `required-keys` | key-rotation blast radius and least-privilege key sets |
| Search | `semantic` (alias `search`) / `find` | meaning-based search, and offline name search |
| Search | `grep` | exact text search over indexed file content, joined to its enclosing symbol |
| Cache | `cache save` / `restore` / `list` / `drop` | fcheap content-addressed index snapshots |
| Cache | `cache export` / `import` | portable `tar.gz` index snapshots — no fcheap needed, for CI/team sharing |
| Branch | `branch-status` / `branch-switch` / `branch-snapshot` | per-branch index snapshots via fcheap |
| Daemon | `daemon start` / `status` / `stop` | background watcher that keeps the index fresh |
| Knowledge | `annotate` / `annotations` | pin / list notes and external data on symbols/paths; `--external-id` makes automated writes retry-safe |
| Agent harness | `agent setup` / `list` / `playbook` | wire codemap (MCP server + playbook) into an AI coding harness |
| Surfaces | `serve` | MCP server (stdio) |
All query commands accept `--json`.
## Accuracy: name-based vs precise
codemap's graph is **name-based by default** — instant, offline, and tolerant of broken code. It
resolves calls *within* a package precisely (Go), but a cross-package method call like `x.Close()`
links to *every* method named `Close`, because resolving the receiver's type needs a type-checker.
codemap is honest about this rather than hiding it: `callers`/`callees`/`impact` flag when a name
resolves to multiple definitions, and `hotspots` marks name-collision inflation.
**For precise graph coverage, reindex with `codemap index --precise`** (Go). It runs an in-process,
pure-Go `go/types` pass that replaces name-based edges in each package/file it resolves successfully.
Each query is `resolved` only when all definition files it matches have precise coverage; packages
that fail type-checking stay name-based, and an uncovered LSP-language definition stays `unresolved`.
On the codemap repo itself this collapses the `Close`/`Error`
fan-out (e.g. one `Close` method that name-matching credited with 71 callers drops to its real ~12)
and turns `hotspots` from name-collision noise into genuine hubs. Requirements and guarantees:
- Needs the `go` toolchain and a buildable module. A package that doesn't type-check keeps its
name-based edges (per-package degrade); a project with no `go`/`go.mod` falls back wholesale **with
a note** — never a hard error, and never worse than name-based.
- Purely additive and opt-in: without `--precise`, indexing is byte-for-byte the fast name-based path.
- Interface dispatch is statically undecidable, so a precise edge points at the interface method, not
the concrete implementors.
**For TypeScript/JavaScript, plain function calls still come only from `--precise`.** Base indexing
now extracts real name-based edges for TS/JS: import edges (`import`/`export … from`/`require`/
dynamic `import()`, comment-safe, with `@/` and `~/` alias and workspace-package resolution), JSX
component-usage call edges in `.tsx`/`.jsx` (`<Foo/>` — rendering is invocation; member expressions
like `<Foo.Bar/>` and `<motion.div/>` resolve to the root binding; lowercase intrinsics like
`<div>` never create edges; generics/comparisons are excluded, and commented-out or string-literal
JSX creates nothing), and Next.js framework-wiring references. Like all name-based extraction these
are *candidate* edges (same over-match contract as Go selector calls) — but a React codebase no
longer reads as disconnected. Ordinary function calls (`foo()`) still have no name-based TS/JS
edges: `index --precise` drives `typescript-language-server` `callHierarchy`; files it resolves gain
exact edges that supersede the candidates per file, while any uncovered definition remains
explicitly `unresolved`. The same
`callers`/`callees`/`impact`/`hotspots`/`path` queries then use that indexed coverage with no flag of their own.
Needs `typescript-language-server` on `PATH`.
For a one-off exact answer *without* reindexing, `callers`/`callees` also accept `--precise`
(`callHierarchy` through the language server), which degrades to the indexed graph with a note
when the server can't resolve.
Precise indexing makes the **edges** exact; a bare query such as `impact Close` still deliberately
unions every definition named `Close`. To keep a follow-up on one definition, use CLI `--at
file:line`, or pass MCP `selector:{file,start_line,fqn,kind}` projected from any symbol result.
Selectors prefer file+FQN+kind, so ordinary line shifts survive reindex; moves/renames return a
miss instead of silently selecting another node. Raw SQLite node IDs are never a public contract.
File dependency evidence is confidence-aware. Exact same-package or precise relationships are
`confirmed`; qualified name fan-out, package-scoped imports, and stale snapshots are `candidate`.
`file-impact` reports `delete_verdict:"unsafe"` only for fresh confirmed file-scoped evidence;
candidate-only or incomplete evidence remains `unknown`. `review` analyzes deleted definitions from
the last indexed snapshot when available and tells an agent to run selected tests before reindexing
prunes that historical evidence.
`orphans` finds call-graph dead ends. It follows functions wired by *value* — handlers in a
table like cobra's `RunE: runInit`, callbacks passed to a registrar — and excludes methods that
implement well-known stdlib interfaces (`error`, `fmt.Stringer`, `Unwrap`, the JSON/text
marshalers), so those aren't flagged as dead (Go). In TS/JS, JSX component usage and Next.js
framework wiring (App Router special files like `page.tsx`/`layout.tsx`, `route.ts` HTTP-verb
handlers, `middleware`, Pages Router modules) keep rendered components and framework-invoked
exports off the dead-code list — including wrapped default exports (`export default memo(Page)`,
`forwardRef(...)`, or a chain of both), whose innermost identifier is resolved as the wired
component. It still can't see callers reached via
*custom* interface dispatch or reflection, or a component passed only as a *prop*
(`<Nav Link={AuthLink}/>` — never JSX-rendered by name),
so treat its output as *candidates*, not proof.
## Use it from an agent (MCP)
codemap is a stdio MCP server. The fastest path is `codemap agent setup <harness>` — it merges the
codemap server into the harness's native config and drops a playbook that teaches agents *when* to
use the tools (no hand-editing config files):
```bash
codemap agent setup claude-code # installs the plugin (MCP server + using-codemap skill)
codemap agent setup cursor # or: codex, gemini, vscode, opencode, cline, roo, zed, aider
codemap agent setup agents-md # playbook-only fallback for any AGENTS.md-aware harness
codemap agent list # what's detected here, and whether codemap is registered
```
In **Claude Code** you can also install the plugin directly:
`/plugin marketplace add abdul-hamid-achik/codemap` then `/plugin install codemap@codemap`.
Prefer to wire it yourself? Most CLIs have a one-liner:
```bash
claude mcp add codemap -- codemap serve # Claude Code (add --scope user for all projects)
codex mcp add codemap -- codemap serve # OpenAI Codex
copilot mcp add codemap -- codemap serve # GitHub Copilot CLI
```
For any other MCP client, add a stdio server to its config (the key may be `mcpServers`, `mcp`, or
`context_servers`):
```json
{
"mcpServers": {
"codemap": { "command": "codemap", "args": ["serve"] }
}
}
```
Once connected, an agent can call `codemap_docs` to learn the tools and workflow on its own.
`CODEMAP_MCP_PROFILE=agent` selects exactly the 26-tool surface derived from the taught agent
workflow (25 named tools plus `codemap_docs`). The compatible `core` profile has the same inventory
today; the default `full` profile remains the explicit 45-tool expert/admin surface. See
[MCP tool profiles](docs/mcp.md#tool-profiles) for the measured schema cost and precedence rules.
Tools (45): `codemap_init`, `codemap_index`, `codemap_status`, `codemap_doctor`, `codemap_semantic`,
`codemap_callers`, `codemap_callees`, `codemap_references`, `codemap_impact`, `codemap_file_impact`,
`codemap_file_context`, `codemap_refactor_plan`, `codemap_dependencies`, `codemap_review`, `codemap_secret_impact`, `codemap_required_keys`,
`codemap_risk`, `codemap_hotspots`, `codemap_orphans`, `codemap_coverage`, `codemap_read_order`,
`codemap_map`, `codemap_explore`, `codemap_traverse`, `codemap_task_context`, `codemap_path`,
`codemap_related_files`, `codemap_symbols`, `codemap_symbol_at`, `codemap_find`, `codemap_grep`, `codemap_source`,
`codemap_context`, `codemap_context_batch`, `codemap_projects`, `codemap_docs`, `codemap_annotate`,
`codemap_annotations`, `codemap_unannotate`, `codemap_branch_status`, `codemap_branch_switch`,
`codemap_cache_save`, `codemap_cache_restore`, `codemap_cache_list`, `codemap_cache_drop`.
Project-scoped tools accept an optional `path` (the project directory) and return JSON;
`codemap_projects`, `codemap_docs`, and `codemap_doctor` are global/environment tools and take no
project path. The two an agent reaches for first:
**`codemap_context <symbol>`** bundles a symbol's definition, callers, callees, value references,
covering tests and blast radius in **one call**, and **`codemap_status`** reports index *freshness* —
a `stale` count of files changed/added/removed since indexing, so the agent knows to reindex before
trusting results. `codemap_callers` / `codemap_callees` accept `precise: true` for exact on-demand
language-server results (gopls for Go, `typescript-language-server` for TS/JS, and pyright for
Python); `codemap_source` returns a symbol's body; `codemap_projects` lists
what's indexed; **`codemap_docs`** returns an agent guide so a harness can learn the tool;
**`codemap_annotate` / `codemap_annotations`** pin notes and external data (DB rows, findings) to
symbols and call paths — a knowledge layer over the graph (see below). Automated writers can send
`external_id`; codemap upserts it within project + source and reports whether the row was created,
updated, or unchanged.
`codemap_map`, `codemap_traverse`, `codemap_refactor_plan`, and `codemap_task_context` are
extended surfaces registered only in the default `full` MCP profile; `codemap_explore` is part of
the taught workflow and ships in every profile. The CLI commands remain available regardless of MCP profile.
For same-named definitions, pass `selector:{file,start_line,fqn,kind}` to `codemap_source`,
`codemap_context`, `codemap_callers`, `codemap_callees`, `codemap_references`, `codemap_impact`,
`codemap_risk`, or full-profile `codemap_traverse`.
`codemap_path` accepts `from_selector` + `to_selector`. The fields are a direct projection of the
symbol objects these tools already return, so chaining adds no database-ID contract.
`codemap_context` uses the indexed graph only: it never launches language servers implicitly, and
reports `call_graph:"unresolved"` plus a precise-index action when the graph is incomplete.
`codemap_context_batch` caps aggregate source bodies at 64 KiB while retaining signatures, docs,
and locations; `source_budget` / `source_truncations` disclose any shortening. Optional component
failures appear in `partial_errors` without discarding the usable parts of the bundle.
Results carry each symbol's **signature** (e.g. `func (s *Store) Hotspots(projectID int64, limit
int) ([]Hotspot, error)`) and **docstring**, so an agent understands what callers/callees/hits are
and what they do without a follow-up file read — and same-named symbols are easy to tell apart.
The flagship is `codemap_impact` — one call returns a symbol's definition sites, callers, the
transitive blast radius, and which tests cover those paths, replacing many file reads.
## Configuration
XDG-style, with `CODEMAP_*` environment overrides and an ecosystem fallback:
```
$XDG_CONFIG_HOME/codemap/config.yaml # config (~/.config/codemap/…)
$XDG_DATA_HOME/codemap/ # graph DB, veclite, project registry
$XDG_CACHE_HOME/codemap/ # caches
```
If `~/.codemap/` already exists it is used (back-compat with vecgrep/noted). `codemap init --local`
drops a `.codemap` marker so a repo-local `codemap.yaml` is picked up from any subdirectory; the
index stays central (set `CODEMAP_DATA` to a path inside the repo for a repo-local index). Precedence
and all keys are documented in the public [configuration guide](docs/configuration.md). Override
paths with `CODEMAP_CONFIG` / `CODEMAP_DATA`; contributors should also read
[AGENTS.md](./AGENTS.md).
## How it fits the ecosystem
codemap is built on [veclite](https://github.com/abdul-hamid-achik/veclite) and shares
conventions with [vecgrep](https://github.com/abdul-hamid-achik/vecgrep) (semantic code
search) and [noted](https://github.com/abdul-hamid-achik/noted) (code notes). Set
`semantic.backend: vecgrep` to make vecgrep the sole retrieval owner while codemap keeps
structural identity, freshness, relations and impact. The boundary is a versioned one-hop CLI
contract—no shared packages or stores. In the other direction,
`codemap structural-manifest --json` gives vecgrep a source-free identity/freshness
preflight before `codemap export-symbols --json` emits the paginated
`codemap.structural-export.v1` feed used by vecgrep's
`structural_chunks: auto|off|required` modes; stale or unreadable symbol content is omitted
explicitly instead of being embedded as if it were current.
## Documentation
Product docs: **[codemap.tools](https://codemap.tools)** · [Quick start](docs/quick-start.md) ·
[CLI](docs/cli.md) · [Configuration](docs/configuration.md) · [Agent guide](docs/agents.md) ·
[MCP](docs/mcp.md) · [Languages](docs/languages.md). Contributor rules live in
[AGENTS.md](./AGENTS.md).
## License
[MIT](./LICENSE) © 2026 Abdul Hamid Achik
This server cannot be deployed
Maintenance
ActivityActive
ResponsivenessNo issues