@plaud-ai/mcp 0.3.4 → 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.
@@ -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,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  PlaudClient,
3
3
  capture
4
- } from "./chunk-D2JZW2TW.js";
4
+ } from "./chunk-FDWRBOUI.js";
5
5
  import {
6
6
  httpClientDuration,
7
7
  httpClientRequests
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  capture,
3
3
  classifyError
4
- } from "./chunk-D2JZW2TW.js";
4
+ } from "./chunk-FDWRBOUI.js";
5
5
  import {
6
6
  logger
7
7
  } from "./chunk-NPCCDRWQ.js";
package/dist/index.js CHANGED
@@ -1,18 +1,19 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  getClient
4
- } from "./chunk-LOGKF7DL.js";
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-XWDA3G2U.js";
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-D2JZW2TW.js";
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.4"
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 setUser(user.id, extractIdentity(user));
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-ETBOS6SA.js");
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");
@@ -186,7 +191,7 @@ async function main() {
186
191
  return;
187
192
  }
188
193
  if (sub === "http") {
189
- const { startHttpServer } = await import("./server-VVQEILKC.js");
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.4",
220
+ appVersion: "0.3.5",
216
221
  transport: "stdio"
217
222
  });
218
223
  } catch {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getClient
3
- } from "./chunk-LOGKF7DL.js";
3
+ } from "./chunk-SEOLTKA5.js";
4
4
  import {
5
5
  commandPathIsStale,
6
6
  copyToClipboard,
@@ -12,7 +12,7 @@ import {
12
12
  } from "./chunk-242FRP4P.js";
13
13
  import {
14
14
  runOAuthCallback
15
- } from "./chunk-D2JZW2TW.js";
15
+ } from "./chunk-FDWRBOUI.js";
16
16
  import "./chunk-RUFCT6DQ.js";
17
17
 
18
18
  // src/install.ts
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  normalizeMcpHost,
3
3
  registerTools
4
- } from "./chunk-XWDA3G2U.js";
4
+ } from "./chunk-YI4KJEAG.js";
5
5
  import {
6
6
  PlaudClient
7
- } from "./chunk-D2JZW2TW.js";
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 = await this.resolveRealUserId(data.access_token);
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: refreshedUserId,
790
- distinctId: refreshedUserId ?? client.client_id
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.4",
1235
- buildId: "ce4457b",
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.4" });
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 ctxUserId = req.auth.clientId && req.auth.clientId !== "unknown" ? req.auth.clientId : void 0;
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plaud-ai/mcp",
3
- "version": "0.3.4",
3
+ "version": "0.3.5",
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.4",
3
+ "version": "0.3.5",
4
4
  "description": "Access your Plaud recordings in Claude",
5
5
  "author": {
6
6
  "name": "Plaud AI"