getmnemo-mcp 0.1.0 → 0.1.2

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,33 @@ 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": "lk_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>.
42
+ Get an API key at <https://app.mnemohq.com/settings/api-keys>.
43
43
 
44
- ### Hosted (HTTP/SSE) at `mcp.proofly.dev`
44
+ ### Hosted (HTTP/SSE) at `mcp.mnemohq.com`
45
45
 
46
46
  ```bash
47
- npx -y install-mcp@latest https://mcp.proofly.dev/mcp --client claude
47
+ npx -y install-mcp@latest https://mcp.mnemohq.com/mcp --client claude
48
48
  ```
49
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.)
50
+ (OAuth flow lands in v0.2 — until then the hosted endpoint accepts `x-getmnemo-api-key` + `x-getmnemo-workspace-id` headers from trusted clients.)
51
51
 
52
52
  ## Develop
53
53
 
54
54
  ```bash
55
55
  npm install
56
- cp .env.example .env # fill in LEDGERMEM_API_KEY + LEDGERMEM_WORKSPACE_ID
56
+ cp .env.example .env # fill in GETMNEMO_API_KEY + GETMNEMO_WORKSPACE_ID
57
57
  npm run dev # stdio
58
58
  npm run dev:http # HTTP/SSE on :8787
59
59
  npm run build # bundle to dist/
@@ -65,7 +65,7 @@ npm run build # bundle to dist/
65
65
  - **HTTP/SSE** (`src/http.ts`): single long-running process for hosted use, header-or-OAuth auth.
66
66
  - Both transports share `src/server.ts` (tool registration + dispatch) and `src/api-client.ts` (typed REST wrapper).
67
67
 
68
- The server deliberately does NOT depend on `@ledgermem/memory` (the JS SDK) so it can ship independently.
68
+ The server deliberately does NOT depend on `getmnemo` (the JS SDK) so it can ship independently.
69
69
 
70
70
  ## License
71
71
 
package/dist/cli.js CHANGED
@@ -10,12 +10,12 @@ async function main() {
10
10
  const workspaceId = process.env.GETMNEMO_WORKSPACE_ID;
11
11
  if (!apiKey || !workspaceId) {
12
12
  process.stderr.write(
13
- "Mnemo MCP: missing GETMNEMO_API_KEY and/or GETMNEMO_WORKSPACE_ID env vars.\nGet a key at https://app.getmnemo.xyz/settings/api-keys\n"
13
+ "Mnemo MCP: missing GETMNEMO_API_KEY and/or GETMNEMO_WORKSPACE_ID env vars.\nGet a key at https://app.mnemohq.com/settings/api-keys\n"
14
14
  );
15
15
  process.exit(1);
16
16
  }
17
17
  const server = createServer({
18
- baseUrl: process.env.GETMNEMO_API_URL ?? "https://api.getmnemo.xyz",
18
+ baseUrl: process.env.GETMNEMO_API_URL ?? "https://api.mnemohq.com",
19
19
  apiKey,
20
20
  workspaceId,
21
21
  actorId: process.env.GETMNEMO_ACTOR_ID
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * Stdio entry-point for local MCP clients (Claude Desktop, Cursor, Windsurf, Zed).\n *\n * Reads config from env:\n * GETMNEMO_API_URL (default: https://api.getmnemo.xyz)\n * GETMNEMO_API_KEY (required)\n * GETMNEMO_WORKSPACE_ID (required)\n * GETMNEMO_ACTOR_ID (optional)\n */\n\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { createServer } from './server.js'\n\nasync function main(): Promise<void> {\n const apiKey = process.env.GETMNEMO_API_KEY\n const workspaceId = process.env.GETMNEMO_WORKSPACE_ID\n if (!apiKey || !workspaceId) {\n process.stderr.write(\n 'Mnemo MCP: missing GETMNEMO_API_KEY and/or GETMNEMO_WORKSPACE_ID env vars.\\n' +\n 'Get a key at https://app.getmnemo.xyz/settings/api-keys\\n',\n )\n process.exit(1)\n }\n\n const server = createServer({\n baseUrl: process.env.GETMNEMO_API_URL ?? 'https://api.getmnemo.xyz',\n apiKey,\n workspaceId,\n actorId: process.env.GETMNEMO_ACTOR_ID,\n })\n\n const transport = new StdioServerTransport()\n await server.connect(transport)\n // Stays alive until parent process closes stdio.\n}\n\nmain().catch((err) => {\n process.stderr.write(`Mnemo MCP fatal: ${err instanceof Error ? err.message : String(err)}\\n`)\n process.exit(1)\n})\n"],"mappings":";;;;;;AAWA,SAAS,4BAA4B;AAGrC,eAAe,OAAsB;AACnC,QAAM,SAAS,QAAQ,IAAI;AAC3B,QAAM,cAAc,QAAQ,IAAI;AAChC,MAAI,CAAC,UAAU,CAAC,aAAa;AAC3B,YAAQ,OAAO;AAAA,MACb;AAAA,IAEF;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,SAAS,aAAa;AAAA,IAC1B,SAAS,QAAQ,IAAI,oBAAoB;AAAA,IACzC;AAAA,IACA;AAAA,IACA,SAAS,QAAQ,IAAI;AAAA,EACvB,CAAC;AAED,QAAM,YAAY,IAAI,qBAAqB;AAC3C,QAAM,OAAO,QAAQ,SAAS;AAEhC;AAEA,KAAK,EAAE,MAAM,CAAC,QAAQ;AACpB,UAAQ,OAAO,MAAM,oBAAoB,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,CAAI;AAC7F,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":[]}
1
+ {"version":3,"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * Stdio entry-point for local MCP clients (Claude Desktop, Cursor, Windsurf, Zed).\n *\n * Reads config from env:\n * GETMNEMO_API_URL (default: https://api.mnemohq.com)\n * GETMNEMO_API_KEY (required)\n * GETMNEMO_WORKSPACE_ID (required)\n * GETMNEMO_ACTOR_ID (optional)\n */\n\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { createServer } from './server.js'\n\nasync function main(): Promise<void> {\n const apiKey = process.env.GETMNEMO_API_KEY\n const workspaceId = process.env.GETMNEMO_WORKSPACE_ID\n if (!apiKey || !workspaceId) {\n process.stderr.write(\n 'Mnemo MCP: missing GETMNEMO_API_KEY and/or GETMNEMO_WORKSPACE_ID env vars.\\n' +\n 'Get a key at https://app.mnemohq.com/settings/api-keys\\n',\n )\n process.exit(1)\n }\n\n const server = createServer({\n baseUrl: process.env.GETMNEMO_API_URL ?? 'https://api.mnemohq.com',\n apiKey,\n workspaceId,\n actorId: process.env.GETMNEMO_ACTOR_ID,\n })\n\n const transport = new StdioServerTransport()\n await server.connect(transport)\n // Stays alive until parent process closes stdio.\n}\n\nmain().catch((err) => {\n process.stderr.write(`Mnemo MCP fatal: ${err instanceof Error ? err.message : String(err)}\\n`)\n process.exit(1)\n})\n"],"mappings":";;;;;;AAWA,SAAS,4BAA4B;AAGrC,eAAe,OAAsB;AACnC,QAAM,SAAS,QAAQ,IAAI;AAC3B,QAAM,cAAc,QAAQ,IAAI;AAChC,MAAI,CAAC,UAAU,CAAC,aAAa;AAC3B,YAAQ,OAAO;AAAA,MACb;AAAA,IAEF;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,SAAS,aAAa;AAAA,IAC1B,SAAS,QAAQ,IAAI,oBAAoB;AAAA,IACzC;AAAA,IACA;AAAA,IACA,SAAS,QAAQ,IAAI;AAAA,EACvB,CAAC;AAED,QAAM,YAAY,IAAI,qBAAqB;AAC3C,QAAM,OAAO,QAAQ,SAAS;AAEhC;AAEA,KAAK,EAAE,MAAM,CAAC,QAAQ;AACpB,UAAQ,OAAO,MAAM,oBAAoB,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,CAAI;AAC7F,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":[]}
package/dist/http.js CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  import { createServer as createHttpServer } from "http";
8
8
  import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
9
9
  var PORT = Number(process.env.PORT ?? 8787);
10
- var DEFAULT_API_URL = process.env.GETMNEMO_API_URL ?? "https://api.getmnemo.xyz";
10
+ var DEFAULT_API_URL = process.env.GETMNEMO_API_URL ?? "https://api.mnemohq.com";
11
11
  var httpServer = createHttpServer((req, res) => {
12
12
  const url = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
13
13
  if (url.pathname === "/healthz") {
package/dist/http.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/http.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * HTTP/SSE entry-point for hosted MCP at mcp.getmnemo.xyz.\n *\n * Each connecting client supplies its own GETMNEMO_API_KEY and\n * GETMNEMO_WORKSPACE_ID via OAuth (Phase 2) or via custom headers\n * `x-getmnemo-api-key` + `x-getmnemo-workspace-id` (Phase 1, dev-only).\n *\n * Listens on PORT (default 8787). Healthcheck at GET /healthz.\n */\n\nimport { createServer as createHttpServer } from 'node:http'\nimport { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js'\nimport { createServer } from './server.js'\n\nconst PORT = Number(process.env.PORT ?? 8787)\nconst DEFAULT_API_URL = process.env.GETMNEMO_API_URL ?? 'https://api.getmnemo.xyz'\n\nconst httpServer = createHttpServer((req, res) => {\n const url = new URL(req.url ?? '/', `http://${req.headers.host ?? 'localhost'}`)\n\n if (url.pathname === '/healthz') {\n res.writeHead(200, { 'content-type': 'application/json' })\n res.end(JSON.stringify({ status: 'ok', service: 'getmnemo-mcp' }))\n return\n }\n\n if (url.pathname !== '/mcp') {\n res.writeHead(404, { 'content-type': 'text/plain' })\n res.end('Not found. GET /mcp for the SSE stream, GET /healthz for liveness.\\n')\n return\n }\n\n if (req.method !== 'GET' && req.method !== 'POST') {\n res.writeHead(405, { 'content-type': 'text/plain', allow: 'GET, POST' })\n res.end('Method not allowed.\\n')\n return\n }\n\n const apiKey =\n (req.headers['x-getmnemo-api-key'] as string | undefined) ?? process.env.GETMNEMO_API_KEY\n const workspaceId =\n (req.headers['x-getmnemo-workspace-id'] as string | undefined) ??\n process.env.GETMNEMO_WORKSPACE_ID\n\n if (!apiKey || !workspaceId) {\n res.writeHead(401, { 'content-type': 'application/json' })\n res.end(\n JSON.stringify({\n error: 'Missing x-getmnemo-api-key and/or x-getmnemo-workspace-id headers.',\n hint: 'OAuth flow lands in v0.2; headers work today for trusted clients.',\n }),\n )\n return\n }\n\n const server = createServer({\n baseUrl: DEFAULT_API_URL,\n apiKey,\n workspaceId,\n actorId: req.headers['x-getmnemo-actor-id'] as string | undefined,\n })\n\n const transport = new SSEServerTransport('/mcp', res)\n\n // SSE keepalive: many proxies (CloudFront, ALB, nginx default 60s) close\n // idle connections, which silently breaks long-lived MCP sessions. Emit a\n // comment-frame heartbeat every 25s so the connection stays warm.\n const KEEPALIVE_MS = 25_000\n // Track tear-down so the heartbeat cannot race with cleanup. Without this\n // guard, `setInterval` can fire on the same tick that the client closes the\n // socket: clearInterval is queued, the timer callback is already running,\n // and `res.write` lands on a half-closed transport — Node throws\n // ERR_STREAM_WRITE_AFTER_END (uncaught here, the empty catch only swallows\n // synchronous errors; the actual error fires on the 'error' event).\n let closed = false\n const keepalive = setInterval(() => {\n if (closed || res.writableEnded || res.destroyed) return\n try {\n // SSE comments start with \":\" and are ignored by the client parser.\n res.write(`: keepalive ${Date.now()}\\n\\n`)\n } catch {\n // res may already be closed; cleanup will run via the 'close' handler.\n }\n }, KEEPALIVE_MS)\n // Don't keep the event loop alive solely for the heartbeat.\n keepalive.unref?.()\n\n const cleanup = (): void => {\n if (closed) return\n closed = true\n clearInterval(keepalive)\n transport.close().catch(() => undefined)\n server.close().catch(() => undefined)\n }\n res.on('close', cleanup)\n res.on('error', cleanup)\n\n server.connect(transport).catch((err) => {\n process.stderr.write(`MCP transport error: ${err instanceof Error ? err.message : err}\\n`)\n cleanup()\n if (!res.headersSent) {\n res.writeHead(500, { 'content-type': 'application/json' })\n res.end(JSON.stringify({ error: 'MCP transport failed to initialize' }))\n }\n })\n})\n\nhttpServer.listen(PORT, () => {\n process.stdout.write(`Mnemo MCP HTTP listening on :${PORT}\\n`)\n})\n\nprocess.on('SIGTERM', () => httpServer.close(() => process.exit(0)))\nprocess.on('SIGINT', () => httpServer.close(() => process.exit(0)))\n"],"mappings":";;;;;;AAWA,SAAS,gBAAgB,wBAAwB;AACjD,SAAS,0BAA0B;AAGnC,IAAM,OAAO,OAAO,QAAQ,IAAI,QAAQ,IAAI;AAC5C,IAAM,kBAAkB,QAAQ,IAAI,oBAAoB;AAExD,IAAM,aAAa,iBAAiB,CAAC,KAAK,QAAQ;AAChD,QAAM,MAAM,IAAI,IAAI,IAAI,OAAO,KAAK,UAAU,IAAI,QAAQ,QAAQ,WAAW,EAAE;AAE/E,MAAI,IAAI,aAAa,YAAY;AAC/B,QAAI,UAAU,KAAK,EAAE,gBAAgB,mBAAmB,CAAC;AACzD,QAAI,IAAI,KAAK,UAAU,EAAE,QAAQ,MAAM,SAAS,eAAe,CAAC,CAAC;AACjE;AAAA,EACF;AAEA,MAAI,IAAI,aAAa,QAAQ;AAC3B,QAAI,UAAU,KAAK,EAAE,gBAAgB,aAAa,CAAC;AACnD,QAAI,IAAI,sEAAsE;AAC9E;AAAA,EACF;AAEA,MAAI,IAAI,WAAW,SAAS,IAAI,WAAW,QAAQ;AACjD,QAAI,UAAU,KAAK,EAAE,gBAAgB,cAAc,OAAO,YAAY,CAAC;AACvE,QAAI,IAAI,uBAAuB;AAC/B;AAAA,EACF;AAEA,QAAM,SACH,IAAI,QAAQ,oBAAoB,KAA4B,QAAQ,IAAI;AAC3E,QAAM,cACH,IAAI,QAAQ,yBAAyB,KACtC,QAAQ,IAAI;AAEd,MAAI,CAAC,UAAU,CAAC,aAAa;AAC3B,QAAI,UAAU,KAAK,EAAE,gBAAgB,mBAAmB,CAAC;AACzD,QAAI;AAAA,MACF,KAAK,UAAU;AAAA,QACb,OAAO;AAAA,QACP,MAAM;AAAA,MACR,CAAC;AAAA,IACH;AACA;AAAA,EACF;AAEA,QAAM,SAAS,aAAa;AAAA,IAC1B,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA,SAAS,IAAI,QAAQ,qBAAqB;AAAA,EAC5C,CAAC;AAED,QAAM,YAAY,IAAI,mBAAmB,QAAQ,GAAG;AAKpD,QAAM,eAAe;AAOrB,MAAI,SAAS;AACb,QAAM,YAAY,YAAY,MAAM;AAClC,QAAI,UAAU,IAAI,iBAAiB,IAAI,UAAW;AAClD,QAAI;AAEF,UAAI,MAAM,eAAe,KAAK,IAAI,CAAC;AAAA;AAAA,CAAM;AAAA,IAC3C,QAAQ;AAAA,IAER;AAAA,EACF,GAAG,YAAY;AAEf,YAAU,QAAQ;AAElB,QAAM,UAAU,MAAY;AAC1B,QAAI,OAAQ;AACZ,aAAS;AACT,kBAAc,SAAS;AACvB,cAAU,MAAM,EAAE,MAAM,MAAM,MAAS;AACvC,WAAO,MAAM,EAAE,MAAM,MAAM,MAAS;AAAA,EACtC;AACA,MAAI,GAAG,SAAS,OAAO;AACvB,MAAI,GAAG,SAAS,OAAO;AAEvB,SAAO,QAAQ,SAAS,EAAE,MAAM,CAAC,QAAQ;AACvC,YAAQ,OAAO,MAAM,wBAAwB,eAAe,QAAQ,IAAI,UAAU,GAAG;AAAA,CAAI;AACzF,YAAQ;AACR,QAAI,CAAC,IAAI,aAAa;AACpB,UAAI,UAAU,KAAK,EAAE,gBAAgB,mBAAmB,CAAC;AACzD,UAAI,IAAI,KAAK,UAAU,EAAE,OAAO,qCAAqC,CAAC,CAAC;AAAA,IACzE;AAAA,EACF,CAAC;AACH,CAAC;AAED,WAAW,OAAO,MAAM,MAAM;AAC5B,UAAQ,OAAO,MAAM,gCAAgC,IAAI;AAAA,CAAI;AAC/D,CAAC;AAED,QAAQ,GAAG,WAAW,MAAM,WAAW,MAAM,MAAM,QAAQ,KAAK,CAAC,CAAC,CAAC;AACnE,QAAQ,GAAG,UAAU,MAAM,WAAW,MAAM,MAAM,QAAQ,KAAK,CAAC,CAAC,CAAC;","names":[]}
1
+ {"version":3,"sources":["../src/http.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * HTTP/SSE entry-point for hosted MCP at mcp.mnemohq.com.\n *\n * Each connecting client supplies its own GETMNEMO_API_KEY and\n * GETMNEMO_WORKSPACE_ID via OAuth (Phase 2) or via custom headers\n * `x-getmnemo-api-key` + `x-getmnemo-workspace-id` (Phase 1, dev-only).\n *\n * Listens on PORT (default 8787). Healthcheck at GET /healthz.\n */\n\nimport { createServer as createHttpServer } from 'node:http'\nimport { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js'\nimport { createServer } from './server.js'\n\nconst PORT = Number(process.env.PORT ?? 8787)\nconst DEFAULT_API_URL = process.env.GETMNEMO_API_URL ?? 'https://api.mnemohq.com'\n\nconst httpServer = createHttpServer((req, res) => {\n const url = new URL(req.url ?? '/', `http://${req.headers.host ?? 'localhost'}`)\n\n if (url.pathname === '/healthz') {\n res.writeHead(200, { 'content-type': 'application/json' })\n res.end(JSON.stringify({ status: 'ok', service: 'getmnemo-mcp' }))\n return\n }\n\n if (url.pathname !== '/mcp') {\n res.writeHead(404, { 'content-type': 'text/plain' })\n res.end('Not found. GET /mcp for the SSE stream, GET /healthz for liveness.\\n')\n return\n }\n\n if (req.method !== 'GET' && req.method !== 'POST') {\n res.writeHead(405, { 'content-type': 'text/plain', allow: 'GET, POST' })\n res.end('Method not allowed.\\n')\n return\n }\n\n const apiKey =\n (req.headers['x-getmnemo-api-key'] as string | undefined) ?? process.env.GETMNEMO_API_KEY\n const workspaceId =\n (req.headers['x-getmnemo-workspace-id'] as string | undefined) ??\n process.env.GETMNEMO_WORKSPACE_ID\n\n if (!apiKey || !workspaceId) {\n res.writeHead(401, { 'content-type': 'application/json' })\n res.end(\n JSON.stringify({\n error: 'Missing x-getmnemo-api-key and/or x-getmnemo-workspace-id headers.',\n hint: 'OAuth flow lands in v0.2; headers work today for trusted clients.',\n }),\n )\n return\n }\n\n const server = createServer({\n baseUrl: DEFAULT_API_URL,\n apiKey,\n workspaceId,\n actorId: req.headers['x-getmnemo-actor-id'] as string | undefined,\n })\n\n const transport = new SSEServerTransport('/mcp', res)\n\n // SSE keepalive: many proxies (CloudFront, ALB, nginx default 60s) close\n // idle connections, which silently breaks long-lived MCP sessions. Emit a\n // comment-frame heartbeat every 25s so the connection stays warm.\n const KEEPALIVE_MS = 25_000\n // Track tear-down so the heartbeat cannot race with cleanup. Without this\n // guard, `setInterval` can fire on the same tick that the client closes the\n // socket: clearInterval is queued, the timer callback is already running,\n // and `res.write` lands on a half-closed transport — Node throws\n // ERR_STREAM_WRITE_AFTER_END (uncaught here, the empty catch only swallows\n // synchronous errors; the actual error fires on the 'error' event).\n let closed = false\n const keepalive = setInterval(() => {\n if (closed || res.writableEnded || res.destroyed) return\n try {\n // SSE comments start with \":\" and are ignored by the client parser.\n res.write(`: keepalive ${Date.now()}\\n\\n`)\n } catch {\n // res may already be closed; cleanup will run via the 'close' handler.\n }\n }, KEEPALIVE_MS)\n // Don't keep the event loop alive solely for the heartbeat.\n keepalive.unref?.()\n\n const cleanup = (): void => {\n if (closed) return\n closed = true\n clearInterval(keepalive)\n transport.close().catch(() => undefined)\n server.close().catch(() => undefined)\n }\n res.on('close', cleanup)\n res.on('error', cleanup)\n\n server.connect(transport).catch((err) => {\n process.stderr.write(`MCP transport error: ${err instanceof Error ? err.message : err}\\n`)\n cleanup()\n if (!res.headersSent) {\n res.writeHead(500, { 'content-type': 'application/json' })\n res.end(JSON.stringify({ error: 'MCP transport failed to initialize' }))\n }\n })\n})\n\nhttpServer.listen(PORT, () => {\n process.stdout.write(`Mnemo MCP HTTP listening on :${PORT}\\n`)\n})\n\nprocess.on('SIGTERM', () => httpServer.close(() => process.exit(0)))\nprocess.on('SIGINT', () => httpServer.close(() => process.exit(0)))\n"],"mappings":";;;;;;AAWA,SAAS,gBAAgB,wBAAwB;AACjD,SAAS,0BAA0B;AAGnC,IAAM,OAAO,OAAO,QAAQ,IAAI,QAAQ,IAAI;AAC5C,IAAM,kBAAkB,QAAQ,IAAI,oBAAoB;AAExD,IAAM,aAAa,iBAAiB,CAAC,KAAK,QAAQ;AAChD,QAAM,MAAM,IAAI,IAAI,IAAI,OAAO,KAAK,UAAU,IAAI,QAAQ,QAAQ,WAAW,EAAE;AAE/E,MAAI,IAAI,aAAa,YAAY;AAC/B,QAAI,UAAU,KAAK,EAAE,gBAAgB,mBAAmB,CAAC;AACzD,QAAI,IAAI,KAAK,UAAU,EAAE,QAAQ,MAAM,SAAS,eAAe,CAAC,CAAC;AACjE;AAAA,EACF;AAEA,MAAI,IAAI,aAAa,QAAQ;AAC3B,QAAI,UAAU,KAAK,EAAE,gBAAgB,aAAa,CAAC;AACnD,QAAI,IAAI,sEAAsE;AAC9E;AAAA,EACF;AAEA,MAAI,IAAI,WAAW,SAAS,IAAI,WAAW,QAAQ;AACjD,QAAI,UAAU,KAAK,EAAE,gBAAgB,cAAc,OAAO,YAAY,CAAC;AACvE,QAAI,IAAI,uBAAuB;AAC/B;AAAA,EACF;AAEA,QAAM,SACH,IAAI,QAAQ,oBAAoB,KAA4B,QAAQ,IAAI;AAC3E,QAAM,cACH,IAAI,QAAQ,yBAAyB,KACtC,QAAQ,IAAI;AAEd,MAAI,CAAC,UAAU,CAAC,aAAa;AAC3B,QAAI,UAAU,KAAK,EAAE,gBAAgB,mBAAmB,CAAC;AACzD,QAAI;AAAA,MACF,KAAK,UAAU;AAAA,QACb,OAAO;AAAA,QACP,MAAM;AAAA,MACR,CAAC;AAAA,IACH;AACA;AAAA,EACF;AAEA,QAAM,SAAS,aAAa;AAAA,IAC1B,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA,SAAS,IAAI,QAAQ,qBAAqB;AAAA,EAC5C,CAAC;AAED,QAAM,YAAY,IAAI,mBAAmB,QAAQ,GAAG;AAKpD,QAAM,eAAe;AAOrB,MAAI,SAAS;AACb,QAAM,YAAY,YAAY,MAAM;AAClC,QAAI,UAAU,IAAI,iBAAiB,IAAI,UAAW;AAClD,QAAI;AAEF,UAAI,MAAM,eAAe,KAAK,IAAI,CAAC;AAAA;AAAA,CAAM;AAAA,IAC3C,QAAQ;AAAA,IAER;AAAA,EACF,GAAG,YAAY;AAEf,YAAU,QAAQ;AAElB,QAAM,UAAU,MAAY;AAC1B,QAAI,OAAQ;AACZ,aAAS;AACT,kBAAc,SAAS;AACvB,cAAU,MAAM,EAAE,MAAM,MAAM,MAAS;AACvC,WAAO,MAAM,EAAE,MAAM,MAAM,MAAS;AAAA,EACtC;AACA,MAAI,GAAG,SAAS,OAAO;AACvB,MAAI,GAAG,SAAS,OAAO;AAEvB,SAAO,QAAQ,SAAS,EAAE,MAAM,CAAC,QAAQ;AACvC,YAAQ,OAAO,MAAM,wBAAwB,eAAe,QAAQ,IAAI,UAAU,GAAG;AAAA,CAAI;AACzF,YAAQ;AACR,QAAI,CAAC,IAAI,aAAa;AACpB,UAAI,UAAU,KAAK,EAAE,gBAAgB,mBAAmB,CAAC;AACzD,UAAI,IAAI,KAAK,UAAU,EAAE,OAAO,qCAAqC,CAAC,CAAC;AAAA,IACzE;AAAA,EACF,CAAC;AACH,CAAC;AAED,WAAW,OAAO,MAAM,MAAM;AAC5B,UAAQ,OAAO,MAAM,gCAAgC,IAAI;AAAA,CAAI;AAC/D,CAAC;AAED,QAAQ,GAAG,WAAW,MAAM,WAAW,MAAM,MAAM,QAAQ,KAAK,CAAC,CAAC,CAAC;AACnE,QAAQ,GAAG,UAAU,MAAM,WAAW,MAAM,MAAM,QAAQ,KAAK,CAAC,CAAC,CAAC;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "getmnemo-mcp",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
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",
@@ -47,5 +47,5 @@
47
47
  "type": "git",
48
48
  "url": "https://github.com/ledgermem/getmnemo-mcp.git"
49
49
  },
50
- "homepage": "https://getmnemo.xyz"
50
+ "homepage": "https://mnemohq.com"
51
51
  }