@memoryrelay/mcp-server 0.4.0 → 0.4.1
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 +32 -3
- package/dist/{chunk-J5PEZEMN.js → chunk-PFC5Z5ZD.js} +15 -5
- package/dist/chunk-PFC5Z5ZD.js.map +1 -0
- package/dist/cli/test.js +1 -1
- package/dist/index.js +14 -3
- package/dist/index.js.map +1 -1
- package/docs/OPENCLAW_GUIDE.md +64 -13
- package/docs/SECURITY.md +6 -6
- package/package.json +1 -1
- package/dist/chunk-J5PEZEMN.js.map +0 -1
package/README.md
CHANGED
|
@@ -17,6 +17,33 @@
|
|
|
17
17
|
|
|
18
18
|
---
|
|
19
19
|
|
|
20
|
+
## Why MemoryRelay?
|
|
21
|
+
|
|
22
|
+
| Feature | MemoryRelay | Mem0 | Basic MCP Memory |
|
|
23
|
+
|---------|------------|------|-----------------|
|
|
24
|
+
| Semantic Search | Yes | Yes | No |
|
|
25
|
+
| Work Sessions | Yes | No | No |
|
|
26
|
+
| Architectural Decisions (ADRs) | Yes | No | No |
|
|
27
|
+
| Reusable Patterns | Yes | No | No |
|
|
28
|
+
| Project Orchestration | Yes | No | No |
|
|
29
|
+
| Knowledge Graph (Entities) | Yes | Limited | No |
|
|
30
|
+
| Multi-Agent Support | Yes | Yes | No |
|
|
31
|
+
| V2 Async Storage (60-600x faster) | Yes | No | No |
|
|
32
|
+
| Tools | 44 | ~10 | 3-5 |
|
|
33
|
+
|
|
34
|
+
MemoryRelay is purpose-built for engineering teams managing complex, long-running projects — not general-purpose Q&A memory.
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Use Cases
|
|
39
|
+
|
|
40
|
+
- **Tech Lead** managing 3+ projects — track architectural decisions across repos, build pattern libraries, understand cross-project dependencies
|
|
41
|
+
- **DevOps Engineer** — record infrastructure decisions with rationale, store runbooks as reusable patterns, track deployment configurations
|
|
42
|
+
- **Solo Developer** — build a persistent knowledge base that grows across sessions, link related concepts through entities
|
|
43
|
+
- **Coding Agent** — auto-capture important context, adopt proven patterns, maintain session continuity across conversations
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
20
47
|
## 📦 Installation
|
|
21
48
|
|
|
22
49
|
### Using npx (recommended)
|
|
@@ -141,6 +168,7 @@ Try asking:
|
|
|
141
168
|
| `MEMORYRELAY_TIMEOUT` | No | `30000` | Request timeout in milliseconds |
|
|
142
169
|
| `MEMORYRELAY_LOG_LEVEL` | No | `info` | Logging level (`debug`, `info`, `warn`, `error`) |
|
|
143
170
|
| `MEMORYRELAY_TOOLS` | No | `all` | Comma-separated tool groups to enable (see below) |
|
|
171
|
+
| `OPENCLAW_AGENT_NAME` | No | - | Agent name when running under OpenClaw (used for agent ID detection) |
|
|
144
172
|
|
|
145
173
|
### Tool Groups
|
|
146
174
|
|
|
@@ -148,7 +176,8 @@ Control which tools are exposed via the `MEMORYRELAY_TOOLS` environment variable
|
|
|
148
176
|
|
|
149
177
|
| Group | Tools | Description |
|
|
150
178
|
|-------|-------|-------------|
|
|
151
|
-
| `core` |
|
|
179
|
+
| `core` | 18 tools | Memory CRUD, entities, agents, health, aliases (forget/recall) |
|
|
180
|
+
| `v2` | 3 tools | Async memory storage, status polling, context building |
|
|
152
181
|
| `sessions` | 4 tools | Session lifecycle (start, end, recall, list) |
|
|
153
182
|
| `decisions` | 4 tools | Decision recording and checking |
|
|
154
183
|
| `patterns` | 4 tools | Pattern library (create, search, adopt, suggest) |
|
|
@@ -172,7 +201,7 @@ The server automatically detects your agent ID from:
|
|
|
172
201
|
|
|
173
202
|
## 🛠️ Available Tools
|
|
174
203
|
|
|
175
|
-
The MCP server provides
|
|
204
|
+
The MCP server provides 44 tools organized into groups:
|
|
176
205
|
|
|
177
206
|
### Memory Management Tools
|
|
178
207
|
|
|
@@ -405,7 +434,7 @@ npm run type-check
|
|
|
405
434
|
mcp-server/
|
|
406
435
|
├── src/
|
|
407
436
|
│ ├── index.ts # Entry point with CLI routing
|
|
408
|
-
│ ├── server.ts # MCP server implementation (
|
|
437
|
+
│ ├── server.ts # MCP server implementation (44 tools)
|
|
409
438
|
│ ├── client.ts # MemoryRelay API client
|
|
410
439
|
│ ├── config.ts # Configuration loader + tool groups
|
|
411
440
|
│ ├── logger.ts # Security-hardened logging
|
|
@@ -15,6 +15,8 @@ var TOOL_GROUPS = {
|
|
|
15
15
|
"memory_get",
|
|
16
16
|
"memory_update",
|
|
17
17
|
"memory_delete",
|
|
18
|
+
"memory_forget",
|
|
19
|
+
"memory_recall",
|
|
18
20
|
"entity_create",
|
|
19
21
|
"entity_link",
|
|
20
22
|
"entity_list",
|
|
@@ -26,6 +28,7 @@ var TOOL_GROUPS = {
|
|
|
26
28
|
"agent_get",
|
|
27
29
|
"memory_health"
|
|
28
30
|
],
|
|
31
|
+
v2: ["memory_store_async", "memory_status", "context_build"],
|
|
29
32
|
sessions: ["session_start", "session_end", "session_recall", "session_list"],
|
|
30
33
|
decisions: ["decision_record", "decision_list", "decision_supersede", "decision_check"],
|
|
31
34
|
patterns: ["pattern_create", "pattern_search", "pattern_adopt", "pattern_suggest"],
|
|
@@ -240,10 +243,11 @@ var MemoryRelayClient = class {
|
|
|
240
243
|
throw new Error(`Rate limited: 429 - Retry after ${waitMs}ms`);
|
|
241
244
|
}
|
|
242
245
|
const errorData = await response.json().catch(() => ({}));
|
|
243
|
-
const errorMsg = `API request failed: ${response.status} ${response.statusText}` + (errorData.
|
|
246
|
+
const errorMsg = `API request failed: ${response.status} ${response.statusText}` + (errorData.detail ? ` - ${errorData.detail}` : "");
|
|
244
247
|
throw new Error(maskApiKey(errorMsg, this.config.apiKey));
|
|
245
248
|
}
|
|
246
|
-
const
|
|
249
|
+
const hasBody = response.status !== 204;
|
|
250
|
+
const data = hasBody ? await response.json() : null;
|
|
247
251
|
this.logger.debug(`API response: ${method} ${path}`, { status: response.status });
|
|
248
252
|
return data;
|
|
249
253
|
} catch (error) {
|
|
@@ -270,7 +274,7 @@ var MemoryRelayClient = class {
|
|
|
270
274
|
/**
|
|
271
275
|
* Store a new memory
|
|
272
276
|
*/
|
|
273
|
-
async storeMemory(content, metadata, deduplicate, dedupThreshold, project, importance, tier) {
|
|
277
|
+
async storeMemory(content, metadata, deduplicate, dedupThreshold, project, importance, tier, sessionId, autoExtractEntities) {
|
|
274
278
|
this.validateContentSize(content);
|
|
275
279
|
const body = {
|
|
276
280
|
content,
|
|
@@ -292,6 +296,12 @@ var MemoryRelayClient = class {
|
|
|
292
296
|
if (tier) {
|
|
293
297
|
body.tier = tier;
|
|
294
298
|
}
|
|
299
|
+
if (sessionId) {
|
|
300
|
+
body.session_id = sessionId;
|
|
301
|
+
}
|
|
302
|
+
if (autoExtractEntities !== void 0) {
|
|
303
|
+
body.auto_extract_entities = autoExtractEntities;
|
|
304
|
+
}
|
|
295
305
|
return this.request("POST", "/v1/memories", body);
|
|
296
306
|
}
|
|
297
307
|
/**
|
|
@@ -304,7 +314,7 @@ var MemoryRelayClient = class {
|
|
|
304
314
|
async searchMemories(query, limit = 10, threshold = 0.5, agentId, includeConfidential = false, includeArchived = false, compress = false, maxContextTokens, project, tier, minImportance) {
|
|
305
315
|
this.validateContentSize(query);
|
|
306
316
|
const effectiveAgentId = agentId === null ? void 0 : agentId ?? this.config.agentId;
|
|
307
|
-
const body = { query, limit, threshold };
|
|
317
|
+
const body = { query, limit, min_score: threshold };
|
|
308
318
|
if (effectiveAgentId) {
|
|
309
319
|
body.agent_id = effectiveAgentId;
|
|
310
320
|
}
|
|
@@ -840,4 +850,4 @@ export {
|
|
|
840
850
|
getLogger,
|
|
841
851
|
MemoryRelayClient
|
|
842
852
|
};
|
|
843
|
-
//# sourceMappingURL=chunk-
|
|
853
|
+
//# sourceMappingURL=chunk-PFC5Z5ZD.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/config.ts","../src/logger.ts","../src/client.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 * Tool groups that can be enabled/disabled via MEMORYRELAY_TOOLS env var.\n * Default (when unset or 'all'): all groups enabled.\n */\nexport const TOOL_GROUPS: Record<string, string[]> = {\n core: [\n 'memory_store', 'memory_search', 'memory_list', 'memory_get',\n 'memory_update', 'memory_delete', 'memory_forget', 'memory_recall',\n 'entity_create', 'entity_link',\n 'entity_list', 'entity_graph', 'memory_batch_store', 'memory_context',\n 'agent_list', 'agent_create', 'agent_get', 'memory_health',\n ],\n v2: ['memory_store_async', 'memory_status', 'context_build'],\n sessions: ['session_start', 'session_end', 'session_recall', 'session_list'],\n decisions: ['decision_record', 'decision_list', 'decision_supersede', 'decision_check'],\n patterns: ['pattern_create', 'pattern_search', 'pattern_adopt', 'pattern_suggest'],\n projects: ['project_register', 'project_list', 'project_info'],\n relationships: [\n 'project_add_relationship', 'project_dependencies', 'project_dependents',\n 'project_related', 'project_impact', 'project_shared_patterns',\n ],\n context: ['project_context', 'memory_promote'],\n};\n\n/**\n * Parse MEMORYRELAY_TOOLS env var and return set of enabled tool names.\n * Returns null if all tools should be enabled (default behavior).\n */\nexport function getEnabledTools(): Set<string> | null {\n const raw = process.env.MEMORYRELAY_TOOLS;\n if (!raw || raw.trim().toLowerCase() === 'all') {\n return null; // all tools enabled\n }\n\n const groups = raw.split(',').map(g => g.trim().toLowerCase());\n const enabled = new Set<string>();\n for (const group of groups) {\n const tools = TOOL_GROUPS[group];\n if (tools) {\n for (const tool of tools) {\n enabled.add(tool);\n }\n }\n }\n return enabled;\n}\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 { cause: error }\n );\n }\n throw error;\n }\n}\n\n/**\n * Get or generate agent ID.\n *\n * Priority order:\n * 1. MEMORYRELAY_AGENT_ID (explicit configuration)\n * 2. OPENCLAW_AGENT_NAME (OpenClaw auto-detection)\n * 3. Auto-generated from username + hostname\n *\n * When no explicit ID is provided we build a human-readable identifier\n * from the current user and hostname so that memories are easier to\n * attribute in the dashboard (e.g. \"sparc-DESKTOP\" instead of \"agent-a1b2c3d4\").\n */\nexport function getAgentId(config: Config): string {\n if (config.agentId) {\n return config.agentId;\n }\n\n // OpenClaw auto-detection: use agent name from OpenClaw environment\n const openclawAgent = process.env.OPENCLAW_AGENT_NAME;\n if (openclawAgent) {\n return openclawAgent.slice(0, 32);\n }\n\n const hostname = process.env.HOSTNAME || process.env.COMPUTERNAME || 'unknown';\n const user = process.env.USER || process.env.USERNAME || '';\n return user\n ? `${user}-${hostname}`.slice(0, 32)\n : `mcp-${hostname}`.slice(0, 32);\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 * MemoryRelay API client with retry logic and error handling\n */\n\nimport type {\n Memory,\n Entity,\n Agent,\n Session,\n SessionDetail,\n Decision,\n DecisionCheckResult,\n Project,\n Pattern,\n PatternSearchResult,\n SearchResult,\n ListResponse,\n ClientConfig,\n EntityType,\n BatchMemoryItem,\n BatchStoreResponse,\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 { detail?: string };\n const errorMsg = `API request failed: ${response.status} ${response.statusText}` +\n (errorData.detail ? ` - ${errorData.detail}` : '');\n \n // Mask API key in error message\n throw new Error(maskApiKey(errorMsg, this.config.apiKey));\n }\n\n const hasBody = response.status !== 204;\n const data = hasBody ? await response.json() : null;\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`, { cause: error });\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(\n content: string,\n metadata?: Record<string, string>,\n deduplicate?: boolean,\n dedupThreshold?: number,\n project?: string,\n importance?: number,\n tier?: string,\n sessionId?: string,\n autoExtractEntities?: boolean\n ): Promise<Memory> {\n this.validateContentSize(content);\n\n const body: Record<string, unknown> = {\n content,\n metadata,\n agent_id: this.config.agentId,\n };\n if (deduplicate) {\n body.deduplicate = true;\n }\n if (dedupThreshold !== undefined) {\n body.dedup_threshold = dedupThreshold;\n }\n if (project) {\n body.project = project;\n }\n if (importance !== undefined) {\n body.importance = importance;\n }\n if (tier) {\n body.tier = tier;\n }\n if (sessionId) {\n body.session_id = sessionId;\n }\n if (autoExtractEntities !== undefined) {\n body.auto_extract_entities = autoExtractEntities;\n }\n\n return this.request<Memory>('POST', '/v1/memories', body);\n }\n\n /**\n * Search memories using semantic search\n * @param agentId - Optional agent ID override. If omitted, uses config agentId. Pass null for cross-agent search.\n * @param includeConfidential - Include confidential memories in results\n * @param includeArchived - Include archived memories in results\n * @param project - Optional project slug to filter by\n */\n async searchMemories(\n query: string,\n limit: number = 10,\n threshold: number = 0.5,\n agentId?: string | null,\n includeConfidential: boolean = false,\n includeArchived: boolean = false,\n compress: boolean = false,\n maxContextTokens?: number,\n project?: string,\n tier?: string,\n minImportance?: number\n ): Promise<SearchResult[]> {\n this.validateContentSize(query);\n\n // If agentId is explicitly null, omit it (cross-agent search).\n // If agentId is undefined, use the default from config.\n const effectiveAgentId = agentId === null ? undefined : (agentId ?? this.config.agentId);\n\n const body: Record<string, unknown> = { query, limit, min_score: threshold };\n if (effectiveAgentId) {\n body.agent_id = effectiveAgentId;\n }\n if (includeConfidential) {\n body.include_confidential = true;\n }\n if (includeArchived) {\n body.include_archived = true;\n }\n if (compress) {\n body.compress = true;\n }\n if (maxContextTokens !== undefined) {\n body.max_context_tokens = maxContextTokens;\n }\n if (project) {\n body.project = project;\n }\n if (tier) {\n body.tier = tier;\n }\n if (minImportance !== undefined) {\n body.min_importance = minImportance;\n }\n\n const response = await this.request<{ data: SearchResult[] }>(\n 'POST',\n '/v1/memories/search',\n body\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 * Get entity neighborhood (ego-centric subgraph).\n * Returns the entity's 1-hop or 2-hop neighbors and relationships.\n */\n async getEntityNeighborhood(\n entityId: string,\n depth: number = 1,\n maxNeighbors: number = 50\n ): Promise<Record<string, unknown>> {\n return this.request<Record<string, unknown>>(\n 'GET',\n `/v1/entities/${entityId}/neighborhood?depth=${depth}&max_neighbors=${maxNeighbors}`\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 * List agents with pagination\n */\n async listAgents(limit: number = 20, offset: number = 0): Promise<ListResponse<Agent>> {\n return this.request<ListResponse<Agent>>(\n 'GET',\n `/v1/agents?limit=${limit}&offset=${offset}`\n );\n }\n\n /**\n * Create a new agent\n */\n async createAgent(\n name: string,\n description?: string,\n metadata?: Record<string, string>\n ): Promise<Agent> {\n const body: Record<string, unknown> = { name };\n if (description) body.description = description;\n if (metadata) body.metadata = metadata;\n\n return this.request<Agent>('POST', '/v1/agents', body);\n }\n\n /**\n * Get an agent by ID\n */\n async getAgent(id: string): Promise<Agent> {\n return this.request<Agent>('GET', `/v1/agents/${id}`);\n }\n\n /**\n * Batch store multiple memories in a single API call.\n * Uses the /v1/memories/batch endpoint.\n */\n async batchStoreMemories(\n items: BatchMemoryItem[]\n ): Promise<BatchStoreResponse> {\n if (items.length === 0) {\n return { success: true, total: 0, succeeded: 0, failed: 0, skipped: 0, results: [] };\n }\n if (items.length > 100) {\n throw new Error('Batch size exceeds maximum of 100 memories');\n }\n\n // Attach default agent_id to items that don't have one\n const memories = items.map(item => ({\n content: item.content,\n metadata: item.metadata || {},\n agent_id: item.agent_id || this.config.agentId,\n }));\n\n return this.request<BatchStoreResponse>('POST', '/v1/memories/batch', { memories });\n }\n\n /**\n * Build a context string from search results.\n * Searches for relevant memories, formats them, and returns\n * a single string ready for prompt injection.\n */\n async buildContext(\n query: string,\n limit: number = 10,\n threshold: number = 0.5,\n maxTokens?: number\n ): Promise<{ context: string; memories_used: number; total_chars: number }> {\n const results = await this.searchMemories(\n query,\n limit,\n threshold,\n undefined, // use default agent\n false, // no confidential\n false, // no archived\n !!maxTokens, // compress if token budget provided\n maxTokens\n );\n\n if (results.length === 0) {\n return { context: '', memories_used: 0, total_chars: 0 };\n }\n\n const lines: string[] = [];\n for (const result of results) {\n const score = (result.score * 100).toFixed(0);\n lines.push(`[${score}%] ${result.memory.content}`);\n }\n\n const context = lines.join('\\n\\n');\n\n // Rough token budget enforcement (1 token ≈ 4 chars)\n let finalContext = context;\n if (maxTokens) {\n const charBudget = maxTokens * 4;\n if (finalContext.length > charBudget) {\n finalContext = finalContext.slice(0, charBudget) + '\\n\\n[...truncated]';\n }\n }\n\n return {\n context: finalContext,\n memories_used: results.length,\n total_chars: finalContext.length,\n };\n }\n\n /**\n * Start a new session\n */\n async startSession(\n title?: string,\n project?: string,\n metadata?: Record<string, string>\n ): Promise<Session> {\n const body: Record<string, unknown> = {};\n if (this.config.agentId) body.agent_id = this.config.agentId;\n if (title) body.title = title;\n if (project) body.project = project;\n if (metadata) body.metadata = metadata;\n return this.request<Session>('POST', '/v1/sessions', body);\n }\n\n /**\n * End an active session\n */\n async endSession(\n sessionId: string,\n summary?: string,\n ): Promise<Session> {\n const body: Record<string, unknown> = {};\n if (summary) body.summary = summary;\n return this.request<Session>('PUT', `/v1/sessions/${sessionId}/end`, body);\n }\n\n /**\n * Get a session by ID with its memories\n */\n async getSession(sessionId: string): Promise<SessionDetail> {\n return this.request<SessionDetail>(\n 'GET',\n `/v1/sessions/${sessionId}?include_memories=true`\n );\n }\n\n /**\n * List sessions with optional filters\n */\n async listSessions(\n limit: number = 20,\n agentId?: string,\n project?: string,\n status?: string,\n ): Promise<ListResponse<Session>> {\n const params = new URLSearchParams();\n params.set('limit', String(limit));\n const effectiveAgentId = agentId ?? this.config.agentId;\n if (effectiveAgentId) params.set('agent_id', effectiveAgentId);\n if (project) params.set('project', project);\n if (status) params.set('status', status);\n return this.request<ListResponse<Session>>(\n 'GET',\n `/v1/sessions?${params.toString()}`\n );\n }\n\n /**\n * Record a new decision\n */\n async recordDecision(\n title: string,\n rationale: string,\n alternatives?: string,\n project?: string,\n tags?: string[],\n status?: string,\n metadata?: Record<string, string>\n ): Promise<Decision> {\n const body: Record<string, unknown> = { title, rationale };\n if (this.config.agentId) body.agent_id = this.config.agentId;\n if (alternatives) body.alternatives = alternatives;\n if (project) body.project_slug = project;\n if (tags) body.tags = tags;\n if (status) body.status = status;\n if (metadata) body.metadata = metadata;\n return this.request<Decision>('POST', '/v1/decisions', body);\n }\n\n /**\n * List decisions with optional filters\n */\n async listDecisions(\n limit?: number,\n project?: string,\n status?: string,\n tags?: string,\n ): Promise<ListResponse<Decision>> {\n const params = new URLSearchParams();\n if (limit) params.set('limit', String(limit));\n if (project) params.set('project', project);\n if (status) params.set('status', status);\n if (tags) params.set('tags', tags);\n return this.request<ListResponse<Decision>>(\n 'GET',\n `/v1/decisions?${params.toString()}`\n );\n }\n\n /**\n * Supersede a decision with a new one\n */\n async supersedeDecision(\n decisionId: string,\n title: string,\n rationale: string,\n alternatives?: string,\n tags?: string[],\n ): Promise<Decision> {\n const body: Record<string, unknown> = { title, rationale };\n if (alternatives) body.alternatives = alternatives;\n if (tags) body.tags = tags;\n return this.request<Decision>(\n 'POST',\n `/v1/decisions/${decisionId}/supersede`,\n body\n );\n }\n\n /**\n * Check for existing decisions about a topic (semantic search)\n */\n async checkDecisions(\n query: string,\n project?: string,\n limit?: number,\n threshold?: number,\n includeSuperseded?: boolean,\n ): Promise<{ data: DecisionCheckResult[]; query: string; total: number }> {\n const params = new URLSearchParams();\n params.set('query', query);\n if (limit) params.set('limit', String(limit));\n if (threshold !== undefined) params.set('threshold', String(threshold));\n if (project) params.set('project', project);\n if (includeSuperseded) params.set('include_superseded', 'true');\n return this.request<{ data: DecisionCheckResult[]; query: string; total: number }>(\n 'GET',\n `/v1/decisions/check?${params.toString()}`\n );\n }\n\n /**\n * Register a new project\n */\n async createProject(\n slug: string,\n name: string,\n description?: string,\n stack?: Record<string, unknown>,\n repo_url?: string,\n metadata?: Record<string, unknown>\n ): Promise<Project> {\n const body: Record<string, unknown> = { slug, name };\n if (description) body.description = description;\n if (stack) body.stack = stack;\n if (repo_url) body.repo_url = repo_url;\n if (metadata) body.metadata = metadata;\n return this.request<Project>('POST', '/v1/projects', body);\n }\n\n /**\n * List projects with optional pagination\n */\n async listProjects(\n limit: number = 20,\n cursor?: string\n ): Promise<ListResponse<Project>> {\n const params = new URLSearchParams();\n params.set('limit', String(limit));\n if (cursor) params.set('cursor', cursor);\n return this.request<ListResponse<Project>>(\n 'GET',\n `/v1/projects?${params.toString()}`\n );\n }\n\n /**\n * Get a project by slug\n */\n async getProject(slug: string): Promise<Project> {\n return this.request<Project>('GET', `/v1/projects/${slug}`);\n }\n\n /**\n * Create a reusable pattern\n */\n async createPattern(\n title: string,\n description: string,\n category?: string,\n example_code?: string,\n scope?: string,\n tags?: string[],\n source_project?: string,\n metadata?: Record<string, unknown>\n ): Promise<Pattern> {\n const body: Record<string, unknown> = { title, description };\n if (category) body.category = category;\n if (example_code) body.example_code = example_code;\n if (scope) body.scope = scope;\n if (tags) body.tags = tags;\n if (source_project) body.source_project = source_project;\n if (metadata) body.metadata = metadata;\n return this.request<Pattern>('POST', '/v1/patterns', body);\n }\n\n /**\n * Search patterns using semantic search\n */\n async searchPatterns(\n query: string,\n category?: string,\n project?: string,\n limit?: number,\n threshold?: number,\n ): Promise<{ data: PatternSearchResult[]; query: string; total: number }> {\n const params = new URLSearchParams();\n params.set('query', query);\n if (category) params.set('category', category);\n if (project) params.set('project', project);\n if (limit) params.set('limit', String(limit));\n if (threshold !== undefined) params.set('threshold', String(threshold));\n return this.request<{ data: PatternSearchResult[]; query: string; total: number }>(\n 'GET',\n `/v1/patterns/search?${params.toString()}`\n );\n }\n\n /**\n * Adopt a pattern for a project\n */\n async adoptPattern(\n patternId: string,\n project: string,\n ): Promise<Pattern> {\n return this.request<Pattern>(\n 'POST',\n `/v1/patterns/${patternId}/adopt`,\n { project }\n );\n }\n\n /**\n * Suggest patterns for a project\n */\n async suggestPatterns(\n project: string,\n limit?: number,\n ): Promise<{ data: Pattern[]; project: string; total: number }> {\n const params = new URLSearchParams();\n params.set('project', project);\n if (limit) params.set('limit', String(limit));\n return this.request<{ data: Pattern[]; project: string; total: number }>(\n 'GET',\n `/v1/patterns/suggest?${params.toString()}`\n );\n }\n\n // ── Project Relationships (Issue #186) ──\n\n /**\n * Add a relationship between two projects\n */\n async addProjectRelationship(\n sourceSlug: string,\n targetProject: string,\n relationshipType: string,\n metadata?: Record<string, unknown>,\n ): Promise<Record<string, unknown>> {\n const body: Record<string, unknown> = {\n target_project: targetProject,\n relationship_type: relationshipType,\n };\n if (metadata) body.metadata = metadata;\n return this.request<Record<string, unknown>>(\n 'POST',\n `/v1/projects/${sourceSlug}/relationships`,\n body,\n );\n }\n\n /**\n * Get what this project depends on\n */\n async getProjectDependencies(slug: string): Promise<Record<string, unknown>> {\n return this.request<Record<string, unknown>>(\n 'GET',\n `/v1/projects/${slug}/dependencies`,\n );\n }\n\n /**\n * Get what depends on this project\n */\n async getProjectDependents(slug: string): Promise<Record<string, unknown>> {\n return this.request<Record<string, unknown>>(\n 'GET',\n `/v1/projects/${slug}/dependents`,\n );\n }\n\n /**\n * Get all related projects\n */\n async getProjectRelated(slug: string): Promise<Record<string, unknown>> {\n return this.request<Record<string, unknown>>(\n 'GET',\n `/v1/projects/${slug}/related`,\n );\n }\n\n /**\n * Run impact analysis for a project change\n */\n async projectImpactAnalysis(\n project: string,\n changeDescription: string,\n ): Promise<Record<string, unknown>> {\n return this.request<Record<string, unknown>>(\n 'POST',\n '/v1/projects/impact-analysis',\n { project, change_description: changeDescription },\n );\n }\n\n /**\n * Find patterns shared between two projects\n */\n async getSharedPatterns(\n slugA: string,\n slugB: string,\n ): Promise<Record<string, unknown>> {\n return this.request<Record<string, unknown>>(\n 'GET',\n `/v1/projects/shared-patterns?a=${encodeURIComponent(slugA)}&b=${encodeURIComponent(slugB)}`,\n );\n }\n\n /**\n * Get full project context (hot memories, decisions, patterns, formatted text)\n */\n async getProjectContext(slug: string): Promise<Record<string, unknown>> {\n return this.request<Record<string, unknown>>(\n 'GET',\n `/v1/projects/${encodeURIComponent(slug)}/context`,\n );\n }\n\n /**\n * Promote/demote a memory by updating its importance and tier\n */\n async promoteMemory(\n memoryId: string,\n importance: number,\n tier?: string\n ): Promise<Memory> {\n const body: Record<string, unknown> = { importance };\n if (tier) {\n body.tier = tier;\n }\n return this.request<Memory>(\n 'PUT',\n `/v1/memories/${encodeURIComponent(memoryId)}/importance`,\n body,\n );\n }\n\n // ── V2 Async API (60-600x faster) ──\n\n /**\n * Store a memory asynchronously (V2 API).\n * Returns immediately with 202 Accepted and a job ID.\n * Use getMemoryStatus() to poll for completion.\n */\n async storeMemoryAsync(\n content: string,\n metadata?: Record<string, string>,\n project?: string,\n importance?: number,\n tier?: string,\n webhookUrl?: string\n ): Promise<{ id: string; status: string; job_id: string; estimated_completion_seconds: number }> {\n this.validateContentSize(content);\n\n const body: Record<string, unknown> = {\n content,\n agent_id: this.config.agentId,\n };\n if (metadata) body.metadata = metadata;\n if (project) body.project = project;\n if (importance !== undefined) body.importance = importance;\n if (tier) body.tier = tier;\n if (webhookUrl) body.webhook_url = webhookUrl;\n\n return this.request<{ id: string; status: string; job_id: string; estimated_completion_seconds: number }>(\n 'POST',\n '/v2/memories',\n body\n );\n }\n\n /**\n * Get memory processing status (V2 API).\n * Use after storeMemoryAsync() to check when embedding is ready.\n */\n async getMemoryStatus(memoryId: string): Promise<{\n id: string;\n status: 'pending' | 'processing' | 'ready' | 'failed';\n created_at: string;\n updated_at: string;\n error?: string;\n }> {\n return this.request<{\n id: string;\n status: 'pending' | 'processing' | 'ready' | 'failed';\n created_at: string;\n updated_at: string;\n error?: string;\n }>('GET', `/v2/memories/${memoryId}/status`);\n }\n\n /**\n * Build a ranked context bundle from memories (V2 API).\n * Supports optional AI summarization with custom LLM URL.\n */\n async buildContextV2(\n query: string,\n options?: {\n agentId?: string | null;\n maxMemories?: number;\n maxTokens?: number;\n aiEnhanced?: boolean;\n rankingVersion?: string;\n searchMode?: 'semantic' | 'hybrid' | 'keyword';\n llmApiUrl?: string;\n llmModel?: string;\n excludeMemoryIds?: string[];\n }\n ): Promise<{\n context: Array<{\n memory_id: string;\n content: string;\n score: number;\n memory_type?: string;\n }>;\n summary?: string;\n token_count: number;\n ranking_version: string;\n ai_enhanced: boolean;\n latency_ms: number;\n }> {\n const body: Record<string, unknown> = { query };\n if (options?.agentId !== undefined) body.agent_id = options.agentId;\n if (options?.maxMemories) body.max_memories = options.maxMemories;\n if (options?.maxTokens) body.max_tokens = options.maxTokens;\n if (options?.aiEnhanced) body.ai_enhanced = true;\n if (options?.rankingVersion) body.ranking_version = options.rankingVersion;\n if (options?.searchMode) body.search_mode = options.searchMode;\n if (options?.llmApiUrl) body.llm_api_url = options.llmApiUrl;\n if (options?.llmModel) body.llm_model = options.llmModel;\n if (options?.excludeMemoryIds) body.exclude_memory_ids = options.excludeMemoryIds;\n\n return this.request<{\n context: Array<{\n memory_id: string;\n content: string;\n score: number;\n memory_type?: string;\n }>;\n summary?: string;\n token_count: number;\n ranking_version: string;\n ai_enhanced: boolean;\n latency_ms: number;\n }>('POST', '/v2/context/build', body);\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"],"mappings":"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","names":[]}
|
package/dist/cli/test.js
CHANGED
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
getLogger,
|
|
7
7
|
initLogger,
|
|
8
8
|
loadConfig
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-PFC5Z5ZD.js";
|
|
10
10
|
|
|
11
11
|
// src/server.ts
|
|
12
12
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
@@ -38,7 +38,7 @@ var MemoryRelayMCPServer = class {
|
|
|
38
38
|
this.server = new Server(
|
|
39
39
|
{
|
|
40
40
|
name: "@memoryrelay/mcp-server",
|
|
41
|
-
version: "0.
|
|
41
|
+
version: "0.4.1"
|
|
42
42
|
},
|
|
43
43
|
{
|
|
44
44
|
capabilities: {
|
|
@@ -114,6 +114,15 @@ var MemoryRelayMCPServer = class {
|
|
|
114
114
|
type: "string",
|
|
115
115
|
description: 'Memory tier override: "hot" (always in context), "warm" (default), "cold" (archived). Auto-computed from importance if omitted.',
|
|
116
116
|
enum: ["hot", "warm", "cold"]
|
|
117
|
+
},
|
|
118
|
+
session_id: {
|
|
119
|
+
type: "string",
|
|
120
|
+
description: "Session ID to associate the memory with. Links the memory to an active session."
|
|
121
|
+
},
|
|
122
|
+
auto_extract_entities: {
|
|
123
|
+
type: "boolean",
|
|
124
|
+
description: "Automatically extract entities (people, places, orgs, etc.) from the memory content.",
|
|
125
|
+
default: false
|
|
117
126
|
}
|
|
118
127
|
},
|
|
119
128
|
required: ["content"]
|
|
@@ -1200,7 +1209,9 @@ var MemoryRelayMCPServer = class {
|
|
|
1200
1209
|
args.dedup_threshold,
|
|
1201
1210
|
args.project,
|
|
1202
1211
|
args.importance,
|
|
1203
|
-
args.tier
|
|
1212
|
+
args.tier,
|
|
1213
|
+
args.session_id,
|
|
1214
|
+
args.auto_extract_entities
|
|
1204
1215
|
);
|
|
1205
1216
|
return {
|
|
1206
1217
|
content: [
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/server.ts","../src/index.ts"],"sourcesContent":["/**\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 type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n} from '@modelcontextprotocol/sdk/types.js';\nimport { z } from 'zod';\nimport { MemoryRelayClient } from './client.js';\nimport { getEnabledTools } from './config.js';\nimport { getLogger } from './logger.js';\nimport type { ClientConfig } from './types.js';\n\n/**\n * HTML-encode string to prevent XSS\n */\nfunction sanitizeHtml(str: string): string {\n return str\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(/\\//g, '/');\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 private activeSessionId: string | null = null;\n private enabledTools: Set<string> | null = null;\n\n constructor(config: ClientConfig, client?: MemoryRelayClient) {\n this.client = client ?? new MemoryRelayClient(config);\n this.enabledTools = getEnabledTools();\n\n this.server = new Server(\n {\n name: '@memoryrelay/mcp-server',\n version: '0.3.0',\n },\n {\n capabilities: {\n tools: {},\n },\n instructions: [\n 'Recommended workflow:',\n '1. Call project_context(project) to load hot-tier memories for context',\n '2. Call session_start(project, goal) to begin tracking your work',\n '3. Call decision_check(project, topic) before making architectural choices',\n '4. Call pattern_search(query) to find established conventions',\n '5. Work on the task, using memory_store for important findings',\n '6. Call session_end(session_id, summary) when done',\n ].join('\\n'),\n }\n );\n\n this.setupHandlers();\n this.logger.info('MCP server initialized');\n }\n\n /**\n * Check if a tool is enabled by the current tool group configuration.\n */\n private isToolEnabled(name: string): boolean {\n return this.enabledTools === null || this.enabledTools.has(name);\n }\n\n /**\n * Setup MCP protocol handlers\n */\n private setupHandlers(): void {\n // List available tools (filtered by MEMORYRELAY_TOOLS env var)\n this.server.setRequestHandler(ListToolsRequestSchema, async () => {\n const sessionHint = this.activeSessionId\n ? ` Active session: ${this.activeSessionId}.`\n : ' Tip: Call session_start first to track what you are working on.';\n\n const allTools = [\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.${sessionHint}`,\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 deduplicate: {\n type: 'boolean',\n description: 'Check for duplicate/near-duplicate content before storing. Returns existing memory if match found.',\n default: false,\n },\n dedup_threshold: {\n type: 'number',\n description: 'Semantic similarity threshold for dedup (0.5-1.0). Only used when deduplicate=true.',\n minimum: 0.5,\n maximum: 1.0,\n default: 0.95,\n },\n project: {\n type: 'string',\n description: 'Project slug to associate the memory with (e.g., \"my-api\")',\n maxLength: 100,\n },\n importance: {\n type: 'number',\n description: 'Memory importance (0.0-1.0). Defaults to 0.5. Values >= 0.8 promote to hot tier.',\n minimum: 0,\n maximum: 1,\n default: 0.5,\n },\n tier: {\n type: 'string',\n description: 'Memory tier override: \"hot\" (always in context), \"warm\" (default), \"cold\" (archived). Auto-computed from importance if omitted.',\n enum: ['hot', 'warm', 'cold'],\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. Omit agent_id to search across all agents.',\n inputSchema: {\n type: 'object',\n properties: {\n query: {\n type: 'string',\n description: 'Natural language search query',\n },\n agent_id: {\n type: 'string',\n description: 'Optional agent ID to scope the search. If omitted, searches across all agents.',\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 include_confidential: {\n type: 'boolean',\n description: 'Include confidential memories in results (default: false)',\n default: false,\n },\n include_archived: {\n type: 'boolean',\n description: 'Include archived memories in results (default: false)',\n default: false,\n },\n compress: {\n type: 'boolean',\n description: 'Enable context compression on results',\n default: false,\n },\n max_context_tokens: {\n type: 'number',\n description: 'Target total token budget for compressed results',\n },\n project: {\n type: 'string',\n description: 'Filter by project slug. Omit for cross-project search.',\n maxLength: 100,\n },\n tier: {\n type: 'string',\n description: 'Filter by tier: \"hot\", \"warm\", or \"cold\". Omit to search all tiers.',\n enum: ['hot', 'warm', 'cold'],\n },\n min_importance: {\n type: 'number',\n description: 'Minimum importance threshold (0.0-1.0). Only return memories above this.',\n minimum: 0,\n maximum: 1,\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: 'entity_list',\n description: 'List entities in the knowledge graph with pagination. Entities are people, places, organizations, projects, and concepts extracted from memories.',\n inputSchema: {\n type: 'object',\n properties: {\n limit: {\n type: 'number',\n description: 'Number of entities 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: 'agent_list',\n description: 'List all agents with their memory counts. Agents are namespaces that isolate memories.',\n inputSchema: {\n type: 'object',\n properties: {\n limit: {\n type: 'number',\n description: 'Number of agents to return (1-100)',\n minimum: 1,\n maximum: 100,\n default: 20,\n },\n },\n },\n },\n {\n name: 'agent_create',\n description: 'Create a named agent. Agents are namespaces that isolate memories for different use cases or AI assistants.',\n inputSchema: {\n type: 'object',\n properties: {\n name: {\n type: 'string',\n description: 'Agent name (descriptive, e.g. \"iris\", \"friday\", \"code-assistant\")',\n },\n description: {\n type: 'string',\n description: 'Optional description of the agent\\'s purpose',\n },\n },\n required: ['name'],\n },\n },\n {\n name: 'agent_get',\n description: 'Get details of a specific agent by ID, including memory count.',\n inputSchema: {\n type: 'object',\n properties: {\n id: {\n type: 'string',\n description: 'The agent ID (UUID) to retrieve',\n },\n },\n required: ['id'],\n },\n },\n {\n name: 'entity_graph',\n description: 'Explore the knowledge graph around an entity. Returns neighboring entities and their relationships up to N hops away. Useful for understanding connections between people, projects, and concepts.',\n inputSchema: {\n type: 'object',\n properties: {\n entity_id: {\n type: 'string',\n description: 'Entity UUID to explore from',\n },\n depth: {\n type: 'number',\n description: 'How many hops to traverse (1 or 2)',\n minimum: 1,\n maximum: 2,\n default: 1,\n },\n max_neighbors: {\n type: 'number',\n description: 'Maximum neighbor entities to return (1-100)',\n minimum: 1,\n maximum: 100,\n default: 50,\n },\n },\n required: ['entity_id'],\n },\n },\n {\n name: 'memory_batch_store',\n description: 'Store multiple memories in a single operation. More efficient than calling memory_store repeatedly when saving several related facts or observations.',\n inputSchema: {\n type: 'object',\n properties: {\n memories: {\n type: 'array',\n description: 'Array of memories to store (1-100 items)',\n items: {\n type: 'object',\n properties: {\n content: {\n type: 'string',\n description: 'The memory content to store',\n },\n metadata: {\n type: 'object',\n description: 'Optional key-value metadata',\n additionalProperties: { type: 'string' },\n },\n },\n required: ['content'],\n },\n minItems: 1,\n maxItems: 100,\n },\n },\n required: ['memories'],\n },\n },\n {\n name: 'memory_context',\n description: 'Build a formatted context string from relevant memories for a given query. Returns ranked memories with similarity scores, ready for use in prompts. More convenient than memory_search when you need a single context block.',\n inputSchema: {\n type: 'object',\n properties: {\n query: {\n type: 'string',\n description: 'Natural language query to find relevant memories',\n },\n limit: {\n type: 'number',\n description: 'Maximum number of memories to include (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 max_tokens: {\n type: 'number',\n description: 'Maximum token budget for the context string. Results are truncated to fit.',\n },\n },\n required: ['query'],\n },\n },\n {\n name: 'project_register',\n description: 'Register a project (codebase/repository) to scope memories, sessions, and decisions. Projects have a unique slug for ergonomic referencing.',\n inputSchema: {\n type: 'object',\n properties: {\n slug: {\n type: 'string',\n description: 'URL-safe identifier (lowercase, hyphens allowed, e.g., \"my-api\")',\n pattern: '^[a-z0-9][a-z0-9-]*$',\n maxLength: 100,\n },\n name: {\n type: 'string',\n description: 'Human-readable project name (e.g., \"My API Service\")',\n maxLength: 255,\n },\n description: {\n type: 'string',\n description: 'Optional project description',\n },\n stack: {\n type: 'object',\n description: 'Technical stack metadata (e.g., {\"languages\": [\"python\"], \"frameworks\": [\"fastapi\"]})',\n },\n repo_url: {\n type: 'string',\n description: 'Repository URL (e.g., \"https://github.com/org/repo\")',\n maxLength: 500,\n },\n },\n required: ['slug', 'name'],\n },\n },\n {\n name: 'project_list',\n description: 'List registered projects. Shows all projects with their memory counts.',\n inputSchema: {\n type: 'object',\n properties: {\n limit: {\n type: 'number',\n description: 'Maximum number of projects to return (1-100)',\n minimum: 1,\n maximum: 100,\n default: 20,\n },\n },\n },\n },\n {\n name: 'project_info',\n description: 'Get detailed information about a specific project by its slug, including memory count and stack metadata.',\n inputSchema: {\n type: 'object',\n properties: {\n slug: {\n type: 'string',\n description: 'Project slug to look up',\n },\n },\n required: ['slug'],\n },\n },\n // ── Project Relationship Tools (Issue #186) ──\n {\n name: 'project_add_relationship',\n description: 'Register a relationship between two projects (e.g., depends_on, api_consumer, shares_schema, shares_infra, pattern_source, forked_from).',\n inputSchema: {\n type: 'object',\n properties: {\n from: {\n type: 'string',\n description: 'Source project slug',\n },\n to: {\n type: 'string',\n description: 'Target project slug',\n },\n type: {\n type: 'string',\n description: 'Relationship type (e.g., depends_on, api_consumer, shares_schema)',\n },\n details: {\n type: 'object',\n description: 'Optional relationship metadata',\n additionalProperties: true,\n },\n },\n required: ['from', 'to', 'type'],\n },\n },\n {\n name: 'project_dependencies',\n description: 'What does this project depend on? Returns outgoing depends_on and api_consumer relationships.',\n inputSchema: {\n type: 'object',\n properties: {\n project: {\n type: 'string',\n description: 'Project slug',\n },\n },\n required: ['project'],\n },\n },\n {\n name: 'project_dependents',\n description: 'What depends on this project? Returns incoming depends_on and api_consumer relationships.',\n inputSchema: {\n type: 'object',\n properties: {\n project: {\n type: 'string',\n description: 'Project slug',\n },\n },\n required: ['project'],\n },\n },\n {\n name: 'project_related',\n description: 'All related projects with relationship types and direction indicators.',\n inputSchema: {\n type: 'object',\n properties: {\n project: {\n type: 'string',\n description: 'Project slug',\n },\n },\n required: ['project'],\n },\n },\n {\n name: 'project_impact',\n description: 'Impact analysis: given a change description, which dependent projects might be affected? Searches decisions and memories in downstream projects.',\n inputSchema: {\n type: 'object',\n properties: {\n project: {\n type: 'string',\n description: 'Project slug being changed',\n },\n change_description: {\n type: 'string',\n description: 'Description of the change to analyze (max 5000 chars)',\n maxLength: 5000,\n },\n },\n required: ['project', 'change_description'],\n },\n },\n {\n name: 'project_shared_patterns',\n description: 'What do two projects have in common? Returns patterns adopted by both projects.',\n inputSchema: {\n type: 'object',\n properties: {\n project_a: {\n type: 'string',\n description: 'First project slug',\n },\n project_b: {\n type: 'string',\n description: 'Second project slug',\n },\n },\n required: ['project_a', 'project_b'],\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 name: 'session_start',\n description: 'Start a new session to group related memories. Sessions track bounded interaction periods (e.g., a coding session, a conversation). Use session_recall to see what happened in previous sessions.',\n inputSchema: {\n type: 'object',\n properties: {\n title: {\n type: 'string',\n description: 'Session title or goal (e.g., \"Fix email queue retry logic\")',\n maxLength: 500,\n },\n project: {\n type: 'string',\n description: 'Project label for filtering sessions (e.g., \"northrelay\")',\n maxLength: 255,\n },\n metadata: {\n type: 'object',\n description: 'Optional metadata',\n additionalProperties: { type: 'string' },\n },\n },\n },\n },\n {\n name: 'session_end',\n description: 'End an active session with an optional summary of what was accomplished.',\n inputSchema: {\n type: 'object',\n properties: {\n id: {\n type: 'string',\n description: 'Session ID (UUID) to end',\n },\n summary: {\n type: 'string',\n description: 'Summary of what was accomplished during the session',\n maxLength: 50000,\n },\n },\n required: ['id'],\n },\n },\n {\n name: 'session_recall',\n description: 'Recall a session by ID, including all memories created during it. Use this to review what happened in a past session.',\n inputSchema: {\n type: 'object',\n properties: {\n id: {\n type: 'string',\n description: 'Session ID (UUID) to recall',\n },\n },\n required: ['id'],\n },\n },\n {\n name: 'session_list',\n description: 'List recent sessions, optionally filtered by project or status. Shows session summaries to understand what happened in previous sessions.',\n inputSchema: {\n type: 'object',\n properties: {\n limit: {\n type: 'number',\n description: 'Maximum number of sessions to return (1-100)',\n minimum: 1,\n maximum: 100,\n default: 20,\n },\n project: {\n type: 'string',\n description: 'Filter by project label',\n },\n status: {\n type: 'string',\n enum: ['active', 'ended'],\n description: 'Filter by session status',\n },\n },\n },\n },\n {\n name: 'decision_record',\n description: 'Record an architectural decision with rationale. Use to log important technical choices, design decisions, or policy changes so they can be referenced later.',\n inputSchema: {\n type: 'object',\n properties: {\n title: {\n type: 'string',\n description: 'Decision title (e.g., \"Use PostgreSQL instead of MongoDB\")',\n maxLength: 500,\n },\n rationale: {\n type: 'string',\n description: 'Why this decision was made. Include context, constraints, and reasoning.',\n maxLength: 50000,\n },\n alternatives: {\n type: 'string',\n description: 'Alternatives that were considered and why they were rejected',\n },\n project: {\n type: 'string',\n description: 'Project slug to scope the decision to',\n maxLength: 100,\n },\n tags: {\n type: 'array',\n items: { type: 'string' },\n description: 'Tags for categorization (e.g., [\"architecture\", \"database\"])',\n },\n status: {\n type: 'string',\n enum: ['active', 'experimental'],\n description: 'Decision status (default: active)',\n },\n },\n required: ['title', 'rationale'],\n },\n },\n {\n name: 'decision_list',\n description: 'List recorded decisions, optionally filtered by project, status, or tags.',\n inputSchema: {\n type: 'object',\n properties: {\n limit: {\n type: 'number',\n description: 'Maximum results (1-100, default 20)',\n minimum: 1,\n maximum: 100,\n default: 20,\n },\n project: {\n type: 'string',\n description: 'Filter by project slug',\n },\n status: {\n type: 'string',\n enum: ['active', 'superseded', 'reverted', 'experimental'],\n description: 'Filter by decision status',\n },\n tags: {\n type: 'string',\n description: 'Comma-separated tags to filter by',\n },\n },\n },\n },\n {\n name: 'decision_supersede',\n description: 'Supersede an existing decision with a new one. Marks the old decision as superseded and creates a new active decision.',\n inputSchema: {\n type: 'object',\n properties: {\n id: {\n type: 'string',\n description: 'ID (UUID) of the decision to supersede',\n },\n title: {\n type: 'string',\n description: 'Title of the new decision',\n },\n rationale: {\n type: 'string',\n description: 'Rationale for the new decision',\n },\n alternatives: {\n type: 'string',\n description: 'Alternatives considered',\n },\n tags: {\n type: 'array',\n items: { type: 'string' },\n description: 'Tags for the new decision (inherits from old if omitted)',\n },\n },\n required: ['id', 'title', 'rationale'],\n },\n },\n {\n name: 'decision_check',\n description: 'Check if there are existing decisions about a topic using semantic search. Use this before making a new decision to see if the topic has already been addressed.',\n inputSchema: {\n type: 'object',\n properties: {\n query: {\n type: 'string',\n description: 'Natural language query describing the decision topic to check',\n },\n project: {\n type: 'string',\n description: 'Filter by project slug',\n },\n limit: {\n type: 'number',\n description: 'Maximum results (1-20, default 5)',\n minimum: 1,\n maximum: 20,\n default: 5,\n },\n threshold: {\n type: 'number',\n description: 'Minimum similarity threshold (0-1, default 0.3)',\n minimum: 0,\n maximum: 1,\n default: 0.3,\n },\n include_superseded: {\n type: 'boolean',\n description: 'Include superseded decisions in results (default: false)',\n default: false,\n },\n },\n required: ['query'],\n },\n },\n {\n name: 'pattern_create',\n description: 'Create a reusable development pattern or convention. Use to document patterns like \"always use Zod for validation\" or \"error responses follow RFC 7807\" so they can be discovered and adopted across projects.',\n inputSchema: {\n type: 'object',\n properties: {\n title: {\n type: 'string',\n description: 'Pattern title (e.g., \"Zod validation at API boundaries\")',\n maxLength: 500,\n },\n description: {\n type: 'string',\n description: 'Full description with context, rationale, and when to apply this pattern',\n maxLength: 50000,\n },\n category: {\n type: 'string',\n description: 'Category (e.g., \"validation\", \"error-handling\", \"auth\", \"testing\")',\n maxLength: 100,\n },\n example_code: {\n type: 'string',\n description: 'Code snippet demonstrating the pattern',\n },\n scope: {\n type: 'string',\n enum: ['global', 'project'],\n description: 'Scope: global (all projects) or project (specific projects). Default: global',\n },\n tags: {\n type: 'array',\n items: { type: 'string' },\n description: 'Tags for categorization',\n },\n source_project: {\n type: 'string',\n description: 'Slug of the project where this pattern was first established',\n },\n },\n required: ['title', 'description'],\n },\n },\n {\n name: 'pattern_search',\n description: 'Search for development patterns using semantic similarity. When working on a project, shows both global patterns and patterns adopted by that project.',\n inputSchema: {\n type: 'object',\n properties: {\n query: {\n type: 'string',\n description: 'Natural language query describing the pattern to find (e.g., \"validation\", \"error handling\")',\n },\n category: {\n type: 'string',\n description: 'Filter by category',\n },\n project: {\n type: 'string',\n description: 'Project context — shows global patterns plus patterns adopted by this project',\n },\n limit: {\n type: 'number',\n description: 'Maximum results (1-50, default 10)',\n minimum: 1,\n maximum: 50,\n default: 10,\n },\n threshold: {\n type: 'number',\n description: 'Minimum similarity threshold (0-1, default 0.3)',\n minimum: 0,\n maximum: 1,\n default: 0.3,\n },\n },\n required: ['query'],\n },\n },\n {\n name: 'pattern_adopt',\n description: 'Mark a pattern as adopted by a project. This links the pattern to the project so it shows up in project-scoped searches.',\n inputSchema: {\n type: 'object',\n properties: {\n id: {\n type: 'string',\n description: 'Pattern ID (UUID) to adopt',\n },\n project: {\n type: 'string',\n description: 'Project slug to adopt this pattern for',\n },\n },\n required: ['id', 'project'],\n },\n },\n {\n name: 'pattern_suggest',\n description: 'Suggest relevant patterns for a project based on what similar projects have adopted. Returns patterns not yet adopted by the target project, ranked by popularity.',\n inputSchema: {\n type: 'object',\n properties: {\n project: {\n type: 'string',\n description: 'Project slug to get suggestions for',\n },\n limit: {\n type: 'number',\n description: 'Maximum suggestions (1-50, default 10)',\n minimum: 1,\n maximum: 50,\n default: 10,\n },\n },\n required: ['project'],\n },\n },\n {\n name: 'project_context',\n description: 'Get full project context for LLM consumption. Returns hot-tier memories, active decisions, adopted patterns, and a pre-formatted markdown context string.',\n inputSchema: {\n type: 'object',\n properties: {\n project: {\n type: 'string',\n description: 'Project slug to get context for',\n },\n },\n required: ['project'],\n },\n },\n {\n name: 'memory_promote',\n description: 'Update a memory\\'s importance and tier. Use to promote critical memories to hot tier (always in context) or demote them to cold tier (archived).',\n inputSchema: {\n type: 'object',\n properties: {\n memory_id: {\n type: 'string',\n description: 'Memory ID (UUID) to promote/demote',\n },\n importance: {\n type: 'number',\n description: 'New importance value (0.0-1.0). Values >= 0.8 promote to hot tier.',\n minimum: 0,\n maximum: 1,\n },\n tier: {\n type: 'string',\n description: 'Optional tier override: \"hot\", \"warm\", or \"cold\". Auto-computed from importance if omitted.',\n enum: ['hot', 'warm', 'cold'],\n },\n },\n required: ['memory_id', 'importance'],\n },\n },\n // ── V2 Async API Tools (60-600x faster) ──\n {\n name: 'memory_store_async',\n description: 'Store a memory asynchronously using V2 API. Returns immediately (<50ms) with 202 Accepted and a job ID. Background workers generate the embedding. Use memory_status to poll for completion. Prefer this over memory_store for high-throughput or latency-sensitive applications.',\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 project: {\n type: 'string',\n description: 'Project slug to associate the memory with',\n maxLength: 100,\n },\n importance: {\n type: 'number',\n description: 'Memory importance (0.0-1.0). Values >= 0.8 promote to hot tier.',\n minimum: 0,\n maximum: 1,\n },\n tier: {\n type: 'string',\n description: 'Memory tier override: \"hot\", \"warm\", or \"cold\"',\n enum: ['hot', 'warm', 'cold'],\n },\n webhook_url: {\n type: 'string',\n description: 'Optional webhook URL to receive completion notification',\n },\n },\n required: ['content'],\n },\n },\n {\n name: 'memory_status',\n description: 'Check the processing status of a memory created via memory_store_async. Poll this endpoint to determine when embedding generation is complete. Status values: pending (waiting for worker), processing (generating embedding), ready (searchable), failed (error occurred).',\n inputSchema: {\n type: 'object',\n properties: {\n memory_id: {\n type: 'string',\n description: 'Memory ID (UUID) to check status for',\n },\n },\n required: ['memory_id'],\n },\n },\n {\n name: 'context_build',\n description: 'Build a ranked context bundle from memories using V2 API with optional AI summarization. Searches for relevant memories, ranks them by composite score, and optionally generates an AI summary. Useful for building token-efficient context windows for LLM prompts. Supports custom LLM endpoints (Ollama, llama.cpp, vLLM, etc.).',\n inputSchema: {\n type: 'object',\n properties: {\n query: {\n type: 'string',\n description: 'Context query describing what information is needed',\n },\n max_memories: {\n type: 'number',\n description: 'Maximum number of memories to include (1-100, default 20)',\n minimum: 1,\n maximum: 100,\n default: 20,\n },\n max_tokens: {\n type: 'number',\n description: 'Token budget for context window (enforces truncation)',\n minimum: 100,\n maximum: 128000,\n },\n ai_enhanced: {\n type: 'boolean',\n description: 'Enable AI summarization of context (uses LLM)',\n default: false,\n },\n search_mode: {\n type: 'string',\n description: 'Search mode: \"semantic\", \"hybrid\", or \"keyword\"',\n enum: ['semantic', 'hybrid', 'keyword'],\n default: 'hybrid',\n },\n llm_api_url: {\n type: 'string',\n description: 'Custom LLM API URL for summarization (OpenAI-compatible). Use for local LLMs: Ollama (http://localhost:11434/v1), llama.cpp, vLLM, LM Studio, etc.',\n },\n llm_model: {\n type: 'string',\n description: 'Model name for custom LLM (e.g., \"mistral\", \"llama3\", \"gemma\")',\n },\n exclude_memory_ids: {\n type: 'array',\n items: { type: 'string' },\n description: 'Memory IDs to exclude (for multi-turn context building)',\n },\n },\n required: ['query'],\n },\n },\n // ── Tool Name Aliases (backward compatibility with OpenClaw plugin) ──\n {\n name: 'memory_forget',\n description: 'Delete a memory by ID, or search by query to find candidates. Alias for memory_delete. Provide memoryId for direct deletion, or query to search first.',\n inputSchema: {\n type: 'object',\n properties: {\n memoryId: {\n type: 'string',\n description: 'Memory ID to delete',\n },\n query: {\n type: 'string',\n description: 'Search query to find memory',\n },\n },\n },\n },\n {\n name: 'memory_recall',\n description: 'Search memories using natural language. Alias for memory_search with default project scoping. Returns the most relevant memories based on semantic similarity.',\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 results (1-50). Default 5.',\n minimum: 1,\n maximum: 50,\n default: 5,\n },\n threshold: {\n type: 'number',\n description: 'Minimum similarity threshold (0-1). Default 0.3.',\n minimum: 0,\n maximum: 1,\n default: 0.3,\n },\n project: {\n type: 'string',\n description: 'Filter by project slug',\n },\n max_tokens: {\n type: 'number',\n description: 'Token budget for context window',\n },\n },\n required: ['query'],\n },\n },\n ];\n\n return {\n tools: allTools.filter(t => this.isToolEnabled(t.name)),\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 args.deduplicate as boolean | undefined,\n args.dedup_threshold as number | undefined,\n args.project as string | undefined,\n args.importance as number | undefined,\n args.tier as 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 // If agent_id is provided, use it; otherwise pass null for cross-agent search\n const searchAgentId = args.agent_id != null\n ? (args.agent_id as string)\n : null;\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 searchAgentId,\n args.include_confidential as boolean | undefined ?? false,\n args.include_archived as boolean | undefined ?? false,\n args.compress as boolean | undefined ?? false,\n args.max_context_tokens as number | undefined,\n args.project as string | undefined,\n args.tier as string | undefined,\n args.min_importance 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 'entity_list': {\n const response = await this.client.listEntities(\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 'agent_list': {\n const response = await this.client.listAgents(\n args.limit 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 'agent_create': {\n const createSchema = z.object({\n name: z.string().min(1).max(255),\n description: z.string().max(1000).optional(),\n });\n\n const validatedInput = createSchema.parse(args);\n const sanitizedName = sanitizeHtml(validatedInput.name);\n\n const agent = await this.client.createAgent(\n sanitizedName,\n validatedInput.description\n );\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(agent, null, 2),\n },\n ],\n };\n }\n\n case 'agent_get': {\n const id = args.id as string;\n validateUuid(id, 'agent_id');\n\n const agent = await this.client.getAgent(id);\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(agent, null, 2),\n },\n ],\n };\n }\n\n case 'entity_graph': {\n const graphSchema = z.object({\n entity_id: z.string().uuid(),\n depth: z.number().min(1).max(2).default(1),\n max_neighbors: z.number().min(1).max(100).default(50),\n });\n\n const validatedInput = graphSchema.parse(args);\n const result = await this.client.getEntityNeighborhood(\n validatedInput.entity_id,\n validatedInput.depth,\n validatedInput.max_neighbors\n );\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(result, null, 2),\n },\n ],\n };\n }\n\n case 'memory_batch_store': {\n const batchSchema = z.object({\n memories: z.array(z.object({\n content: z.string().min(1),\n metadata: z.record(z.string()).optional(),\n })).min(1).max(100),\n });\n\n const validatedInput = batchSchema.parse(args);\n const result = await this.client.batchStoreMemories(validatedInput.memories);\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(result, null, 2),\n },\n ],\n };\n }\n\n case 'memory_context': {\n const contextSchema = z.object({\n query: z.string().min(1),\n limit: z.number().min(1).max(50).default(10),\n threshold: z.number().min(0).max(1).default(0.5),\n max_tokens: z.number().positive().optional(),\n });\n\n const validatedInput = contextSchema.parse(args);\n const result = await this.client.buildContext(\n validatedInput.query,\n validatedInput.limit,\n validatedInput.threshold,\n validatedInput.max_tokens\n );\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(result, null, 2),\n },\n ],\n };\n }\n\n case 'project_register': {\n const projectSchema = z.object({\n slug: z.string().min(1).max(100).regex(/^[a-z0-9][a-z0-9-]*$/),\n name: z.string().min(1).max(255),\n description: z.string().optional(),\n stack: z.record(z.unknown()).optional(),\n repo_url: z.string().max(500).optional(),\n });\n\n const validatedInput = projectSchema.parse(args);\n const project = await this.client.createProject(\n validatedInput.slug,\n validatedInput.name,\n validatedInput.description,\n validatedInput.stack,\n validatedInput.repo_url,\n );\n return {\n content: [{ type: 'text', text: JSON.stringify(project, null, 2) }],\n };\n }\n\n case 'project_list': {\n const response = await this.client.listProjects(\n args.limit as number | undefined,\n );\n return {\n content: [{ type: 'text', text: JSON.stringify(response, null, 2) }],\n };\n }\n\n case 'project_info': {\n const slug = args.slug as string;\n if (!slug) {\n throw new Error('Project slug is required');\n }\n const project = await this.client.getProject(slug);\n return {\n content: [{ type: 'text', text: JSON.stringify(project, null, 2) }],\n };\n }\n\n // ── Project Relationship Handlers (Issue #186) ──\n\n case 'project_add_relationship': {\n const relSchema = z.object({\n from: z.string().min(1),\n to: z.string().min(1),\n type: z.string().min(1).max(100),\n details: z.record(z.unknown()).optional(),\n });\n const relArgs = relSchema.parse(args);\n const relationship = await this.client.addProjectRelationship(\n relArgs.from,\n relArgs.to,\n relArgs.type,\n relArgs.details as Record<string, unknown> | undefined,\n );\n return {\n content: [{ type: 'text', text: JSON.stringify(relationship, null, 2) }],\n };\n }\n\n case 'project_dependencies': {\n const depSlug = args.project as string;\n if (!depSlug) throw new Error('Project slug is required');\n const deps = await this.client.getProjectDependencies(depSlug);\n return {\n content: [{ type: 'text', text: JSON.stringify(deps, null, 2) }],\n };\n }\n\n case 'project_dependents': {\n const deptSlug = args.project as string;\n if (!deptSlug) throw new Error('Project slug is required');\n const dependents = await this.client.getProjectDependents(deptSlug);\n return {\n content: [{ type: 'text', text: JSON.stringify(dependents, null, 2) }],\n };\n }\n\n case 'project_related': {\n const relatedSlug = args.project as string;\n if (!relatedSlug) throw new Error('Project slug is required');\n const related = await this.client.getProjectRelated(relatedSlug);\n return {\n content: [{ type: 'text', text: JSON.stringify(related, null, 2) }],\n };\n }\n\n case 'project_impact': {\n const impactSchema = z.object({\n project: z.string().min(1),\n change_description: z.string().min(1).max(5000),\n });\n const impactArgs = impactSchema.parse(args);\n const impact = await this.client.projectImpactAnalysis(\n impactArgs.project,\n impactArgs.change_description,\n );\n return {\n content: [{ type: 'text', text: JSON.stringify(impact, null, 2) }],\n };\n }\n\n case 'project_shared_patterns': {\n const spSchema = z.object({\n project_a: z.string().min(1),\n project_b: z.string().min(1),\n });\n const spArgs = spSchema.parse(args);\n const shared = await this.client.getSharedPatterns(\n spArgs.project_a,\n spArgs.project_b,\n );\n return {\n content: [{ type: 'text', text: JSON.stringify(shared, null, 2) }],\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 case 'session_start': {\n const session = await this.client.startSession(\n args.title as string | undefined,\n args.project as string | undefined,\n args.metadata as Record<string, string> | undefined,\n );\n // Track active session for session-aware tool descriptions\n this.activeSessionId = (session as unknown as Record<string, unknown>).id as string ?? null;\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(session, null, 2),\n },\n ],\n };\n }\n\n case 'session_end': {\n const id = args.id as string;\n validateUuid(id, 'session_id');\n const session = await this.client.endSession(\n id,\n args.summary as string | undefined,\n );\n // Clear active session tracking\n if (this.activeSessionId === id) {\n this.activeSessionId = null;\n }\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(session, null, 2),\n },\n ],\n };\n }\n\n case 'session_recall': {\n const id = args.id as string;\n validateUuid(id, 'session_id');\n const session = await this.client.getSession(id);\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(session, null, 2),\n },\n ],\n };\n }\n\n case 'session_list': {\n const response = await this.client.listSessions(\n args.limit as number | undefined,\n undefined,\n args.project as string | undefined,\n args.status as string | undefined,\n );\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(response, null, 2),\n },\n ],\n };\n }\n\n case 'decision_record': {\n const decision = await this.client.recordDecision(\n args.title as string,\n args.rationale as string,\n args.alternatives as string | undefined,\n args.project as string | undefined,\n args.tags as string[] | undefined,\n args.status as string | undefined,\n );\n return {\n content: [{ type: 'text', text: JSON.stringify(decision, null, 2) }],\n };\n }\n\n case 'decision_list': {\n const response = await this.client.listDecisions(\n args.limit as number | undefined,\n args.project as string | undefined,\n args.status as string | undefined,\n args.tags as string | undefined,\n );\n return {\n content: [{ type: 'text', text: JSON.stringify(response, null, 2) }],\n };\n }\n\n case 'decision_supersede': {\n const id = args.id as string;\n validateUuid(id, 'decision_id');\n const decision = await this.client.supersedeDecision(\n id,\n args.title as string,\n args.rationale as string,\n args.alternatives as string | undefined,\n args.tags as string[] | undefined,\n );\n return {\n content: [{ type: 'text', text: JSON.stringify(decision, null, 2) }],\n };\n }\n\n case 'decision_check': {\n const response = await this.client.checkDecisions(\n args.query as string,\n args.project as string | undefined,\n args.limit as number | undefined,\n args.threshold as number | undefined,\n (args.include_superseded as boolean | undefined) ?? false,\n );\n return {\n content: [{ type: 'text', text: JSON.stringify(response, null, 2) }],\n };\n }\n\n case 'pattern_create': {\n const patternSchema = z.object({\n title: z.string().min(1).max(500),\n description: z.string().min(1).max(50000),\n category: z.string().max(100).optional(),\n example_code: z.string().optional(),\n scope: z.enum(['global', 'project']).optional(),\n tags: z.array(z.string()).max(20).optional(),\n source_project: z.string().max(100).optional(),\n });\n\n const validatedInput = patternSchema.parse(args);\n const pattern = await this.client.createPattern(\n validatedInput.title,\n validatedInput.description,\n validatedInput.category,\n validatedInput.example_code,\n validatedInput.scope,\n validatedInput.tags,\n validatedInput.source_project,\n );\n return {\n content: [{ type: 'text', text: JSON.stringify(pattern, null, 2) }],\n };\n }\n\n case 'pattern_search': {\n const response = await this.client.searchPatterns(\n args.query as string,\n args.category as string | undefined,\n args.project as string | undefined,\n args.limit as number | undefined,\n args.threshold as number | undefined,\n );\n return {\n content: [{ type: 'text', text: JSON.stringify(response, null, 2) }],\n };\n }\n\n case 'pattern_adopt': {\n const id = args.id as string;\n validateUuid(id, 'pattern_id');\n const pattern = await this.client.adoptPattern(\n id,\n args.project as string,\n );\n return {\n content: [{ type: 'text', text: JSON.stringify(pattern, null, 2) }],\n };\n }\n\n case 'pattern_suggest': {\n const response = await this.client.suggestPatterns(\n args.project as string,\n args.limit as number | undefined,\n );\n return {\n content: [{ type: 'text', text: JSON.stringify(response, null, 2) }],\n };\n }\n\n case 'project_context': {\n const context = await this.client.getProjectContext(\n args.project as string,\n );\n return {\n content: [{ type: 'text', text: JSON.stringify(context, null, 2) }],\n };\n }\n\n case 'memory_promote': {\n const id = args.memory_id as string;\n validateUuid(id, 'memory_id');\n const updated = await this.client.promoteMemory(\n id,\n args.importance as number,\n args.tier as string | undefined,\n );\n return {\n content: [{ type: 'text', text: JSON.stringify(updated, null, 2) }],\n };\n }\n\n // ── V2 Async API Tool Handlers ──\n\n case 'memory_store_async': {\n const response = await this.client.storeMemoryAsync(\n args.content as string,\n args.metadata as Record<string, string> | undefined,\n args.project as string | undefined,\n args.importance as number | undefined,\n args.tier as string | undefined,\n args.webhook_url as string | undefined,\n );\n return {\n content: [{ type: 'text', text: JSON.stringify(response, null, 2) }],\n };\n }\n\n case 'memory_status': {\n const id = args.memory_id as string;\n validateUuid(id, 'memory_id');\n const status = await this.client.getMemoryStatus(id);\n return {\n content: [{ type: 'text', text: JSON.stringify(status, null, 2) }],\n };\n }\n\n case 'context_build': {\n const result = await this.client.buildContextV2(\n args.query as string,\n {\n agentId: args.agent_id as string | null | undefined,\n maxMemories: args.max_memories as number | undefined,\n maxTokens: args.max_tokens as number | undefined,\n aiEnhanced: args.ai_enhanced as boolean | undefined,\n rankingVersion: args.ranking_version as string | undefined,\n searchMode: args.search_mode as 'semantic' | 'hybrid' | 'keyword' | undefined,\n llmApiUrl: args.llm_api_url as string | undefined,\n llmModel: args.llm_model as string | undefined,\n excludeMemoryIds: args.exclude_memory_ids as string[] | undefined,\n }\n );\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n };\n }\n\n // ── Tool Name Aliases (backward compatibility) ──\n\n case 'memory_forget': {\n // Alias for memory_delete\n const id = args.memoryId as string | undefined;\n const query = args.query as string | undefined;\n \n if (id) {\n await this.client.deleteMemory(id);\n return {\n content: [{ type: 'text', text: `Memory ${id.slice(0, 8)}... deleted.` }],\n };\n } else if (query) {\n // Search and auto-delete if high confidence match\n const results = await this.client.searchMemories(query, 1, 0.9);\n if (results.length === 1) {\n await this.client.deleteMemory(results[0].memory.id);\n return {\n content: [{ type: 'text', text: `Memory ${results[0].memory.id.slice(0, 8)}... deleted (matched query).` }],\n };\n }\n return {\n content: [{ type: 'text', text: `Found ${results.length} matches. Provide memoryId to delete.` }],\n };\n }\n throw new Error('memoryId or query is required');\n }\n\n case 'memory_recall': {\n // Alias for memory_search with default agent_id from config\n const results = await this.client.searchMemories(\n args.query as string,\n (args.limit as number) ?? 5,\n (args.threshold as number) ?? 0.3,\n undefined, // use default agent\n false,\n false,\n false,\n args.max_tokens as number | undefined,\n args.project as string | undefined,\n );\n return {\n content: [{ type: 'text', text: JSON.stringify({ memories: results, total: results.length }, null, 2) }],\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 * 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 * Connect the MCP server to a custom transport (for testing)\n */\n async connectTransport(transport: Transport): Promise<void> {\n await this.server.connect(transport);\n }\n\n /**\n * Close the MCP server connection\n */\n async close(): Promise<void> {\n await this.server.close();\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 * CLI commands:\n * npx memoryrelay-mcp Start MCP server (stdio transport)\n * npx memoryrelay-mcp setup Interactive setup wizard\n * npx memoryrelay-mcp test Test API connectivity\n */\n\nimport { loadConfig, getAgentId } from './config.js';\nimport { initLogger, getLogger } from './logger.js';\nimport { MemoryRelayMCPServer } from './server.js';\n\nasync function startServer(): Promise<void> {\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\nasync function main(): Promise<void> {\n const command = process.argv[2];\n\n try {\n switch (command) {\n case 'setup': {\n const { runSetup } = await import('./cli/setup.js');\n await runSetup();\n break;\n }\n case 'test': {\n const { runTest } = await import('./cli/test.js');\n await runTest();\n break;\n }\n case '--help':\n case '-h': {\n console.error(`\n memoryrelay-mcp - Persistent memory for AI agents\n\n Usage:\n npx memoryrelay-mcp Start MCP server (stdio transport)\n npx memoryrelay-mcp setup Interactive setup wizard\n npx memoryrelay-mcp test Test API connectivity\n npx memoryrelay-mcp --help Show this help message\n\n Environment variables:\n MEMORYRELAY_API_KEY API key (required, starts with \"mem_\")\n MEMORYRELAY_API_URL API URL (default: https://api.memoryrelay.net)\n MEMORYRELAY_AGENT_ID Agent ID (optional, auto-detected)\n MEMORYRELAY_TIMEOUT Request timeout in ms (default: 30000)\n MEMORYRELAY_LOG_LEVEL Log level: debug|info|warn|error (default: info)\n\n Documentation: https://github.com/memoryrelay/mcp-server\n`);\n break;\n }\n default:\n await startServer();\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('\\nFailed to start MemoryRelay MCP server\\n');\n console.error(error.message);\n console.error('\\nFor help, run: npx memoryrelay-mcp --help\\n');\n } else {\n logger.error('Fatal error:', { error });\n console.error('\\nAn unexpected error occurred\\n');\n }\n\n process.exit(1);\n }\n}\n\nmain();\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/server.ts","../src/index.ts"],"sourcesContent":["/**\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 type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n} from '@modelcontextprotocol/sdk/types.js';\nimport { z } from 'zod';\nimport { MemoryRelayClient } from './client.js';\nimport { getEnabledTools } from './config.js';\nimport { getLogger } from './logger.js';\nimport type { ClientConfig } from './types.js';\n\n/**\n * HTML-encode string to prevent XSS\n */\nfunction sanitizeHtml(str: string): string {\n return str\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n .replace(/\\//g, '/');\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 private activeSessionId: string | null = null;\n private enabledTools: Set<string> | null = null;\n\n constructor(config: ClientConfig, client?: MemoryRelayClient) {\n this.client = client ?? new MemoryRelayClient(config);\n this.enabledTools = getEnabledTools();\n\n this.server = new Server(\n {\n name: '@memoryrelay/mcp-server',\n version: '0.4.1',\n },\n {\n capabilities: {\n tools: {},\n },\n instructions: [\n 'Recommended workflow:',\n '1. Call project_context(project) to load hot-tier memories for context',\n '2. Call session_start(project, goal) to begin tracking your work',\n '3. Call decision_check(project, topic) before making architectural choices',\n '4. Call pattern_search(query) to find established conventions',\n '5. Work on the task, using memory_store for important findings',\n '6. Call session_end(session_id, summary) when done',\n ].join('\\n'),\n }\n );\n\n this.setupHandlers();\n this.logger.info('MCP server initialized');\n }\n\n /**\n * Check if a tool is enabled by the current tool group configuration.\n */\n private isToolEnabled(name: string): boolean {\n return this.enabledTools === null || this.enabledTools.has(name);\n }\n\n /**\n * Setup MCP protocol handlers\n */\n private setupHandlers(): void {\n // List available tools (filtered by MEMORYRELAY_TOOLS env var)\n this.server.setRequestHandler(ListToolsRequestSchema, async () => {\n const sessionHint = this.activeSessionId\n ? ` Active session: ${this.activeSessionId}.`\n : ' Tip: Call session_start first to track what you are working on.';\n\n const allTools = [\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.${sessionHint}`,\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 deduplicate: {\n type: 'boolean',\n description: 'Check for duplicate/near-duplicate content before storing. Returns existing memory if match found.',\n default: false,\n },\n dedup_threshold: {\n type: 'number',\n description: 'Semantic similarity threshold for dedup (0.5-1.0). Only used when deduplicate=true.',\n minimum: 0.5,\n maximum: 1.0,\n default: 0.95,\n },\n project: {\n type: 'string',\n description: 'Project slug to associate the memory with (e.g., \"my-api\")',\n maxLength: 100,\n },\n importance: {\n type: 'number',\n description: 'Memory importance (0.0-1.0). Defaults to 0.5. Values >= 0.8 promote to hot tier.',\n minimum: 0,\n maximum: 1,\n default: 0.5,\n },\n tier: {\n type: 'string',\n description: 'Memory tier override: \"hot\" (always in context), \"warm\" (default), \"cold\" (archived). Auto-computed from importance if omitted.',\n enum: ['hot', 'warm', 'cold'],\n },\n session_id: {\n type: 'string',\n description: 'Session ID to associate the memory with. Links the memory to an active session.',\n },\n auto_extract_entities: {\n type: 'boolean',\n description: 'Automatically extract entities (people, places, orgs, etc.) from the memory content.',\n default: false,\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. Omit agent_id to search across all agents.',\n inputSchema: {\n type: 'object',\n properties: {\n query: {\n type: 'string',\n description: 'Natural language search query',\n },\n agent_id: {\n type: 'string',\n description: 'Optional agent ID to scope the search. If omitted, searches across all agents.',\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 include_confidential: {\n type: 'boolean',\n description: 'Include confidential memories in results (default: false)',\n default: false,\n },\n include_archived: {\n type: 'boolean',\n description: 'Include archived memories in results (default: false)',\n default: false,\n },\n compress: {\n type: 'boolean',\n description: 'Enable context compression on results',\n default: false,\n },\n max_context_tokens: {\n type: 'number',\n description: 'Target total token budget for compressed results',\n },\n project: {\n type: 'string',\n description: 'Filter by project slug. Omit for cross-project search.',\n maxLength: 100,\n },\n tier: {\n type: 'string',\n description: 'Filter by tier: \"hot\", \"warm\", or \"cold\". Omit to search all tiers.',\n enum: ['hot', 'warm', 'cold'],\n },\n min_importance: {\n type: 'number',\n description: 'Minimum importance threshold (0.0-1.0). Only return memories above this.',\n minimum: 0,\n maximum: 1,\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: 'entity_list',\n description: 'List entities in the knowledge graph with pagination. Entities are people, places, organizations, projects, and concepts extracted from memories.',\n inputSchema: {\n type: 'object',\n properties: {\n limit: {\n type: 'number',\n description: 'Number of entities 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: 'agent_list',\n description: 'List all agents with their memory counts. Agents are namespaces that isolate memories.',\n inputSchema: {\n type: 'object',\n properties: {\n limit: {\n type: 'number',\n description: 'Number of agents to return (1-100)',\n minimum: 1,\n maximum: 100,\n default: 20,\n },\n },\n },\n },\n {\n name: 'agent_create',\n description: 'Create a named agent. Agents are namespaces that isolate memories for different use cases or AI assistants.',\n inputSchema: {\n type: 'object',\n properties: {\n name: {\n type: 'string',\n description: 'Agent name (descriptive, e.g. \"iris\", \"friday\", \"code-assistant\")',\n },\n description: {\n type: 'string',\n description: 'Optional description of the agent\\'s purpose',\n },\n },\n required: ['name'],\n },\n },\n {\n name: 'agent_get',\n description: 'Get details of a specific agent by ID, including memory count.',\n inputSchema: {\n type: 'object',\n properties: {\n id: {\n type: 'string',\n description: 'The agent ID (UUID) to retrieve',\n },\n },\n required: ['id'],\n },\n },\n {\n name: 'entity_graph',\n description: 'Explore the knowledge graph around an entity. Returns neighboring entities and their relationships up to N hops away. Useful for understanding connections between people, projects, and concepts.',\n inputSchema: {\n type: 'object',\n properties: {\n entity_id: {\n type: 'string',\n description: 'Entity UUID to explore from',\n },\n depth: {\n type: 'number',\n description: 'How many hops to traverse (1 or 2)',\n minimum: 1,\n maximum: 2,\n default: 1,\n },\n max_neighbors: {\n type: 'number',\n description: 'Maximum neighbor entities to return (1-100)',\n minimum: 1,\n maximum: 100,\n default: 50,\n },\n },\n required: ['entity_id'],\n },\n },\n {\n name: 'memory_batch_store',\n description: 'Store multiple memories in a single operation. More efficient than calling memory_store repeatedly when saving several related facts or observations.',\n inputSchema: {\n type: 'object',\n properties: {\n memories: {\n type: 'array',\n description: 'Array of memories to store (1-100 items)',\n items: {\n type: 'object',\n properties: {\n content: {\n type: 'string',\n description: 'The memory content to store',\n },\n metadata: {\n type: 'object',\n description: 'Optional key-value metadata',\n additionalProperties: { type: 'string' },\n },\n },\n required: ['content'],\n },\n minItems: 1,\n maxItems: 100,\n },\n },\n required: ['memories'],\n },\n },\n {\n name: 'memory_context',\n description: 'Build a formatted context string from relevant memories for a given query. Returns ranked memories with similarity scores, ready for use in prompts. More convenient than memory_search when you need a single context block.',\n inputSchema: {\n type: 'object',\n properties: {\n query: {\n type: 'string',\n description: 'Natural language query to find relevant memories',\n },\n limit: {\n type: 'number',\n description: 'Maximum number of memories to include (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 max_tokens: {\n type: 'number',\n description: 'Maximum token budget for the context string. Results are truncated to fit.',\n },\n },\n required: ['query'],\n },\n },\n {\n name: 'project_register',\n description: 'Register a project (codebase/repository) to scope memories, sessions, and decisions. Projects have a unique slug for ergonomic referencing.',\n inputSchema: {\n type: 'object',\n properties: {\n slug: {\n type: 'string',\n description: 'URL-safe identifier (lowercase, hyphens allowed, e.g., \"my-api\")',\n pattern: '^[a-z0-9][a-z0-9-]*$',\n maxLength: 100,\n },\n name: {\n type: 'string',\n description: 'Human-readable project name (e.g., \"My API Service\")',\n maxLength: 255,\n },\n description: {\n type: 'string',\n description: 'Optional project description',\n },\n stack: {\n type: 'object',\n description: 'Technical stack metadata (e.g., {\"languages\": [\"python\"], \"frameworks\": [\"fastapi\"]})',\n },\n repo_url: {\n type: 'string',\n description: 'Repository URL (e.g., \"https://github.com/org/repo\")',\n maxLength: 500,\n },\n },\n required: ['slug', 'name'],\n },\n },\n {\n name: 'project_list',\n description: 'List registered projects. Shows all projects with their memory counts.',\n inputSchema: {\n type: 'object',\n properties: {\n limit: {\n type: 'number',\n description: 'Maximum number of projects to return (1-100)',\n minimum: 1,\n maximum: 100,\n default: 20,\n },\n },\n },\n },\n {\n name: 'project_info',\n description: 'Get detailed information about a specific project by its slug, including memory count and stack metadata.',\n inputSchema: {\n type: 'object',\n properties: {\n slug: {\n type: 'string',\n description: 'Project slug to look up',\n },\n },\n required: ['slug'],\n },\n },\n // ── Project Relationship Tools (Issue #186) ──\n {\n name: 'project_add_relationship',\n description: 'Register a relationship between two projects (e.g., depends_on, api_consumer, shares_schema, shares_infra, pattern_source, forked_from).',\n inputSchema: {\n type: 'object',\n properties: {\n from: {\n type: 'string',\n description: 'Source project slug',\n },\n to: {\n type: 'string',\n description: 'Target project slug',\n },\n type: {\n type: 'string',\n description: 'Relationship type (e.g., depends_on, api_consumer, shares_schema)',\n },\n details: {\n type: 'object',\n description: 'Optional relationship metadata',\n additionalProperties: true,\n },\n },\n required: ['from', 'to', 'type'],\n },\n },\n {\n name: 'project_dependencies',\n description: 'What does this project depend on? Returns outgoing depends_on and api_consumer relationships.',\n inputSchema: {\n type: 'object',\n properties: {\n project: {\n type: 'string',\n description: 'Project slug',\n },\n },\n required: ['project'],\n },\n },\n {\n name: 'project_dependents',\n description: 'What depends on this project? Returns incoming depends_on and api_consumer relationships.',\n inputSchema: {\n type: 'object',\n properties: {\n project: {\n type: 'string',\n description: 'Project slug',\n },\n },\n required: ['project'],\n },\n },\n {\n name: 'project_related',\n description: 'All related projects with relationship types and direction indicators.',\n inputSchema: {\n type: 'object',\n properties: {\n project: {\n type: 'string',\n description: 'Project slug',\n },\n },\n required: ['project'],\n },\n },\n {\n name: 'project_impact',\n description: 'Impact analysis: given a change description, which dependent projects might be affected? Searches decisions and memories in downstream projects.',\n inputSchema: {\n type: 'object',\n properties: {\n project: {\n type: 'string',\n description: 'Project slug being changed',\n },\n change_description: {\n type: 'string',\n description: 'Description of the change to analyze (max 5000 chars)',\n maxLength: 5000,\n },\n },\n required: ['project', 'change_description'],\n },\n },\n {\n name: 'project_shared_patterns',\n description: 'What do two projects have in common? Returns patterns adopted by both projects.',\n inputSchema: {\n type: 'object',\n properties: {\n project_a: {\n type: 'string',\n description: 'First project slug',\n },\n project_b: {\n type: 'string',\n description: 'Second project slug',\n },\n },\n required: ['project_a', 'project_b'],\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 name: 'session_start',\n description: 'Start a new session to group related memories. Sessions track bounded interaction periods (e.g., a coding session, a conversation). Use session_recall to see what happened in previous sessions.',\n inputSchema: {\n type: 'object',\n properties: {\n title: {\n type: 'string',\n description: 'Session title or goal (e.g., \"Fix email queue retry logic\")',\n maxLength: 500,\n },\n project: {\n type: 'string',\n description: 'Project label for filtering sessions (e.g., \"northrelay\")',\n maxLength: 255,\n },\n metadata: {\n type: 'object',\n description: 'Optional metadata',\n additionalProperties: { type: 'string' },\n },\n },\n },\n },\n {\n name: 'session_end',\n description: 'End an active session with an optional summary of what was accomplished.',\n inputSchema: {\n type: 'object',\n properties: {\n id: {\n type: 'string',\n description: 'Session ID (UUID) to end',\n },\n summary: {\n type: 'string',\n description: 'Summary of what was accomplished during the session',\n maxLength: 50000,\n },\n },\n required: ['id'],\n },\n },\n {\n name: 'session_recall',\n description: 'Recall a session by ID, including all memories created during it. Use this to review what happened in a past session.',\n inputSchema: {\n type: 'object',\n properties: {\n id: {\n type: 'string',\n description: 'Session ID (UUID) to recall',\n },\n },\n required: ['id'],\n },\n },\n {\n name: 'session_list',\n description: 'List recent sessions, optionally filtered by project or status. Shows session summaries to understand what happened in previous sessions.',\n inputSchema: {\n type: 'object',\n properties: {\n limit: {\n type: 'number',\n description: 'Maximum number of sessions to return (1-100)',\n minimum: 1,\n maximum: 100,\n default: 20,\n },\n project: {\n type: 'string',\n description: 'Filter by project label',\n },\n status: {\n type: 'string',\n enum: ['active', 'ended'],\n description: 'Filter by session status',\n },\n },\n },\n },\n {\n name: 'decision_record',\n description: 'Record an architectural decision with rationale. Use to log important technical choices, design decisions, or policy changes so they can be referenced later.',\n inputSchema: {\n type: 'object',\n properties: {\n title: {\n type: 'string',\n description: 'Decision title (e.g., \"Use PostgreSQL instead of MongoDB\")',\n maxLength: 500,\n },\n rationale: {\n type: 'string',\n description: 'Why this decision was made. Include context, constraints, and reasoning.',\n maxLength: 50000,\n },\n alternatives: {\n type: 'string',\n description: 'Alternatives that were considered and why they were rejected',\n },\n project: {\n type: 'string',\n description: 'Project slug to scope the decision to',\n maxLength: 100,\n },\n tags: {\n type: 'array',\n items: { type: 'string' },\n description: 'Tags for categorization (e.g., [\"architecture\", \"database\"])',\n },\n status: {\n type: 'string',\n enum: ['active', 'experimental'],\n description: 'Decision status (default: active)',\n },\n },\n required: ['title', 'rationale'],\n },\n },\n {\n name: 'decision_list',\n description: 'List recorded decisions, optionally filtered by project, status, or tags.',\n inputSchema: {\n type: 'object',\n properties: {\n limit: {\n type: 'number',\n description: 'Maximum results (1-100, default 20)',\n minimum: 1,\n maximum: 100,\n default: 20,\n },\n project: {\n type: 'string',\n description: 'Filter by project slug',\n },\n status: {\n type: 'string',\n enum: ['active', 'superseded', 'reverted', 'experimental'],\n description: 'Filter by decision status',\n },\n tags: {\n type: 'string',\n description: 'Comma-separated tags to filter by',\n },\n },\n },\n },\n {\n name: 'decision_supersede',\n description: 'Supersede an existing decision with a new one. Marks the old decision as superseded and creates a new active decision.',\n inputSchema: {\n type: 'object',\n properties: {\n id: {\n type: 'string',\n description: 'ID (UUID) of the decision to supersede',\n },\n title: {\n type: 'string',\n description: 'Title of the new decision',\n },\n rationale: {\n type: 'string',\n description: 'Rationale for the new decision',\n },\n alternatives: {\n type: 'string',\n description: 'Alternatives considered',\n },\n tags: {\n type: 'array',\n items: { type: 'string' },\n description: 'Tags for the new decision (inherits from old if omitted)',\n },\n },\n required: ['id', 'title', 'rationale'],\n },\n },\n {\n name: 'decision_check',\n description: 'Check if there are existing decisions about a topic using semantic search. Use this before making a new decision to see if the topic has already been addressed.',\n inputSchema: {\n type: 'object',\n properties: {\n query: {\n type: 'string',\n description: 'Natural language query describing the decision topic to check',\n },\n project: {\n type: 'string',\n description: 'Filter by project slug',\n },\n limit: {\n type: 'number',\n description: 'Maximum results (1-20, default 5)',\n minimum: 1,\n maximum: 20,\n default: 5,\n },\n threshold: {\n type: 'number',\n description: 'Minimum similarity threshold (0-1, default 0.3)',\n minimum: 0,\n maximum: 1,\n default: 0.3,\n },\n include_superseded: {\n type: 'boolean',\n description: 'Include superseded decisions in results (default: false)',\n default: false,\n },\n },\n required: ['query'],\n },\n },\n {\n name: 'pattern_create',\n description: 'Create a reusable development pattern or convention. Use to document patterns like \"always use Zod for validation\" or \"error responses follow RFC 7807\" so they can be discovered and adopted across projects.',\n inputSchema: {\n type: 'object',\n properties: {\n title: {\n type: 'string',\n description: 'Pattern title (e.g., \"Zod validation at API boundaries\")',\n maxLength: 500,\n },\n description: {\n type: 'string',\n description: 'Full description with context, rationale, and when to apply this pattern',\n maxLength: 50000,\n },\n category: {\n type: 'string',\n description: 'Category (e.g., \"validation\", \"error-handling\", \"auth\", \"testing\")',\n maxLength: 100,\n },\n example_code: {\n type: 'string',\n description: 'Code snippet demonstrating the pattern',\n },\n scope: {\n type: 'string',\n enum: ['global', 'project'],\n description: 'Scope: global (all projects) or project (specific projects). Default: global',\n },\n tags: {\n type: 'array',\n items: { type: 'string' },\n description: 'Tags for categorization',\n },\n source_project: {\n type: 'string',\n description: 'Slug of the project where this pattern was first established',\n },\n },\n required: ['title', 'description'],\n },\n },\n {\n name: 'pattern_search',\n description: 'Search for development patterns using semantic similarity. When working on a project, shows both global patterns and patterns adopted by that project.',\n inputSchema: {\n type: 'object',\n properties: {\n query: {\n type: 'string',\n description: 'Natural language query describing the pattern to find (e.g., \"validation\", \"error handling\")',\n },\n category: {\n type: 'string',\n description: 'Filter by category',\n },\n project: {\n type: 'string',\n description: 'Project context — shows global patterns plus patterns adopted by this project',\n },\n limit: {\n type: 'number',\n description: 'Maximum results (1-50, default 10)',\n minimum: 1,\n maximum: 50,\n default: 10,\n },\n threshold: {\n type: 'number',\n description: 'Minimum similarity threshold (0-1, default 0.3)',\n minimum: 0,\n maximum: 1,\n default: 0.3,\n },\n },\n required: ['query'],\n },\n },\n {\n name: 'pattern_adopt',\n description: 'Mark a pattern as adopted by a project. This links the pattern to the project so it shows up in project-scoped searches.',\n inputSchema: {\n type: 'object',\n properties: {\n id: {\n type: 'string',\n description: 'Pattern ID (UUID) to adopt',\n },\n project: {\n type: 'string',\n description: 'Project slug to adopt this pattern for',\n },\n },\n required: ['id', 'project'],\n },\n },\n {\n name: 'pattern_suggest',\n description: 'Suggest relevant patterns for a project based on what similar projects have adopted. Returns patterns not yet adopted by the target project, ranked by popularity.',\n inputSchema: {\n type: 'object',\n properties: {\n project: {\n type: 'string',\n description: 'Project slug to get suggestions for',\n },\n limit: {\n type: 'number',\n description: 'Maximum suggestions (1-50, default 10)',\n minimum: 1,\n maximum: 50,\n default: 10,\n },\n },\n required: ['project'],\n },\n },\n {\n name: 'project_context',\n description: 'Get full project context for LLM consumption. Returns hot-tier memories, active decisions, adopted patterns, and a pre-formatted markdown context string.',\n inputSchema: {\n type: 'object',\n properties: {\n project: {\n type: 'string',\n description: 'Project slug to get context for',\n },\n },\n required: ['project'],\n },\n },\n {\n name: 'memory_promote',\n description: 'Update a memory\\'s importance and tier. Use to promote critical memories to hot tier (always in context) or demote them to cold tier (archived).',\n inputSchema: {\n type: 'object',\n properties: {\n memory_id: {\n type: 'string',\n description: 'Memory ID (UUID) to promote/demote',\n },\n importance: {\n type: 'number',\n description: 'New importance value (0.0-1.0). Values >= 0.8 promote to hot tier.',\n minimum: 0,\n maximum: 1,\n },\n tier: {\n type: 'string',\n description: 'Optional tier override: \"hot\", \"warm\", or \"cold\". Auto-computed from importance if omitted.',\n enum: ['hot', 'warm', 'cold'],\n },\n },\n required: ['memory_id', 'importance'],\n },\n },\n // ── V2 Async API Tools (60-600x faster) ──\n {\n name: 'memory_store_async',\n description: 'Store a memory asynchronously using V2 API. Returns immediately (<50ms) with 202 Accepted and a job ID. Background workers generate the embedding. Use memory_status to poll for completion. Prefer this over memory_store for high-throughput or latency-sensitive applications.',\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 project: {\n type: 'string',\n description: 'Project slug to associate the memory with',\n maxLength: 100,\n },\n importance: {\n type: 'number',\n description: 'Memory importance (0.0-1.0). Values >= 0.8 promote to hot tier.',\n minimum: 0,\n maximum: 1,\n },\n tier: {\n type: 'string',\n description: 'Memory tier override: \"hot\", \"warm\", or \"cold\"',\n enum: ['hot', 'warm', 'cold'],\n },\n webhook_url: {\n type: 'string',\n description: 'Optional webhook URL to receive completion notification',\n },\n },\n required: ['content'],\n },\n },\n {\n name: 'memory_status',\n description: 'Check the processing status of a memory created via memory_store_async. Poll this endpoint to determine when embedding generation is complete. Status values: pending (waiting for worker), processing (generating embedding), ready (searchable), failed (error occurred).',\n inputSchema: {\n type: 'object',\n properties: {\n memory_id: {\n type: 'string',\n description: 'Memory ID (UUID) to check status for',\n },\n },\n required: ['memory_id'],\n },\n },\n {\n name: 'context_build',\n description: 'Build a ranked context bundle from memories using V2 API with optional AI summarization. Searches for relevant memories, ranks them by composite score, and optionally generates an AI summary. Useful for building token-efficient context windows for LLM prompts. Supports custom LLM endpoints (Ollama, llama.cpp, vLLM, etc.).',\n inputSchema: {\n type: 'object',\n properties: {\n query: {\n type: 'string',\n description: 'Context query describing what information is needed',\n },\n max_memories: {\n type: 'number',\n description: 'Maximum number of memories to include (1-100, default 20)',\n minimum: 1,\n maximum: 100,\n default: 20,\n },\n max_tokens: {\n type: 'number',\n description: 'Token budget for context window (enforces truncation)',\n minimum: 100,\n maximum: 128000,\n },\n ai_enhanced: {\n type: 'boolean',\n description: 'Enable AI summarization of context (uses LLM)',\n default: false,\n },\n search_mode: {\n type: 'string',\n description: 'Search mode: \"semantic\", \"hybrid\", or \"keyword\"',\n enum: ['semantic', 'hybrid', 'keyword'],\n default: 'hybrid',\n },\n llm_api_url: {\n type: 'string',\n description: 'Custom LLM API URL for summarization (OpenAI-compatible). Use for local LLMs: Ollama (http://localhost:11434/v1), llama.cpp, vLLM, LM Studio, etc.',\n },\n llm_model: {\n type: 'string',\n description: 'Model name for custom LLM (e.g., \"mistral\", \"llama3\", \"gemma\")',\n },\n exclude_memory_ids: {\n type: 'array',\n items: { type: 'string' },\n description: 'Memory IDs to exclude (for multi-turn context building)',\n },\n },\n required: ['query'],\n },\n },\n // ── Tool Name Aliases (backward compatibility with OpenClaw plugin) ──\n {\n name: 'memory_forget',\n description: 'Delete a memory by ID, or search by query to find candidates. Alias for memory_delete. Provide memoryId for direct deletion, or query to search first.',\n inputSchema: {\n type: 'object',\n properties: {\n memoryId: {\n type: 'string',\n description: 'Memory ID to delete',\n },\n query: {\n type: 'string',\n description: 'Search query to find memory',\n },\n },\n },\n },\n {\n name: 'memory_recall',\n description: 'Search memories using natural language. Alias for memory_search with default project scoping. Returns the most relevant memories based on semantic similarity.',\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 results (1-50). Default 5.',\n minimum: 1,\n maximum: 50,\n default: 5,\n },\n threshold: {\n type: 'number',\n description: 'Minimum similarity threshold (0-1). Default 0.3.',\n minimum: 0,\n maximum: 1,\n default: 0.3,\n },\n project: {\n type: 'string',\n description: 'Filter by project slug',\n },\n max_tokens: {\n type: 'number',\n description: 'Token budget for context window',\n },\n },\n required: ['query'],\n },\n },\n ];\n\n return {\n tools: allTools.filter(t => this.isToolEnabled(t.name)),\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 args.deduplicate as boolean | undefined,\n args.dedup_threshold as number | undefined,\n args.project as string | undefined,\n args.importance as number | undefined,\n args.tier as string | undefined,\n args.session_id as string | undefined,\n args.auto_extract_entities as boolean | 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 // If agent_id is provided, use it; otherwise pass null for cross-agent search\n const searchAgentId = args.agent_id != null\n ? (args.agent_id as string)\n : null;\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 searchAgentId,\n args.include_confidential as boolean | undefined ?? false,\n args.include_archived as boolean | undefined ?? false,\n args.compress as boolean | undefined ?? false,\n args.max_context_tokens as number | undefined,\n args.project as string | undefined,\n args.tier as string | undefined,\n args.min_importance 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 'entity_list': {\n const response = await this.client.listEntities(\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 'agent_list': {\n const response = await this.client.listAgents(\n args.limit 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 'agent_create': {\n const createSchema = z.object({\n name: z.string().min(1).max(255),\n description: z.string().max(1000).optional(),\n });\n\n const validatedInput = createSchema.parse(args);\n const sanitizedName = sanitizeHtml(validatedInput.name);\n\n const agent = await this.client.createAgent(\n sanitizedName,\n validatedInput.description\n );\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(agent, null, 2),\n },\n ],\n };\n }\n\n case 'agent_get': {\n const id = args.id as string;\n validateUuid(id, 'agent_id');\n\n const agent = await this.client.getAgent(id);\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(agent, null, 2),\n },\n ],\n };\n }\n\n case 'entity_graph': {\n const graphSchema = z.object({\n entity_id: z.string().uuid(),\n depth: z.number().min(1).max(2).default(1),\n max_neighbors: z.number().min(1).max(100).default(50),\n });\n\n const validatedInput = graphSchema.parse(args);\n const result = await this.client.getEntityNeighborhood(\n validatedInput.entity_id,\n validatedInput.depth,\n validatedInput.max_neighbors\n );\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(result, null, 2),\n },\n ],\n };\n }\n\n case 'memory_batch_store': {\n const batchSchema = z.object({\n memories: z.array(z.object({\n content: z.string().min(1),\n metadata: z.record(z.string()).optional(),\n })).min(1).max(100),\n });\n\n const validatedInput = batchSchema.parse(args);\n const result = await this.client.batchStoreMemories(validatedInput.memories);\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(result, null, 2),\n },\n ],\n };\n }\n\n case 'memory_context': {\n const contextSchema = z.object({\n query: z.string().min(1),\n limit: z.number().min(1).max(50).default(10),\n threshold: z.number().min(0).max(1).default(0.5),\n max_tokens: z.number().positive().optional(),\n });\n\n const validatedInput = contextSchema.parse(args);\n const result = await this.client.buildContext(\n validatedInput.query,\n validatedInput.limit,\n validatedInput.threshold,\n validatedInput.max_tokens\n );\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(result, null, 2),\n },\n ],\n };\n }\n\n case 'project_register': {\n const projectSchema = z.object({\n slug: z.string().min(1).max(100).regex(/^[a-z0-9][a-z0-9-]*$/),\n name: z.string().min(1).max(255),\n description: z.string().optional(),\n stack: z.record(z.unknown()).optional(),\n repo_url: z.string().max(500).optional(),\n });\n\n const validatedInput = projectSchema.parse(args);\n const project = await this.client.createProject(\n validatedInput.slug,\n validatedInput.name,\n validatedInput.description,\n validatedInput.stack,\n validatedInput.repo_url,\n );\n return {\n content: [{ type: 'text', text: JSON.stringify(project, null, 2) }],\n };\n }\n\n case 'project_list': {\n const response = await this.client.listProjects(\n args.limit as number | undefined,\n );\n return {\n content: [{ type: 'text', text: JSON.stringify(response, null, 2) }],\n };\n }\n\n case 'project_info': {\n const slug = args.slug as string;\n if (!slug) {\n throw new Error('Project slug is required');\n }\n const project = await this.client.getProject(slug);\n return {\n content: [{ type: 'text', text: JSON.stringify(project, null, 2) }],\n };\n }\n\n // ── Project Relationship Handlers (Issue #186) ──\n\n case 'project_add_relationship': {\n const relSchema = z.object({\n from: z.string().min(1),\n to: z.string().min(1),\n type: z.string().min(1).max(100),\n details: z.record(z.unknown()).optional(),\n });\n const relArgs = relSchema.parse(args);\n const relationship = await this.client.addProjectRelationship(\n relArgs.from,\n relArgs.to,\n relArgs.type,\n relArgs.details as Record<string, unknown> | undefined,\n );\n return {\n content: [{ type: 'text', text: JSON.stringify(relationship, null, 2) }],\n };\n }\n\n case 'project_dependencies': {\n const depSlug = args.project as string;\n if (!depSlug) throw new Error('Project slug is required');\n const deps = await this.client.getProjectDependencies(depSlug);\n return {\n content: [{ type: 'text', text: JSON.stringify(deps, null, 2) }],\n };\n }\n\n case 'project_dependents': {\n const deptSlug = args.project as string;\n if (!deptSlug) throw new Error('Project slug is required');\n const dependents = await this.client.getProjectDependents(deptSlug);\n return {\n content: [{ type: 'text', text: JSON.stringify(dependents, null, 2) }],\n };\n }\n\n case 'project_related': {\n const relatedSlug = args.project as string;\n if (!relatedSlug) throw new Error('Project slug is required');\n const related = await this.client.getProjectRelated(relatedSlug);\n return {\n content: [{ type: 'text', text: JSON.stringify(related, null, 2) }],\n };\n }\n\n case 'project_impact': {\n const impactSchema = z.object({\n project: z.string().min(1),\n change_description: z.string().min(1).max(5000),\n });\n const impactArgs = impactSchema.parse(args);\n const impact = await this.client.projectImpactAnalysis(\n impactArgs.project,\n impactArgs.change_description,\n );\n return {\n content: [{ type: 'text', text: JSON.stringify(impact, null, 2) }],\n };\n }\n\n case 'project_shared_patterns': {\n const spSchema = z.object({\n project_a: z.string().min(1),\n project_b: z.string().min(1),\n });\n const spArgs = spSchema.parse(args);\n const shared = await this.client.getSharedPatterns(\n spArgs.project_a,\n spArgs.project_b,\n );\n return {\n content: [{ type: 'text', text: JSON.stringify(shared, null, 2) }],\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 case 'session_start': {\n const session = await this.client.startSession(\n args.title as string | undefined,\n args.project as string | undefined,\n args.metadata as Record<string, string> | undefined,\n );\n // Track active session for session-aware tool descriptions\n this.activeSessionId = (session as unknown as Record<string, unknown>).id as string ?? null;\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(session, null, 2),\n },\n ],\n };\n }\n\n case 'session_end': {\n const id = args.id as string;\n validateUuid(id, 'session_id');\n const session = await this.client.endSession(\n id,\n args.summary as string | undefined,\n );\n // Clear active session tracking\n if (this.activeSessionId === id) {\n this.activeSessionId = null;\n }\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(session, null, 2),\n },\n ],\n };\n }\n\n case 'session_recall': {\n const id = args.id as string;\n validateUuid(id, 'session_id');\n const session = await this.client.getSession(id);\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(session, null, 2),\n },\n ],\n };\n }\n\n case 'session_list': {\n const response = await this.client.listSessions(\n args.limit as number | undefined,\n undefined,\n args.project as string | undefined,\n args.status as string | undefined,\n );\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(response, null, 2),\n },\n ],\n };\n }\n\n case 'decision_record': {\n const decision = await this.client.recordDecision(\n args.title as string,\n args.rationale as string,\n args.alternatives as string | undefined,\n args.project as string | undefined,\n args.tags as string[] | undefined,\n args.status as string | undefined,\n );\n return {\n content: [{ type: 'text', text: JSON.stringify(decision, null, 2) }],\n };\n }\n\n case 'decision_list': {\n const response = await this.client.listDecisions(\n args.limit as number | undefined,\n args.project as string | undefined,\n args.status as string | undefined,\n args.tags as string | undefined,\n );\n return {\n content: [{ type: 'text', text: JSON.stringify(response, null, 2) }],\n };\n }\n\n case 'decision_supersede': {\n const id = args.id as string;\n validateUuid(id, 'decision_id');\n const decision = await this.client.supersedeDecision(\n id,\n args.title as string,\n args.rationale as string,\n args.alternatives as string | undefined,\n args.tags as string[] | undefined,\n );\n return {\n content: [{ type: 'text', text: JSON.stringify(decision, null, 2) }],\n };\n }\n\n case 'decision_check': {\n const response = await this.client.checkDecisions(\n args.query as string,\n args.project as string | undefined,\n args.limit as number | undefined,\n args.threshold as number | undefined,\n (args.include_superseded as boolean | undefined) ?? false,\n );\n return {\n content: [{ type: 'text', text: JSON.stringify(response, null, 2) }],\n };\n }\n\n case 'pattern_create': {\n const patternSchema = z.object({\n title: z.string().min(1).max(500),\n description: z.string().min(1).max(50000),\n category: z.string().max(100).optional(),\n example_code: z.string().optional(),\n scope: z.enum(['global', 'project']).optional(),\n tags: z.array(z.string()).max(20).optional(),\n source_project: z.string().max(100).optional(),\n });\n\n const validatedInput = patternSchema.parse(args);\n const pattern = await this.client.createPattern(\n validatedInput.title,\n validatedInput.description,\n validatedInput.category,\n validatedInput.example_code,\n validatedInput.scope,\n validatedInput.tags,\n validatedInput.source_project,\n );\n return {\n content: [{ type: 'text', text: JSON.stringify(pattern, null, 2) }],\n };\n }\n\n case 'pattern_search': {\n const response = await this.client.searchPatterns(\n args.query as string,\n args.category as string | undefined,\n args.project as string | undefined,\n args.limit as number | undefined,\n args.threshold as number | undefined,\n );\n return {\n content: [{ type: 'text', text: JSON.stringify(response, null, 2) }],\n };\n }\n\n case 'pattern_adopt': {\n const id = args.id as string;\n validateUuid(id, 'pattern_id');\n const pattern = await this.client.adoptPattern(\n id,\n args.project as string,\n );\n return {\n content: [{ type: 'text', text: JSON.stringify(pattern, null, 2) }],\n };\n }\n\n case 'pattern_suggest': {\n const response = await this.client.suggestPatterns(\n args.project as string,\n args.limit as number | undefined,\n );\n return {\n content: [{ type: 'text', text: JSON.stringify(response, null, 2) }],\n };\n }\n\n case 'project_context': {\n const context = await this.client.getProjectContext(\n args.project as string,\n );\n return {\n content: [{ type: 'text', text: JSON.stringify(context, null, 2) }],\n };\n }\n\n case 'memory_promote': {\n const id = args.memory_id as string;\n validateUuid(id, 'memory_id');\n const updated = await this.client.promoteMemory(\n id,\n args.importance as number,\n args.tier as string | undefined,\n );\n return {\n content: [{ type: 'text', text: JSON.stringify(updated, null, 2) }],\n };\n }\n\n // ── V2 Async API Tool Handlers ──\n\n case 'memory_store_async': {\n const response = await this.client.storeMemoryAsync(\n args.content as string,\n args.metadata as Record<string, string> | undefined,\n args.project as string | undefined,\n args.importance as number | undefined,\n args.tier as string | undefined,\n args.webhook_url as string | undefined,\n );\n return {\n content: [{ type: 'text', text: JSON.stringify(response, null, 2) }],\n };\n }\n\n case 'memory_status': {\n const id = args.memory_id as string;\n validateUuid(id, 'memory_id');\n const status = await this.client.getMemoryStatus(id);\n return {\n content: [{ type: 'text', text: JSON.stringify(status, null, 2) }],\n };\n }\n\n case 'context_build': {\n const result = await this.client.buildContextV2(\n args.query as string,\n {\n agentId: args.agent_id as string | null | undefined,\n maxMemories: args.max_memories as number | undefined,\n maxTokens: args.max_tokens as number | undefined,\n aiEnhanced: args.ai_enhanced as boolean | undefined,\n rankingVersion: args.ranking_version as string | undefined,\n searchMode: args.search_mode as 'semantic' | 'hybrid' | 'keyword' | undefined,\n llmApiUrl: args.llm_api_url as string | undefined,\n llmModel: args.llm_model as string | undefined,\n excludeMemoryIds: args.exclude_memory_ids as string[] | undefined,\n }\n );\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n };\n }\n\n // ── Tool Name Aliases (backward compatibility) ──\n\n case 'memory_forget': {\n // Alias for memory_delete\n const id = args.memoryId as string | undefined;\n const query = args.query as string | undefined;\n \n if (id) {\n await this.client.deleteMemory(id);\n return {\n content: [{ type: 'text', text: `Memory ${id.slice(0, 8)}... deleted.` }],\n };\n } else if (query) {\n // Search and auto-delete if high confidence match\n const results = await this.client.searchMemories(query, 1, 0.9);\n if (results.length === 1) {\n await this.client.deleteMemory(results[0].memory.id);\n return {\n content: [{ type: 'text', text: `Memory ${results[0].memory.id.slice(0, 8)}... deleted (matched query).` }],\n };\n }\n return {\n content: [{ type: 'text', text: `Found ${results.length} matches. Provide memoryId to delete.` }],\n };\n }\n throw new Error('memoryId or query is required');\n }\n\n case 'memory_recall': {\n // Alias for memory_search with default agent_id from config\n const results = await this.client.searchMemories(\n args.query as string,\n (args.limit as number) ?? 5,\n (args.threshold as number) ?? 0.3,\n undefined, // use default agent\n false,\n false,\n false,\n args.max_tokens as number | undefined,\n args.project as string | undefined,\n );\n return {\n content: [{ type: 'text', text: JSON.stringify({ memories: results, total: results.length }, null, 2) }],\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 * 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 * Connect the MCP server to a custom transport (for testing)\n */\n async connectTransport(transport: Transport): Promise<void> {\n await this.server.connect(transport);\n }\n\n /**\n * Close the MCP server connection\n */\n async close(): Promise<void> {\n await this.server.close();\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 * CLI commands:\n * npx memoryrelay-mcp Start MCP server (stdio transport)\n * npx memoryrelay-mcp setup Interactive setup wizard\n * npx memoryrelay-mcp test Test API connectivity\n */\n\nimport { loadConfig, getAgentId } from './config.js';\nimport { initLogger, getLogger } from './logger.js';\nimport { MemoryRelayMCPServer } from './server.js';\n\nasync function startServer(): Promise<void> {\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\nasync function main(): Promise<void> {\n const command = process.argv[2];\n\n try {\n switch (command) {\n case 'setup': {\n const { runSetup } = await import('./cli/setup.js');\n await runSetup();\n break;\n }\n case 'test': {\n const { runTest } = await import('./cli/test.js');\n await runTest();\n break;\n }\n case '--help':\n case '-h': {\n console.error(`\n memoryrelay-mcp - Persistent memory for AI agents\n\n Usage:\n npx memoryrelay-mcp Start MCP server (stdio transport)\n npx memoryrelay-mcp setup Interactive setup wizard\n npx memoryrelay-mcp test Test API connectivity\n npx memoryrelay-mcp --help Show this help message\n\n Environment variables:\n MEMORYRELAY_API_KEY API key (required, starts with \"mem_\")\n MEMORYRELAY_API_URL API URL (default: https://api.memoryrelay.net)\n MEMORYRELAY_AGENT_ID Agent ID (optional, auto-detected)\n MEMORYRELAY_TIMEOUT Request timeout in ms (default: 30000)\n MEMORYRELAY_LOG_LEVEL Log level: debug|info|warn|error (default: info)\n\n Documentation: https://github.com/memoryrelay/mcp-server\n`);\n break;\n }\n default:\n await startServer();\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('\\nFailed to start MemoryRelay MCP server\\n');\n console.error(error.message);\n console.error('\\nFor help, run: npx memoryrelay-mcp --help\\n');\n } else {\n logger.error('Fatal error:', { error });\n console.error('\\nAn unexpected error occurred\\n');\n }\n\n process.exit(1);\n }\n}\n\nmain();\n"],"mappings":"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","names":[]}
|
package/docs/OPENCLAW_GUIDE.md
CHANGED
|
@@ -79,40 +79,91 @@ For most OpenClaw setups, setting `OPENCLAW_AGENT_NAME` in the config is suffici
|
|
|
79
79
|
|
|
80
80
|
## Available Tools
|
|
81
81
|
|
|
82
|
-
The MCP server exposes
|
|
82
|
+
The MCP server exposes 44 tools across 8 groups:
|
|
83
83
|
|
|
84
|
-
### Memory Tools
|
|
84
|
+
### Memory Tools (core)
|
|
85
85
|
|
|
86
86
|
| Tool | Description |
|
|
87
87
|
|---|---|
|
|
88
|
-
| `memory_store` | Store a new memory with optional metadata and
|
|
88
|
+
| `memory_store` | Store a new memory with optional metadata, deduplication, and entity extraction. |
|
|
89
89
|
| `memory_search` | Semantic search across memories using natural language queries. |
|
|
90
90
|
| `memory_list` | List recent memories chronologically with pagination. |
|
|
91
91
|
| `memory_get` | Retrieve a specific memory by its UUID. |
|
|
92
92
|
| `memory_update` | Update the content or metadata of an existing memory. |
|
|
93
93
|
| `memory_delete` | Permanently delete a memory by its UUID. |
|
|
94
|
+
| `memory_forget` | Alias for memory_delete (natural language convenience). |
|
|
95
|
+
| `memory_recall` | Alias for memory_search (natural language convenience). |
|
|
96
|
+
| `memory_batch_store` | Store multiple memories in a single request. |
|
|
97
|
+
| `memory_context` | Build a context string from relevant memories. |
|
|
98
|
+
| `entity_create` | Create a named entity (person, place, organization, project, concept). |
|
|
99
|
+
| `entity_link` | Link an entity to a memory with a relationship label. |
|
|
100
|
+
| `entity_list` | List entities in the knowledge graph with pagination. |
|
|
101
|
+
| `entity_graph` | Get an entity's neighborhood in the knowledge graph. |
|
|
102
|
+
| `agent_list` | List all agents with their memory counts. |
|
|
103
|
+
| `agent_create` | Create a new named agent (memory namespace). |
|
|
104
|
+
| `agent_get` | Get details of a specific agent by ID. |
|
|
105
|
+
| `memory_health` | Check API connectivity and server health status. |
|
|
94
106
|
|
|
95
|
-
###
|
|
107
|
+
### V2 Async Tools (v2)
|
|
96
108
|
|
|
97
109
|
| Tool | Description |
|
|
98
110
|
|---|---|
|
|
99
|
-
| `
|
|
100
|
-
| `
|
|
101
|
-
| `
|
|
111
|
+
| `memory_store_async` | Store a memory asynchronously (returns immediately with job ID). |
|
|
112
|
+
| `memory_status` | Check processing status of an async memory. |
|
|
113
|
+
| `context_build` | Build a ranked context bundle with optional AI summarization. |
|
|
102
114
|
|
|
103
|
-
###
|
|
115
|
+
### Session Tools (sessions)
|
|
104
116
|
|
|
105
117
|
| Tool | Description |
|
|
106
118
|
|---|---|
|
|
107
|
-
| `
|
|
108
|
-
| `
|
|
109
|
-
| `
|
|
119
|
+
| `session_start` | Start a new development session. |
|
|
120
|
+
| `session_end` | End an active session with optional summary. |
|
|
121
|
+
| `session_recall` | Get a session by ID with its memories. |
|
|
122
|
+
| `session_list` | List sessions with optional filters. |
|
|
110
123
|
|
|
111
|
-
###
|
|
124
|
+
### Decision Tools (decisions)
|
|
112
125
|
|
|
113
126
|
| Tool | Description |
|
|
114
127
|
|---|---|
|
|
115
|
-
| `
|
|
128
|
+
| `decision_record` | Record an architectural decision with rationale. |
|
|
129
|
+
| `decision_list` | List decisions with optional filters. |
|
|
130
|
+
| `decision_supersede` | Supersede a decision with a new one. |
|
|
131
|
+
| `decision_check` | Check for existing decisions about a topic. |
|
|
132
|
+
|
|
133
|
+
### Pattern Tools (patterns)
|
|
134
|
+
|
|
135
|
+
| Tool | Description |
|
|
136
|
+
|---|---|
|
|
137
|
+
| `pattern_create` | Create a reusable pattern. |
|
|
138
|
+
| `pattern_search` | Search patterns using semantic search. |
|
|
139
|
+
| `pattern_adopt` | Adopt a pattern for a project. |
|
|
140
|
+
| `pattern_suggest` | Suggest patterns for a project. |
|
|
141
|
+
|
|
142
|
+
### Project Tools (projects)
|
|
143
|
+
|
|
144
|
+
| Tool | Description |
|
|
145
|
+
|---|---|
|
|
146
|
+
| `project_register` | Register a new project. |
|
|
147
|
+
| `project_list` | List projects with pagination. |
|
|
148
|
+
| `project_info` | Get project details by slug. |
|
|
149
|
+
|
|
150
|
+
### Relationship Tools (relationships)
|
|
151
|
+
|
|
152
|
+
| Tool | Description |
|
|
153
|
+
|---|---|
|
|
154
|
+
| `project_add_relationship` | Add a relationship between two projects. |
|
|
155
|
+
| `project_dependencies` | Get what a project depends on. |
|
|
156
|
+
| `project_dependents` | Get what depends on a project. |
|
|
157
|
+
| `project_related` | Get all related projects. |
|
|
158
|
+
| `project_impact` | Run impact analysis for a project change. |
|
|
159
|
+
| `project_shared_patterns` | Find patterns shared between two projects. |
|
|
160
|
+
|
|
161
|
+
### Context Tools (context)
|
|
162
|
+
|
|
163
|
+
| Tool | Description |
|
|
164
|
+
|---|---|
|
|
165
|
+
| `project_context` | Get full project context (hot memories, decisions, patterns). |
|
|
166
|
+
| `memory_promote` | Promote/demote a memory by updating importance and tier. |
|
|
116
167
|
|
|
117
168
|
---
|
|
118
169
|
|
package/docs/SECURITY.md
CHANGED
|
@@ -198,7 +198,7 @@ All tool inputs are validated using Zod schemas:
|
|
|
198
198
|
|
|
199
199
|
#### Memory Content
|
|
200
200
|
- Type: String (required)
|
|
201
|
-
-
|
|
201
|
+
- 50,000 character limit (validated client-side before API call)
|
|
202
202
|
- HTML-encoded when used in entity names
|
|
203
203
|
|
|
204
204
|
#### Entity Names
|
|
@@ -282,8 +282,8 @@ Errors are sanitized before being returned to clients:
|
|
|
282
282
|
The MCP server respects API rate limits:
|
|
283
283
|
|
|
284
284
|
- **Timeout**: Default 30 seconds per request (configurable)
|
|
285
|
-
- **Retries**:
|
|
286
|
-
- **Backoff**:
|
|
285
|
+
- **Retries**: Automatic retries with exponential backoff (up to 3 retries for transient errors)
|
|
286
|
+
- **Backoff**: Exponential backoff with jitter on 5xx and timeout errors; 429 rate-limit responses honored via Retry-After header
|
|
287
287
|
|
|
288
288
|
### API Rate Limits
|
|
289
289
|
|
|
@@ -439,11 +439,11 @@ To enable comprehensive audit logging:
|
|
|
439
439
|
## 📚 Further Reading
|
|
440
440
|
|
|
441
441
|
- [MCP Security Best Practices](https://modelcontextprotocol.io/security)
|
|
442
|
-
- [MemoryRelay API Documentation](https://
|
|
442
|
+
- [MemoryRelay API Documentation](https://docs.memoryrelay.ai/)
|
|
443
443
|
- [OWASP Secure Coding Practices](https://owasp.org/www-project-secure-coding-practices-quick-reference-guide/)
|
|
444
444
|
- [Node.js Security Best Practices](https://nodejs.org/en/docs/guides/security/)
|
|
445
445
|
|
|
446
446
|
---
|
|
447
447
|
|
|
448
|
-
**Last Updated:** 2026-
|
|
449
|
-
**Version:** 0.
|
|
448
|
+
**Last Updated:** 2026-03-24
|
|
449
|
+
**Version:** 0.4.0
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/config.ts","../src/logger.ts","../src/client.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 * Tool groups that can be enabled/disabled via MEMORYRELAY_TOOLS env var.\n * Default (when unset or 'all'): all groups enabled.\n */\nexport const TOOL_GROUPS: Record<string, string[]> = {\n core: [\n 'memory_store', 'memory_search', 'memory_list', 'memory_get',\n 'memory_update', 'memory_delete', 'entity_create', 'entity_link',\n 'entity_list', 'entity_graph', 'memory_batch_store', 'memory_context',\n 'agent_list', 'agent_create', 'agent_get', 'memory_health',\n ],\n sessions: ['session_start', 'session_end', 'session_recall', 'session_list'],\n decisions: ['decision_record', 'decision_list', 'decision_supersede', 'decision_check'],\n patterns: ['pattern_create', 'pattern_search', 'pattern_adopt', 'pattern_suggest'],\n projects: ['project_register', 'project_list', 'project_info'],\n relationships: [\n 'project_add_relationship', 'project_dependencies', 'project_dependents',\n 'project_related', 'project_impact', 'project_shared_patterns',\n ],\n context: ['project_context', 'memory_promote'],\n};\n\n/**\n * Parse MEMORYRELAY_TOOLS env var and return set of enabled tool names.\n * Returns null if all tools should be enabled (default behavior).\n */\nexport function getEnabledTools(): Set<string> | null {\n const raw = process.env.MEMORYRELAY_TOOLS;\n if (!raw || raw.trim().toLowerCase() === 'all') {\n return null; // all tools enabled\n }\n\n const groups = raw.split(',').map(g => g.trim().toLowerCase());\n const enabled = new Set<string>();\n for (const group of groups) {\n const tools = TOOL_GROUPS[group];\n if (tools) {\n for (const tool of tools) {\n enabled.add(tool);\n }\n }\n }\n return enabled;\n}\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 { cause: error }\n );\n }\n throw error;\n }\n}\n\n/**\n * Get or generate agent ID.\n *\n * Priority order:\n * 1. MEMORYRELAY_AGENT_ID (explicit configuration)\n * 2. OPENCLAW_AGENT_NAME (OpenClaw auto-detection)\n * 3. Auto-generated from username + hostname\n *\n * When no explicit ID is provided we build a human-readable identifier\n * from the current user and hostname so that memories are easier to\n * attribute in the dashboard (e.g. \"sparc-DESKTOP\" instead of \"agent-a1b2c3d4\").\n */\nexport function getAgentId(config: Config): string {\n if (config.agentId) {\n return config.agentId;\n }\n\n // OpenClaw auto-detection: use agent name from OpenClaw environment\n const openclawAgent = process.env.OPENCLAW_AGENT_NAME;\n if (openclawAgent) {\n return openclawAgent.slice(0, 32);\n }\n\n const hostname = process.env.HOSTNAME || process.env.COMPUTERNAME || 'unknown';\n const user = process.env.USER || process.env.USERNAME || '';\n return user\n ? `${user}-${hostname}`.slice(0, 32)\n : `mcp-${hostname}`.slice(0, 32);\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 * MemoryRelay API client with retry logic and error handling\n */\n\nimport type {\n Memory,\n Entity,\n Agent,\n Session,\n SessionDetail,\n Decision,\n DecisionCheckResult,\n Project,\n Pattern,\n PatternSearchResult,\n SearchResult,\n ListResponse,\n ClientConfig,\n EntityType,\n BatchMemoryItem,\n BatchStoreResponse,\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 { message?: string };\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`, { cause: error });\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(\n content: string,\n metadata?: Record<string, string>,\n deduplicate?: boolean,\n dedupThreshold?: number,\n project?: string,\n importance?: number,\n tier?: string\n ): Promise<Memory> {\n this.validateContentSize(content);\n\n const body: Record<string, unknown> = {\n content,\n metadata,\n agent_id: this.config.agentId,\n };\n if (deduplicate) {\n body.deduplicate = true;\n }\n if (dedupThreshold !== undefined) {\n body.dedup_threshold = dedupThreshold;\n }\n if (project) {\n body.project = project;\n }\n if (importance !== undefined) {\n body.importance = importance;\n }\n if (tier) {\n body.tier = tier;\n }\n\n return this.request<Memory>('POST', '/v1/memories', body);\n }\n\n /**\n * Search memories using semantic search\n * @param agentId - Optional agent ID override. If omitted, uses config agentId. Pass null for cross-agent search.\n * @param includeConfidential - Include confidential memories in results\n * @param includeArchived - Include archived memories in results\n * @param project - Optional project slug to filter by\n */\n async searchMemories(\n query: string,\n limit: number = 10,\n threshold: number = 0.5,\n agentId?: string | null,\n includeConfidential: boolean = false,\n includeArchived: boolean = false,\n compress: boolean = false,\n maxContextTokens?: number,\n project?: string,\n tier?: string,\n minImportance?: number\n ): Promise<SearchResult[]> {\n this.validateContentSize(query);\n\n // If agentId is explicitly null, omit it (cross-agent search).\n // If agentId is undefined, use the default from config.\n const effectiveAgentId = agentId === null ? undefined : (agentId ?? this.config.agentId);\n\n const body: Record<string, unknown> = { query, limit, threshold };\n if (effectiveAgentId) {\n body.agent_id = effectiveAgentId;\n }\n if (includeConfidential) {\n body.include_confidential = true;\n }\n if (includeArchived) {\n body.include_archived = true;\n }\n if (compress) {\n body.compress = true;\n }\n if (maxContextTokens !== undefined) {\n body.max_context_tokens = maxContextTokens;\n }\n if (project) {\n body.project = project;\n }\n if (tier) {\n body.tier = tier;\n }\n if (minImportance !== undefined) {\n body.min_importance = minImportance;\n }\n\n const response = await this.request<{ data: SearchResult[] }>(\n 'POST',\n '/v1/memories/search',\n body\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 * Get entity neighborhood (ego-centric subgraph).\n * Returns the entity's 1-hop or 2-hop neighbors and relationships.\n */\n async getEntityNeighborhood(\n entityId: string,\n depth: number = 1,\n maxNeighbors: number = 50\n ): Promise<Record<string, unknown>> {\n return this.request<Record<string, unknown>>(\n 'GET',\n `/v1/entities/${entityId}/neighborhood?depth=${depth}&max_neighbors=${maxNeighbors}`\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 * List agents with pagination\n */\n async listAgents(limit: number = 20, offset: number = 0): Promise<ListResponse<Agent>> {\n return this.request<ListResponse<Agent>>(\n 'GET',\n `/v1/agents?limit=${limit}&offset=${offset}`\n );\n }\n\n /**\n * Create a new agent\n */\n async createAgent(\n name: string,\n description?: string,\n metadata?: Record<string, string>\n ): Promise<Agent> {\n const body: Record<string, unknown> = { name };\n if (description) body.description = description;\n if (metadata) body.metadata = metadata;\n\n return this.request<Agent>('POST', '/v1/agents', body);\n }\n\n /**\n * Get an agent by ID\n */\n async getAgent(id: string): Promise<Agent> {\n return this.request<Agent>('GET', `/v1/agents/${id}`);\n }\n\n /**\n * Batch store multiple memories in a single API call.\n * Uses the /v1/memories/batch endpoint.\n */\n async batchStoreMemories(\n items: BatchMemoryItem[]\n ): Promise<BatchStoreResponse> {\n if (items.length === 0) {\n return { success: true, total: 0, succeeded: 0, failed: 0, skipped: 0, results: [] };\n }\n if (items.length > 100) {\n throw new Error('Batch size exceeds maximum of 100 memories');\n }\n\n // Attach default agent_id to items that don't have one\n const memories = items.map(item => ({\n content: item.content,\n metadata: item.metadata || {},\n agent_id: item.agent_id || this.config.agentId,\n }));\n\n return this.request<BatchStoreResponse>('POST', '/v1/memories/batch', { memories });\n }\n\n /**\n * Build a context string from search results.\n * Searches for relevant memories, formats them, and returns\n * a single string ready for prompt injection.\n */\n async buildContext(\n query: string,\n limit: number = 10,\n threshold: number = 0.5,\n maxTokens?: number\n ): Promise<{ context: string; memories_used: number; total_chars: number }> {\n const results = await this.searchMemories(\n query,\n limit,\n threshold,\n undefined, // use default agent\n false, // no confidential\n false, // no archived\n !!maxTokens, // compress if token budget provided\n maxTokens\n );\n\n if (results.length === 0) {\n return { context: '', memories_used: 0, total_chars: 0 };\n }\n\n const lines: string[] = [];\n for (const result of results) {\n const score = (result.score * 100).toFixed(0);\n lines.push(`[${score}%] ${result.memory.content}`);\n }\n\n const context = lines.join('\\n\\n');\n\n // Rough token budget enforcement (1 token ≈ 4 chars)\n let finalContext = context;\n if (maxTokens) {\n const charBudget = maxTokens * 4;\n if (finalContext.length > charBudget) {\n finalContext = finalContext.slice(0, charBudget) + '\\n\\n[...truncated]';\n }\n }\n\n return {\n context: finalContext,\n memories_used: results.length,\n total_chars: finalContext.length,\n };\n }\n\n /**\n * Start a new session\n */\n async startSession(\n title?: string,\n project?: string,\n metadata?: Record<string, string>\n ): Promise<Session> {\n const body: Record<string, unknown> = {};\n if (this.config.agentId) body.agent_id = this.config.agentId;\n if (title) body.title = title;\n if (project) body.project = project;\n if (metadata) body.metadata = metadata;\n return this.request<Session>('POST', '/v1/sessions', body);\n }\n\n /**\n * End an active session\n */\n async endSession(\n sessionId: string,\n summary?: string,\n ): Promise<Session> {\n const body: Record<string, unknown> = {};\n if (summary) body.summary = summary;\n return this.request<Session>('PUT', `/v1/sessions/${sessionId}/end`, body);\n }\n\n /**\n * Get a session by ID with its memories\n */\n async getSession(sessionId: string): Promise<SessionDetail> {\n return this.request<SessionDetail>(\n 'GET',\n `/v1/sessions/${sessionId}?include_memories=true`\n );\n }\n\n /**\n * List sessions with optional filters\n */\n async listSessions(\n limit: number = 20,\n agentId?: string,\n project?: string,\n status?: string,\n ): Promise<ListResponse<Session>> {\n const params = new URLSearchParams();\n params.set('limit', String(limit));\n const effectiveAgentId = agentId ?? this.config.agentId;\n if (effectiveAgentId) params.set('agent_id', effectiveAgentId);\n if (project) params.set('project', project);\n if (status) params.set('status', status);\n return this.request<ListResponse<Session>>(\n 'GET',\n `/v1/sessions?${params.toString()}`\n );\n }\n\n /**\n * Record a new decision\n */\n async recordDecision(\n title: string,\n rationale: string,\n alternatives?: string,\n project?: string,\n tags?: string[],\n status?: string,\n metadata?: Record<string, string>\n ): Promise<Decision> {\n const body: Record<string, unknown> = { title, rationale };\n if (this.config.agentId) body.agent_id = this.config.agentId;\n if (alternatives) body.alternatives = alternatives;\n if (project) body.project_slug = project;\n if (tags) body.tags = tags;\n if (status) body.status = status;\n if (metadata) body.metadata = metadata;\n return this.request<Decision>('POST', '/v1/decisions', body);\n }\n\n /**\n * List decisions with optional filters\n */\n async listDecisions(\n limit?: number,\n project?: string,\n status?: string,\n tags?: string,\n ): Promise<ListResponse<Decision>> {\n const params = new URLSearchParams();\n if (limit) params.set('limit', String(limit));\n if (project) params.set('project', project);\n if (status) params.set('status', status);\n if (tags) params.set('tags', tags);\n return this.request<ListResponse<Decision>>(\n 'GET',\n `/v1/decisions?${params.toString()}`\n );\n }\n\n /**\n * Supersede a decision with a new one\n */\n async supersedeDecision(\n decisionId: string,\n title: string,\n rationale: string,\n alternatives?: string,\n tags?: string[],\n ): Promise<Decision> {\n const body: Record<string, unknown> = { title, rationale };\n if (alternatives) body.alternatives = alternatives;\n if (tags) body.tags = tags;\n return this.request<Decision>(\n 'POST',\n `/v1/decisions/${decisionId}/supersede`,\n body\n );\n }\n\n /**\n * Check for existing decisions about a topic (semantic search)\n */\n async checkDecisions(\n query: string,\n project?: string,\n limit?: number,\n threshold?: number,\n includeSuperseded?: boolean,\n ): Promise<{ data: DecisionCheckResult[]; query: string; total: number }> {\n const params = new URLSearchParams();\n params.set('query', query);\n if (limit) params.set('limit', String(limit));\n if (threshold !== undefined) params.set('threshold', String(threshold));\n if (project) params.set('project', project);\n if (includeSuperseded) params.set('include_superseded', 'true');\n return this.request<{ data: DecisionCheckResult[]; query: string; total: number }>(\n 'GET',\n `/v1/decisions/check?${params.toString()}`\n );\n }\n\n /**\n * Register a new project\n */\n async createProject(\n slug: string,\n name: string,\n description?: string,\n stack?: Record<string, unknown>,\n repo_url?: string,\n metadata?: Record<string, unknown>\n ): Promise<Project> {\n const body: Record<string, unknown> = { slug, name };\n if (description) body.description = description;\n if (stack) body.stack = stack;\n if (repo_url) body.repo_url = repo_url;\n if (metadata) body.metadata = metadata;\n return this.request<Project>('POST', '/v1/projects', body);\n }\n\n /**\n * List projects with optional pagination\n */\n async listProjects(\n limit: number = 20,\n cursor?: string\n ): Promise<ListResponse<Project>> {\n const params = new URLSearchParams();\n params.set('limit', String(limit));\n if (cursor) params.set('cursor', cursor);\n return this.request<ListResponse<Project>>(\n 'GET',\n `/v1/projects?${params.toString()}`\n );\n }\n\n /**\n * Get a project by slug\n */\n async getProject(slug: string): Promise<Project> {\n return this.request<Project>('GET', `/v1/projects/${slug}`);\n }\n\n /**\n * Create a reusable pattern\n */\n async createPattern(\n title: string,\n description: string,\n category?: string,\n example_code?: string,\n scope?: string,\n tags?: string[],\n source_project?: string,\n metadata?: Record<string, unknown>\n ): Promise<Pattern> {\n const body: Record<string, unknown> = { title, description };\n if (category) body.category = category;\n if (example_code) body.example_code = example_code;\n if (scope) body.scope = scope;\n if (tags) body.tags = tags;\n if (source_project) body.source_project = source_project;\n if (metadata) body.metadata = metadata;\n return this.request<Pattern>('POST', '/v1/patterns', body);\n }\n\n /**\n * Search patterns using semantic search\n */\n async searchPatterns(\n query: string,\n category?: string,\n project?: string,\n limit?: number,\n threshold?: number,\n ): Promise<{ data: PatternSearchResult[]; query: string; total: number }> {\n const params = new URLSearchParams();\n params.set('query', query);\n if (category) params.set('category', category);\n if (project) params.set('project', project);\n if (limit) params.set('limit', String(limit));\n if (threshold !== undefined) params.set('threshold', String(threshold));\n return this.request<{ data: PatternSearchResult[]; query: string; total: number }>(\n 'GET',\n `/v1/patterns/search?${params.toString()}`\n );\n }\n\n /**\n * Adopt a pattern for a project\n */\n async adoptPattern(\n patternId: string,\n project: string,\n ): Promise<Pattern> {\n return this.request<Pattern>(\n 'POST',\n `/v1/patterns/${patternId}/adopt`,\n { project }\n );\n }\n\n /**\n * Suggest patterns for a project\n */\n async suggestPatterns(\n project: string,\n limit?: number,\n ): Promise<{ data: Pattern[]; project: string; total: number }> {\n const params = new URLSearchParams();\n params.set('project', project);\n if (limit) params.set('limit', String(limit));\n return this.request<{ data: Pattern[]; project: string; total: number }>(\n 'GET',\n `/v1/patterns/suggest?${params.toString()}`\n );\n }\n\n // ── Project Relationships (Issue #186) ──\n\n /**\n * Add a relationship between two projects\n */\n async addProjectRelationship(\n sourceSlug: string,\n targetProject: string,\n relationshipType: string,\n metadata?: Record<string, unknown>,\n ): Promise<Record<string, unknown>> {\n const body: Record<string, unknown> = {\n target_project: targetProject,\n relationship_type: relationshipType,\n };\n if (metadata) body.metadata = metadata;\n return this.request<Record<string, unknown>>(\n 'POST',\n `/v1/projects/${sourceSlug}/relationships`,\n body,\n );\n }\n\n /**\n * Get what this project depends on\n */\n async getProjectDependencies(slug: string): Promise<Record<string, unknown>> {\n return this.request<Record<string, unknown>>(\n 'GET',\n `/v1/projects/${slug}/dependencies`,\n );\n }\n\n /**\n * Get what depends on this project\n */\n async getProjectDependents(slug: string): Promise<Record<string, unknown>> {\n return this.request<Record<string, unknown>>(\n 'GET',\n `/v1/projects/${slug}/dependents`,\n );\n }\n\n /**\n * Get all related projects\n */\n async getProjectRelated(slug: string): Promise<Record<string, unknown>> {\n return this.request<Record<string, unknown>>(\n 'GET',\n `/v1/projects/${slug}/related`,\n );\n }\n\n /**\n * Run impact analysis for a project change\n */\n async projectImpactAnalysis(\n project: string,\n changeDescription: string,\n ): Promise<Record<string, unknown>> {\n return this.request<Record<string, unknown>>(\n 'POST',\n '/v1/projects/impact-analysis',\n { project, change_description: changeDescription },\n );\n }\n\n /**\n * Find patterns shared between two projects\n */\n async getSharedPatterns(\n slugA: string,\n slugB: string,\n ): Promise<Record<string, unknown>> {\n return this.request<Record<string, unknown>>(\n 'GET',\n `/v1/projects/shared-patterns?a=${encodeURIComponent(slugA)}&b=${encodeURIComponent(slugB)}`,\n );\n }\n\n /**\n * Get full project context (hot memories, decisions, patterns, formatted text)\n */\n async getProjectContext(slug: string): Promise<Record<string, unknown>> {\n return this.request<Record<string, unknown>>(\n 'GET',\n `/v1/projects/${encodeURIComponent(slug)}/context`,\n );\n }\n\n /**\n * Promote/demote a memory by updating its importance and tier\n */\n async promoteMemory(\n memoryId: string,\n importance: number,\n tier?: string\n ): Promise<Memory> {\n const body: Record<string, unknown> = { importance };\n if (tier) {\n body.tier = tier;\n }\n return this.request<Memory>(\n 'PUT',\n `/v1/memories/${encodeURIComponent(memoryId)}/importance`,\n body,\n );\n }\n\n // ── V2 Async API (60-600x faster) ──\n\n /**\n * Store a memory asynchronously (V2 API).\n * Returns immediately with 202 Accepted and a job ID.\n * Use getMemoryStatus() to poll for completion.\n */\n async storeMemoryAsync(\n content: string,\n metadata?: Record<string, string>,\n project?: string,\n importance?: number,\n tier?: string,\n webhookUrl?: string\n ): Promise<{ id: string; status: string; job_id: string; estimated_completion_seconds: number }> {\n this.validateContentSize(content);\n\n const body: Record<string, unknown> = {\n content,\n agent_id: this.config.agentId,\n };\n if (metadata) body.metadata = metadata;\n if (project) body.project = project;\n if (importance !== undefined) body.importance = importance;\n if (tier) body.tier = tier;\n if (webhookUrl) body.webhook_url = webhookUrl;\n\n return this.request<{ id: string; status: string; job_id: string; estimated_completion_seconds: number }>(\n 'POST',\n '/v2/memories',\n body\n );\n }\n\n /**\n * Get memory processing status (V2 API).\n * Use after storeMemoryAsync() to check when embedding is ready.\n */\n async getMemoryStatus(memoryId: string): Promise<{\n id: string;\n status: 'pending' | 'processing' | 'ready' | 'failed';\n created_at: string;\n updated_at: string;\n error?: string;\n }> {\n return this.request<{\n id: string;\n status: 'pending' | 'processing' | 'ready' | 'failed';\n created_at: string;\n updated_at: string;\n error?: string;\n }>('GET', `/v2/memories/${memoryId}/status`);\n }\n\n /**\n * Build a ranked context bundle from memories (V2 API).\n * Supports optional AI summarization with custom LLM URL.\n */\n async buildContextV2(\n query: string,\n options?: {\n agentId?: string | null;\n maxMemories?: number;\n maxTokens?: number;\n aiEnhanced?: boolean;\n rankingVersion?: string;\n searchMode?: 'semantic' | 'hybrid' | 'keyword';\n llmApiUrl?: string;\n llmModel?: string;\n excludeMemoryIds?: string[];\n }\n ): Promise<{\n context: Array<{\n memory_id: string;\n content: string;\n score: number;\n memory_type?: string;\n }>;\n summary?: string;\n token_count: number;\n ranking_version: string;\n ai_enhanced: boolean;\n latency_ms: number;\n }> {\n const body: Record<string, unknown> = { query };\n if (options?.agentId !== undefined) body.agent_id = options.agentId;\n if (options?.maxMemories) body.max_memories = options.maxMemories;\n if (options?.maxTokens) body.max_tokens = options.maxTokens;\n if (options?.aiEnhanced) body.ai_enhanced = true;\n if (options?.rankingVersion) body.ranking_version = options.rankingVersion;\n if (options?.searchMode) body.search_mode = options.searchMode;\n if (options?.llmApiUrl) body.llm_api_url = options.llmApiUrl;\n if (options?.llmModel) body.llm_model = options.llmModel;\n if (options?.excludeMemoryIds) body.exclude_memory_ids = options.excludeMemoryIds;\n\n return this.request<{\n context: Array<{\n memory_id: string;\n content: string;\n score: number;\n memory_type?: string;\n }>;\n summary?: string;\n token_count: number;\n ranking_version: string;\n ai_enhanced: boolean;\n latency_ms: number;\n }>('POST', '/v2/context/build', body);\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"],"mappings":"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","names":[]}
|