Basemind
Navigate large or unfamiliar codebases via the basemind MCP server — outlines, symbol search, reference/caller lookups, commit history, blame, and diffs without reading source files. Reach for it whenever the user asks "where is X defined", "what calls Y", "what changed recently in Z", or whenever you're about to grep or open many files to find structural information.From its SKILL.md
npx -y skills add Goldziher/basemind --skill basemindAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
SKILL.md
10.0 KB, as published. Nobody here has run it
basemind — the indexed context layer
basemind is the full context layer for this repository, served over MCP. It pre-indexes the repo into a content-addressed blob store + Fjall inverted index (and, when enabled, a LanceDB vector store) so structural, historical, and semantic questions resolve in milliseconds — without you reading whole files.
Capabilities
- Code map across 300+ languages — tree-sitter outlines, symbol search, references, callers, call graphs, implementations, dependents.
- Full-text + symbol search —
codemodesgrepandsymbols. - Git intelligence — history, blame, and structural diffs at symbol resolution, plus churn.
- Document RAG over 90+ file formats — PDFs, Office, HTML, email, images (OCR) → semantic
search with cross-encoder reranking (
memorymodedocuments). - Shared memory — per-repo, scope-keyed key-value + semantic memory across sessions.
- Web crawl — scrape / follow-link crawl into the same searchable document store.
Dedicated per-capability skills
This umbrella skill covers the whole surface. For focused workflows, reach for the dedicated skills:
basemind-code-search— outlines, symbol search, references, callers, call graphs.basemind-git-history— history, blame, structural diffs, churn.basemind-documents— document RAG (memorymodedocuments), web ingestion, memory.basemind-comms— coordinating with other agents in the same repo over the broker.basemind-cli— the same surface driven headlessly from the CLI.
When to reach for it (instead of grep / read_file)
Use basemind for:
- Locating a symbol: "where is
Foodefined?", "find the constructor forBar", "show me every type ending inService". - Following call graphs: "what calls
process_file?", "who depends on this module?". - Mapping a file's shape before reading it: which symbols, in what order, with what signatures.
- Walking recent history: "what changed in this file in the last 20 commits?", "when did this symbol last change?".
- Blame and ownership: "who last touched this function?", "what commit introduced this line?".
- Diffing across revisions: "what symbols did this branch add?", "show the hunks for
foo.rsbetween HEAD~5 and HEAD".
If you are about to open more than two or three files just to learn structure, stop
and use basemind first. The tools return paths + line numbers; you only read_file
once you know exactly which span you need.
Context economy — the operating discipline
basemind tools return paths, line numbers, and signatures — not file bodies, so a structural answer costs a fraction of the tokens of reading source. Treat that as the default workflow, not an optimization:
- Use
codemodeoutlinebefore you open a file. Read the whole file only when you have already identified the exact span you need from the outline; thenread_filethat range, not the file. - Use
codemodesymbolsinstead ofgrep/rgfor a definition. It matches indexed symbol names and returnspath:line, skipping the comment/string/test-name noise grep drowns you in. - Use
codemodesreferences/callersinstead of grepping call sites. Indexed call edges, not text matches. - Use
codemodegrepinstead of shelling out to ripgrep when you genuinely need regex over content — it runs over the in-RAM index and returns capped, structured hits. - Use
adminmoderescanafter you edit code, not a server reconnect. Passpaths: [...]to limit it to the files you touched. - Do not re-read a file basemind already mapped. If the outline answered the question, stop.
Rule of thumb: if a question is about where, what calls, what shape, who changed, or
what's indexed, a basemind tool answers it cheaper than reading files. Reach for read_file
only to see the actual implementation of a span you have already located.
basemind first, shell/grep/git fallback. Prefer basemind over reading files, over grep/rg,
and over naked git: use it for code parsing (outlines, references, callers), git history / blame /
diffs, document extraction / RAG / keyword + entity (NER) / summary (memory mode documents), and
web modes scrape / crawl / map. Drop to raw shell, grep, or
git only when no basemind tool covers the question.
Tool routing (copy this into your mental model)
| Question | Tool |
|---|---|
| "Where is X defined?" | code { mode: "symbols", name: X } (substring; optional kind) |
| "Jump to the definition of X used here?" | code { mode: "definition", path, line, column? } |
| "What's the high-level architecture / module map?" | graph { mode: "map" } |
| "What's the shape of file F?" | code { mode: "outline", path: F, l2?: true } |
| "What calls X?" (any name) | code { mode: "references", name: X } |
| "What calls this specific definition?" | code { mode: "callers", path: F, name: X } |
| "Trace the call graph from a function?" | graph { mode: "calls", name: X } |
| "What implements / extends / inherits from X?" | code { mode: "implementations", trait_name: X } |
| "What imports module M?" | code { mode: "dependents", module: M } |
| "What files are indexed?" | code { mode: "files" } |
| "What changed recently?" | git modes recent, touching, or by_path |
| "When did symbol X last change?" | git { mode: "symbol_history", path: F, name: X } |
| "Who wrote this line / symbol?" | git mode blame or blame_symbol |
| "Where's the churn?" | git { mode: "churn" } |
| "What's dirty in the working tree?" | git { mode: "status" } |
| "What's HEAD / branch?" | admin { mode: "repo" } |
| "Show diff between revs for file F" | git mode diff or diff_outline |
| "What's indexed?" | admin { mode: "status" } |
| "Semantic search over PDFs / Office docs?" | memory { mode: "documents", query } |
| "Recall something the agent stored earlier?" | memory mode get, list, or search |
| "Remember this for future sessions?" | memory { mode: "put", key, value } |
| "Refresh the index after editing code?" | admin { mode: "rescan", paths?: […] } |
| "Fetch next page of results?" | Pass next_cursor from prior response as cursor |
| "Pull this URL into RAG?" | web { mode: "scrape", url } — single page, robots-aware |
| "Ingest a docs site section?" | web { mode: "crawl", url } — link-following from a seed |
| "What URLs exist on this site?" | web { mode: "map", url } — discovery without bodies |
| "How much has basemind helped today?" | admin { mode: "telemetry", window: "today" } |
Setup (one-time per repo)
basemind needs an index before it can answer queries. The index lives in a machine-global cache
(Linux ~/.local/share/basemind/, macOS ~/Library/Application Support/basemind/; override
BASEMIND_DATA_HOME), keyed by workspace — never inside your repo. From the repo root:
basemind scan
This walks the tree, parses with tree-sitter, and writes a content-addressed blob store + Fjall inverted index into the machine-global cache. A few seconds for small repos, ~22 s for an ~80k-file TypeScript monorepo.
The MCP server is launched by the host (basemind serve — wired up in
.claude-plugin/plugin.json for you). You do not start it manually.
Re-run basemind scan after large changes, or run basemind watch to keep the index fresh on file save.
If a tool returns "no indexed files", that means basemind scan hasn't been run in this repo yet.
Examples
Locating a symbol
code { mode: "symbols", name: "MapCache" }
→ src/mcp/mod.rs:79:1 MapCache (struct)
src/mcp/mod.rs:88:1 MapCache (impl)
Now you know exactly where to read.
Following references
code { mode: "references", name: "process_file" }
→ src/scanner.rs:142:9 process_file
src/scanner.rs:201:13 process_file
...
No need to grep — the index already knows.
Outline a file before reading
code { mode: "outline", path: "src/mcp/tools.rs" }
→ 21 code router (function)
112 code helper (function)
...
A 1000-line file becomes a 30-line table of contents.
Notes
- All paths are repository-relative with forward-slash separators.
- Lists are capped (
limit, default 100, max 1000). Index scanners usescan_cap = limit * 8to bound work on common names. - Matching is substring on names —
codemodereferenceswithname: "bar"matchesFoo::bar()andbar()alike. There is no scope resolution; cross-check with modeoutlineif disambiguation matters. - Git tools require
basemind serveto be running inside a git repository. Outside a git repo they return a clear error. memorymodes require basemind to be built with--features full(or the individualdocuments/memoryflags). Without them the tools dispatch but return an MCP error. Memory is scoped by the normalisedoriginremote URL ([email protected]:Foo/bar.gitandhttps://github.com/Foo/bar/collapse to the same scope key) — clones of the same repo share memory; unrelated repos do not see each other's entries.webmodesscrape,crawl, andmaprequire--features crawl. When that feature is off they are NOT registered on the server at all — agents will simply not see them in the tool list. Crawled pages land in thedocumentsLanceDB table tagged with scopeweb:<host>;memorymodedocumentsfinds them alongside every other ingested document. It searches across ALL documents and has noscopeparameter — you cannot filter results to a single host at query time. robots.txt is honoured by default; only[crawl].respect_robots_txt = falsein the repo-rootbasemind.toml(config-file-only) disables it.