vestige/crates/vestige-mcp
Sam Valladares da8c40935e
Some checks are pending
CI / Test (macos-latest) (push) Waiting to run
CI / Test (ubuntu-latest) (push) Waiting to run
CI / Release Build (aarch64-apple-darwin) (push) Blocked by required conditions
CI / Release Build (x86_64-unknown-linux-gnu) (push) Blocked by required conditions
CI / Release Build (x86_64-apple-darwin) (push) Blocked by required conditions
Test Suite / Unit Tests (push) Waiting to run
Test Suite / MCP E2E Tests (push) Waiting to run
Test Suite / User Journey Tests (push) Blocked by required conditions
Test Suite / Dashboard Build (push) Waiting to run
Test Suite / Code Coverage (push) Waiting to run
v2.0.9 "Autopilot" — backend event-subscriber + 3,091 LOC orphan cleanup (#46)
* feat(v2.0.9): Autopilot — backend event-subscriber routes 6 live events into cognitive hooks

The single architectural change that flips 14 dormant cognitive primitives
into active ones. Before this commit, Vestige's 20-event WebSocket bus had
zero backend subscribers — every emitted event flowed to the dashboard
animation layer and terminated. Cognitive modules with fully-built trigger
methods (synaptic_tagging.trigger_prp, predictive_memory.record_*,
activation_network.activate, prospective_memory.check_triggers, the 6h
auto-consolidation dreamer path) were never actually called from the bus.

New module `crates/vestige-mcp/src/autopilot.rs` spawns two tokio tasks at
startup:

1. Event subscriber — consumes the broadcast::Receiver, routes:
   - MemoryCreated  → synaptic_tagging.trigger_prp(CrossReference)
                    + predictive_memory.record_memory_access(id, preview, tags)
   - SearchPerformed → predictive_memory.record_query(q, [])
                    + record_memory_access on top 10 result_ids
   - MemoryPromoted → activation_network.activate(id, 0.3) spread
   - MemorySuppressed → emit Rac1CascadeSwept (was declared-never-emitted)
   - ImportanceScored (composite > 0.85 AND memory_id present)
                    → storage.promote_memory + re-emit MemoryPromoted
   - Heartbeat (memory_count > 700, 6h cooldown)
                    → spawned find_duplicates sweep (rate-limited)
   The loop holds the CognitiveEngine mutex only per-handler, never across
   an await, so MCP tool dispatch is never starved.

2. Prospective poller — 60s tokio::interval calls
   prospective_memory.check_triggers(Context { timestamp: now, .. }).
   Matched intentions are logged at info! level today; v2.5 "Autonomic"
   upgrades this to MCP sampling/createMessage for agent-side notifications.

ImportanceScored event gained optional `memory_id: Option<String>` field
(#[serde(default)], backward-compatible) so auto-promote has the id to
target. Both existing emit sites (server.rs tool dispatch, dashboard
handlers::score_importance) pass None because they score arbitrary content,
not stored memories — matches current semantics.

docs/VESTIGE_STATE_AND_PLAN.md §15 POST-v2.0.8 ADDENDUM records the full
three-agent audit that produced this architecture (2026-SOTA research,
active-vs-passive module audit, competitor landscape), the v2.0.9/v2.5/v2.6
ship order, and the one-line thesis: "the bottleneck was one missing
event-subscriber task; wiring it flips Vestige from memory library to
cognitive agent that acts on the host LLM."

Verified:
  - cargo check --workspace        clean
  - cargo clippy --workspace -- -D warnings  clean (let-chain on Rust 1.91+)
  - cargo test -p vestige-mcp --lib  356/356 passing, 0 failed

* fix(autopilot): supervisor + dedup race + opt-out env var

Three blockers from the 5-agent v2.0.9 audit, all in autopilot.rs.

1. Supervisor loops around both tokio tasks (event subscriber + prospective
   poller). Previously, if a cognitive hook panicked on a single bad memory,
   the spawned task died permanently and silently — every future event lost.
   Now the outer supervisor catches JoinError::is_panic(), logs the panic
   with full error detail, sleeps 5s, and respawns the inner task. Turns
   a permanent silent failure into a transient hiccup.

2. DedupSweepState struct replaces the bare Option<Instant> timestamp. It
   tracks the in-flight JoinHandle so the next Heartbeat skips spawning a
   second sweep while the first is still running. Previously, the cooldown
   timestamp was set BEFORE spawning the async sweep, which allowed two
   concurrent find_duplicates scans on 100k+ memory DBs where the sweep
   could exceed the 6h cooldown window. is_running() drops finished handles
   so a long-dead sweep doesn't block the next legitimate tick.

3. VESTIGE_AUTOPILOT_ENABLED=0 opt-out. v2.0.8 users updating in place
   can preserve the passive-library contract by setting the env var to
   any of {0, false, no, off}. Any other value (unset, 1, true, etc.)
   enables the default v2.0.9 Autopilot behavior. spawn() early-returns
   with an info! log before any task is spawned.

Audit breakdown:
- Agent 1 (internals): NO-GO → fixed (1, 2)
- Agent 2 (backward compat): NO-GO → fixed (3)
- Agent 3 (orphan cleanup): GO clean
- Agent 4 (runtime safety): GO clean
- Agent 5 (release prep): GO, procedural note logged

Verification:
- cargo check -p vestige-mcp: clean
- cargo test -p vestige-mcp --lib: 373 passed, 0 failed
- cargo clippy -p vestige-mcp --lib --bins -- -D warnings: clean

* chore(release): v2.0.9 "Autopilot"

Bump workspace + vestige-core + vestige-mcp + apps/dashboard to 2.0.9.
CHANGELOG [2.0.9] entry + README hero banner rewrite to "Autopilot".

Scope (two commits on top of v2.0.8):
- 0e9b260: 3,091 LOC orphan-code cleanup
- fe7a68c: Autopilot backend event-subscriber
- HEAD (this branch): supervisor + dedup race + opt-out env var hardening

Pure backend release — tool count unchanged (24), schema unchanged,
JSON-RPC shape unchanged, CLI flags unchanged. Only visible behavior
change is the Autopilot task running in the background, which is
VESTIGE_AUTOPILOT_ENABLED=0-gated.

Test gate: 1,223 passing / 0 failed (workspace, no-fail-fast).
Clippy: clean on vestige-mcp lib + bins with -D warnings.
Audit: 5 parallel agents (internals, backward compat, orphan cleanup,
runtime safety, release prep) — all GO after hardening commit.
2026-04-24 02:00:00 -05:00
..
src v2.0.9 "Autopilot" — backend event-subscriber + 3,091 LOC orphan cleanup (#46) 2026-04-24 02:00:00 -05:00
Cargo.toml v2.0.9 "Autopilot" — backend event-subscriber + 3,091 LOC orphan cleanup (#46) 2026-04-24 02:00:00 -05:00
README.md Switch embedding model from BGE to nomic-embed-text-v1.5 2026-01-25 03:11:15 -06:00

Vestige MCP Server

A bleeding-edge Rust MCP (Model Context Protocol) server for Vestige - providing Claude and other AI assistants with long-term memory capabilities.

Features

  • FSRS-6 Algorithm: State-of-the-art spaced repetition (21 parameters, personalized decay)
  • Dual-Strength Memory Model: Based on Bjork & Bjork 1992 cognitive science research
  • Local Semantic Embeddings: nomic-embed-text-v1.5 (768d) via fastembed v5 (no external API)
  • HNSW Vector Search: USearch-based, 20x faster than FAISS
  • Hybrid Search: BM25 + semantic with RRF fusion
  • Codebase Memory: Remember patterns, decisions, and context

Installation

cd /path/to/vestige/crates/vestige-mcp
cargo build --release

Binary will be at target/release/vestige-mcp

Claude Desktop Configuration

Add to your Claude Desktop config (~/Library/Application Support/Claude/claude_desktop_config.json on macOS):

{
  "mcpServers": {
    "vestige": {
      "command": "/path/to/vestige-mcp"
    }
  }
}

Available Tools

Core Memory

Tool Description
ingest Add new knowledge to memory
recall Search and retrieve memories
semantic_search Find conceptually similar content
hybrid_search Combined keyword + semantic search
get_knowledge Retrieve a specific memory by ID
delete_knowledge Delete a memory
mark_reviewed Review with FSRS rating (1-4)

Statistics & Maintenance

Tool Description
get_stats Memory system statistics
health_check System health status
run_consolidation Apply decay, generate embeddings

Codebase Tools

Tool Description
remember_pattern Remember code patterns
remember_decision Remember architectural decisions
get_codebase_context Get patterns and decisions

Available Resources

Memory Resources

URI Description
memory://stats Current statistics
memory://recent?n=10 Recent memories
memory://decaying Low retention memories
memory://due Memories due for review

Codebase Resources

URI Description
codebase://structure Known codebases
codebase://patterns Remembered patterns
codebase://decisions Architectural decisions

Example Usage (with Claude)

User: Remember that we decided to use FSRS-6 instead of SM-2 because it's 20-30% more efficient.

Claude: [calls remember_decision]
I've recorded that architectural decision.

User: What decisions have we made about algorithms?

Claude: [calls get_codebase_context]
I found 1 decision:
- We decided to use FSRS-6 instead of SM-2 because it's 20-30% more efficient.

Data Storage

  • Database: ~/Library/Application Support/com.vestige.mcp/vestige-mcp.db (macOS)
  • Uses SQLite with FTS5 for full-text search
  • Vector embeddings stored in separate table

Protocol

  • JSON-RPC 2.0 over stdio
  • MCP Protocol Version: 2024-11-05
  • Logging to stderr (stdout reserved for JSON-RPC)

License

MIT