Skip to main content
Glama
danielsimonjr

Enhanced Knowledge Graph Memory Server

COMPONENTS.md22.9 kB
# Memory MCP - Component Reference **Version**: 0.47.1 **Last Updated**: 2025-12-02 --- ## Table of Contents 1. [Overview](#overview) 2. [Server Components](#server-components) 3. [Core Components](#core-components) 4. [Search Components](#search-components) 5. [Feature Components](#feature-components) 6. [Utility Components](#utility-components) 7. [Type Definitions](#type-definitions) 8. [Component Dependencies](#component-dependencies) --- ## Overview Memory MCP follows a layered architecture with specialized components: ``` ┌─────────────────────────────────────────────────────────────┐ │ server/ │ MCP protocol handling │ ├─────────────────────────────────────────────────────────────┤ │ core/ │ Central managers and storage │ ├─────────────────────────────────────────────────────────────┤ │ search/ │ Search implementations │ ├─────────────────────────────────────────────────────────────┤ │ features/ │ Advanced capabilities │ ├─────────────────────────────────────────────────────────────┤ │ utils/ │ Shared utilities │ ├─────────────────────────────────────────────────────────────┤ │ types/ │ TypeScript definitions │ └─────────────────────────────────────────────────────────────┘ ``` --- ## Server Components ### MCPServer (`server/MCPServer.ts`) **Purpose**: MCP protocol handling and request routing **Lines**: 67 (reduced from 907 in v0.41.0) ```typescript export class MCPServer { constructor(manager: KnowledgeGraphManager) async start(): Promise<void> } ``` **Responsibilities**: - Initialize MCP SDK server - Register tool list handler (delegates to `toolDefinitions`) - Register tool call handler (delegates to `toolHandlers`) - Start stdio transport **Dependencies**: `toolDefinitions`, `toolHandlers`, `KnowledgeGraphManager` --- ### toolDefinitions (`server/toolDefinitions.ts`) **Purpose**: Schema definitions for all 47 MCP tools **Lines**: ~400 ```typescript export interface ToolDefinition { name: string; description: string; inputSchema: { type: 'object'; properties: Record<string, unknown>; required?: string[]; }; } export const toolDefinitions: ToolDefinition[] ``` **Tool Categories**: | Category | Count | Tools | |----------|-------|-------| | Entity | 4 | create_entities, delete_entities, read_graph, open_nodes | | Relation | 2 | create_relations, delete_relations | | Observation | 2 | add_observations, delete_observations | | Search | 6 | search_nodes, search_nodes_ranked, boolean_search, fuzzy_search, search_by_date_range, get_search_suggestions | | Saved Searches | 5 | save_search, execute_saved_search, list_saved_searches, delete_saved_search, update_saved_search | | Tag Management | 6 | add_tags, remove_tags, set_importance, add_tags_to_multiple_entities, replace_tag, merge_tags | | Tag Aliases | 5 | add_tag_alias, list_tag_aliases, remove_tag_alias, get_aliases_for_tag, resolve_tag | | Hierarchy | 9 | set_entity_parent, get_children, get_parent, get_ancestors, get_descendants, get_subtree, get_root_entities, get_entity_depth, move_entity | | Analytics | 2 | get_graph_stats, validate_graph | | Compression | 4 | find_duplicates, merge_entities, compress_graph, archive_entities | | Import/Export | 2 | export_graph, import_graph | --- ### toolHandlers (`server/toolHandlers.ts`) **Purpose**: Handler implementations for all 47 tools **Lines**: ~200 ```typescript export type ToolHandler = ( manager: KnowledgeGraphManager, args: Record<string, unknown> ) => Promise<ToolResponse>; export const toolHandlers: Record<string, ToolHandler> export async function handleToolCall( name: string, args: Record<string, unknown>, manager: KnowledgeGraphManager ): Promise<ToolResponse> ``` **Pattern**: Registry pattern - handlers registered by tool name **Response Format**: All handlers use `formatToolResponse()` for consistent output --- ## Core Components ### KnowledgeGraphManager (`core/KnowledgeGraphManager.ts`) **Purpose**: Central facade coordinating all graph operations **Pattern**: Facade Pattern with Lazy Initialization ```typescript export class KnowledgeGraphManager { constructor(memoryFilePath: string) // Entity operations async createEntities(entities: Entity[]): Promise<Entity[]> async deleteEntities(entityNames: string[]): Promise<void> async addObservations(...): Promise<...> async deleteObservations(...): Promise<void> // Relation operations async createRelations(relations: Relation[]): Promise<Relation[]> async deleteRelations(relations: Relation[]): Promise<void> // Search operations async searchNodes(query, tags?, minImportance?, maxImportance?): Promise<KnowledgeGraph> async searchNodesRanked(...): Promise<SearchResult[]> async booleanSearch(...): Promise<KnowledgeGraph> async fuzzySearch(...): Promise<KnowledgeGraph> // Hierarchy operations async setEntityParent(entityName, parentName): Promise<Entity> async getChildren(entityName): Promise<Entity[]> async getAncestors(entityName): Promise<Entity[]> async getDescendants(entityName): Promise<Entity[]> // Compression operations async findDuplicates(threshold?): Promise<string[][]> async mergeEntities(entityNames, targetName?): Promise<Entity> async compressGraph(threshold?, dryRun?): Promise<CompressionResult> // Import/Export async exportGraph(format, filter?): Promise<string> async importGraph(format, data, mergeStrategy?, dryRun?): Promise<ImportResult> // Analytics async getGraphStats(): Promise<GraphStats> async validateGraph(): Promise<ValidationReport> } ``` **Lazy Initialization**: ```typescript // Managers created on first access using ??= operator private get entityManager(): EntityManager { return (this._entityManager ??= new EntityManager(this.storage)); } ``` **Managed Components** (10 total): - EntityManager, RelationManager - SearchManager, CompressionManager - HierarchyManager, ExportManager, ImportManager - AnalyticsManager, TagManager, ArchiveManager --- ### EntityManager (`core/EntityManager.ts`) **Purpose**: Entity CRUD operations with validation ```typescript export class EntityManager { constructor(storage: GraphStorage) async createEntities(entities: Entity[]): Promise<Entity[]> async deleteEntities(entityNames: string[]): Promise<void> async addObservations(observations: {...}[]): Promise<{...}[]> async deleteObservations(deletions: {...}[]): Promise<void> async addTags(entityName, tags): Promise<{...}> async removeTags(entityName, tags): Promise<{...}> async setImportance(entityName, importance): Promise<{...}> async addTagsToMultipleEntities(entityNames, tags): Promise<{...}[]> async replaceTag(oldTag, newTag): Promise<{...}> async mergeTags(tag1, tag2, targetTag): Promise<{...}> } ``` **Key Features**: - Automatic timestamp management (createdAt, lastModified) - Tag normalization (lowercase) - Importance validation (0-10 range) - Batch operations (single I/O) - Zod schema validation **Constants**: - `MIN_IMPORTANCE = 0` - `MAX_IMPORTANCE = 10` --- ### RelationManager (`core/RelationManager.ts`) **Purpose**: Relation CRUD operations ```typescript export class RelationManager { constructor(storage: GraphStorage) async createRelations(relations: Relation[]): Promise<Relation[]> async deleteRelations(relations: Relation[]): Promise<void> } ``` **Key Features**: - Automatic timestamp management - Duplicate relation prevention - Deferred integrity (relations to non-existent entities allowed) --- ### GraphStorage (`core/GraphStorage.ts`) **Purpose**: File I/O with in-memory caching ```typescript export class GraphStorage { constructor(memoryFilePath: string) async loadGraph(): Promise<KnowledgeGraph> async saveGraph(graph: KnowledgeGraph): Promise<void> invalidateCache(): void } ``` **Key Features**: - JSONL format (line-delimited JSON) - In-memory cache with write-through invalidation - Deep copy on cache reads (prevents mutation) - Backward compatibility for missing timestamps **Cache Behavior**: - `loadGraph()`: Returns cached copy if available, else reads from disk - `saveGraph()`: Writes to disk and invalidates cache - Cache cleared on every write for consistency --- ## Search Components ### SearchManager (`search/SearchManager.ts`) **Purpose**: Orchestrates all search types ```typescript export class SearchManager { constructor(storage: GraphStorage, savedSearchesFilePath: string) // Basic search async searchNodes(query, tags?, minImportance?, maxImportance?): Promise<KnowledgeGraph> async openNodes(names): Promise<KnowledgeGraph> async searchByDateRange(startDate?, endDate?, entityType?, tags?): Promise<KnowledgeGraph> // Advanced search async searchNodesRanked(query, tags?, min?, max?, limit?): Promise<SearchResult[]> async booleanSearch(query, tags?, min?, max?): Promise<KnowledgeGraph> async fuzzySearch(query, threshold?, tags?, min?, max?): Promise<KnowledgeGraph> // Suggestions async getSearchSuggestions(query, maxSuggestions?): Promise<string[]> // Saved searches async saveSearch(search): Promise<SavedSearch> async listSavedSearches(): Promise<SavedSearch[]> async executeSavedSearch(name): Promise<KnowledgeGraph> async deleteSavedSearch(name): Promise<boolean> } ``` **Composed Components**: - BasicSearch, RankedSearch, BooleanSearch, FuzzySearch - SearchSuggestions, SavedSearchManager --- ### BasicSearch (`search/BasicSearch.ts`) **Purpose**: Simple text matching with filters **Algorithm**: Case-insensitive substring matching across name, entityType, observations ```typescript export class BasicSearch { constructor(storage: GraphStorage) async searchNodes(query, tags?, minImportance?, maxImportance?): Promise<KnowledgeGraph> async openNodes(names): Promise<KnowledgeGraph> async searchByDateRange(startDate?, endDate?, entityType?, tags?): Promise<KnowledgeGraph> } ``` --- ### RankedSearch (`search/RankedSearch.ts`) **Purpose**: TF-IDF relevance scoring **Algorithm**: Term Frequency-Inverse Document Frequency ```typescript export class RankedSearch { constructor(storage: GraphStorage) async searchNodesRanked( query: string, tags?: string[], minImportance?: number, maxImportance?: number, limit?: number ): Promise<SearchResult[]> } ``` **Scoring**: - Tokenizes query and entity content - Calculates TF-IDF score per entity - Returns sorted results with scores --- ### BooleanSearch (`search/BooleanSearch.ts`) **Purpose**: Boolean query parsing and evaluation **Syntax**: `AND`, `OR`, `NOT`, parentheses, field prefixes ```typescript export class BooleanSearch { constructor(storage: GraphStorage) async booleanSearch( query: string, tags?: string[], minImportance?: number, maxImportance?: number ): Promise<KnowledgeGraph> } ``` **Query Examples**: - `Alice AND Bob` - `name:Alice OR type:person` - `NOT archived AND (project OR task)` --- ### FuzzySearch (`search/FuzzySearch.ts`) **Purpose**: Typo-tolerant search using Levenshtein distance ```typescript export class FuzzySearch { constructor(storage: GraphStorage) async fuzzySearch( query: string, threshold?: number, // 0.0-1.0, default 0.7 tags?: string[], minImportance?: number, maxImportance?: number ): Promise<KnowledgeGraph> } ``` **Algorithm**: Levenshtein distance normalized to similarity score --- ### SearchFilterChain (`search/SearchFilterChain.ts`) **Purpose**: Unified filter logic for all search implementations ```typescript export interface SearchFilters { tags?: string[]; minImportance?: number; maxImportance?: number; entityType?: string; createdAfter?: string; createdBefore?: string; modifiedAfter?: string; modifiedBefore?: string; } export class SearchFilterChain { static applyFilters(entities: Entity[], filters: SearchFilters): Entity[] static entityPassesFilters(entity: Entity, filters: SearchFilters): boolean static hasActiveFilters(filters: SearchFilters): boolean static filterAndPaginate(entities, filters, offset?, limit?): Entity[] static filterByTags(entities, tags?): Entity[] static filterByImportance(entities, min?, max?): Entity[] } ``` **Benefits**: - Eliminates ~65 lines of duplicate filter code per search implementation - Consistent filtering behavior across all search types - Short-circuit evaluation for performance - Pre-normalizes tags once per filter operation --- ## Feature Components ### HierarchyManager (`features/HierarchyManager.ts`) **Purpose**: Parent-child relationships and tree navigation ```typescript export class HierarchyManager { constructor(storage: GraphStorage) async setEntityParent(entityName, parentName): Promise<Entity> async getChildren(entityName): Promise<Entity[]> async getParent(entityName): Promise<Entity | null> async getAncestors(entityName): Promise<Entity[]> async getDescendants(entityName): Promise<Entity[]> async getSubtree(entityName): Promise<KnowledgeGraph> async getRootEntities(): Promise<Entity[]> async getEntityDepth(entityName): Promise<number> async moveEntity(entityName, newParentName): Promise<Entity> } ``` **Safety**: Cycle detection prevents invalid parent assignments --- ### CompressionManager (`features/CompressionManager.ts`) **Purpose**: Duplicate detection and entity merging ```typescript export class CompressionManager { constructor(storage: GraphStorage) async findDuplicates(threshold?: number): Promise<string[][]> async mergeEntities(entityNames, targetName?): Promise<Entity> async compressGraph(threshold?, dryRun?): Promise<CompressionResult> } ``` **Similarity Algorithm**: - **Name**: Levenshtein distance (weight: 0.4) - **Type**: Exact match (weight: 0.3) - **Observations**: Jaccard similarity (weight: 0.2) - **Tags**: Jaccard similarity (weight: 0.1) **Optimization**: Two-level bucketing by entityType reduces O(n²) to O(n²/k) --- ### ExportManager (`features/ExportManager.ts`) **Purpose**: Multi-format graph export ```typescript export type ExportFormat = 'json' | 'csv' | 'graphml' | 'gexf' | 'dot' | 'markdown' | 'mermaid'; export class ExportManager { exportGraph(graph: KnowledgeGraph, format: ExportFormat): string } ``` **Supported Formats**: | Format | Description | |--------|-------------| | json | Pretty-printed JSON | | csv | Comma-separated values | | graphml | XML-based graph format | | gexf | Graph Exchange XML Format | | dot | Graphviz DOT language | | markdown | Human-readable markdown | | mermaid | Mermaid diagram syntax | --- ### ImportManager (`features/ImportManager.ts`) **Purpose**: Multi-format graph import with merge strategies ```typescript export class ImportManager { constructor(storage: GraphStorage) async importGraph( format: 'json' | 'csv' | 'graphml', data: string, mergeStrategy?: 'replace' | 'skip' | 'merge' | 'fail', dryRun?: boolean ): Promise<ImportResult> } ``` **Merge Strategies**: - `replace`: Overwrite existing entities - `skip`: Skip entities that exist - `merge`: Combine observations and tags - `fail`: Error if any conflicts --- ### AnalyticsManager (`features/AnalyticsManager.ts`) **Purpose**: Graph statistics and validation ```typescript export class AnalyticsManager { constructor(storage: GraphStorage) async getGraphStats(): Promise<GraphStats> async validateGraph(): Promise<ValidationReport> } ``` **GraphStats** includes: - Entity/relation counts - Entity types distribution - Tag usage statistics - Importance distribution - Date range of content **ValidationReport** checks: - Orphaned relations (references to non-existent entities) - Duplicate entity names - Invalid importance values - Circular hierarchy references --- ### TagManager (`features/TagManager.ts`) **Purpose**: Tag aliases and synonyms ```typescript export class TagManager { constructor(tagAliasesFilePath: string) async resolveTag(tag: string): Promise<string> async addTagAlias(alias, canonical, description?): Promise<TagAlias> async listTagAliases(): Promise<TagAlias[]> async removeTagAlias(alias): Promise<boolean> async getAliasesForTag(canonicalTag): Promise<string[]> } ``` **Use Case**: Map synonyms to canonical tags (e.g., "js" → "javascript") --- ### ArchiveManager (`features/ArchiveManager.ts`) **Purpose**: Archive old/low-importance entities ```typescript export class ArchiveManager { constructor(storage: GraphStorage) async archiveEntities( criteria: { olderThan?: string; // ISO date importanceLessThan?: number; tags?: string[]; }, dryRun?: boolean ): Promise<{ archived: number; entityNames: string[] }> } ``` --- ## Utility Components ### schemas (`utils/schemas.ts`) **Purpose**: Zod validation schemas **Key Schemas**: - `EntitySchema`, `CreateEntitySchema`, `UpdateEntitySchema` - `RelationSchema`, `CreateRelationSchema` - `BatchCreateEntitiesSchema` (max 1000 items) - `SearchQuerySchema`, `DateRangeSchema` - `ImportanceSchema` (0-10) --- ### constants (`utils/constants.ts`) **Purpose**: Centralized configuration values ```typescript export const SIMILARITY_WEIGHTS = { NAME: 0.4, TYPE: 0.3, OBSERVATIONS: 0.2, TAGS: 0.1, }; export const DEFAULT_DUPLICATE_THRESHOLD = 0.8; export const SEARCH_LIMITS = { DEFAULT: 50, MAX: 1000, }; export const GRAPH_LIMITS = { MAX_ENTITIES: 10000, MAX_RELATIONS: 50000, }; ``` --- ### responseFormatter (`utils/responseFormatter.ts`) **Purpose**: Consistent MCP tool response formatting ```typescript export function formatToolResponse(data: unknown): ToolResponse export function formatTextResponse(text: string): ToolResponse export function formatRawResponse(content: unknown): ToolResponse ``` --- ### levenshtein (`utils/levenshtein.ts`) **Purpose**: Levenshtein distance calculation for fuzzy matching ```typescript export function levenshteinDistance(s1: string, s2: string): number ``` --- ### tfidf (`utils/tfidf.ts`) **Purpose**: TF-IDF scoring for ranked search ```typescript export function calculateTF(term: string, document: string): number export function calculateIDF(term: string, documents: string[]): number export function calculateTFIDF(term: string, document: string, documents: string[]): number ``` --- ## Type Definitions ### Entity Types (`types/entity.types.ts`) ```typescript interface Entity { name: string; entityType: string; observations: string[]; parentId?: string; tags?: string[]; importance?: number; createdAt?: string; lastModified?: string; } interface Relation { from: string; to: string; relationType: string; createdAt?: string; lastModified?: string; } interface KnowledgeGraph { entities: Entity[]; relations: Relation[]; } ``` ### Search Types (`types/search.types.ts`) ```typescript interface SearchResult { entity: Entity; score: number; matchedFields: string[]; } interface SavedSearch { name: string; query: string; searchType: 'basic' | 'ranked' | 'boolean' | 'fuzzy'; filters?: SearchFilters; createdAt: string; lastUsed?: string; useCount: number; } ``` ### Analytics Types (`types/analytics.types.ts`) ```typescript interface GraphStats { entityCount: number; relationCount: number; entityTypes: Record<string, number>; tagCounts: Record<string, number>; importanceDistribution: Record<number, number>; } interface ValidationReport { valid: boolean; errors: ValidationError[]; warnings: ValidationWarning[]; } ``` --- ## Component Dependencies ``` ┌──────────────────────────────────────────────────────────────┐ │ MCPServer │ │ └── KnowledgeGraphManager (facade) │ │ ├── EntityManager ────────┐ │ │ ├── RelationManager ──────┤ │ │ ├── SearchManager ────────┤ │ │ │ ├── BasicSearch ────┤ │ │ │ ├── RankedSearch ───┤ │ │ │ ├── BooleanSearch ──┼──► GraphStorage │ │ │ ├── FuzzySearch ────┤ │ │ │ │ └── SavedSearchMgr ─┤ ▼ │ │ ├── HierarchyManager ─────┤ memory.jsonl │ │ ├── CompressionManager ───┤ │ │ ├── ExportManager ────────┘ │ │ ├── ImportManager ────────► GraphStorage │ │ ├── AnalyticsManager ─────► GraphStorage │ │ ├── TagManager ───────────► tag-aliases.jsonl │ │ └── ArchiveManager ───────► GraphStorage │ └──────────────────────────────────────────────────────────────┘ ``` **Shared Dependencies**: - All managers receive `GraphStorage` via dependency injection - `SearchFilterChain` used by all search implementations - `utils/schemas.ts` used for input validation across managers - `utils/constants.ts` provides shared configuration --- **Document Version**: 1.0 **Last Updated**: 2025-11-26 **Maintained By**: Daniel Simon Jr.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/danielsimonjr/memory-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server