@llmnesia/mcp 0.1.12 → 0.1.13
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 +44 -8
- package/dist/{chunk-MI5RBP7Y.js → chunk-7DAYOGB6.js} +1 -1
- package/dist/{cli-GKHVUCEP.js → cli-OJM47LQR.js} +23 -69
- package/dist/cli.js +2 -2
- package/dist/llmnesia.mcpb +0 -0
- package/dist/mcp.js +25 -23
- package/package.json +1 -1
- package/server.json +2 -2
package/README.md
CHANGED
|
@@ -48,19 +48,38 @@ The installer:
|
|
|
48
48
|
1. sets up the native host that bridges the browser extension to your local
|
|
49
49
|
corpus,
|
|
50
50
|
2. copies the server into `~/.llmnesia/bin` so it has a permanent home,
|
|
51
|
-
3. sets up the supported desktop AI apps (Claude Code,
|
|
51
|
+
3. sets up the supported desktop AI apps (Claude Code, Cursor,
|
|
52
52
|
and Codex/ChatGPT), and
|
|
53
53
|
4. registers that copy using the client's own CLI where available, or with an
|
|
54
54
|
automatic backup before editing its documented user config. It prepares all
|
|
55
55
|
of those standard config paths, so an app installed later does not require
|
|
56
56
|
running setup again.
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
58
|
+
Claude Desktop on Windows does not provide a supported API for third-party
|
|
59
|
+
installers to add a local desktop extension. LLMnesia therefore leaves any
|
|
60
|
+
existing Claude configuration untouched rather than claiming that Claude has
|
|
61
|
+
been connected.
|
|
62
|
+
|
|
63
|
+
### Claude Desktop on Windows (current one-time manual step)
|
|
64
|
+
|
|
65
|
+
Until LLMnesia is available in Claude's extension directory, Claude Desktop on
|
|
66
|
+
Windows has one extra, manual step. First run `install` above so the local
|
|
67
|
+
browser bridge and corpus exist. Then download the official LLMnesia
|
|
68
|
+
`llmnesia.mcpb` desktop-extension file from LLMnesia and use Claude Desktop's
|
|
69
|
+
**Settings → Extensions → Install extension** flow to install it. Fully quit
|
|
70
|
+
and reopen Claude Desktop afterwards.
|
|
71
|
+
|
|
72
|
+
This is deliberately separate from the npm command: Claude does not provide a
|
|
73
|
+
supported Windows API for another installer to silently add an `.mcpb`
|
|
74
|
+
extension. The command therefore never edits Claude's internal extension state
|
|
75
|
+
or reports a false success. The packaged extension itself is read-only: it can
|
|
76
|
+
search, list, and read the local corpus but cannot modify it.
|
|
77
|
+
|
|
78
|
+
The future Claude Directory listing is a convenience distribution route, not a
|
|
79
|
+
dependency for the general LLMnesia release. It will replace this one manual
|
|
80
|
+
Claude step with Claude's own in-app install button if Anthropic selects the
|
|
81
|
+
extension. See [`docs/CLAUDE_DESKTOP_RELEASE_PLAN.md`](../docs/CLAUDE_DESKTOP_RELEASE_PLAN.md)
|
|
82
|
+
for the release and directory-submission plan.
|
|
64
83
|
|
|
65
84
|
The `install` command is the approval to perform those setup steps. It does not
|
|
66
85
|
interrupt setup with a separate prompt for every detected app, and it never
|
|
@@ -128,7 +147,7 @@ received data — check it before concluding a chat does not exist.
|
|
|
128
147
|
| Client | How `install` wires it |
|
|
129
148
|
| --- | --- |
|
|
130
149
|
| Claude Code | Runs `claude mcp add --scope user` with the absolute Node and installed runtime paths when available. Otherwise it writes the documented user-scope `~/.claude.json` entry, so Windows users do not need the `claude` command on PATH. |
|
|
131
|
-
| Claude Desktop |
|
|
150
|
+
| Claude Desktop | macOS uses the working local JSON registration. On Windows, run `install` for browser sync, then install the official `llmnesia.mcpb` once in Claude Desktop; Claude exposes no supported external installation API for custom desktop extensions. |
|
|
132
151
|
| Cursor | Edits `~/.cursor/mcp.json`, preparing it in advance if Cursor is installed later. |
|
|
133
152
|
| Codex / ChatGPT desktop | Runs `codex mcp add` with the absolute runtime paths when available. If the bundled CLI is unavailable, the installer safely edits `~/.codex/config.toml` itself and backs up existing settings first, including preparing it for a later installation. Read-only LLMnesia tools are configured to run without repeated approval prompts; writes still ask. |
|
|
134
153
|
| Others (Windsurf, Zed, LM Studio, …) | Prints the generic stdio block for you to paste. |
|
|
@@ -185,6 +204,23 @@ llmnesia-mcp --version # print the installed version
|
|
|
185
204
|
|
|
186
205
|
Questions and bug reports: [hello@llmnesia.com](mailto:hello@llmnesia.com).
|
|
187
206
|
|
|
207
|
+
## Privacy Policy
|
|
208
|
+
|
|
209
|
+
The MCP server reads and writes only the LLMnesia corpus stored on the user's
|
|
210
|
+
own computer. It does not upload conversation content, titles, URLs, prompts,
|
|
211
|
+
responses, or search queries to LLMnesia or to any third party, and it makes no
|
|
212
|
+
analytics or advertising requests of its own.
|
|
213
|
+
|
|
214
|
+
The browser extension separately sends limited, non-content product analytics
|
|
215
|
+
to PostHog. Conversation data and MCP searches are excluded. The complete
|
|
216
|
+
policy explains collection, local storage, third-party processing, retention,
|
|
217
|
+
deletion, and contact details:
|
|
218
|
+
[LLMnesia Privacy Policy](https://www.llmnesia.com/privacy-policy).
|
|
219
|
+
|
|
220
|
+
The local MCP corpus remains on the device until the user deletes it. Running
|
|
221
|
+
`uninstall` deliberately leaves that corpus intact so uninstalling the helper
|
|
222
|
+
cannot accidentally destroy the user's history.
|
|
223
|
+
|
|
188
224
|
## License
|
|
189
225
|
|
|
190
226
|
MIT — see [LICENSE](./LICENSE).
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
__commonJS,
|
|
16
16
|
__require,
|
|
17
17
|
__toESM
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-7DAYOGB6.js";
|
|
19
19
|
|
|
20
20
|
// ../node_modules/isexe/windows.js
|
|
21
21
|
var require_windows = __commonJS({
|
|
@@ -41,15 +41,15 @@ var require_windows = __commonJS({
|
|
|
41
41
|
}
|
|
42
42
|
return false;
|
|
43
43
|
}
|
|
44
|
-
function checkStat(
|
|
45
|
-
if (!
|
|
44
|
+
function checkStat(stat6, path, options) {
|
|
45
|
+
if (!stat6.isSymbolicLink() && !stat6.isFile()) {
|
|
46
46
|
return false;
|
|
47
47
|
}
|
|
48
48
|
return checkPathExt(path, options);
|
|
49
49
|
}
|
|
50
50
|
function isexe(path, options, cb) {
|
|
51
|
-
fs.stat(path, function(er,
|
|
52
|
-
cb(er, er ? false : checkStat(
|
|
51
|
+
fs.stat(path, function(er, stat6) {
|
|
52
|
+
cb(er, er ? false : checkStat(stat6, path, options));
|
|
53
53
|
});
|
|
54
54
|
}
|
|
55
55
|
function sync(path, options) {
|
|
@@ -66,20 +66,20 @@ var require_mode = __commonJS({
|
|
|
66
66
|
isexe.sync = sync;
|
|
67
67
|
var fs = __require("fs");
|
|
68
68
|
function isexe(path, options, cb) {
|
|
69
|
-
fs.stat(path, function(er,
|
|
70
|
-
cb(er, er ? false : checkStat(
|
|
69
|
+
fs.stat(path, function(er, stat6) {
|
|
70
|
+
cb(er, er ? false : checkStat(stat6, options));
|
|
71
71
|
});
|
|
72
72
|
}
|
|
73
73
|
function sync(path, options) {
|
|
74
74
|
return checkStat(fs.statSync(path), options);
|
|
75
75
|
}
|
|
76
|
-
function checkStat(
|
|
77
|
-
return
|
|
76
|
+
function checkStat(stat6, options) {
|
|
77
|
+
return stat6.isFile() && checkMode(stat6, options);
|
|
78
78
|
}
|
|
79
|
-
function checkMode(
|
|
80
|
-
var mod =
|
|
81
|
-
var uid =
|
|
82
|
-
var gid =
|
|
79
|
+
function checkMode(stat6, options) {
|
|
80
|
+
var mod = stat6.mode;
|
|
81
|
+
var uid = stat6.uid;
|
|
82
|
+
var gid = stat6.gid;
|
|
83
83
|
var myUid = options.uid !== void 0 ? options.uid : process.getuid && process.getuid();
|
|
84
84
|
var myGid = options.gid !== void 0 ? options.gid : process.getgid && process.getgid();
|
|
85
85
|
var u = parseInt("100", 8);
|
|
@@ -251,8 +251,8 @@ var require_path_key = __commonJS({
|
|
|
251
251
|
"use strict";
|
|
252
252
|
var pathKey = (options = {}) => {
|
|
253
253
|
const environment = options.env || process.env;
|
|
254
|
-
const
|
|
255
|
-
if (
|
|
254
|
+
const platform4 = options.platform || process.platform;
|
|
255
|
+
if (platform4 !== "win32") {
|
|
256
256
|
return "PATH";
|
|
257
257
|
}
|
|
258
258
|
return Object.keys(environment).reverse().find((key) => key.toUpperCase() === "PATH") || "Path";
|
|
@@ -2439,8 +2439,8 @@ var FSWatcher = class extends EventEmitter {
|
|
|
2439
2439
|
}
|
|
2440
2440
|
return this._userIgnored(path, stats);
|
|
2441
2441
|
}
|
|
2442
|
-
_isntIgnored(path,
|
|
2443
|
-
return !this._isIgnored(path,
|
|
2442
|
+
_isntIgnored(path, stat6) {
|
|
2443
|
+
return !this._isIgnored(path, stat6);
|
|
2444
2444
|
}
|
|
2445
2445
|
/**
|
|
2446
2446
|
* Provides a set of common helpers and properties relating to symlink handling.
|
|
@@ -3259,14 +3259,11 @@ async function registerClients(options) {
|
|
|
3259
3259
|
);
|
|
3260
3260
|
if (claudeDesktop) {
|
|
3261
3261
|
if (osPlatform2 === "win32") {
|
|
3262
|
-
|
|
3263
|
-
|
|
3264
|
-
|
|
3265
|
-
|
|
3266
|
-
|
|
3267
|
-
detail: "Claude Desktop uses the packaged LLMnesia extension on Windows."
|
|
3268
|
-
}
|
|
3269
|
-
);
|
|
3262
|
+
results.push({
|
|
3263
|
+
client: "Claude Desktop",
|
|
3264
|
+
action: "skipped",
|
|
3265
|
+
detail: "Automatic Claude Desktop setup is not available on Windows; existing configuration was left unchanged."
|
|
3266
|
+
});
|
|
3270
3267
|
} else {
|
|
3271
3268
|
results.push(
|
|
3272
3269
|
await safe(
|
|
@@ -3788,36 +3785,6 @@ function formatDoctorReport(report) {
|
|
|
3788
3785
|
return report.checks.map((c) => `${icon[c.status]} ${c.name}: ${c.detail}`).join("\n");
|
|
3789
3786
|
}
|
|
3790
3787
|
|
|
3791
|
-
// src/claudeDesktopExtension.ts
|
|
3792
|
-
import { execFile as execFile3 } from "child_process";
|
|
3793
|
-
import { access as access2, stat as stat6 } from "fs/promises";
|
|
3794
|
-
import { homedir as homedir5, platform as platform4 } from "os";
|
|
3795
|
-
import { join as join7 } from "path";
|
|
3796
|
-
import { promisify as promisify3 } from "util";
|
|
3797
|
-
var execFileAsync3 = promisify3(execFile3);
|
|
3798
|
-
async function defaultOpenBundle(bundlePath) {
|
|
3799
|
-
await execFileAsync3("rundll32.exe", ["url.dll,FileProtocolHandler", bundlePath], { windowsHide: true });
|
|
3800
|
-
}
|
|
3801
|
-
async function promptClaudeDesktopExtension(options) {
|
|
3802
|
-
const home2 = options.home ?? homedir5();
|
|
3803
|
-
const osPlatform2 = options.osPlatform ?? platform4();
|
|
3804
|
-
const bundlePath = join7(options.binDir, "llmnesia.mcpb");
|
|
3805
|
-
if (osPlatform2 !== "win32") {
|
|
3806
|
-
return { status: "unsupported", bundlePath };
|
|
3807
|
-
}
|
|
3808
|
-
const appData = options.appData ?? process.env.APPDATA ?? join7(home2, "AppData", "Roaming");
|
|
3809
|
-
try {
|
|
3810
|
-
if (!(await stat6(join7(appData, "Claude"))).isDirectory()) {
|
|
3811
|
-
return { status: "not-installed", bundlePath };
|
|
3812
|
-
}
|
|
3813
|
-
} catch {
|
|
3814
|
-
return { status: "not-installed", bundlePath };
|
|
3815
|
-
}
|
|
3816
|
-
await access2(bundlePath);
|
|
3817
|
-
await (options.openBundle ?? defaultOpenBundle)(bundlePath);
|
|
3818
|
-
return { status: "opened", bundlePath };
|
|
3819
|
-
}
|
|
3820
|
-
|
|
3821
3788
|
// src/cli.ts
|
|
3822
3789
|
var USAGE = `llmnesia-mcp ${VERSION}
|
|
3823
3790
|
|
|
@@ -3890,7 +3857,7 @@ function summarizeClientRegistrations(results) {
|
|
|
3890
3857
|
return { connected, prepared, errors };
|
|
3891
3858
|
}
|
|
3892
3859
|
function formatInstallSuccess() {
|
|
3893
|
-
return "\nSetup complete.\nFully close and reopen your browser and any desktop AI app you use.\nLLMnesia will be available in
|
|
3860
|
+
return "\nSetup complete.\nFully close and reopen your browser and any desktop AI app you use.\nLLMnesia will be available in the desktop AI apps connected during setup.\nLLMnesia Settings will confirm when your history is ready.\n";
|
|
3894
3861
|
}
|
|
3895
3862
|
async function runInstall(positionals, options, flags) {
|
|
3896
3863
|
let hadProblems = false;
|
|
@@ -3929,19 +3896,6 @@ async function runInstall(positionals, options, flags) {
|
|
|
3929
3896
|
`);
|
|
3930
3897
|
}
|
|
3931
3898
|
hadProblems ||= registrations.errors.length > 0;
|
|
3932
|
-
if (process.platform === "win32") {
|
|
3933
|
-
try {
|
|
3934
|
-
const claude = await promptClaudeDesktopExtension({ binDir: runtime.binDir });
|
|
3935
|
-
if (claude.status === "opened") {
|
|
3936
|
-
process.stdout.write("Claude opened. Click Install to add LLMnesia.\n");
|
|
3937
|
-
}
|
|
3938
|
-
} catch (err) {
|
|
3939
|
-
process.stderr.write(
|
|
3940
|
-
`Claude Desktop needs one more step: open ${runtime.binDir}\\llmnesia.mcpb and click Install. (${err instanceof Error ? err.message : String(err)})
|
|
3941
|
-
`
|
|
3942
|
-
);
|
|
3943
|
-
}
|
|
3944
|
-
}
|
|
3945
3899
|
if (hadProblems) {
|
|
3946
3900
|
process.stderr.write("\nSetup needs attention. Fix the message above, then run the same command again.\n");
|
|
3947
3901
|
return 1;
|
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-7DAYOGB6.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-OJM47LQR.js");
|
|
145
145
|
return main();
|
|
146
146
|
}
|
|
147
147
|
bootstrap().then((code) => {
|
package/dist/llmnesia.mcpb
CHANGED
|
Binary file
|
package/dist/mcp.js
CHANGED
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
__commonJS,
|
|
14
14
|
__export,
|
|
15
15
|
__toESM
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-7DAYOGB6.js";
|
|
17
17
|
|
|
18
18
|
// ../node_modules/ajv/dist/compile/codegen/code.js
|
|
19
19
|
var require_code = __commonJS({
|
|
@@ -21632,28 +21632,30 @@ async function runServe() {
|
|
|
21632
21632
|
return jsonResult(status);
|
|
21633
21633
|
})
|
|
21634
21634
|
);
|
|
21635
|
-
|
|
21636
|
-
|
|
21637
|
-
|
|
21638
|
-
|
|
21639
|
-
|
|
21640
|
-
|
|
21641
|
-
|
|
21642
|
-
|
|
21643
|
-
|
|
21644
|
-
|
|
21645
|
-
|
|
21646
|
-
|
|
21647
|
-
|
|
21648
|
-
|
|
21649
|
-
|
|
21650
|
-
|
|
21651
|
-
|
|
21652
|
-
|
|
21653
|
-
|
|
21654
|
-
|
|
21655
|
-
|
|
21656
|
-
|
|
21635
|
+
if (process.env.LLMNESIA_READ_ONLY !== "1") {
|
|
21636
|
+
server.registerTool(
|
|
21637
|
+
"save_conversation",
|
|
21638
|
+
{
|
|
21639
|
+
title: "Save conversation",
|
|
21640
|
+
description: "Add or update a conversation in the user's local corpus. Provide platform, title, and the messages; identity is keyed on docId (or platform:sourceId), so re-saving the same conversation updates it in place.",
|
|
21641
|
+
inputSchema: saveConversationSchema.shape,
|
|
21642
|
+
annotations: {
|
|
21643
|
+
readOnlyHint: false,
|
|
21644
|
+
destructiveHint: false,
|
|
21645
|
+
idempotentHint: false,
|
|
21646
|
+
openWorldHint: false
|
|
21647
|
+
}
|
|
21648
|
+
},
|
|
21649
|
+
async (args) => withService(async (service2) => {
|
|
21650
|
+
try {
|
|
21651
|
+
const result = await service2.saveConversation(args);
|
|
21652
|
+
return jsonResult(result);
|
|
21653
|
+
} catch (err) {
|
|
21654
|
+
return errorResult(`save_conversation failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
21655
|
+
}
|
|
21656
|
+
})
|
|
21657
|
+
);
|
|
21658
|
+
}
|
|
21657
21659
|
server.server.oninitialized = () => service.start();
|
|
21658
21660
|
const transport = new StdioServerTransport();
|
|
21659
21661
|
await server.connect(transport);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@llmnesia/mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.13",
|
|
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.1.
|
|
6
|
+
"version": "0.1.13",
|
|
7
7
|
"packages": [
|
|
8
8
|
{
|
|
9
9
|
"registryType": "npm",
|
|
10
10
|
"registryBaseUrl": "https://registry.npmjs.org",
|
|
11
11
|
"identifier": "@llmnesia/mcp",
|
|
12
|
-
"version": "0.1.
|
|
12
|
+
"version": "0.1.13",
|
|
13
13
|
"transport": {
|
|
14
14
|
"type": "stdio"
|
|
15
15
|
}
|