superlocalmemory 2.3.4 → 2.3.5

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.
@@ -1,7 +1,16 @@
1
1
  {
2
- "_README": "ChatGPT requires HTTP transport, not stdio. See docs/MCP-MANUAL-SETUP.md#chatgpt-desktop-app",
3
- "_step1": "Run: slm serve --port 8001",
4
- "_step2": "Expose via: ngrok http 8001 (or cloudflared tunnel)",
5
- "_step3": "Add the HTTPS URL to ChatGPT -> Settings -> Apps & Connectors -> Developer Mode",
6
- "_note": "100% local - your MCP server runs on YOUR machine. The tunnel just makes it reachable."
2
+ "_README": "ChatGPT Integration SuperLocalMemory V2 as ChatGPT Connector",
3
+ "_requires": "ChatGPT Pro/Plus/Business/Enterprise with Developer Mode enabled",
4
+ "_tools": "search(query) and fetch(id) required by OpenAI MCP spec for Connectors",
5
+ "_setup": {
6
+ "step1": "Start MCP server: slm serve --port 8417",
7
+ "step2": "Expose via tunnel: ngrok http 8417",
8
+ "step3": "Copy the HTTPS URL from ngrok (e.g. https://abc123.ngrok.app)",
9
+ "step4": "In ChatGPT: Settings → Connectors → Advanced → Enable Developer Mode",
10
+ "step5": "Create new Connector → paste URL with /sse/ suffix (e.g. https://abc123.ngrok.app/sse/)",
11
+ "step6": "Name it 'SuperLocalMemory' and click Create",
12
+ "step7": "In any chat, click + → More → select SuperLocalMemory connector"
13
+ },
14
+ "_alternative_transport": "For Streamable HTTP (recommended): slm serve --transport streamable-http --port 8417",
15
+ "_note": "100% local — your MCP server runs on YOUR machine. The tunnel just makes it reachable by ChatGPT servers. All data stays in ~/.claude-memory/memory.db"
7
16
  }
package/mcp_server.py CHANGED
@@ -374,6 +374,108 @@ async def switch_profile(name: str) -> dict:
374
374
  }
375
375
 
376
376
 
377
+ # ============================================================================
378
+ # CHATGPT CONNECTOR TOOLS (search + fetch — required by OpenAI MCP spec)
379
+ # These two tools are required for ChatGPT Connectors and Deep Research.
380
+ # They wrap existing SuperLocalMemory search/retrieval logic.
381
+ # Ref: https://platform.openai.com/docs/mcp
382
+ # ============================================================================
383
+
384
+ @mcp.tool(annotations=ToolAnnotations(
385
+ readOnlyHint=True,
386
+ destructiveHint=False,
387
+ openWorldHint=False,
388
+ ))
389
+ async def search(query: str) -> dict:
390
+ """
391
+ Search for documents in SuperLocalMemory.
392
+
393
+ Required by ChatGPT Connectors and Deep Research.
394
+ Returns a list of search results with id, title, text snippet, and url.
395
+
396
+ Args:
397
+ query: Search query string. Natural language queries work best.
398
+
399
+ Returns:
400
+ {"results": [{"id": str, "title": str, "text": str, "url": str}]}
401
+ """
402
+ try:
403
+ store = MemoryStoreV2(DB_PATH)
404
+ raw_results = store.search(query, limit=20)
405
+
406
+ results = []
407
+ for r in raw_results:
408
+ if r.get('score', 0) < 0.2:
409
+ continue
410
+ content = r.get('content', '') or r.get('summary', '') or ''
411
+ snippet = content[:200] + "..." if len(content) > 200 else content
412
+ mem_id = str(r.get('id', ''))
413
+ title = r.get('category', 'Memory') + ': ' + (content[:60].replace('\n', ' ') if content else 'Untitled')
414
+ results.append({
415
+ "id": mem_id,
416
+ "title": title,
417
+ "text": snippet,
418
+ "url": f"memory://local/{mem_id}"
419
+ })
420
+
421
+ return {"results": results}
422
+
423
+ except Exception as e:
424
+ return {"results": [], "error": str(e)}
425
+
426
+
427
+ @mcp.tool(annotations=ToolAnnotations(
428
+ readOnlyHint=True,
429
+ destructiveHint=False,
430
+ openWorldHint=False,
431
+ ))
432
+ async def fetch(id: str) -> dict:
433
+ """
434
+ Retrieve full content of a memory by ID.
435
+
436
+ Required by ChatGPT Connectors and Deep Research.
437
+ Use after search() to get complete document content for analysis and citation.
438
+
439
+ Args:
440
+ id: Memory ID from search results.
441
+
442
+ Returns:
443
+ {"id": str, "title": str, "text": str, "url": str, "metadata": dict|null}
444
+ """
445
+ try:
446
+ store = MemoryStoreV2(DB_PATH)
447
+ mem = store.get_by_id(int(id))
448
+
449
+ if not mem:
450
+ raise ValueError(f"Memory with ID {id} not found")
451
+
452
+ content = mem.get('content', '') or mem.get('summary', '') or ''
453
+ title = (mem.get('category', 'Memory') or 'Memory') + ': ' + (content[:60].replace('\n', ' ') if content else 'Untitled')
454
+
455
+ metadata = {}
456
+ if mem.get('tags'):
457
+ metadata['tags'] = mem['tags']
458
+ if mem.get('project_name'):
459
+ metadata['project'] = mem['project_name']
460
+ if mem.get('importance'):
461
+ metadata['importance'] = mem['importance']
462
+ if mem.get('cluster_id'):
463
+ metadata['cluster_id'] = mem['cluster_id']
464
+ if mem.get('created_at'):
465
+ metadata['created_at'] = mem['created_at']
466
+
467
+ return {
468
+ "id": str(id),
469
+ "title": title,
470
+ "text": content,
471
+ "url": f"memory://local/{id}",
472
+ "metadata": metadata if metadata else None
473
+ }
474
+
475
+ except Exception as e:
476
+ raise ValueError(f"Failed to fetch memory {id}: {str(e)}")
477
+
478
+
377
479
  # ============================================================================
378
480
  # MCP RESOURCES (Data endpoints)
379
481
  # ============================================================================
@@ -532,9 +634,9 @@ if __name__ == "__main__":
532
634
  )
533
635
  parser.add_argument(
534
636
  "--transport",
535
- choices=["stdio", "http", "sse"],
637
+ choices=["stdio", "http", "sse", "streamable-http"],
536
638
  default="stdio",
537
- help="Transport method: stdio for local IDEs (default), http/sse for remote access"
639
+ help="Transport method: stdio for local IDEs (default), sse/streamable-http for ChatGPT and remote access"
538
640
  )
539
641
  parser.add_argument(
540
642
  "--port",
@@ -565,6 +667,8 @@ if __name__ == "__main__":
565
667
  print("MCP Tools Available:", file=sys.stderr)
566
668
  print(" - remember(content, tags, project, importance)", file=sys.stderr)
567
669
  print(" - recall(query, limit, min_score)", file=sys.stderr)
670
+ print(" - search(query) [ChatGPT Connector]", file=sys.stderr)
671
+ print(" - fetch(id) [ChatGPT Connector]", file=sys.stderr)
568
672
  print(" - list_recent(limit)", file=sys.stderr)
569
673
  print(" - get_status()", file=sys.stderr)
570
674
  print(" - build_graph()", file=sys.stderr)
@@ -588,8 +692,14 @@ if __name__ == "__main__":
588
692
  if args.transport == "stdio":
589
693
  # stdio transport for local IDEs (default)
590
694
  mcp.run(transport="stdio")
695
+ elif args.transport == "streamable-http":
696
+ # Streamable HTTP transport (recommended for ChatGPT 2026+)
697
+ print(f"Streamable HTTP server at http://localhost:{args.port}", file=sys.stderr)
698
+ print("ChatGPT setup: expose via ngrok, paste URL in Settings > Connectors", file=sys.stderr)
699
+ mcp.run(transport="streamable-http")
591
700
  else:
592
701
  # SSE transport for remote access (ChatGPT, web clients)
593
702
  # "http" is accepted as alias for "sse"
594
703
  print(f"HTTP/SSE server will be available at http://localhost:{args.port}", file=sys.stderr)
704
+ print("ChatGPT setup: expose via ngrok, paste URL in Settings > Connectors", file=sys.stderr)
595
705
  mcp.run(transport="sse")
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "superlocalmemory",
3
- "version": "2.3.4",
3
+ "version": "2.3.5",
4
4
  "description": "Your AI Finally Remembers You - Local-first intelligent memory system for AI assistants. Works with Claude, Cursor, Windsurf, VS Code/Copilot, Codex, and 16+ AI tools. 100% local, zero cloud dependencies.",
5
5
  "keywords": [
6
6
  "ai-memory",
@@ -18,7 +18,11 @@
18
18
  "claude-desktop",
19
19
  "ai-tools",
20
20
  "memory-extension",
21
- "local-ai"
21
+ "local-ai",
22
+ "chatgpt",
23
+ "chatgpt-connector",
24
+ "openai",
25
+ "deep-research"
22
26
  ],
23
27
  "author": {
24
28
  "name": "Varun Pratap Bhardwaj",