getmnemo-mcp 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
- # @ledgermem/mcp-server
1
+ # getmnemo-mcp
2
2
 
3
- Model Context Protocol server for [LedgerMem Memory](https://proofly.dev) — exposes long-term memory tools to any MCP client (Claude Desktop, Cursor, Windsurf, VS Code, Zed).
3
+ Model Context Protocol server for [Mnemo Memory](https://mnemohq.com) — exposes long-term memory tools to any MCP client (Claude Desktop, Cursor, Windsurf, VS Code, Zed).
4
4
 
5
5
  ## Tools
6
6
 
@@ -19,7 +19,7 @@ All calls are scoped to a workspace and (optionally) an actor.
19
19
  ### Claude Desktop / Cursor / Windsurf / VS Code / Zed
20
20
 
21
21
  ```bash
22
- npx -y @ledgermem/mcp-server
22
+ npx -y getmnemo-mcp
23
23
  ```
24
24
 
25
25
  Or wire it into the client config directly. Example for Claude Desktop (`~/Library/Application Support/Claude/claude_desktop_config.json`):
@@ -27,33 +27,25 @@ Or wire it into the client config directly. Example for Claude Desktop (`~/Libra
27
27
  ```json
28
28
  {
29
29
  "mcpServers": {
30
- "ledgermem": {
30
+ "getmnemo": {
31
31
  "command": "npx",
32
- "args": ["-y", "@ledgermem/mcp-server"],
32
+ "args": ["-y", "getmnemo-mcp"],
33
33
  "env": {
34
- "LEDGERMEM_API_KEY": "lk_live_...",
35
- "LEDGERMEM_WORKSPACE_ID": "ws_..."
34
+ "GETMNEMO_API_KEY": "prfly_live_...",
35
+ "GETMNEMO_WORKSPACE_ID": "ws_..."
36
36
  }
37
37
  }
38
38
  }
39
39
  }
40
40
  ```
41
41
 
42
- Get an API key at <https://app.proofly.dev/settings/api-keys>.
43
-
44
- ### Hosted (HTTP/SSE) at `mcp.proofly.dev`
45
-
46
- ```bash
47
- npx -y install-mcp@latest https://mcp.proofly.dev/mcp --client claude
48
- ```
49
-
50
- (OAuth flow lands in v0.2 — until then the hosted endpoint accepts `x-ledgermem-api-key` + `x-ledgermem-workspace-id` headers from trusted clients.)
42
+ Get an API key at <https://app.mnemohq.com/settings/api-keys>.
51
43
 
52
44
  ## Develop
53
45
 
54
46
  ```bash
55
47
  npm install
56
- cp .env.example .env # fill in LEDGERMEM_API_KEY + LEDGERMEM_WORKSPACE_ID
48
+ cp .env.example .env # fill in GETMNEMO_API_KEY + GETMNEMO_WORKSPACE_ID
57
49
  npm run dev # stdio
58
50
  npm run dev:http # HTTP/SSE on :8787
59
51
  npm run build # bundle to dist/
@@ -65,7 +57,7 @@ npm run build # bundle to dist/
65
57
  - **HTTP/SSE** (`src/http.ts`): single long-running process for hosted use, header-or-OAuth auth.
66
58
  - Both transports share `src/server.ts` (tool registration + dispatch) and `src/api-client.ts` (typed REST wrapper).
67
59
 
68
- The server deliberately does NOT depend on `@ledgermem/memory` (the JS SDK) so it can ship independently.
60
+ The server deliberately does NOT depend on `getmnemo` (the JS SDK) so it can ship independently.
69
61
 
70
62
  ## License
71
63
 
@@ -258,4 +258,4 @@ export {
258
258
  MnemoApiClient,
259
259
  createServer
260
260
  };
261
- //# sourceMappingURL=chunk-KXH67NNU.js.map
261
+ //# sourceMappingURL=chunk-FJQEJR25.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/api-client.ts","../src/server.ts"],"sourcesContent":["/**\n * Thin REST client for the Mnemo Memory API.\n *\n * This duplicates the surface area we need for MCP tools — we deliberately\n * do NOT depend on getmnemo here so this server can ship even if\n * the JS SDK lags behind. When the SDK stabilises, swap this for it.\n */\n\nexport type Memory = {\n id: string\n content: string\n metadata?: Record<string, unknown>\n workspaceId: string\n actorId?: string | null\n createdAt: string\n updatedAt: string\n}\n\nexport type SearchHit = {\n memoryId: string\n content: string\n score: number\n metadata?: Record<string, unknown>\n source?: { documentId?: string; chunkId?: string } | null\n}\n\nexport type SearchResponse = {\n hits: SearchHit[]\n query: string\n latencyMs: number\n}\n\nexport type ApiClientConfig = {\n baseUrl: string\n apiKey: string\n workspaceId: string\n actorId?: string\n fetch?: typeof fetch\n /** Per-request timeout in ms (default 30s). */\n timeoutMs?: number\n}\n\nexport class MnemoApiError extends Error {\n constructor(\n message: string,\n readonly status: number,\n readonly body?: unknown,\n ) {\n super(message)\n this.name = 'MnemoApiError'\n }\n}\n\nexport class MnemoApiClient {\n private readonly baseUrl: string\n private readonly headers: Record<string, string>\n private readonly fetchImpl: typeof fetch\n private readonly timeoutMs: number\n\n constructor(cfg: ApiClientConfig) {\n if (!cfg.apiKey) throw new Error('apiKey is required')\n if (!cfg.workspaceId) throw new Error('workspaceId is required')\n this.baseUrl = cfg.baseUrl.replace(/\\/$/, '')\n this.headers = {\n 'authorization': `Bearer ${cfg.apiKey}`,\n 'x-workspace-id': cfg.workspaceId,\n 'content-type': 'application/json',\n 'user-agent': '@mnemo/mcp-server',\n ...(cfg.actorId ? { 'x-actor-id': cfg.actorId } : {}),\n }\n this.fetchImpl = cfg.fetch ?? fetch\n this.timeoutMs = cfg.timeoutMs ?? 30_000\n }\n\n async search(input: {\n query: string\n limit?: number\n actorId?: string\n }): Promise<SearchResponse> {\n return this.request<SearchResponse>('POST', '/v1/search', {\n query: input.query,\n limit: input.limit ?? 8,\n ...(input.actorId !== undefined ? { actorId: input.actorId } : {}),\n })\n }\n\n async addMemory(input: {\n content: string\n metadata?: Record<string, unknown>\n actorId?: string\n }): Promise<Memory> {\n return this.request<Memory>('POST', '/v1/memories', {\n content: input.content,\n ...(input.metadata !== undefined ? { metadata: input.metadata } : {}),\n ...(input.actorId !== undefined ? { actorId: input.actorId } : {}),\n })\n }\n\n async updateMemory(\n id: string,\n input: { content?: string; metadata?: Record<string, unknown> },\n ): Promise<Memory> {\n return this.request<Memory>('PATCH', `/v1/memories/${encodeURIComponent(id)}`, input)\n }\n\n async deleteMemory(id: string): Promise<{ id: string; deleted: true }> {\n return this.request<{ id: string; deleted: true }>(\n 'DELETE',\n `/v1/memories/${encodeURIComponent(id)}`,\n )\n }\n\n async listMemories(input?: {\n limit?: number\n cursor?: string\n actorId?: string\n }): Promise<{ items: Memory[]; nextCursor: string | null }> {\n const params = new URLSearchParams()\n if (input?.limit !== undefined) params.set('limit', String(input.limit))\n if (input?.cursor !== undefined) params.set('cursor', input.cursor)\n if (input?.actorId !== undefined) params.set('actorId', input.actorId)\n const qs = params.toString()\n return this.request('GET', `/v1/memories${qs ? `?${qs}` : ''}`)\n }\n\n private async request<T>(\n method: string,\n path: string,\n body?: unknown,\n ): Promise<T> {\n const ctrl = new AbortController()\n const timer = setTimeout(() => ctrl.abort(), this.timeoutMs)\n try {\n const res = await this.fetchImpl(`${this.baseUrl}${path}`, {\n method,\n headers: { ...this.headers },\n body: body === undefined ? undefined : JSON.stringify(body),\n signal: ctrl.signal,\n })\n const text = await res.text()\n const parsed = text ? safeJson(text) : undefined\n if (!res.ok) {\n const msg =\n (parsed && typeof parsed === 'object' && 'message' in parsed\n ? String((parsed as { message: unknown }).message)\n : null) ?? `HTTP ${res.status} ${res.statusText}`\n throw new MnemoApiError(msg, res.status, parsed)\n }\n if (parsed !== undefined && typeof parsed !== 'object') {\n throw new MnemoApiError(\n `Expected JSON object response, got: ${typeof parsed}`,\n res.status,\n parsed,\n )\n }\n return parsed as T\n } finally {\n clearTimeout(timer)\n }\n }\n}\n\nfunction safeJson(s: string): unknown {\n try {\n return JSON.parse(s)\n } catch {\n return s\n }\n}\n","/**\n * MCP server factory.\n *\n * Exposes 5 tools to MCP clients (Claude Desktop, Cursor, Windsurf, VS Code,\n * Zed): memory_search, memory_add, memory_update, memory_delete, memory_list.\n *\n * Transport-agnostic — wire to stdio (cli.ts) or HTTP/SSE (http.ts).\n */\n\nimport { Server } from '@modelcontextprotocol/sdk/server/index.js'\nimport {\n CallToolRequestSchema,\n ErrorCode,\n ListToolsRequestSchema,\n McpError,\n type Tool,\n} from '@modelcontextprotocol/sdk/types.js'\nimport { z } from 'zod'\n\nimport { MnemoApiClient, type ApiClientConfig, MnemoApiError } from './api-client.js'\n\nconst SearchInput = z.object({\n query: z.string().min(1).max(2000).describe('Natural-language search query.'),\n limit: z.number().int().min(1).max(50).default(8).describe('Max number of memories to return.'),\n actor_id: z\n .string()\n .min(1)\n .max(256)\n .optional()\n .describe('Optional actor scope (defaults to the configured actor).'),\n})\n\n// Cap metadata size so a malicious or buggy client cannot push a 10MB blob\n// through the MCP boundary (the upstream API enforces its own limits, but\n// we'd rather reject early than waste a round-trip).\nconst METADATA_MAX_SERIALIZED_BYTES = 16 * 1024\nconst boundedMetadata = z\n .record(z.unknown())\n .refine(\n (m) => {\n try {\n return Buffer.byteLength(JSON.stringify(m), 'utf8') <= METADATA_MAX_SERIALIZED_BYTES\n } catch {\n return false\n }\n },\n { message: `metadata exceeds ${METADATA_MAX_SERIALIZED_BYTES} bytes when serialized` },\n )\n\nconst AddInput = z.object({\n content: z.string().min(1).max(10_000).describe('The fact or memory to store.'),\n metadata: boundedMetadata\n .optional()\n .describe('Arbitrary JSON metadata (tags, source, etc.). Max 16KB serialized.'),\n actor_id: z.string().min(1).max(256).optional(),\n})\n\nconst UpdateInput = z.object({\n id: z.string().min(1).max(256).describe('Memory ID returned by memory_add or memory_search.'),\n content: z.string().min(1).max(10_000).optional(),\n metadata: boundedMetadata.optional(),\n})\n\nconst DeleteInput = z.object({\n id: z.string().min(1).max(256).describe('Memory ID to delete.'),\n})\n\nconst ListInput = z.object({\n limit: z.number().int().min(1).max(100).default(20),\n cursor: z.string().min(1).max(1024).optional(),\n actor_id: z.string().min(1).max(256).optional(),\n})\n\nconst TOOLS: Tool[] = [\n {\n name: 'memory_search',\n description:\n 'Search the Mnemo memory store for facts relevant to a query. Returns ranked hits with content, score, and source citations. Use this BEFORE answering any question that might require remembered context.',\n inputSchema: {\n type: 'object',\n properties: {\n query: { type: 'string', description: 'Natural-language search query.' },\n limit: { type: 'integer', minimum: 1, maximum: 50, default: 8 },\n actor_id: { type: 'string' },\n },\n required: ['query'],\n },\n },\n {\n name: 'memory_add',\n description:\n 'Store a new atomic fact in long-term memory. Use this whenever the user reveals durable preferences, facts about themselves, or context that should persist across sessions.',\n inputSchema: {\n type: 'object',\n properties: {\n content: { type: 'string' },\n metadata: { type: 'object' },\n actor_id: { type: 'string' },\n },\n required: ['content'],\n },\n },\n {\n name: 'memory_update',\n description:\n \"Update an existing memory's content or metadata. Use when a previously-stored fact is no longer accurate.\",\n inputSchema: {\n type: 'object',\n properties: {\n id: { type: 'string' },\n content: { type: 'string' },\n metadata: { type: 'object' },\n },\n required: ['id'],\n },\n },\n {\n name: 'memory_delete',\n description:\n 'Delete a memory by ID. Use only when the user explicitly asks to forget something or when a fact is permanently invalid.',\n inputSchema: {\n type: 'object',\n properties: { id: { type: 'string' } },\n required: ['id'],\n },\n },\n {\n name: 'memory_list',\n description:\n 'List memories in the workspace with cursor pagination. Useful for review/debug; prefer memory_search for retrieval.',\n inputSchema: {\n type: 'object',\n properties: {\n limit: { type: 'integer', minimum: 1, maximum: 100, default: 20 },\n cursor: { type: 'string' },\n actor_id: { type: 'string' },\n },\n },\n },\n]\n\nexport function createServer(cfg: ApiClientConfig): Server {\n const api = new MnemoApiClient(cfg)\n const server = new Server(\n { name: 'getmnemo', version: '0.1.0' },\n { capabilities: { tools: {} } },\n )\n\n server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS }))\n\n server.setRequestHandler(CallToolRequestSchema, async (req) => {\n const { name, arguments: args } = req.params\n try {\n const result = await dispatch(api, name, args ?? {})\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n } catch (err) {\n if (err instanceof McpError) throw err\n const message =\n err instanceof MnemoApiError\n ? `Mnemo API error (${err.status}): ${err.message}`\n : err instanceof z.ZodError\n ? `Invalid arguments: ${err.issues.map((i) => `${i.path.join('.') || '(root)'}: ${i.message}`).join('; ')}`\n : err instanceof Error\n ? err.message\n : 'Unknown error'\n return {\n isError: true,\n content: [{ type: 'text', text: message }],\n }\n }\n })\n\n return server\n}\n\nasync function dispatch(\n api: MnemoApiClient,\n name: string,\n raw: Record<string, unknown>,\n): Promise<unknown> {\n switch (name) {\n case 'memory_search': {\n const i = SearchInput.parse(raw)\n return api.search({ query: i.query, limit: i.limit, actorId: i.actor_id })\n }\n case 'memory_add': {\n const i = AddInput.parse(raw)\n return api.addMemory({ content: i.content, metadata: i.metadata, actorId: i.actor_id })\n }\n case 'memory_update': {\n const i = UpdateInput.parse(raw)\n return api.updateMemory(i.id, { content: i.content, metadata: i.metadata })\n }\n case 'memory_delete': {\n const i = DeleteInput.parse(raw)\n return api.deleteMemory(i.id)\n }\n case 'memory_list': {\n const i = ListInput.parse(raw)\n return api.listMemories({ limit: i.limit, cursor: i.cursor, actorId: i.actor_id })\n }\n default:\n throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${name}`)\n }\n}\n"],"mappings":"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","names":[]}
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  createServer
4
- } from "./chunk-KXH67NNU.js";
4
+ } from "./chunk-FJQEJR25.js";
5
5
 
6
6
  // src/cli.ts
7
7
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
package/dist/http.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  createServer
4
- } from "./chunk-KXH67NNU.js";
4
+ } from "./chunk-FJQEJR25.js";
5
5
 
6
6
  // src/http.ts
7
7
  import { createServer as createHttpServer } from "http";
package/dist/index.d.ts CHANGED
@@ -4,7 +4,7 @@ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
4
4
  * Thin REST client for the Mnemo Memory API.
5
5
  *
6
6
  * This duplicates the surface area we need for MCP tools — we deliberately
7
- * do NOT depend on @mnemo/memory here so this server can ship even if
7
+ * do NOT depend on getmnemo here so this server can ship even if
8
8
  * the JS SDK lags behind. When the SDK stabilises, swap this for it.
9
9
  */
10
10
  type Memory = {
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  MnemoApiClient,
3
3
  MnemoApiError,
4
4
  createServer
5
- } from "./chunk-KXH67NNU.js";
5
+ } from "./chunk-FJQEJR25.js";
6
6
  export {
7
7
  MnemoApiClient,
8
8
  MnemoApiError,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "getmnemo-mcp",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Model Context Protocol server for Mnemo Memory — exposes search/add/update/delete tools to Claude Desktop, Cursor, Windsurf, VS Code, Zed.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/api-client.ts","../src/server.ts"],"sourcesContent":["/**\n * Thin REST client for the Mnemo Memory API.\n *\n * This duplicates the surface area we need for MCP tools — we deliberately\n * do NOT depend on @mnemo/memory here so this server can ship even if\n * the JS SDK lags behind. When the SDK stabilises, swap this for it.\n */\n\nexport type Memory = {\n id: string\n content: string\n metadata?: Record<string, unknown>\n workspaceId: string\n actorId?: string | null\n createdAt: string\n updatedAt: string\n}\n\nexport type SearchHit = {\n memoryId: string\n content: string\n score: number\n metadata?: Record<string, unknown>\n source?: { documentId?: string; chunkId?: string } | null\n}\n\nexport type SearchResponse = {\n hits: SearchHit[]\n query: string\n latencyMs: number\n}\n\nexport type ApiClientConfig = {\n baseUrl: string\n apiKey: string\n workspaceId: string\n actorId?: string\n fetch?: typeof fetch\n /** Per-request timeout in ms (default 30s). */\n timeoutMs?: number\n}\n\nexport class MnemoApiError extends Error {\n constructor(\n message: string,\n readonly status: number,\n readonly body?: unknown,\n ) {\n super(message)\n this.name = 'MnemoApiError'\n }\n}\n\nexport class MnemoApiClient {\n private readonly baseUrl: string\n private readonly headers: Record<string, string>\n private readonly fetchImpl: typeof fetch\n private readonly timeoutMs: number\n\n constructor(cfg: ApiClientConfig) {\n if (!cfg.apiKey) throw new Error('apiKey is required')\n if (!cfg.workspaceId) throw new Error('workspaceId is required')\n this.baseUrl = cfg.baseUrl.replace(/\\/$/, '')\n this.headers = {\n 'authorization': `Bearer ${cfg.apiKey}`,\n 'x-workspace-id': cfg.workspaceId,\n 'content-type': 'application/json',\n 'user-agent': '@mnemo/mcp-server',\n ...(cfg.actorId ? { 'x-actor-id': cfg.actorId } : {}),\n }\n this.fetchImpl = cfg.fetch ?? fetch\n this.timeoutMs = cfg.timeoutMs ?? 30_000\n }\n\n async search(input: {\n query: string\n limit?: number\n actorId?: string\n }): Promise<SearchResponse> {\n return this.request<SearchResponse>('POST', '/v1/search', {\n query: input.query,\n limit: input.limit ?? 8,\n ...(input.actorId !== undefined ? { actorId: input.actorId } : {}),\n })\n }\n\n async addMemory(input: {\n content: string\n metadata?: Record<string, unknown>\n actorId?: string\n }): Promise<Memory> {\n return this.request<Memory>('POST', '/v1/memories', {\n content: input.content,\n ...(input.metadata !== undefined ? { metadata: input.metadata } : {}),\n ...(input.actorId !== undefined ? { actorId: input.actorId } : {}),\n })\n }\n\n async updateMemory(\n id: string,\n input: { content?: string; metadata?: Record<string, unknown> },\n ): Promise<Memory> {\n return this.request<Memory>('PATCH', `/v1/memories/${encodeURIComponent(id)}`, input)\n }\n\n async deleteMemory(id: string): Promise<{ id: string; deleted: true }> {\n return this.request<{ id: string; deleted: true }>(\n 'DELETE',\n `/v1/memories/${encodeURIComponent(id)}`,\n )\n }\n\n async listMemories(input?: {\n limit?: number\n cursor?: string\n actorId?: string\n }): Promise<{ items: Memory[]; nextCursor: string | null }> {\n const params = new URLSearchParams()\n if (input?.limit !== undefined) params.set('limit', String(input.limit))\n if (input?.cursor !== undefined) params.set('cursor', input.cursor)\n if (input?.actorId !== undefined) params.set('actorId', input.actorId)\n const qs = params.toString()\n return this.request('GET', `/v1/memories${qs ? `?${qs}` : ''}`)\n }\n\n private async request<T>(\n method: string,\n path: string,\n body?: unknown,\n ): Promise<T> {\n const ctrl = new AbortController()\n const timer = setTimeout(() => ctrl.abort(), this.timeoutMs)\n try {\n const res = await this.fetchImpl(`${this.baseUrl}${path}`, {\n method,\n headers: { ...this.headers },\n body: body === undefined ? undefined : JSON.stringify(body),\n signal: ctrl.signal,\n })\n const text = await res.text()\n const parsed = text ? safeJson(text) : undefined\n if (!res.ok) {\n const msg =\n (parsed && typeof parsed === 'object' && 'message' in parsed\n ? String((parsed as { message: unknown }).message)\n : null) ?? `HTTP ${res.status} ${res.statusText}`\n throw new MnemoApiError(msg, res.status, parsed)\n }\n if (parsed !== undefined && typeof parsed !== 'object') {\n throw new MnemoApiError(\n `Expected JSON object response, got: ${typeof parsed}`,\n res.status,\n parsed,\n )\n }\n return parsed as T\n } finally {\n clearTimeout(timer)\n }\n }\n}\n\nfunction safeJson(s: string): unknown {\n try {\n return JSON.parse(s)\n } catch {\n return s\n }\n}\n","/**\n * MCP server factory.\n *\n * Exposes 5 tools to MCP clients (Claude Desktop, Cursor, Windsurf, VS Code,\n * Zed): memory_search, memory_add, memory_update, memory_delete, memory_list.\n *\n * Transport-agnostic — wire to stdio (cli.ts) or HTTP/SSE (http.ts).\n */\n\nimport { Server } from '@modelcontextprotocol/sdk/server/index.js'\nimport {\n CallToolRequestSchema,\n ErrorCode,\n ListToolsRequestSchema,\n McpError,\n type Tool,\n} from '@modelcontextprotocol/sdk/types.js'\nimport { z } from 'zod'\n\nimport { MnemoApiClient, type ApiClientConfig, MnemoApiError } from './api-client.js'\n\nconst SearchInput = z.object({\n query: z.string().min(1).max(2000).describe('Natural-language search query.'),\n limit: z.number().int().min(1).max(50).default(8).describe('Max number of memories to return.'),\n actor_id: z\n .string()\n .min(1)\n .max(256)\n .optional()\n .describe('Optional actor scope (defaults to the configured actor).'),\n})\n\n// Cap metadata size so a malicious or buggy client cannot push a 10MB blob\n// through the MCP boundary (the upstream API enforces its own limits, but\n// we'd rather reject early than waste a round-trip).\nconst METADATA_MAX_SERIALIZED_BYTES = 16 * 1024\nconst boundedMetadata = z\n .record(z.unknown())\n .refine(\n (m) => {\n try {\n return Buffer.byteLength(JSON.stringify(m), 'utf8') <= METADATA_MAX_SERIALIZED_BYTES\n } catch {\n return false\n }\n },\n { message: `metadata exceeds ${METADATA_MAX_SERIALIZED_BYTES} bytes when serialized` },\n )\n\nconst AddInput = z.object({\n content: z.string().min(1).max(10_000).describe('The fact or memory to store.'),\n metadata: boundedMetadata\n .optional()\n .describe('Arbitrary JSON metadata (tags, source, etc.). Max 16KB serialized.'),\n actor_id: z.string().min(1).max(256).optional(),\n})\n\nconst UpdateInput = z.object({\n id: z.string().min(1).max(256).describe('Memory ID returned by memory_add or memory_search.'),\n content: z.string().min(1).max(10_000).optional(),\n metadata: boundedMetadata.optional(),\n})\n\nconst DeleteInput = z.object({\n id: z.string().min(1).max(256).describe('Memory ID to delete.'),\n})\n\nconst ListInput = z.object({\n limit: z.number().int().min(1).max(100).default(20),\n cursor: z.string().min(1).max(1024).optional(),\n actor_id: z.string().min(1).max(256).optional(),\n})\n\nconst TOOLS: Tool[] = [\n {\n name: 'memory_search',\n description:\n 'Search the Mnemo memory store for facts relevant to a query. Returns ranked hits with content, score, and source citations. Use this BEFORE answering any question that might require remembered context.',\n inputSchema: {\n type: 'object',\n properties: {\n query: { type: 'string', description: 'Natural-language search query.' },\n limit: { type: 'integer', minimum: 1, maximum: 50, default: 8 },\n actor_id: { type: 'string' },\n },\n required: ['query'],\n },\n },\n {\n name: 'memory_add',\n description:\n 'Store a new atomic fact in long-term memory. Use this whenever the user reveals durable preferences, facts about themselves, or context that should persist across sessions.',\n inputSchema: {\n type: 'object',\n properties: {\n content: { type: 'string' },\n metadata: { type: 'object' },\n actor_id: { type: 'string' },\n },\n required: ['content'],\n },\n },\n {\n name: 'memory_update',\n description:\n \"Update an existing memory's content or metadata. Use when a previously-stored fact is no longer accurate.\",\n inputSchema: {\n type: 'object',\n properties: {\n id: { type: 'string' },\n content: { type: 'string' },\n metadata: { type: 'object' },\n },\n required: ['id'],\n },\n },\n {\n name: 'memory_delete',\n description:\n 'Delete a memory by ID. Use only when the user explicitly asks to forget something or when a fact is permanently invalid.',\n inputSchema: {\n type: 'object',\n properties: { id: { type: 'string' } },\n required: ['id'],\n },\n },\n {\n name: 'memory_list',\n description:\n 'List memories in the workspace with cursor pagination. Useful for review/debug; prefer memory_search for retrieval.',\n inputSchema: {\n type: 'object',\n properties: {\n limit: { type: 'integer', minimum: 1, maximum: 100, default: 20 },\n cursor: { type: 'string' },\n actor_id: { type: 'string' },\n },\n },\n },\n]\n\nexport function createServer(cfg: ApiClientConfig): Server {\n const api = new MnemoApiClient(cfg)\n const server = new Server(\n { name: 'getmnemo', version: '0.1.0' },\n { capabilities: { tools: {} } },\n )\n\n server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS }))\n\n server.setRequestHandler(CallToolRequestSchema, async (req) => {\n const { name, arguments: args } = req.params\n try {\n const result = await dispatch(api, name, args ?? {})\n return {\n content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],\n }\n } catch (err) {\n if (err instanceof McpError) throw err\n const message =\n err instanceof MnemoApiError\n ? `Mnemo API error (${err.status}): ${err.message}`\n : err instanceof z.ZodError\n ? `Invalid arguments: ${err.issues.map((i) => `${i.path.join('.') || '(root)'}: ${i.message}`).join('; ')}`\n : err instanceof Error\n ? err.message\n : 'Unknown error'\n return {\n isError: true,\n content: [{ type: 'text', text: message }],\n }\n }\n })\n\n return server\n}\n\nasync function dispatch(\n api: MnemoApiClient,\n name: string,\n raw: Record<string, unknown>,\n): Promise<unknown> {\n switch (name) {\n case 'memory_search': {\n const i = SearchInput.parse(raw)\n return api.search({ query: i.query, limit: i.limit, actorId: i.actor_id })\n }\n case 'memory_add': {\n const i = AddInput.parse(raw)\n return api.addMemory({ content: i.content, metadata: i.metadata, actorId: i.actor_id })\n }\n case 'memory_update': {\n const i = UpdateInput.parse(raw)\n return api.updateMemory(i.id, { content: i.content, metadata: i.metadata })\n }\n case 'memory_delete': {\n const i = DeleteInput.parse(raw)\n return api.deleteMemory(i.id)\n }\n case 'memory_list': {\n const i = ListInput.parse(raw)\n return api.listMemories({ limit: i.limit, cursor: i.cursor, actorId: i.actor_id })\n }\n default:\n throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${name}`)\n }\n}\n"],"mappings":"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","names":[]}