Typed Edges in the Knowledge Graph: How Agents Share Causal Chains in MCP-Memory-Service
Typed edges in the knowledge graph are semantic relationships that connect memory nodes, enabling agents to store, query, and reason over causal chains using directional links like causes, fixes, and supports.
The mcp-memory-service repository implements a persistent knowledge graph that records not just isolated memories, but the rich semantic connections between them. These typed edges transform a simple memory store into a causal reasoning engine where agents can trace why events occurred, what fixed them, and how concepts relate across sessions.
What Are Typed Edges in the Knowledge Graph?
Typed edges are first-class relationships defined in the ontology model that describe how two memory nodes semantically interact. Unlike generic "related" links, each type carries specific directional semantics and symmetry constraints.
The system defines six relationship types in src/mcp_memory_service/models/ontology.py:
| Edge type | Symmetry | Meaning |
|---|---|---|
causes |
Asymmetric (directed) | A → B means "A causes B". The reverse edge is not stored. |
fixes |
Asymmetric | A → B means "A fixes B". |
supports |
Asymmetric | A → B means "A supports B". |
follows |
Asymmetric | A → B means "A follows B". |
contradicts |
Symmetric (bidirectional) | A ↔ B means "A contradicts B". |
related |
Symmetric | A ↔ B means "A related to B". |
The ontology definition for causes explicitly marks it as asymmetric with a directional description【/src/mcp_memory_service/models/ontology.py#L166-L167】. This distinction determines how the storage layer writes edges to the database.
How Typed Edges Are Stored in the Graph Database
The graph storage layer in src/mcp_memory_service/storage/graph.py handles the persistence logic for typed edges, respecting their symmetry constraints. For asymmetric relationships like causes, the system stores only the directed edge (A→B), while symmetric types like contradicts are stored bidirectionally to enable efficient traversal from either node【/src/mcp_memory_service/storage/graph.py#L164-L175】.
When an agent creates a causal link, it calls store_association() with the relationship_type parameter:
# Example: an agent records that a recent decision caused an error
await graph_storage.store_association(
source_hash="decision_a",
target_hash="error_b",
confidence=0.9,
tags=["causal"],
relationship_type="causes", # ← typed edge
)
This call inserts a single directed row representing the causal relationship【/src/mcp_memory_service/storage/graph.py#L321-L335】. The storage layer validates the relationship type against the ontology before persisting, ensuring only defined semantic relationships enter the graph.
How Agents Share Causal Chains Using Typed Edges
Agents leverage typed edges to build collective intelligence by recording observations and querying the causal history of events. The system provides multiple mechanisms for traversing these semantic links.
Storing Causal Links
Agents persist causal observations using the causes relationship type to document decision outcomes. This creates a directed acyclic graph of events where each edge represents a causal hypothesis with an associated confidence score.
# src/mcp_memory_service/examples/store_causal_edge.py
import asyncio
from mcp_memory_service.storage.graph import GraphStorage
async def main():
storage = GraphStorage()
await storage.store_association(
source_hash="decision_123",
target_hash="error_456",
confidence=0.95,
tags=["runtime", "crash"],
relationship_type="causes",
)
print("Causal edge stored.")
asyncio.run(main())
Querying Upstream Causes
To understand why an event occurred, agents query incoming edges using the find_connected() method with direction="incoming". This retrieves all memories that directly caused the target event.
async def get_upstream_causes(error_hash: str):
storage = GraphStorage()
incoming = await storage.find_connected(
memory_id=error_hash,
relationship_type="causes",
direction="incoming",
)
return [mem for mem, score in incoming]
# usage
causes = asyncio.run(get_upstream_causes("error_456"))
print("Causes:", causes)
The find_connected API supports filtering by relationship type and direction, enabling agents to traverse specific semantic pathways such as fixes or supports【/src/mcp_memory_service/storage/graph.py#L164-L175】.
Transitive Causal Inference
The Semantic Reasoner extends simple edge traversal by computing transitive closure over causal chains. The infer_transitive() method recursively walks causes edges to find indirect causal relationships up to a specified hop limit.
async def full_causal_chain(target_hash: str, hops: int = 3):
reasoner = InferenceEngine()
chain = await reasoner.infer_transitive(
relationship_type="causes",
max_hops=hops,
start_hash=target_hash,
)
return chain # → {'error_456': ['decision_123', 'observation_9', ...]}
# Example
chain = asyncio.run(full_causal_chain("error_456"))
print(chain)
The reasoner implements this via find_causes(), which calls _get_connected() with direction="incoming" to build the causal graph【/src/mcp_memory_service/reasoning/inference.py#L112-L131】.
Visualizing Causal Chains
The Knowledge-Graph Dashboard renders typed edges in an interactive D3 force-directed graph, allowing users and agents to visually trace causal, fix, and contradiction paths across the memory network【/docs/features/knowledge-graph-dashboard.md#L70-L79】.
Summary
- Typed edges are semantic relationships (
causes,fixes,supports,follows,contradicts,related) defined insrc/mcp_memory_service/models/ontology.pythat connect memory nodes with specific directional semantics. - Asymmetric edges (like
causes) store single directed links, while symmetric edges (likecontradicts) store bidirectional links insrc/mcp_memory_service/storage/graph.py. - Agents create causal chains by calling
store_association()withrelationship_type="causes", and retrieve them usingfind_connected()withdirection="incoming". - The Semantic Reasoner in
src/mcp_memory_service/reasoning/inference.pycomputes transitive causal chains across multiple hops usinginfer_transitive(). - The Knowledge-Graph Dashboard visualizes these chains, enabling shared causal reasoning across agent sessions.
Frequently Asked Questions
What is the difference between asymmetric and symmetric typed edges?
Asymmetric typed edges, such as causes, fixes, supports, and follows, represent directional relationships where the order of nodes matters. The system stores only the directed link (A→B) without implying the reverse. Symmetric edges like contradicts and related represent bidirectional relationships where A→B implies B→A, so the storage layer persists both directions to enable efficient traversal from either node【/src/mcp_memory_service/storage/graph.py#L164-L175】.
How does the Semantic Reasoner infer transitive causal chains?
The Semantic Reasoner implements transitive inference by recursively walking the causes edges using the infer_transitive() method. It starts from a target memory and follows incoming causes edges up to a configurable maximum hop count (default 3), aggregating all indirect causal ancestors. The implementation in src/mcp_memory_service/reasoning/inference.py uses _get_connected() with direction="incoming" to build the complete causal graph for a given event【/src/mcp_memory_service/reasoning/inference.py#L112-L131】.
Can agents share causal chains across different sessions?
Yes, because the knowledge graph persists typed edges in SQLite-vec via the GraphStorage class, causal chains survive beyond individual agent sessions. Any agent—whether built with LangGraph, CrewAI, AutoGen, or a generic HTTP client—can query the stored causes edges using find_connected() or the Semantic Reasoner to reconstruct the causal history of events created by other agents in previous sessions.
What file defines the available typed edge relationships?
The ontology model in src/mcp_memory_service/models/ontology.py defines the six available typed edge relationships: causes, fixes, supports, follows, contradicts, and related. This file specifies each relationship's metadata, including its description, symmetry properties, and directional semantics, which the storage layer references when validating and persisting edges【/src/mcp_memory_service/models/ontology.py#L166-L170】.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →