@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
JavaScript
/**
* 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