@memoryrelay/mcp-server 0.1.9 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -77,7 +77,7 @@ Edit `~/Library/Application Support/Claude/claude_desktop_config.json`:
77
77
  ```json
78
78
  {
79
79
  "mcpServers": {
80
- "memoryrelay": {
80
+ "MemoryRelay": {
81
81
  "command": "npx",
82
82
  "args": ["-y", "@memoryrelay/mcp-server"],
83
83
  "env": {
@@ -103,7 +103,7 @@ npm install -g @memoryrelay/mcp-server
103
103
  ```json
104
104
  {
105
105
  "mcpServers": {
106
- "memoryrelay": {
106
+ "MemoryRelay": {
107
107
  "command": "node",
108
108
  "args": ["%APPDATA%\\npm\\node_modules\\@memoryrelay\\mcp-server\\dist\\index.js"],
109
109
  "env": {
@@ -664,6 +664,12 @@ Contributions welcome! Please open an issue or pull request on [GitHub](https://
664
664
 
665
665
  ## šŸ“ Changelog
666
666
 
667
+ ### v0.2.0 (2026-02-15)
668
+
669
+ - **CRITICAL FIX**: All memory API endpoints now use correct paths (store, search, list, get, update, delete all work)
670
+ - Fix health check endpoint path
671
+ - Config examples now use `MemoryRelay` display name for Claude Desktop
672
+
667
673
  ### v0.1.9 (2026-02-15)
668
674
 
669
675
  - Add Windows-specific Claude Desktop setup instructions (global install + `node` command)
package/dist/index.js CHANGED
@@ -235,7 +235,7 @@ var MemoryRelayClient = class {
235
235
  */
236
236
  async storeMemory(content, metadata) {
237
237
  this.validateContentSize(content);
238
- return this.request("POST", "/v1/memories/memories", {
238
+ return this.request("POST", "/v1/memories", {
239
239
  content,
240
240
  metadata,
241
241
  agent_id: this.config.agentId
@@ -248,7 +248,7 @@ var MemoryRelayClient = class {
248
248
  this.validateContentSize(query);
249
249
  const response = await this.request(
250
250
  "POST",
251
- "/v1/memories/memories/search",
251
+ "/v1/memories/search",
252
252
  { query, limit, threshold, agent_id: this.config.agentId }
253
253
  );
254
254
  return response.data;
@@ -259,21 +259,21 @@ var MemoryRelayClient = class {
259
259
  async listMemories(limit = 20, offset = 0) {
260
260
  return this.request(
261
261
  "GET",
262
- `/v1/memories/memories?limit=${limit}&offset=${offset}`
262
+ `/v1/memories?limit=${limit}&offset=${offset}`
263
263
  );
264
264
  }
265
265
  /**
266
266
  * Get a specific memory by ID
267
267
  */
268
268
  async getMemory(id) {
269
- return this.request("GET", `/v1/memories/memories/${id}`);
269
+ return this.request("GET", `/v1/memories/${id}`);
270
270
  }
271
271
  /**
272
272
  * Update an existing memory
273
273
  */
274
274
  async updateMemory(id, content, metadata) {
275
275
  this.validateContentSize(content);
276
- return this.request("PATCH", `/v1/memories/memories/${id}`, {
276
+ return this.request("PATCH", `/v1/memories/${id}`, {
277
277
  content,
278
278
  metadata
279
279
  });
@@ -282,7 +282,7 @@ var MemoryRelayClient = class {
282
282
  * Delete a memory
283
283
  */
284
284
  async deleteMemory(id) {
285
- await this.request("DELETE", `/v1/memories/memories/${id}`);
285
+ await this.request("DELETE", `/v1/memories/${id}`);
286
286
  }
287
287
  /**
288
288
  * Create a named entity
@@ -331,7 +331,7 @@ var MemoryRelayClient = class {
331
331
  */
332
332
  async healthCheck() {
333
333
  try {
334
- await this.request("GET", "/v1/health");
334
+ await this.request("GET", "/health");
335
335
  return {
336
336
  status: "healthy",
337
337
  message: "API connection successful"
@@ -366,7 +366,7 @@ var MemoryRelayMCPServer = class {
366
366
  this.server = new Server(
367
367
  {
368
368
  name: "@memoryrelay/mcp-server",
369
- version: "0.1.9"
369
+ version: "0.2.0"
370
370
  },
371
371
  {
372
372
  capabilities: {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/config.ts","../src/logger.ts","../src/server.ts","../src/client.ts","../src/index.ts"],"sourcesContent":["import { z } from 'zod';\n\n/**\n * Configuration schema with security validation\n */\nexport const configSchema = z.object({\n apiKey: z.string()\n .startsWith('mem_', { message: 'API key must start with \"mem_\"' })\n .min(20, { message: 'API key appears to be invalid (too short)' }),\n apiUrl: z.string()\n .url({ message: 'API URL must be a valid URL' })\n .default('https://api.memoryrelay.net'),\n agentId: z.string()\n .optional()\n .describe('Agent identifier - auto-detected if not provided'),\n timeout: z.number()\n .positive({ message: 'Timeout must be positive' })\n .default(30000),\n logLevel: z.enum(['debug', 'info', 'warn', 'error'])\n .default('info'),\n});\n\nexport type Config = z.infer<typeof configSchema>;\n\n/**\n * Load and validate configuration from environment variables\n */\nexport function loadConfig(): Config {\n try {\n const config = configSchema.parse({\n apiKey: process.env.MEMORYRELAY_API_KEY,\n apiUrl: process.env.MEMORYRELAY_API_URL,\n agentId: process.env.MEMORYRELAY_AGENT_ID,\n timeout: process.env.MEMORYRELAY_TIMEOUT \n ? parseInt(process.env.MEMORYRELAY_TIMEOUT, 10) \n : undefined,\n logLevel: process.env.MEMORYRELAY_LOG_LEVEL,\n });\n\n return config;\n } catch (error) {\n if (error instanceof z.ZodError) {\n const issues = error.issues.map(issue => \n ` - ${issue.path.join('.')}: ${issue.message}`\n ).join('\\n');\n \n throw new Error(\n `Configuration validation failed:\\n${issues}\\n\\n` +\n 'Please check your environment variables:\\n' +\n ' - MEMORYRELAY_API_KEY (required, starts with \"mem_\")\\n' +\n ' - MEMORYRELAY_API_URL (optional, default: https://api.memoryrelay.net)\\n' +\n ' - MEMORYRELAY_AGENT_ID (optional, auto-detected)\\n' +\n ' - MEMORYRELAY_TIMEOUT (optional, default: 30000)\\n' +\n ' - MEMORYRELAY_LOG_LEVEL (optional, default: info)'\n );\n }\n throw error;\n }\n}\n\n/**\n * Get or generate agent ID\n */\nexport function getAgentId(config: Config): string {\n if (config.agentId) {\n return config.agentId;\n }\n\n // Check OpenClaw agent name\n if (process.env.OPENCLAW_AGENT_NAME) {\n return process.env.OPENCLAW_AGENT_NAME;\n }\n\n // Auto-generate from hostname\n const hostname = process.env.HOSTNAME || 'unknown';\n return `agent-${hostname.slice(0, 8)}`;\n}\n","/**\n * Security-hardened logger for MCP server\n * \n * - All output to stderr (stdout reserved for MCP protocol)\n * - Automatic masking of API keys (anything starting with \"mem_\")\n * - No internal paths in error messages\n */\n\ntype LogLevel = 'debug' | 'info' | 'warn' | 'error';\n\nconst LOG_LEVELS: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n};\n\nexport class Logger {\n private minLevel: number;\n\n constructor(level: LogLevel = 'info') {\n this.minLevel = LOG_LEVELS[level];\n }\n\n /**\n * Mask sensitive data in log messages\n * - API keys starting with \"mem_\" are masked\n * - Internal paths are sanitized\n */\n private sanitize(message: string): string {\n let sanitized = message;\n\n // Mask API keys (mem_xxx -> mem_****)\n sanitized = sanitized.replace(/mem_[a-zA-Z0-9_-]+/g, 'mem_****');\n\n // Remove internal paths (anything that looks like a file path)\n sanitized = sanitized.replace(/\\/[a-zA-Z0-9_\\-./]+\\.(ts|js|json)/g, '<file>');\n sanitized = sanitized.replace(/at\\s+[^\\s]+\\s+\\([^)]+\\)/g, 'at <location>');\n\n return sanitized;\n }\n\n /**\n * Format log message with timestamp and level\n */\n private format(level: LogLevel, message: string, data?: unknown): string {\n const timestamp = new Date().toISOString();\n const sanitizedMessage = this.sanitize(message);\n \n let output = `[${timestamp}] [${level.toUpperCase()}] ${sanitizedMessage}`;\n \n if (data !== undefined) {\n const sanitizedData = this.sanitize(JSON.stringify(data, null, 2));\n output += `\\n${sanitizedData}`;\n }\n \n return output;\n }\n\n debug(message: string, data?: unknown): void {\n if (this.minLevel <= LOG_LEVELS.debug) {\n console.error(this.format('debug', message, data));\n }\n }\n\n info(message: string, data?: unknown): void {\n if (this.minLevel <= LOG_LEVELS.info) {\n console.error(this.format('info', message, data));\n }\n }\n\n warn(message: string, data?: unknown): void {\n if (this.minLevel <= LOG_LEVELS.warn) {\n console.error(this.format('warn', message, data));\n }\n }\n\n error(message: string, data?: unknown): void {\n if (this.minLevel <= LOG_LEVELS.error) {\n console.error(this.format('error', message, data));\n }\n }\n}\n\n// Export singleton instance\nlet logger: Logger;\n\nexport function initLogger(level: LogLevel = 'info'): Logger {\n logger = new Logger(level);\n return logger;\n}\n\nexport function getLogger(): Logger {\n if (!logger) {\n logger = new Logger();\n }\n return logger;\n}\n","/**\n * MCP Server implementation for MemoryRelay\n */\n\nimport { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n ListResourcesRequestSchema,\n ListResourceTemplatesRequestSchema,\n ReadResourceRequestSchema,\n ListPromptsRequestSchema,\n GetPromptRequestSchema,\n} from '@modelcontextprotocol/sdk/types.js';\nimport { z } from 'zod';\nimport { MemoryRelayClient } from './client.js';\nimport { getLogger } from './logger.js';\nimport type { ClientConfig } from './types.js';\n\ndeclare const __VERSION__: string;\n\n/**\n * HTML-encode string to prevent XSS\n */\nfunction sanitizeHtml(str: string): string {\n return str\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#x27;')\n .replace(/\\//g, '&#x2F;');\n}\n\n/**\n * Validate UUID format\n */\nconst uuidSchema = z.string().uuid();\n\nfunction validateUuid(id: string, fieldName: string = 'id'): void {\n const result = uuidSchema.safeParse(id);\n if (!result.success) {\n throw new Error(`Invalid ${fieldName}: must be a valid UUID`);\n }\n}\n\nexport class MemoryRelayMCPServer {\n private server: Server;\n private client: MemoryRelayClient;\n private logger = getLogger();\n\n constructor(config: ClientConfig) {\n this.client = new MemoryRelayClient(config);\n \n this.server = new Server(\n {\n name: '@memoryrelay/mcp-server',\n version: __VERSION__,\n },\n {\n capabilities: {\n tools: {},\n resources: {},\n prompts: {},\n },\n }\n );\n\n this.setupToolHandlers();\n this.setupResourceHandlers();\n this.setupPromptHandlers();\n this.logger.info('MCP server initialized');\n }\n\n /**\n * Setup MCP tool handlers\n */\n private setupToolHandlers(): void {\n // List available tools\n this.server.setRequestHandler(ListToolsRequestSchema, async () => ({\n tools: [\n {\n name: 'memory_store',\n description: 'Store a new memory. Use this to save important information, facts, preferences, or context that should be remembered for future conversations.',\n inputSchema: {\n type: 'object',\n properties: {\n content: {\n type: 'string',\n description: 'The memory content to store. Be specific and include relevant context.',\n },\n metadata: {\n type: 'object',\n description: 'Optional key-value metadata to attach to the memory',\n additionalProperties: { type: 'string' },\n },\n },\n required: ['content'],\n },\n },\n {\n name: 'memory_search',\n description: 'Search memories using natural language. Returns the most relevant memories based on semantic similarity to the query.',\n inputSchema: {\n type: 'object',\n properties: {\n query: {\n type: 'string',\n description: 'Natural language search query',\n },\n limit: {\n type: 'number',\n description: 'Maximum number of results to return (1-50)',\n minimum: 1,\n maximum: 50,\n default: 10,\n },\n threshold: {\n type: 'number',\n description: 'Minimum similarity threshold (0-1)',\n minimum: 0,\n maximum: 1,\n default: 0.5,\n },\n },\n required: ['query'],\n },\n },\n {\n name: 'memory_list',\n description: 'List recent memories chronologically. Use to review what has been remembered.',\n inputSchema: {\n type: 'object',\n properties: {\n limit: {\n type: 'number',\n description: 'Number of memories to return (1-100)',\n minimum: 1,\n maximum: 100,\n default: 20,\n },\n offset: {\n type: 'number',\n description: 'Offset for pagination',\n minimum: 0,\n default: 0,\n },\n },\n },\n },\n {\n name: 'memory_get',\n description: 'Retrieve a specific memory by its ID.',\n inputSchema: {\n type: 'object',\n properties: {\n id: {\n type: 'string',\n description: 'The memory ID (UUID) to retrieve',\n },\n },\n required: ['id'],\n },\n },\n {\n name: 'memory_update',\n description: 'Update the content of an existing memory. Use to correct or expand stored information.',\n inputSchema: {\n type: 'object',\n properties: {\n id: {\n type: 'string',\n description: 'The memory ID (UUID) to update',\n },\n content: {\n type: 'string',\n description: 'The new content to replace the existing memory',\n },\n metadata: {\n type: 'object',\n description: 'Updated metadata (replaces existing)',\n additionalProperties: { type: 'string' },\n },\n },\n required: ['id', 'content'],\n },\n },\n {\n name: 'memory_delete',\n description: 'Permanently delete a memory. Use sparingly - memories are valuable context.',\n inputSchema: {\n type: 'object',\n properties: {\n id: {\n type: 'string',\n description: 'The memory ID (UUID) to delete',\n },\n },\n required: ['id'],\n },\n },\n {\n name: 'entity_create',\n description: 'Create a named entity (person, place, organization, project, concept) for the knowledge graph. Entities help organize and connect memories.',\n inputSchema: {\n type: 'object',\n properties: {\n name: {\n type: 'string',\n minLength: 1,\n maxLength: 200,\n description: 'Entity name (1-200 characters)',\n },\n type: {\n type: 'string',\n enum: ['person', 'place', 'organization', 'project', 'concept', 'other'],\n description: 'Entity type classification',\n },\n metadata: {\n type: 'object',\n description: 'Optional key-value metadata',\n additionalProperties: { type: 'string' },\n },\n },\n required: ['name', 'type'],\n },\n },\n {\n name: 'entity_link',\n description: 'Link an entity to a memory to establish relationships in the knowledge graph.',\n inputSchema: {\n type: 'object',\n properties: {\n entity_id: {\n type: 'string',\n description: 'Entity UUID',\n },\n memory_id: {\n type: 'string',\n description: 'Memory UUID',\n },\n relationship: {\n type: 'string',\n description: 'Relationship type (e.g., \"mentioned_in\", \"created_by\", \"relates_to\")',\n default: 'mentioned_in',\n },\n },\n required: ['entity_id', 'memory_id'],\n },\n },\n {\n name: 'memory_health',\n description: 'Check API connectivity and health status.',\n inputSchema: {\n type: 'object',\n properties: {},\n },\n },\n ],\n }));\n\n // Handle tool calls\n this.server.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args = {} } = request.params;\n\n this.logger.debug(`Tool called: ${name}`, args);\n\n try {\n switch (name) {\n case 'memory_store': {\n const memory = await this.client.storeMemory(\n args.content as string,\n args.metadata as Record<string, string> | undefined\n );\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(memory, null, 2),\n },\n ],\n };\n }\n\n case 'memory_search': {\n const results = await this.client.searchMemories(\n args.query as string,\n args.limit as number | undefined,\n args.threshold as number | undefined\n );\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n { memories: results, total: results.length },\n null,\n 2\n ),\n },\n ],\n };\n }\n\n case 'memory_list': {\n const response = await this.client.listMemories(\n args.limit as number | undefined,\n args.offset as number | undefined\n );\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(response, null, 2),\n },\n ],\n };\n }\n\n case 'memory_get': {\n const id = args.id as string;\n validateUuid(id, 'memory_id');\n\n const memory = await this.client.getMemory(id);\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(memory, null, 2),\n },\n ],\n };\n }\n\n case 'memory_update': {\n const id = args.id as string;\n validateUuid(id, 'memory_id');\n\n const memory = await this.client.updateMemory(\n id,\n args.content as string,\n args.metadata as Record<string, string> | undefined\n );\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(memory, null, 2),\n },\n ],\n };\n }\n\n case 'memory_delete': {\n const id = args.id as string;\n validateUuid(id, 'memory_id');\n\n await this.client.deleteMemory(id);\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n { success: true, message: 'Memory deleted successfully' },\n null,\n 2\n ),\n },\n ],\n };\n }\n\n case 'entity_create': {\n // Validate input schema\n const entitySchema = z.object({\n name: z.string().min(1).max(200),\n type: z.enum(['person', 'place', 'organization', 'project', 'concept', 'other']),\n metadata: z.record(z.string()).optional(),\n });\n\n const validatedInput = entitySchema.parse(args);\n \n // Sanitize name to prevent XSS\n const sanitizedName = sanitizeHtml(validatedInput.name);\n \n const entity = await this.client.createEntity(\n sanitizedName,\n validatedInput.type,\n validatedInput.metadata\n );\n \n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(entity, null, 2),\n },\n ],\n };\n }\n\n case 'entity_link': {\n // Validate input schema\n const linkSchema = z.object({\n entity_id: z.string().uuid(),\n memory_id: z.string().uuid(),\n relationship: z.string().default('mentioned_in'),\n });\n\n const validatedInput = linkSchema.parse(args);\n \n await this.client.linkEntity(\n validatedInput.entity_id,\n validatedInput.memory_id,\n validatedInput.relationship\n );\n \n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n {\n success: true,\n message: 'Entity linked to memory successfully',\n entity_id: validatedInput.entity_id,\n memory_id: validatedInput.memory_id,\n relationship: validatedInput.relationship,\n },\n null,\n 2\n ),\n },\n ],\n };\n }\n\n case 'memory_health': {\n const health = await this.client.healthCheck();\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(health, null, 2),\n },\n ],\n };\n }\n\n default:\n throw new Error(`Unknown tool: ${name}`);\n }\n } catch (error) {\n let errorMessage = 'Unknown error';\n let errorDetails: unknown = undefined;\n\n if (error instanceof z.ZodError) {\n errorMessage = 'Validation error';\n errorDetails = error.errors;\n } else if (error instanceof Error) {\n errorMessage = error.message;\n }\n\n this.logger.error(`Tool execution failed: ${name}`, {\n error: errorMessage,\n details: errorDetails,\n });\n \n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n {\n error: 'Tool execution failed',\n message: errorMessage,\n details: errorDetails,\n },\n null,\n 2\n ),\n },\n ],\n isError: true,\n };\n }\n });\n }\n\n /**\n * Setup MCP resource handlers\n */\n private setupResourceHandlers(): void {\n // List static resources\n this.server.setRequestHandler(ListResourcesRequestSchema, async () => ({\n resources: [\n {\n uri: 'memory:///recent',\n name: 'Recent Memories',\n description: 'The 20 most recent memories stored in MemoryRelay',\n mimeType: 'application/json',\n },\n ],\n }));\n\n // List resource templates for dynamic access\n this.server.setRequestHandler(ListResourceTemplatesRequestSchema, async () => ({\n resourceTemplates: [\n {\n uriTemplate: 'memory:///{id}',\n name: 'Memory by ID',\n description: 'Retrieve a specific memory by its UUID',\n mimeType: 'application/json',\n },\n ],\n }));\n\n // Read a resource\n this.server.setRequestHandler(ReadResourceRequestSchema, async (request) => {\n const { uri } = request.params;\n\n try {\n if (uri === 'memory:///recent') {\n const response = await this.client.listMemories(20, 0);\n return {\n contents: [\n {\n uri,\n mimeType: 'application/json',\n text: JSON.stringify(response, null, 2),\n },\n ],\n };\n }\n\n // Match memory:///{uuid} pattern\n const match = uri.match(/^memory:\\/\\/\\/([0-9a-f-]{36})$/);\n if (match) {\n const id = match[1];\n validateUuid(id, 'memory_id');\n const memory = await this.client.getMemory(id);\n return {\n contents: [\n {\n uri,\n mimeType: 'application/json',\n text: JSON.stringify(memory, null, 2),\n },\n ],\n };\n }\n\n throw new Error(`Unknown resource: ${uri}`);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n this.logger.error(`Resource read failed: ${uri}`, { error: message });\n throw error;\n }\n });\n }\n\n /**\n * Setup MCP prompt handlers\n */\n private setupPromptHandlers(): void {\n // List available prompts\n this.server.setRequestHandler(ListPromptsRequestSchema, async () => ({\n prompts: [\n {\n name: 'store_memory',\n description: 'Store information as a persistent memory with appropriate metadata',\n arguments: [\n {\n name: 'information',\n description: 'The information to remember',\n required: true,\n },\n {\n name: 'category',\n description: 'Category for the memory (e.g., preference, fact, instruction, context)',\n required: false,\n },\n ],\n },\n {\n name: 'recall_memories',\n description: 'Search for and recall relevant memories about a topic',\n arguments: [\n {\n name: 'topic',\n description: 'The topic or question to search memories for',\n required: true,\n },\n ],\n },\n {\n name: 'summarize_memories',\n description: 'List and summarize all recent memories for context',\n arguments: [],\n },\n ],\n }));\n\n // Get a specific prompt\n this.server.setRequestHandler(GetPromptRequestSchema, async (request) => {\n const { name, arguments: args } = request.params;\n\n switch (name) {\n case 'store_memory': {\n const information = args?.information ?? '';\n const category = args?.category ?? '';\n const metadataInstruction = category\n ? ` Attach metadata with category \"${category}\".`\n : ' Attach appropriate metadata with a category tag.';\n return {\n messages: [\n {\n role: 'user' as const,\n content: {\n type: 'text' as const,\n text: `Please store the following information as a persistent memory using the memory_store tool.${metadataInstruction}\\n\\nInformation to remember:\\n${information}`,\n },\n },\n ],\n };\n }\n\n case 'recall_memories': {\n const topic = args?.topic ?? '';\n return {\n messages: [\n {\n role: 'user' as const,\n content: {\n type: 'text' as const,\n text: `Search my memories for information related to: \"${topic}\"\\n\\nUse the memory_search tool to find relevant memories, then summarize what you found. If nothing relevant is found, let me know.`,\n },\n },\n ],\n };\n }\n\n case 'summarize_memories': {\n return {\n messages: [\n {\n role: 'user' as const,\n content: {\n type: 'text' as const,\n text: 'List my recent memories using the memory_list tool and provide a brief summary of what has been remembered. Group them by topic or category if possible.',\n },\n },\n ],\n };\n }\n\n default:\n throw new Error(`Unknown prompt: ${name}`);\n }\n });\n }\n\n /**\n * Start the MCP server with STDIO transport\n */\n async start(): Promise<void> {\n const transport = new StdioServerTransport();\n await this.server.connect(transport);\n this.logger.info('MCP server started on STDIO');\n }\n}\n","/**\n * MemoryRelay API client with retry logic and error handling\n */\n\nimport type {\n Memory,\n Entity,\n SearchResult,\n ListResponse,\n ClientConfig,\n EntityType,\n} from './types.js';\nimport { getLogger } from './logger.js';\n\n// Retry configuration\nconst MAX_RETRIES = 3;\nconst INITIAL_DELAY_MS = 1000;\nconst MAX_CONTENT_SIZE = 50 * 1024; // 50KB\n\n/**\n * Exponential backoff retry wrapper\n */\nasync function withRetry<T>(\n fn: () => Promise<T>,\n retries: number = MAX_RETRIES\n): Promise<T> {\n let lastError: Error | undefined;\n \n for (let attempt = 0; attempt <= retries; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n \n // Don't retry on certain errors\n if (\n lastError.message.includes('401') ||\n lastError.message.includes('403') ||\n lastError.message.includes('404') ||\n lastError.message.includes('400')\n ) {\n throw lastError;\n }\n \n // On last attempt, throw the error\n if (attempt === retries) {\n throw lastError;\n }\n \n // Exponential backoff with jitter\n const delay = INITIAL_DELAY_MS * Math.pow(2, attempt);\n const jitter = Math.random() * 0.3 * delay;\n await new Promise(resolve => setTimeout(resolve, delay + jitter));\n }\n }\n \n throw lastError || new Error('Retry failed');\n}\n\n/**\n * Mask API key in error messages for security\n */\nfunction maskApiKey(message: string, apiKey: string): string {\n if (!apiKey) return message;\n const maskedKey = apiKey.substring(0, 8) + '***';\n return message.replace(new RegExp(apiKey, 'g'), maskedKey);\n}\n\nexport class MemoryRelayClient {\n private config: ClientConfig;\n private logger = getLogger();\n\n constructor(config: ClientConfig) {\n this.config = config;\n this.logger.info('MemoryRelay client initialized', {\n apiUrl: config.apiUrl,\n agentId: config.agentId,\n });\n }\n\n /**\n * Make authenticated HTTP request to MemoryRelay API with retry logic\n */\n private async request<T>(\n method: string,\n path: string,\n body?: unknown\n ): Promise<T> {\n return withRetry(async () => {\n const url = `${this.config.apiUrl}${path}`;\n \n this.logger.debug(`API request: ${method} ${path}`);\n\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), this.config.timeout);\n\n try {\n const response = await fetch(url, {\n method,\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.config.apiKey}`,\n 'User-Agent': '@memoryrelay/mcp-server',\n },\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n\n if (!response.ok) {\n // Handle rate limiting with retry\n if (response.status === 429) {\n const retryAfter = response.headers.get('Retry-After');\n const waitMs = retryAfter ? parseInt(retryAfter) * 1000 : 5000;\n this.logger.warn(`Rate limited, waiting ${waitMs}ms`);\n await new Promise(resolve => setTimeout(resolve, waitMs));\n throw new Error(`Rate limited: 429 - Retry after ${waitMs}ms`);\n }\n\n const errorData = await response.json().catch(() => ({})) as Record<string, unknown>;\n const errorMsg = `API request failed: ${response.status} ${response.statusText}` +\n (errorData.message ? ` - ${errorData.message}` : '');\n \n // Mask API key in error message\n throw new Error(maskApiKey(errorMsg, this.config.apiKey));\n }\n\n const data = await response.json();\n this.logger.debug(`API response: ${method} ${path}`, { status: response.status });\n \n return data as T;\n } catch (error) {\n if (error instanceof Error) {\n if (error.name === 'AbortError') {\n throw new Error(`Request timeout after ${this.config.timeout}ms`);\n }\n // Mask API key in all error messages\n error.message = maskApiKey(error.message, this.config.apiKey);\n }\n throw error;\n } finally {\n clearTimeout(timeout);\n }\n });\n }\n\n /**\n * Validate content size\n */\n private validateContentSize(content: string): void {\n if (content.length > MAX_CONTENT_SIZE) {\n throw new Error(`Content exceeds maximum size of ${MAX_CONTENT_SIZE} bytes`);\n }\n }\n\n /**\n * Store a new memory\n */\n async storeMemory(content: string, metadata?: Record<string, string>): Promise<Memory> {\n this.validateContentSize(content);\n \n return this.request<Memory>('POST', '/v1/memories/memories', {\n content,\n metadata,\n agent_id: this.config.agentId,\n });\n }\n\n /**\n * Search memories using semantic search\n */\n async searchMemories(\n query: string,\n limit: number = 10,\n threshold: number = 0.5\n ): Promise<SearchResult[]> {\n this.validateContentSize(query);\n \n const response = await this.request<{ data: SearchResult[] }>(\n 'POST',\n '/v1/memories/memories/search',\n { query, limit, threshold, agent_id: this.config.agentId }\n );\n return response.data;\n }\n\n /**\n * List recent memories with pagination\n */\n async listMemories(limit: number = 20, offset: number = 0): Promise<ListResponse<Memory>> {\n return this.request<ListResponse<Memory>>(\n 'GET',\n `/v1/memories/memories?limit=${limit}&offset=${offset}`\n );\n }\n\n /**\n * Get a specific memory by ID\n */\n async getMemory(id: string): Promise<Memory> {\n return this.request<Memory>('GET', `/v1/memories/memories/${id}`);\n }\n\n /**\n * Update an existing memory\n */\n async updateMemory(\n id: string,\n content: string,\n metadata?: Record<string, string>\n ): Promise<Memory> {\n this.validateContentSize(content);\n \n return this.request<Memory>('PATCH', `/v1/memories/memories/${id}`, {\n content,\n metadata,\n });\n }\n\n /**\n * Delete a memory\n */\n async deleteMemory(id: string): Promise<void> {\n await this.request<void>('DELETE', `/v1/memories/memories/${id}`);\n }\n\n /**\n * Create a named entity\n */\n async createEntity(\n name: string,\n type: EntityType,\n metadata?: Record<string, string>\n ): Promise<Entity> {\n this.validateContentSize(name);\n \n return this.request<Entity>('POST', '/v1/entities', {\n name,\n type,\n metadata,\n });\n }\n\n /**\n * Link an entity to a memory\n */\n async linkEntity(\n entityId: string,\n memoryId: string,\n relationship: string = 'mentioned_in'\n ): Promise<void> {\n await this.request<void>('POST', '/v1/entities/links', {\n entity_id: entityId,\n memory_id: memoryId,\n relationship,\n });\n }\n\n /**\n * Get an entity by ID\n */\n async getEntity(id: string): Promise<Entity> {\n return this.request<Entity>('GET', `/v1/entities/${id}`);\n }\n\n /**\n * List entities with pagination\n */\n async listEntities(limit: number = 20, offset: number = 0): Promise<ListResponse<Entity>> {\n return this.request<ListResponse<Entity>>(\n 'GET',\n `/v1/entities?limit=${limit}&offset=${offset}`\n );\n }\n\n /**\n * Delete an entity\n */\n async deleteEntity(id: string): Promise<void> {\n await this.request<void>('DELETE', `/v1/entities/${id}`);\n }\n\n /**\n * Health check - verify API connectivity\n */\n async healthCheck(): Promise<{ status: string; message: string }> {\n try {\n // Simple GET request to check API is reachable\n await this.request<{ status: string }>('GET', '/v1/health');\n return {\n status: 'healthy',\n message: 'API connection successful',\n };\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : 'Unknown error';\n return {\n status: 'unhealthy',\n message: `API connection failed: ${errorMsg}`,\n };\n }\n }\n}\n","#!/usr/bin/env node\n/**\n * MemoryRelay MCP Server - Entry Point\n * \n * Provides persistent memory storage for AI agents via Model Context Protocol\n */\n\nimport { loadConfig, getAgentId } from './config.js';\nimport { initLogger, getLogger } from './logger.js';\nimport { MemoryRelayMCPServer } from './server.js';\n\nasync function main() {\n try {\n // Load and validate configuration\n const config = loadConfig();\n \n // Initialize logger with configured level\n initLogger(config.logLevel);\n const logger = getLogger();\n\n logger.info('Starting MemoryRelay MCP server');\n\n // Get or generate agent ID\n const agentId = getAgentId(config);\n\n // Create and start MCP server\n const server = new MemoryRelayMCPServer({\n apiKey: config.apiKey,\n apiUrl: config.apiUrl,\n agentId,\n timeout: config.timeout,\n });\n\n await server.start();\n\n // Keep process alive\n process.on('SIGINT', () => {\n logger.info('Received SIGINT, shutting down gracefully');\n process.exit(0);\n });\n\n process.on('SIGTERM', () => {\n logger.info('Received SIGTERM, shutting down gracefully');\n process.exit(0);\n });\n\n } catch (error) {\n const logger = getLogger();\n \n if (error instanceof Error) {\n logger.error('Fatal error:', { message: error.message });\n \n // Print user-friendly error to stderr\n console.error('\\nāŒ Failed to start MemoryRelay MCP server\\n');\n console.error(error.message);\n console.error('\\nFor help, see: https://github.com/memoryrelay/mcp-server#troubleshooting\\n');\n } else {\n logger.error('Fatal error:', { error });\n console.error('\\nāŒ An unexpected error occurred\\n');\n }\n \n process.exit(1);\n }\n}\n\nmain();\n"],"mappings":"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","names":["z","z","logger"]}
1
+ {"version":3,"sources":["../src/config.ts","../src/logger.ts","../src/server.ts","../src/client.ts","../src/index.ts"],"sourcesContent":["import { z } from 'zod';\n\n/**\n * Configuration schema with security validation\n */\nexport const configSchema = z.object({\n apiKey: z.string()\n .startsWith('mem_', { message: 'API key must start with \"mem_\"' })\n .min(20, { message: 'API key appears to be invalid (too short)' }),\n apiUrl: z.string()\n .url({ message: 'API URL must be a valid URL' })\n .default('https://api.memoryrelay.net'),\n agentId: z.string()\n .optional()\n .describe('Agent identifier - auto-detected if not provided'),\n timeout: z.number()\n .positive({ message: 'Timeout must be positive' })\n .default(30000),\n logLevel: z.enum(['debug', 'info', 'warn', 'error'])\n .default('info'),\n});\n\nexport type Config = z.infer<typeof configSchema>;\n\n/**\n * Load and validate configuration from environment variables\n */\nexport function loadConfig(): Config {\n try {\n const config = configSchema.parse({\n apiKey: process.env.MEMORYRELAY_API_KEY,\n apiUrl: process.env.MEMORYRELAY_API_URL,\n agentId: process.env.MEMORYRELAY_AGENT_ID,\n timeout: process.env.MEMORYRELAY_TIMEOUT \n ? parseInt(process.env.MEMORYRELAY_TIMEOUT, 10) \n : undefined,\n logLevel: process.env.MEMORYRELAY_LOG_LEVEL,\n });\n\n return config;\n } catch (error) {\n if (error instanceof z.ZodError) {\n const issues = error.issues.map(issue => \n ` - ${issue.path.join('.')}: ${issue.message}`\n ).join('\\n');\n \n throw new Error(\n `Configuration validation failed:\\n${issues}\\n\\n` +\n 'Please check your environment variables:\\n' +\n ' - MEMORYRELAY_API_KEY (required, starts with \"mem_\")\\n' +\n ' - MEMORYRELAY_API_URL (optional, default: https://api.memoryrelay.net)\\n' +\n ' - MEMORYRELAY_AGENT_ID (optional, auto-detected)\\n' +\n ' - MEMORYRELAY_TIMEOUT (optional, default: 30000)\\n' +\n ' - MEMORYRELAY_LOG_LEVEL (optional, default: info)'\n );\n }\n throw error;\n }\n}\n\n/**\n * Get or generate agent ID\n */\nexport function getAgentId(config: Config): string {\n if (config.agentId) {\n return config.agentId;\n }\n\n // Check OpenClaw agent name\n if (process.env.OPENCLAW_AGENT_NAME) {\n return process.env.OPENCLAW_AGENT_NAME;\n }\n\n // Auto-generate from hostname\n const hostname = process.env.HOSTNAME || 'unknown';\n return `agent-${hostname.slice(0, 8)}`;\n}\n","/**\n * Security-hardened logger for MCP server\n * \n * - All output to stderr (stdout reserved for MCP protocol)\n * - Automatic masking of API keys (anything starting with \"mem_\")\n * - No internal paths in error messages\n */\n\ntype LogLevel = 'debug' | 'info' | 'warn' | 'error';\n\nconst LOG_LEVELS: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n};\n\nexport class Logger {\n private minLevel: number;\n\n constructor(level: LogLevel = 'info') {\n this.minLevel = LOG_LEVELS[level];\n }\n\n /**\n * Mask sensitive data in log messages\n * - API keys starting with \"mem_\" are masked\n * - Internal paths are sanitized\n */\n private sanitize(message: string): string {\n let sanitized = message;\n\n // Mask API keys (mem_xxx -> mem_****)\n sanitized = sanitized.replace(/mem_[a-zA-Z0-9_-]+/g, 'mem_****');\n\n // Remove internal paths (anything that looks like a file path)\n sanitized = sanitized.replace(/\\/[a-zA-Z0-9_\\-./]+\\.(ts|js|json)/g, '<file>');\n sanitized = sanitized.replace(/at\\s+[^\\s]+\\s+\\([^)]+\\)/g, 'at <location>');\n\n return sanitized;\n }\n\n /**\n * Format log message with timestamp and level\n */\n private format(level: LogLevel, message: string, data?: unknown): string {\n const timestamp = new Date().toISOString();\n const sanitizedMessage = this.sanitize(message);\n \n let output = `[${timestamp}] [${level.toUpperCase()}] ${sanitizedMessage}`;\n \n if (data !== undefined) {\n const sanitizedData = this.sanitize(JSON.stringify(data, null, 2));\n output += `\\n${sanitizedData}`;\n }\n \n return output;\n }\n\n debug(message: string, data?: unknown): void {\n if (this.minLevel <= LOG_LEVELS.debug) {\n console.error(this.format('debug', message, data));\n }\n }\n\n info(message: string, data?: unknown): void {\n if (this.minLevel <= LOG_LEVELS.info) {\n console.error(this.format('info', message, data));\n }\n }\n\n warn(message: string, data?: unknown): void {\n if (this.minLevel <= LOG_LEVELS.warn) {\n console.error(this.format('warn', message, data));\n }\n }\n\n error(message: string, data?: unknown): void {\n if (this.minLevel <= LOG_LEVELS.error) {\n console.error(this.format('error', message, data));\n }\n }\n}\n\n// Export singleton instance\nlet logger: Logger;\n\nexport function initLogger(level: LogLevel = 'info'): Logger {\n logger = new Logger(level);\n return logger;\n}\n\nexport function getLogger(): Logger {\n if (!logger) {\n logger = new Logger();\n }\n return logger;\n}\n","/**\n * MCP Server implementation for MemoryRelay\n */\n\nimport { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n ListResourcesRequestSchema,\n ListResourceTemplatesRequestSchema,\n ReadResourceRequestSchema,\n ListPromptsRequestSchema,\n GetPromptRequestSchema,\n} from '@modelcontextprotocol/sdk/types.js';\nimport { z } from 'zod';\nimport { MemoryRelayClient } from './client.js';\nimport { getLogger } from './logger.js';\nimport type { ClientConfig } from './types.js';\n\ndeclare const __VERSION__: string;\n\n/**\n * HTML-encode string to prevent XSS\n */\nfunction sanitizeHtml(str: string): string {\n return str\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#x27;')\n .replace(/\\//g, '&#x2F;');\n}\n\n/**\n * Validate UUID format\n */\nconst uuidSchema = z.string().uuid();\n\nfunction validateUuid(id: string, fieldName: string = 'id'): void {\n const result = uuidSchema.safeParse(id);\n if (!result.success) {\n throw new Error(`Invalid ${fieldName}: must be a valid UUID`);\n }\n}\n\nexport class MemoryRelayMCPServer {\n private server: Server;\n private client: MemoryRelayClient;\n private logger = getLogger();\n\n constructor(config: ClientConfig) {\n this.client = new MemoryRelayClient(config);\n \n this.server = new Server(\n {\n name: '@memoryrelay/mcp-server',\n version: __VERSION__,\n },\n {\n capabilities: {\n tools: {},\n resources: {},\n prompts: {},\n },\n }\n );\n\n this.setupToolHandlers();\n this.setupResourceHandlers();\n this.setupPromptHandlers();\n this.logger.info('MCP server initialized');\n }\n\n /**\n * Setup MCP tool handlers\n */\n private setupToolHandlers(): void {\n // List available tools\n this.server.setRequestHandler(ListToolsRequestSchema, async () => ({\n tools: [\n {\n name: 'memory_store',\n description: 'Store a new memory. Use this to save important information, facts, preferences, or context that should be remembered for future conversations.',\n inputSchema: {\n type: 'object',\n properties: {\n content: {\n type: 'string',\n description: 'The memory content to store. Be specific and include relevant context.',\n },\n metadata: {\n type: 'object',\n description: 'Optional key-value metadata to attach to the memory',\n additionalProperties: { type: 'string' },\n },\n },\n required: ['content'],\n },\n },\n {\n name: 'memory_search',\n description: 'Search memories using natural language. Returns the most relevant memories based on semantic similarity to the query.',\n inputSchema: {\n type: 'object',\n properties: {\n query: {\n type: 'string',\n description: 'Natural language search query',\n },\n limit: {\n type: 'number',\n description: 'Maximum number of results to return (1-50)',\n minimum: 1,\n maximum: 50,\n default: 10,\n },\n threshold: {\n type: 'number',\n description: 'Minimum similarity threshold (0-1)',\n minimum: 0,\n maximum: 1,\n default: 0.5,\n },\n },\n required: ['query'],\n },\n },\n {\n name: 'memory_list',\n description: 'List recent memories chronologically. Use to review what has been remembered.',\n inputSchema: {\n type: 'object',\n properties: {\n limit: {\n type: 'number',\n description: 'Number of memories to return (1-100)',\n minimum: 1,\n maximum: 100,\n default: 20,\n },\n offset: {\n type: 'number',\n description: 'Offset for pagination',\n minimum: 0,\n default: 0,\n },\n },\n },\n },\n {\n name: 'memory_get',\n description: 'Retrieve a specific memory by its ID.',\n inputSchema: {\n type: 'object',\n properties: {\n id: {\n type: 'string',\n description: 'The memory ID (UUID) to retrieve',\n },\n },\n required: ['id'],\n },\n },\n {\n name: 'memory_update',\n description: 'Update the content of an existing memory. Use to correct or expand stored information.',\n inputSchema: {\n type: 'object',\n properties: {\n id: {\n type: 'string',\n description: 'The memory ID (UUID) to update',\n },\n content: {\n type: 'string',\n description: 'The new content to replace the existing memory',\n },\n metadata: {\n type: 'object',\n description: 'Updated metadata (replaces existing)',\n additionalProperties: { type: 'string' },\n },\n },\n required: ['id', 'content'],\n },\n },\n {\n name: 'memory_delete',\n description: 'Permanently delete a memory. Use sparingly - memories are valuable context.',\n inputSchema: {\n type: 'object',\n properties: {\n id: {\n type: 'string',\n description: 'The memory ID (UUID) to delete',\n },\n },\n required: ['id'],\n },\n },\n {\n name: 'entity_create',\n description: 'Create a named entity (person, place, organization, project, concept) for the knowledge graph. Entities help organize and connect memories.',\n inputSchema: {\n type: 'object',\n properties: {\n name: {\n type: 'string',\n minLength: 1,\n maxLength: 200,\n description: 'Entity name (1-200 characters)',\n },\n type: {\n type: 'string',\n enum: ['person', 'place', 'organization', 'project', 'concept', 'other'],\n description: 'Entity type classification',\n },\n metadata: {\n type: 'object',\n description: 'Optional key-value metadata',\n additionalProperties: { type: 'string' },\n },\n },\n required: ['name', 'type'],\n },\n },\n {\n name: 'entity_link',\n description: 'Link an entity to a memory to establish relationships in the knowledge graph.',\n inputSchema: {\n type: 'object',\n properties: {\n entity_id: {\n type: 'string',\n description: 'Entity UUID',\n },\n memory_id: {\n type: 'string',\n description: 'Memory UUID',\n },\n relationship: {\n type: 'string',\n description: 'Relationship type (e.g., \"mentioned_in\", \"created_by\", \"relates_to\")',\n default: 'mentioned_in',\n },\n },\n required: ['entity_id', 'memory_id'],\n },\n },\n {\n name: 'memory_health',\n description: 'Check API connectivity and health status.',\n inputSchema: {\n type: 'object',\n properties: {},\n },\n },\n ],\n }));\n\n // Handle tool calls\n this.server.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args = {} } = request.params;\n\n this.logger.debug(`Tool called: ${name}`, args);\n\n try {\n switch (name) {\n case 'memory_store': {\n const memory = await this.client.storeMemory(\n args.content as string,\n args.metadata as Record<string, string> | undefined\n );\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(memory, null, 2),\n },\n ],\n };\n }\n\n case 'memory_search': {\n const results = await this.client.searchMemories(\n args.query as string,\n args.limit as number | undefined,\n args.threshold as number | undefined\n );\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n { memories: results, total: results.length },\n null,\n 2\n ),\n },\n ],\n };\n }\n\n case 'memory_list': {\n const response = await this.client.listMemories(\n args.limit as number | undefined,\n args.offset as number | undefined\n );\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(response, null, 2),\n },\n ],\n };\n }\n\n case 'memory_get': {\n const id = args.id as string;\n validateUuid(id, 'memory_id');\n\n const memory = await this.client.getMemory(id);\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(memory, null, 2),\n },\n ],\n };\n }\n\n case 'memory_update': {\n const id = args.id as string;\n validateUuid(id, 'memory_id');\n\n const memory = await this.client.updateMemory(\n id,\n args.content as string,\n args.metadata as Record<string, string> | undefined\n );\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(memory, null, 2),\n },\n ],\n };\n }\n\n case 'memory_delete': {\n const id = args.id as string;\n validateUuid(id, 'memory_id');\n\n await this.client.deleteMemory(id);\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n { success: true, message: 'Memory deleted successfully' },\n null,\n 2\n ),\n },\n ],\n };\n }\n\n case 'entity_create': {\n // Validate input schema\n const entitySchema = z.object({\n name: z.string().min(1).max(200),\n type: z.enum(['person', 'place', 'organization', 'project', 'concept', 'other']),\n metadata: z.record(z.string()).optional(),\n });\n\n const validatedInput = entitySchema.parse(args);\n \n // Sanitize name to prevent XSS\n const sanitizedName = sanitizeHtml(validatedInput.name);\n \n const entity = await this.client.createEntity(\n sanitizedName,\n validatedInput.type,\n validatedInput.metadata\n );\n \n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(entity, null, 2),\n },\n ],\n };\n }\n\n case 'entity_link': {\n // Validate input schema\n const linkSchema = z.object({\n entity_id: z.string().uuid(),\n memory_id: z.string().uuid(),\n relationship: z.string().default('mentioned_in'),\n });\n\n const validatedInput = linkSchema.parse(args);\n \n await this.client.linkEntity(\n validatedInput.entity_id,\n validatedInput.memory_id,\n validatedInput.relationship\n );\n \n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n {\n success: true,\n message: 'Entity linked to memory successfully',\n entity_id: validatedInput.entity_id,\n memory_id: validatedInput.memory_id,\n relationship: validatedInput.relationship,\n },\n null,\n 2\n ),\n },\n ],\n };\n }\n\n case 'memory_health': {\n const health = await this.client.healthCheck();\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(health, null, 2),\n },\n ],\n };\n }\n\n default:\n throw new Error(`Unknown tool: ${name}`);\n }\n } catch (error) {\n let errorMessage = 'Unknown error';\n let errorDetails: unknown = undefined;\n\n if (error instanceof z.ZodError) {\n errorMessage = 'Validation error';\n errorDetails = error.errors;\n } else if (error instanceof Error) {\n errorMessage = error.message;\n }\n\n this.logger.error(`Tool execution failed: ${name}`, {\n error: errorMessage,\n details: errorDetails,\n });\n \n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(\n {\n error: 'Tool execution failed',\n message: errorMessage,\n details: errorDetails,\n },\n null,\n 2\n ),\n },\n ],\n isError: true,\n };\n }\n });\n }\n\n /**\n * Setup MCP resource handlers\n */\n private setupResourceHandlers(): void {\n // List static resources\n this.server.setRequestHandler(ListResourcesRequestSchema, async () => ({\n resources: [\n {\n uri: 'memory:///recent',\n name: 'Recent Memories',\n description: 'The 20 most recent memories stored in MemoryRelay',\n mimeType: 'application/json',\n },\n ],\n }));\n\n // List resource templates for dynamic access\n this.server.setRequestHandler(ListResourceTemplatesRequestSchema, async () => ({\n resourceTemplates: [\n {\n uriTemplate: 'memory:///{id}',\n name: 'Memory by ID',\n description: 'Retrieve a specific memory by its UUID',\n mimeType: 'application/json',\n },\n ],\n }));\n\n // Read a resource\n this.server.setRequestHandler(ReadResourceRequestSchema, async (request) => {\n const { uri } = request.params;\n\n try {\n if (uri === 'memory:///recent') {\n const response = await this.client.listMemories(20, 0);\n return {\n contents: [\n {\n uri,\n mimeType: 'application/json',\n text: JSON.stringify(response, null, 2),\n },\n ],\n };\n }\n\n // Match memory:///{uuid} pattern\n const match = uri.match(/^memory:\\/\\/\\/([0-9a-f-]{36})$/);\n if (match) {\n const id = match[1];\n validateUuid(id, 'memory_id');\n const memory = await this.client.getMemory(id);\n return {\n contents: [\n {\n uri,\n mimeType: 'application/json',\n text: JSON.stringify(memory, null, 2),\n },\n ],\n };\n }\n\n throw new Error(`Unknown resource: ${uri}`);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n this.logger.error(`Resource read failed: ${uri}`, { error: message });\n throw error;\n }\n });\n }\n\n /**\n * Setup MCP prompt handlers\n */\n private setupPromptHandlers(): void {\n // List available prompts\n this.server.setRequestHandler(ListPromptsRequestSchema, async () => ({\n prompts: [\n {\n name: 'store_memory',\n description: 'Store information as a persistent memory with appropriate metadata',\n arguments: [\n {\n name: 'information',\n description: 'The information to remember',\n required: true,\n },\n {\n name: 'category',\n description: 'Category for the memory (e.g., preference, fact, instruction, context)',\n required: false,\n },\n ],\n },\n {\n name: 'recall_memories',\n description: 'Search for and recall relevant memories about a topic',\n arguments: [\n {\n name: 'topic',\n description: 'The topic or question to search memories for',\n required: true,\n },\n ],\n },\n {\n name: 'summarize_memories',\n description: 'List and summarize all recent memories for context',\n arguments: [],\n },\n ],\n }));\n\n // Get a specific prompt\n this.server.setRequestHandler(GetPromptRequestSchema, async (request) => {\n const { name, arguments: args } = request.params;\n\n switch (name) {\n case 'store_memory': {\n const information = args?.information ?? '';\n const category = args?.category ?? '';\n const metadataInstruction = category\n ? ` Attach metadata with category \"${category}\".`\n : ' Attach appropriate metadata with a category tag.';\n return {\n messages: [\n {\n role: 'user' as const,\n content: {\n type: 'text' as const,\n text: `Please store the following information as a persistent memory using the memory_store tool.${metadataInstruction}\\n\\nInformation to remember:\\n${information}`,\n },\n },\n ],\n };\n }\n\n case 'recall_memories': {\n const topic = args?.topic ?? '';\n return {\n messages: [\n {\n role: 'user' as const,\n content: {\n type: 'text' as const,\n text: `Search my memories for information related to: \"${topic}\"\\n\\nUse the memory_search tool to find relevant memories, then summarize what you found. If nothing relevant is found, let me know.`,\n },\n },\n ],\n };\n }\n\n case 'summarize_memories': {\n return {\n messages: [\n {\n role: 'user' as const,\n content: {\n type: 'text' as const,\n text: 'List my recent memories using the memory_list tool and provide a brief summary of what has been remembered. Group them by topic or category if possible.',\n },\n },\n ],\n };\n }\n\n default:\n throw new Error(`Unknown prompt: ${name}`);\n }\n });\n }\n\n /**\n * Start the MCP server with STDIO transport\n */\n async start(): Promise<void> {\n const transport = new StdioServerTransport();\n await this.server.connect(transport);\n this.logger.info('MCP server started on STDIO');\n }\n}\n","/**\n * MemoryRelay API client with retry logic and error handling\n */\n\nimport type {\n Memory,\n Entity,\n SearchResult,\n ListResponse,\n ClientConfig,\n EntityType,\n} from './types.js';\nimport { getLogger } from './logger.js';\n\n// Retry configuration\nconst MAX_RETRIES = 3;\nconst INITIAL_DELAY_MS = 1000;\nconst MAX_CONTENT_SIZE = 50 * 1024; // 50KB\n\n/**\n * Exponential backoff retry wrapper\n */\nasync function withRetry<T>(\n fn: () => Promise<T>,\n retries: number = MAX_RETRIES\n): Promise<T> {\n let lastError: Error | undefined;\n \n for (let attempt = 0; attempt <= retries; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n \n // Don't retry on certain errors\n if (\n lastError.message.includes('401') ||\n lastError.message.includes('403') ||\n lastError.message.includes('404') ||\n lastError.message.includes('400')\n ) {\n throw lastError;\n }\n \n // On last attempt, throw the error\n if (attempt === retries) {\n throw lastError;\n }\n \n // Exponential backoff with jitter\n const delay = INITIAL_DELAY_MS * Math.pow(2, attempt);\n const jitter = Math.random() * 0.3 * delay;\n await new Promise(resolve => setTimeout(resolve, delay + jitter));\n }\n }\n \n throw lastError || new Error('Retry failed');\n}\n\n/**\n * Mask API key in error messages for security\n */\nfunction maskApiKey(message: string, apiKey: string): string {\n if (!apiKey) return message;\n const maskedKey = apiKey.substring(0, 8) + '***';\n return message.replace(new RegExp(apiKey, 'g'), maskedKey);\n}\n\nexport class MemoryRelayClient {\n private config: ClientConfig;\n private logger = getLogger();\n\n constructor(config: ClientConfig) {\n this.config = config;\n this.logger.info('MemoryRelay client initialized', {\n apiUrl: config.apiUrl,\n agentId: config.agentId,\n });\n }\n\n /**\n * Make authenticated HTTP request to MemoryRelay API with retry logic\n */\n private async request<T>(\n method: string,\n path: string,\n body?: unknown\n ): Promise<T> {\n return withRetry(async () => {\n const url = `${this.config.apiUrl}${path}`;\n \n this.logger.debug(`API request: ${method} ${path}`);\n\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), this.config.timeout);\n\n try {\n const response = await fetch(url, {\n method,\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${this.config.apiKey}`,\n 'User-Agent': '@memoryrelay/mcp-server',\n },\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n\n if (!response.ok) {\n // Handle rate limiting with retry\n if (response.status === 429) {\n const retryAfter = response.headers.get('Retry-After');\n const waitMs = retryAfter ? parseInt(retryAfter) * 1000 : 5000;\n this.logger.warn(`Rate limited, waiting ${waitMs}ms`);\n await new Promise(resolve => setTimeout(resolve, waitMs));\n throw new Error(`Rate limited: 429 - Retry after ${waitMs}ms`);\n }\n\n const errorData = await response.json().catch(() => ({})) as Record<string, unknown>;\n const errorMsg = `API request failed: ${response.status} ${response.statusText}` +\n (errorData.message ? ` - ${errorData.message}` : '');\n \n // Mask API key in error message\n throw new Error(maskApiKey(errorMsg, this.config.apiKey));\n }\n\n const data = await response.json();\n this.logger.debug(`API response: ${method} ${path}`, { status: response.status });\n \n return data as T;\n } catch (error) {\n if (error instanceof Error) {\n if (error.name === 'AbortError') {\n throw new Error(`Request timeout after ${this.config.timeout}ms`);\n }\n // Mask API key in all error messages\n error.message = maskApiKey(error.message, this.config.apiKey);\n }\n throw error;\n } finally {\n clearTimeout(timeout);\n }\n });\n }\n\n /**\n * Validate content size\n */\n private validateContentSize(content: string): void {\n if (content.length > MAX_CONTENT_SIZE) {\n throw new Error(`Content exceeds maximum size of ${MAX_CONTENT_SIZE} bytes`);\n }\n }\n\n /**\n * Store a new memory\n */\n async storeMemory(content: string, metadata?: Record<string, string>): Promise<Memory> {\n this.validateContentSize(content);\n \n return this.request<Memory>('POST', '/v1/memories', {\n content,\n metadata,\n agent_id: this.config.agentId,\n });\n }\n\n /**\n * Search memories using semantic search\n */\n async searchMemories(\n query: string,\n limit: number = 10,\n threshold: number = 0.5\n ): Promise<SearchResult[]> {\n this.validateContentSize(query);\n \n const response = await this.request<{ data: SearchResult[] }>(\n 'POST',\n '/v1/memories/search',\n { query, limit, threshold, agent_id: this.config.agentId }\n );\n return response.data;\n }\n\n /**\n * List recent memories with pagination\n */\n async listMemories(limit: number = 20, offset: number = 0): Promise<ListResponse<Memory>> {\n return this.request<ListResponse<Memory>>(\n 'GET',\n `/v1/memories?limit=${limit}&offset=${offset}`\n );\n }\n\n /**\n * Get a specific memory by ID\n */\n async getMemory(id: string): Promise<Memory> {\n return this.request<Memory>('GET', `/v1/memories/${id}`);\n }\n\n /**\n * Update an existing memory\n */\n async updateMemory(\n id: string,\n content: string,\n metadata?: Record<string, string>\n ): Promise<Memory> {\n this.validateContentSize(content);\n \n return this.request<Memory>('PATCH', `/v1/memories/${id}`, {\n content,\n metadata,\n });\n }\n\n /**\n * Delete a memory\n */\n async deleteMemory(id: string): Promise<void> {\n await this.request<void>('DELETE', `/v1/memories/${id}`);\n }\n\n /**\n * Create a named entity\n */\n async createEntity(\n name: string,\n type: EntityType,\n metadata?: Record<string, string>\n ): Promise<Entity> {\n this.validateContentSize(name);\n \n return this.request<Entity>('POST', '/v1/entities', {\n name,\n type,\n metadata,\n });\n }\n\n /**\n * Link an entity to a memory\n */\n async linkEntity(\n entityId: string,\n memoryId: string,\n relationship: string = 'mentioned_in'\n ): Promise<void> {\n await this.request<void>('POST', '/v1/entities/links', {\n entity_id: entityId,\n memory_id: memoryId,\n relationship,\n });\n }\n\n /**\n * Get an entity by ID\n */\n async getEntity(id: string): Promise<Entity> {\n return this.request<Entity>('GET', `/v1/entities/${id}`);\n }\n\n /**\n * List entities with pagination\n */\n async listEntities(limit: number = 20, offset: number = 0): Promise<ListResponse<Entity>> {\n return this.request<ListResponse<Entity>>(\n 'GET',\n `/v1/entities?limit=${limit}&offset=${offset}`\n );\n }\n\n /**\n * Delete an entity\n */\n async deleteEntity(id: string): Promise<void> {\n await this.request<void>('DELETE', `/v1/entities/${id}`);\n }\n\n /**\n * Health check - verify API connectivity\n */\n async healthCheck(): Promise<{ status: string; message: string }> {\n try {\n // Simple GET request to check API is reachable\n await this.request<{ status: string }>('GET', '/health');\n return {\n status: 'healthy',\n message: 'API connection successful',\n };\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : 'Unknown error';\n return {\n status: 'unhealthy',\n message: `API connection failed: ${errorMsg}`,\n };\n }\n }\n}\n","#!/usr/bin/env node\n/**\n * MemoryRelay MCP Server - Entry Point\n * \n * Provides persistent memory storage for AI agents via Model Context Protocol\n */\n\nimport { loadConfig, getAgentId } from './config.js';\nimport { initLogger, getLogger } from './logger.js';\nimport { MemoryRelayMCPServer } from './server.js';\n\nasync function main() {\n try {\n // Load and validate configuration\n const config = loadConfig();\n \n // Initialize logger with configured level\n initLogger(config.logLevel);\n const logger = getLogger();\n\n logger.info('Starting MemoryRelay MCP server');\n\n // Get or generate agent ID\n const agentId = getAgentId(config);\n\n // Create and start MCP server\n const server = new MemoryRelayMCPServer({\n apiKey: config.apiKey,\n apiUrl: config.apiUrl,\n agentId,\n timeout: config.timeout,\n });\n\n await server.start();\n\n // Keep process alive\n process.on('SIGINT', () => {\n logger.info('Received SIGINT, shutting down gracefully');\n process.exit(0);\n });\n\n process.on('SIGTERM', () => {\n logger.info('Received SIGTERM, shutting down gracefully');\n process.exit(0);\n });\n\n } catch (error) {\n const logger = getLogger();\n \n if (error instanceof Error) {\n logger.error('Fatal error:', { message: error.message });\n \n // Print user-friendly error to stderr\n console.error('\\nāŒ Failed to start MemoryRelay MCP server\\n');\n console.error(error.message);\n console.error('\\nFor help, see: https://github.com/memoryrelay/mcp-server#troubleshooting\\n');\n } else {\n logger.error('Fatal error:', { error });\n console.error('\\nāŒ An unexpected error occurred\\n');\n }\n \n process.exit(1);\n }\n}\n\nmain();\n"],"mappings":"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","names":["z","z","logger"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memoryrelay/mcp-server",
3
- "version": "0.1.9",
3
+ "version": "0.2.0",
4
4
  "description": "MCP server for MemoryRelay - persistent memory for AI agents",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",