# Memory MCP - Data Flow Documentation
**Version**: 10.0.0
**Last Updated**: 2026-01-09
---
## Table of Contents
1. [Overview](#overview)
2. [Request Processing Flow](#request-processing-flow)
3. [Entity Operations](#entity-operations)
4. [Relation Operations](#relation-operations)
5. [Search Operations](#search-operations)
6. [Hierarchy Operations](#hierarchy-operations)
7. [Compression Operations](#compression-operations)
8. [Import/Export Operations](#importexport-operations)
9. [Caching Strategy](#caching-strategy)
10. [Error Handling Flow](#error-handling-flow)
---
## Overview
Data flows through Memory MCP in a layered pattern:
```
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β MCP Client Request (JSON-RPC) β
βββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Layer 1: Protocol Layer β
β βββββββββββββββ ββββββββββββββββ ββββββββββββββββββββ β
β β MCPServer βββββΆβ toolHandlers βββββΆβ handleToolCall() β β
β βββββββββββββββ ββββββββββββββββ ββββββββββ¬ββββββββββ β
ββββββββββββββββββββββββββββββββββββββββββββββββββββΌβββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Layer 2: Manager Layer β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β ManagerContext (aliased as KnowledgeGraphManager) β β
β β βββββββββββββββββ βββββββββββββββββ βββββββββββββββ β β
β β β EntityManager β β SearchManager β β IOManager β β β
β β β (+hierarchy β β (+compression β β (import/ β β β
β β β +archive) β β +analytics) β β export) β β β
β β βββββββββ¬ββββββββ βββββββββ¬ββββββββ ββββββββ¬βββββββ β β
β ββββββββββββΌβββββββββββββββββββΌββββββββββββββββββΌββββββββββ β
βββββββββββββββΌβββββββββββββββββββΌββββββββββββββββββΌβββββββββββββββ
β β β
βββββββββββββββββββ¬β΄ββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Layer 3: Storage Layer β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β GraphStorage β β
β β ββββββββββββββββ βββββββββββββββββββββ β β
β β β In-Memory βββββββββββββββΆβ JSONL Files β β β
β β β Cache β read/write β (disk) β β β
β β ββββββββββββββββ βββββββββββββββββββββ β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β MCP Client Response (JSON-RPC) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
```
---
## Request Processing Flow
### General Request Flow
```
1. MCP Client sends JSON-RPC request
β
βΌ
2. MCPServer.registerToolHandlers receives request
β
βΌ
3. handleToolCall(name, args, manager) invoked
β
βΌ
4. toolHandlers[name](manager, args) executed
β
βΌ
5. Manager method called via KnowledgeGraphManager
β
βΌ
6. Specialized manager processes request
β
βΌ
7. GraphStorage handles persistence
β
βΌ
8. formatToolResponse() creates response
β
βΌ
9. Response returned to MCP Client
```
### Example: create_entities Request
```typescript
// 1. Client Request
{
"method": "tools/call",
"params": {
"name": "create_entities",
"arguments": {
"entities": [
{ "name": "Alice", "entityType": "person", "observations": ["Engineer"] }
]
}
}
}
// 2. Handler lookup in toolHandlers
toolHandlers['create_entities'](manager, args)
// 3. Manager delegation
manager.createEntities(args.entities)
// 4. EntityManager processing
entityManager.createEntities(entities)
// 5. Response formatting
formatToolResponse(createdEntities)
// 6. Client Response
{
"content": [{
"type": "text",
"text": "[{\"name\":\"Alice\",...}]"
}]
}
```
---
## Entity Operations
### Create Entities Flow
```
create_entities
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 1. VALIDATION β
β BatchCreateEntitiesSchema.safeParse(entities) β
β βββ Validates: name, entityType, observations, tags β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 2. LOAD GRAPH β
β storage.loadGraph() β
β βββ Returns cached or loads from disk β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 3. FILTER DUPLICATES β
β entities.filter(e => !exists(e.name)) β
β βββ Skip entities that already exist β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 4. CHECK LIMITS β
β if (count > MAX_ENTITIES) throw ValidationError β
β βββ Default limit: 10,000 entities β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 5. TRANSFORM ENTITIES β
β For each entity: β
β βββ Add timestamps (createdAt, lastModified) β
β βββ Normalize tags to lowercase β
β βββ Validate importance (0-10) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 6. PERSIST β
β graph.entities.push(...newEntities) β
β storage.saveGraph(graph) β
β βββ Writes to disk, invalidates cache β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
Return: Entity[]
```
### Delete Entities Flow
```
delete_entities(entityNames)
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 1. LOAD GRAPH β
β storage.loadGraph() β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 2. REMOVE ENTITIES β
β graph.entities = entities.filter(e => !toDelete(e.name)) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 3. REMOVE ORPHANED RELATIONS β
β graph.relations = relations.filter(r => β
β !toDelete(r.from) && !toDelete(r.to)) β
β βββ Cascading delete of related relations β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 4. PERSIST β
β storage.saveGraph(graph) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
Return: void
```
### Add Observations Flow
```
add_observations([{ entityName, contents }])
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 1. LOAD GRAPH β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 2. FOR EACH OBSERVATION REQUEST β
β βββ Find entity by name (throw if not found) β
β βββ Filter out duplicate observations β
β βββ Push new observations to entity.observations β
β βββ Update entity.lastModified β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 3. PERSIST (single write for all updates) β
β storage.saveGraph(graph) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
Return: { entityName, addedObservations }[]
```
---
## Relation Operations
### Create Relations Flow
```
create_relations(relations)
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 1. VALIDATION β
β BatchCreateRelationsSchema.safeParse(relations) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 2. LOAD GRAPH β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 3. FILTER DUPLICATES β
β Check for existing (from, to, relationType) combinations β
β βββ Note: Deferred integrity - entities may not exist β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 4. ADD TIMESTAMPS β
β For each relation: β
β βββ Add createdAt β
β βββ Add lastModified β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 5. PERSIST β
β graph.relations.push(...newRelations) β
β storage.saveGraph(graph) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
Return: Relation[]
```
---
## Search Operations
### Basic Search Flow
```
search_nodes(query, tags?, minImportance?, maxImportance?)
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 1. LOAD GRAPH β
β storage.loadGraph() β cached if available β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 2. TEXT MATCHING β
β For each entity: β
β βββ Match query against entity.name (case-insensitive) β
β βββ Match query against entity.entityType β
β βββ Match query against each observation β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 3. APPLY FILTERS (SearchFilterChain) β
β SearchFilterChain.applyFilters(matches, { β
β tags, minImportance, maxImportance β
β }) β
β βββ Filter by tags (any match) β
β βββ Filter by importance range β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 4. COLLECT RELATIONS β
β Find relations where from OR to matches filtered entities β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
Return: KnowledgeGraph { entities, relations }
```
### Ranked Search Flow (TF-IDF)
```
search_nodes_ranked(query, tags?, min?, max?, limit?)
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 1. LOAD & FILTER β
β Load graph, apply SearchFilterChain filters β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 2. BUILD DOCUMENT CORPUS β
β For each entity, create searchable document: β
β document = name + ' ' + entityType + ' ' + observations β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 3. TOKENIZE QUERY β
β queryTerms = query.toLowerCase().split(/\s+/) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 4. CALCULATE TF-IDF SCORES β
β For each entity: β
β βββ For each query term: β
β β βββ TF = term frequency in document β
β β βββ IDF = log(N / docs containing term) β
β β βββ score += TF Γ IDF β
β βββ Total score = sum of term scores β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 5. SORT & LIMIT β
β results.sort((a, b) => b.score - a.score) β
β results.slice(0, limit) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
Return: SearchResult[] { entity, score, matchedFields }
```
### Boolean Search Flow
```
boolean_search("name:Alice AND (type:person OR observation:engineer)")
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 1. TOKENIZE QUERY β
β Tokens: ['name:Alice', 'AND', '(', 'type:person', 'OR', β
β 'observation:engineer', ')'] β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 2. PARSE TO AST β
β BooleanQueryNode tree: β
β AND β
β βββ FIELD(name, Alice) β
β βββ OR β
β βββ FIELD(type, person) β
β βββ FIELD(observation, engineer) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 3. EVALUATE AST β
β For each entity: β
β βββ Recursively evaluate AST nodes β
β βββ AND: all children must match β
β βββ OR: any child must match β
β βββ NOT: child must not match β
β βββ FIELD: check specific field contains value β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 4. APPLY FILTERS & COLLECT RELATIONS β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
Return: KnowledgeGraph
```
### Fuzzy Search Flow
```
fuzzy_search(query, threshold=0.7)
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 1. LOAD & FILTER β
β Load graph, apply tag/importance filters β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 2. CALCULATE SIMILARITIES β
β For each entity: β
β βββ For each searchable field (name, type, observations): β
β β βββ distance = levenshteinDistance(query, field) β
β β βββ maxLen = max(query.length, field.length) β
β β βββ similarity = 1 - (distance / maxLen) β
β βββ Match if any similarity >= threshold β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 3. COLLECT MATCHES & RELATIONS β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
Return: KnowledgeGraph
```
---
## Hierarchy Operations
### Set Parent Flow
```
set_entity_parent(entityName, parentName)
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 1. LOAD GRAPH β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 2. VALIDATE ENTITY EXISTS β
β if (!entity) throw EntityNotFoundError β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 3. VALIDATE PARENT EXISTS (if not null) β
β if (parentName && !parent) throw EntityNotFoundError β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 4. CYCLE DETECTION β
β wouldCreateCycle(graph, entityName, parentName): β
β βββ Start at parentName β
β βββ Walk up parent chain β
β βββ If we reach entityName β cycle detected β
β βββ If we reach root (no parent) β no cycle β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 5. UPDATE ENTITY β
β entity.parentId = parentName || undefined β
β entity.lastModified = timestamp β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 6. PERSIST β
β storage.saveGraph(graph) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
Return: Entity
```
### Get Descendants Flow (Recursive)
```
get_descendants(entityName)
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 1. LOAD GRAPH & FIND ENTITY β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 2. RECURSIVE TRAVERSAL β
β function collectDescendants(name): β
β βββ children = entities.filter(e => e.parentId === name) β
β βββ For each child: β
β β βββ Add child to results β
β β βββ results.push(...collectDescendants(child.name)) β
β βββ Return results β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
Return: Entity[] (all descendants, depth-first)
```
---
## Compression Operations
### Find Duplicates Flow
```
find_duplicates(threshold=0.8)
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 1. LOAD GRAPH β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 2. BUCKET BY TYPE (Optimization) β
β buckets = Map<entityType, Entity[]> β
β βββ Only compare entities of same type β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 3. PAIRWISE SIMILARITY (within buckets) β
β For each bucket: β
β βββ For each pair (e1, e2): β
β β βββ similarity = calculateEntitySimilarity(e1, e2) β
β βββ If similarity >= threshold β add to duplicate group β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 4. SIMILARITY CALCULATION β
β score = (nameSim Γ 0.4) + (typeSim Γ 0.3) β
β + (obsSim Γ 0.2) + (tagSim Γ 0.1) β
β βββ nameSim: 1 - levenshtein/maxLen β
β βββ typeSim: 1 if exact match, 0 otherwise β
β βββ obsSim: Jaccard(observations1, observations2) β
β βββ tagSim: Jaccard(tags1, tags2) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
Return: string[][] (groups of duplicate entity names)
```
### Merge Entities Flow
```
merge_entities(entityNames, targetName?)
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 1. VALIDATE β
β if (entityNames.length < 2) throw InsufficientEntities β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 2. LOAD & FIND ENTITIES β
β entities = entityNames.map(name => findEntity(name)) β
β if (any missing) throw EntityNotFoundError β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 3. CREATE MERGED ENTITY β
β merged = { β
β name: targetName || entityNames[0], β
β entityType: first.entityType, β
β observations: unique(all observations), β
β tags: unique(all tags), β
β importance: max(all importances), β
β createdAt: earliest createdAt, β
β lastModified: now() β
β } β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 4. TRANSFER RELATIONS β
β For each relation involving merged entities: β
β βββ Update 'from' to point to merged entity β
β βββ Update 'to' to point to merged entity β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 5. REMOVE ORIGINAL ENTITIES β
β graph.entities = entities.filter(e => β
β !entityNames.includes(e.name) || e.name === merged.name β
β ) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 6. PERSIST β
β storage.saveGraph(graph) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
Return: Entity (merged entity)
```
---
## Import/Export Operations
### Export Flow
```
export_graph(format, filter?)
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 1. GET GRAPH DATA β
β if (filter) { β
β graph = searchByDateRange(filter params) β
β } else { β
β graph = loadGraph() β
β } β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 2. FORMAT CONVERSION β
β switch (format): β
β βββ 'json' β JSON.stringify(graph, null, 2) β
β βββ 'csv' β entities CSV + relations CSV β
β βββ 'graphml' β XML graph format β
β βββ 'gexf' β Gephi exchange format β
β βββ 'dot' β Graphviz DOT β
β βββ 'markdown' β Human-readable MD β
β βββ 'mermaid' β Mermaid diagram syntax β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
Return: string (formatted export)
```
### Import Flow
```
import_graph(format, data, mergeStrategy='skip', dryRun=false)
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 1. PARSE INPUT β
β switch (format): β
β βββ 'json' β JSON.parse(data) β
β βββ 'csv' β parseCSV(data) β
β βββ 'graphml' β parseXML(data) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 2. VALIDATE PARSED DATA β
β Validate entities and relations against schemas β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 3. LOAD EXISTING GRAPH β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 4. APPLY MERGE STRATEGY β
β For each imported entity: β
β βββ 'replace' β overwrite if exists β
β βββ 'skip' β ignore if exists β
β βββ 'merge' β combine observations/tags β
β βββ 'fail' β error if any conflict β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 5. PERSIST (unless dryRun) β
β if (!dryRun) storage.saveGraph(mergedGraph) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
Return: ImportResult {
entitiesCreated, entitiesUpdated, entitiesSkipped,
relationsCreated, relationsSkipped, errors
}
```
---
## Caching Strategy
### GraphStorage Cache Flow
```
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β loadGraph() β
βββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββ
β
βββββββββββββ΄ββββββββββββ
β cache !== null ? β
βββββββββββββ¬ββββββββββββ
β± β²
YES NO
β β
βΌ βΌ
ββββββββββββββββββ ββββββββββββββββββββββ
β Return deep β β Read from disk β
β copy of cache β β Parse JSONL lines β
ββββββββββββββββββ β Populate cache β
β Return deep copy β
ββββββββββββββββββββββ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β saveGraph() β
βββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββ
β Write to disk β
β (JSONL format) β
βββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββ
β Invalidate cache β
β cache = null β
β clearAllSearchCaches()β
βββββββββββββββββββββββββ
```
### Cache Characteristics
| Aspect | Behavior |
|--------|----------|
| Cache Population | On first `loadGraph()` call |
| Cache Invalidation | On every `saveGraph()` call |
| Deep Copy | Always returns deep copy (prevents mutation) |
| Search Cache | Cleared when main graph cache invalidates |
| Memory Impact | Full graph held in memory |
---
## Error Handling Flow
### Error Propagation
```
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Manager Layer Errors β
β βββ ValidationError (invalid input) β
β βββ EntityNotFoundError (missing entity) β
β βββ InvalidImportanceError (out of range) β
β βββ CycleDetectedError (hierarchy cycle) β
β βββ InsufficientEntitiesError (merge < 2) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β toolHandlers catch and format β
β try { ... } catch (error) { β
β return formatErrorResponse(error.message) β
β } β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β MCP Error Response β
β { β
β "content": [{ β
β "type": "text", β
β "text": "Error: Entity 'Unknown' not found" β
β }], β
β "isError": true β
β } β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
```
### Validation Error Details
```typescript
// Zod validation provides detailed error paths
{
"errors": [
"entities.0.name: Required",
"entities.0.entityType: String must contain at least 1 character",
"entities.2.importance: Number must be less than or equal to 10"
]
}
```
---
## I/O Optimization Summary
| Operation | Read Ops | Write Ops | Total I/O |
|-----------|----------|-----------|-----------|
| create_entities (batch) | 1 | 1 | 2 |
| delete_entities | 1 | 1 | 2 |
| add_observations (batch) | 1 | 1 | 2 |
| search_nodes | 1 (cached) | 0 | 1 |
| search_nodes_ranked | 1 (cached) | 0 | 1 |
| find_duplicates | 1 (cached) | 0 | 1 |
| merge_entities | 1 | 1 | 2 |
| compress_graph | 1 | 1 | 2 |
| export_graph | 1 (cached) | 0 | 1 |
| import_graph | 1 | 1 | 2 |
**Key Optimization**: Batch operations use single read/write cycle regardless of batch size.
---
**Document Version**: 2.0
**Last Updated**: 2026-01-07
**Maintained By**: Daniel Simon Jr.