@llmnesia/mcp 0.2.0 → 0.2.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
@@ -16,7 +16,22 @@ steps when the installed version is too old. If that happens in an interactive
16
16
  terminal, it offers the official Node.js installer through an OS-specific
17
17
  LLMnesia download link for you.
18
18
 
19
- ## Install
19
+ ## Recommended setup
20
+
21
+ Start in the LLMnesia browser extension so you do not miss the browser
22
+ permission, Node.js requirement, OS-specific command, restart, or the extra
23
+ Claude Desktop step on Windows:
24
+
25
+ 1. Install LLMnesia and import the chat history you want available.
26
+ 2. Open **Full settings → Connect desktop AI**.
27
+ 3. Follow every step shown for your computer, including fully quitting and
28
+ reopening the browser and connected AI app when instructed.
29
+
30
+ The commands below are the connector-install step from that guided flow. They
31
+ are also provided as a reference for technical users; running one by itself is
32
+ not the complete LLMnesia setup.
33
+
34
+ ### Connector command
20
35
 
21
36
  On macOS or Linux:
22
37
 
@@ -38,7 +38,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
38
38
  ));
39
39
 
40
40
  // src/version.ts
41
- var VERSION = true ? "0.2.0" : "0.0.0-dev";
41
+ var VERSION = true ? "0.2.2" : "0.0.0-dev";
42
42
 
43
43
  export {
44
44
  __require,
@@ -3,7 +3,7 @@ import { createRequire as __llmnesiaCreateRequire } from "node:module";
3
3
  const require = __llmnesiaCreateRequire(import.meta.url);
4
4
  import {
5
5
  VERSION
6
- } from "./chunk-ACIWPSVH.js";
6
+ } from "./chunk-5ZRNGUJL.js";
7
7
 
8
8
  // src/config.ts
9
9
  import { readFileSync } from "fs";
@@ -14,13 +14,13 @@ import {
14
14
  runtimeBinDir,
15
15
  staleIndexFiles,
16
16
  uninstallRuntime
17
- } from "./chunk-53KPHHH2.js";
17
+ } from "./chunk-LPGVZ7XY.js";
18
18
  import {
19
19
  VERSION,
20
20
  __commonJS,
21
21
  __require,
22
22
  __toESM
23
- } from "./chunk-ACIWPSVH.js";
23
+ } from "./chunk-5ZRNGUJL.js";
24
24
 
25
25
  // ../node_modules/isexe/windows.js
26
26
  var require_windows = __commonJS({
package/dist/cli.js CHANGED
@@ -3,7 +3,7 @@ import { createRequire as __llmnesiaCreateRequire } from "node:module";
3
3
  const require = __llmnesiaCreateRequire(import.meta.url);
4
4
  import {
5
5
  VERSION
6
- } from "./chunk-ACIWPSVH.js";
6
+ } from "./chunk-5ZRNGUJL.js";
7
7
 
8
8
  // src/nodeDownload.ts
9
9
  var NODE_DOWNLOAD_URLS = {
@@ -141,7 +141,7 @@ async function bootstrap() {
141
141
  await guideUnsupportedNodeVersion(process.versions.node);
142
142
  return 1;
143
143
  }
144
- const { main } = await import("./cli-VB4QKSGH.js");
144
+ const { main } = await import("./cli-SLGWH5Y2.js");
145
145
  return main();
146
146
  }
147
147
  bootstrap().then((code) => {
Binary file
package/dist/mcp.js CHANGED
@@ -9,13 +9,13 @@ import {
9
9
  pendingInboxFiles,
10
10
  resolveCorpusDir,
11
11
  scheduleSelfUpdate
12
- } from "./chunk-53KPHHH2.js";
12
+ } from "./chunk-LPGVZ7XY.js";
13
13
  import {
14
14
  VERSION,
15
15
  __commonJS,
16
16
  __export,
17
17
  __toESM
18
- } from "./chunk-ACIWPSVH.js";
18
+ } from "./chunk-5ZRNGUJL.js";
19
19
 
20
20
  // ../node_modules/ajv/dist/compile/codegen/code.js
21
21
  var require_code = __commonJS({
@@ -21602,6 +21602,10 @@ var LazyResource = class {
21602
21602
  function jsonResult(payload) {
21603
21603
  return { content: [{ type: "text", text: JSON.stringify(payload, null, 2) }] };
21604
21604
  }
21605
+ var SOURCE_LINK_INSTRUCTION = "When answering from these conversations, always include a Sources section with a clickable Markdown link to every original chat you relied on whose `url` is non-empty. Do this automatically; do not wait for the user to ask for links.";
21606
+ function sourcedJsonResult(payload) {
21607
+ return jsonResult({ responseInstruction: SOURCE_LINK_INSTRUCTION, ...payload });
21608
+ }
21605
21609
  function errorResult(message) {
21606
21610
  return { content: [{ type: "text", text: message }], isError: true };
21607
21611
  }
@@ -21648,14 +21652,14 @@ async function runServe() {
21648
21652
  const server = new McpServer(
21649
21653
  { name: "llmnesia", version: VERSION },
21650
21654
  {
21651
- instructions: "LLMnesia is the user's searchable archive of past AI chats. Whenever the user asks about 'my chats', 'my conversations', or anything they previously said, discussed, decided, or worked on, use LLMnesia before built-in task/thread lists, local file scans, or memory, unless they explicitly ask only about Codex tasks. Use list_conversations with sort='oldest' for their earliest chat, search_conversations to find relevant prior chats, get_conversation to read a full transcript, and list_recent to see what they worked on lately. Search and list results carry a `corpus` block saying when the corpus last received data; if a chat the user expects is missing, check corpus_status before concluding it does not exist."
21655
+ instructions: "LLMnesia is the user's searchable archive of past AI chats. Whenever the user asks about 'my chats', 'my conversations', or anything they previously said, discussed, decided, or worked on, use LLMnesia before built-in task/thread lists, local file scans, or memory, unless they explicitly ask only about Codex tasks. Use list_conversations with sort='oldest' for their earliest chat, search_conversations to find relevant prior chats, get_conversation to read a full transcript, and list_recent to see what they worked on lately. Search and list results carry a `corpus` block saying when the corpus last received data; if a chat the user expects is missing, check corpus_status before concluding it does not exist. Whenever you answer using LLMnesia, always include a Sources section with clickable links to the original chats you used when their `url` fields are non-empty; never wait for the user to ask."
21652
21656
  }
21653
21657
  );
21654
21658
  server.registerTool(
21655
21659
  "search_conversations",
21656
21660
  {
21657
21661
  title: "Search conversations",
21658
- description: "Full-text search across the user's past AI conversations. Call this whenever the user asks what they said, thought, discussed, decided, or worked on previously \u2014 even if the question doesn't say 'search' \u2014 rather than answering from conversation memory alone or claiming no record exists. Returns matching conversations with a highlighted snippet, ranked by relevance. Defaults to recall-first matching (any term); pass match_mode to answer questions where a wrong hit matters, such as whether or how often something was discussed.",
21662
+ description: "Full-text search across the user's past AI conversations. Call this whenever the user asks what they said, thought, discussed, decided, or worked on previously \u2014 even if the question doesn't say 'search' \u2014 rather than answering from conversation memory alone or claiming no record exists. Returns matching conversations with a highlighted snippet, ranked by relevance. Defaults to recall-first matching (any term); pass match_mode to answer questions where a wrong hit matters, such as whether or how often something was discussed. Every result includes its original-chat URL when available; always link the chats used in the answer.",
21659
21663
  inputSchema: {
21660
21664
  query: external_exports.string().describe("Search terms (natural words; FTS operators are not needed)."),
21661
21665
  match_mode: external_exports.enum(["any", "all", "phrase"]).optional().describe(
@@ -21685,7 +21689,7 @@ async function runServe() {
21685
21689
  };
21686
21690
  const hits = await service2.search(args.query, filters);
21687
21691
  const status = await service2.corpusStatus({ refresh: false });
21688
- return jsonResult({
21692
+ return sourcedJsonResult({
21689
21693
  count: hits.length,
21690
21694
  corpus: corpusField(status),
21691
21695
  results: hits.map((h) => {
@@ -21712,7 +21716,7 @@ async function runServe() {
21712
21716
  "get_conversation",
21713
21717
  {
21714
21718
  title: "Get conversation",
21715
- description: "Return the full transcript of one conversation by its id (the `id` from search results).",
21719
+ description: "Return the full transcript of one conversation by its id (the `id` from search results). The conversation includes its original-chat URL when available; always link it in an answer based on this transcript.",
21716
21720
  inputSchema: {
21717
21721
  id: external_exports.string().describe("The conversation id (docId), e.g. 'claude:abc-123'.")
21718
21722
  },
@@ -21728,7 +21732,7 @@ async function runServe() {
21728
21732
  if (!record2) {
21729
21733
  return errorResult(`No conversation found with id '${args.id}'.`);
21730
21734
  }
21731
- return jsonResult({
21735
+ return sourcedJsonResult({
21732
21736
  conversation: record2.conversation,
21733
21737
  messages: record2.messages.map((m) => ({
21734
21738
  index: m.msgIndex,
@@ -21743,7 +21747,7 @@ async function runServe() {
21743
21747
  "list_recent",
21744
21748
  {
21745
21749
  title: "List recent conversations",
21746
- description: "List the user's most recently updated conversations (title + summary), newest first.",
21750
+ description: "List the user's most recently updated conversations (title + summary + original-chat URL), newest first. Always link the chats used in the answer.",
21747
21751
  inputSchema: {
21748
21752
  limit: external_exports.number().int().min(1).max(100).optional().describe("How many to return (default 10).")
21749
21753
  },
@@ -21757,7 +21761,7 @@ async function runServe() {
21757
21761
  async (args) => withService(async (service2) => {
21758
21762
  const entries = await service2.listRecent(args.limit ?? 10);
21759
21763
  const status = await service2.corpusStatus({ refresh: false });
21760
- return jsonResult({
21764
+ return sourcedJsonResult({
21761
21765
  count: entries.length,
21762
21766
  corpus: corpusField(status),
21763
21767
  conversations: entries.map((e) => {
@@ -21765,6 +21769,7 @@ async function runServe() {
21765
21769
  id: e.docId,
21766
21770
  title: e.title,
21767
21771
  platform: e.platform,
21772
+ url: e.url,
21768
21773
  updatedAt: e.updatedAt,
21769
21774
  messageCount: e.messageCount,
21770
21775
  pinned: e.pinned,
@@ -21781,7 +21786,7 @@ async function runServe() {
21781
21786
  "list_conversations",
21782
21787
  {
21783
21788
  title: "List conversations by date",
21784
- description: "List conversation metadata in chronological order. Use sort='oldest' for the user's earliest or oldest chat, sort='newest' for most recently created chats, and sort='recent' for most recently updated chats. This is the complete corpus chronology, so do not scan LLMnesia's private files with shell commands.",
21789
+ description: "List conversation metadata in chronological order. Use sort='oldest' for the user's earliest or oldest chat, sort='newest' for most recently created chats, and sort='recent' for most recently updated chats. This is the complete corpus chronology, so do not scan LLMnesia's private files with shell commands. Entries include original-chat URLs when available; always link the chats used in the answer.",
21785
21790
  inputSchema: {
21786
21791
  sort: external_exports.enum(["recent", "oldest", "newest"]).optional().describe("Chronology: recent (default, updated), oldest (created), or newest (created)."),
21787
21792
  limit: external_exports.number().int().min(1).max(100).optional().describe("How many to return (default 10).")
@@ -21796,7 +21801,7 @@ async function runServe() {
21796
21801
  async (args) => withService(async (service2) => {
21797
21802
  const entries = await service2.listConversations(args.limit ?? 10, args.sort ?? "recent");
21798
21803
  const status = await service2.corpusStatus({ refresh: false });
21799
- return jsonResult({
21804
+ return sourcedJsonResult({
21800
21805
  count: entries.length,
21801
21806
  sort: args.sort ?? "recent",
21802
21807
  corpus: corpusField(status),
@@ -21805,6 +21810,7 @@ async function runServe() {
21805
21810
  id: e.docId,
21806
21811
  title: e.title,
21807
21812
  platform: e.platform,
21813
+ url: e.url,
21808
21814
  createdAt: e.createdAt,
21809
21815
  updatedAt: e.updatedAt,
21810
21816
  messageCount: e.messageCount,
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@llmnesia/mcp",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "comment:mcpName": "The MCP Registry's ownership marker: it must equal server.json's `name`, and the namespace must match how you authenticate with mcp-publisher. `com.llmnesia/...` requires DNS auth (a TXT record on llmnesia.com) — see docs/MCP_INSTALLER_BOARD.md.",
7
7
  "mcpName": "com.llmnesia/mcp",
8
- "description": "LLMnesia MCP server + installer: search your own AI chat history from Claude Desktop, Claude Code, Cursor, Codex, and other MCP clients. Local-first, one command to set up.",
8
+ "description": "Search your LLMnesia chat history from Claude Desktop, Claude Code, Cursor, Codex, and other MCP clients. Local-first guided setup.",
9
9
  "keywords": [
10
10
  "mcp",
11
11
  "model-context-protocol",
package/server.json CHANGED
@@ -3,13 +3,13 @@
3
3
  "name": "com.llmnesia/mcp",
4
4
  "title": "LLMnesia",
5
5
  "description": "Search your AI chat history from Claude, Cursor, Codex, and other MCP clients.",
6
- "version": "0.2.0",
6
+ "version": "0.2.2",
7
7
  "packages": [
8
8
  {
9
9
  "registryType": "npm",
10
10
  "registryBaseUrl": "https://registry.npmjs.org",
11
11
  "identifier": "@llmnesia/mcp",
12
- "version": "0.2.0",
12
+ "version": "0.2.2",
13
13
  "transport": {
14
14
  "type": "stdio"
15
15
  }