@pipeshub-ai/mcp 2.3.0 → 2.3.1

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/bin/mcp-server.js CHANGED
@@ -53098,7 +53098,10 @@ var init_agentsListAgents = __esm(() => {
53098
53098
  });
53099
53099
 
53100
53100
  // src/mcp-server/tools/_helpers.ts
53101
- async function readJson(response) {
53101
+ async function readJson(response, context = "PipesHub request") {
53102
+ const httpErr = await httpErrorResult(response, context);
53103
+ if (httpErr)
53104
+ return { ok: false, result: httpErr };
53102
53105
  const text = await response.text();
53103
53106
  if (!text) {
53104
53107
  return {
@@ -53127,6 +53130,13 @@ ${text.slice(0, 500)}`
53127
53130
  };
53128
53131
  }
53129
53132
  }
53133
+ function expiredTokenError(exp) {
53134
+ if (typeof exp !== "number" || !Number.isFinite(exp))
53135
+ return null;
53136
+ if (exp * 1000 > Date.now())
53137
+ return null;
53138
+ return errorResult(`The access token expired on ${new Date(exp * 1000).toISOString()}. ` + "Mint a new personal access token in PipesHub under " + "Developer Settings → Personal Access Tokens.");
53139
+ }
53130
53140
  function jsonResult(value) {
53131
53141
  return {
53132
53142
  content: [{ type: "text", text: JSON.stringify(value, null, 2) }]
@@ -53153,11 +53163,15 @@ async function httpErrorResult(response, context) {
53153
53163
  message = candidate || body;
53154
53164
  } catch {}
53155
53165
  }
53156
- const detail = message ? ` ${message.slice(0, 400)}` : "";
53166
+ const reason = message.slice(0, 400).trim();
53167
+ const detail = reason ? ` ${/[.!?]$/.test(reason) ? reason : `${reason}.`}` : "";
53157
53168
  const auth = response.status === 401 || response.status === 403 ? " Check that the bearer token / credentials are valid and not expired." : "";
53158
53169
  return errorResult(`${context} failed (HTTP ${response.status} ${response.statusText}).${detail}${auth}`);
53159
53170
  }
53160
- async function readValidated(response, schema) {
53171
+ async function readValidated(response, schema, context = "PipesHub request") {
53172
+ const httpErr = await httpErrorResult(response, context);
53173
+ if (httpErr)
53174
+ return { ok: false, result: httpErr };
53161
53175
  const text = await response.text();
53162
53176
  if (!text) {
53163
53177
  return { ok: false, result: errorResult("Empty response from server") };
@@ -53791,7 +53805,7 @@ When presenting results to the user, link each record using its
53791
53805
  }, { fetchOptions: { signal: ctx.signal } }).$inspect();
53792
53806
  if (!result.ok)
53793
53807
  return errorResult(result.error.message);
53794
- const parsed = await readJson(result.value);
53808
+ const parsed = await readJson(result.value, "PipesHub search");
53795
53809
  if (!parsed.ok)
53796
53810
  return parsed.result;
53797
53811
  const sr = parsed.value.searchResponse ?? {};
@@ -54806,7 +54820,7 @@ var init_pipeshubDirectory = __esm(() => {
54806
54820
  "list_groups",
54807
54821
  "list_my_teams"
54808
54822
  ]).describe(`What to do:
54809
- ` + "- `whoami` — return the authenticated user's identity (decoded from " + `the bearer JWT). No other args needed.
54823
+ ` + "- `whoami` — return the authenticated user's identity, confirmed " + `against the server. No other args needed.
54810
54824
  ` + "- `list_users` — paginated list of org users. Optional `page`, " + "`limit`, `search` (substring match against name or email).\n" + "- `get_user` — full profile for one user. Required `userId`. " + "Use `whoami` to find your own id first if needed.\n" + "- `list_groups` — paginated list of user groups (with `userCount`).\n" + "- `list_my_teams` — teams the authenticated user belongs to, with " + "capability flags."),
54811
54825
  userId: string2().optional().describe("Required when `action` is `get_user`. 24-character ObjectId."),
54812
54826
  page: number2().int().min(1).optional().describe("Pagination — 1-based page number. Used by list_* actions."),
@@ -54820,7 +54834,8 @@ actions — pick the right \`action\`:
54820
54834
 
54821
54835
  - \`whoami\` — who is the caller? Use this whenever you need the
54822
54836
  authenticated user's own id, email, or full name (e.g. before
54823
- \`get_user\` on themselves).
54837
+ \`get_user\` on themselves). Errors if the credential is expired
54838
+ or revoked.
54824
54839
  - \`list_users\` — search / page through org users.
54825
54840
  - \`get_user\` — full \`User\` document for one user (requires \`userId\`).
54826
54841
  - \`list_groups\` — list user groups with \`userCount\`.
@@ -54845,13 +54860,39 @@ Output shape varies by action; see each action's docs above.`,
54845
54860
  if (!claims) {
54846
54861
  return errorResult("No bearer token configured on the SDK client, so `whoami` " + "cannot resolve the caller's identity. Ask the user for " + "their email and use `list_users` with `search`.");
54847
54862
  }
54863
+ const exp = claims["exp"];
54864
+ const expired = expiredTokenError(exp);
54865
+ if (expired)
54866
+ return expired;
54867
+ const tokenExpiresAt = typeof exp === "number" ? new Date(exp * 1000).toISOString() : undefined;
54868
+ const userId = claims["userId"];
54869
+ let verified = "unchecked";
54870
+ let unverifiedReason = "No userId claim in the token, so the identity could not be " + "confirmed with the server.";
54871
+ if (typeof userId === "string" && userId) {
54872
+ const [probe] = await usersGetUserById(client, { id: userId }, {
54873
+ fetchOptions
54874
+ }).$inspect();
54875
+ if (!probe.ok) {
54876
+ unverifiedReason = `Could not reach PipesHub to confirm the ` + `identity (${probe.error.message}). The details below come ` + `from the token itself.`;
54877
+ } else if (probe.value.status === 401) {
54878
+ return errorResult("PipesHub rejected this access token (HTTP 401 Unauthorized), " + "so the identity in it is no longer valid — it has most " + "likely been revoked. Mint a new personal access token " + "under Developer Settings → Personal Access Tokens.");
54879
+ } else if (probe.value.ok) {
54880
+ verified = true;
54881
+ unverifiedReason = undefined;
54882
+ } else {
54883
+ unverifiedReason = `PipesHub returned HTTP ${probe.value.status} ` + `when confirming the identity, so it could not be checked. ` + `The details below come from the token itself.`;
54884
+ }
54885
+ }
54848
54886
  return jsonResult({
54849
54887
  userId: claims["userId"],
54850
54888
  orgId: claims["orgId"],
54851
54889
  email: claims["email"],
54852
54890
  fullName: claims["fullName"],
54853
54891
  mobile: claims["mobile"],
54854
- userSlug: claims["userSlug"]
54892
+ userSlug: claims["userSlug"],
54893
+ tokenExpiresAt,
54894
+ identityVerified: verified,
54895
+ note: unverifiedReason
54855
54896
  });
54856
54897
  }
54857
54898
  case "list_users": {
@@ -54862,7 +54903,7 @@ Output shape varies by action; see each action's docs above.`,
54862
54903
  }, { fetchOptions }).$inspect();
54863
54904
  if (!result.ok)
54864
54905
  return errorResult(result.error.message);
54865
- const parsed = await readJson(result.value);
54906
+ const parsed = await readJson(result.value, "User listing");
54866
54907
  if (!parsed.ok)
54867
54908
  return parsed.result;
54868
54909
  return jsonResult(parsed.value);
@@ -54876,7 +54917,7 @@ Output shape varies by action; see each action's docs above.`,
54876
54917
  }, { fetchOptions }).$inspect();
54877
54918
  if (!result.ok)
54878
54919
  return errorResult(result.error.message);
54879
- const parsed = await readJson(result.value);
54920
+ const parsed = await readJson(result.value, "User lookup");
54880
54921
  if (!parsed.ok)
54881
54922
  return parsed.result;
54882
54923
  return jsonResult(parsed.value);
@@ -54889,7 +54930,7 @@ Output shape varies by action; see each action's docs above.`,
54889
54930
  }, { fetchOptions }).$inspect();
54890
54931
  if (!result.ok)
54891
54932
  return errorResult(result.error.message);
54892
- const parsed = await readJson(result.value);
54933
+ const parsed = await readJson(result.value, "Group listing");
54893
54934
  if (!parsed.ok)
54894
54935
  return parsed.result;
54895
54936
  return jsonResult(parsed.value);
@@ -54902,7 +54943,7 @@ Output shape varies by action; see each action's docs above.`,
54902
54943
  }, { fetchOptions }).$inspect();
54903
54944
  if (!result.ok)
54904
54945
  return errorResult(result.error.message);
54905
- const parsed = await readJson(result.value);
54946
+ const parsed = await readJson(result.value, "Team listing");
54906
54947
  if (!parsed.ok)
54907
54948
  return parsed.result;
54908
54949
  return jsonResult(parsed.value);
@@ -55187,7 +55228,7 @@ are returned by default; pass \`include\` to override.`,
55187
55228
  }, { fetchOptions }).$inspect();
55188
55229
  if (!r.ok)
55189
55230
  return errorResult(`sources: ${r.error.message}`);
55190
- const parsed = await readJson(r.value);
55231
+ const parsed = await readJson(r.value, "Knowledge base listing");
55191
55232
  if (!parsed.ok)
55192
55233
  return parsed.result;
55193
55234
  result["sources"] = (parsed.value.items ?? []).map((n) => ({
@@ -55209,7 +55250,7 @@ are returned by default; pass \`include\` to override.`,
55209
55250
  }, { fetchOptions }).$inspect();
55210
55251
  if (!r.ok)
55211
55252
  return errorResult(`${key}: ${r.error.message}`);
55212
- const parsed = await readJson(r.value);
55253
+ const parsed = await readJson(r.value, "Model listing");
55213
55254
  if (!parsed.ok)
55214
55255
  return parsed.result;
55215
55256
  result[key] = (parsed.value.models ?? []).map((m) => ({
@@ -55560,7 +55601,7 @@ it using the \`Web URL\` from its metadata header (when present).`
55560
55601
  },
55561
55602
  {
55562
55603
  name: "pipeshub_directory",
55563
- description: "Look up people, groups, and teams in PipesHub. One tool with five\nactions — pick the right `action`:\n\n- `whoami` — who is the caller? Use this whenever you need the\n authenticated user's own id, email, or full name (e.g. before\n `get_user` on themselves).\n- `list_users` — search / page through org users.\n- `get_user` — full `User` document for one user (requires `userId`).\n- `list_groups` — list user groups with `userCount`.\n- `list_my_teams` — teams the caller belongs to, with capability flags\n (`canEdit` / `canDelete` / `canManageMembers`).\n\nOutput shape varies by action; see each action's docs above."
55604
+ description: "Look up people, groups, and teams in PipesHub. One tool with five\nactions — pick the right `action`:\n\n- `whoami` — who is the caller? Use this whenever you need the\n authenticated user's own id, email, or full name (e.g. before\n `get_user` on themselves). Errors if the credential is expired\n or revoked.\n- `list_users` — search / page through org users.\n- `get_user` — full `User` document for one user (requires `userId`).\n- `list_groups` — list user groups with `userCount`.\n- `list_my_teams` — teams the caller belongs to, with capability flags\n (`canEdit` / `canDelete` / `canManageMembers`).\n\nOutput shape varies by action; see each action's docs above."
55564
55605
  },
55565
55606
  {
55566
55607
  name: "pipeshub_agents",
@@ -59193,5 +59234,5 @@ export {
59193
59234
  app
59194
59235
  };
59195
59236
 
59196
- //# debugId=90FD24D95D2C4D3664756E2164756E21
59237
+ //# debugId=B3EADAB5212D24DD64756E2164756E21
59197
59238
  //# sourceMappingURL=mcp-server.js.map