mirror of
https://github.com/samvallad33/vestige.git
synced 2026-06-08 20:25:16 +02:00
memory_timeline PR #37 exposed the same class of bug in the graph endpoint: the dashboard Graph page (and the /api/graph endpoint it hits) defaulted to centering on the most-connected memory, ran BFS at depth 3, and capped the subgraph at 150 nodes. On a mature corpus this clustered the visualization around a historical hotspot and hid freshly ingested memories that hadn't accumulated edges yet. User-visible symptom: TimeSlider on /graph showing "Feb 21 → Mar 1 2026" when the database actually contains memories through today (Apr 20). **Backend (`crates/vestige-mcp/src/dashboard/handlers.rs`):** - `GraphParams` gains `sort: Option<String>` (accepted: "recent" | "connected", unknown falls back to "recent"). - New internal `GraphSort` enum + case-insensitive `parse()`. - Extracted `default_center_id(storage, sort)` so handler logic and tests share the same branching. Recent path picks `get_all_nodes(1, 0)` (ORDER BY created_at DESC). Connected path picks `get_most_connected_memory`, degrading gracefully to recent if the DB has no edges yet. - Default behaviour flipped from "connected" to "recent" — matches user expectation of "show me my recent stuff". **Dashboard (`apps/dashboard`):** - `api.graph()` accepts `sort?: 'recent' | 'connected'` with JSDoc explaining the rationale. - `/graph/+page.svelte` passes `sort: 'recent'` when no query or center_id is active. Query / center_id paths unchanged — they already carry their own centering intent. **Tests:** 6 new unit tests in `handlers::tests`: - `graph_sort_parse_defaults_to_recent` (None, empty, garbage, "recent", "Recent", "RECENT") - `graph_sort_parse_accepts_connected_case_insensitive` - `default_center_id_recent_returns_newest_node` — ingest 3 nodes, assert newest is picked - `default_center_id_connected_prefers_hub_over_newest` — wire a hub node with 3 spokes, then ingest a newer "lonely" node; assert the hub wins in Connected mode even though it's older - `default_center_id_connected_falls_back_to_recent_when_no_edges` — fresh DB with no connections still returns newest, not 404 - `default_center_id_returns_not_found_on_empty_db` — both modes return 404 cleanly on empty storage Build + test: - cargo test -p vestige-mcp --lib handlers:: → 6/6 pass - cargo test --workspace --lib → 830/830 pass, 0 failed - cargo clippy -p vestige-core -p vestige-mcp --lib -- -D warnings → clean - npm run check → 0 errors, 0 warnings - npm test → 361/361 pass Binary already installed at ~/.local/bin/vestige-mcp (copied from cargo build --release -p vestige-mcp). New Claude Desktop / Code sessions will pick it up automatically when they respawn their MCP subprocess. The dashboard HTTP server on port 3927 needs a manual relaunch from a terminal with the usual pattern: nohup bash -c 'tail -f /dev/null | \ VESTIGE_DASHBOARD_ENABLED=true ~/.local/bin/vestige-mcp' \ > /tmp/vestige-mcp.log 2>&1 & disown |
||
|---|---|---|
| .. | ||
| src | ||
| Cargo.toml | ||
| README.md | ||
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