agentmap

MCP serverAI & models

agentmap 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 filesagentmapSaved
Does a helper for this already exist?14,7401999.9%
Load the whole repo into context150,2811,12799.3%
What breaks if I change this file?81,03861699.2%
Where is this symbol defined?1,9502099%
What files make up this feature?6,1211,02583.3%
Give me a repo overview3,0651,12763.2%
What does this one file import?58351711.3%
All 7 combined257,7784,45198.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:

agentmapgit grep
What depends on this file?100% precision59.9% precision
Where is this defined? (top-1)100%32%
Where is this defined? (top-3)100%80%
Tokens to find a definition1.9× fewer

n=42 dependents / n=75 definitions across zod, zustand, hono. Re-run: npm run eval · method → EVAL.md


⚡ The five commands

You wantRunSaves
"Do we already have this?"agentmap --find formatCurrency99.9%
"What breaks if I touch this?"agentmap --relates lib/auth.ts99.2%
"Where is this defined?"agentmap --find ChatMessage99%
"Give me the repo, cheap"agentmap --map --tokens 200099.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/http in the source. ⚠️ Install the scoped name; unscoped npx agentmap is 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.
  • --relates returns the full blast radius, so it costs more than a bare grep -l file 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 that cats 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.

agentmapAider repo mapRepoMapperRepomixcode2prompt
Ranking algorithmPersonalized PageRank (file + symbol graphs)PageRank (graph ranking)Importance heuristicsNone (file order)None (file order)
LanguagesTS/JS + Vue SFC (via ts-morph)Many (tree-sitter)Many (tree-sitter)Language-agnostic (text)Language-agnostic (text)
Token-budget outputYes — --map [--tokens N] ranked digestYes (built into Aider's context)PartialYes (size caps)Yes (templates/caps)
TS/JS resolution depthCompiler-grade — tsconfig paths + vite/webpack alias + #imports + workspaces (ts-morph)Basename/regex heuristicsBasename/regex heuristicsN/A (text)N/A (text)
Retrieval-accuracy evalYes — published EVAL.md vs live ground truthNoNoNoNo
Agent-loop wiringYes — post-commit auto-refresh + PreToolUse hookIn-process (Aider only)NoMCP server (no auto-refresh, no nudge)No
Dependenciests-morph onlyPython + tree-sitter stackPython + tree-sitterNodeRust binary
Installnpx @raymondchins/agentmappip install aider-chatpip installnpx/globalcargo/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:

--platformSkillAlso installs (project)Global docs
gemini.gemini/skills/…/SKILL.mdGEMINI.md + .gemini/settings.json BeforeTool nudge~/.gemini/GEMINI.md
codex.codex/skills/…/SKILL.mdAGENTS.md merge-safe <!-- agentmap:begin/end --> block~/.codex/AGENTS.md
opencode.opencode/skills/…/SKILL.mdAGENTS.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-commit hook. Claude Code plugins can't write into .git/hooks/, so the auto-refresh-on-commit still needs a one-time npx @raymondchins/agentmap --install-hooks in 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:

PlatformInstallEnforcementKnown gaps
Claude Code/plugin install agentmap@agentmap (or --install-hooks)live hookPreToolUse nudge on Grep + Bash searchersnon-blocking (never denies grep); bare-symbol Grep nudge requires the #3 hook fix
Gemini CLI--install-skill --platform geminilive hook.gemini/settings.json nudgefires 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 opencodelog-only.opencode/plugins/agentmap-nudge.js writes to the log, does not inject contextplugin 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 serverdenies 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 codexlive gate.codex/config.toml PreToolUse hookdenies 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 copilotdocs-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.

PlatformRemove
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
Allmap 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