Skip to main content
Glama
capatinore

ContextForge

by capatinore
README.md
# ContextForge

**MCP orchestrator that combines [codebase-memory-mcp](https://github.com/DeusData/codebase-memory-mcp) + [headroom](https://github.com/headroomlabs-ai/headroom) into a single pipeline.**

Your AI agent gets a code knowledge graph *and* automatic context compression — in one MCP server.

```
Agent (Claude Code / Codex / Cursor)
  │
  ▼
ContextForge  ←─── single MCP server
  │
  ├─→  codebase-memory-mcp  (graph query: 99% fewer retrieval tokens)
  │           │
  │           ▼
  └─→  headroom             (compression: 60–95% fewer prompt tokens)
            │
            ▼
        LLM Provider
```

---

## Why

| Problem | Without ContextForge | With ContextForge |
|---------|---------------------|-------------------|
| "What calls `processPayment`?" | Agent greps 30 files → ~80K tokens | Graph query → ~500 tokens |
| Tool output bloat | Raw JSON/logs fill context | headroom compresses 60–95% |
| Managing two MCP servers | Two configs, two binaries | One `contextforge run` |
| Session visibility | No insight | `cf_stats` shows real savings |

**Real numbers from the upstream projects:**

- `codebase-memory-mcp`: 5 structural queries used ~3,400 tokens vs ~412,000 via file-by-file grep (99.2% reduction, arXiv:2603.27277)
- `headroom`: 47–92% token reduction on real workloads (GSM8K, TruthfulQA, SQuAD v2 accuracy preserved)

---

## Install

### Prerequisites

| Dependency | Install |
|------------|---------|
| Python 3.10+ | [python.org](https://python.org) |
| Node.js + npm | [nodejs.org](https://nodejs.org) |
| codebase-memory-mcp | `npm install -g codebase-memory-mcp` |
| headroom-ai | `pip install "headroom-ai[all]"` |

### Quick install (Linux / macOS)

```bash
curl -fsSL https://raw.githubusercontent.com/yourusername/contextforge/main/scripts/install.sh | bash
```

### Quick install (Windows PowerShell)

```powershell
iwr -useb https://raw.githubusercontent.com/yourusername/contextforge/main/scripts/install.ps1 | iex
```

### Manual install

```bash
pip install contextforge
# or with uv (recommended):
uv tool install contextforge
```

---

## Setup

### 1. Health check

```bash
contextforge doctor
```

Expected output:
```
✅  Python 3.12
✅  mcp (Model Context Protocol SDK)
✅  headroom-ai
✅  codebase-memory-mcp → /usr/local/bin/codebase-memory-mcp
✅  Everything looks good!
```

### 2. Configure your agent

**Claude Code** (writes `.mcp.json` in current directory):

```bash
contextforge install --target claude
```

**Manual** — add to your `.mcp.json`:

```json
{
  "mcpServers": {
    "contextforge": {
      "command": "contextforge",
      "args": ["run"]
    }
  }
}
```

### 3. Add to CLAUDE.md (recommended)

Paste this into `~/.claude/CLAUDE.md` or your project's `CLAUDE.md`:

```markdown
## ContextForge (code intelligence + compression)

When ContextForge MCP tools are available, **always prefer cbm_* tools over
grep/Glob/Read for structural code questions** — they use 99% fewer tokens.

| Instead of...              | Use...                                 |
|----------------------------|-----------------------------------------|
| Grep for a function name   | `cbm_search_graph(name_pattern="...")`  |
| Reading files for call chains | `cbm_trace_path(function_name="...")` |
| Exploring the architecture | `cbm_get_architecture()`                |
| Text search across files   | `cbm_search_code(query="...")`          |

Index first: `cbm_index_repository(repo_path=".")`. After that, all results
pass through headroom compression automatically. Use `cf_stats` to see savings.
```

---

## Usage

### Index your project (first time)

```
cbm_index_repository(repo_path="/path/to/your/project")
```

This takes seconds to minutes depending on repo size. The Linux kernel (28M LOC) indexes in ~3 minutes.

### Structural queries (all auto-compressed)

```python
# Find all functions matching a pattern
cbm_search_graph(name_pattern=".*Handler.*", label="Function")

# Who calls processPayment?
cbm_trace_path(function_name="processPayment", direction="inbound")

# What would break if I change this?
cbm_get_impact(node_id="<node_id_from_search>")

# High-level architecture view
cbm_get_architecture()

# Full-text search ranked by graph importance
cbm_search_code(query="database connection pool")

# Find unused code
cbm_find_dead_code(confidence="high")
```

### Compression utilities

```python
# Compress arbitrary text before including in context
cf_compress(text="<large log output>", hint="logs")

# Session stats
cf_stats()
# → { "tokens_saved": 42183, "overall_compression_ratio": "78%", ... }

# Reset counters for a new session
cf_reset_stats()
```

---

## Available tools

### CBM tools (14) — routed to codebase-memory-mcp + compressed

| Tool | Description |
|------|-------------|
| `cbm_index_repository` | Index a repo into the knowledge graph |
| `cbm_search_graph` | Search by name pattern (regex) |
| `cbm_search_code` | Full-text + graph-ranked code search |
| `cbm_trace_path` | Trace call paths (inbound/outbound) |
| `cbm_trace_call_path` | Full call chain analysis |
| `cbm_get_architecture` | High-level module/service overview |
| `cbm_get_node_details` | Detailed info on a graph node |
| `cbm_find_dead_code` | Detect unreachable code |
| `cbm_find_similar_code` | Find code clones |
| `cbm_get_impact` | Impact radius of a change |
| `cbm_cypher_query` | Raw Cypher-like graph query |
| `cbm_manage_adr` | Architecture Decision Records |
| `cbm_get_cross_service_links` | HTTP/gRPC/GraphQL cross-service edges |
| `cbm_get_indexing_status` | Indexing progress |

### ContextForge meta tools (3)

| Tool | Description |
|------|-------------|
| `cf_stats` | Session compression statistics |
| `cf_compress` | Compress arbitrary text with headroom |
| `cf_reset_stats` | Reset session counters |

---

## Environment variables

| Variable | Default | Description |
|----------|---------|-------------|
| `CBM_BINARY_PATH` | auto-detect | Path to `codebase-memory-mcp` binary |
| `CONTEXTFORGE_MODEL` | `claude-sonnet-4-6` | Model hint for headroom token counting |
| `CONTEXTFORGE_LOG_LEVEL` | `WARNING` | `DEBUG \| INFO \| WARNING \| ERROR` |

---

## Architecture

```
contextforge/
├── src/contextforge/
│   ├── __init__.py
│   ├── server.py        # FastMCP server — tool definitions + orchestration
│   ├── cbm_client.py    # stdio JSON-RPC client for the CBM binary
│   ├── compressor.py    # headroom-ai wrapper with per-tool profiles + stats
│   └── cli.py           # typer CLI (run / install / doctor / info)
├── config/
│   └── default.toml     # Default configuration
├── scripts/
│   ├── install.sh        # Linux/macOS quick install
│   └── install.ps1       # Windows PowerShell quick install
├── pyproject.toml
└── README.md
```

**Request lifecycle:**

1. Agent calls a `cbm_*` tool via MCP
2. `server.py` forwards the call to `cbm_client.py`
3. `cbm_client.py` sends a JSON-RPC request to the `codebase-memory-mcp` subprocess over stdio
4. The result comes back as structured JSON
5. `compressor.py` runs it through `headroom-ai[compress()]` with a tool-specific profile
6. Compressed result (+ token savings header) is returned to the agent

**Why a subprocess and not a native library?**

`codebase-memory-mcp` is a static C binary — no Python bindings exist. The stdio JSON-RPC protocol is its native interface. This is actually an advantage: zero Python dependency conflicts, and the binary is self-contained.

---

## Contributing

PRs welcome. Key areas:

- **Additional tool profiles** in `compressor.py` — better headroom hints per CBM tool
- **Incremental reindex** — watch file changes and trigger `index_repository` automatically
- **Stats persistence** — save session stats to disk for long-running workflows
- **Docker image** — bundle both binaries in one container

---

## Credits

Built on top of:

- **[codebase-memory-mcp](https://github.com/DeusData/codebase-memory-mcp)** by DeusData — MIT License
- **[headroom](https://github.com/headroomlabs-ai/headroom)** by headroomlabs-ai — Apache 2.0

ContextForge itself is MIT licensed.

---

## License

MIT — see [LICENSE](LICENSE)