ContextForge
Integrates with JetBrains AI to provide persistent memory, enabling agents to access and store knowledge across conversations and workspaces.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@ContextForgeWhat did we decide about JWT vs sessions for auth?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
ContextForge
Powered by AdoptNow.AI. AdoptNow.AI is currently a project domain, not a registered company.
Graph-based knowledge storage for AI coding agents — works with any IDE via MCP.
ContextForge captures your conversations with AI coding agents (Copilot, Cursor, JetBrains AI, etc.), extracts structured knowledge into a graph database, and makes it available across all your projects and workspaces. Instead of agents starting every conversation from scratch, they can build on past decisions, patterns, and context.
Distributed as a single binary — no source code, no npm install, no runtime dependencies.
Quick Start
1. Run the complete setup
From a fresh ContextForge checkout, run:
npm run setupThis is the primary setup path. It installs dependencies, downloads the semantic-search model into the correct user cache, and builds the MCP server. It is safe to run again and reuses cached model files.
After setup completes, configure your MCP client using the instructions below. For OS-specific details, see SETUP-MAC.md or SETUP-WINDOWS.md.
Alternative: use a packaged release
cp -r release/ ~/.contextforge/
chmod +x ~/.contextforge/contextforgeModel and release details
npm run setup downloads the model from Hugging Face into ~/.contextforge/models/Xenova/all-MiniLM-L6-v2/. The MCP server uses this local copy and does not access the network during searches. To only download the model after dependencies are already installed, use npm run download:model --workspace packages/core.
For a packaged release, the release builder copies this cached model beside the binary when it is present. Set CONTEXTFORGE_MODEL_DIR if the model is stored elsewhere.
Related MCP server: mcp-chest-memory
Table of Contents
The Problem
AI coding agents are stateless. Every new conversation starts from zero — the agent doesn't remember:
What files were changed last week and why
What architectural decisions were made
What errors were encountered and how they were fixed
What libraries, patterns, and conventions the project uses
Raw conversation logs are huge (50-200KB each) and full of noise (tool output, repeated system prompts, file contents). Storing and searching them is expensive and slow.
How It Works
ContextForge solves this with a 3-step pipeline:
Step 1: Capture Step 2: Extract Step 3: Query
┌──────────────┐ ┌────────────────────┐ ┌───────────────────┐
│ Agent talks │──────▶│ Extractor pulls │────▶│ Graph DB stores │
│ to user │ │ entities, facts, │ │ only structured │
│ (50-200KB) │ │ relations │ │ knowledge (2-5KB) │
└──────────────┘ └────────────────────┘ └───────────────────┘
│ │
▼ ▼
Raw text DISCARDED Graph is queryable
across all projectsResult: 96% smaller storage, instant graph queries, knowledge that persists across workspaces and IDEs.
The agent calls MCP tools automatically — no manual invocation needed. The tools are available to any IDE that supports MCP (VS Code, Cursor).
What gets extracted
Extracted | Example |
Files |
|
Functions/Classes |
|
Libraries |
|
Errors |
|
Decisions | "Used JWT instead of sessions because it scales better" |
Relationships |
|
What gets discarded
Raw file contents that were shown to the agent
Tool call outputs (grep results, terminal output)
System prompts and context blocks
Repeated/duplicate content
2. Configure MCP server in your IDE
VS Code / Cursor — open the global MCP config (Cmd+Shift+P → "MCP: Open User Configuration") and add:
{
"servers": {
"contextforge": {
"command": "/Users/<username>/.contextforge/contextforge",
"type": "stdio"
}
}
}Replace <username> with your macOS username. This is global — works across all projects.
MCP setup by client
MCP registration and agent instructions are separate. Register the server first, then install or enable the client-specific instructions so the agent actually retrieves and saves memory.
Client | MCP registration location | Instruction location |
VS Code / Copilot | Project: | Project: |
Claude Code | Project: | Project: |
Other CLI MCP clients | The client's MCP JSON/config file, using a stdio server entry | The client's instruction or rules file; there is no universal CLI location |
For a packaged installation, use the absolute executable path in the MCP entry:
{
"contextforge": {
"type": "stdio",
"command": "/Users/<username>/.contextforge/contextforge",
"args": []
}
}VS Code uses the servers wrapper:
{
"servers": {
"contextforge": {
"type": "stdio",
"command": "/Users/<username>/.contextforge/contextforge",
"args": []
}
}
}Claude Code uses the mcpServers wrapper. The project command is:
claude mcp add --transport stdio --scope project contextforge -- /Users/<username>/.contextforge/contextforgeFor a source checkout, replace the packaged command with an absolute Node executable and the built server path. Set CONTEXTFORGE_MODEL_DIR to packages/core/release/models when semantic search model files are not bundled beside the server. After changing configuration, reload or restart the client and confirm that contextforge is connected.
3. Add agent instructions (so agents use memory automatically)
The MCP server alone makes tools available — but agents won't use them unless instructed. This step ensures every conversation automatically stores and retrieves knowledge.
VS Code / Cursor — create the file ~/Library/Application Support/Code/User/prompts/contextforge.instructions.md:
---
description: "Use when: starting any conversation, recalling past work, ending a conversation. Manages persistent memory across all workspaces using the contextforge MCP tools."
---
# ContextForge
You have access to a persistent knowledge graph via MCP tools that remembers context across all conversations and workspaces.
## At the start of every conversation
1. Call `get_workspace_context` with the current workspace path to load known entities, decisions, patterns, and facts from past conversations.
2. Use this context to avoid re-asking questions the user already answered, and to build on past decisions.
## During the conversation
- When the user asks about past work, decisions, or patterns, call `search_memory` to find relevant entities.
- When the user asks to refer to a Rally ticket (for example `US12345` or `TF6789`), call `get_rally_work_item` to fetch the latest details from Rally.
- When a notable decision, pattern, or convention is established, call `add_fact` to persist it immediately.
## At the end of a meaningful conversation
- When significant work was done (code changes, architectural decisions, bug fixes, new patterns), call `save_conversation` with the workspace path and the conversation messages.
- This extracts entities, relationships, and facts into the graph. Raw text is discarded.
- Skip this for trivial questions or one-off lookups.
## Tool summary
| Tool | When to use |
|------|-------------|
| `get_workspace_context` | Start of conversation — load past knowledge |
| `search_memory` | Recall past work, decisions, errors, patterns |
| `add_fact` | Persist a decision, convention, or insight immediately |
| `get_rally_work_item` | Fetch live Rally details for TF/US references |
| `save_conversation` | End of meaningful conversation — extract and store knowledge |
| `memory_status` | Check how much is stored, which workspaces have data |
| `cleanup_memory` | Remove old knowledge by time range (optionally per workspace) |
| `forget_workspace` | Completely remove all knowledge for a workspace |This file is user-level — it applies globally across all projects automatically.
4. Install the Capture Extension (automatic conversation saving)
Steps 2-3 set up the read side (agent retrieves knowledge) and instruction-driven write (agent calls save_conversation). The capture extension adds automatic write — conversations are saved to the knowledge graph without the agent needing to cooperate.
VS Code / Cursor:
# Install the VSIX from the release folder
code --install-extension release/contextforge-capture-0.1.0.vsixOr: Open VS Code → Cmd+Shift+P → "Extensions: Install from VSIX..." → select the .vsix file.
The extension automatically:
Watches Copilot Chat session files for completed conversations
Extracts messages and writes them to
~/.contextforge/inbox/The MCP server processes the inbox on its next call
You'll see a status bar item: $(database) Memory: active.
Chat commands:
@memory /save— manually save the current conversation immediately@memory /status— show capture status
Settings (via VS Code Settings UI → "ContextForge"):
contextforge.autoCapture— enable/disable auto-capture (default: true)contextforge.captureDelaySeconds— seconds to wait after last write before capturing (default: 30)contextforge.minMessages— minimum messages to capture a session (default: 2)
5. Verify
Start a new conversation with your AI agent and check:
The agent should call
get_workspace_contextat the startAsk: "What do you know about this project from past conversations?" — it should call
search_memoryOn first use, results will be empty — the database populates as you have conversations
Architecture
WRITE PATH READ PATH
────────── ─────────
┌──────────────────────────────────┐ ┌──────────────────────────────────┐
│ Capture Extension (in IDE) │ │ Agent (in IDE) │
│ │ │ │
│ Watches chat sessions, │ │ MCP resource auto-injected │
│ extracts messages, │ │ into context on start. │
│ writes to inbox. │ │ MCP tools called on demand. │
│ (VS Code extension) │ │ │
└─────────────┬────────────────────┘ └───────────────┬──────────────────┘
│ │
▼ │
~/.contextforge/inbox/ │
(JSON files: sessionId, │
workspace, messages) │
│ │
▼ ▼
┌──────────────────────────────────────────────────────────┐
│ MCP Server (contextforge binary) │
│ │
│ On startup + before reads: processInbox() │
│ → parse inbox JSON → extract knowledge → ingest │
│ │
│ Tools (8): search_memory, get_workspace_context, │
│ save_conversation, add_fact, get_rally_work_item, │
│ memory_status, cleanup_memory, forget_workspace │
│ │
│ Resource: contextforge://workspace/{path} │
│ → auto-injected into agent context │
│ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ Extractor │ │MemoryDatabase│ │
│ │ (no LLM) │ │ (SQLite) │ │
│ └──────────────┘ └──────┬───────┘ │
└───────────────────────────┼─────────────────────────────┘
│
▼
~/.contextforge/contextforge.dbData Flow — Step by Step
Write Path (automatic capture)
┌─────────────────────────────────────┐
│ 1. User chats with Copilot in IDE │
│ (VS Code) │
└──────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ 2. IDE writes session to disk │
│ chatSessions/<id>.jsonl │
│ (JSONL event log format) │
└──────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ 3. Capture Extension detects │
│ change via FileSystemWatcher │
│ (30-second debounce) │
└──────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ 4. Extension parses JSONL, │
│ extracts messages, writes │
│ JSON to inbox │
│ ~/.contextforge/inbox/ │
│ session-<id>-<ts>.json │
└──────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ 5. MCP Server processInbox() │
│ runs on startup + before │
│ each resource read │
└──────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ 6. Extractor (rule-based, no LLM) │
│ extracts entities, relations, │
│ facts from messages │
└──────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ 7. SQLite Database │
│ ~/.contextforge/contextforge.db │
│ Entities, Facts, Relations │
│ stored permanently │
└─────────────────────────────────────┘Read Path (agent queries)
┌─────────────────────────────────────┐
│ 1. New conversation starts │
│ IDE auto-reads MCP resource │
│ contextforge://workspace/... │
└──────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ 2. MCP Server queries SQLite DB │
│ Returns entities, facts, │
│ relationships for workspace │
└──────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ 3. Knowledge injected into agent │
│ context — agent sees past │
│ decisions, patterns, errors │
│ before first user message │
└──────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ 4. During conversation, agent │
│ calls search_memory, add_fact │
│ on demand via MCP tools │
└─────────────────────────────────────┘Inbox Format
Each file in ~/.contextforge/inbox/ is a JSON document:
{
"sessionId": "abc123-...",
"workspace": "/Users/you/src/my-project",
"title": "Fix auth middleware bug",
"messages": [
{ "role": "user", "content": "The login endpoint returns 401..." },
{ "role": "assistant", "content": "The JWT expiry check in auth.ts..." }
],
"capturedAt": 1776885043000
}The MCP server reads this, runs the Extractor, ingests into the graph DB, and deletes the file. Failed files are renamed to .error for debugging.
Three pieces, three purposes
Piece | What it does | Where it lives |
MCP config | Tells the IDE where to find the server binary |
|
Agent instructions | Tells the agent when and how to call tools + when to save |
|
Capture extension | Automatically writes conversations to inbox for MCP processing | VS Code extension |
The capture extension is optional — without it, the agent still saves conversations via instructions. The extension adds reliability (auto-capture) and catches conversations where the agent forgot to call save_conversation.
Why this architecture?
MCP protocol — works with any IDE that supports MCP, no custom plugins needed
Single binary — no Node.js, no npm install, no runtime dependencies for end users
One global database — all workspaces write to the same graph, so agents remember context from any project
stdio transport — the IDE starts/stops the process automatically, no port management
No LLM required — extraction is rule-based, works offline, zero API costs
MCP Tools & Resources
The MCP server exposes 8 tools (agent calls on demand) and 1 resource template (IDE auto-attaches to context).
Resource: Workspace Knowledge (auto-injected)
URI template: contextforge://workspace/{workspace_path}The IDE reads this resource automatically and injects it into the agent's context at the start of every conversation. The agent doesn't need to call anything — the IDE attaches the workspace knowledge before the first message.
This is what makes it work with any model, including cheaper ones that can't reliably follow tool-calling instructions. The knowledge is just... there.
What the IDE does | What the agent sees |
Calls | (nothing, this is invisible) |
Calls | Agent's context now includes all entities, facts, and relationships from past conversations |
Tools (agent calls on demand)
search_memory
Search the knowledge graph for entities (files, functions, libraries, errors, decisions, patterns). Use this to recall past work, decisions, and context from previous conversations across all workspaces.
Parameter | Required | Description |
| Yes | Entity name or partial name (e.g. |
| No | Filter by entity type: |
| No | Filter to a specific workspace path |
| No | Graph traversal depth (default: 2) |
| No | Max results (default: 20) |
get_workspace_context
Get all known entities, relationships, and facts for a workspace. Use this at the start of a conversation to load relevant context from past work.
Parameter | Required | Description |
| Yes | Workspace path to get context for |
| No | Max entities to return (default: 200, override with |
save_conversation
Save a completed conversation. Extracts entities, relationships, and facts into the knowledge graph. Raw text is discarded after extraction. Call this when a meaningful conversation ends.
Parameter | Required | Description |
| Yes | Workspace path where the conversation took place |
| No | Short title summarizing the conversation |
| Yes | Array of |
add_fact
Store a specific fact about an entity. Use this to record decisions, patterns, conventions, or other knowledge that should persist.
Parameter | Required | Description |
| Yes | Name of the entity (file, function, service, etc.) |
| Yes | Type of entity |
| Yes | Workspace path |
| Yes | Fact key (e.g. |
| Yes | Fact value |
get_rally_work_item
Fetch Rally work item details by FormattedID (for example US12345 or TF6789).
Parameter | Required | Description |
| Yes | Rally FormattedID to fetch |
| No | Include Description/Notes text in the response (default: |
| No | Optional Rally workspace ref (for example |
| No | Optional Rally project ref (for example |
memory_status
Show how much knowledge is stored across all workspaces. Returns entity, fact, and relation counts per workspace along with timestamp ranges.
No parameters.
cleanup_memory
Remove old knowledge by time range. Useful for clearing stale data without deleting everything.
Parameter | Required | Description |
| Yes | Delete knowledge older than this many days |
| No | Limit cleanup to a specific workspace (default: all workspaces) |
forget_workspace
Completely remove all knowledge for a workspace — entities, facts, relations, and conversation metadata.
Parameter | Required | Description |
| Yes | Workspace path to forget |
Knowledge Graph Design
The database uses SQLite with better-sqlite3 (WAL mode), sqlite-vec for vector search, and FTS5 for full-text search. All data is stored in a single file.
Node types
Node Table | Properties | Purpose |
| id, type, name, workspace, metadata, createdAt, updatedAt | Files, functions, libraries, errors, decisions, patterns, etc. |
| id, key, value, confidence, sourceConversationId, createdAt, updatedAt | Key-value knowledge about an entity |
| id, workspace, projectName, ide, title, startedAt, endedAt | Metadata only — no raw text stored |
Edge types
Edge Table | From → To | Purpose |
| Entity → Entity | Typed relationships (uses, depends_on, tests, caused_by, etc.) |
| Entity → Fact | Links facts to their entity |
| Entity → Conversation | Tracks which conversations referenced an entity |
Entity types
file, function, class, service, library, pattern, error, decision, config, endpoint, test
Relation types stored in RELATES_TO edges
uses, depends_on, modifies, tests, calls, caused_by, fixed_by, replaces, contains, implements, configures
Example queries (Cypher)
-- "What do we know about auth.ts?"
MATCH (e:Entity {name: 'auth.ts'})-[r:RELATES_TO]->(related:Entity)
RETURN e, r, related
-- "What libraries does the project use?"
MATCH (e:Entity {type: 'library', workspace: '/my/project'})
RETURN e.name
-- "What errors have been fixed?"
MATCH (err:Entity {type: 'error'})-[r:RELATES_TO {type: 'fixed_by'}]->(fix:Entity)
RETURN err.name, fix.name
-- "Everything about JWT" (2-hop traversal)
MATCH (e:Entity)-[*1..2]-(related:Entity)
WHERE e.name CONTAINS 'JWT'
RETURN e, relatedWhy graph over flat storage?
The agent doesn't need to use the same words the user used. The graph stores entities and relationships, not text blobs:
User says: "fix login bug"
│
Graph resolves: "login" → login.ts → auth.ts → JWT expiry bug → fix applied
(traverses relationships, not keyword matching)No full-text search index needed. No embedding model needed. Just graph traversal.
Query resolution — how search_memory finds the right entity
When the user asks "Why did we choose JWT?", here's the exact code path that resolves the query to a graph answer:
┌─────────────────────────────────────┐
│ 1. User asks: │
│ "Why did we choose JWT?" │
└──────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ 2. Agent parses intent │
│ Keyword: JWT │
│ Intent: decision / reason │
└──────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ 3. Agent calls search_memory │
│ query='JWT', depth=2, limit=20 │
└──────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ 4. mcp.ts search_memory handler │
│ Builds GraphQuery: │
│ entityName = 'JWT' │
└──────────────┬──────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────┐
│ database.ts → query() │
│ │
│ ┌────────────────────────────────────────────────────┐ │
│ │ Step 1: Find root entities │ │
│ │ MATCH (e:Entity) │ │
│ │ WHERE e.name CONTAINS 'JWT' │ │
│ │ ORDER BY e.updatedAt DESC │ │
│ │ LIMIT 20 │ │
│ │ │ │
│ │ Matches: │ │
│ │ [library] JWT │ │
│ │ [decision] JWT instead of sessions │ │
│ │ [error] JWT expiry bug │ │
│ └────────────────┬───────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────────────────────┐ │
│ │ Step 2: Walk relationships (depth=2) │ │
│ │ For each root entity: │ │
│ │ MATCH (a)-[r:RELATES_TO*1..2]->(b) │ │
│ │ WHERE a.id = rootId │ │
│ │ │ │
│ │ Discovers connected entities: │ │
│ │ auth.ts, jsonwebtoken, login.ts, │ │
│ │ auth.test.ts ... │ │
│ └────────────────┬───────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────────────────────┐ │
│ │ Step 3: Get direct relations │ │
│ │ Between all found entity IDs: │ │
│ │ MATCH (a)-[r:RELATES_TO]->(b) │ │
│ │ │ │
│ │ auth.ts --uses--> JWT │ │
│ │ auth.test.ts --tests--> auth.ts │ │
│ │ error --caused_by--> auth.ts │ │
│ └────────────────┬───────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌────────────────────────────────────────────────────┐ │
│ │ Step 4: Get facts │ │
│ │ For each entity ID: │ │
│ │ MATCH (e)-[:HAS_FACT]->(f) │ │
│ │ │ │
│ │ decision entity → │ │
│ │ key = 'reason' │ │
│ │ value = 'scales better than sessions' │ │
│ └────────────────┬───────────────────────────────────┘ │
└───────────────────┼──────────────────────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ 5. mcp.ts formats GraphResult │
│ into text response: │
│ │
│ [library] JWT (/my/project) │
│ [decision] JWT instead of sessions │
│ reason: scales better │
│ │
│ Relationships: │
│ auth.ts --uses--> JWT │
│ auth.test.ts --tests--> auth.ts │
└──────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ 6. Agent synthesizes answer: │
│ "We chose JWT over sessions │
│ because it scales better. │
│ It's used in auth.ts." │
└─────────────────────────────────────┘If no entities match "JWT" in Step 1, the agent gets No entities found matching "JWT" and responds that it has no record of that decision.
Key details:
Substring matching — the query uses
e.name CONTAINS 'JWT', not semantic search. The entity name must literally contain the search term.No ranking — all matching entities are returned sorted by
updatedAt DESC. A[decision]entity with the "reason" fact might appear alongside[file]and[library]entities.Graph traversal — the 2-hop walk from root entities pulls in connected files, libraries, and errors, giving the agent a subgraph of related context.
Agent synthesis — the MCP server returns raw graph data. The agent (LLM) is responsible for picking the relevant pieces and forming a coherent answer.
Extraction Engine
The Extractor class uses rule-based pattern matching — no LLM, no API keys, no internet connection required.
What it extracts
Category | How it works |
File references | Regex matching file paths with known extensions ( |
Library imports | Matches |
Function/class names | Matches |
Error patterns | Matches |
Decisions | Matches "I'll use X because Y", "X instead of Y", "we should X" patterns |
How relations are built
Relation | Detection method |
File → uses → Library | Both mentioned within 500 chars of each other |
TestFile → tests → SourceFile | File name contains |
Error → caused_by → File | Error and file mentioned within 500 chars |
File → contains → Function | Function and file mentioned within 500 chars |
Deduplication
Entities are keyed by
type + name + workspace— same entity is updated, not duplicatedRelations are keyed by
source + target + type— existing relations get their context updatedFacts are keyed by
entity + key— new values overwrite old ones with updated confidence scores
Configuration
Environment variables
Variable | Default | Description |
|
| Override database path |
|
| Max entities returned by |
External sources (Rally, GitHub, Knowledge Hub)
ContextForge is a local memory tool only — it does not connect to Rally, GitHub, or the Knowledge Hub itself. Those are separate MCP servers the agent connects to directly, each added as its own entry in VS Code's MCP config. See the "Connect the other MCP sources" step in SETUP-MAC.md / SETUP-WINDOWS.md. Rally is used read-only (lookup/search/hierarchy).
Data Storage
All data is stored locally:
~/.contextforge/
├── contextforge # MCP server binary
├── contextforge.db # SQLite database (all workspaces, all IDEs)
├── models/ # ONNX embedding model (optional, for vector search)
│ └── Xenova/all-MiniLM-L6-v2/
├── inbox/ # Conversations queued by capture extensions
│ ├── <session-id>.json # Pending conversations (processed on next MCP call)
│ └── .processed # Log of already-processed session IDs
└── node_modules/ # Native addons
└── better-sqlite3/ # SQLite native binding
# Agent instructions (VS Code / Cursor)
~/Library/Application Support/Code/User/prompts/
└── contextforge.instructions.md # Tells agents to use memory tools automatically
# MCP config (VS Code / Cursor)
~/Library/Application Support/Code/User/mcp.jsonSize
Binary + native addon: ~69 MB
Typical database size: 1-10 MB for hundreds of conversations
Compare: raw conversation storage would be 100-1000 MB for the same data
Backup
# Simply copy the database file
cp ~/.contextforge/contextforge.db ~/backup/contextforge.dbReset
# Delete the database and start fresh
rm -rf ~/.contextforge/contextforge.db
# The next MCP tool call will create a new empty databaseProject Structure
agent-plugin-optimize-prompt-history/
├── package.json # Root workspace config
├── tsconfig.base.json # Shared TypeScript config
├── packages/
│ ├── core/ # MCP server + graph engine
│ │ ├── src/
│ │ │ ├── index.ts # Public API exports
│ │ │ ├── models.ts # TypeScript types (Entity, Relation, Fact, etc.)
│ │ │ ├── schema.ts # SQLite schema initialization (tables, indexes, FTS5, vec0)
│ │ │ ├── database.ts # MemoryDatabase — SQLite wrapper with graph-like queries
│ │ │ ├── extractor.ts # Rule-based knowledge extraction
│ │ │ ├── mcp.ts # MCP stdio server (entry point for binary)
│ │ │ └── __tests__/
│ │ │ └── extractor.test.ts # Unit tests for extraction (7 tests)
│ │ ├── build.js # Build pipeline (esbuild → obfuscate → pkg → release)
│ │ ├── package.json
│ │ └── tsconfig.json
│ ├── vscode-extension/ # VS Code capture extension
│ │ ├── src/
│ │ │ ├── extension.ts # Main entry point, command registration
│ │ │ ├── capture.ts # Chat session file watcher + debounced capture
│ │ │ ├── sessionParser.ts # JSONL event log parser for Copilot Chat sessions
│ │ │ ├── chatParticipant.ts # @memory chat participant (manual save/search/status)
│ │ │ ├── inbox.ts # Writes to ~/.contextforge/inbox/ queue
│ │ │ └── statusBar.ts # Status bar integration
│ │ └── package.json # Extension manifest with contributionsTech Stack
Component | Technology | License |
Database | SQLite (better-sqlite3 + sqlite-vec + FTS5) | MIT / Public Domain |
MCP protocol | MIT | |
Bundler | esbuild | MIT |
Binary packaging | @yao-pkg/pkg | MIT |
Code protection | javascript-obfuscator | BSD-2 |
Monorepo | npm workspaces | — |
Everything runs 100% locally. No cloud services, no API keys, no telemetry, no internet required.
Why ContextForge vs Native Copilot Chat?
Capability | Copilot Native | ContextForge |
Search current workspace files | ✅ | ✅ |
Remember decisions across conversations | ❌ (forgets on close) | ✅ |
Recall "why did we choose X?" weeks later | ❌ | ✅ |
Headless agents (no IDE) get memory | ❌ | ✅ |
Per-agent isolated memory (test ≠ dev) | ❌ | ✅ |
Works with any LLM (Claude, GPT, Llama) | ❌ (Copilot only) | ✅ |
Time-based queries ("what broke last week?") | ❌ | ✅ |
Survives machine rebuild (backup/restore) | ❌ | ✅ |
Demo Scenarios
Close VS Code, reopen, ask "what was the last decision we made?" — Copilot draws a blank, ContextForge answers immediately.
Spin up a headless test agent — it already knows the codebase conventions from past runs without re-reading everything.
Ask "what errors have we hit in this project?" — ContextForge recalls the full history; Copilot only knows what's in the current code/logs.
Two agents, same repo, different roles — show test-agent has zero knowledge of developer-agent's shortcuts/biases.
The One-Liner Pitch
Copilot searches your code. ContextForge searches your decisions — across sessions, agents, and time.
The workspace search Copilot does is just grepping files. ContextForge stores the reasoning and context that isn't in any file — architecture decisions, past errors, why something was done a certain way.
License
Copyright 2026 Vikas Rai
Licensed under the Apache License, Version 2.0. See LICENSE for the full license text.
This server cannot be deployed
Maintenance
Related MCP Connectors
Shared, governed long-term memory for AI agents across tools and sessions via MCP and REST.
Persistent personal memory for AI assistants — save, search, and recall across every MCP client.
Your memory, everywhere AI goes. Build knowledge once, access it via MCP anywhere.
Persistent AI memory shared across Claude, ChatGPT, coding agents, and compatible MCP clients.
Related MCP Servers
- AlicenseAqualityBmaintenanceProvides persistent memory for AI coding agents via MCP, enabling teams to share and recall facts across sessions. Automatically captures, classifies, and curates knowledge from supported transcript sources.188 npm1AGPL 3.0
- AlicenseNot gradedqualityBmaintenanceProvides a persistent, local-first memory for coding agents over MCP, enabling automatic recall and recording of past work, failures, and decisions to reduce repetition and token usage.MIT
- AlicenseNot gradedqualityAmaintenanceProvides persistent memory for AI coding agents via MCP, enabling agents to store and semantically recall facts, events, and lessons across sessions, all running locally without cloud dependencies.Apache 2.0
- AlicenseNot gradedqualityBmaintenanceProvides a persistent, cross-tool memory layer for AI coding agents via MCP, enabling storage and retrieval of decisions, preferences, and context across different tools and models.5 npm1MIT