harness-cortexdb — CortexDB as a harness Memory
Implements [harness_core::Memory] over CortexDB's
MCP server: recall calls memory_search (semantic / lexical vector
retrieval) and write calls memory_save. Drop it in anywhere a
Memory is expected — the MemoryGuide, the experience layer
(harness-experience), a scheduler, etc. — to get semantic recall and a
brain that can be shared with other tools (Claude Code / Codex all use
~/.cortexdb by default).
use harness_cortexdb::CortexdbMemory;
use std::sync::Arc;
// Spawn CortexDB's MCP server; share the global brain (~/.cortexdb).
let mem = Arc::new(CortexdbMemory::connect_stdio("cortexdb-mcp-stdio", &[]).await?);
let recorder = harness_experience::ExperienceRecorder::new(mem); // semantic!
Harness MemoryEntry fields round-trip through CortexDB: content maps to
the memory content; tags + source are stored under CortexDB's
metadata and read back on recall.
Record conversations, then distill them into the graph
Pair the TranscriptRecorder hook
(turns → CortexDB) with periodic [CortexdbMemory::consolidate] (memories →
knowledge graph, server-side):
let mem = Arc::new(CortexdbMemory::connect_stdio("cortexdb-mcp-stdio", &[]).await?
.with_scope("session").with_namespace("myapp-chat"));
// 1. capture every turn as it happens
let (recorder, rx) = harness_experience::TranscriptRecorder::new("sess-1");
harness_experience::spawn_transcript_writer(rx, mem.clone());
let loop_ = AgentLoop::new(model).with_hook(Arc::new(recorder));
// 2. every 10 min, let CortexDB distill accumulated turns into the graph
let m = mem.clone();
tokio::spawn(async move {
let mut tick = tokio::time::interval(std::time::Duration::from_secs(600));
loop { tick.tick().await; let _ = m.consolidate(serde_json::Value::Null).await; }
});