coldstart
Description
Codebase memory for coding agents, with no embeddings and no API key. A deterministic AST index answers "which files are relevant to this task?" in milliseconds, and agents write durable notes about the repo that are content-hash checked — a note flags itself stale the moment…
About
Codebase memory for coding agents, with no embeddings and no API key. A deterministic AST index answers "which files are relevant to this task?" in milliseconds, and agents write durable notes about the repo that are content-hash checked — a note flags itself stale the moment the code it describes changes. Notes are…
Details
- Author
- akashgoenka
- Categories
- Developer Tools, Other, Productivity, Knowledge Base
Jump to
Setup
Install coldstart in your MCP client (Claude Desktop, Cursor, Windsurf, and others).
Repository: https://github.com/akashgoenka/coldstart
Follow the installation instructions in the repository README, then restart your MCP client.
Self-maintaining codebase knowledge for AI coding agents.
Agent-written notes that stay anchored to your code — plus fast, deterministic navigation — so Claude Code, Codex, and Cursor stop rediscovering the repo every session.
Website·Docs·Blog·Philosophy·npm
- The notebook(coldstart kb) — durable, agent-written notes about howthiscodebase actually works: what a file is for, how a flow spans files, which invariants hold. Captured after real tasks, recalled when a later task matches, and kept honest by the index — every note is anchored to real files, and a note whose evidence drifted is flagged, not served as truth.
- Navigation(coldstart find/coldstart gs) — a fast static index over file paths, symbol names, exports, and the import/call graph. It answers "which files are relevant to this task?" in milliseconds, with checkable evidence instead of a similarity score.
No embeddings, no model to run, no service to babysit. Agents are already good at reading and reasoning about code; what they waste tokens on isfindingthe right file andre-derivingwhat the last session already figured out. coldstart does those two parts and gets out of the way.
npm install -g @cstart/coldstart cd your-project coldstart init # coldstart.md + client wiring + notebook + background index warm-up
A singlecoldstart initdoes everything — navigationandthe notebook. It asks two things — theexperience(cli, recommended, ormcp) and theclient— then writes the agent-facing guidance into the client's own rules file (as an importedcoldstart.mdfor Claude Code; inlined directly for Cursor and Codex, which don't resolve@filereferences), wires the client, and sets up the notebook (skeleton, git wiring, and — for Claude Code, Codex, and Cursor — the capture/recall hooks). Pass--experience/--clientto skip the prompts. The client is never auto-detected; you always pick it.
- Claude Code→ writescoldstart.mdand ensuresCLAUDE.mdimports it via@coldstart.md, and registers both the find/gs search hooks (a PostToolUse nudge + a PreToolUse find-dedup guard) and the notebook recall/capture hooks (UserPromptSubmit + Stop/SubagentStop) in.claude/settings.json— merged into any existing settings, never overwriting them. Themcpexperience also writes.mcp.json.
- Codex→ embeds the full coldstart guidance inline in a marked block inAGENTS.md(Codex has no@fileinclude, so there's no separatecoldstart.md), refreshed in place on re-run, and registers Codex-specific navigation plus notebook hooks in.codex/hooks.json. The capture hook understands Codex rollout and subagent transcripts. Themcpexperience also writes[mcp_servers.coldstart]into.codex/config.toml.
- Cursor→ writes.cursor/rules/coldstart.mdc— an always-applied rule that carries the full coldstart guidance inline (Cursor doesn't reliably resolve@filereferences in rules), rewritten on every init — and registers Cursor-specific navigation plus notebook hooks in.cursor/hooks.json(apreToolUsefind-dedup guard, apostToolUsenudge,beforeSubmitPromptrecall, andstop/subagentStopcapture — merged into any existing hooks). The capture hook parses Cursor's own conversation transcript. Themcpexperience also writes.cursor/mcp.json.
- Other→ writescoldstart.mdonly, and prints the wiring directions (plus the MCP server entry for themcpexperience).
initthen warms the index in the background, so your first lookup is instant. Re-runninginitis safe — it never duplicates entries.
npm install -g @cstart/coldstart@latest coldstart init # re-run in each project to refresh coldstart.md
A version stamp in the keeper's lockfile makes the old background keeper shut down on the next lookup; a fresh one spawns from the new binary. No manual restart needed.
[!NOTE]Migrating fromcoldstart-mcp:the package was renamedcoldstart-mcp→@cstart/coldstartat 2.0.0 (the CLI is now the primary surface).coldstart-mcpis deprecated but still installs; switch withnpm uninstall -g coldstart-mcp && npm install -g @cstart/coldstart && coldstart init. Thecoldstart-mcpbinary name is kept as an alias, so existing MCP configs keep working.
initwrites per-repo wiring that a globalnpm uninstallcan't reach (npm fires no reliable uninstall hook, and it has no record of which repos youinit'd). So — like husky — coldstart ships an explicit reverse:
coldstart unwire # strip coldstart's wiring from this repo (notebook kept) coldstart unwire --purge # also delete .coldstart/notebook/ and its git plumbing
unwireremovesonlycoldstart-owned markers from the filesinittouched — hook entries, the@coldstart.mdimport, theAGENTS.mdblock, the MCP server entry, and files coldstart fully owns (coldstart.md,.cursor/rules/coldstart.mdc) — never your own content in shared files. It sweeps all four clients, is idempotent (a second run reports everything already gone), andkeeps the notebook by defaultsince it's committed, shared data. Run it in each project first, thennpm uninstall -g @cstart/coldstartto remove the package.
A repo-local knowledge base written and read by agents, in.coldstart/notebook/:
coldstart kb search tile save lifecycle # plain task words, symbols, or file names coldstart kb lookup src/models.py Tile # everything known at one exact address coldstart kb write spec.json # the write gate (two-phase dedup) coldstart kb commit # publish notes to git, nothing else rides along coldstart kb view # open a single-file HTML browser of the notebook coldstart kb repair # worklist of notes that are written but unfindable coldstart kb repair-aliases # worklist of aliases that may no longer be true coldstart kb status / lint / render / init / migrate
What a note is.Three shapes: afile note(what a file is for — a single summary, or per-symbol facets for hub files), aflow note(a cross-file story: ordered steps, invariants), and alesson(a trap, rule, bug-cause, rationale, or confirmed absence). Every note carriesanchors— concrete file paths and symbols its claims rest on.
Where notes reach the agent.Three surfaces, no new habits required:
- Summary:lines onfindresults— a past agent's verified overview of a file, right where the file ranks.[fresh]means the file is byte-identical to when the summary was verified — the agent can rely on it without re-reading the file.
- Recall at prompt time(optional hook) — notes whose titles, aliases, or anchors match the incoming prompt are surfaced as a compact title + gist + path block, hard-capped, framed as reference data. Nothing matches → nothing injected.
- kb search/kb lookup— a search engine over the notebook for mid-task vocabulary changes, and an exact-address lookup (path [symbol]) before editing a file.
Why it can be trusted.This is the part that took the design work:
- Freshness is mechanical, not hoped-for.Every anchor is stamped with a content hash at write time; the index re-checks stamps as the code changes. A drifted note renders[evidence changed: <path>]and the guidance says re-verify — stale knowledge degrades into a labeled hypothesis instead of a confident lie.
- The log is the truth.Notes live in an append-only.rawevent log (commit it — merges are unions, so parallel branches of notes reconcile without conflicts). The Markdown notes are derived, regenerated mechanically, and gitignored.
- Writes go through a gate.A new note's concept is first searched against existing notes — the agent must explicitly merge into a match (--into <id>) or declare it new (--new). Duplicates are gated at write time, not cleaned up later.
- Concurrent sessions are safe.Multiple agents can write at once: per-note append-only logs, exclusive creation for new note ids (a same-moment duplicate becomes two visible notes, never a silent merge), lossless merging for shared file notes, and atomic renders (a reader never sees a half-written note).
- Corrections happen in-session.If an agent finds a note wrong while the evidence is in its context, the guidance tells it to fix or retract the note right then — no better-placed future agent exists.
Setup:the notebook comes withcoldstart init— no separate step. It creates the notebook skeleton, sets union-merge for the logs, and (on Claude Code, Codex and Cursor) wires the two hooks — capture at session end, recall at prompt time. (coldstart kb initstill exists as an alias if you want to (re-)wire just the notebook.) Other hosts can drive the notebook without the hooks: via the fullkbCLI, or — for no-shell clients — thekb_search/kb_lookup/kb_write/kb_status/kb_repair/kb_repair_aliasesMCP tools.
Language-agnostic.The notebook's freshness machinery is content-hash based, so it works on any codebase — including languages the navigation index doesn't parse. Where the index does parse, notes additionally get symbol-level freshness.
[!NOTE]The notebook is young.What's verified today: notes written by agents in real sessions checked out accurate against the code; the stale-note loop closes end-to-end (flag → re-read → correction); capture, recall, and concurrent writes hold up under stress. The bet — stated as a bet — is that a corpus like this compounds over a repo's lifetime: the second time any question comes up, the answer is oneReadaway instead of a re-derivation.
The intended flow:finda concept → pick the best path →gsthat file for its shape and who uses it →Readonly for the implementation inside a method body. Notebook summaries ride along onfindresults, so often the orientation step answers itself.
flowchart LR A["coldstart find<br/>which files?"] --> B["coldstart gs<br/>what is it? who uses it?"] --> C["Read<br/>just the method body"] class A,B cold class C warm classDef cold stroke:#16708f,stroke-width:2px classDef warm stroke:#c26714,stroke-width:2px
[!TIP]Pass every salient identifierfrom your task — the symbol, the domain noun, the rare token you half-remember — not one distilled keyword.findranks files by how many of your terms each one covers and shows, per file, which terms it defines vs. imports and a preview of the lines where they cluster. Often that's enough to answer without opening anything.
Speed-wise,findcompetes with raw grep: its repo-wide reference pass runs onripgrep— yours from PATH, the bundled copy, or an editor's (COLDSTART_RGoverrides) — withgit grep/grepfallbacks, and the ranked page comes from the pre-built index, not a scan.
Flags:--path GLOB(scope; comma-combine,!excludes) ·--tests(include test files) ·--via(show name-reference relations) ·--json
Returns the file's symbols (with line ranges), its 1-hop internal imports, who imports it, and per-symbol cross-file callers — in one call. This is the answer to"who uses this file / who calls this symbol"; it is not a grep.
Flags:--symbol a,b(deliver named method bodies inline) ·--match TERM(filter a god-file to one area;a|b= OR,/regex/= regex) ·--view symbols|imports|importers|callers·--json
Batch independent lookups in one shell call
coldstart ships as one binary with two front doors:
- CLI (primary)—coldstart find …/coldstart gs …/coldstart kb …. For any shell-capable agent (Claude Code, Cursor, terminal use). This is the fast path.
- MCP (for no-shell clients)— thefindandgstools, plus the notebook askb_search/kb_lookup/kb_write/kb_status/kb_repair/kb_repair_aliases, all byte-identical to the CLI. For clients like Claude Desktop that have no shell. (kb commitstays CLI/human-only — publishing notes to git is never an agent action.)
Same engine, same index, same results. Pick whichever your agent can reach.
It works best withClaude Code,Codex, andCursor: all three get platform-specific find/gs hooks and notebook recall/capture hooks fromcoldstart init. Any other client getscoldstart.mdplus printed wiring directions.
coldstart has no embeddings, no generated summaries, no semantic layer computed at index time —on purpose. The semantic layer is the agent.Every consumer is already a frontier model; pre-computing meaning at index time only duplicates that, worse and stale. So the index keeps what's cheap to keepexact— paths, symbols, exports, the import/call graph — and returnswhyeach file ranked.
The notebook is the same philosophy applied to memory: coldstart still computes no meaning of its own. It stores, anchors, and freshness-checks the meaningagentsauthor — written at task time, by the reasoner that had the full context, about the question that actually mattered. The full argument is inPHILOSOPHY.md.
flowchart TD K["keeper — coldstart --daemon<br/>watches repo, patches/rebuilds, saves cache<br/>serves nothing"] -->|debounced save| C[("on-disk cache")] C --> F["coldstart find<br/>reads cache, prints"] C --> G["coldstart gs<br/>reads cache, prints"] C --> M["MCP server<br/>reads cache, stdio"] class K cold classDef cold stroke:#16708f,stroke-width:2px
- A singlekeeperprocess per repo watches the filesystem and keeps the on-disk cache current. It doesnotanswer queries.
- The CLI readers (find/gs) and the MCP server arestateless readersover that cache. The first reader for a repo lazily spawns the keeper, so even uncommitted edits stay live.
- Readers never build the index.On a cache miss they wait for the keeper's build (progress to stderr) instead of silently kicking off a multi-minute build inline — or three of them concurrently.
- No HTTP, no ports, no bridge. The keeper logs to~/.coldstart/daemon/<root>.logand exits when its lockfile is removed.
There is no cache TTL.The index is never discarded for being old — it's keptcorrectinstead:
- While the keeper runs:edits are debounced (400 ms), thenpatched incrementally(~2–5 ms/file, up to 30 files or 20% of the repo, whichever is larger) or trigger abackground full rebuildabove that (served from the last good index until the swap). The cache re-saves ~5 s after edits settle, inatomic generations— a reader can never load a half-written mix of old and new.
- When the keeper starts:itreconciles— stat-checks every indexed file against its stored fingerprint (~150 ms even at 16k files) plus a git diff against the indexed HEAD — and patches exactly what changed while nothing was watching. A branch switch that used to force a 96-second rebuild on a 16k-file repo is now a ~3-second patch.
- As a backstop:every patch is lint-checked against index invariants (a violation triggers an automatic rebuild and lands in a repair log thatstatusshows), and a rotating fingerprint audit after each save catches watcher-missed events.
The keeper also stamps the notebook's anchor freshness (a small sidecar, derived single-flight) — the notebook never loads the code index to answer a query.
coldstart status # keepers on this machine: alive? fresh? last patch/rebuild/save? repairs? coldstart restart # kill the current repo's keeper (respawns on next lookup) coldstart restart --root DIR # kill a specific repo's keeper from anywhere coldstart restart --all # kill every keeper coldstart index # build + save the cache once, up front (single-writer prep)
restartis the right move whenever anything feels stale — a fresh keeper reconciles on start, so it comes backcorrect, not just alive.statusanswers "is my index fresh, and why?": liveness, cache age, the keeper's last reconcile/patch/rebuild/save stamps, and the tail of the repair log — no network probe.
Navigation index: TypeScript, JavaScript, JSX/TSX, Vue, Svelte, Astro, AngularJS 1.x, Java, Kotlin, Ruby (Rails-aware:has_many/belongs_toassociations,routes.rbresources, controller↔view edges), Python (Django convention edges), Go, Rust, C#, PHP (Laravel convention edges), C++, Groovy (incl. Gradle DSL), GraphQL, YAML, TOML, XML, and.envfiles.
Not indexed:Swift, Dart — no extension mapping; these files are not walked or parsed.
Thenotebook works regardless— its freshness stamps are content-hash based, so notes on a Swift repo are as trustworthy as notes on a TypeScript one (they just lack symbol-level freshness detail).
- A literal string / phrase / regex inside file bodies →Grep.
- Reading an implementation →Read, aftergsgives you the shape.
- findsays"no indexed file contains any of […]"→ those identifiers aren't in the repo. Don't grep spelling variants.
npm install npm run build npm test # run a query from your build: node dist/index.js find auth --root . # run the MCP server in a single process (no background keeper) for debugging: node dist/index.js --root . --no-daemon
SeePHILOSOPHY.mdfor why coldstart computes no semantics of its own,ARCHITECTURE.mdfor the index pipeline, process model, and notebook internals, andTROUBLESHOOTING.mdfor recovery procedures.
- It's a routing layer plus an agent-written notebook — no semantic analysis or generated code summaries. This is deliberate: the consuming agent is the semantic layer (seePHILOSOPHY.md).
- gscallers are one-hop and file-scoped. Member-expression calls (this.method(),api.method()) aren't cross-file resolved; named function/constant calls are. Chase further hops by callinggson the caller files.
- Dynamic/computed imports (import(variable)) and runtime-DSL references (polymorphic associations, gem/reflection-backed models) stay unresolved.
- Hidden directories and files over 1 MB are skipped by the index.
- The keeper is per-repo and per-machine — no sharing across projects or hosts. The notebookdoestravel: its.rawlogs are committed and union-merge across branches and machines.
- Notebook quality is bounded by what writing agents actually read — notes are accurate about what they state, but a note is not a proof of completeness.
Longer pieces on the problems behind this tool — what agent sessions actually cost, and what happened to the design when the measurements disagreed with the plan.
- Where the tokens go in an agent session— session cost is roughly turns × resident context, and output is a rounding error. How to decompose your own transcripts instead of trusting anyone's published numbers.
- An index cannot answer the same question twice— a code graph makes each hop cheaper without reducing how many hops you take, and ranking by in-degree makes leaf files structurally unrankable.
- The tool the agent doesn't call— availability, documentation, and an explicit instruction still don't add up to adoption. Including the times our own agents bypassed our own command.
- From four tools to two— which tools got deleted, which capability genuinely went with them, and why the surface stayed small afterwards.
- Notes about code should be written by whoever read the code— why the notebook captures in-session rather than summarizing transcripts later.
This is a web browser that enables your coding agent, such as Claude Code, to visit websites on your behalf and assist you in identifying bugs or creating UI test cases.
Perform semantic search and retrieval augmented generation over your Apple Notes.
Chartbrew + AI agents. MCP server exposing Chartbrew's documented API: teams, connections, datasets, dashboards, charts, live queries, and secure embedding. TypeScript · stdio · restricted/unrestricted tool modes.
Zero-dependency persistent AI memory using SQLite. Dual-store, pluggable embeddings, 10 MCP tools.
Local code analysis MCP server with 25+ tools: semantic search, call graph tracing, dependency analysis, and symbol navigation. Built with Tree-sitter and CozoDB. Supports Go, Python, JS, TS.
A local-first code indexer that enhances LLMs with deep code understanding. It integrates with AI assistants via the Model Context Protocol (MCP) and supports AI-powered semantic search.
A server for managing structured project context using SQLite, with support for vector embeddings for semantic search and Retrieval Augmented Generation (RAG).
Persistent memory with semantic search, hit-based ranking, universal import, and a knowledge marketplace
MCP of MCPs is a meta-server that merges all your MCP servers into a single smart endpoint. It gives AI agents instant tool discovery, selective schema loading, and massively cheaper execution, so you stop wasting tokens and time. With persistent tool metadata, semantic search, and direct code execution between tools, it turns chaotic multi-server setups into a fast, efficient, hallucination-free workflow. It also automatically analyzes the tools output schemas if not exist and preserves them across sessions for consistent behavior.
Explore and understand codebases through conversation by breaking files into logical chunks for searching and querying without embeddings.
An MCP server for intelligent tool routing, using a Qdrant vector database and LM Studio for embeddings.
Sign in to leave a review
Use Google, GitHub, or an email account so ratings stay tied to real people.
No reviews posted yet.





