@llmnesia/mcp 0.2.6 → 0.2.7
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/dist/{chunk-YRK2DRGG.js → chunk-CMQHGLAD.js} +1 -1
- package/dist/{chunk-HL5QE57W.js → chunk-O34A5U2L.js} +30 -9
- package/dist/{cli-DRB4DVH3.js → cli-XQUMZ3BU.js} +2 -2
- package/dist/cli.js +2 -2
- package/dist/llmnesia.mcpb +0 -0
- package/dist/mcp.js +23 -12
- package/package.json +1 -1
- package/server.json +2 -2
|
@@ -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-
|
|
6
|
+
} from "./chunk-CMQHGLAD.js";
|
|
7
7
|
|
|
8
8
|
// src/config.ts
|
|
9
9
|
import { readFileSync } from "fs";
|
|
@@ -47,7 +47,7 @@ function expandHome(p) {
|
|
|
47
47
|
import { join as join2 } from "path";
|
|
48
48
|
import { readdir } from "fs/promises";
|
|
49
49
|
import { createHash } from "crypto";
|
|
50
|
-
var INDEX_FORMAT_VERSION =
|
|
50
|
+
var INDEX_FORMAT_VERSION = 4;
|
|
51
51
|
function indexDbFilename(version) {
|
|
52
52
|
return version === 1 ? "llmnesia.db" : `llmnesia-v${version}.db`;
|
|
53
53
|
}
|
|
@@ -208,6 +208,8 @@ function canonicalConversationDoc(c) {
|
|
|
208
208
|
assignIfDefined(out, "origin", c.origin);
|
|
209
209
|
assignIfDefined(out, "accountId", c.accountId);
|
|
210
210
|
assignIfDefined(out, "accountLabel", c.accountLabel);
|
|
211
|
+
if (c.models && c.models.length > 0) out.models = [...c.models];
|
|
212
|
+
assignIfDefined(out, "modelMetadataUpdatedAt", c.modelMetadataUpdatedAt);
|
|
211
213
|
if (c.summary) {
|
|
212
214
|
out.summary = {
|
|
213
215
|
text: c.summary.text,
|
|
@@ -227,6 +229,7 @@ function canonicalMessageDoc(m) {
|
|
|
227
229
|
text: m.text
|
|
228
230
|
};
|
|
229
231
|
assignIfDefined(out, "formattedText", m.formattedText);
|
|
232
|
+
assignIfDefined(out, "model", m.model);
|
|
230
233
|
out.createdAt = m.createdAt;
|
|
231
234
|
out.updatedAt = m.updatedAt;
|
|
232
235
|
out.contentHash = m.contentHash;
|
|
@@ -904,6 +907,9 @@ function coerceMessage(docId, value) {
|
|
|
904
907
|
if (typeof m.formattedText === "string") {
|
|
905
908
|
message.formattedText = m.formattedText;
|
|
906
909
|
}
|
|
910
|
+
if (typeof m.model === "string" && m.model.trim()) {
|
|
911
|
+
message.model = m.model.trim();
|
|
912
|
+
}
|
|
907
913
|
if (typeof m.platformMessageId === "string") {
|
|
908
914
|
message.platformMessageId = m.platformMessageId;
|
|
909
915
|
} else if (m.platformMessageId === null) {
|
|
@@ -1008,7 +1014,8 @@ CREATE TABLE IF NOT EXISTS conversations (
|
|
|
1008
1014
|
preview TEXT NOT NULL,
|
|
1009
1015
|
pinned INTEGER NOT NULL,
|
|
1010
1016
|
accountId TEXT,
|
|
1011
|
-
accountLabel TEXT
|
|
1017
|
+
accountLabel TEXT,
|
|
1018
|
+
models TEXT
|
|
1012
1019
|
);
|
|
1013
1020
|
CREATE INDEX IF NOT EXISTS idx_conversations_platform ON conversations(platform);
|
|
1014
1021
|
CREATE INDEX IF NOT EXISTS idx_conversations_createdAt ON conversations(createdAt);
|
|
@@ -1082,8 +1089,8 @@ var SearchIndex = class {
|
|
|
1082
1089
|
deleteConversation: this.db.prepare("DELETE FROM conversations WHERE docId = ?"),
|
|
1083
1090
|
insertConversation: this.db.prepare(
|
|
1084
1091
|
`INSERT INTO conversations
|
|
1085
|
-
(docId, platform, title, url, createdAt, updatedAt, messageCount, preview, pinned, accountId, accountLabel)
|
|
1086
|
-
VALUES (@docId, @platform, @title, @url, @createdAt, @updatedAt, @messageCount, @preview, @pinned, @accountId, @accountLabel)`
|
|
1092
|
+
(docId, platform, title, url, createdAt, updatedAt, messageCount, preview, pinned, accountId, accountLabel, models)
|
|
1093
|
+
VALUES (@docId, @platform, @title, @url, @createdAt, @updatedAt, @messageCount, @preview, @pinned, @accountId, @accountLabel, @models)`
|
|
1087
1094
|
),
|
|
1088
1095
|
deleteMemoryFts: this.db.prepare("DELETE FROM memories_fts WHERE memoryId = ?"),
|
|
1089
1096
|
insertMemoryFts: this.db.prepare(
|
|
@@ -1127,14 +1134,16 @@ var SearchIndex = class {
|
|
|
1127
1134
|
const orderBy = sort === "oldest" ? "createdAt ASC, updatedAt ASC" : sort === "newest" ? "createdAt DESC, updatedAt DESC" : "updatedAt DESC, createdAt DESC";
|
|
1128
1135
|
const rows = this.db.prepare(
|
|
1129
1136
|
`SELECT docId, platform, title, url, createdAt, updatedAt, messageCount, preview, pinned,
|
|
1130
|
-
accountId, accountLabel
|
|
1137
|
+
accountId, accountLabel, models
|
|
1131
1138
|
FROM conversations ORDER BY ${orderBy} LIMIT ?`
|
|
1132
1139
|
).all(limit);
|
|
1133
1140
|
return rows.map((r) => {
|
|
1134
|
-
const { accountId, accountLabel, ...rest } = r;
|
|
1141
|
+
const { accountId, accountLabel, models, ...rest } = r;
|
|
1135
1142
|
const entry = { ...rest, pinned: r.pinned === 1 };
|
|
1136
1143
|
if (accountId) entry.accountId = accountId;
|
|
1137
1144
|
if (accountLabel) entry.accountLabel = accountLabel;
|
|
1145
|
+
const parsedModels = parseModels(models);
|
|
1146
|
+
if (parsedModels.length > 0) entry.models = parsedModels;
|
|
1138
1147
|
return entry;
|
|
1139
1148
|
});
|
|
1140
1149
|
}
|
|
@@ -1221,7 +1230,8 @@ var SearchIndex = class {
|
|
|
1221
1230
|
preview: conversation.preview ?? "",
|
|
1222
1231
|
pinned: conversation.pinned ? 1 : 0,
|
|
1223
1232
|
accountId: conversation.accountId ?? null,
|
|
1224
|
-
accountLabel: conversation.accountLabel ?? null
|
|
1233
|
+
accountLabel: conversation.accountLabel ?? null,
|
|
1234
|
+
models: conversation.models?.length ? JSON.stringify(conversation.models) : null
|
|
1225
1235
|
});
|
|
1226
1236
|
}
|
|
1227
1237
|
insertFtsRow(docId, msgIndex, role, text) {
|
|
@@ -1286,7 +1296,7 @@ var SearchIndex = class {
|
|
|
1286
1296
|
const sql = `
|
|
1287
1297
|
SELECT
|
|
1288
1298
|
c.docId, c.platform, c.title, c.url, c.createdAt, c.updatedAt,
|
|
1289
|
-
c.messageCount, c.preview, c.pinned, c.accountId, c.accountLabel,
|
|
1299
|
+
c.messageCount, c.preview, c.pinned, c.accountId, c.accountLabel, c.models,
|
|
1290
1300
|
m.msgIndex AS msgIndex, m.role AS role,
|
|
1291
1301
|
bm25(messages_fts) AS bm25
|
|
1292
1302
|
FROM messages_fts
|
|
@@ -1322,6 +1332,8 @@ var SearchIndex = class {
|
|
|
1322
1332
|
};
|
|
1323
1333
|
if (row.accountId) hit.accountId = row.accountId;
|
|
1324
1334
|
if (row.accountLabel) hit.accountLabel = row.accountLabel;
|
|
1335
|
+
const models = parseModels(row.models);
|
|
1336
|
+
if (models.length > 0) hit.models = models;
|
|
1325
1337
|
hits.push(hit);
|
|
1326
1338
|
if (hits.length >= limit) {
|
|
1327
1339
|
break;
|
|
@@ -1402,6 +1414,15 @@ function normalizeMatchRole(role) {
|
|
|
1402
1414
|
}
|
|
1403
1415
|
return role === "assistant" || role === "user" || role === "system" ? role : "unknown";
|
|
1404
1416
|
}
|
|
1417
|
+
function parseModels(value) {
|
|
1418
|
+
if (!value) return [];
|
|
1419
|
+
try {
|
|
1420
|
+
const parsed = JSON.parse(value);
|
|
1421
|
+
return Array.isArray(parsed) ? parsed.filter((model) => typeof model === "string" && model.trim().length > 0) : [];
|
|
1422
|
+
} catch {
|
|
1423
|
+
return [];
|
|
1424
|
+
}
|
|
1425
|
+
}
|
|
1405
1426
|
|
|
1406
1427
|
// src/storageMaintenance.ts
|
|
1407
1428
|
import { promises as fs4 } from "fs";
|
|
@@ -17,13 +17,13 @@ import {
|
|
|
17
17
|
runtimeBinDir,
|
|
18
18
|
staleIndexFiles,
|
|
19
19
|
uninstallRuntime
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-O34A5U2L.js";
|
|
21
21
|
import {
|
|
22
22
|
VERSION,
|
|
23
23
|
__commonJS,
|
|
24
24
|
__require,
|
|
25
25
|
__toESM
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-CMQHGLAD.js";
|
|
27
27
|
|
|
28
28
|
// ../node_modules/isexe/windows.js
|
|
29
29
|
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-
|
|
6
|
+
} from "./chunk-CMQHGLAD.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-
|
|
144
|
+
const { main } = await import("./cli-XQUMZ3BU.js");
|
|
145
145
|
return main();
|
|
146
146
|
}
|
|
147
147
|
bootstrap().then((code) => {
|
package/dist/llmnesia.mcpb
CHANGED
|
Binary file
|
package/dist/mcp.js
CHANGED
|
@@ -12,13 +12,13 @@ import {
|
|
|
12
12
|
resolveCorpusDir,
|
|
13
13
|
runAutomaticMaintenance,
|
|
14
14
|
scheduleSelfUpdate
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-O34A5U2L.js";
|
|
16
16
|
import {
|
|
17
17
|
VERSION,
|
|
18
18
|
__commonJS,
|
|
19
19
|
__export,
|
|
20
20
|
__toESM
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-CMQHGLAD.js";
|
|
22
22
|
|
|
23
23
|
// ../node_modules/ajv/dist/compile/codegen/code.js
|
|
24
24
|
var require_code = __commonJS({
|
|
@@ -21678,19 +21678,26 @@ var LazyResource = class {
|
|
|
21678
21678
|
function jsonResult(payload) {
|
|
21679
21679
|
return { content: [{ type: "text", text: JSON.stringify(payload, null, 2) }] };
|
|
21680
21680
|
}
|
|
21681
|
-
var SOURCE_LINK_INSTRUCTION = "When answering from these conversations, always include a Sources section with a clickable Markdown link to every chat you relied on. Link its `sourceUrl`: this is the original chat URL when available, otherwise
|
|
21681
|
+
var SOURCE_LINK_INSTRUCTION = "When answering from these conversations, always include a Sources section with a clickable Markdown link to every chat you relied on. Link its `sourceUrl`: this is the original chat URL when available, otherwise an HTTPS hand-off that opens the local LLMnesia Viewer without sending the conversation id to the website. Do this automatically; do not wait for the user to ask for links.";
|
|
21682
21682
|
var STORE_EXTENSION_ID = "leekfgbdojiaabifbjbbgiiclannjdkf";
|
|
21683
21683
|
var EXTENSION_ID_RE = /^[a-p]{32}$/;
|
|
21684
|
+
var VIEWER_HANDOFF_URL = "https://llmnesia.com/open";
|
|
21684
21685
|
function viewerExtensionId() {
|
|
21685
21686
|
const configured = process.env.LLMNESIA_VIEWER_EXTENSION_ID?.trim() ?? readNativeHostViewerExtensionId();
|
|
21686
21687
|
return configured && EXTENSION_ID_RE.test(configured) ? configured : STORE_EXTENSION_ID;
|
|
21687
21688
|
}
|
|
21688
|
-
function
|
|
21689
|
-
|
|
21689
|
+
function viewerSourceUrl(docId, extensionId) {
|
|
21690
|
+
const fragment = new URLSearchParams({ docId, extensionId });
|
|
21691
|
+
return `${VIEWER_HANDOFF_URL}#${fragment.toString()}`;
|
|
21690
21692
|
}
|
|
21691
21693
|
function sourceLinks(docId, originalUrl) {
|
|
21692
|
-
const
|
|
21693
|
-
|
|
21694
|
+
const extensionId = viewerExtensionId();
|
|
21695
|
+
const localViewerUrl = `chrome-extension://${extensionId}/viewer.html?docId=${encodeURIComponent(docId)}`;
|
|
21696
|
+
return originalUrl ? { viewerUrl: localViewerUrl, sourceUrl: originalUrl, sourceKind: "original" } : {
|
|
21697
|
+
viewerUrl: localViewerUrl,
|
|
21698
|
+
sourceUrl: viewerSourceUrl(docId, extensionId),
|
|
21699
|
+
sourceKind: "viewer"
|
|
21700
|
+
};
|
|
21694
21701
|
}
|
|
21695
21702
|
function sourcedJsonResult(payload) {
|
|
21696
21703
|
return jsonResult({ responseInstruction: SOURCE_LINK_INSTRUCTION, ...payload });
|
|
@@ -21757,14 +21764,14 @@ async function runServe() {
|
|
|
21757
21764
|
const server = new McpServer(
|
|
21758
21765
|
{ name: "llmnesia", version: VERSION },
|
|
21759
21766
|
{
|
|
21760
|
-
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 chats you used. Link each result's `sourceUrl`, which is its original URL when available or its local LLMnesia Viewer
|
|
21767
|
+
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 chats you used. Link each result's `sourceUrl`, which is its original URL when available or a clickable HTTPS hand-off to its local LLMnesia Viewer otherwise; never wait for the user to ask."
|
|
21761
21768
|
}
|
|
21762
21769
|
);
|
|
21763
21770
|
server.registerTool(
|
|
21764
21771
|
"search_conversations",
|
|
21765
21772
|
{
|
|
21766
21773
|
title: "Search conversations",
|
|
21767
|
-
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 `sourceUrl`: the original chat URL when available, otherwise its local LLMnesia Viewer
|
|
21774
|
+
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 `sourceUrl`: the original chat URL when available, otherwise a clickable HTTPS hand-off to its local LLMnesia Viewer. Always link the chats used in the answer.",
|
|
21768
21775
|
inputSchema: {
|
|
21769
21776
|
query: external_exports.string().describe("Search terms (natural words; FTS operators are not needed)."),
|
|
21770
21777
|
match_mode: external_exports.enum(["any", "all", "phrase"]).optional().describe(
|
|
@@ -21813,6 +21820,7 @@ async function runServe() {
|
|
|
21813
21820
|
};
|
|
21814
21821
|
if (h.accountId) entry.accountId = h.accountId;
|
|
21815
21822
|
if (h.accountLabel) entry.accountLabel = h.accountLabel;
|
|
21823
|
+
if (h.models?.length) entry.models = h.models;
|
|
21816
21824
|
return entry;
|
|
21817
21825
|
})
|
|
21818
21826
|
});
|
|
@@ -21822,7 +21830,7 @@ async function runServe() {
|
|
|
21822
21830
|
"get_conversation",
|
|
21823
21831
|
{
|
|
21824
21832
|
title: "Get conversation",
|
|
21825
|
-
description: "Return the full transcript of one conversation by its id (the `id` from search results). The conversation includes `sourceUrl`: its original-chat URL when available, otherwise its local LLMnesia Viewer
|
|
21833
|
+
description: "Return the full transcript of one conversation by its id (the `id` from search results). The conversation includes `sourceUrl`: its original-chat URL when available, otherwise a clickable HTTPS hand-off to its local LLMnesia Viewer. Always link it in an answer based on this transcript.",
|
|
21826
21834
|
inputSchema: {
|
|
21827
21835
|
id: external_exports.string().describe("The conversation id (docId), e.g. 'claude:abc-123'.")
|
|
21828
21836
|
},
|
|
@@ -21846,6 +21854,7 @@ async function runServe() {
|
|
|
21846
21854
|
messages: record2.messages.map((m) => ({
|
|
21847
21855
|
index: m.msgIndex,
|
|
21848
21856
|
role: m.role,
|
|
21857
|
+
...m.model ? { model: m.model } : {},
|
|
21849
21858
|
// Prefer the block-formatted copy; fall back to the search-collapsed text.
|
|
21850
21859
|
text: m.formattedText ?? m.text
|
|
21851
21860
|
}))
|
|
@@ -21856,7 +21865,7 @@ async function runServe() {
|
|
|
21856
21865
|
"list_recent",
|
|
21857
21866
|
{
|
|
21858
21867
|
title: "List recent conversations",
|
|
21859
|
-
description: "List the user's most recently updated conversations (title + summary + source URL), newest first. `sourceUrl` is the original chat URL when available, otherwise its local LLMnesia Viewer
|
|
21868
|
+
description: "List the user's most recently updated conversations (title + summary + source URL), newest first. `sourceUrl` is the original chat URL when available, otherwise a clickable HTTPS hand-off to its local LLMnesia Viewer. Always link the chats used in the answer.",
|
|
21860
21869
|
inputSchema: {
|
|
21861
21870
|
limit: external_exports.number().int().min(1).max(100).optional().describe("How many to return (default 10).")
|
|
21862
21871
|
},
|
|
@@ -21887,6 +21896,7 @@ async function runServe() {
|
|
|
21887
21896
|
};
|
|
21888
21897
|
if (e.accountId) entry.accountId = e.accountId;
|
|
21889
21898
|
if (e.accountLabel) entry.accountLabel = e.accountLabel;
|
|
21899
|
+
if (e.models?.length) entry.models = e.models;
|
|
21890
21900
|
return entry;
|
|
21891
21901
|
})
|
|
21892
21902
|
});
|
|
@@ -21896,7 +21906,7 @@ async function runServe() {
|
|
|
21896
21906
|
"list_conversations",
|
|
21897
21907
|
{
|
|
21898
21908
|
title: "List conversations by date",
|
|
21899
|
-
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 `sourceUrl`: the original chat URL when available, otherwise the local LLMnesia Viewer
|
|
21909
|
+
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 `sourceUrl`: the original chat URL when available, otherwise a clickable HTTPS hand-off to the local LLMnesia Viewer. Always link the chats used in the answer.",
|
|
21900
21910
|
inputSchema: {
|
|
21901
21911
|
sort: external_exports.enum(["recent", "oldest", "newest"]).optional().describe("Chronology: recent (default, updated), oldest (created), or newest (created)."),
|
|
21902
21912
|
limit: external_exports.number().int().min(1).max(100).optional().describe("How many to return (default 10).")
|
|
@@ -21930,6 +21940,7 @@ async function runServe() {
|
|
|
21930
21940
|
};
|
|
21931
21941
|
if (e.accountId) entry.accountId = e.accountId;
|
|
21932
21942
|
if (e.accountLabel) entry.accountLabel = e.accountLabel;
|
|
21943
|
+
if (e.models?.length) entry.models = e.models;
|
|
21933
21944
|
return entry;
|
|
21934
21945
|
})
|
|
21935
21946
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@llmnesia/mcp",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.7",
|
|
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.",
|
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.
|
|
6
|
+
"version": "0.2.7",
|
|
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.
|
|
12
|
+
"version": "0.2.7",
|
|
13
13
|
"transport": {
|
|
14
14
|
"type": "stdio"
|
|
15
15
|
}
|