devcontext-ai
v0.1.1
Published
Local-first persistent memory layer for AI coding agents.
Maintainers
Readme
DevContext
Local-first persistent memory for AI coding agents
The institutional memory of your repository. Your agent forgets. DevContext doesn't.
Developer starts their coding agent normally
│
▼
Coding agent OpenCode · Claude Code · Codex · Cursor
│ ◄────── MCP over stdio ──────┤
▼
DevContext runs 100% locally
├── retrieves relevant project history for the task
├── exposes decisions / discoveries / tasks / past sessions
└── captures new knowledge as reviewable candidatesNo cloud service · no account · no vector database
Why DevContext
Coding agents understand the current code. They forget what earlier sessions learned:
- architectural decisions and their reasons,
- debugging discoveries and root causes,
- known bugs, failed approaches, unfinished work.
DevContext stores that knowledge inside your repository. It hands it back to any MCP-compatible agent at the exact moment of need. You keep full ownership: memory lives in plain files, reviewable in git like everything else.
Highlights
| | |
| --- | --- |
| Persistent | Knowledge survives across sessions, agents, and teammates |
| Local-first | Plain JSON + Markdown under .devcontext/. Nothing leaves your machine |
| Agent-native | MCP stdio server with 11 tools; auto-registers with Claude Code, OpenCode, Cursor |
| Human-approved | Agent memories land in a candidate queue. Nothing becomes permanent without your review |
| Deterministic retrieval | Keyword + path + type + recency scoring. No network, no models, reproducible |
| Zero workflow change | Run devcontext init once. Then work exactly as before |
Installation
Requirements: Node.js >= 20 and git.
# install from npm
npm install -g devcontext-ai
devcontext --help
# or from source
git clone https://github.com/ashuksingh11/devcontext-ai
cd devcontext-ai
npm install && npm run build && npm link
devcontext --helpQuick start
cd your-project # a git repository
devcontext initinit does four things:
Detects your stack — languages, frameworks, package managers.
Creates the human-readable
.devcontext/folder.Writes an
AGENTS.mdsection that teaches agents when to query memory.Detects installed coding agents and registers the MCP server with each:
| Agent | Config location | | --- | --- | | Claude Code |
.mcp.json| | OpenCode |opencode.json| | Cursor |.cursor/mcp.json| | Codex | prints a TOML snippet for~/.codex/config.toml|
Codex keeps its MCP config global by design. Projects must not edit it, so
initprints the snippet instead of writing it.
Start your coding agent as usual. No workflow change.
Example workflow
Teach DevContext something today:
devcontext add discovery "Stripe sends duplicate webhook events" \
-c "Duplicate deliveries caused duplicate payments once. Keep the idempotency check." \
-f src/payment/webhook.ts
devcontext add decision "Keep idempotency protection in webhook processing" \
-c "The guard stays because of the duplicate-event incident." \
-f src/payment/webhook.tsWeeks later, ask your agent to refactor webhook processing. The agent calls
get_related_context("refactor webhook processing") and receives:
# DevContext — relevant project memory
## HISTORICAL CONTEXT — read before changing code
- [dec-001] (decision) Keep idempotency protection in webhook processing
The guard stays because of the duplicate-event incident.
Files: src/payment/webhook.ts
- [disc-001] (discovery) Stripe can send duplicate webhook events
...Run the deterministic demo at any time:
devcontext demoCLI reference
| Command | Purpose |
| --- | --- |
| devcontext init | Initialize .devcontext, scan the project, wire up agents |
| devcontext status | Memory counts, branch, last update |
| devcontext ask "<question>" | Ranked memories with provenance |
| devcontext context "<task>" | Compact agent-ready context block (--json supported) |
| devcontext decisions / discoveries / knowledge | List one memory type |
| devcontext tasks [--all] | List open work; [ ] open, [!] blocked, [x] done |
| devcontext add <type> "<title>" -c "…" | Add memory by hand |
| devcontext record-session file.json | Ingest a structured session summary |
| devcontext review | Approve or discard candidate memories left by agents |
| devcontext mcp-config [agent] | Print MCP setup snippets |
| devcontext demo | Deterministic end-to-end scenario in a sandbox |
| devcontext mcp | Start the MCP stdio server (agents run this) |
Exit codes: 0 success, 1 error, 2 usage error.
Memory model
Five memory types live in .devcontext/:
.devcontext/
├── config.json
├── project.md # generated overview; safe to edit by hand
├── knowledge/ # stable facts: stack, services, environments
├── decisions/ # architectural choices + reasons
├── discoveries/ # incidents, root causes, surprising behavior
├── tasks/ # open / blocked / done work
├── sessions/ # compact summaries of past agent sessions
└── candidates/ # new memories awaiting 'devcontext review'Every memory carries provenance:
{
"id": "disc-018",
"type": "discovery",
"title": "Stripe can send duplicate webhook events",
"content": "…",
"created_at": "2026-08-22T09:00:00.000Z",
"source": "incident-43",
"related_files": ["src/payment/webhook.ts"],
"related_commits": []
}Human approval
Memories recorded through MCP never become permanent directly. They land in
.devcontext/candidates/ and stay invisible to retrieval until you approve them:
devcontext reviewAnswers: y save, n discard, a save all, q quit.
record-session accepts the PRD shape:
{
"goal": "Fix payment retry logic",
"agent": "opencode",
"files_changed": ["src/payment/retry.ts"],
"discoveries": ["Stripe may return duplicate webhook events"],
"decisions": ["Keep idempotency check in webhook handler"],
"remaining_work": ["Integration test still failing"],
"status": "PARTIALLY_COMPLETE"
}MCP tools
Agents discover these tools automatically after init:
| Tool | Purpose |
| --- | --- |
| get_project_context | Project overview + memory counts |
| search | Free-text search across all memory |
| get_decisions / get_discoveries / get_tasks | Type listings |
| get_related_context | Ranked context for a task; includes historical warnings |
| get_file_context | All memory tied to one file + recent commits touching it |
| record_discovery / record_decision / record_task | Stage a candidate memory |
| record_session | Stage a session summary |
Tool descriptions tell agents when to call each tool. The generated AGENTS.md
section reinforces the contract: look before you change code, record what you learn.
Retrieval
v0 uses deterministic scoring only — no network, no models:
| Signal | Weight behavior |
| --- | --- |
| Keyword overlap | Title weighted double, light stemming |
| File-path match | Query paths matched against related_files |
| Memory type | Decisions and discoveries rank slightly higher |
| Recency | Exponential decay, half-life ≈ 120 days |
The retriever sits behind the ContextRetriever interface. A semantic/embedding
implementation can replace or augment it without touching storage, CLI, or MCP code.
src/
├── types.ts # memory model
├── core/
│ ├── memory.ts # validation, ids, normalization
│ ├── store.ts # .devcontext read/write, candidates, approval
│ ├── scanner.ts # project detection, project.md rendering
│ ├── git.ts # branch, commits, status, file history
│ ├── retriever.ts # deterministic ranking engine
│ └── render.ts # compact text renderers shared by CLI + MCP
├── agents/config.ts # agent detection + native config writing
├── commands/ # CLI command implementations
├── mcp/server.ts # MCP stdio server
└── cli.ts # command definitionsDesign rules: append-oriented storage with provenance; .bak backups before the
first merge into an existing agent config; marker-delimited AGENTS.md blocks so
re-init never duplicates content; retrieval reads only approved memories.
Testing
npm test # builds, then runs vitest49 tests cover: store lifecycle, id assignment, candidate approval, schema validation, project scanning, git extraction, ranking behavior, path boosts, stemming, determinism, agent config merging, AGENTS.md markers, all MCP tools, session ingestion, and a full end-to-end CLI walk (init → add → ingest → context).
OpenCode setup example
After devcontext init inside an OpenCode project you will find:
{
"mcp": {
"devcontext": {
"type": "local",
"command": ["devcontext", "mcp"],
"enabled": true
}
}
}Start opencode normally and ask:
Fix the login timeout issue.
The agent discovers the DevContext tools over MCP, calls get_related_context,
and reads prior session notes about login timeouts without you pasting anything.
Limitations
- Keyword retrieval only; paraphrases may miss unless tokens overlap.
- Session capture is manual (
record-sessionorrecord_session); automatic extraction from OpenCode history is future work. - One memory per JSON file is simple and inspectable, but not built for tens of thousands of entries.
- Codex registration stays manual by design; projects should not edit global configs.
- English-only tokenization heuristics.
Roadmap
Designed for, not yet implemented:
- [ ] Automatic OpenCode/Codex/Claude session extraction
- [ ] Embeddings-backed semantic search behind the same interface
- [ ] IDE extension
- [ ] Project knowledge graph
- [ ] Team-shared memory, cloud sync, conflict resolution
- [ ] Pre-change "historical warning" hooks wired into file-edit events
