UNPKG

@andrebuzeli/advanced-memory-markdown-mcp

Version:

Advanced Memory Bank MCP v3.1.5 - Sistema avançado de gerenciamento de memória com isolamento de projetos por IDE, sincronização sob demanda, backup a cada 30min, apenas arquivos .md principais sincronizados, pasta reasoning temporária com limpeza automát

375 lines 19.4 kB
/** * Topic Server - MCP Server with topic-based memory system * Uses MEMORY_BANK_ROOT environment variable for storage */ import { Server } from '@modelcontextprotocol/sdk/server/index.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js'; import { TopicMemoryManager } from '../core/topic-memory-manager.js'; import { CreativeAnalyzer } from '../core/creative-analyzer.js'; import { SequentialThinking } from '../core/sequential-thinking.js'; import { MemoryManager } from '../core/memory-manager.js'; import { VERSION } from '../version.js'; const server = new Server({ name: 'advanced-memory-bank', version: VERSION, capabilities: { tools: {}, } }); // Instanciar gerenciadores const memoryManager = new MemoryManager(); const topicManager = new TopicMemoryManager(); const creativeAnalyzer = new CreativeAnalyzer(memoryManager); const sequentialThinking = new SequentialThinking(); // Lista de ferramentas (15 no total) server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [ { name: 'store-topic-memory', description: 'Armazena informações em um tópico específico do projeto (usa detecção automática se projectName não fornecido)', inputSchema: { type: 'object', properties: { projectName: { type: 'string', description: 'Nome do projeto (opcional - detecta automaticamente se não fornecido)' }, topic: { type: 'string', description: 'Nome do tópico (fixo ou personalizado)' }, content: { type: 'string', description: 'Conteúdo a ser armazenado' }, tags: { type: 'array', items: { type: 'string' }, description: 'Tags para categorização' }, importance: { type: 'number', minimum: 1, maximum: 10, description: 'Nível de importância 1-10' } }, required: ['topic', 'content'] } }, { name: 'get-topic-memory', description: 'Recupera todo o conteúdo armazenado em um tópico (usa detecção automática se projectName não fornecido)', inputSchema: { type: 'object', properties: { projectName: { type: 'string', description: 'Nome do projeto (opcional - detecta automaticamente se não fornecido)' }, topic: { type: 'string', description: 'Nome do tópico a recuperar' } }, required: ['topic'] } }, { name: 'list-topics', description: 'Lista todos os tópicos existentes no projeto (usa detecção automática se projectName não fornecido)', inputSchema: { type: 'object', properties: { projectName: { type: 'string', description: 'Nome do projeto (opcional - detecta automaticamente se não fornecido)' } }, required: [] } }, { name: 'list-all-topic-memories', description: 'Lista todas as memórias organizadas por tópicos (usa detecção automática se projectName não fornecido)', inputSchema: { type: 'object', properties: { projectName: { type: 'string', description: 'Nome do projeto (opcional - detecta automaticamente se não fornecido)' }, sortBy: { type: 'string', enum: ['timestamp', 'importance'], description: 'Critério de ordenação' }, limit: { type: 'number', minimum: 1, maximum: 200, description: 'Máximo de resultados' } }, required: [] } }, { name: 'search-topic-memories', description: 'Busca conteúdo em todos os tópicos do projeto (usa detecção automática se projectName não fornecido)', inputSchema: { type: 'object', properties: { projectName: { type: 'string', description: 'Nome do projeto (opcional - detecta automaticamente se não fornecido)' }, query: { type: 'string', description: 'Termo de busca' }, limit: { type: 'number', minimum: 1, maximum: 100, description: 'Máximo de resultados' } }, required: ['query'] } }, { name: 'update-topic-memory', description: 'Atualiza o conteúdo de um tópico existente', inputSchema: { type: 'object', properties: { projectName: { type: 'string', description: 'Nome do projeto' }, topic: { type: 'string', description: 'Nome do tópico' }, content: { type: 'string', description: 'Novo conteúdo' }, tags: { type: 'array', items: { type: 'string' }, description: 'Novas tags' }, importance: { type: 'number', minimum: 1, maximum: 10, description: 'Nova importância' } }, required: ['projectName', 'topic'] } }, { name: 'delete-topic-memory', description: 'Remove completamente um tópico e seu conteúdo', inputSchema: { type: 'object', properties: { projectName: { type: 'string', description: 'Nome do projeto' }, topic: { type: 'string', description: 'Nome do tópico a remover' } }, required: ['projectName', 'topic'] } }, { name: 'get-project-info', description: 'Obtém informações detalhadas sobre o projeto', inputSchema: { type: 'object', properties: { projectName: { type: 'string', description: 'Nome do projeto' } }, required: ['projectName'] } }, { name: 'list-projects', description: 'Lista todos os projetos disponíveis no sistema', inputSchema: { type: 'object', properties: {}, required: [] } }, { name: 'reset-project', description: 'Remove todas as memórias de um projeto', inputSchema: { type: 'object', properties: { projectName: { type: 'string', description: 'Nome do projeto' }, confirmReset: { type: 'boolean', description: 'Confirmação para reset' } }, required: ['projectName', 'confirmReset'] } }, { name: 'initialize-fixed-topics', description: 'Cria automaticamente todos os tópicos fixos padrão', inputSchema: { type: 'object', properties: { projectName: { type: 'string', description: 'Nome do projeto' } }, required: ['projectName'] } }, { name: 'list-fixed-topics', description: 'Lista todos os tópicos fixos disponíveis no sistema', inputSchema: { type: 'object', properties: {}, required: [] } }, { name: 'analyze-creative-content', description: 'Analisa conteúdo para extrair insights e padrões criativos', inputSchema: { type: 'object', properties: { content: { type: 'string', description: 'Conteúdo a ser analisado' }, analysisType: { type: 'string', enum: ['structure', 'themes', 'style', 'comprehensive'], description: 'Tipo de análise' } }, required: ['content'] } }, { name: 'sequential-thinking', description: 'Processa problemas complexos através de pensamento sequencial estruturado', inputSchema: { type: 'object', properties: { thought: { type: 'string', description: 'Pensamento/análise atual' }, thoughtNumber: { type: 'number', minimum: 1, description: 'Número do pensamento atual' }, totalThoughts: { type: 'number', minimum: 1, description: 'Total estimado de pensamentos' }, nextThoughtNeeded: { type: 'boolean', description: 'Se precisa de próximo pensamento' } }, required: ['thought', 'thoughtNumber', 'totalThoughts', 'nextThoughtNeeded'] } } ] }; }); // Handler para execução das ferramentas server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; // Verificação de tipos if (!args || typeof args !== 'object') { return { content: [{ type: 'text', text: 'Argumentos inválidos fornecidos' }], isError: true }; } try { switch (name) { case 'store-topic-memory': // Use detecção automática se projectName não fornecido const storeProjectName = args.projectName || topicManager.getCurrentProjectName(); await topicManager.storeTopicMemory(storeProjectName, args.topic, args.content, args.tags || [], args.importance || 5); return { content: [{ type: 'text', text: `Memória armazenada no tópico '${args.topic}' do projeto '${storeProjectName}'` }] }; case 'get-topic-memory': // Use detecção automática se projectName não fornecido const getProjectName = args.projectName || topicManager.getCurrentProjectName(); const memory = await topicManager.getTopicMemory(getProjectName, args.topic); if (!memory) { return { content: [{ type: 'text', text: `Tópico '${args.topic}' não encontrado no projeto '${getProjectName}'` }] }; } return { content: [{ type: 'text', text: `**Tópico: ${args.topic}**\n\n${memory.content}\n\n**Tags:** ${memory.tags.join(', ')}\n**Importância:** ${memory.importance}/10\n**Modificado:** ${new Date(memory.lastModified).toLocaleString()}` }] }; case 'list-topics': // Use detecção automática se projectName não fornecido const listProjectName = args.projectName || topicManager.getCurrentProjectName(); const topics = await topicManager.listTopics(listProjectName); return { content: [{ type: 'text', text: `**Tópicos do projeto '${listProjectName}':**\n${topics.length > 0 ? topics.map(t => `- ${t}`).join('\n') : 'Nenhum tópico encontrado'}` }] }; case 'list-all-topic-memories': // Use detecção automática se projectName não fornecido const allProjectName = args.projectName || topicManager.getCurrentProjectName(); const allMemories = await topicManager.listAllTopicMemories(allProjectName); const memoryList = Object.entries(allMemories) .map(([topic, memory]) => `**${topic}** (${memory.importance}/10) - ${memory.content.substring(0, 100)}...`) .join('\n\n'); return { content: [{ type: 'text', text: `**Todas as memórias do projeto '${allProjectName}':**\n\n${memoryList || 'Nenhuma memória encontrada'}` }] }; case 'search-topic-memories': // Use detecção automática se projectName não fornecido const searchProjectName = args.projectName || topicManager.getCurrentProjectName(); const searchResults = await topicManager.searchTopicMemories(searchProjectName, args.query, args.limit || 100); const resultsText = searchResults .map(r => `**${r.topic}** (score: ${r.score}) - ${r.memory.content.substring(0, 150)}...`) .join('\n\n'); return { content: [{ type: 'text', text: `**Resultados da busca por '${args.query}' no projeto '${searchProjectName}':**\n\n${resultsText || 'Nenhum resultado encontrado'}` }] }; case 'update-topic-memory': await topicManager.updateTopicMemory(args.projectName, args.topic, args.content, args.tags, args.importance); return { content: [{ type: 'text', text: `Tópico '${args.topic}' atualizado no projeto '${args.projectName}'` }] }; case 'delete-topic-memory': await topicManager.deleteTopicMemory(args.projectName, args.topic); return { content: [{ type: 'text', text: `Tópico '${args.topic}' removido do projeto '${args.projectName}'` }] }; case 'get-project-info': const projectInfo = await topicManager.getProjectInfo(args.projectName); if (!projectInfo) { return { content: [{ type: 'text', text: `Projeto '${args.projectName}' não encontrado` }] }; } return { content: [{ type: 'text', text: `**Projeto: ${projectInfo.name}**\n\n- Tópicos: ${projectInfo.topicCount}\n- Memórias: ${projectInfo.memoryCount}\n- Importância total: ${projectInfo.totalImportance}\n- Criado: ${new Date(projectInfo.createdAt).toLocaleString()}\n- Modificado: ${new Date(projectInfo.lastModified).toLocaleString()}` }] }; case 'list-projects': const projects = await topicManager.listProjects(); return { content: [{ type: 'text', text: `**Projetos disponíveis:**\n${projects.length > 0 ? projects.map(p => `- ${p}`).join('\n') : 'Nenhum projeto encontrado'}\n\n**Diretório de memórias:** ${topicManager.getMemoryRootPath()}` }] }; case 'reset-project': if (!args.confirmReset) { return { content: [{ type: 'text', text: `Reset cancelado. Para confirmar, defina confirmReset como true.` }] }; } await topicManager.resetProject(args.projectName); return { content: [{ type: 'text', text: `Projeto '${args.projectName}' resetado com sucesso` }] }; case 'initialize-fixed-topics': await topicManager.initializeFixedTopics(args.projectName); const fixedTopics = topicManager.getFixedTopics(); return { content: [{ type: 'text', text: `Tópicos fixos inicializados no projeto '${args.projectName}':\n${fixedTopics.map(t => `- ${t}`).join('\n')}` }] }; case 'list-fixed-topics': const availableTopics = topicManager.getFixedTopics(); return { content: [{ type: 'text', text: `**Tópicos fixos disponíveis:**\n${availableTopics.map(t => `- ${t}`).join('\n')}` }] }; case 'analyze-creative-content': const analysis = await creativeAnalyzer.analyzeContent(args.content, args.analysisType || 'comprehensive'); return { content: [{ type: 'text', text: `**Análise Criativa:**\n\n**Padrões:** ${analysis.patterns?.join(', ') || 'N/A'}\n**Temas:** ${analysis.themes?.join(', ') || 'N/A'}\n**Estilo:** ${analysis.styleElements?.join(', ') || 'N/A'}\n**Insights:** ${analysis.insights.join('\n- ')}` }] }; case 'sequential-thinking': const thinkingResult = await sequentialThinking.processThought(args.thought, args.thoughtNumber, args.totalThoughts, args.nextThoughtNeeded); return { content: [{ type: 'text', text: `**Pensamento ${thinkingResult.thoughtNumber}/${thinkingResult.totalThoughts}:**\n\n${thinkingResult.content}\n\n**Status:** ${thinkingResult.status}\n**Próximo pensamento necessário:** ${thinkingResult.nextThoughtNeeded ? 'Sim' : 'Não'}` }] }; default: throw new Error(`Ferramenta desconhecida: ${name}`); } } catch (error) { return { content: [{ type: 'text', text: `Erro ao executar ${name}: ${error instanceof Error ? error.message : String(error)}` }], isError: true }; } }); // Inicializar servidor async function main() { const transport = new StdioServerTransport(); await server.connect(transport); // Log do diretório sendo usado (apenas em desenvolvimento) if (process.env.NODE_ENV !== 'production') { console.error(`[TopicServer v${VERSION}] Iniciado`); console.error(`[TopicServer v${VERSION}] Diretório de memórias: ${topicManager.getMemoryRootPath()}`); console.error(`[TopicServer v${VERSION}] MEMORY_BANK_ROOT: ${process.env.MEMORY_BANK_ROOT || 'não definido'}`); } } main().catch(console.error); //# sourceMappingURL=topic-server.js.map