Skip to main content

Persistent Memory Subsystem

The Cortex Memory Subsystem is a self-hosted, full-stack persistence layer that provides AI agents with three distinct memory planes: episodic (short-term chat history), semantic (long-term vector-indexed knowledge), and relational (graph-based entity associations). It is composed of four services: mongodb-db, memory-api, memory-web, and mcp-memory.


1. Stack Overview​

memory-web (Nginx, port 80)
└── reverse-proxies /api/* to memory-api:3006
memory-api (Fastify, port 3006)
└── MongoDB 7.0 rs0 (port 27017)
mcp-memory (Fastify MCP adapter, port 8080)
└── delegates all tool calls to memory-api:3006/api/memory/*

Public access: https://memory-dev.tupynambalucas.dev Traffic path: Cloudflare Tunnel -> Traefik (platform namespace) -> memory-web Nginx -> memory-api:3006


2. MongoDB Collections​

Agent memory is divided across three collections to balance document flexibility with graph-level relationship mapping.

A. chat_history (Episodic Memory)​

Tracks linear conversational turns grouped by session identifier.

  • Purpose: Restores immediate conversational context when resuming active threads.
  • Key fields: sessionId / conversationId (aliased), agentId, role (user | assistant | system), content, createdAt.

B. entities (Semantic Memory)​

Represents discrete facts, user preferences, workspace concepts, and documentation chunks with vector embeddings.

  • Purpose: Acts as the primary semantic index. Each document is associated with a 128-dimensional float vector for similarity search.
  • Key fields: name, type (workspace | doc_file | doc_chunk | chat_message), content, embedding (float[128]), metadata.
  • Vector index: MongoDB $vectorSearch aggregation against the embedding field. numCandidates is always set to at least 10x the limit value.

C. relations (Graph Layer)​

Stores directed, weighted edges between entities.

  • Purpose: Creates an associative knowledge graph that links related concepts (e.g., a doc_chunk entity BELONGS_TO a doc_file entity).
  • Relation types: BELONGS_TO, REFERENCES, DEPENDS_ON.
  • Key fields: fromId (ObjectId), toId (ObjectId), relationType, weight (numeric strength).

3. Vector Search and RAG Pipeline​

The retrieval-augmented generation pipeline translates a natural language query into a ranked set of relevant document chunks and connected graph nodes:

[Agent Query]
|
v
[Generate Embedding] POST /api/memory/search
| query -> hash-based float[128] vector
v
[MongoDB $vectorSearch] entities collection, minScore filter
|
v
[Retrieve Top-K Entities]
|
v
[Graph Hydration] GET /api/memory/graph (maxDepth hops)
| relations collection traversal
v
[Compile Context]
|
v
[Return to Agent via mcp-memory search_knowledge tool]

API endpoints involved:

StepEndpointDescription
Semantic searchPOST /api/memory/searchVector similarity query over entities.
Graph traversalGET /api/memory/graphBFS traversal of relations from a root entity.
Store turnPOST /api/memory/chatAppend a message turn to chat_history.
Ingest docsPOST /api/memory/ingest/docsTrigger full documentation re-sync pipeline.

4. Knowledge Graph​

The knowledge graph is built from the documentation corpus and conversational artifacts. After the initial monorepo documentation sync:

  • 300 unique entity nodes
  • 384 graph connections
  • 4,503 text chunks across 534 source files
  • 6,209 total graph edges

Node types and their typical relationships:

From TypeRelationTo Type
doc_chunkBELONGS_TOdoc_file
doc_fileBELONGS_TOworkspace
doc_fileREFERENCESdoc_file
doc_chunkDEPENDS_ONdoc_chunk

5. Documentation Ingestion​

Build-Time Bundling​

The Docusaurus documentation site (docs/) is copied into the memory-api Docker image at build time:

COPY docs ./docs

The .dockerignore for memory-api must explicitly exclude only transient build artifacts while preserving the source MDX files:

docs/node_modules/
docs/.docusaurus/
docs/build/

Startup Auto-Sync​

On every memory-api startup, the service walks the bundled /app/docs directory and ingests all .mdx and .md files. The pipeline is idempotent: a SHA-256 content hash is computed per file before embedding to skip unchanged documents.

Manual Re-Sync​

To trigger re-ingestion without restarting the service:

curl -X POST http://memory-api:3006/api/memory/ingest/docs

Or click the Re-sync Docs button in the Memory Web Dashboard Graph Topology panel.


6. Memory Web Dashboard​

The web dashboard at https://memory-dev.tupynambalucas.dev provides three interactive panels:

  • Graph Topology: Force-directed visualization of all entity nodes and their relations. Supports filtering by node type and relation weight.
  • RAG Playground: Interactive search_knowledge form with similarity score display and raw chunk inspection.
  • Episodic Memory Chat: Browse and replay chat_history turns filtered by sessionId.

Nginx Configuration​

memory-web Nginx performs the following:

  • Serves the React SPA bundle at /.
  • Reverse-proxies all /api/* requests to memory-api:3006.
  • Reverse-proxies /healthz directly to memory-api:3006/health.
  • Sets CSP, X-Frame-Options, and X-Content-Type-Options security headers.

7. MCP Layer (mcp-memory)​

Agent access to the Memory Subsystem is exclusively through the mcp-memory adapter service, which is federated through AgentGateway. The four tools map directly to memory-api endpoints:

ToolMaps toDescription
search_knowledgePOST /api/memory/searchRAG vector search with optional score threshold.
store_episodicPOST /api/memory/chatPersist a conversation turn by session.
query_graphGET /api/memory/graphTraverse entity relationships by depth.
ingest_documentPOST /api/memory/ingest/docsTrigger full docs re-sync pipeline.

For full tool parameter schemas, see the Memory MCP Adapter reference.