# FURNACE

**Formal Unified Runtime for Network-Augmented Code Engineering**

FURNACE is an AI-powered code generation and analysis system implemented as a Rust [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server. It exposes a suite of tools over MCP's stdio transport that allow LLM clients (Claude, GPT, etc.) to search codebases, generate code, validate constraints, run tests, and auto-apply changes -- all driven by a knowledge graph and tiered search engine.

The binary is fully self-contained: SQLite, KuzuDB (graph), and LanceDB (vectors) are all embedded -- zero external services required.

---

## Installation

### Pre-built binaries

Download from the [latest GitHub release](https://github.com/forgewithfurnace/furnace-releases/releases/latest):

```bash
# macOS (Apple Silicon — also runs on Intel via Rosetta 2)
curl -L https://github.com/forgewithfurnace/furnace-releases/releases/latest/download/furnace-aarch64-apple-darwin.tar.gz | tar xz
sudo mv furnace /usr/local/bin/

# Linux (x86_64)
curl -L https://github.com/forgewithfurnace/furnace-releases/releases/latest/download/furnace-x86_64-unknown-linux-gnu.tar.gz | tar xz
sudo mv furnace /usr/local/bin/

# Windows (x86_64) — download, extract, and add to PATH
# https://github.com/forgewithfurnace/furnace-releases/releases/latest/download/furnace-x86_64-pc-windows-gnu.zip
# Or with PowerShell:
Invoke-WebRequest -Uri https://github.com/forgewithfurnace/furnace-releases/releases/latest/download/furnace-x86_64-pc-windows-gnu.zip -OutFile furnace.zip
Expand-Archive furnace.zip -DestinationPath .
```

### Install via npm (recommended)

```bash
npm install -g furnace-mcp
```

### MCP client config

```json
{"mcpServers": {"furnace": {"command": "npx", "args": ["-y", "furnace-mcp"]}}}
```

### Install from source

```bash
cargo install furnace-mcp
```

> **Build requirements**: Rust 1.70+, CMake, C++20 compiler, protoc (protobuf compiler). On macOS: `brew install cmake protobuf`. On Ubuntu: `apt install cmake protobuf-compiler`.

### Verify installation

```bash
furnace --version
# furnace 0.7.1
```

---

## Client Configuration

### Claude Desktop

Add to `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "furnace": {
      "command": "npx",
      "args": ["-y", "furnace-mcp"]
    }
  }
}
```

### Cursor IDE

Add to Cursor's MCP settings (`.cursor/mcp.json`):

```json
{
  "mcpServers": {
    "furnace": {
      "command": "npx",
      "args": ["-y", "furnace-mcp"]
    }
  }
}
```

### Claude Code

Add via CLI:

```bash
claude mcp add furnace -- npx -y furnace-mcp
```

Or add to `~/.claude/claude_code_config.json`:

```json
{
  "mcpServers": {
    "furnace": {
      "command": "npx",
      "args": ["-y", "furnace-mcp"]
    }
  }
}
```

### VS Code (GitHub Copilot)

Add to `.vscode/mcp.json` in your workspace:

```json
{
  "servers": {
    "furnace": {
      "command": "npx",
      "args": ["-y", "furnace-mcp"]
    }
  }
}
```

### Windsurf

Add to Windsurf's MCP configuration (`~/.codeium/windsurf/mcp_config.json`):

```json
{
  "mcpServers": {
    "furnace": {
      "command": "npx",
      "args": ["-y", "furnace-mcp"]
    }
  }
}
```

### OpenAI Codex CLI

Add to `~/.codex/config.toml`:

```toml
[mcp_servers.furnace]
command = "npx"
args = ["-y", "furnace-mcp"]
```

Or register via CLI:

```bash
codex mcp add furnace -- npx -y furnace-mcp
```

---

## What It Does

FURNACE sits between an LLM and your codebase. When an LLM client connects via MCP, it gets access to 27 tools:

| Tool | Description |
|------|-------------|
| `search_code` | Search the codebase using tiered search (vector, hybrid, agentic) |
| `create_scroll` | Create a SCROLL (specification) from a natural-language intent |
| `add_tasks` | Add tasks to an existing SCROLL with file targets and generated code |
| `execute_scroll` | Execute a SCROLL -- run all tasks, generate code, apply changes |
| `update_scroll` | Update a SCROLL's title, intent, or constraints |
| `update_task` | Update a task's description, target file, type, or status |
| `remove_tasks` | Remove tasks from a SCROLL by task ID |
| `validate_scroll` | Validate constraints, dependencies, types, and breaking changes |
| `reload_scroll` | Reload a SCROLL from its `.scroll` file on disk |
| `list_scrolls` | List all SCROLLs with external link data, optionally filtered by status |
| `get_scroll` | Retrieve a specific SCROLL with tasks, metadata, and external links |
| `analyze_file` | Analyze a file for code quality, complexity, and issues |
| `search_feedback` | Submit satisfaction feedback to improve search strategy learning |
| `list_recipes` | List available prompt template recipes with descriptions |
| `render_recipe` | Render a recipe template with variable substitution |
| `configure_sync` | Configure an external system (Linear, Jira, Notion) for bidirectional sync |
| `link_issue` | Link a SCROLL to an external issue/page with bidirectional reference |
| `push_scroll` | Push a SCROLL's status to an external system |
| `sync_status` | Compute the mapped status between a SCROLL and an external system |
| `list_connections` | List all external system connections with ISO 8601 timestamps |
| `get_metrics` | Get aggregate usage metrics: searches, scrolls, latency, auto-forge runs |
| `furnace_status` | Get server health, recipe count, database stats, and feature suggestions |
| `configure_kb` | Register an external knowledge base (ChromaDB, Pinecone, Weaviate) |
| `query_kb` | Search a knowledge base for relevant documents |
| `sync_kb` | Sync a knowledge base to refresh and assimilate into the graph |
| `ingest_kb` | Push a document to a knowledge base collection |
| `kb_status` | Get detailed status of a specific knowledge base |

### The SCROLL Workflow

A **SCROLL** (Specification for Code Review, Orchestration, Linting, and Logistics) is the central unit of work:

```
Intent ("Add JWT authentication")
    |
    v
[Gandalf] -- Extracts constraints from knowledge graph
    |
    v
[Gimli] -- Generates code per-task using LLM + constraints + recipe templates
    |
    v
[Morpheus] -- Validates: no circular deps, type safety, no breaking changes
    |
    v
[Aragorn] -- Orchestrates parallel execution (DAG topological sort)
    |
    v
[Trinity] -- Generates and runs tests
    |
    v
[Legolas] -- Code review: quality, complexity, security
    |
    v
[AutoForge] -- Auto-apply -> auto-test -> auto-verify -> report
```

### What It Outputs

Every MCP tool call returns a JSON response. Key outputs:

**`search_code`** returns ranked results with file paths, content snippets, and relevance scores:
```json
{
  "results": [
    { "file_path": "src/auth/jwt.rs", "content": "pub fn verify_token...", "relevance_score": 0.92 }
  ],
  "source": "Tier1",
  "latency_ms": 45,
  "cost": 0.0
}
```

**`create_scroll` / `get_scroll`** returns a SCROLL with tasks, constraints, and metadata:
```json
{
  "id": "01HX...",
  "title": "Add JWT authentication",
  "intent": "Add JWT authentication to the API",
  "status": "Completed",
  "cleanup_after": "2026-02-08T16:00:00Z",
  "constraints": [
    { "constraint_type": "Must", "description": "Follow ErrorWithCode pattern", "pattern": "ErrorWithCode" }
  ],
  "tasks": [
    { "id": "01HX...", "description": "Create JWT middleware", "target_file": "src/auth/jwt.rs", "task_type": "Create" }
  ]
}
```

**`validate_scroll`** returns a validation report:
```json
{
  "scroll_id": "01HX...",
  "is_valid": true,
  "constraint_violations": [],
  "circular_dependencies": [],
  "type_errors": [],
  "breaking_changes": []
}
```

**`execute_scroll`** returns an execution report with per-task status, test results, and code analysis.

### How to Use the Output

1. **As an MCP server**: Connect any MCP-compatible client (Claude Desktop, Cursor, Codex) to FURNACE. The client discovers tools via `tools/list` and invokes them via `tools/call`. Responses are JSON wrapped in MCP content blocks.

2. **Direct binary**: Run `furnace` and send JSON-RPC messages on stdin, read responses on stdout. Logs go to stderr.

---

## Project Structure

```
furnace/
├── Cargo.toml                          # Dependencies and project metadata
├── README.md                           # This file
├── LICENSE                             # MIT license
├── Design/                             # 18 LLD specification documents (v4.0)
│
└── src/
    ├── main.rs                 (784)   # Entry point: CLI flags, terminal detection, rmcp stdio transport wiring, startup cleanup
    ├── lib.rs                   (10)   # Library root (re-exports)
    ├── config.rs               (452)   # FurnaceConfig, SearchConfig (w/ tier costs), DatabaseConfig
    ├── error.rs                 (57)   # FurnaceError enum (13 variants)
    ├── types.rs                (499)   # Domain types: Scroll (w/ cleanup_after), Task, CleanupStats, LearnedStrategy, etc.
    │
    ├── db/                    (2391)   # Database layer
    │   ├── mod.rs                      #   Re-exports
    │   ├── sqlite.rs                   #   SQLite: scrolls, tasks, search_queries, learned_strategies,
    │   │                               #   cleanup (TTL sweep), daily_spend persistence
    │   ├── lancedb.rs                  #   LanceDB: embedded vector store (cosine similarity)
    │   └── kuzu.rs                     #   KuzuGraph: embedded graph database (Cypher queries, INFORMS edges)
    │
    ├── search/                (5382)   # Tiered search engine
    │   ├── mod.rs                      #   Re-exports
    │   ├── orchestrator.rs             #   SearchOrchestrator: classify -> strategize -> search -> judge,
    │   │                               #   async KB graph assimilation with dedup cache
    │   ├── query_classifier.rs         #   LLM-based query type classification
    │   ├── strategy_selector.rs        #   Adaptive strategy selection with exploration/exploitation,
    │   │                               #   confidence thresholds (30 samples, 60% success rate)
    │   ├── cache.rs                    #   TTL-based result cache with LRU eviction
    │   ├── cost_optimizer.rs           #   Persistent daily budget (SQLite), configurable tier costs,
    │   │                               #   auto UTC date rollover
    │   ├── tier1_vector.rs             #   Tier 1: fast vector similarity search
    │   ├── tier2_hybrid.rs             #   Tier 2: vector + keyword + graph hybrid
    │   ├── tier3_agentic.rs            #   Tier 3: LLM-driven deep agentic search
    │   ├── result_judge.rs             #   LLM-based result quality assessment
    │   ├── metrics.rs                  #   Temporal-decay metrics (14d half-life), composite success
    │   │                               #   scoring (results 40% + satisfaction 40% + latency 20%)
    │   ├── freshness.rs                #   File freshness tracking and reindex queue
    │   └── agentic/           (1615)   #   Agentic search subsystem
    │       ├── mod.rs                  #     Re-exports
    │       ├── search.rs               #     AgenticSearch: multi-round grep + LLM reasoning
    │       ├── plan_parser.rs          #     LLM response -> SearchPlan extraction
    │       ├── grep_executor.rs        #     Safe regex grep with path traversal protection
    │       ├── result_ranker.rs        #     LLM-based result re-ranking
    │       ├── deduplicator.rs         #     File-level deduplication (keep highest score)
    │       ├── hybrid.rs               #     Hybrid search combining vector + grep
    │       └── deep.rs                 #     Deep iterative search with follow-up queries
    │
    ├── agents/               (10276)   # AI agent components
    │   ├── mod.rs                      #   Re-exports
    │   ├── gandalf/           (1061)   #   Constraint Extractor
    │   │   └── mod.rs                  #     Extract constraints from graph, build context, validate
    │   ├── gimli/             (1241)   #   Code Generator
    │   │   └── mod.rs                  #     LLM prompt building, code generation, constraint validation
    │   ├── trinity/            (885)   #   Test Generator
    │   │   └── mod.rs                  #     Generate tests, parse results (cargo/pytest/jest), suggest fixes
    │   ├── legolas/           (1167)   #   Code Reviewer
    │   │   └── mod.rs                  #     Static analysis: dead code, secrets, nesting, complexity
    │   ├── morpheus/          (2175)   #   Validator
    │   │   ├── mod.rs                  #     Orchestrate all validation, generate report
    │   │   ├── constraint_validator.rs #     Must/MustNot/Should/ShouldNot constraint checking
    │   │   ├── dependency_checker.rs   #     Tarjan's SCC for circular dependency detection
    │   │   ├── type_validator.rs       #     Type reference validation against graph
    │   │   └── breaking_change_detector.rs # Dependent file impact analysis
    │   ├── aragorn/           (1542)   #   Execution Orchestrator
    │   │   └── mod.rs                  #     DAG builder, DFS cycle detection, Kahn's topo sort,
    │   │                               #     parallel execution with semaphore, retry + backoff
    │   └── elrond/            (1733)   #   Lifecycle Manager
    │       └── mod.rs                  #     Multi-language regex parser (25+ languages),
    │                                   #     workspace scanning, graph + vector indexing
    │
    ├── autoforge/             (2214)   # Automated workflow engine
    │   ├── mod.rs                      #   Re-exports
    │   └── workflow.rs                 #   Auto-apply (fs writes), auto-test (process runner),
    │                                   #   auto-verify (regex security/quality scan),
    │                                   #   batch_execute (consolidated approval), reporting
    │
    ├── sync/                 (1227)   # Bidirectional sync bridge
    │   ├── mod.rs                      #   Re-exports
    │   ├── types.rs                    #   ExternalSystem, ExternalRef, SyncDirection, SyncResult
    │   ├── credentials.rs              #   Thread-safe in-memory credential store (OS keyring)
    │   ├── mapper.rs                   #   ScrollStatus ↔ Linear/Jira/Notion status mapping
    │   └── bridge.rs                   #   SyncBridge: link, push, pull, sync_status, event listener
    │
    ├── mcp/                   (4245)   # MCP protocol layer
    │   ├── mod.rs                      #   Re-exports
    │   ├── server.rs                   #   McpServer: tool registry, JSON-RPC dispatch,
    │   │                               #   27 tools, ToolHandler trait
    │   └── handlers.rs                 #   Concrete handlers for all 27 tools
    │
    ├── recipes/               (1177)   # Prompt template system
    │   ├── mod.rs                      #   Re-exports
    │   └── manager.rs                  #   RecipeManager: load/save/render recipes from disk,
    │                                   #   YAML frontmatter, {{variable}} substitution, LLM variants
    │
    ├── knowledge/             (1693)   # Knowledge base integration
    │   ├── mod.rs                      #   Re-exports
    │   ├── types.rs                    #   KBSource, KnowledgeEntry, Concept, KBQueryResult, KBSyncResult
    │   ├── manager.rs                  #   KnowledgeManager: query, sync, assimilate, scatter-gather
    │   ├── connector.rs                #   KBConnector: MCP client connections to external KB servers
    │   ├── assimilator.rs              #   KBAssimilator: KB entries → Knowledge/Concept graph nodes,
    │   │                               #   DEFINES_REQUIREMENT + INFORMS edges
    │   └── search_adapter.rs           #   Convert KBQueryResult → SearchResult for blending
    │
    ├── scroll/                 (613)   # Bidirectional scroll editing
    │   ├── mod.rs                      #   Re-exports
    │   ├── scroll_export.rs            #   ScrollExporter: DB → .scroll JSON file export
    │   └── scroll_import.rs            #   ScrollImporter: .scroll file → DB import (reload from disk)
    │
    └── telemetry/              (813)   # Usage tracking
        ├── mod.rs                      #   Re-exports
        └── tracker.rs                  #   JSONL event logging, statistics, export, anonymous UUID
```

**Total: 68 source files, ~32,100 lines of Rust**

---

## Architecture

```
┌─────────────────────────────────────────────────────┐
│                   MCP Client (LLM)                  │
│         (Claude Desktop, Cursor, Codex CLI)         │
└──────────────────────┬──────────────────────────────┘
                       │ JSON-RPC over stdio
                       ▼
┌─────────────────────────────────────────────────────┐
│                  FurnaceHandler                      │
│            (rmcp ServerHandler impl)                 │
│                                                     │
│  ┌───────────────────────────────────────────────┐  │
│  │              McpServer                        │  │
│  │  27 tools: search, scrolls, recipes, sync,    │  │
│  │  knowledge bases, metrics, status              │  │
│  └──────────────────┬────────────────────────────┘  │
│                     │                               │
│  ┌──────────────────┼────────────────────────────┐  │
│  │            Agent Pipeline                     │  │
│  │                                               │  │
│  │  Gandalf ─> Gimli ─> Morpheus ─> Aragorn      │  │
│  │  (constraints) (codegen) (validate) (execute)  │  │
│  │                                               │  │
│  │  Trinity (tests)  Legolas (review)            │  │
│  │  Elrond (indexing) AutoForge (auto-apply)     │  │
│  └──────────────────┬────────────────────────────┘  │
│                     │                               │
│  ┌──────────────────┼────────────────────────────┐  │
│  │          Search Engine                        │  │
│  │                                               │  │
│  │  Tier 1: Vector (LanceDB, <100ms)             │  │
│  │  Tier 2: Hybrid (vector + keyword + graph)    │  │
│  │  Tier 3: Agentic (LLM-driven grep, <5s)      │  │
│  │                                               │  │
│  │  + Cache, Cost Optimizer (persistent budget),  │  │
│  │    Adaptive Learning (temporal decay + explore) │  │
│  └──────────────────┬────────────────────────────┘  │
│                     │                               │
│  ┌──────────────────┴────────────────────────────┐  │
│  │            Storage Layer (all embedded)        │  │
│  │                                               │  │
│  │  SQLite: scrolls (TTL), tasks, metrics, spend  │  │
│  │  KuzuDB: knowledge graph (files, deps, KB)    │  │
│  │  LanceDB: vector embeddings (cosine search)   │  │
│  └───────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────┘
```

### Key Design Decisions

- **Tiered search escalation**: Tier 1 (vector) is tried first for speed. If results are insufficient, Tier 2 (hybrid) is tried, then Tier 3 (agentic). This keeps most queries fast and cheap.
- **Advanced adaptive strategy learning**: SearchMetrics uses exponentially-weighted temporal decay (14-day half-life) to favor recent search results. A composite success metric blends result count (40%), user satisfaction (40%), and latency bonus (20%). Counter-based exploration (10% rate) prevents strategy ossification, and confidence thresholds (30 samples, 60% success rate) gate learned strategies.
- **Persistent cost optimization**: CostOptimizer tracks daily spend in SQLite (micro-dollar precision) with configurable tier costs and automatic UTC date rollover. Budgets survive server restarts.
- **Lifecycle cleanup with TTL**: Completed/Failed SCROLLs receive a soft TTL (`cleanup_after = now + 1 day`). Expired scrolls and their children are swept on startup. Search queries older than 90 days are pruned automatically.
- **Deep KB graph assimilation**: When knowledge base results are blended into search, they are asynchronously assimilated into the KuzuDB knowledge graph (Knowledge nodes, Concept nodes, DEFINES_REQUIREMENT/INFORMS edges). A session-level dedup cache prevents redundant graph writes.
- **DAG-based execution**: Aragorn builds a dependency graph from SCROLL tasks and executes them in parallel using Kahn's topological sort with a bounded semaphore.
- **Regex-based parsing**: Elrond parses 25+ languages using regex patterns instead of tree-sitter, keeping the dependency footprint minimal.
- **Embedded databases**: All three databases (SQLite, KuzuDB, LanceDB) compile into the binary. Zero external services, zero runtime dependencies beyond the OS.
- **MCP over stdio**: All communication uses JSON-RPC over stdin/stdout. Tracing logs go to stderr.

---

## Bidirectional Sync Bridge

FURNACE includes a sync bridge for linking SCROLLs to external project management tools. The bridge maps SCROLL lifecycle states to external statuses bidirectionally.

### Supported Systems

| System | Status Mapping | Direction |
|--------|---------------|-----------|
| **Linear** | Draft→backlog, InProgress→in_progress, Completed→done, Failed→cancelled | Push / Pull |
| **Jira** | Draft→To Do, InProgress→In Progress, Completed→Done, Failed→Won't Do | Push / Pull |
| **Notion** | Draft→Not Started, InProgress→In Progress, Completed→Done | Push / Pull |

### Components

| Module | Description |
|--------|-------------|
| `sync::types` | `ExternalSystem`, `ExternalRef`, `SyncDirection`, `SyncResult` types |
| `sync::credentials` | Thread-safe in-memory credential store (`store_token`, `get_token`, `remove_token`) |
| `sync::mapper` | Bidirectional status mapping between ScrollStatus and external system statuses |
| `sync::bridge` | `SyncBridge` core: link scrolls to external issues, push/pull status, query sync state |

### Database

External references are stored in the `external_refs` SQLite table with a `(scroll_id, system)` composite primary key, enabling one link per system per SCROLL.

### MCP Tools

All five sync tools are registered and wired with concrete handlers:

| Tool | Description |
|------|-------------|
| `configure_sync` | Store API token and register an external system connection |
| `link_issue` | Link a SCROLL to an external issue with bidirectional reference |
| `push_scroll` | Push SCROLL status to the linked external system |
| `sync_status` | Compute the mapped status without pushing |
| `list_connections` | List all links with ISO 8601 timestamps and direction labels |

`list_scrolls` and `get_scroll` responses are enriched with `external_links` arrays so IDE dashboards can display sync badges automatically.

### Current Status

The sync bridge is implemented with credential management (OS keyring via `keyring` crate), bidirectional status mapping, and persistent link storage. External API calls (HTTP to Linear/Jira/Notion MCP servers) are stubbed -- the bridge validates credentials, maps statuses, and persists links, but does not yet make outbound HTTP requests. Event-driven auto-sync fires on SCROLL state changes via the `ScrollEventListener` trait wired into Aragorn. Planned additions:

- OAuth 2.0/2.1 token acquisition and refresh flow
- Outbound HTTP to remote MCP servers (Linear, Jira, Notion)
- Webhook support for external push notifications

---

## Recipes (Portable Prompt Templates)

Recipes are portable prompt templates stored as Markdown files with YAML frontmatter in `~/.furnace/recipes/`:

```markdown
---
description: "Generate a REST API endpoint"
variables:
  - name: endpoint_path
    description: "The URL path for the endpoint"
    required: true
  - name: method
    description: "HTTP method"
    required: true
    default: "GET"
---
Generate a {{method}} endpoint at {{endpoint_path}} following
the project's existing patterns for error handling and validation.
```

- `{{variable}}` placeholders are substituted at render time
- LLM-specific variants: `recipe_name.claude.md` takes priority over `recipe_name.md` when the LLM is Claude
- Recipes are cached in memory and reloaded on demand
- When a SCROLL specifies a recipe via `create_scroll`, the recipe template is rendered and injected into Gimli's code generation prompt for guided output

### MCP Tools

| Tool | Description |
|------|-------------|
| `list_recipes` | List all available recipes with descriptions and variable info |
| `render_recipe` | Render a recipe template with variable substitution, returns the fully rendered prompt |

---

## Furnace Forge Project (IDE Extensions)

Both VS Code and IntelliJ extensions share the name **Furnace Forge Project** and provide identical visual project tracking capabilities with stunning dashboards.

### VS Code

Source: [furnace-vscode](https://github.com/forgewithfurnace/furnace-vscode)

```bash
cd furnace-vscode && npm install && npm run compile
```

### IntelliJ

Source: [furnace-intellij](https://github.com/forgewithfurnace/furnace-intellij)

```bash
cd furnace-intellij && ./gradlew buildPlugin
```

### Shared Features

| Feature | Description |
|---------|-------------|
| Visual Project Dashboard | Status pipeline (Draft > Valid > Active > Done > Failed), animated metric cards, success rate, SCROLL cards with progress bars |
| External Link Badges | Jira, Linear, and Notion link badges on SCROLL cards (via sync bridge) |
| SCROLL Visual Editor | Form-based editor for `.scroll` files with real SCROLL ID tracking |
| Click-to-View Details | Click/double-click any SCROLL to open full JSON with tasks |
| Code Search | Search codebase via FURNACE's tiered search engine |
| File Analysis | Analyze files for complexity, quality, and security |
| Recipes Browser | Browse prompt template recipes from `~/.furnace/recipes/` |

Both extensions integrate with all 27 MCP tools and communicate with the FURNACE binary over stdio (JSON-RPC). The dashboards display telemetry metrics (searches, latency, scroll counts, auto-forge runs) via the `get_metrics` tool, and external sync link badges via enriched `list_scrolls` responses. Sync commands (configure, link, push) are available from the command palette (VS Code) and settings panel (IntelliJ). Configure the binary path in each extension's settings if `furnace` is not on your PATH.

---

## Building from Source

```bash
# Prerequisites:
#   Rust 1.70+ with cargo
#   CMake + C++20 compiler (for kuzu graph database)
#   protoc (protobuf compiler, for lance-encoding)
#   SQLite is bundled -- no system install needed

# macOS
brew install cmake protobuf

# Ubuntu/Debian
sudo apt install cmake protobuf-compiler

cargo build --release
```

The binary is at `target/release/furnace`.

### Dependencies

| Crate | Purpose |
|-------|---------|
| `rmcp` | MCP protocol server with stdio transport |
| `tokio` | Async runtime |
| `rusqlite` (bundled) | SQLite database |
| `kuzu` | KuzuDB embedded graph database |
| `lancedb` | LanceDB embedded vector database |
| `arrow` / `arrow-array` / `arrow-schema` | Arrow data interchange (for LanceDB) |
| `serde` / `serde_json` | JSON serialization |
| `walkdir` / `glob` / `notify` | Filesystem scanning and watching |
| `regex` | Code parsing and grep execution |
| `tracing` | Structured logging |
| `chrono` | Timestamps |
| `ulid` / `uuid` | ID generation |
| `dashmap` | Concurrent hash maps |
| `toml` / `dirs` | Config file loading |
| `thiserror` / `anyhow` | Error handling |
| `futures` | Async stream processing |

---

## Running

```bash
# Run with default config (~/.furnace/config.toml, or built-in defaults)
furnace

# Run with debug logging to stderr
RUST_LOG=debug furnace

# Run with trace-level logging for a specific module
RUST_LOG=furnace_mcp::search=trace furnace
```

On first run, FURNACE creates `~/.furnace/` with:
- `furnace.db` -- SQLite database for scrolls (with TTL cleanup), tasks, metrics, daily spend
- `graph/` -- KuzuDB graph data
- `vectors/` -- LanceDB vector store
- `recipes/` -- Prompt template directory (with bundled starter recipes)

### Configuration

Create `~/.furnace/config.toml` to override defaults:

```toml
workspace_root = "/path/to/your/project"
data_dir = "/home/user/.furnace"
recipes_dir = "/home/user/.furnace/recipes"

[search]
cache_ttl = 300          # seconds
max_cache_entries = 1000
daily_budget = 1.0       # dollars
min_relevance_score = 0.5
tier1_cost = 0.0         # vector search cost per query
tier2_cost = 0.001       # hybrid search cost per query
tier3_cost = 0.01        # agentic search cost per query

[database]
sqlite_path = "/home/user/.furnace/furnace.db"
kuzu_path = "/home/user/.furnace/graph"
lancedb_path = "/home/user/.furnace/vectors"

[agents]
max_concurrent_tasks = 5
task_timeout = 300       # seconds
max_retries = 3
```

Each project gets its own isolated database directory under `~/.furnace/`. FURNACE uses the `workspace_root` config to scope all data to the current project, so multiple projects never share knowledge graph or vector data.

---

## Tests

471 tests covering every module. All tests are self-contained -- they use embedded databases in temporary directories, requiring no external services.

```bash
# Run all tests
cargo test

# Run tests for a specific module
cargo test agents::aragorn
cargo test search::agentic
cargo test autoforge::workflow

# Run a single test
cargo test test_cycle_detection_simple_cycle

# Run with output (see println! in tests)
cargo test -- --nocapture
```

### Running Specific Test Suites

```bash
# All agent tests
cargo test agents::

# All search tests (including agentic subsystem)
cargo test search::

# All Morpheus sub-validators
cargo test agents::morpheus::

# AutoForge workflow
cargo test autoforge::

# MCP server protocol
cargo test mcp::

# Sync bridge
cargo test sync::

# Recipes and telemetry
cargo test recipes::
cargo test telemetry::
```

---

## License

MIT
