@codai/memorai-mcp
Version:
MemorAI CBD-based MCP Server - High-Performance Vector Memory System
955 lines • 61.4 kB
JavaScript
#!/usr/bin/env node
/**
* MemorAI MCP Consolidated Server - Production-Ready Implementation
*
* This is the single, optimized server implementation that combines:
* - Comprehensive feature set from server.ts (27 tools)
* - Simplified configuration from server-simple.ts
* - Performance optimizations from server-unified.ts
* - Correct tool naming for MCP compatibility (no prefixes)
* - CBD backend for high-performance and reliability
* - Advanced semantic search with OpenAI embeddings
* - Memory lifecycle management and analytics
* - Federation and collaboration features
*
* Version: 10.0.0 (Consolidated)
* Date: 2024-12-19
*/
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { CallToolRequestSchema, ErrorCode, ListToolsRequestSchema, McpError, } from '@modelcontextprotocol/sdk/types.js';
import { existsSync, mkdirSync, writeFileSync, readFileSync } from 'fs';
import { join, resolve } from 'path';
import { randomUUID, createHash } from 'crypto';
import { config } from 'dotenv';
import OpenAI from 'openai';
import { MemoryRecommendationEngine } from './recommendation-engine.js';
import { MemoryRelationshipEngine } from './relationship-engine.js';
export class MemorAIConsolidatedServer {
server;
config;
memories = new Map();
dataPath;
isStarted = false;
openai;
// Advanced engines (optional - will be initialized if available)
recommendationEngine;
relationshipEngine;
// Performance tracking
operationCount = 0;
operationTimes = [];
startTime = Date.now();
// Memory analytics
memoryStats = {
totalMemories: 0,
uniqueAgents: new Set(),
uniqueProjects: new Set(),
averageImportance: 0,
averageQuality: 0,
totalOperations: 0,
};
constructor(config) {
this.config = {
...config,
enableSemanticSearch: config.enableSemanticSearch ?? true,
enablePerformanceTracking: config.enablePerformanceTracking ?? true,
enableHybridStorage: config.enableHybridStorage ?? true,
enableAnalytics: config.enableAnalytics ?? true,
enableFederation: config.enableFederation ?? true,
enableLearning: config.enableLearning ?? true,
enablePredictive: config.enablePredictive ?? true,
enableRecommendations: config.enableRecommendations ?? true,
enableRelationships: config.enableRelationships ?? true,
fallbackStorage: config.fallbackStorage ?? 'json'
};
this.dataPath = this.config.cbdPath;
// Ensure data directory exists
if (!existsSync(this.dataPath)) {
mkdirSync(this.dataPath, { recursive: true });
}
// Initialize OpenAI client
this.initializeOpenAI();
// Initialize advanced engines
this.initializeEngines();
// Initialize MCP Server
this.server = new Server({
name: this.config.serverName,
version: this.config.version,
}, {
capabilities: {
tools: {},
},
});
this.setupHandlers();
this.loadMemories();
this.log('info', `🚀 ${this.config.serverName} v${this.config.version} initialized with ${this.memories.size} memories`);
}
initializeOpenAI() {
if (this.config.azureOpenAI && this.config.enableSemanticSearch) {
this.openai = new OpenAI({
apiKey: this.config.azureOpenAI.apiKey,
baseURL: `${this.config.azureOpenAI.endpoint}/openai/deployments/${this.config.azureOpenAI.embeddingDeployment}`,
defaultQuery: { 'api-version': this.config.azureOpenAI.apiVersion },
defaultHeaders: {
'api-key': this.config.azureOpenAI.apiKey,
},
});
this.log('info', `🔗 Azure OpenAI initialized with deployment: ${this.config.azureOpenAI.embeddingDeployment}`);
}
else if (this.config.openaiApiKey && this.config.enableSemanticSearch) {
this.openai = new OpenAI({
apiKey: this.config.openaiApiKey,
});
this.log('info', '🔗 OpenAI initialized (fallback mode)');
}
}
initializeEngines() {
try {
if (this.config.enableRecommendations) {
this.recommendationEngine = new MemoryRecommendationEngine(this.openai);
this.log('info', '💡 Recommendation engine initialized');
}
if (this.config.enableRelationships) {
this.relationshipEngine = new MemoryRelationshipEngine();
this.log('info', '🔗 Relationship engine initialized');
}
}
catch (error) {
this.log('warn', 'Some engines failed to initialize:', error);
}
}
log(level, message, ...args) {
const timestamp = new Date().toISOString();
console.error(`[${timestamp}] [${level.toUpperCase()}] ${message}`, ...args);
}
setupHandlers() {
// List available tools - all 27 tools with correct naming (no prefixes)
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
// Core memory operations
{
name: 'remember',
description: 'Store a new memory with advanced metadata and semantic indexing',
inputSchema: {
type: 'object',
properties: {
agentId: { type: 'string', description: 'Agent identifier' },
content: { type: 'string', description: 'Memory content to store' },
metadata: {
type: 'object',
properties: {
entityType: { type: 'string', description: 'Type of entity' },
priority: { type: 'string', description: 'Priority level' },
project: { type: 'string', description: 'Project name' },
session: { type: 'string', description: 'Session identifier' },
tags: { type: 'array', items: { type: 'string' }, description: 'Tags' },
importance: { type: 'number', description: 'Importance score 0-1' },
sourceType: { type: 'string', description: 'Source type' },
confidence: { type: 'number', description: 'Confidence score 0-1' },
validUntil: { type: 'string', description: 'Validity date' },
shareWith: { type: 'array', items: { type: 'string' }, description: 'Share with agents' }
}
}
},
required: ['agentId', 'content'],
},
},
{
name: 'recall',
description: 'Search and retrieve memories with semantic understanding',
inputSchema: {
type: 'object',
properties: {
agentId: { type: 'string', description: 'Agent identifier' },
query: { type: 'string', description: 'Search query' },
limit: { type: 'number', description: 'Maximum results', default: 10 },
minImportance: { type: 'number', description: 'Minimum importance score', default: 0 },
project: { type: 'string', description: 'Filter by project' },
session: { type: 'string', description: 'Filter by session' },
useSemanticSearch: { type: 'boolean', description: 'Use semantic search', default: true },
includeArchived: { type: 'boolean', description: 'Include archived memories', default: false }
},
required: ['agentId', 'query'],
},
},
{
name: 'forget',
description: 'Delete a memory by structured key with safety checks',
inputSchema: {
type: 'object',
properties: {
agentId: { type: 'string', description: 'Agent identifier' },
structuredKey: { type: 'string', description: 'Structured key of memory to delete' },
force: { type: 'boolean', description: 'Force deletion ignoring dependencies', default: false }
},
required: ['agentId', 'structuredKey'],
},
},
{
name: 'context',
description: 'Get recent context for agent with relevance scoring',
inputSchema: {
type: 'object',
properties: {
agentId: { type: 'string', description: 'Agent identifier' },
contextSize: { type: 'number', description: 'Number of recent memories', default: 5 },
includeRelated: { type: 'boolean', description: 'Include related memories', default: true }
},
required: ['agentId'],
},
},
{
name: 'get_memory',
description: 'Get memory by exact structured key with full details',
inputSchema: {
type: 'object',
properties: {
structuredKey: { type: 'string', description: 'Exact structured key' },
includeRelationships: { type: 'boolean', description: 'Include relationship data', default: true }
},
required: ['structuredKey'],
},
},
{
name: 'search_keys',
description: 'Vector similarity search for memory keys',
inputSchema: {
type: 'object',
properties: {
query: { type: 'string', description: 'Query for finding similar memory keys' },
limit: { type: 'number', description: 'Maximum keys to return', default: 10 },
minScore: { type: 'number', description: 'Minimum similarity score', default: 0.7 }
},
required: ['query'],
},
},
// Memory management
{
name: 'link_memories',
description: 'Create relationships between two memories',
inputSchema: {
type: 'object',
properties: {
memoryKey1: { type: 'string', description: 'First memory structured key' },
memoryKey2: { type: 'string', description: 'Second memory structured key' },
relationshipType: { type: 'string', description: 'Type of relationship' },
strength: { type: 'number', description: 'Relationship strength 0-1', default: 0.5 }
},
required: ['memoryKey1', 'memoryKey2', 'relationshipType'],
},
},
{
name: 'share_memory',
description: 'Share a memory with other agents',
inputSchema: {
type: 'object',
properties: {
structuredKey: { type: 'string', description: 'Memory structured key' },
targetAgents: { type: 'array', items: { type: 'string' }, description: 'Target agent IDs' },
permissions: { type: 'array', items: { type: 'string' }, description: 'Permission levels' }
},
required: ['structuredKey', 'targetAgents'],
},
},
{
name: 'synchronize_federation',
description: 'Synchronize memories across federated agents',
inputSchema: {
type: 'object',
properties: {
federationId: { type: 'string', description: 'Federation identifier' },
syncType: { type: 'string', description: 'Synchronization type', enum: ['full', 'incremental', 'selective'] },
filters: { type: 'object', description: 'Synchronization filters' }
},
required: ['federationId'],
},
},
// Analytics and insights
{
name: 'get_analytics',
description: 'Generate comprehensive memory usage analytics',
inputSchema: {
type: 'object',
properties: {
agentId: { type: 'string', description: 'Agent identifier (optional for global analytics)' },
timeRange: { type: 'string', description: 'Time range for analytics', default: '7d' },
reportType: { type: 'string', description: 'Type of report', enum: ['usage', 'performance', 'trends', 'quality'] }
},
},
},
{
name: 'get_insights',
description: 'Get AI-powered insights into memory patterns',
inputSchema: {
type: 'object',
properties: {
agentId: { type: 'string', description: 'Agent identifier' },
insightType: { type: 'string', description: 'Type of insights', enum: ['patterns', 'gaps', 'recommendations', 'predictions'] },
depth: { type: 'string', description: 'Analysis depth', enum: ['basic', 'detailed', 'comprehensive'], default: 'detailed' }
},
required: ['agentId'],
},
},
{
name: 'collective_insights',
description: 'Aggregate insights from multiple agents about a topic',
inputSchema: {
type: 'object',
properties: {
topic: { type: 'string', description: 'Topic to analyze' },
agents: { type: 'array', items: { type: 'string' }, description: 'Agent IDs to include' },
analysisType: { type: 'string', description: 'Type of analysis', enum: ['consensus', 'diversity', 'expertise', 'trends'] }
},
required: ['topic'],
},
},
{
name: 'learn_from_usage',
description: 'Analyze usage patterns to enhance future predictions',
inputSchema: {
type: 'object',
properties: {
agentId: { type: 'string', description: 'Agent identifier' },
learningType: { type: 'string', description: 'Type of learning', enum: ['patterns', 'preferences', 'performance', 'optimization'] },
timeWindow: { type: 'string', description: 'Learning time window', default: '30d' }
},
required: ['agentId'],
},
},
{
name: 'get_relationships',
description: 'Explore relationships between memories',
inputSchema: {
type: 'object',
properties: {
memoryKey: { type: 'string', description: 'Starting memory key' },
depth: { type: 'number', description: 'Relationship depth to explore', default: 2 },
relationshipTypes: { type: 'array', items: { type: 'string' }, description: 'Types of relationships to include' }
},
required: ['memoryKey'],
},
},
// Optimization and enhancement
{
name: 'optimize_retrieval',
description: 'Enhance memory retrieval based on query patterns',
inputSchema: {
type: 'object',
properties: {
agentId: { type: 'string', description: 'Agent identifier' },
optimizationType: { type: 'string', description: 'Optimization type', enum: ['speed', 'accuracy', 'relevance', 'comprehensive'] },
queryPatterns: { type: 'array', items: { type: 'string' }, description: 'Common query patterns' }
},
required: ['agentId'],
},
},
{
name: 'predict_enhanced',
description: 'Improved memory need predictions with learning integration',
inputSchema: {
type: 'object',
properties: {
agentId: { type: 'string', description: 'Agent identifier' },
context: { type: 'string', description: 'Current context' },
predictionHorizon: { type: 'string', description: 'Prediction time horizon', default: '1h' },
confidence: { type: 'number', description: 'Minimum confidence level', default: 0.7 }
},
required: ['agentId', 'context'],
},
},
{
name: 'predict_evolution',
description: 'Forecast how memories will evolve over time',
inputSchema: {
type: 'object',
properties: {
memoryKey: { type: 'string', description: 'Memory to analyze' },
timeHorizon: { type: 'string', description: 'Prediction time horizon', default: '30d' },
factors: { type: 'array', items: { type: 'string' }, description: 'Evolution factors to consider' }
},
required: ['memoryKey'],
},
},
{
name: 'predict_structure',
description: 'Suggest optimal memory structures based on usage patterns',
inputSchema: {
type: 'object',
properties: {
agentId: { type: 'string', description: 'Agent identifier' },
dataPattern: { type: 'string', description: 'Data pattern to analyze' },
optimizationGoal: { type: 'string', description: 'Optimization goal', enum: ['speed', 'storage', 'accuracy', 'flexibility'] }
},
required: ['agentId'],
},
},
{
name: 'adapt_organization',
description: 'Adjust memory organization based on effectiveness metrics',
inputSchema: {
type: 'object',
properties: {
agentId: { type: 'string', description: 'Agent identifier' },
organizationType: { type: 'string', description: 'Organization type', enum: ['hierarchical', 'graph', 'temporal', 'semantic'] },
effectivenessMetrics: { type: 'object', description: 'Effectiveness metrics to optimize' }
},
required: ['agentId'],
},
},
// Collaboration and federation
{
name: 'collaborative_learning',
description: 'Enable real-time learning across agents',
inputSchema: {
type: 'object',
properties: {
initiatorAgent: { type: 'string', description: 'Initiating agent ID' },
participantAgents: { type: 'array', items: { type: 'string' }, description: 'Participating agent IDs' },
learningTopic: { type: 'string', description: 'Topic for collaborative learning' },
sessionDuration: { type: 'string', description: 'Session duration', default: '1h' }
},
required: ['initiatorAgent', 'learningTopic'],
},
},
{
name: 'federated_query',
description: 'Perform distributed queries across multiple agents',
inputSchema: {
type: 'object',
properties: {
query: { type: 'string', description: 'Query to execute across federation' },
targetAgents: { type: 'array', items: { type: 'string' }, description: 'Target agent IDs' },
aggregationType: { type: 'string', description: 'How to aggregate results', enum: ['union', 'intersection', 'weighted', 'ranked'] },
timeout: { type: 'string', description: 'Query timeout', default: '30s' }
},
required: ['query'],
},
},
{
name: 'explore_graph',
description: 'Navigate the knowledge graph starting from a memory',
inputSchema: {
type: 'object',
properties: {
startingMemory: { type: 'string', description: 'Starting memory key' },
explorationDepth: { type: 'number', description: 'Exploration depth', default: 3 },
explorationStrategy: { type: 'string', description: 'Exploration strategy', enum: ['breadth-first', 'depth-first', 'relevance-based', 'importance-weighted'] },
filters: { type: 'object', description: 'Exploration filters' }
},
required: ['startingMemory'],
},
},
{
name: 'resolve_conflicts',
description: 'Detect and resolve conflicts between memories',
inputSchema: {
type: 'object',
properties: {
scope: { type: 'string', description: 'Conflict resolution scope', enum: ['agent', 'project', 'session', 'global'] },
agentId: { type: 'string', description: 'Agent identifier (if agent scope)' },
resolutionStrategy: { type: 'string', description: 'Resolution strategy', enum: ['latest', 'highest-confidence', 'consensus', 'manual'] },
autoResolve: { type: 'boolean', description: 'Automatically resolve conflicts', default: false }
},
required: ['scope'],
},
},
// Lifecycle management
{
name: 'manage_lifecycle',
description: 'Manage memory lifecycles with automated policies',
inputSchema: {
type: 'object',
properties: {
agentId: { type: 'string', description: 'Agent identifier' },
operation: { type: 'string', description: 'Lifecycle operation', enum: ['archive', 'promote', 'clean', 'validate', 'extend'] },
criteria: { type: 'object', description: 'Operation criteria' },
dryRun: { type: 'boolean', description: 'Perform dry run only', default: true }
},
required: ['operation'],
},
},
{
name: 'consolidate_memories',
description: 'Group related memories for better organization',
inputSchema: {
type: 'object',
properties: {
agentId: { type: 'string', description: 'Agent identifier' },
consolidationType: { type: 'string', description: 'Consolidation type', enum: ['topic', 'temporal', 'semantic', 'project'] },
similarityThreshold: { type: 'number', description: 'Similarity threshold', default: 0.8 },
preserveOriginals: { type: 'boolean', description: 'Keep original memories', default: true }
},
required: ['agentId'],
},
},
{
name: 'evolve_memory',
description: 'Automatically update memories based on new information',
inputSchema: {
type: 'object',
properties: {
memoryKey: { type: 'string', description: 'Memory to evolve' },
newInformation: { type: 'string', description: 'New information to integrate' },
evolutionType: { type: 'string', description: 'Evolution type', enum: ['append', 'merge', 'replace', 'enhance'] },
confidence: { type: 'number', description: 'Confidence in new information', default: 0.8 }
},
required: ['memoryKey', 'newInformation'],
},
},
{
name: 'get_recommendations',
description: 'Get intelligent recommendations for memory optimization',
inputSchema: {
type: 'object',
properties: {
agentId: { type: 'string', description: 'Agent identifier' },
recommendationType: { type: 'string', description: 'Recommendation type', enum: ['organization', 'cleanup', 'enhancement', 'relationships'] },
scope: { type: 'string', description: 'Recommendation scope', enum: ['recent', 'project', 'all'] },
priority: { type: 'string', description: 'Priority level', enum: ['low', 'medium', 'high', 'critical'] }
},
required: ['agentId'],
},
}
],
};
});
// Handle tool calls
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
const startTime = Date.now();
try {
let result;
switch (name) {
// Core operations
case 'remember':
result = await this.handleRemember(args);
break;
case 'recall':
result = await this.handleRecall(args);
break;
case 'forget':
result = await this.handleForget(args);
break;
case 'context':
result = await this.handleContext(args);
break;
case 'get_memory':
result = await this.handleGetMemory(args);
break;
case 'search_keys':
result = await this.handleSearchKeys(args);
break;
// Memory management
case 'link_memories':
result = await this.handleLinkMemories(args);
break;
case 'share_memory':
result = await this.handleShareMemory(args);
break;
case 'synchronize_federation':
result = await this.handleSynchronizeFederation(args);
break;
// Analytics
case 'get_analytics':
result = await this.handleGetAnalytics(args);
break;
case 'get_insights':
result = await this.handleGetInsights(args);
break;
case 'collective_insights':
result = await this.handleCollectiveInsights(args);
break;
case 'learn_from_usage':
result = await this.handleLearnFromUsage(args);
break;
case 'get_relationships':
result = await this.handleGetRelationships(args);
break;
// Optimization
case 'optimize_retrieval':
result = await this.handleOptimizeRetrieval(args);
break;
case 'predict_enhanced':
result = await this.handlePredictEnhanced(args);
break;
case 'predict_evolution':
result = await this.handlePredictEvolution(args);
break;
case 'predict_structure':
result = await this.handlePredictStructure(args);
break;
case 'adapt_organization':
result = await this.handleAdaptOrganization(args);
break;
// Collaboration
case 'collaborative_learning':
result = await this.handleCollaborativeLearning(args);
break;
case 'federated_query':
result = await this.handleFederatedQuery(args);
break;
case 'explore_graph':
result = await this.handleExploreGraph(args);
break;
case 'resolve_conflicts':
result = await this.handleResolveConflicts(args);
break;
// Lifecycle
case 'manage_lifecycle':
result = await this.handleManageLifecycle(args);
break;
case 'consolidate_memories':
result = await this.handleConsolidateMemories(args);
break;
case 'evolve_memory':
result = await this.handleEvolveMemory(args);
break;
case 'get_recommendations':
result = await this.handleGetRecommendations(args);
break;
default:
throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${name}`);
}
const responseTime = Date.now() - startTime;
this.updateMetrics(responseTime);
return result;
}
catch (error) {
const responseTime = Date.now() - startTime;
this.updateMetrics(responseTime);
this.log('error', `Tool ${name} failed:`, error);
throw error;
}
});
}
// Core operation handlers
async handleRemember(args) {
const { agentId, content, metadata = {} } = args;
// Generate content hash for duplicate detection
const contentHash = createHash('sha256').update(content).digest('hex');
// Check for duplicates
const existingMemory = Array.from(this.memories.values())
.find(m => m.contentHash === contentHash && m.metadata.agentId === agentId);
if (existingMemory) {
existingMemory.accessCount++;
existingMemory.lastAccessed = new Date().toISOString();
existingMemory.lifecycle.updatedAt = new Date().toISOString();
this.saveMemories();
return {
content: [{
type: 'text',
text: JSON.stringify({
success: true,
memoryId: existingMemory.id,
structuredKey: existingMemory.structuredKey,
isDuplicate: true,
message: 'Memory already exists, access updated',
metadata: {
serverVersion: this.config.version,
operation: 'store_memory'
}
}, null, 2)
}]
};
}
// Generate structured key
const dateStr = new Date().toISOString().split('T')[0];
const date = dateStr ? dateStr.replace(/-/g, '') : 'unknown';
const project = metadata.project || 'default';
const session = metadata.session || agentId;
const sequence = this.getNextSequenceNumber(project, session);
const structuredKey = `${project}_${date}_${session}_${sequence}`;
// Generate embedding if semantic search is enabled
let embedding;
if (this.config.enableSemanticSearch && this.openai) {
try {
const embeddingResponse = await this.openai.embeddings.create({
model: this.config.azureOpenAI?.embeddingModel || this.config.embeddingModel,
input: content,
});
if (embeddingResponse.data?.[0]?.embedding) {
embedding = embeddingResponse.data[0].embedding;
}
}
catch (error) {
this.log('warn', 'Failed to generate embedding:', error);
}
}
const importance = this.calculateImportance(content, metadata);
const qualityScore = this.calculateQualityScore(content, metadata);
const memory = {
id: randomUUID(),
content,
contentHash,
structuredKey,
projectName: project,
sessionName: session,
sequenceNumber: sequence,
metadata: {
agentId,
timestamp: new Date().toISOString(),
importance,
embeddingSummary: content.substring(0, 100) + '...',
...metadata
},
accessCount: 0,
lastAccessed: new Date().toISOString(),
relevanceScore: 0.5,
qualityScore,
embedding,
embeddingModel: this.config.embeddingModel,
lifecycle: {
stage: 'active',
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
retentionPolicy: 'default'
},
relationships: {
parentMemories: [],
childMemories: [],
relatedMemories: [],
conflicts: [],
dependencies: []
}
};
this.memories.set(memory.structuredKey, memory);
this.updateMemoryStats(memory);
this.saveMemories();
this.log('info', `📝 Stored memory: ${memory.structuredKey}`);
return {
content: [{
type: 'text',
text: JSON.stringify({
success: true,
memoryId: memory.id,
structuredKey: memory.structuredKey,
projectName: memory.projectName,
sessionName: memory.sessionName,
sequenceNumber: memory.sequenceNumber,
isDuplicate: false,
importanceScore: importance,
qualityScore,
message: 'Memory stored with structured key',
metadata: {
serverVersion: this.config.version,
operation: 'store_memory',
structuredKeyFormat: 'project_date_session_sequence',
timestamp: new Date().toISOString(),
hasEmbedding: !!embedding
}
}, null, 2)
}]
};
}
async handleRecall(args) {
const { agentId, query, limit = 10, minImportance = 0, project, session, useSemanticSearch = true, includeArchived = false } = args;
let memories = Array.from(this.memories.values())
.filter(memory => {
if (memory.metadata.agentId !== agentId)
return false;
if (!includeArchived && memory.lifecycle.stage !== 'active')
return false;
if (memory.metadata.importance < minImportance)
return false;
if (project && memory.projectName !== project)
return false;
if (session && memory.sessionName !== session)
return false;
return true;
});
// Perform search
let searchResults = memories;
if (useSemanticSearch && this.openai) {
// Basic semantic search implementation
try {
const queryEmbedding = await this.openai.embeddings.create({
model: this.config.azureOpenAI?.embeddingModel || this.config.embeddingModel,
input: query,
});
if (queryEmbedding.data?.[0]?.embedding) {
const queryVector = queryEmbedding.data[0].embedding;
searchResults = memories
.filter(memory => memory.embedding)
.map(memory => {
const similarity = this.calculateCosineSimilarity(queryVector, memory.embedding);
return { ...memory, relevanceScore: similarity };
})
.filter(memory => memory.relevanceScore > 0.3)
.sort((a, b) => (b.relevanceScore || 0) - (a.relevanceScore || 0));
}
}
catch (error) {
this.log('warn', 'Semantic search failed, falling back to text search:', error);
searchResults = this.performTextSearch(query, memories);
}
}
else {
searchResults = this.performTextSearch(query, memories);
}
// Update access patterns
searchResults.forEach(memory => {
memory.accessCount++;
memory.lastAccessed = new Date().toISOString();
});
const limitedResults = searchResults.slice(0, limit);
const summary = this.generateSearchSummary(limitedResults, query);
this.log('info', `🔍 Recalled ${limitedResults.length} memories for query: ${query}`);
return {
content: [{
type: 'text',
text: JSON.stringify({
success: true,
memories: limitedResults.map(memory => ({
id: memory.id,
content: memory.content,
structuredKey: memory.structuredKey,
metadata: memory.metadata,
relevanceScore: memory.relevanceScore || 0.5,
qualityScore: memory.qualityScore || 0.5,
accessCount: memory.accessCount,
lastAccessed: memory.lastAccessed,
lifecycle: memory.lifecycle,
rank: limitedResults.indexOf(memory) + 1
})),
totalFound: searchResults.length,
query,
summary,
searchOptions: { limit, minImportance, project, session, useSemanticSearch, includeArchived },
metadata: {
serverVersion: this.config.version,
operation: 'recall_memories',
timestamp: new Date().toISOString(),
searchType: useSemanticSearch ? 'semantic' : 'text'
}
}, null, 2)
}]
};
}
// Add placeholders for other handlers (to be implemented based on engine capabilities)
async handleForget(args) {
// Implementation for forget functionality
return { content: [{ type: 'text', text: 'Forget handler implementation pending' }] };
}
async handleContext(args) {
// Implementation for context functionality
return { content: [{ type: 'text', text: 'Context handler implementation pending' }] };
}
async handleGetMemory(args) {
// Implementation for get_memory functionality
return { content: [{ type: 'text', text: 'Get memory handler implementation pending' }] };
}
async handleSearchKeys(args) {
// Implementation for search_keys functionality
return { content: [{ type: 'text', text: 'Search keys handler implementation pending' }] };
}
// Additional handler placeholders for all 27 tools...
async handleLinkMemories(args) {
return { content: [{ type: 'text', text: 'Link memories handler implementation pending' }] };
}
async handleShareMemory(args) {
return { content: [{ type: 'text', text: 'Share memory handler implementation pending' }] };
}
async handleSynchronizeFederation(args) {
return { content: [{ type: 'text', text: 'Synchronize federation handler implementation pending' }] };
}
async handleGetAnalytics(args) {
return { content: [{ type: 'text', text: 'Get analytics handler implementation pending' }] };
}
async handleGetInsights(args) {
return { content: [{ type: 'text', text: 'Get insights handler implementation pending' }] };
}
async handleCollectiveInsights(args) {
return { content: [{ type: 'text', text: 'Collective insights handler implementation pending' }] };
}
async handleLearnFromUsage(args) {
return { content: [{ type: 'text', text: 'Learn from usage handler implementation pending' }] };
}
async handleGetRelationships(args) {
return { content: [{ type: 'text', text: 'Get relationships handler implementation pending' }] };
}
async handleOptimizeRetrieval(args) {
return { content: [{ type: 'text', text: 'Optimize retrieval handler implementation pending' }] };
}
async handlePredictEnhanced(args) {
return { content: [{ type: 'text', text: 'Predict enhanced handler implementation pending' }] };
}
async handlePredictEvolution(args) {
return { content: [{ type: 'text', text: 'Predict evolution handler implementation pending' }] };
}
async handlePredictStructure(args) {
return { content: [{ type: 'text', text: 'Predict structure handler implementation pending' }] };
}
async handleAdaptOrganization(args) {
return { content: [{ type: 'text', text: 'Adapt organization handler implementation pending' }] };
}
async handleCollaborativeLearning(args) {
return { content: [{ type: 'text', text: 'Collaborative learning handler implementation pending' }] };
}
async handleFederatedQuery(args) {
return { content: [{ type: 'text', text: 'Federated query handler implementation pending' }] };
}
async handleExploreGraph(args) {
return { content: [{ type: 'text', text: 'Explore graph handler implementation pending' }] };
}
async handleResolveConflicts(args) {
return { content: [{ type: 'text', text: 'Resolve conflicts handler implementation pending' }] };
}
async handleManageLifecycle(args) {
return { content: [{ type: 'text', text: 'Manage lifecycle handler implementation pending' }] };
}
async handleConsolidateMemories(args) {
return { content: [{ type: 'text', text: 'Consolidate memories handler implementation pending' }] };
}
async handleEvolveMemory(args) {
return { content: [{ type: 'text', text: 'Evolve memory handler implementation pending' }] };
}
async handleGetRecommendations(args) {
return { content: [{ type: 'text', text: 'Get recommendations handler implementation pending' }] };
}
// Utility methods
calculateCosineSimilarity(vectorA, vectorB) {
if (vectorA.length !== vectorB.length)
return 0;
const dotProduct = vectorA.reduce((sum, a, i) => sum + a * (vectorB[i] || 0), 0);
const magnitudeA = Math.sqrt(vectorA.reduce((sum, a) => sum + a * a, 0));
const magnitudeB = Math.sqrt(vectorB.reduce((sum, b) => sum + b * b, 0));
if (magnitudeA === 0 || magnitudeB === 0)
return 0;
return dotProduct / (magnitudeA * magnitudeB);
}
getNextSequenceNumber(project, session) {
const dateStr = new Date().toISOString().split('T')[0];
const date = dateStr ? dateStr.replace(/-/g, '') : 'unknown';
const prefix = `${project}_${date}_${session}_`;
const existingKeys = Array.from(this.memories.keys())
.filter(key => key.startsWith(prefix))
.map(key => {
const parts = key.split('_');
const lastPart = parts[parts.length - 1];
return lastPart ? parseInt(lastPart) || 0 : 0;
});
return existingKeys.length > 0 ? Math.max(...existingKeys) + 1 : 1;
}
calculateImportance(content, metadata) {
if (metadata.importance !== undefined)
return metadata.importance;
let score = 0.5; // Base score
// Length factor
if (content.length > 500)
score += 0.1;
if (content.length > 1000)
score += 0.1;
// Keywords that indicate importance
const importantKeywords = ['critical', 'important', 'urgent', 'key', 'essential', 'vital'];
const keywordMatches = importantKeywords.filter(keyword => content.toLowerCase().includes(keyword)).length;
score += keywordMatches * 0.05;
// Priority from metadata
if (metadata.priority === 'high')
score += 0.2;
if (metadata.priority === 'critical')
score += 0.3;
return Math.min(1.0, score);
}
calculateQualityScore(content, metadata) {
let score = 0.5; //