Knowledge Graph (AGE)
Sulcus uses Apache AGE — a temporal knowledge graph extension for PostgreSQL — as the structural backbone for memory relationships. Memories are vertices, relationships are edges. Every store, recall, and entity extraction writes to AGE automatically. The graph is self-healing.
Sulcus v2.9 · Apache AGE Knowledge Graph · age_graph capability
Overview
A temporal knowledge graph built on Apache AGE — Postgres-native, self-healing
Every other memory system stores text. Sulcus stores structured knowledge. The AGE graph tracks not just what memories exist, but how they relate to each other — and when those relationships were formed.
This is fundamentally different from vector similarity (which answers "what is near this?") or BM25 text search (which answers "what contains this word?"). The knowledge graph answers: "What does the agent know about X, and how does X connect to everything else?"
Apache AGE runs as a Postgres extension. No separate graph database. Same ACID guarantees. Same backups.
Every store, recall, and entity extraction writes to AGE automatically. The graph is always consistent with the memory store.
Full Cypher query language. Traverse relationships, filter by heat or type, find paths between memories.
SILU — Entity Extraction
Store Intelligence Labeling Unit: GPT-5.4-nano extracts entities and relationships on every store
SILU runs automatically on every memory store. It sends the memory content to GPT-5.4-nano and extracts:
- entities — Named things: people, tools, services, concepts, projects
- relationships — How entities relate: USES, PART_OF, RELATES_TO, DEPENDS_ON
- triples — Entity → Relation → Entity, written to AGE as graph edges
The result: every memory is automatically enriched with structured knowledge. A procedural memory about deployment becomes a node connected to "ACR", "Azure", and "az containerapp" via typed edges.
// Entity triples extracted by SILU from:
// "Deploy: push to ACR then az containerapp update — Azure project"
//
// Extracted triples:
// (Memory) --[HAS_ENTITY]--> (Entity: "ACR", type: "service")
// (Memory) --[HAS_ENTITY]--> (Entity: "az containerapp", type: "tool")
// (Memory) --[HAS_ENTITY]--> (Entity: "Azure", type: "platform")
// (Entity: "ACR") --[PART_OF]--> (Entity: "Azure")
// (Entity: "az containerapp") --[USES]--> (Entity: "ACR")Graph Structure
Vertex and edge schema — what's stored in the AGE graph
Every memory node is a vertex in the AGE graph. Properties mirror the memory store:
| Property | Description |
|---|---|
| id | UUID — matches the memory node ID |
| label | Memory content label (searchable) |
| memory_type | episodic, semantic, procedural, fact, preference |
| namespace | Agent/tenant namespace |
| heat | Current heat value (0–1, updated on tick and recall) |
| base_utility | SIVU utility score (0–1) |
| created_at | ISO timestamp of creation |
| updated_at | ISO timestamp of last update |
Named entities extracted by SILU. Properties: name, type (person, tool, service, concept, platform), namespace, mention_count.
RELATES_TOHAS_ENTITYPART_OFUSESDEPENDS_ONCO_RECALLEDCypher Queries
Full openCypher query language — traverse relationships, filter by heat or type
Find related memories by traversal
// Find all memories related to "deployment" within 2 hops
MATCH (m:Memory)-[r:RELATES_TO*1..2]-(related:Memory)
WHERE m.label CONTAINS 'deploy'
AND m.heat > 0.3
RETURN m, r, related
ORDER BY related.heat DESC
LIMIT 20Find entities extracted from a memory type
// Find all entities extracted from procedural memories
MATCH (m:Memory {memory_type: 'procedural'})-[:HAS_ENTITY]->(e:Entity)
WHERE m.namespace = 'my-agent'
RETURN e.name, e.type, COUNT(m) as mention_count
ORDER BY mention_count DESCTemporal Traversal
Query the graph at a point in time — what did the agent know before a given date?
Every vertex and edge carries timestamps. You can traverse the graph at any point in time — asking questions like "what did this agent know about deployment before the incident?" or "which facts were hot during last quarter?"
This is the AGE advantage over pure vector stores: temporal validity windows. Not just "what is similar" but "what was true at this moment."
// Temporal traversal — find what was known before a date
MATCH (m:Memory)
WHERE m.created_at < '2026-03-01T00:00:00Z'
AND m.heat > 0.2
AND m.namespace = 'my-agent'
RETURN m.label, m.memory_type, m.heat, m.created_at
ORDER BY m.heat DESCSelf-Healing Graph Writes
Every memory operation keeps the AGE graph in sync automatically
The AGE graph is not a separate system you need to maintain. Every operation that touches the memory store also updates the graph:
memory_storeCreates vertex with all properties; SILU extracts entities and writes triplesmemory_recallUpdates vertex heat in AGE; creates CO_RECALLED edges between co-occurring memoriesmemory_deleteRemoves vertex and all incident edges; entities are orphaned (not deleted — may be shared)memory_boostUpdates heat property on vertex immediatelytick (300s)Batch-updates heat on all vertices to match the memory store after decayentity extractionSILU runs asynchronously post-store; adds HAS_ENTITY edges and Entity verticesZero configuration required. The AGE graph writes are built into the memory engine. When you store a memory via SDK, REST API, MCP, or OpenClaw plugin, the graph is updated automatically. The age_graph: true capability flag in the server status confirms the graph backend is active.
REST API
HTTP endpoints for graph queries and entity access
/api/v1/graph/query/api/v1/graph/nodes/:id/api/v1/graph/nodes/:id/entities/api/v1/graph/entities/api/v1/graph/entities/:name/memories# Query the AGE graph via REST
curl -X POST https://api.sulcus.ca/api/v1/graph/query \
-H "Authorization: Bearer sk-..." \
-H "Content-Type: application/json" \
-d '{
"cypher": "MATCH (m:Memory) WHERE m.heat > 0.5 RETURN m.label, m.heat LIMIT 10",
"namespace": "my-agent"
}'
# Get entity relationships for a memory
curl https://api.sulcus.ca/api/v1/graph/nodes/node_01J.../entities \
-H "Authorization: Bearer sk-..."MCP Tools
Query the knowledge graph from any MCP-compatible agent
The Sulcus MCP server exposes graph tools alongside the standard memory tools. Your agents can traverse the knowledge graph, find related memories, and query entity relationships directly from conversation context.
graph_queryget_memory_entitieslist_entitiesfind_related// MCP tool — graph_query
{
"cypher": "MATCH (m:Memory)-[r:RELATES_TO]-(n:Memory) WHERE m.id = 'node_01J...' RETURN n",
"namespace": "my-agent"
}Memory that knows itself.
The AGE knowledge graph is active in Sulcus v2.9. Check your server status for age_graph: true to confirm the graph backend is running. No configuration required — store a memory, and the graph updates automatically.