Skip to main content
Glama

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 setup

This 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/contextforge

Model 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 projects

Result: 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

auth.ts, middleware.ts, package.json

Functions/Classes

handleLogin(), UserService, AuthMiddleware

Libraries

express, react, jsonwebtoken

Errors

TypeError: Cannot read property 'id' of undefined

Decisions

"Used JWT instead of sessions because it scales better"

Relationships

auth.ts → uses → jsonwebtoken, auth.test.ts → tests → auth.ts

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: .vscode/mcp.json; global: MCP: Open User Configuration

Project: .github/instructions/contextforge-memory.instructions.md; global: ~/Library/Application Support/Code/User/prompts/contextforge.instructions.md

Claude Code

Project: .mcp.json; global: claude mcp add --scope user ...

Project: CLAUDE.md; global: add the same rules to your user-level Claude instructions

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/contextforge

For 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.vsix

Or: 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:

  1. The agent should call get_workspace_context at the start

  2. Ask: "What do you know about this project from past conversations?" — it should call search_memory

  3. On 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.db

Data 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

mcp.json (VS Code)

Agent instructions

Tells the agent when and how to call tools + when to save

instructions.md (VS Code)

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 resources/list → gets known workspaces

(nothing, this is invisible)

Calls resources/read for current workspace

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

query

Yes

Entity name or partial name (e.g. "auth.ts", "JWT", "LoginService")

type

No

Filter by entity type: file, function, class, service, library, pattern, error, decision, config, endpoint, test

workspace

No

Filter to a specific workspace path

depth

No

Graph traversal depth (default: 2)

limit

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

workspace

Yes

Workspace path to get context for

limit

No

Max entities to return (default: 200, override with CONTEXTFORGE_CONTEXT_LIMIT)

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

workspace

Yes

Workspace path where the conversation took place

title

No

Short title summarizing the conversation

messages

Yes

Array of {role, content} messages

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

entityName

Yes

Name of the entity (file, function, service, etc.)

entityType

Yes

Type of entity

workspace

Yes

Workspace path

key

Yes

Fact key (e.g. "pattern", "convention", "reason", "note")

value

Yes

Fact value

get_rally_work_item

Fetch Rally work item details by FormattedID (for example US12345 or TF6789).

Parameter

Required

Description

reference

Yes

Rally FormattedID to fetch

includeDescription

No

Include Description/Notes text in the response (default: false)

workspaceRef

No

Optional Rally workspace ref (for example /workspace/123456789)

projectRef

No

Optional Rally project ref (for example /project/987654321)

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

olderThanDays

Yes

Delete knowledge older than this many days

workspace

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

workspace

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

Entity

id, type, name, workspace, metadata, createdAt, updatedAt

Files, functions, libraries, errors, decisions, patterns, etc.

Fact

id, key, value, confidence, sourceConversationId, createdAt, updatedAt

Key-value knowledge about an entity

Conversation

id, workspace, projectName, ide, title, startedAt, endedAt

Metadata only — no raw text stored

Edge types

Edge Table

From → To

Purpose

RELATES_TO

Entity → Entity

Typed relationships (uses, depends_on, tests, caused_by, etc.)

HAS_FACT

Entity → Fact

Links facts to their entity

MENTIONED_IN

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, related

Why 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:

  1. Substring matching — the query uses e.name CONTAINS 'JWT', not semantic search. The entity name must literally contain the search term.

  2. 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.

  3. Graph traversal — the 2-hop walk from root entities pulls in connected files, libraries, and errors, giving the agent a subgraph of related context.

  4. 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 (.ts, .py, .java, .go, etc.)

Library imports

Matches import ... from 'x', require('x'), Python import x patterns

Function/class names

Matches function, class, arrow function, method definition patterns

Error patterns

Matches Error:, Exception:, ENOENT, TypeError, Cannot find, etc.

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 .test. or .spec. + matching source file found

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 duplicated

  • Relations are keyed by source + target + type — existing relations get their context updated

  • Facts are keyed by entity + key — new values overwrite old ones with updated confidence scores


Configuration

Environment variables

Variable

Default

Description

CONTEXTFORGE_DB_PATH

~/.contextforge/contextforge.db

Override database path

CONTEXTFORGE_CONTEXT_LIMIT

500

Max entities returned by get_workspace_context and the resource template

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.json

Size

  • 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.db

Reset

# Delete the database and start fresh
rm -rf ~/.contextforge/contextforge.db
# The next MCP tool call will create a new empty database

Project 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 contributions

Tech Stack

Component

Technology

License

Database

SQLite (better-sqlite3 + sqlite-vec + FTS5)

MIT / Public Domain

MCP protocol

@modelcontextprotocol/sdk

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

  1. Close VS Code, reopen, ask "what was the last decision we made?" — Copilot draws a blank, ContextForge answers immediately.

  2. Spin up a headless test agent — it already knows the codebase conventions from past runs without re-reading everything.

  3. Ask "what errors have we hit in this project?" — ContextForge recalls the full history; Copilot only knows what's in the current code/logs.

  4. 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.

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    B
    maintenance
    Provides 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.
    18
    8 npm
    1
    AGPL 3.0
  • A
    license
    Not graded
    quality
    B
    maintenance
    Provides 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
  • A
    license
    Not graded
    quality
    A
    maintenance
    Provides 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
  • A
    license
    Not graded
    quality
    B
    maintenance
    Provides 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 npm
    1
    MIT