openmemory
Version:
A Model Context Protocol (MCP) server that provides memory storage and retrieval capabilities using [Mem0](https://github.com/mem0ai/mem0). This tool allows you to store and search through memories, making it useful for maintaining context and making info
1 lines • 14.7 kB
Source Map (JSON)
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport {\n Tool,\n CallToolRequestSchema,\n ListToolsRequestSchema,\n} from '@modelcontextprotocol/sdk/types.js';\nimport dotenv from 'dotenv';\n\ndotenv.config();\n\nconst OPENMEMORY_API_KEY = process?.env?.OPENMEMORY_API_KEY || '';\nconst HOST = process?.env?.HOST || 'api.openmemory.dev';\nconst CLIENT_NAME = process?.env?.CLIENT_NAME || 'openmemory';\nconst HTTP_PROTOCOL = process?.env?.HTTP_PROTOCOL || 'https';\nconst ASYNC_MODE = process?.env?.ASYNC_MODE || true;\n\n// OpenMemory API base URL\nconst API_BASE_URL = `${HTTP_PROTOCOL}://${HOST}`;\n\n// Tool definitions\nconst ADD_MEMORY_TOOL: Tool = {\n name: 'add-memory',\n description:\n 'Add a new memory. This method is called everytime the user informs anything about themselves, their preferences, or anything that has any relevent information whcih can be useful in the future conversation. This can also be called when the user asks you to remember something.',\n inputSchema: {\n type: 'object',\n properties: {\n content: {\n type: 'string',\n description: 'The content to store in memory',\n },\n },\n required: ['content'],\n },\n};\n\nconst SEARCH_MEMORIES_TOOL: Tool = {\n name: 'search-memories',\n description: 'Search through stored memories. This method is called ANYTIME the user asks anything.',\n inputSchema: {\n type: 'object',\n properties: {\n query: {\n type: 'string',\n description: \"The search query. This is the query that the user has asked for. Example: 'What did I tell you about the weather last week?' or 'What did I tell you about my friend John?'\",\n },\n },\n required: ['query'],\n },\n};\n\nconst LIST_MEMORIES_TOOL: Tool = {\n name: 'list-memories',\n description: 'List all memories in the user\\'s memory storage.',\n inputSchema: {\n type: 'object',\n properties: {},\n required: [],\n },\n};\n\nconst DELETE_ALL_MEMORIES_TOOL: Tool = {\n name: 'delete-all-memories',\n description: 'Delete all memories in the user\\'s memory storage. Use with caution as this action cannot be undone.',\n inputSchema: {\n type: 'object',\n properties: {},\n required: [],\n },\n};\n\n// Create server instance\nconst server = new Server(\n {\n name: 'openmemory',\n version: '0.0.1',\n },\n {\n capabilities: {\n tools: {},\n logging: {},\n },\n }\n);\n\n// Helper function to add memories\nasync function addMemory(content: string) {\n try {\n const response = await fetch(`${API_BASE_URL}/mcp/add_memories`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${OPENMEMORY_API_KEY}`,\n },\n body: JSON.stringify({\n text: content,\n client_name: CLIENT_NAME,\n async_mode: ASYNC_MODE || true,\n }),\n });\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const result = await response.json();\n return result.status === 'success';\n } catch (error) {\n console.error('Error adding memory:', error);\n return false;\n }\n}\n\n// Helper function to search memories\nasync function searchMemories(query: string) {\n try {\n const response = await fetch(`${API_BASE_URL}/mcp/search_memory`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${OPENMEMORY_API_KEY}`,\n },\n body: JSON.stringify({\n query: query,\n client_name: CLIENT_NAME,\n }),\n });\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const result = await response.json();\n return result.memories || [];\n } catch (error) {\n console.error('Error searching memories:', error);\n return [];\n }\n}\n\n// Helper function to list all memories\nasync function listMemories() {\n try {\n const response = await fetch(`${API_BASE_URL}/mcp/list_memories`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${OPENMEMORY_API_KEY}`,\n },\n body: JSON.stringify({\n client_name: CLIENT_NAME,\n }),\n });\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const result = await response.json();\n return result.memories || [];\n } catch (error) {\n console.error('Error listing memories:', error);\n return [];\n }\n}\n\n// Helper function to delete all memories\nasync function deleteAllMemories() {\n try {\n const response = await fetch(`${API_BASE_URL}/mcp/delete_all_memories`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${OPENMEMORY_API_KEY}`,\n },\n body: JSON.stringify({\n client_name: CLIENT_NAME,\n }),\n });\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const result = await response.json();\n return result;\n } catch (error) {\n console.error('Error deleting all memories:', error);\n return { status: 'error', message: 'Failed to delete memories' };\n }\n}\n\n// Register tool handlers\nserver.setRequestHandler(ListToolsRequestSchema, async () => ({\n tools: [ADD_MEMORY_TOOL, SEARCH_MEMORIES_TOOL, LIST_MEMORIES_TOOL, DELETE_ALL_MEMORIES_TOOL],\n}));\n\nserver.setRequestHandler(CallToolRequestSchema, async (request) => {\n try {\n const { name, arguments: args } = request.params;\n \n if (!args) {\n throw new Error('No arguments provided');\n }\n \n switch (name) {\n case 'add-memory': {\n const { content } = args as { content: string };\n await addMemory(content);\n return {\n content: [\n {\n type: 'text',\n text: 'Memory added successfully',\n },\n ],\n isError: false,\n };\n }\n \n case 'search-memories': {\n const { query } = args as { query: string };\n const results = await searchMemories(query);\n const formattedResults = results.map((result: any) => \n `Memory: ${result.memory || result.text}\\nRelevance: ${result.score || 'N/A'}\\n---`\n ).join('\\n');\n \n return {\n content: [\n {\n type: 'text',\n text: formattedResults || 'No memories found',\n },\n ],\n isError: false,\n };\n }\n \n case 'list-memories': {\n const results = await listMemories();\n const formattedResults = results.map((result: any, index: number) => \n `${index + 1}. Memory: ${result.memory || result.text}\\nID: ${result.id || 'N/A'}\\n---`\n ).join('\\n');\n \n return {\n content: [\n {\n type: 'text',\n text: formattedResults || 'No memories found',\n },\n ],\n isError: false,\n };\n }\n \n case 'delete-all-memories': {\n const result = await deleteAllMemories();\n const message = result.status === 'success' \n ? result.message || 'All memories deleted successfully'\n : result.message || 'Failed to delete memories';\n \n return {\n content: [\n {\n type: 'text',\n text: message,\n },\n ],\n isError: result.status !== 'success',\n };\n }\n \n default:\n return {\n content: [\n { type: 'text', text: `Unknown tool: ${name}` },\n ],\n isError: true,\n };\n }\n } catch (error) {\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n isError: true,\n };\n }\n});\n\n// Function to log safely\nfunction safeLog(\n level: 'error' | 'debug' | 'info' | 'notice' | 'warning' | 'critical' | 'alert' | 'emergency',\n data: any\n): void {\n // For stdio transport, log to stderr to avoid protocol interference\n console.error(`[${level}] ${typeof data === 'object' ? JSON.stringify(data) : data}`);\n \n // Send to logging capability if available\n try {\n server.sendLoggingMessage({ level, data });\n } catch (error) {\n // Ignore errors when logging is not available\n }\n}\n\n// Server startup\nasync function main() {\n try {\n console.error('Initializing OpenMemory MCP Server...');\n console.error(`Connecting to OpenMemory API at: ${API_BASE_URL}`);\n console.error(`Using client name: ${CLIENT_NAME}`);\n \n const transport = new StdioServerTransport();\n await server.connect(transport);\n \n safeLog('info', 'OpenMemory MCP Server initialized successfully');\n console.error('OpenMemory MCP Server running on stdio');\n } catch (error) {\n console.error('Fatal error running server:', error);\n process.exit(1);\n }\n}\n\nmain().catch((error) => {\n console.error('Fatal error in main():', error);\n process.exit(1);\n});"],"mappings":"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","names":["dotenv"]}