@plaud-ai/mcp 0.3.1 → 0.3.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.
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  PlaudClient,
3
3
  capture
4
- } from "./chunk-R5G6UXSI.js";
4
+ } from "./chunk-D2JZW2TW.js";
5
5
  import {
6
6
  httpClientDuration,
7
7
  httpClientRequests
@@ -1,9 +1,10 @@
1
1
  import {
2
- skillsCombined
3
- } from "./chunk-4QBEOJPX.js";
2
+ loadSkills,
3
+ skillsSourceDir
4
+ } from "./chunk-242FRP4P.js";
4
5
 
5
6
  // src/install-utils.ts
6
- import { readFile, writeFile, mkdir } from "fs/promises";
7
+ import { readFile, writeFile, mkdir, cp, rm } from "fs/promises";
7
8
  import { existsSync } from "fs";
8
9
  import { join, dirname } from "path";
9
10
  import { homedir, platform } from "os";
@@ -43,30 +44,28 @@ function copyToClipboard(content) {
43
44
  }
44
45
  return false;
45
46
  }
46
- async function writeSkillsToClaudeCode() {
47
- const claudeMdPath = join(homedir(), ".claude", "CLAUDE.md");
48
- const combined = await skillsCombined();
49
- const block = `${SKILLS_MARKER_START}
50
- ${combined}
51
- ${SKILLS_MARKER_END}`;
52
- let existing = "";
53
- try {
54
- existing = await readFile(claudeMdPath, "utf-8");
55
- } catch {
56
- }
57
- if (existing.includes(SKILLS_MARKER_START)) {
58
- const updated = existing.replace(
59
- new RegExp(`${SKILLS_MARKER_START}[\\s\\S]*?${SKILLS_MARKER_END}`),
60
- block
61
- );
62
- await mkdir(dirname(claudeMdPath), { recursive: true });
63
- await writeFile(claudeMdPath, updated, "utf-8");
64
- } else {
65
- await mkdir(dirname(claudeMdPath), { recursive: true });
66
- await writeFile(claudeMdPath, existing + (existing.endsWith("\n") ? "" : "\n") + block + "\n", "utf-8");
47
+ async function installSkillsToClaudeCode() {
48
+ const sourceDir = skillsSourceDir();
49
+ const skills = await loadSkills();
50
+ const destRoot = join(homedir(), ".claude", "skills");
51
+ await mkdir(destRoot, { recursive: true });
52
+ const installed = [];
53
+ for (const skill of skills) {
54
+ await cp(join(sourceDir, skill.dir), join(destRoot, skill.dir), { recursive: true, force: true });
55
+ installed.push(skill.name);
67
56
  }
57
+ await removeLegacySkillsBlock();
58
+ return installed;
68
59
  }
69
60
  async function removeSkillsFromClaudeCode() {
61
+ const destRoot = join(homedir(), ".claude", "skills");
62
+ const skills = await loadSkills();
63
+ for (const skill of skills) {
64
+ await rm(join(destRoot, skill.dir), { recursive: true, force: true }).catch(() => void 0);
65
+ }
66
+ await removeLegacySkillsBlock();
67
+ }
68
+ async function removeLegacySkillsBlock() {
70
69
  const claudeMdPath = join(homedir(), ".claude", "CLAUDE.md");
71
70
  let existing = "";
72
71
  try {
@@ -84,6 +83,6 @@ async function removeSkillsFromClaudeCode() {
84
83
  export {
85
84
  getMcpEntry,
86
85
  copyToClipboard,
87
- writeSkillsToClaudeCode,
86
+ installSkillsToClaudeCode,
88
87
  removeSkillsFromClaudeCode
89
88
  };
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  capture,
3
3
  classifyError
4
- } from "./chunk-R5G6UXSI.js";
4
+ } from "./chunk-D2JZW2TW.js";
5
5
  import {
6
6
  logger
7
7
  } from "./chunk-NPCCDRWQ.js";
@@ -13,6 +13,7 @@ import {
13
13
  // src/tools/index.ts
14
14
  import { z } from "zod";
15
15
  import { randomUUID } from "crypto";
16
+ var toolHooks = null;
16
17
  var MAX_FILTER_PAGES = 5;
17
18
  var FILTER_PAGE_SIZE = 100;
18
19
  function parseDate(s) {
@@ -37,6 +38,10 @@ function normalizeMcpHost(name) {
37
38
  function emitToolClick(tool, props = {}) {
38
39
  const requestId = randomUUID();
39
40
  capture("mcp:tool:click", { tool_name: tool, request_id: requestId, passive: false, ...props });
41
+ toolHooks?.onToolClick({
42
+ tool,
43
+ fileId: typeof props.file_id === "string" ? props.file_id : void 0
44
+ });
40
45
  return requestId;
41
46
  }
42
47
  function recordToolMetric(tool, status, durationMs, requestId, props = {}, err) {
@@ -52,8 +57,16 @@ function recordToolMetric(tool, status, durationMs, requestId, props = {}, err)
52
57
  if (status === "success") evProps.duration_ms = durationMs;
53
58
  else evProps.error_type = classifyError(err);
54
59
  capture(event, evProps);
60
+ toolHooks?.onToolResult({
61
+ tool,
62
+ status,
63
+ durationMs,
64
+ fileId: typeof props.file_id === "string" ? props.file_id : void 0,
65
+ failureKind: status === "error" ? classifyError(err) : void 0
66
+ });
55
67
  }
56
- function registerTools(server, client) {
68
+ function registerTools(server, client, hooks) {
69
+ toolHooks = hooks ?? null;
57
70
  server.registerTool(
58
71
  "list_files",
59
72
  {
package/dist/index.js CHANGED
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  getClient
4
- } from "./chunk-QJV4OLZI.js";
4
+ } from "./chunk-LOGKF7DL.js";
5
5
  import {
6
6
  loadSkills
7
- } from "./chunk-4QBEOJPX.js";
7
+ } from "./chunk-242FRP4P.js";
8
8
  import {
9
9
  normalizeMcpHost,
10
10
  registerTools
11
- } from "./chunk-XA77WLYF.js";
11
+ } from "./chunk-XWDA3G2U.js";
12
12
  import {
13
13
  capture,
14
14
  classifyError,
@@ -20,10 +20,9 @@ import {
20
20
  setMcpHost,
21
21
  setUser,
22
22
  shutdown
23
- } from "./chunk-R5G6UXSI.js";
23
+ } from "./chunk-D2JZW2TW.js";
24
24
  import "./chunk-NPCCDRWQ.js";
25
25
  import "./chunk-RUFCT6DQ.js";
26
- import "./chunk-MCKGQKYU.js";
27
26
 
28
27
  // src/index.ts
29
28
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
@@ -31,7 +30,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
31
30
  import open from "open";
32
31
  var server = new McpServer({
33
32
  name: "plaud",
34
- version: "0.3.1"
33
+ version: "0.3.3"
35
34
  });
36
35
  var CALLBACK_PORT = 8199;
37
36
  var LOGIN_TIMEOUT_MS = 12e4;
@@ -154,7 +153,7 @@ async function main() {
154
153
  const sub = process.argv[2];
155
154
  const sub2 = process.argv[3];
156
155
  if (sub === "install") {
157
- const { runInstall } = await import("./install-42GM4XUO.js");
156
+ const { runInstall } = await import("./install-XCMWU6GQ.js");
158
157
  const args = process.argv.slice(3);
159
158
  const yes = args.some((a) => a === "--yes" || a === "-y");
160
159
  const noLogin = args.some((a) => a === "--no-login");
@@ -162,33 +161,33 @@ async function main() {
162
161
  return;
163
162
  }
164
163
  if (sub === "clean-plugin") {
165
- const { runCleanPlugin } = await import("./setup-GLWZYNRW.js");
164
+ const { runCleanPlugin } = await import("./setup-N55HQZFZ.js");
166
165
  await runCleanPlugin();
167
166
  return;
168
167
  }
169
168
  if (sub === "setup" && sub2 === "codex") {
170
- const { runSetupCodex } = await import("./setup-GLWZYNRW.js");
169
+ const { runSetupCodex } = await import("./setup-N55HQZFZ.js");
171
170
  await runSetupCodex();
172
171
  return;
173
172
  }
174
173
  if (sub === "unsetup" && sub2 === "codex") {
175
- const { runUnsetupCodex } = await import("./setup-GLWZYNRW.js");
174
+ const { runUnsetupCodex } = await import("./setup-N55HQZFZ.js");
176
175
  await runUnsetupCodex();
177
176
  return;
178
177
  }
179
178
  if (sub === "setup") {
180
- const { runSetup } = await import("./setup-GLWZYNRW.js");
179
+ const { runSetup } = await import("./setup-N55HQZFZ.js");
181
180
  await runSetup();
182
181
  return;
183
182
  }
184
183
  if (sub === "unsetup") {
185
- const { runUnsetup } = await import("./setup-GLWZYNRW.js");
184
+ const { runUnsetup } = await import("./setup-N55HQZFZ.js");
186
185
  await runUnsetup();
187
186
  return;
188
187
  }
189
188
  if (sub === "http") {
190
- const { startHttpServer } = await import("./server-KBYYESVJ.js");
191
- const { startMetricsServer } = await import("./server-BOR5EZLF.js");
189
+ const { startHttpServer } = await import("./server-DDSU6DGR.js");
190
+ const { startMetricsServer } = await import("./server-NKCNUA6P.js");
192
191
  startMetricsServer();
193
192
  startHttpServer();
194
193
  return;
@@ -213,7 +212,7 @@ Usage:
213
212
  try {
214
213
  await initTelemetry({
215
214
  surface: "mcp",
216
- appVersion: "0.3.1",
215
+ appVersion: "0.3.3",
217
216
  transport: "stdio"
218
217
  });
219
218
  } catch {
@@ -1,19 +1,18 @@
1
1
  import {
2
2
  getClient
3
- } from "./chunk-QJV4OLZI.js";
3
+ } from "./chunk-LOGKF7DL.js";
4
4
  import {
5
5
  copyToClipboard,
6
6
  getMcpEntry,
7
- writeSkillsToClaudeCode
8
- } from "./chunk-QT25MKZJ.js";
7
+ installSkillsToClaudeCode
8
+ } from "./chunk-WR565PER.js";
9
9
  import {
10
10
  skillsCombined
11
- } from "./chunk-4QBEOJPX.js";
11
+ } from "./chunk-242FRP4P.js";
12
12
  import {
13
13
  runOAuthCallback
14
- } from "./chunk-R5G6UXSI.js";
14
+ } from "./chunk-D2JZW2TW.js";
15
15
  import "./chunk-RUFCT6DQ.js";
16
- import "./chunk-MCKGQKYU.js";
17
16
 
18
17
  // src/install.ts
19
18
  import { createInterface } from "readline/promises";
@@ -142,6 +141,11 @@ function isJsonObject(value) {
142
141
  function readErrorCode(err) {
143
142
  return isJsonObject(err) && typeof err.code === "string" ? err.code : void 0;
144
143
  }
144
+ function entryAutoUpdates(entry) {
145
+ if (!isJsonObject(entry)) return false;
146
+ const args = Array.isArray(entry.args) ? entry.args : [];
147
+ return args.some((a) => typeof a === "string" && a.includes("@plaud-ai/mcp@latest"));
148
+ }
145
149
  function jsonMcpServersAdapter(spec) {
146
150
  const rootKey = spec.rootKey ?? "mcpServers";
147
151
  const serverKey = spec.serverKey ?? "plaud";
@@ -179,10 +183,21 @@ function jsonMcpServersAdapter(spec) {
179
183
  return { status: "failed", message: `failed: ${configPath} field ${rootKey} must be a JSON object.` };
180
184
  }
181
185
  const servers = existingServers ?? {};
182
- if (servers[serverKey]) {
186
+ const existing = servers[serverKey];
187
+ if (existing) {
188
+ if (entryAutoUpdates(existing)) {
189
+ return {
190
+ status: "already-configured",
191
+ message: "already configured (npx @latest \u2014 auto-updates)",
192
+ restartHint: spec.restartHint
193
+ };
194
+ }
195
+ config[rootKey] = { ...servers, [serverKey]: toEntry(ctx.entry) };
196
+ await mkdir2(dirname2(configPath), { recursive: true });
197
+ await writeFile2(configPath, JSON.stringify(config, null, 2), "utf-8");
183
198
  return {
184
- status: "already-configured",
185
- message: "already configured",
199
+ status: "configured",
200
+ message: "migrated to npx @latest (was pinned/local \u2014 now auto-updates)",
186
201
  restartHint: spec.restartHint
187
202
  };
188
203
  }
@@ -249,6 +264,12 @@ function isJsonObject2(value) {
249
264
  function readErrorCode2(err) {
250
265
  return isJsonObject2(err) && typeof err.code === "string" ? err.code : void 0;
251
266
  }
267
+ function entryAutoUpdates2(existing) {
268
+ if (!isJsonObject2(existing)) return false;
269
+ const command = existing.command;
270
+ const args = isJsonObject2(command) && Array.isArray(command.args) ? command.args : [];
271
+ return args.some((a) => typeof a === "string" && a.includes("@plaud-ai/mcp@latest"));
272
+ }
252
273
  function zedAdapter() {
253
274
  return {
254
275
  id: "zed",
@@ -276,9 +297,10 @@ function zedAdapter() {
276
297
  return { status: "failed", message: `failed: ${configPath} field context_servers must be a JSON object.` };
277
298
  }
278
299
  const servers = existingServers ?? {};
279
- if (servers.plaud) {
280
- return { status: "already-configured", message: "already configured", restartHint: RESTART_HINT3 };
300
+ if (servers.plaud && entryAutoUpdates2(servers.plaud)) {
301
+ return { status: "already-configured", message: "already configured (npx @latest \u2014 auto-updates)", restartHint: RESTART_HINT3 };
281
302
  }
303
+ const migrating = Boolean(servers.plaud);
282
304
  config.context_servers = {
283
305
  ...servers,
284
306
  plaud: { command: { path: entry.command, args: entry.args } }
@@ -287,7 +309,7 @@ function zedAdapter() {
287
309
  await writeFile3(configPath, JSON.stringify(config, null, 2), "utf-8");
288
310
  return {
289
311
  status: "configured",
290
- message: "configured. Restart Zed to load the Plaud MCP.",
312
+ message: migrating ? "migrated to npx @latest (was pinned/local \u2014 now auto-updates). Restart Zed." : "configured. Restart Zed to load the Plaud MCP.",
291
313
  restartHint: RESTART_HINT3
292
314
  };
293
315
  }
@@ -514,8 +536,8 @@ async function runInstall(opts = {}) {
514
536
  if (succeeded.some((c) => c.id === "claude-code")) {
515
537
  process.stdout.write("\u2192 Claude Code skills... ");
516
538
  try {
517
- await writeSkillsToClaudeCode();
518
- console.log("written to ~/.claude/CLAUDE.md.");
539
+ const installed = await installSkillsToClaudeCode();
540
+ console.log(`installed ${installed.length} skill${installed.length === 1 ? "" : "s"} to ~/.claude/skills/.`);
519
541
  } catch (err) {
520
542
  console.log(`failed: ${err instanceof Error ? err.message : String(err)}`);
521
543
  }