@plaud-ai/mcp 0.2.4 → 0.3.0
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-BU3JMO4H.js +50 -0
- package/dist/chunk-MCKGQKYU.js +15 -0
- package/dist/chunk-NPCCDRWQ.js +10 -0
- package/dist/{chunk-BZOIX6WC.js → chunk-QXV7KYGD.js} +61 -7
- package/dist/chunk-RUFCT6DQ.js +60 -0
- package/dist/chunk-TPGKCGTQ.js +20687 -0
- package/dist/index.js +83 -15
- package/dist/{install-ALLWR7CL.js → install-2EIB7ZP3.js} +4 -2
- package/dist/server-BOR5EZLF.js +35 -0
- package/dist/{server-VY7ANVCH.js → server-ZVB7U2VZ.js} +32 -4
- package/dist/{setup-QXZHVVDP.js → setup-GLWZYNRW.js} +1 -0
- package/package.json +3 -1
- package/plugin.json +1 -1
- package/dist/chunk-3XRFIJUG.js +0 -352
- package/dist/chunk-GZ7QPRKV.js +0 -33
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import {
|
|
2
|
+
PlaudClient,
|
|
3
|
+
capture
|
|
4
|
+
} from "./chunk-TPGKCGTQ.js";
|
|
5
|
+
import {
|
|
6
|
+
httpClientDuration,
|
|
7
|
+
httpClientRequests
|
|
8
|
+
} from "./chunk-RUFCT6DQ.js";
|
|
9
|
+
|
|
10
|
+
// src/config.ts
|
|
11
|
+
function buildExtraHeaders() {
|
|
12
|
+
const headers = {};
|
|
13
|
+
if (process.env.PLAUD_ENV) headers["x-pld-env"] = process.env.PLAUD_ENV;
|
|
14
|
+
if (process.env.PLAUD_REGION) headers["x-pld-region"] = process.env.PLAUD_REGION;
|
|
15
|
+
return headers;
|
|
16
|
+
}
|
|
17
|
+
function normalizeEndpoint(path) {
|
|
18
|
+
return path.replace(/\/open\/third-party\/files\/[^/?]+/, "/open/third-party/files/:id").split("?")[0];
|
|
19
|
+
}
|
|
20
|
+
function recordUpstreamRequest(obs) {
|
|
21
|
+
const endpoint = normalizeEndpoint(obs.path);
|
|
22
|
+
httpClientRequests.inc({ host: obs.host, endpoint, status: String(obs.status) });
|
|
23
|
+
httpClientDuration.observe({ host: obs.host, endpoint }, obs.durationMs / 1e3);
|
|
24
|
+
}
|
|
25
|
+
var CONFIG = {
|
|
26
|
+
clientId: process.env.PLAUD_MCP_CLIENT_ID ?? process.env.PLAUD_CLIENT_ID ?? "client_9c501dad-8a0d-40b2-a7b0-d1cb8787f674",
|
|
27
|
+
clientSecret: process.env.PLAUD_CLIENT_SECRET ?? "",
|
|
28
|
+
redirectUri: "http://localhost:8199/auth/callback",
|
|
29
|
+
tokenFile: "tokens-mcp.json",
|
|
30
|
+
apiBase: process.env.PLAUD_API_BASE,
|
|
31
|
+
authorizationUrl: process.env.PLAUD_AUTH_URL,
|
|
32
|
+
tokenUrl: process.env.PLAUD_TOKEN_URL,
|
|
33
|
+
refreshUrl: process.env.PLAUD_REFRESH_URL,
|
|
34
|
+
extraHeaders: buildExtraHeaders(),
|
|
35
|
+
onRequest: recordUpstreamRequest,
|
|
36
|
+
// Background token refresh → passive telemetry event. CLI/stdio only:
|
|
37
|
+
// capture() no-ops in the HTTP server (which never inits frontend telemetry).
|
|
38
|
+
onTokenRefresh: (status, errorType) => capture(`auth:token_refresh:${status}`, { passive: true, ...errorType ? { error_type: errorType } : {} })
|
|
39
|
+
};
|
|
40
|
+
var client = null;
|
|
41
|
+
function getClient() {
|
|
42
|
+
if (!client) {
|
|
43
|
+
client = new PlaudClient(CONFIG);
|
|
44
|
+
}
|
|
45
|
+
return client;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export {
|
|
49
|
+
getClient
|
|
50
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
2
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
3
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
4
|
+
}) : x)(function(x) {
|
|
5
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
6
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
7
|
+
});
|
|
8
|
+
var __commonJS = (cb, mod) => function __require2() {
|
|
9
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export {
|
|
13
|
+
__require,
|
|
14
|
+
__commonJS
|
|
15
|
+
};
|
|
@@ -1,12 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
import {
|
|
2
|
+
capture,
|
|
3
|
+
classifyError
|
|
4
|
+
} from "./chunk-TPGKCGTQ.js";
|
|
5
|
+
import {
|
|
6
|
+
logger
|
|
7
|
+
} from "./chunk-NPCCDRWQ.js";
|
|
8
|
+
import {
|
|
9
|
+
mcpToolCalls,
|
|
10
|
+
mcpToolDuration
|
|
11
|
+
} from "./chunk-RUFCT6DQ.js";
|
|
7
12
|
|
|
8
13
|
// src/tools/index.ts
|
|
9
14
|
import { z } from "zod";
|
|
15
|
+
import { randomUUID } from "crypto";
|
|
10
16
|
var MAX_FILTER_PAGES = 5;
|
|
11
17
|
var FILTER_PAGE_SIZE = 100;
|
|
12
18
|
function parseDate(s) {
|
|
@@ -15,6 +21,38 @@ function parseDate(s) {
|
|
|
15
21
|
if (Number.isNaN(d.getTime())) return null;
|
|
16
22
|
return d.getTime();
|
|
17
23
|
}
|
|
24
|
+
function normalizeMcpHost(name) {
|
|
25
|
+
if (!name) return void 0;
|
|
26
|
+
const n = name.trim().toLowerCase();
|
|
27
|
+
if (!n) return void 0;
|
|
28
|
+
if (n === "claude-ai" || n.includes("claude desktop") || n.includes("claude-desktop")) return "claude_desktop";
|
|
29
|
+
if (n.includes("claude code") || n.includes("claude-code")) return "claude_code";
|
|
30
|
+
if (n.includes("cursor")) return "cursor";
|
|
31
|
+
if (n.includes("windsurf")) return "windsurf";
|
|
32
|
+
if (n.includes("cline")) return "cline";
|
|
33
|
+
if (n.includes("continue")) return "continue";
|
|
34
|
+
if (n.includes("vscode") || n.includes("vs code")) return "vscode";
|
|
35
|
+
return n;
|
|
36
|
+
}
|
|
37
|
+
function emitToolClick(tool, props = {}) {
|
|
38
|
+
const requestId = randomUUID();
|
|
39
|
+
capture("mcp:tool:click", { tool_name: tool, request_id: requestId, passive: false, ...props });
|
|
40
|
+
return requestId;
|
|
41
|
+
}
|
|
42
|
+
function recordToolMetric(tool, status, durationMs, requestId, props = {}, err) {
|
|
43
|
+
mcpToolCalls.inc({ tool, status });
|
|
44
|
+
mcpToolDuration.observe({ tool }, durationMs / 1e3);
|
|
45
|
+
const event = status === "success" ? "mcp:tool:success" : "mcp:tool:error";
|
|
46
|
+
const evProps = {
|
|
47
|
+
tool_name: tool,
|
|
48
|
+
request_id: requestId,
|
|
49
|
+
passive: true,
|
|
50
|
+
...props
|
|
51
|
+
};
|
|
52
|
+
if (status === "success") evProps.duration_ms = durationMs;
|
|
53
|
+
else evProps.error_type = classifyError(err);
|
|
54
|
+
capture(event, evProps);
|
|
55
|
+
}
|
|
18
56
|
function registerTools(server, client) {
|
|
19
57
|
server.registerTool(
|
|
20
58
|
"list_files",
|
|
@@ -38,9 +76,11 @@ function registerTools(server, client) {
|
|
|
38
76
|
const start = Date.now();
|
|
39
77
|
const hasFilter = Boolean(query || date_from || date_to);
|
|
40
78
|
logger.info({ event: "tool_call", tool: "list_files", has_filter: hasFilter });
|
|
79
|
+
const requestId = emitToolClick("list_files");
|
|
41
80
|
try {
|
|
42
81
|
if (!hasFilter) {
|
|
43
82
|
const result = await client.listFiles(page, page_size);
|
|
83
|
+
recordToolMetric("list_files", "success", Date.now() - start, requestId);
|
|
44
84
|
logger.info({ event: "tool_call_end", tool: "list_files", duration_ms: Date.now() - start });
|
|
45
85
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
46
86
|
}
|
|
@@ -68,6 +108,7 @@ function registerTools(server, client) {
|
|
|
68
108
|
if (items.length < FILTER_PAGE_SIZE) break;
|
|
69
109
|
if (p === MAX_FILTER_PAGES) truncated = true;
|
|
70
110
|
}
|
|
111
|
+
recordToolMetric("list_files", "success", Date.now() - start, requestId);
|
|
71
112
|
logger.info({ event: "tool_call_end", tool: "list_files", duration_ms: Date.now() - start, scanned, matched: matches.length, truncated });
|
|
72
113
|
return {
|
|
73
114
|
content: [{ type: "text", text: JSON.stringify({
|
|
@@ -79,6 +120,7 @@ function registerTools(server, client) {
|
|
|
79
120
|
}, null, 2) }]
|
|
80
121
|
};
|
|
81
122
|
} catch (err) {
|
|
123
|
+
recordToolMetric("list_files", "error", Date.now() - start, requestId, {}, err);
|
|
82
124
|
logger.error({ event: "tool_call_error", tool: "list_files", duration_ms: Date.now() - start, error: String(err) });
|
|
83
125
|
return { content: [{ type: "text", text: `Failed to list files: ${err}` }], isError: true };
|
|
84
126
|
}
|
|
@@ -99,11 +141,14 @@ function registerTools(server, client) {
|
|
|
99
141
|
async ({ file_id }) => {
|
|
100
142
|
const start = Date.now();
|
|
101
143
|
logger.info({ event: "tool_call", tool: "get_file", file_id });
|
|
144
|
+
const requestId = emitToolClick("get_file", { file_id });
|
|
102
145
|
try {
|
|
103
146
|
const file = await client.getFile(file_id);
|
|
147
|
+
recordToolMetric("get_file", "success", Date.now() - start, requestId, { file_id });
|
|
104
148
|
logger.info({ event: "tool_call_end", tool: "get_file", duration_ms: Date.now() - start });
|
|
105
149
|
return { content: [{ type: "text", text: JSON.stringify(file, null, 2) }] };
|
|
106
150
|
} catch (err) {
|
|
151
|
+
recordToolMetric("get_file", "error", Date.now() - start, requestId, { file_id }, err);
|
|
107
152
|
logger.error({ event: "tool_call_error", tool: "get_file", duration_ms: Date.now() - start, error: String(err) });
|
|
108
153
|
return { content: [{ type: "text", text: `Failed to get file: ${err}` }], isError: true };
|
|
109
154
|
}
|
|
@@ -124,11 +169,14 @@ function registerTools(server, client) {
|
|
|
124
169
|
async ({ file_id }) => {
|
|
125
170
|
const start = Date.now();
|
|
126
171
|
logger.info({ event: "tool_call", tool: "get_note", file_id });
|
|
172
|
+
const requestId = emitToolClick("get_note", { file_id });
|
|
127
173
|
try {
|
|
128
174
|
const file = await client.getFile(file_id);
|
|
175
|
+
recordToolMetric("get_note", "success", Date.now() - start, requestId, { file_id });
|
|
129
176
|
logger.info({ event: "tool_call_end", tool: "get_note", duration_ms: Date.now() - start });
|
|
130
177
|
return { content: [{ type: "text", text: JSON.stringify(file.note_list ?? [], null, 2) }] };
|
|
131
178
|
} catch (err) {
|
|
179
|
+
recordToolMetric("get_note", "error", Date.now() - start, requestId, { file_id }, err);
|
|
132
180
|
logger.error({ event: "tool_call_error", tool: "get_note", duration_ms: Date.now() - start, error: String(err) });
|
|
133
181
|
return { content: [{ type: "text", text: `Failed to get note: ${err}` }], isError: true };
|
|
134
182
|
}
|
|
@@ -149,11 +197,14 @@ function registerTools(server, client) {
|
|
|
149
197
|
async ({ file_id }) => {
|
|
150
198
|
const start = Date.now();
|
|
151
199
|
logger.info({ event: "tool_call", tool: "get_transcript", file_id });
|
|
200
|
+
const requestId = emitToolClick("get_transcript", { file_id });
|
|
152
201
|
try {
|
|
153
202
|
const file = await client.getFile(file_id);
|
|
203
|
+
recordToolMetric("get_transcript", "success", Date.now() - start, requestId, { file_id });
|
|
154
204
|
logger.info({ event: "tool_call_end", tool: "get_transcript", duration_ms: Date.now() - start });
|
|
155
205
|
return { content: [{ type: "text", text: JSON.stringify(file.source_list ?? [], null, 2) }] };
|
|
156
206
|
} catch (err) {
|
|
207
|
+
recordToolMetric("get_transcript", "error", Date.now() - start, requestId, { file_id }, err);
|
|
157
208
|
logger.error({ event: "tool_call_error", tool: "get_transcript", duration_ms: Date.now() - start, error: String(err) });
|
|
158
209
|
return { content: [{ type: "text", text: `Failed to get transcript: ${err}` }], isError: true };
|
|
159
210
|
}
|
|
@@ -173,11 +224,14 @@ function registerTools(server, client) {
|
|
|
173
224
|
async () => {
|
|
174
225
|
const start = Date.now();
|
|
175
226
|
logger.info({ event: "tool_call", tool: "get_current_user" });
|
|
227
|
+
const requestId = emitToolClick("get_current_user");
|
|
176
228
|
try {
|
|
177
229
|
const user = await client.getCurrentUser();
|
|
230
|
+
recordToolMetric("get_current_user", "success", Date.now() - start, requestId);
|
|
178
231
|
logger.info({ event: "tool_call_end", tool: "get_current_user", duration_ms: Date.now() - start });
|
|
179
232
|
return { content: [{ type: "text", text: JSON.stringify(user, null, 2) }] };
|
|
180
233
|
} catch (err) {
|
|
234
|
+
recordToolMetric("get_current_user", "error", Date.now() - start, requestId, {}, err);
|
|
181
235
|
logger.error({ event: "tool_call_error", tool: "get_current_user", duration_ms: Date.now() - start, error: String(err) });
|
|
182
236
|
return { content: [{ type: "text", text: `Failed to get user info: ${err}` }], isError: true };
|
|
183
237
|
}
|
|
@@ -186,6 +240,6 @@ function registerTools(server, client) {
|
|
|
186
240
|
}
|
|
187
241
|
|
|
188
242
|
export {
|
|
189
|
-
|
|
243
|
+
normalizeMcpHost,
|
|
190
244
|
registerTools
|
|
191
245
|
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// src/metrics/registry.ts
|
|
2
|
+
import { Registry, Counter, Histogram, Gauge, collectDefaultMetrics } from "prom-client";
|
|
3
|
+
var registry = new Registry();
|
|
4
|
+
collectDefaultMetrics({ register: registry });
|
|
5
|
+
var httpRequestDuration = new Histogram({
|
|
6
|
+
name: "http_request_duration_seconds",
|
|
7
|
+
help: "HTTP request latency in seconds",
|
|
8
|
+
labelNames: ["method", "handler", "status"],
|
|
9
|
+
buckets: [0.01, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10],
|
|
10
|
+
registers: [registry]
|
|
11
|
+
});
|
|
12
|
+
var httpRequestsInProgress = new Gauge({
|
|
13
|
+
name: "http_requests_in_progress",
|
|
14
|
+
help: "Number of in-progress HTTP requests",
|
|
15
|
+
labelNames: ["method", "handler"],
|
|
16
|
+
registers: [registry]
|
|
17
|
+
});
|
|
18
|
+
var mcpToolCalls = new Counter({
|
|
19
|
+
name: "mcp_tool_calls_total",
|
|
20
|
+
help: "MCP tool invocation count",
|
|
21
|
+
labelNames: ["tool", "status"],
|
|
22
|
+
registers: [registry]
|
|
23
|
+
});
|
|
24
|
+
var mcpToolDuration = new Histogram({
|
|
25
|
+
name: "mcp_tool_duration_seconds",
|
|
26
|
+
help: "MCP tool execution latency in seconds",
|
|
27
|
+
labelNames: ["tool"],
|
|
28
|
+
buckets: [0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10, 30],
|
|
29
|
+
registers: [registry]
|
|
30
|
+
});
|
|
31
|
+
var oauthTokenRefresh = new Counter({
|
|
32
|
+
name: "oauth_token_refresh_total",
|
|
33
|
+
help: "OAuth token refresh attempts grouped by outcome",
|
|
34
|
+
labelNames: ["result"],
|
|
35
|
+
registers: [registry]
|
|
36
|
+
});
|
|
37
|
+
var httpClientRequests = new Counter({
|
|
38
|
+
name: "http_client_requests_total",
|
|
39
|
+
help: "Outbound HTTP requests to upstream services",
|
|
40
|
+
labelNames: ["host", "endpoint", "status"],
|
|
41
|
+
registers: [registry]
|
|
42
|
+
});
|
|
43
|
+
var httpClientDuration = new Histogram({
|
|
44
|
+
name: "http_client_duration_seconds",
|
|
45
|
+
help: "Outbound HTTP request latency in seconds",
|
|
46
|
+
labelNames: ["host", "endpoint"],
|
|
47
|
+
buckets: [0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10],
|
|
48
|
+
registers: [registry]
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
export {
|
|
52
|
+
registry,
|
|
53
|
+
httpRequestDuration,
|
|
54
|
+
httpRequestsInProgress,
|
|
55
|
+
mcpToolCalls,
|
|
56
|
+
mcpToolDuration,
|
|
57
|
+
oauthTokenRefresh,
|
|
58
|
+
httpClientRequests,
|
|
59
|
+
httpClientDuration
|
|
60
|
+
};
|