@llmnesia/mcp 0.1.2 → 0.1.3

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
@@ -37,8 +37,11 @@ The installer:
37
37
  3. detects supported MCP clients you have (Claude Code, Claude Desktop,
38
38
  Cursor, and Codex), and
39
39
  4. registers that copy with each detected client — using the client's own CLI
40
- where available, or after a confirm prompt and backup for config files it
41
- edits.
40
+ where available, or with an automatic backup before editing its config file.
41
+
42
+ The `install` command is the approval to perform those setup steps. It does not
43
+ interrupt setup with a separate prompt for every detected app, and it never
44
+ prints existing client configurations or their credentials.
42
45
 
43
46
  Then **fully quit and reopen** your MCP client. Clients read their config once
44
47
  at startup, so reloading a window is not enough.
@@ -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.1.2" : "0.0.0-dev";
41
+ var VERSION = true ? "0.1.3" : "0.0.0-dev";
42
42
 
43
43
  export {
44
44
  __require,
@@ -15,7 +15,7 @@ import {
15
15
  __commonJS,
16
16
  __require,
17
17
  __toESM
18
- } from "./chunk-BQM5Q4XX.js";
18
+ } from "./chunk-EBVGUZX2.js";
19
19
 
20
20
  // ../node_modules/isexe/windows.js
21
21
  var require_windows = __commonJS({
@@ -609,7 +609,7 @@ function posixBrowsers(homeDir = home, forPlatform = osPlatform) {
609
609
  ["Chromium", join(base, "chromium")]
610
610
  ];
611
611
  }
612
- async function installPosix(manifestBase, hostPath) {
612
+ async function installPosix(manifestBase, hostPath, log) {
613
613
  const manifest = { ...manifestBase, path: hostPath };
614
614
  let installed = 0;
615
615
  for (const [label, browserDir] of posixBrowsers()) {
@@ -620,7 +620,7 @@ async function installPosix(manifestBase, hostPath) {
620
620
  await mkdir(dir, { recursive: true });
621
621
  await writeFile(join(dir, `${HOST_NAME}.json`), `${JSON.stringify(manifest, null, 2)}
622
622
  `, "utf8");
623
- console.log(`Manifest \u2192 ${label}: ${join(dir, `${HOST_NAME}.json`)}`);
623
+ log(`Manifest \u2192 ${label}: ${join(dir, `${HOST_NAME}.json`)}`);
624
624
  installed += 1;
625
625
  }
626
626
  return installed;
@@ -634,17 +634,17 @@ function windowsBrowsers() {
634
634
  ["Chromium", join(localAppData, "Chromium", "User Data"), "Software\\Chromium"]
635
635
  ];
636
636
  }
637
- async function installWindows(manifestBase, hostPath, installDir) {
637
+ async function installWindows(manifestBase, hostPath, installDir, log) {
638
638
  const batPath = join(installDir, "llmnesia-claude-host.bat");
639
639
  await writeFile(batPath, `@echo off\r
640
640
  "${process.execPath}" "${hostPath}" %*\r
641
641
  `, "utf8");
642
- console.log(`Launcher \u2192 ${batPath}`);
642
+ log(`Launcher \u2192 ${batPath}`);
643
643
  const manifest = { ...manifestBase, path: batPath };
644
644
  const manifestPath = join(installDir, `${HOST_NAME}.json`);
645
645
  await writeFile(manifestPath, `${JSON.stringify(manifest, null, 2)}
646
646
  `, "utf8");
647
- console.log(`Manifest \u2192 ${manifestPath}`);
647
+ log(`Manifest \u2192 ${manifestPath}`);
648
648
  let installed = 0;
649
649
  for (const [label, userDataDir, vendorKey] of windowsBrowsers()) {
650
650
  if (!await exists(userDataDir)) {
@@ -653,12 +653,14 @@ async function installWindows(manifestBase, hostPath, installDir) {
653
653
  const key = `HKCU\\${vendorKey}\\NativeMessagingHosts\\${HOST_NAME}`;
654
654
  const regExe = join(process.env.SystemRoot || "C:\\Windows", "System32", "reg.exe");
655
655
  await execFileAsync(regExe, ["add", key, "/ve", "/t", "REG_SZ", "/d", manifestPath, "/f"]);
656
- console.log(`Registry \u2192 ${label}: ${key}`);
656
+ log(`Registry \u2192 ${label}: ${key}`);
657
657
  installed += 1;
658
658
  }
659
659
  return installed;
660
660
  }
661
- async function installNativeHost({ ids = [], corpus, force = false } = {}) {
661
+ async function installNativeHost({ ids = [], corpus, force = false, quiet = false } = {}) {
662
+ const log = quiet ? () => {
663
+ } : console.log;
662
664
  const isWindows2 = osPlatform === "win32";
663
665
  const invalidId = ids.find((id) => !/^[a-p]{32}$/.test(id));
664
666
  if (invalidId) {
@@ -681,32 +683,32 @@ async function installNativeHost({ ids = [], corpus, force = false } = {}) {
681
683
  if (!isWindows2) {
682
684
  await chmod(hostPath, 493);
683
685
  }
684
- console.log(`Host script \u2192 ${hostPath}`);
686
+ log(`Host script \u2192 ${hostPath}`);
685
687
  const manifestBase = {
686
688
  name: HOST_NAME,
687
689
  description: "LLMnesia \u2014 reads local Claude Code sessions",
688
690
  type: "stdio",
689
691
  allowed_origins: allowedOrigins
690
692
  };
691
- const installedCount = isWindows2 ? await installWindows(manifestBase, hostPath, installDir) : await installPosix(manifestBase, hostPath);
693
+ const installedCount = isWindows2 ? await installWindows(manifestBase, hostPath, installDir, log) : await installPosix(manifestBase, hostPath, log);
692
694
  const corpusRoot = resolveCorpusDir2(corpus);
693
695
  const existingRoot = existing && typeof existing.corpusRoot === "string" ? existing.corpusRoot : null;
694
696
  let corpusRootChanged = true;
695
697
  if (existingRoot && existingRoot !== corpusRoot && !force) {
696
698
  corpusRootChanged = false;
697
- console.log(`Corpus config kept \u2192 ${configPath}`);
698
- console.log(` already points at: ${existingRoot}`);
699
- console.log(` to change it: re-run with --corpus <dir> --force`);
699
+ log(`Corpus config kept \u2192 ${configPath}`);
700
+ log(` already points at: ${existingRoot}`);
701
+ log(` to change it: re-run with --corpus <dir> --force`);
700
702
  } else {
701
703
  await writeFile(configPath, `${JSON.stringify({ corpusRoot }, null, 2)}
702
704
  `, { encoding: "utf8", mode: 384 });
703
705
  await chmod(configPath, 384);
704
- console.log(`Corpus config \u2192 ${configPath}`);
705
- console.log(` corpus root: ${corpusRoot}`);
706
+ log(`Corpus config \u2192 ${configPath}`);
707
+ log(` corpus root: ${corpusRoot}`);
706
708
  }
707
- console.log(`
709
+ log(`
708
710
  Done. Allowed extension id(s): ${allIds.join(", ")}`);
709
- console.log("Fully quit and reopen the browser, then open LLMnesia Settings.");
711
+ log("Fully quit and reopen the browser, then open LLMnesia Settings.");
710
712
  return {
711
713
  installedCount,
712
714
  allowedIds: allIds,
@@ -3006,8 +3008,9 @@ async function registerJsonClient(clientLabel, configPath, serve, confirm, now)
3006
3008
  if (already && JSON.stringify(already) === JSON.stringify(nextEntry)) {
3007
3009
  return { client: clientLabel, action: "skipped", detail: `Already registered at ${configPath}.` };
3008
3010
  }
3009
- const preview = JSON.stringify({ mcpServers: { ...servers, [SERVER_NAME]: nextEntry } }, null, 2);
3010
- const message = existed ? `${clientLabel}: update ${configPath} to add the "${SERVER_NAME}" MCP server?
3011
+ const preview = JSON.stringify({ mcpServers: { [SERVER_NAME]: nextEntry } }, null, 2);
3012
+ const message = existed ? `${clientLabel}: update ${configPath} to add the "${SERVER_NAME}" MCP server? Existing servers and settings are preserved.
3013
+ Add:
3011
3014
  ${preview}` : `${clientLabel}: create ${configPath} with the "${SERVER_NAME}" MCP server?
3012
3015
  ${preview}`;
3013
3016
  const ok = await confirm(message);
@@ -3594,7 +3597,7 @@ Options:
3594
3597
  --from <iso|ms> search: only conversations created on/after this date
3595
3598
  --to <iso|ms> search: only conversations created on/before this date
3596
3599
  --force install: overwrite a differing corpus root in config.json
3597
- --yes, -y install/uninstall: skip confirmation prompts
3600
+ --yes, -y uninstall: skip its confirmation prompt
3598
3601
  --version, -v print the version and exit
3599
3602
  `;
3600
3603
  function parseDate(value) {
@@ -3621,36 +3624,54 @@ ${message}
3621
3624
  }
3622
3625
  function printRegistrationResults(results) {
3623
3626
  for (const r of results) {
3624
- const icon = r.action === "registered" ? "\u2713" : r.action === "error" ? "\u2717" : "\u2022";
3625
- process.stdout.write(`${icon} ${r.client}: ${r.detail}
3626
-
3627
+ if (r.client.startsWith("Other MCP clients")) {
3628
+ continue;
3629
+ }
3630
+ if (r.action === "registered") {
3631
+ process.stdout.write(`\u2713 ${r.client}
3632
+ `);
3633
+ continue;
3634
+ }
3635
+ if (r.action === "skipped" && r.detail.startsWith("Already registered")) {
3636
+ process.stdout.write(`\u2713 ${r.client} (already configured)
3637
+ `);
3638
+ continue;
3639
+ }
3640
+ if (r.action === "error") {
3641
+ process.stderr.write(`\u2717 ${r.client}: ${r.detail}
3627
3642
  `);
3643
+ continue;
3644
+ }
3645
+ if (r.action === "printed") {
3646
+ process.stdout.write(`\u2022 ${r.client}: ${r.detail}
3647
+ `);
3648
+ }
3628
3649
  }
3629
3650
  }
3630
3651
  async function runInstall(positionals, options, flags) {
3631
- const skipConfirm = flags.has("yes");
3632
3652
  let hadProblems = false;
3633
- process.stdout.write("Installing native messaging host\u2026\n");
3653
+ process.stdout.write("Installing LLMnesia MCP\u2026\n");
3634
3654
  try {
3635
- await installNativeHost({ ids: positionals, corpus: options.corpus, force: flags.has("force") });
3655
+ const host = await installNativeHost({
3656
+ ids: positionals,
3657
+ corpus: options.corpus,
3658
+ force: flags.has("force"),
3659
+ quiet: true
3660
+ });
3661
+ process.stdout.write(`\u2713 Browser helper (${host.installedCount} browser${host.installedCount === 1 ? "" : "s"})
3662
+ `);
3636
3663
  } catch (err) {
3637
3664
  hadProblems = true;
3638
- process.stderr.write(`
3639
- Native host install failed: ${err instanceof Error ? err.message : String(err)}
3665
+ process.stderr.write(`\u2717 Browser helper: ${err instanceof Error ? err.message : String(err)}
3640
3666
  `);
3641
- process.stderr.write("Continuing to register MCP clients anyway \u2014 the server itself doesn't need a browser.\n");
3642
3667
  }
3643
- process.stdout.write("\nInstalling the MCP server runtime\u2026\n");
3644
3668
  const runtime = await installRuntime();
3645
- process.stdout.write(`Installed to ${runtime.binDir} (running on ${runtime.nodePath})
3646
- `);
3647
- process.stdout.write("\nRegistering MCP clients\u2026\n\n");
3648
- const confirm = skipConfirm ? async () => true : promptConfirm;
3649
- const results = await registerClients({ serve: runtime.serve, confirm });
3669
+ process.stdout.write("\u2713 MCP runtime\n");
3670
+ const results = await registerClients({ serve: runtime.serve, confirm: async () => true });
3650
3671
  printRegistrationResults(results);
3651
3672
  hadProblems ||= results.some((result) => result.action === "error");
3652
3673
  process.stdout.write(
3653
- "Next step: fully quit and reopen your MCP client (and your browser, if you\nuse the extension). Reloading a window is not enough \u2014 the config is read\nonce at startup.\n\nFor automatic browser-history sync, open LLMnesia Settings and click\n\u2018Enable automatic sync\u2019 once. Chrome requires that one permission click;\nthe existing-history backfill and future updates are automatic after it.\n\n"
3674
+ "\nDone. Fully quit and reopen your MCP apps (and browser) to load LLMnesia.\nFor browser-history sync, open LLMnesia Settings and click \u2018Enable automatic sync\u2019 once.\n"
3654
3675
  );
3655
3676
  process.stdout.write("Then run `npx -y @llmnesia/mcp@latest doctor` to check what's wired up.\n");
3656
3677
  if (hadProblems) {
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-BQM5Q4XX.js";
6
+ } from "./chunk-EBVGUZX2.js";
7
7
 
8
8
  // src/nodeVersion.ts
9
9
  var MINIMUM_NODE_VERSION = "22.13.0";
@@ -46,7 +46,7 @@ async function bootstrap() {
46
46
  process.stderr.write(unsupportedNodeMessage(process.versions.node));
47
47
  return 1;
48
48
  }
49
- const { main } = await import("./cli-CNIF4XT3.js");
49
+ const { main } = await import("./cli-JFZO44NP.js");
50
50
  return main();
51
51
  }
52
52
  bootstrap().then((code) => {
package/dist/mcp.js CHANGED
@@ -13,7 +13,7 @@ import {
13
13
  __commonJS,
14
14
  __export,
15
15
  __toESM
16
- } from "./chunk-BQM5Q4XX.js";
16
+ } from "./chunk-EBVGUZX2.js";
17
17
 
18
18
  // ../node_modules/ajv/dist/compile/codegen/code.js
19
19
  var require_code = __commonJS({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@llmnesia/mcp",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
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.2",
6
+ "version": "0.1.3",
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.2",
12
+ "version": "0.1.3",
13
13
  "transport": {
14
14
  "type": "stdio"
15
15
  }