agentmap
MCP serverAI & modelsagentmap gives your AI an accurate map of a TypeScript or JavaScript codebase. It indexes imports, symbols, and call relationships so your AI can understand how the code fits together instead of guessing. Once added, your AI can look up how parts of a project connect before planning edits or explaining code.
Unavailable. This server has no hosted endpoint yet, so ahel can't serve it.
Add it and point it at a TypeScript or JavaScript repository. Your AI can then query the code map whenever it needs to navigate the project or plan a change.
What your AI can do with it
- Map imports across a TypeScript or JavaScript project
- Find where functions and classes are defined
- Trace which functions call which
- Look up a symbol and see everywhere it is referenced
- Answer questions about code structure from source-accurate data
From the project's README
As published by raymondchins/agentmap in README.md.
agentmap
Your agent burns most of its context just finding code. This gives it the answer in one line.
npx @raymondchins/agentmap --relates lib/db/schema.ts
relates: lib/db/schema.ts (pr 0.073744)
dependents (21): lib/types.ts, lib/utils.ts, lib/db/queries.ts,
components/chat/message.tsx, app/(chat)/api/chat/route.ts, …
Every file on that list really imports it. grep gets 40% of them wrong.
💸 What it saves
Token cost of the hidden first step in every agent task — find the relevant code —
on a real 154-file Next.js app (vercel/ai-chatbot, sha 2becdb4):
| The agent needs to know… | Reading files | agentmap | Saved |
|---|---|---|---|
| Does a helper for this already exist? | 14,740 | 19 | 99.9% |
| Load the whole repo into context | 150,281 | 1,127 | 99.3% |
| What breaks if I change this file? | 81,038 | 616 | 99.2% |
| Where is this symbol defined? | 1,950 | 20 | 99% |
| What files make up this feature? | 6,121 | 1,025 | 83.3% |
| Give me a repo overview | 3,065 | 1,127 | 63.2% |
| What does this one file import? | 583 | 517 | 11.3% |
| All 7 combined | 257,778 | 4,451 | 98.3% |
Holds on zod too (367 files, 99.2%) and
taxonomy (125 files, 96.0%).
Captured output, pinned shas → benchmark/RESULTS.md
🎯 …and it's still right
Fewer tokens is worthless if they're the wrong ones. Separate eval, ground truth derived live from real repos:
| agentmap | git grep | |
|---|---|---|
| What depends on this file? | 100% precision | 59.9% precision |
| Where is this defined? (top-1) | 100% | 32% |
| Where is this defined? (top-3) | 100% | 80% |
| Tokens to find a definition | 1.9× fewer | — |
n=42 dependents / n=75 definitions across zod, zustand, hono. Re-run: npm run eval · method → EVAL.md
⚡ The five commands
| You want | Run | Saves |
|---|---|---|
| "Do we already have this?" | agentmap --find formatCurrency | 99.9% |
| "What breaks if I touch this?" | agentmap --relates lib/auth.ts | 99.2% |
| "Where is this defined?" | agentmap --find ChatMessage | 99% |
| "Give me the repo, cheap" | agentmap --map --tokens 2000 | 99.3% |
| Don't want to pick? | agentmap --any <anything> | — |
--any routes it for you: file → symbol → feature → live content search.
Cold build ~1.2s. Cached query ~0.1s. No server, no vector DB, no API key.
🔌 Setup
npx @raymondchins/agentmap --install-hooks # rebuild on commit + steer the agent to the map
npx @raymondchins/agentmap --install-skill # Claude Code · Cursor · Codex · Gemini · OpenCode · Copilot
Most repo-map tools stop at building the map. These two hooks are why it stays useful: the map rebuilds itself after every commit, and the agent gets nudged to the map the moment it reaches for a dependency-shaped grep. Claude Code users can get both from the plugin.
100% local. Zero network calls, zero telemetry — not one
fetch/httpin the source. ⚠️ Install the scoped name; unscopednpx agentmapis someone else's package.
First run caches to .claude/agentmap/map.json (--install-hooks gitignores it). Later runs
serve that cache only on a clean tree at an unchanged HEAD — with uncommitted
.ts/.tsx/.js/… edits it silently rebuilds, so you never query a stale snapshot.
$ npx @raymondchins/agentmap
agentmap: 154 files | 4 features | top hub: lib/utils.ts (deg 52, pr 0.105171)
From a checkout, every command also works as node agentmap.mjs ….
🧠 Why the answers are right
Built on ts-morph — the real TypeScript compiler, not text matching or tree-sitter
guessing. It resolves tsconfig path aliases, vite/webpack aliases, #imports subpaths,
and monorepo workspaces. Where grep sees a string, agentmap sees the resolved module.
That's also why barrels don't fool it: export * from "./x" looks identical to a real
definition to a text search, so your agent edits the re-export and changes nothing. agentmap
follows the chain and names the file that actually declares it.
- The win scales with the work. The 63% and 11% rows are the floor. A trivial
single-file lookup can cost more than
cat+grep— taxonomy's file-import task hit −313%, and it stays in the table. - The 98.3% headline is carried by its two biggest rows — repo dump (150,281 → 1,127) and blast radius (81,038 → 616). Drop the repo dump and it's 96.9%; drop both and it's 89.8% here, 93.7% pooled across all three repos, and 73.1% on the smallest one. All of those are real — they answer different questions. The headline is the common worst case: an agent dumping the repo at session start.
--relatesreturns the full blast radius, so it costs more than a baregrep -lfile list. That's why the same command reads as 99.2% saved in the benchmark and more expensive in the eval: the benchmark's baseline is an agent thatcats all 65 dependent files, the eval's is a file list nobody reads. Against the list, agentmap trades tokens for precision — 100% vs 59.9%, so ~4 in 10 files on the grep list don't belong. Complete-and-correct over short-and-wrong, but it is a trade → EVAL.md.- Numbers are context-token volume, not answer quality or wall-clock.
- Token counts are estimates (
chars / 4), applied identically to both sides. - TypeScript/JavaScript only (+ Vue SFC) — see Scope & limitations.
Why it's different
Many "repo context" tools are a photocopy: they dump your repository (or a slice of it) into the prompt once and walk away — the copy goes stale the moment you edit a file, and nothing makes the agent actually read it. agentmap is queryable and ranked instead: the agent interrogates it flag-by-flag rather than swallowing a dump.
It also reports an edgeCoverage map-health signal and warns loudly when a repo's imports
mostly don't resolve, so a broken map is never quietly framed as success.
The self-refreshing side — a post-commit rebuild plus a PreToolUse hook that steers the agent
to the map before it serial-greps — is genuinely useful, but it isn't unique: CodeGraph
(colbymchenry/codegraph, ~62k★ (2026-07-26)) ships a native
OS-event file watcher (FSEvents/inotify) with debounced auto-sync and an installer that
auto-configures eight agent CLIs. agentmap's honest edge over the multi-language graph tools is
narrower and sharper: TS/JS resolution the others approximate, with a published accuracy eval.
| agentmap | Aider repo map | RepoMapper | Repomix | code2prompt | |
|---|---|---|---|---|---|
| Ranking algorithm | Personalized PageRank (file + symbol graphs) | PageRank (graph ranking) | Importance heuristics | None (file order) | None (file order) |
| Languages | TS/JS + Vue SFC (via ts-morph) | Many (tree-sitter) | Many (tree-sitter) | Language-agnostic (text) | Language-agnostic (text) |
| Token-budget output | Yes — --map [--tokens N] ranked digest | Yes (built into Aider's context) | Partial | Yes (size caps) | Yes (templates/caps) |
| TS/JS resolution depth | Compiler-grade — tsconfig paths + vite/webpack alias + #imports + workspaces (ts-morph) | Basename/regex heuristics | Basename/regex heuristics | N/A (text) | N/A (text) |
| Retrieval-accuracy eval | Yes — published EVAL.md vs live ground truth | No | No | No | No |
| Agent-loop wiring | Yes — post-commit auto-refresh + PreToolUse hook | In-process (Aider only) | No | MCP server (no auto-refresh, no nudge) | No |
| Dependencies | ts-morph only | Python + tree-sitter stack | Python + tree-sitter | Node | Rust binary |
| Install | npx @raymondchins/agentmap | pip install aider-chat | pip install | npx/global | cargo/binary |
Comparison as of 2026-07-27, from each project's own docs. These are moving targets — if a cell is out of date, that's a bug: open an issue.
What that table is not claiming: agentmap is TS/JS-only (the others are multi-language),
and it's a file-level import graph, not a full call-site/reference resolver (see
Scope & limitations). The differentiators are narrow and honest:
(1) compiler-grade TS/JS resolution (aliases, vite/webpack, #imports, workspaces) with a
published accuracy eval, and (2) the --any router. The agent-loop wiring is real and
convenient but not unique — CodeGraph and others
auto-sync and auto-configure agent CLIs too; we don't claim it as a moat.
The agent loop (staying current, staying used)
A common failure of repo-map tools: they build a beautiful map, and then the agent forgets it exists and greps anyway. A map the agent doesn't open is just dead weight.
agentmap closes that loop. Two hooks (in ./hooks/) do the work: the map
refreshes itself after every commit, and the agent gets nudged to query it before it
serial-greps. You wire it once — then it stays current on its own, and stays used.
This wiring is table stakes, not the moat — CodeGraph and other tools also auto-sync (via native OS file watchers) and auto-configure agent CLIs. agentmap ships it because it's genuinely useful; the actual point of agentmap is the compiler-grade TS/JS accuracy the map is built on.
1. Auto-refresh on commit
hooks/post-commit rebuilds .claude/agentmap/map.json after each
commit, detached + silenced so it never slows the commit. It skips during
rebase/merge/cherry-pick and no-ops if Node is missing.
The hooks ship inside the npm package. The simplest setup:
npx @raymondchins/agentmap --install-hooks
This copies hooks/post-commit into .git/hooks/, sets it executable, ensures
.claude/agentmap/ is in .gitignore, and auto-wires the PreToolUse nudge
hook into .claude/settings.json (merge-safe + idempotent) so map enforcement is
on by default — no manual paste. Manual alternative for just the post-commit hook:
# from your repo root
cp hooks/post-commit .git/hooks/post-commit
chmod +x .git/hooks/post-commit
The hook resolves the builder to the installed package — node_modules/.bin/agentmap,
a PATH agentmap binary verified to be @raymondchins/agentmap, then
npx @raymondchins/agentmap. It never runs a repo-local ./agentmap.mjs unless you opt in
with AGENTMAP_HOOK_ALLOW_LOCAL=1 (for developing agentmap itself), so an
attacker-planted agentmap.mjs can't execute on your next commit.
2. Force the agent to use it — PreToolUse hook
hooks/agentmap-nudge.mjs is a non-blocking hook for
Claude Code that covers both the Grep tool and raw Bash text-searchers
(grep/rg/egrep/fgrep/ag/ack). When either looks like a dependency /
who-imports / component-usage / reuse / where-is-symbol search, it injects a reminder
steering the agent to agentmap --any first. It never denies the call, and stays silent
for raw-string / Tailwind-class / lowercase-HTML-tag sweeps and for pipe-filtered commands
like ps aux | grep node — so it's high-signal, not nagging.
Fires on: import/require/export/from '...' patterns, JSX component tags
(<Hero, <ProviderCard), explicit intent words (where is, who imports, reuse,
existing component), and — in both the Grep tool and the Bash branch — bare multi-hump
PascalCase identifiers (ProviderCard, TopProviders) that almost always mean "where is
this symbol / who uses it". The Bash branch additionally only fires when the searcher is the primary command (at the start,
or after ;/&&); piped log-filters stay silent.
All four nudge/gate variants (this one, Codex, Gemini, OpenCode) also self-gate on
project presence: since they ship at user/global scope too (plugin bundle, ~/.gemini,
~/.codex, ~/.config/opencode), they walk up from the tool call's cwd to the
filesystem root looking for node_modules/@raymondchins/agentmap or a built
.claude/agentmap/map.json before doing anything else, so a repo with no agentmap stays
silent instead of nagging (or, for Codex, denying a grep it has no business denying).
--install-hooks writes both matchers into .claude/settings.json for you (merge-safe —
preserves existing settings, won't duplicate on re-run). The single hook file dispatches
internally on tool_name. For reference, or to wire it by hand:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Grep",
"hooks": [{ "type": "command", "command": "node ./hooks/agentmap-nudge.mjs" }]
},
{
"matcher": "Bash",
"hooks": [{ "type": "command", "command": "node ./hooks/agentmap-nudge.mjs" }]
}
]
}
}
That's the "forced to use it" in the tagline: the map stays current on its own, and the agent is steered to it the moment it reaches for a dependency-shaped grep or Bash search.
3. Agent skills (Cursor, Claude Code, Codex, OpenCode, Gemini, Antigravity, Copilot)
npx @raymondchins/agentmap --install-skill
…or grab just the skill (no agentmap flags) via the skills
CLI — agentmap ships the skills/agentmap/SKILL.md layout it expects:
npx skills add raymondchins/agentmap
--install-skill copies packaged SKILL.md files and a Cursor rule (.cursor/rules/agentmap.mdc,
alwaysApply: true) into the current repo or global agent directories. Paths follow
each platform's official skill-directory conventions. Options:
agentmap --install-skill --platform cursor # Cursor rule + .cursor/hooks.json shell gate (project)
agentmap --install-skill --platform claude # .claude/skills/agentmap/SKILL.md
agentmap --install-skill --platform codex # .codex/skills/ (project) or ~/.codex/skills/ (global)
agentmap --install-skill --platform opencode # .opencode/skills/ (project) or ~/.config/opencode/skills/ (global)
agentmap --install-skill --platform gemini # .gemini/skills/ (project); global ~/.gemini/skills/ (Windows global: ~/.agents/skills/)
agentmap --install-skill --platform antigravity # .agents/skills/ (project) or ~/.gemini/config/skills/ (global)
agentmap --install-skill --platform copilot # .copilot/skills/ or ~/.copilot/skills/
agentmap --install-skill --global --platform claude # ~/.claude/skills/...
agentmap --install-skill --platform agents # legacy .agents/skills/ (project or global); excluded from default `all`
agentmap --install-skill --dry-run # preview paths, no writes
--platform all installs: claude, cursor, codex, opencode, gemini, antigravity, copilot (not legacy agents).
Some platforms also get always-on docs and hooks in the same command:
--platform | Skill | Also installs (project) | Global docs |
|---|---|---|---|
gemini | .gemini/skills/…/SKILL.md | GEMINI.md + .gemini/settings.json BeforeTool nudge | ~/.gemini/GEMINI.md |
codex | .codex/skills/…/SKILL.md | AGENTS.md merge-safe <!-- agentmap:begin/end --> block | ~/.codex/AGENTS.md |
opencode | .opencode/skills/…/SKILL.md | AGENTS.md + .opencode/plugins/agentmap-nudge.js | ~/.config/opencode/AGENTS.md |
cursor | .cursor/rules/agentmap.mdc | .cursor/hooks.json beforeShellExecution gate + .cursor/hooks/agentmap-cursor-nudge.mjs | — (project-scope only) |
Codex and OpenCode share one repo-root AGENTS.md on project install. Existing content outside the marked block is preserved.
Pair with --install-hooks (Claude Code) or --mcp (Cursor MCP).
4. Claude Code plugin (one-command bundle)
Prefer the plugin over --install-skill/--install-hooks if you're on Claude Code and
want the skill, the PreToolUse grep/Bash nudge, and the stdio MCP server in a single
install that auto-updates:
# in Claude Code
/plugin marketplace add raymondchins/agentmap
/plugin install agentmap@agentmap
The plugin bundles: the packaged SKILL.md, the PreToolUse nudge (both the Grep
tool and Bash text-searchers, via ${CLAUDE_PLUGIN_ROOT}), and the stdio MCP server
(npx -y @raymondchins/agentmap --mcp, so ts-morph is fetched on demand — the plugin
cache ships no node_modules).
One thing the plugin can't do: install the git
post-commithook. Claude Code plugins can't write into.git/hooks/, so the auto-refresh-on-commit still needs a one-timenpx @raymondchins/agentmap --install-hooksin each repo (it also wires the nudge into.claude/settings.json, harmlessly redundant with the plugin's copy). Without it the map still rebuilds on any dirty query — you just lose the commit-time refresh.
Onboarding by platform
Enforcement isn't uniform — some CLIs get a live hook that actively steers grep to agentmap, some get an MCP server the agent can call, and some are docs-only (a skill/rule the agent may or may not consult). Honest matrix:
| Platform | Install | Enforcement | Known gaps |
|---|---|---|---|
| Claude Code | /plugin install agentmap@agentmap (or --install-hooks) | live hook — PreToolUse nudge on Grep + Bash searchers | non-blocking (never denies grep); bare-symbol Grep nudge requires the #3 hook fix |
| Gemini CLI | --install-skill --platform gemini | live hook — .gemini/settings.json nudge | fires on BeforeTool and emits a top-level systemMessage; Gemini parses and then drops hookSpecificOutput.additionalContext on BeforeTool, which is why the nudge used to vanish silently |
| OpenCode | --install-skill --platform opencode | log-only — .opencode/plugins/agentmap-nudge.js writes to the log, does not inject context | plugin can't steer the model; relies on the AGENTS.md block being read |
| Cursor | --install-skill --platform cursor + .cursor/mcp.json (below) | live gate — .cursor/hooks.json beforeShellExecution hook, plus the alwaysApply rule and the MCP server | denies only high-confidence structural greps; allow-fallback for logs/pipes/non-TS-JS; AGENTMAP_CURSOR_GATE=0 bypasses; project-scope only |
| Codex CLI | --install-skill --platform codex | live gate — .codex/config.toml PreToolUse hook | denies only high-confidence structural greps; allow-fallback for logs/pipes/non-TS-JS; AGENTMAP_CODEX_GATE=0 bypasses; needs a trusted dir + Codex hooks-GA |
| Copilot CLI | --install-skill --platform copilot | docs-only — .copilot/skills/ | same as Codex — no live hook yet |
Cursor MCP — copy-paste .cursor/mcp.json (Cursor's --mcp wiring is a documented
dead-end otherwise; drop this at your repo root):
{
"mcpServers": {
"agentmap": {
"command": "npx",
"args": ["-y", "@raymondchins/agentmap", "--mcp"]
}
}
}
Then Cursor exposes the 11 query tools (any, find, relates, map, hubs,
features, feature, symbols, search, callers, calls). Run agentmap --doctor any time to see what's wired
vs missing.
Uninstall
agentmap only writes files into your repo/home — remove them to fully uninstall. agentmap --doctor lists every path it wrote, and every docs merge lives inside an
<!-- agentmap:begin/end --> (or # agentmap:begin/end) fence, so deleting just that block
leaves the rest of your AGENTS.md / GEMINI.md intact.
| Platform | Remove |
|---|---|
| Claude Code | .claude/skills/agentmap/ + the agentmap PreToolUse block in .claude/settings.json |
| Cursor | .cursor/rules/agentmap.mdc, .cursor/hooks/agentmap-cursor-nudge.mjs, the beforeShellExecution entry in .cursor/hooks.json, + the agentmap entry in .cursor/mcp.json |
| Codex | .codex/skills/agentmap/, the # agentmap:begin/end block in .codex/config.toml, .codex/hooks/agentmap-codex-nudge.mjs, and the fenced block in AGENTS.md |
| OpenCode | .opencode/skills/agentmap/, .opencode/plugins/agentmap-nudge.js, the AGENTS.md block |
| Gemini | .gemini/skills/agentmap/, .gemini/hooks/agentmap-nudge.mjs, the BeforeTool hook in .gemini/settings.json, the GEMINI.md block |
| All | map cache rm -rf .claude/agentmap/; npm devDep npm rm @raymondchins/agentmap; the agentmap block in .git/hooks/post-commit |
Troubleshooting
Shortened here. Read the whole README on GitHub.
Signals
- GitHub stars
- 48
- Forks
- 11
- Last commit
- Sep 2026
Advanced
- Delivery
- agentmap MCP server → your ahel gateway (mcp.ahel.ai) → every connected AI client.
- Catalog kind
- mcp-server
- Gateway key
io-github-raymondchins-agentmap- Source
- github.com/raymondchins/agentmap