@plaud-ai/mcp 0.3.3 → 0.3.4

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.
@@ -13,11 +13,12 @@ var SKILLS_MARKER_START = "<!-- plaud-skills:start -->";
13
13
  var SKILLS_MARKER_END = "<!-- plaud-skills:end -->";
14
14
  function findNodeBinCommand(command) {
15
15
  const commandName = platform() === "win32" ? `${command}.cmd` : command;
16
+ const sibling = join(dirname(process.execPath), commandName);
17
+ if (existsSync(sibling)) return sibling;
16
18
  const found = spawnSync(platform() === "win32" ? "where" : "which", [commandName], { encoding: "utf-8" });
17
19
  const firstMatch = found.status === 0 ? found.stdout.split(/\r?\n/).find((line) => line.trim())?.trim() : void 0;
18
20
  if (firstMatch) return firstMatch;
19
- const sibling = join(dirname(process.execPath), commandName);
20
- return existsSync(sibling) ? sibling : commandName;
21
+ return commandName;
21
22
  }
22
23
  function isLocalPackageSpec(spec) {
23
24
  return spec.endsWith(".tgz") || spec.startsWith(".") || spec.startsWith("/") || /^[A-Za-z]:[\\/]/.test(spec);
@@ -35,6 +36,12 @@ function getMcpEntry() {
35
36
  args: ["-y", packageSpec]
36
37
  };
37
38
  }
39
+ function commandPathIsStale(command) {
40
+ if (!command) return false;
41
+ if (command.includes("fnm_multishells")) return true;
42
+ const isAbsolute = command.startsWith("/") || /^[A-Za-z]:[\\/]/.test(command);
43
+ return isAbsolute && !existsSync(command);
44
+ }
38
45
  function copyToClipboard(content) {
39
46
  if (platform() === "win32") {
40
47
  return spawnSync("clip", [], { input: content }).status === 0;
@@ -82,6 +89,7 @@ async function removeLegacySkillsBlock() {
82
89
 
83
90
  export {
84
91
  getMcpEntry,
92
+ commandPathIsStale,
85
93
  copyToClipboard,
86
94
  installSkillsToClaudeCode,
87
95
  removeSkillsFromClaudeCode
package/dist/index.js CHANGED
@@ -30,7 +30,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
30
30
  import open from "open";
31
31
  var server = new McpServer({
32
32
  name: "plaud",
33
- version: "0.3.3"
33
+ version: "0.3.4"
34
34
  });
35
35
  var CALLBACK_PORT = 8199;
36
36
  var LOGIN_TIMEOUT_MS = 12e4;
@@ -153,7 +153,7 @@ async function main() {
153
153
  const sub = process.argv[2];
154
154
  const sub2 = process.argv[3];
155
155
  if (sub === "install") {
156
- const { runInstall } = await import("./install-XCMWU6GQ.js");
156
+ const { runInstall } = await import("./install-ETBOS6SA.js");
157
157
  const args = process.argv.slice(3);
158
158
  const yes = args.some((a) => a === "--yes" || a === "-y");
159
159
  const noLogin = args.some((a) => a === "--no-login");
@@ -161,32 +161,32 @@ async function main() {
161
161
  return;
162
162
  }
163
163
  if (sub === "clean-plugin") {
164
- const { runCleanPlugin } = await import("./setup-N55HQZFZ.js");
164
+ const { runCleanPlugin } = await import("./setup-SMS45JC5.js");
165
165
  await runCleanPlugin();
166
166
  return;
167
167
  }
168
168
  if (sub === "setup" && sub2 === "codex") {
169
- const { runSetupCodex } = await import("./setup-N55HQZFZ.js");
169
+ const { runSetupCodex } = await import("./setup-SMS45JC5.js");
170
170
  await runSetupCodex();
171
171
  return;
172
172
  }
173
173
  if (sub === "unsetup" && sub2 === "codex") {
174
- const { runUnsetupCodex } = await import("./setup-N55HQZFZ.js");
174
+ const { runUnsetupCodex } = await import("./setup-SMS45JC5.js");
175
175
  await runUnsetupCodex();
176
176
  return;
177
177
  }
178
178
  if (sub === "setup") {
179
- const { runSetup } = await import("./setup-N55HQZFZ.js");
179
+ const { runSetup } = await import("./setup-SMS45JC5.js");
180
180
  await runSetup();
181
181
  return;
182
182
  }
183
183
  if (sub === "unsetup") {
184
- const { runUnsetup } = await import("./setup-N55HQZFZ.js");
184
+ const { runUnsetup } = await import("./setup-SMS45JC5.js");
185
185
  await runUnsetup();
186
186
  return;
187
187
  }
188
188
  if (sub === "http") {
189
- const { startHttpServer } = await import("./server-DDSU6DGR.js");
189
+ const { startHttpServer } = await import("./server-VVQEILKC.js");
190
190
  const { startMetricsServer } = await import("./server-NKCNUA6P.js");
191
191
  startMetricsServer();
192
192
  startHttpServer();
@@ -212,7 +212,7 @@ Usage:
212
212
  try {
213
213
  await initTelemetry({
214
214
  surface: "mcp",
215
- appVersion: "0.3.3",
215
+ appVersion: "0.3.4",
216
216
  transport: "stdio"
217
217
  });
218
218
  } catch {
@@ -2,10 +2,11 @@ import {
2
2
  getClient
3
3
  } from "./chunk-LOGKF7DL.js";
4
4
  import {
5
+ commandPathIsStale,
5
6
  copyToClipboard,
6
7
  getMcpEntry,
7
8
  installSkillsToClaudeCode
8
- } from "./chunk-WR565PER.js";
9
+ } from "./chunk-VHTXWQUE.js";
9
10
  import {
10
11
  skillsCombined
11
12
  } from "./chunk-242FRP4P.js";
@@ -84,12 +85,38 @@ import { existsSync as existsSync2 } from "fs";
84
85
  import { homedir as homedir2 } from "os";
85
86
  import { dirname, join as join2 } from "path";
86
87
  var RESTART_HINT2 = "Quit Codex Desktop and reopen it.";
88
+ var PLAUD_HEADER = "[mcp_servers.plaud]";
87
89
  function codexConfigPath() {
88
90
  return join2(homedir2(), ".codex", "config.toml");
89
91
  }
90
92
  function quoteTomlString(value) {
91
93
  return JSON.stringify(value);
92
94
  }
95
+ function plaudBlockRange(lines) {
96
+ const start = lines.findIndex((l) => l.trim() === PLAUD_HEADER);
97
+ if (start === -1) return null;
98
+ let end = lines.length;
99
+ for (let i = start + 1; i < lines.length; i++) {
100
+ if (/^\s*\[/.test(lines[i])) {
101
+ end = i;
102
+ break;
103
+ }
104
+ }
105
+ return { start, end };
106
+ }
107
+ function extractCommand(blockLines) {
108
+ for (const line of blockLines) {
109
+ const m = line.match(/^\s*command\s*=\s*("(?:[^"\\]|\\.)*")\s*$/);
110
+ if (m) {
111
+ try {
112
+ return JSON.parse(m[1]);
113
+ } catch {
114
+ return void 0;
115
+ }
116
+ }
117
+ }
118
+ return void 0;
119
+ }
93
120
  function codexAdapter() {
94
121
  return {
95
122
  id: "codex",
@@ -101,25 +128,38 @@ function codexAdapter() {
101
128
  async install({ entry }) {
102
129
  const configPath = codexConfigPath();
103
130
  const argsStr = entry.args.map(quoteTomlString).join(", ");
104
- const serverEntry = `
105
- [mcp_servers.plaud]
131
+ const blockBody = `${PLAUD_HEADER}
106
132
  command = ${quoteTomlString(entry.command)}
107
- args = [${argsStr}]
108
- `;
133
+ args = [${argsStr}]`;
109
134
  let content = "";
110
135
  try {
111
136
  content = await readFile(configPath, "utf-8");
112
137
  } catch {
113
138
  }
114
- if (content.includes("[mcp_servers.plaud]")) {
139
+ const lines = content.split("\n");
140
+ const range = plaudBlockRange(lines);
141
+ if (range) {
142
+ const existingCommand = extractCommand(lines.slice(range.start, range.end));
143
+ if (!commandPathIsStale(existingCommand)) {
144
+ return {
145
+ status: "already-configured",
146
+ message: "already configured",
147
+ restartHint: RESTART_HINT2
148
+ };
149
+ }
150
+ const rebuilt = [...lines.slice(0, range.start), ...blockBody.split("\n"), ...lines.slice(range.end)].join("\n");
151
+ await mkdir(dirname(configPath), { recursive: true });
152
+ await writeFile(configPath, rebuilt, "utf-8");
115
153
  return {
116
- status: "already-configured",
117
- message: "already configured",
154
+ status: "configured",
155
+ message: "repaired stale launch path (now stable npx @latest)",
118
156
  restartHint: RESTART_HINT2
119
157
  };
120
158
  }
121
159
  await mkdir(dirname(configPath), { recursive: true });
122
- await writeFile(configPath, content + serverEntry, "utf-8");
160
+ await writeFile(configPath, content + `
161
+ ${blockBody}
162
+ `, "utf-8");
123
163
  const combined = await skillsCombined();
124
164
  const copied = copyToClipboard(combined);
125
165
  return {
@@ -185,19 +225,21 @@ function jsonMcpServersAdapter(spec) {
185
225
  const servers = existingServers ?? {};
186
226
  const existing = servers[serverKey];
187
227
  if (existing) {
188
- if (entryAutoUpdates(existing)) {
228
+ const existingCommand = isJsonObject(existing) && typeof existing.command === "string" ? existing.command : void 0;
229
+ if (entryAutoUpdates(existing) && !commandPathIsStale(existingCommand)) {
189
230
  return {
190
231
  status: "already-configured",
191
232
  message: "already configured (npx @latest \u2014 auto-updates)",
192
233
  restartHint: spec.restartHint
193
234
  };
194
235
  }
236
+ const repairing = entryAutoUpdates(existing);
195
237
  config[rootKey] = { ...servers, [serverKey]: toEntry(ctx.entry) };
196
238
  await mkdir2(dirname2(configPath), { recursive: true });
197
239
  await writeFile2(configPath, JSON.stringify(config, null, 2), "utf-8");
198
240
  return {
199
241
  status: "configured",
200
- message: "migrated to npx @latest (was pinned/local \u2014 now auto-updates)",
242
+ message: repairing ? "repaired stale launch path (now stable npx @latest)" : "migrated to npx @latest (was pinned/local \u2014 now auto-updates)",
201
243
  restartHint: spec.restartHint
202
244
  };
203
245
  }
@@ -297,10 +339,13 @@ function zedAdapter() {
297
339
  return { status: "failed", message: `failed: ${configPath} field context_servers must be a JSON object.` };
298
340
  }
299
341
  const servers = existingServers ?? {};
300
- if (servers.plaud && entryAutoUpdates2(servers.plaud)) {
342
+ const existingPlaud = servers.plaud;
343
+ const existingPath = isJsonObject2(existingPlaud) && isJsonObject2(existingPlaud.command) && typeof existingPlaud.command.path === "string" ? existingPlaud.command.path : void 0;
344
+ if (existingPlaud && entryAutoUpdates2(existingPlaud) && !commandPathIsStale(existingPath)) {
301
345
  return { status: "already-configured", message: "already configured (npx @latest \u2014 auto-updates)", restartHint: RESTART_HINT3 };
302
346
  }
303
- const migrating = Boolean(servers.plaud);
347
+ const repairing = Boolean(existingPlaud) && entryAutoUpdates2(existingPlaud);
348
+ const migrating = Boolean(existingPlaud);
304
349
  config.context_servers = {
305
350
  ...servers,
306
351
  plaud: { command: { path: entry.command, args: entry.args } }
@@ -309,7 +354,7 @@ function zedAdapter() {
309
354
  await writeFile3(configPath, JSON.stringify(config, null, 2), "utf-8");
310
355
  return {
311
356
  status: "configured",
312
- message: migrating ? "migrated to npx @latest (was pinned/local \u2014 now auto-updates). Restart Zed." : "configured. Restart Zed to load the Plaud MCP.",
357
+ message: repairing ? "repaired stale launch path (now stable npx @latest). Restart Zed." : migrating ? "migrated to npx @latest (was pinned/local \u2014 now auto-updates). Restart Zed." : "configured. Restart Zed to load the Plaud MCP.",
313
358
  restartHint: RESTART_HINT3
314
359
  };
315
360
  }
@@ -1231,8 +1231,8 @@ function startHttpServer() {
1231
1231
  common: {
1232
1232
  serviceName: process.env.PLAUD_WAREHOUSE_SERVICE_NAME ?? "plaudmcp",
1233
1233
  // matches §1.3 key label `plaudmcp:TRACKING_KEY_PLAUDMCP`; confirm exact string with David
1234
- serviceVersion: "0.3.3",
1235
- buildId: "76e2306",
1234
+ serviceVersion: "0.3.4",
1235
+ buildId: "ce4457b",
1236
1236
  // mcp tsup TODO: inject git short SHA (like CLI)
1237
1237
  region: process.env.PLAUD_REGION ?? "US",
1238
1238
  env: process.env.PLAUD_ENV ?? process.env.NODE_ENV ?? "development"
@@ -1473,7 +1473,7 @@ function startHttpServer() {
1473
1473
  apiBase,
1474
1474
  staticToken: token
1475
1475
  });
1476
- const mcpServer = new McpServer({ name: "plaud", version: "0.3.3" });
1476
+ const mcpServer = new McpServer({ name: "plaud", version: "0.3.4" });
1477
1477
  registerTools(mcpServer, client, warehouseToolHooks);
1478
1478
  const transport = new StreamableHTTPServerTransport({
1479
1479
  sessionIdGenerator: void 0,
@@ -3,7 +3,7 @@ import {
3
3
  getMcpEntry,
4
4
  installSkillsToClaudeCode,
5
5
  removeSkillsFromClaudeCode
6
- } from "./chunk-WR565PER.js";
6
+ } from "./chunk-VHTXWQUE.js";
7
7
  import {
8
8
  skillsCombined
9
9
  } from "./chunk-242FRP4P.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plaud-ai/mcp",
3
- "version": "0.3.3",
3
+ "version": "0.3.4",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
package/plugin.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "plaud",
3
- "version": "0.3.3",
3
+ "version": "0.3.4",
4
4
  "description": "Access your Plaud recordings in Claude",
5
5
  "author": {
6
6
  "name": "Plaud AI"