Skip to main content
Glama

Memory MCP Server

by win10ogod
index.js7.28 kB
#!/usr/bin/env node /** * Memory MCP Server * A Model Context Protocol server providing dynamic short-term and long-term memory management */ 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 { ShortTermMemoryManager } from './memory/short-term.js'; import { LongTermMemoryManager } from './memory/long-term.js'; import { StorageManager } from './memory/storage.js'; import { createShortTermTools } from './tools/short-term-tools.js'; import { createLongTermTools } from './tools/long-term-tools.js'; import { zodToJsonSchema } from './utils/zod-to-json-schema.js'; // 全局管理器映射(按 conversation_id) const shortTermManagers = new Map(); const longTermManagers = new Map(); const storageManagers = new Map(); /** * 获取或创建短期记忆管理器 * @param {string} conversationId * @returns {Promise<ShortTermMemoryManager>} */ async function getShortTermManager(conversationId) { if (!shortTermManagers.has(conversationId)) { const manager = new ShortTermMemoryManager(); const storage = getStorageManager(conversationId); const memories = await storage.loadShortTermMemories(); manager.loadMemories(memories); shortTermManagers.set(conversationId, manager); } return shortTermManagers.get(conversationId); } /** * 获取或创建长期记忆管理器 * @param {string} conversationId * @returns {Promise<LongTermMemoryManager>} */ async function getLongTermManager(conversationId) { if (!longTermManagers.has(conversationId)) { const manager = new LongTermMemoryManager(); const storage = getStorageManager(conversationId); const memories = await storage.loadLongTermMemories(); manager.loadMemories(memories); longTermManagers.set(conversationId, manager); } return longTermManagers.get(conversationId); } /** * 获取或创建存储管理器 * @param {string} conversationId * @returns {StorageManager} */ function getStorageManager(conversationId) { if (!storageManagers.has(conversationId)) { const manager = new StorageManager(conversationId); storageManagers.set(conversationId, manager); } return storageManagers.get(conversationId); } /** * 创建 MCP 服务器 */ async function createServer() { const server = new Server( { name: 'memory-mcp-server', version: '0.1.0', }, { capabilities: { tools: {}, }, } ); // 工具注册表 const toolRegistry = new Map(); // 注册工具的辅助函数 function registerTool(toolDef, scope) { toolRegistry.set(toolDef.name, { ...toolDef, scope }); } // 动态创建工具(使用默认 conversation_id) const defaultConversationId = 'default'; const defaultShortTermManager = await getShortTermManager(defaultConversationId); const defaultLongTermManager = await getLongTermManager(defaultConversationId); const defaultStorageManager = getStorageManager(defaultConversationId); // 注册所有短期记忆工具 const shortTermTools = createShortTermTools(defaultShortTermManager, defaultStorageManager); shortTermTools.forEach(tool => registerTool(tool, 'short-term')); // 注册所有长期记忆工具 const longTermTools = createLongTermTools(defaultLongTermManager, defaultStorageManager); longTermTools.forEach(tool => registerTool(tool, 'long-term')); // 处理 list_tools 请求 server.setRequestHandler(ListToolsRequestSchema, async () => { const tools = Array.from(toolRegistry.values()).map(tool => ({ name: tool.name, description: tool.description, inputSchema: zodToJsonSchema(tool.inputSchema) })); return { tools }; }); // 处理 call_tool 请求 server.setRequestHandler(CallToolRequestSchema, async (request) => { const toolName = request.params.name; const toolDef = toolRegistry.get(toolName); if (!toolDef) { return { content: [ { type: 'text', text: `Unknown tool: ${toolName}` } ], isError: true }; } try { // 验证参数 const validatedArgs = toolDef.inputSchema.parse(request.params.arguments); // 如果工具需要特定的 conversation_id,获取对应的管理器 const conversationId = validatedArgs.conversation_id || defaultConversationId; const toolScope = toolDef.scope; let manager, storage; if (toolScope === 'short-term' || toolName.includes('short_term')) { manager = await getShortTermManager(conversationId); storage = getStorageManager(conversationId); // 重新创建工具以使用正确的管理器 const tools = createShortTermTools(manager, storage); const tool = tools.find(t => t.name === toolName); const result = await tool.handler(validatedArgs); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2) } ] }; } else if (toolScope === 'long-term' || toolName.includes('long_term')) { manager = await getLongTermManager(conversationId); storage = getStorageManager(conversationId); // 重新创建工具以使用正确的管理器 const tools = createLongTermTools(manager, storage); const tool = tools.find(t => t.name === toolName); const result = await tool.handler(validatedArgs); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2) } ] }; } else { // 对于其他工具,直接调用 const result = await toolDef.handler(validatedArgs); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2) } ] }; } } catch (error) { if (error.name === 'ZodError') { return { content: [ { type: 'text', text: `Invalid arguments: ${JSON.stringify(error.errors, null, 2)}` } ], isError: true }; } console.error(`Error executing tool ${toolName}:`, error); return { content: [ { type: 'text', text: `Error: ${error.message}` } ], isError: true }; } }); return server; } /** * 启动服务器 */ async function main() { try { const server = await createServer(); const transport = new StdioServerTransport(); await server.connect(transport); console.error('Memory MCP Server running on stdio'); console.error('Server initialized with short-term and long-term memory capabilities'); } catch (error) { console.error('Fatal error starting server:', error); process.exit(1); } } main(); export { createServer };

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/win10ogod/memory-mcp-server'

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