@plaud-ai/mcp 0.3.3 → 0.3.5
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-D2JZW2TW.js → chunk-FDWRBOUI.js} +19 -0
- package/dist/{chunk-LOGKF7DL.js → chunk-SEOLTKA5.js} +1 -1
- package/dist/{chunk-WR565PER.js → chunk-VHTXWQUE.js} +10 -2
- package/dist/{chunk-XWDA3G2U.js → chunk-YI4KJEAG.js} +1 -1
- package/dist/index.js +18 -13
- package/dist/{install-XCMWU6GQ.js → install-OHOKLBHH.js} +61 -16
- package/dist/{server-DDSU6DGR.js → server-XUKJZCFN.js} +10 -35
- package/dist/{setup-N55HQZFZ.js → setup-SMS45JC5.js} +1 -1
- package/package.json +1 -1
- package/plugin.json +1 -1
|
@@ -82,6 +82,16 @@ var TokenStore = class {
|
|
|
82
82
|
};
|
|
83
83
|
|
|
84
84
|
// ../shared/dist/oauth.js
|
|
85
|
+
function clientUserIdFromAccessToken(token) {
|
|
86
|
+
if (!token)
|
|
87
|
+
return void 0;
|
|
88
|
+
try {
|
|
89
|
+
const payload = JSON.parse(Buffer.from(token.split(".")[1], "base64url").toString());
|
|
90
|
+
return typeof payload.sub === "string" && payload.sub.length > 0 ? payload.sub : void 0;
|
|
91
|
+
} catch {
|
|
92
|
+
return void 0;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
85
95
|
var DEFAULT_AUTHORIZATION_URL = "https://web.plaud.ai/platform/oauth";
|
|
86
96
|
var DEFAULT_TOKEN_URL = "https://platform.plaud.ai/developer/api/oauth/third-party/access-token";
|
|
87
97
|
var DEFAULT_REFRESH_URL = "https://platform.plaud.ai/developer/api/oauth/third-party/access-token/refresh";
|
|
@@ -497,6 +507,8 @@ var EMAIL_REGEX = /[\w.+-]+@[\w-]+\.[\w.-]+/;
|
|
|
497
507
|
var ALLOWED_PROPERTIES = /* @__PURE__ */ new Set([
|
|
498
508
|
// Global common properties (Plaud Common Event Properties + Spec §2)
|
|
499
509
|
"user_id",
|
|
510
|
+
"client_user_id",
|
|
511
|
+
// per-OAuth-client user id (JWT sub, `client_user_…`); DA common param across web/CLI/stdio/HTTP (Mirela 2026-06-29)
|
|
500
512
|
"member_id",
|
|
501
513
|
// fill-if-present; OAuth /users/current doesn't return it yet (Q16)
|
|
502
514
|
"workspace_id",
|
|
@@ -696,6 +708,7 @@ var state = {
|
|
|
696
708
|
memberId: null,
|
|
697
709
|
workspaceId: null,
|
|
698
710
|
role: null,
|
|
711
|
+
clientUserId: null,
|
|
699
712
|
mcpHost: null
|
|
700
713
|
};
|
|
701
714
|
async function initTelemetry(options) {
|
|
@@ -716,6 +729,7 @@ async function initTelemetry(options) {
|
|
|
716
729
|
state.memberId = identity?.memberId ?? null;
|
|
717
730
|
state.workspaceId = identity?.workspaceId ?? null;
|
|
718
731
|
state.role = identity?.role ?? null;
|
|
732
|
+
state.clientUserId = identity?.clientUserId ?? null;
|
|
719
733
|
state.currentDistinctId = identity?.idHash || userId || await getAnonymousId();
|
|
720
734
|
state.initialised = true;
|
|
721
735
|
}
|
|
@@ -727,6 +741,7 @@ async function setUser(userId, identity) {
|
|
|
727
741
|
state.memberId = identity?.memberId ?? null;
|
|
728
742
|
state.workspaceId = identity?.workspaceId ?? null;
|
|
729
743
|
state.role = identity?.role ?? null;
|
|
744
|
+
state.clientUserId = identity?.clientUserId ?? null;
|
|
730
745
|
if (state.surface) {
|
|
731
746
|
try {
|
|
732
747
|
await saveUserIdentity(state.surface, userId, identity);
|
|
@@ -752,6 +767,7 @@ async function clearUser() {
|
|
|
752
767
|
state.memberId = null;
|
|
753
768
|
state.workspaceId = null;
|
|
754
769
|
state.role = null;
|
|
770
|
+
state.clientUserId = null;
|
|
755
771
|
if (state.surface) {
|
|
756
772
|
try {
|
|
757
773
|
await clearUserIdentity(state.surface);
|
|
@@ -797,6 +813,8 @@ function buildCommonProperties() {
|
|
|
797
813
|
out.transport = state.transport;
|
|
798
814
|
if (state.currentUserId)
|
|
799
815
|
out.user_id = state.currentUserId;
|
|
816
|
+
if (state.clientUserId)
|
|
817
|
+
out.client_user_id = state.clientUserId;
|
|
800
818
|
if (state.memberId)
|
|
801
819
|
out.member_id = state.memberId;
|
|
802
820
|
if (state.workspaceId)
|
|
@@ -820,6 +838,7 @@ function extractIdentity(user) {
|
|
|
820
838
|
export {
|
|
821
839
|
classifyError,
|
|
822
840
|
oauthCallbackErrorType,
|
|
841
|
+
clientUserIdFromAccessToken,
|
|
823
842
|
PlaudClient,
|
|
824
843
|
runOAuthCallback,
|
|
825
844
|
shutdown,
|
|
@@ -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
|
-
|
|
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
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
getClient
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-SEOLTKA5.js";
|
|
5
5
|
import {
|
|
6
6
|
loadSkills
|
|
7
7
|
} from "./chunk-242FRP4P.js";
|
|
8
8
|
import {
|
|
9
9
|
normalizeMcpHost,
|
|
10
10
|
registerTools
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-YI4KJEAG.js";
|
|
12
12
|
import {
|
|
13
13
|
capture,
|
|
14
14
|
classifyError,
|
|
15
15
|
clearUser,
|
|
16
|
+
clientUserIdFromAccessToken,
|
|
16
17
|
extractIdentity,
|
|
17
18
|
initTelemetry,
|
|
18
19
|
oauthCallbackErrorType,
|
|
@@ -20,7 +21,7 @@ import {
|
|
|
20
21
|
setMcpHost,
|
|
21
22
|
setUser,
|
|
22
23
|
shutdown
|
|
23
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-FDWRBOUI.js";
|
|
24
25
|
import "./chunk-NPCCDRWQ.js";
|
|
25
26
|
import "./chunk-RUFCT6DQ.js";
|
|
26
27
|
|
|
@@ -30,7 +31,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
|
|
30
31
|
import open from "open";
|
|
31
32
|
var server = new McpServer({
|
|
32
33
|
name: "plaud",
|
|
33
|
-
version: "0.3.
|
|
34
|
+
version: "0.3.5"
|
|
34
35
|
});
|
|
35
36
|
var CALLBACK_PORT = 8199;
|
|
36
37
|
var LOGIN_TIMEOUT_MS = 12e4;
|
|
@@ -81,7 +82,11 @@ server.registerTool("login", {
|
|
|
81
82
|
try {
|
|
82
83
|
const user = await client.getCurrentUser();
|
|
83
84
|
if (user && typeof user.id === "string") {
|
|
84
|
-
await
|
|
85
|
+
const token = await client.auth.getAccessToken();
|
|
86
|
+
await setUser(user.id, {
|
|
87
|
+
...extractIdentity(user),
|
|
88
|
+
clientUserId: clientUserIdFromAccessToken(token)
|
|
89
|
+
});
|
|
85
90
|
}
|
|
86
91
|
} catch {
|
|
87
92
|
}
|
|
@@ -153,7 +158,7 @@ async function main() {
|
|
|
153
158
|
const sub = process.argv[2];
|
|
154
159
|
const sub2 = process.argv[3];
|
|
155
160
|
if (sub === "install") {
|
|
156
|
-
const { runInstall } = await import("./install-
|
|
161
|
+
const { runInstall } = await import("./install-OHOKLBHH.js");
|
|
157
162
|
const args = process.argv.slice(3);
|
|
158
163
|
const yes = args.some((a) => a === "--yes" || a === "-y");
|
|
159
164
|
const noLogin = args.some((a) => a === "--no-login");
|
|
@@ -161,32 +166,32 @@ async function main() {
|
|
|
161
166
|
return;
|
|
162
167
|
}
|
|
163
168
|
if (sub === "clean-plugin") {
|
|
164
|
-
const { runCleanPlugin } = await import("./setup-
|
|
169
|
+
const { runCleanPlugin } = await import("./setup-SMS45JC5.js");
|
|
165
170
|
await runCleanPlugin();
|
|
166
171
|
return;
|
|
167
172
|
}
|
|
168
173
|
if (sub === "setup" && sub2 === "codex") {
|
|
169
|
-
const { runSetupCodex } = await import("./setup-
|
|
174
|
+
const { runSetupCodex } = await import("./setup-SMS45JC5.js");
|
|
170
175
|
await runSetupCodex();
|
|
171
176
|
return;
|
|
172
177
|
}
|
|
173
178
|
if (sub === "unsetup" && sub2 === "codex") {
|
|
174
|
-
const { runUnsetupCodex } = await import("./setup-
|
|
179
|
+
const { runUnsetupCodex } = await import("./setup-SMS45JC5.js");
|
|
175
180
|
await runUnsetupCodex();
|
|
176
181
|
return;
|
|
177
182
|
}
|
|
178
183
|
if (sub === "setup") {
|
|
179
|
-
const { runSetup } = await import("./setup-
|
|
184
|
+
const { runSetup } = await import("./setup-SMS45JC5.js");
|
|
180
185
|
await runSetup();
|
|
181
186
|
return;
|
|
182
187
|
}
|
|
183
188
|
if (sub === "unsetup") {
|
|
184
|
-
const { runUnsetup } = await import("./setup-
|
|
189
|
+
const { runUnsetup } = await import("./setup-SMS45JC5.js");
|
|
185
190
|
await runUnsetup();
|
|
186
191
|
return;
|
|
187
192
|
}
|
|
188
193
|
if (sub === "http") {
|
|
189
|
-
const { startHttpServer } = await import("./server-
|
|
194
|
+
const { startHttpServer } = await import("./server-XUKJZCFN.js");
|
|
190
195
|
const { startMetricsServer } = await import("./server-NKCNUA6P.js");
|
|
191
196
|
startMetricsServer();
|
|
192
197
|
startHttpServer();
|
|
@@ -212,7 +217,7 @@ Usage:
|
|
|
212
217
|
try {
|
|
213
218
|
await initTelemetry({
|
|
214
219
|
surface: "mcp",
|
|
215
|
-
appVersion: "0.3.
|
|
220
|
+
appVersion: "0.3.5",
|
|
216
221
|
transport: "stdio"
|
|
217
222
|
});
|
|
218
223
|
} catch {
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getClient
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-SEOLTKA5.js";
|
|
4
4
|
import {
|
|
5
|
+
commandPathIsStale,
|
|
5
6
|
copyToClipboard,
|
|
6
7
|
getMcpEntry,
|
|
7
8
|
installSkillsToClaudeCode
|
|
8
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-VHTXWQUE.js";
|
|
9
10
|
import {
|
|
10
11
|
skillsCombined
|
|
11
12
|
} from "./chunk-242FRP4P.js";
|
|
12
13
|
import {
|
|
13
14
|
runOAuthCallback
|
|
14
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-FDWRBOUI.js";
|
|
15
16
|
import "./chunk-RUFCT6DQ.js";
|
|
16
17
|
|
|
17
18
|
// src/install.ts
|
|
@@ -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
|
|
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
|
-
|
|
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: "
|
|
117
|
-
message: "
|
|
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 +
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
normalizeMcpHost,
|
|
3
3
|
registerTools
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-YI4KJEAG.js";
|
|
5
5
|
import {
|
|
6
6
|
PlaudClient
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-FDWRBOUI.js";
|
|
8
8
|
import {
|
|
9
9
|
logger
|
|
10
10
|
} from "./chunk-NPCCDRWQ.js";
|
|
@@ -610,31 +610,6 @@ var PlaudOAuthProvider = class extends ProxyOAuthServerProvider {
|
|
|
610
610
|
});
|
|
611
611
|
res.redirect(target.toString());
|
|
612
612
|
}
|
|
613
|
-
/**
|
|
614
|
-
* Resolve the REAL Plaud user_id (the `/users/current` `id` field) from a fresh
|
|
615
|
-
* access token — the same id the CLI/stdio telemetry and the Plaud app use, so
|
|
616
|
-
* warehouse auth.* events join with tool events, subscription and frontend data.
|
|
617
|
-
* The JWT `sub` is only an OAuth pseudo-id (`client_user_…`), so we resolve via
|
|
618
|
-
* the API. Best-effort: on any failure fall back to the JWT sub, so the event
|
|
619
|
-
* still carries a stable id and the auth flow is never blocked.
|
|
620
|
-
*/
|
|
621
|
-
async resolveRealUserId(accessToken) {
|
|
622
|
-
if (!accessToken) return void 0;
|
|
623
|
-
try {
|
|
624
|
-
const client = new PlaudClient({
|
|
625
|
-
clientId: this._plaudClientId,
|
|
626
|
-
clientSecret: "",
|
|
627
|
-
redirectUri: "",
|
|
628
|
-
apiBase: this._plaudApiBase,
|
|
629
|
-
staticToken: accessToken
|
|
630
|
-
});
|
|
631
|
-
const user = await client.getCurrentUser();
|
|
632
|
-
const id = typeof user?.id === "string" ? user.id : void 0;
|
|
633
|
-
return id ?? subFromJwt(accessToken);
|
|
634
|
-
} catch {
|
|
635
|
-
return subFromJwt(accessToken);
|
|
636
|
-
}
|
|
637
|
-
}
|
|
638
613
|
// Override to use PKCE public-client flow — no Basic auth, client_id sent in body.
|
|
639
614
|
async exchangeAuthorizationCode(client, authorizationCode, codeVerifier, _redirectUri, resource) {
|
|
640
615
|
const failedAuth = (failureKind) => {
|
|
@@ -710,7 +685,7 @@ var PlaudOAuthProvider = class extends ProxyOAuthServerProvider {
|
|
|
710
685
|
throw new McpServerError("Token endpoint returned non-JSON response");
|
|
711
686
|
}
|
|
712
687
|
logger.info({ event: "oauth_token_exchange_ok", has_refresh_token: !!data.refresh_token });
|
|
713
|
-
const authorizedUserId =
|
|
688
|
+
const authorizedUserId = subFromJwt(data.access_token);
|
|
714
689
|
this._tracker?.track({
|
|
715
690
|
name: "auth.oauth_callback_success",
|
|
716
691
|
actorType: "user",
|
|
@@ -782,12 +757,11 @@ var PlaudOAuthProvider = class extends ProxyOAuthServerProvider {
|
|
|
782
757
|
throw new McpServerError("Refresh endpoint returned non-JSON response");
|
|
783
758
|
}
|
|
784
759
|
oauthTokenRefresh.inc({ result: "success" });
|
|
785
|
-
const refreshedUserId = await this.resolveRealUserId(data.access_token);
|
|
786
760
|
this._tracker?.track({
|
|
787
761
|
name: "auth.token_refresh_success",
|
|
788
762
|
actorType: "user",
|
|
789
|
-
userId:
|
|
790
|
-
distinctId:
|
|
763
|
+
userId: subFromJwt(data.access_token),
|
|
764
|
+
distinctId: subFromJwt(data.access_token) ?? client.client_id
|
|
791
765
|
});
|
|
792
766
|
logger.info({
|
|
793
767
|
event: "oauth_token_refresh_ok",
|
|
@@ -1231,8 +1205,8 @@ function startHttpServer() {
|
|
|
1231
1205
|
common: {
|
|
1232
1206
|
serviceName: process.env.PLAUD_WAREHOUSE_SERVICE_NAME ?? "plaudmcp",
|
|
1233
1207
|
// matches §1.3 key label `plaudmcp:TRACKING_KEY_PLAUDMCP`; confirm exact string with David
|
|
1234
|
-
serviceVersion: "0.3.
|
|
1235
|
-
buildId: "
|
|
1208
|
+
serviceVersion: "0.3.5",
|
|
1209
|
+
buildId: "38e7de5",
|
|
1236
1210
|
// mcp tsup TODO: inject git short SHA (like CLI)
|
|
1237
1211
|
region: process.env.PLAUD_REGION ?? "US",
|
|
1238
1212
|
env: process.env.PLAUD_ENV ?? process.env.NODE_ENV ?? "development"
|
|
@@ -1473,7 +1447,7 @@ function startHttpServer() {
|
|
|
1473
1447
|
apiBase,
|
|
1474
1448
|
staticToken: token
|
|
1475
1449
|
});
|
|
1476
|
-
const mcpServer = new McpServer({ name: "plaud", version: "0.3.
|
|
1450
|
+
const mcpServer = new McpServer({ name: "plaud", version: "0.3.5" });
|
|
1477
1451
|
registerTools(mcpServer, client, warehouseToolHooks);
|
|
1478
1452
|
const transport = new StreamableHTTPServerTransport({
|
|
1479
1453
|
sessionIdGenerator: void 0,
|
|
@@ -1481,7 +1455,8 @@ function startHttpServer() {
|
|
|
1481
1455
|
enableDnsRebindingProtection: true,
|
|
1482
1456
|
allowedOrigins: ALLOWED_ORIGINS
|
|
1483
1457
|
});
|
|
1484
|
-
const
|
|
1458
|
+
const fallbackClientId = req.auth.clientId && req.auth.clientId !== "unknown" ? req.auth.clientId : void 0;
|
|
1459
|
+
const ctxUserId = subFromJwt(token) ?? fallbackClientId;
|
|
1485
1460
|
const telemetryCtx = {
|
|
1486
1461
|
userId: ctxUserId,
|
|
1487
1462
|
requestId: reqId,
|
package/package.json
CHANGED