Ember
by dp177
README.md
# Ember — a warm start for coding agents
**Persistent, queryable memory for your codebase, over MCP.**
Point Ember at a repo once; every coding agent you use (Alan, Claude Code,
Cursor, …) starts warm instead of cold — with semantic-ish search, a repo map,
a mined decision log, and answers that cite `file:line`.
Built at [OpenFire 2026](https://luma.com/2k6cxr0n) (Alan AI's 24h open-source
hackathon). MIT licensed, local-first, zero native dependencies.
## The problem
Coding agents start every session cold. Architecture, conventions, and the
reasons behind past decisions get reconstructed tool call by tool call —
slowly, expensively, and often wrong. Humans carry that context implicitly.
## What Ember does
- `index_repo` — scans a repo, splits code into symbol-aware chunks, embeds
them, and builds a **pure-TypeScript HNSW** approximate nearest-neighbour
index. Everything persists in `<repo>/.ember/` — no database, no daemon.
Re-indexing is incremental: per-file hashes mean unchanged files keep their
embeddings, only new/changed files are re-embedded, and deleted files drop
out (`--full` forces a from-scratch rebuild).
- `search_code` — ranked `file:line` hits for natural-language queries.
- `ask` — answers questions with citations. With an OpenAI-compatible chat
endpoint configured (e.g. open models via OpenRouter) answers are
synthesized by the model; without one they are extractive (top chunks +
citations). It never invents an answer source.
- `repo_map` — entry points, hub files (most referenced), key symbols,
languages. The orientation pass an agent otherwise burns minutes on.
- `decisions` / `recent_changes` — the "why": decision-like commits and
ADR-style docs, plus recent history.
- `index_status` — freshness and embedder info.
- `save_note` / `recall_notes` — cross-session agent memory: an agent leaves a
short factual note (decision, gotcha, task state) and any later session —
including a different agent — recalls it. Notes persist in
`.ember/notes.jsonl`; recall is deterministic keyword matching.
## Quickstart
```bash
npm install
npm run build
# index any repo
node dist/cli.js index --path /path/to/repo
# search it
node dist/cli.js search "how are neighbors selected in the vector index" --path /path/to/repo
# ask with citations
node dist/cli.js ask "where does scanning decide which files to skip" --path /path/to/repo
# repo orientation
node dist/cli.js map --path /path/to/repo
node dist/cli.js decisions --path /path/to/repo
# leave a note for the next session, and recall notes later
node dist/cli.js note "chose jwt over sessions; see auth.ts" --tags auth --path /path/to/repo
node dist/cli.js notes -q auth --path /path/to/repo
# re-index after edits: only changed files are re-embedded
node dist/cli.js index --path /path/to/repo
```
## Use it from your coding agent (MCP)
Ember speaks MCP over stdio. Add it to your agent's MCP config:
```json
{
"mcpServers": {
"ember": {
"command": "node",
"args": ["/absolute/path/to/ember/dist/cli.js", "serve", "--path", "/path/to/your/repo"]
}
}
}
```
Then ask your agent to call `index_repo` once, and `repo_map` / `search_code`
/ `ask` whenever it would otherwise grope around the tree.
## Honest capability notes
- **Default embedder is lexical, not semantic.** Out of the box Ember uses a
deterministic hashing embedder (stemmed token overlap). It matches shared
vocabulary well — code identifiers are meaningful — but it does not
paraphrase. For true semantic embeddings, point Ember at any
OpenAI-compatible `/embeddings` endpoint:
```bash
export EMBER_API_BASE=https://openrouter.ai/api/v1
export EMBER_API_KEY=...
export EMBER_EMBED_MODEL=<an open embedding model>
export EMBER_EMBED_DIM=<its dimension>
node dist/cli.js index --path /path/to/repo # rebuild with the new embedder
```
_Status: this endpoint path is implemented but not yet live-tested; the
offline default above is the verified configuration. A configured endpoint
receives the text it embeds (code chunks and queries)._
- **Answer synthesis needs a chat model.** Set `EMBER_CHAT_BASE`,
`EMBER_API_KEY` (shared with embeddings), and `EMBER_CHAT_MODEL` (e.g. an
open model like `qwen/qwen3-coder` or `meta-llama/llama-4-maverick` via
OpenRouter) to get synthesized answers; otherwise `ask` is extractive.
Same status as embeddings: implemented, not yet live-tested.
- **HNSW is exact HNSW, not a placeholder.** M=16, efConstruction=200,
diversity-preserving neighbor selection (paper alg. 4), serialized graph in
`.ember/`. Tests measure recall@10 vs brute force (>0.9 on clustered data).
- **Incremental indexing is hash-based.** `.ember/files.json` stores a sha1
per file. Unchanged files keep their chunks and vectors; modified files are
re-chunked and re-embedded; deleted files are removed. Switching embedders
(kind or dimension) triggers an automatic full rebuild.
- **Note recall is keyword matching.** `recall_notes` scores by unique
query-term overlap - predictable and offline, not semantic.
- **Local-first.** The index never leaves your machine; network calls happen
only when you configure an external endpoint.
## How it fits together
```
src/core/scanner.ts git-aware file walk (skips deps, build output, binaries)
src/core/chunker.ts symbol-aware code chunking (falls back to windows)
src/core/embedder.ts pluggable embedders (offline lexical / HTTP endpoint)
src/core/hnsw.ts pure-TS HNSW index (cosine, diversity selection)
src/core/store.ts .ember/ persistence (chunks + vectors + graph + file hashes)
src/core/notes.ts cross-session agent notes (notes.jsonl)
src/core/engine.ts load + search
src/core/repomap.ts structure / entry points / hub files
src/core/decisions.ts decision log + recent changes from git
src/core/ask.ts cited answers (model or extractive)
src/mcp/server.ts MCP server (stdio)
src/cli.ts CLI
```
## Tests
```bash
npm test # 17 tests: hnsw recall, chunking, end-to-end index+search,
# notes persistence, incremental re-index, error paths,
# and a real MCP stdio session (mutations + restart recall)
```
## License
MIT © 2026 Daksh Patel
---
_Built by Daksh Patel with AI assistance (Instinct agent): code, tests and docs were developed iteratively with an AI pair-programmer; all claims in this README reflect behavior verified by the test suite._
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues