@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 +56 -15
- package/bin/mcp-server.js.map +7 -7
- package/bin/pipeshub.js +2 -2
- package/bin/pipeshub.js.map +3 -3
- package/esm/cli/client.d.ts.map +1 -1
- package/esm/cli/client.js +6 -1
- package/esm/cli/client.js.map +1 -1
- package/esm/mcp-server/tools/_helpers.d.ts +20 -3
- package/esm/mcp-server/tools/_helpers.d.ts.map +1 -1
- package/esm/mcp-server/tools/_helpers.js +41 -4
- package/esm/mcp-server/tools/_helpers.js.map +1 -1
- package/esm/mcp-server/tools/pipeshubDirectory.d.ts.map +1 -1
- package/esm/mcp-server/tools/pipeshubDirectory.js +62 -8
- package/esm/mcp-server/tools/pipeshubDirectory.js.map +1 -1
- package/esm/mcp-server/tools/pipeshubGetRecordContent.d.ts +1 -1
- package/esm/mcp-server/tools/pipeshubSearch.js +1 -1
- package/esm/mcp-server/tools/pipeshubSearch.js.map +1 -1
- package/esm/mcp-server/tools/pipeshubSources.js +2 -2
- package/esm/mcp-server/tools/pipeshubSources.js.map +1 -1
- package/esm/models/availablemodelsresponse.d.ts +1 -1
- package/esm/models/conversation.d.ts +1 -1
- package/esm/models/userteamsresponse.d.ts +1 -1
- package/esm/tool-names.js +1 -1
- package/esm/tool-names.js.map +1 -1
- package/package.json +1 -1
- package/qm/sandbox/Dockerfile +1 -1
- package/src/cli/client.ts +8 -1
- package/src/mcp-server/tools/_helpers.ts +42 -2
- package/src/mcp-server/tools/pipeshubDirectory.ts +65 -7
- package/src/mcp-server/tools/pipeshubSearch.ts +1 -1
- package/src/mcp-server/tools/pipeshubSources.ts +2 -2
- package/src/tool-names.ts +1 -1
|
@@ -6,7 +6,7 @@ import { usersGetAllUsers } from "../../funcs/usersGetAllUsers.js";
|
|
|
6
6
|
import { usersGetUserById } from "../../funcs/usersGetUserById.js";
|
|
7
7
|
import { userGroupsGetAllUserGroups } from "../../funcs/userGroupsGetAllUserGroups.js";
|
|
8
8
|
import { teamsGetUserTeams } from "../../funcs/teamsGetUserTeams.js";
|
|
9
|
-
import { decodeBearer, errorResult, jsonResult, readJson, } from "./_helpers.js";
|
|
9
|
+
import { decodeBearer, errorResult, jsonResult, expiredTokenError, readJson, } from "./_helpers.js";
|
|
10
10
|
const args = {
|
|
11
11
|
action: z.enum([
|
|
12
12
|
"whoami",
|
|
@@ -15,8 +15,8 @@ const args = {
|
|
|
15
15
|
"list_groups",
|
|
16
16
|
"list_my_teams",
|
|
17
17
|
]).describe("What to do:\n"
|
|
18
|
-
+ "- `whoami` — return the authenticated user's identity
|
|
19
|
-
+ "the
|
|
18
|
+
+ "- `whoami` — return the authenticated user's identity, confirmed "
|
|
19
|
+
+ "against the server. No other args needed.\n"
|
|
20
20
|
+ "- `list_users` — paginated list of org users. Optional `page`, "
|
|
21
21
|
+ "`limit`, `search` (substring match against name or email).\n"
|
|
22
22
|
+ "- `get_user` — full profile for one user. Required `userId`. "
|
|
@@ -36,7 +36,8 @@ actions — pick the right \`action\`:
|
|
|
36
36
|
|
|
37
37
|
- \`whoami\` — who is the caller? Use this whenever you need the
|
|
38
38
|
authenticated user's own id, email, or full name (e.g. before
|
|
39
|
-
\`get_user\` on themselves).
|
|
39
|
+
\`get_user\` on themselves). Errors if the credential is expired
|
|
40
|
+
or revoked.
|
|
40
41
|
- \`list_users\` — search / page through org users.
|
|
41
42
|
- \`get_user\` — full \`User\` document for one user (requires \`userId\`).
|
|
42
43
|
- \`list_groups\` — list user groups with \`userCount\`.
|
|
@@ -63,6 +64,53 @@ Output shape varies by action; see each action's docs above.`,
|
|
|
63
64
|
+ "cannot resolve the caller's identity. Ask the user for "
|
|
64
65
|
+ "their email and use `list_users` with `search`.");
|
|
65
66
|
}
|
|
67
|
+
// The claims come out of the local token, which proves nothing about
|
|
68
|
+
// whether the server still accepts it — a revoked token carries a
|
|
69
|
+
// perfectly good name and org. Since whoami is the command people run
|
|
70
|
+
// to check "is my login working?", answering from the token alone
|
|
71
|
+
// gives a confident yes in exactly the case that matters.
|
|
72
|
+
//
|
|
73
|
+
// Expiry is checkable offline, so check it first: it is the common
|
|
74
|
+
// case and costs no round-trip.
|
|
75
|
+
const exp = claims["exp"];
|
|
76
|
+
const expired = expiredTokenError(exp);
|
|
77
|
+
if (expired)
|
|
78
|
+
return expired;
|
|
79
|
+
const tokenExpiresAt = typeof exp === "number"
|
|
80
|
+
? new Date(exp * 1000).toISOString()
|
|
81
|
+
: undefined;
|
|
82
|
+
// Revocation can only be established by asking the server. get_user on
|
|
83
|
+
// the caller's own id needs `user:read`, which whoami's callers already
|
|
84
|
+
// hold, and returns 401 for a rejected credential.
|
|
85
|
+
const userId = claims["userId"];
|
|
86
|
+
let verified = "unchecked";
|
|
87
|
+
let unverifiedReason = "No userId claim in the token, so the identity could not be "
|
|
88
|
+
+ "confirmed with the server.";
|
|
89
|
+
if (typeof userId === "string" && userId) {
|
|
90
|
+
const [probe] = await usersGetUserById(client, { id: userId }, {
|
|
91
|
+
fetchOptions,
|
|
92
|
+
}).$inspect();
|
|
93
|
+
if (!probe.ok) {
|
|
94
|
+
unverifiedReason = `Could not reach PipesHub to confirm the `
|
|
95
|
+
+ `identity (${probe.error.message}). The details below come `
|
|
96
|
+
+ `from the token itself.`;
|
|
97
|
+
}
|
|
98
|
+
else if (probe.value.status === 401) {
|
|
99
|
+
return errorResult("PipesHub rejected this access token (HTTP 401 Unauthorized), "
|
|
100
|
+
+ "so the identity in it is no longer valid — it has most "
|
|
101
|
+
+ "likely been revoked. Mint a new personal access token "
|
|
102
|
+
+ "under Developer Settings → Personal Access Tokens.");
|
|
103
|
+
}
|
|
104
|
+
else if (probe.value.ok) {
|
|
105
|
+
verified = true;
|
|
106
|
+
unverifiedReason = undefined;
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
unverifiedReason = `PipesHub returned HTTP ${probe.value.status} `
|
|
110
|
+
+ `when confirming the identity, so it could not be checked. `
|
|
111
|
+
+ `The details below come from the token itself.`;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
66
114
|
return jsonResult({
|
|
67
115
|
userId: claims["userId"],
|
|
68
116
|
orgId: claims["orgId"],
|
|
@@ -70,6 +118,12 @@ Output shape varies by action; see each action's docs above.`,
|
|
|
70
118
|
fullName: claims["fullName"],
|
|
71
119
|
mobile: claims["mobile"],
|
|
72
120
|
userSlug: claims["userSlug"],
|
|
121
|
+
tokenExpiresAt,
|
|
122
|
+
// Never `false`: that reads as "the server rejected this identity",
|
|
123
|
+
// which is a different and much more alarming claim than "this was
|
|
124
|
+
// not checked". A rejection returns an error above instead.
|
|
125
|
+
identityVerified: verified,
|
|
126
|
+
note: unverifiedReason,
|
|
73
127
|
});
|
|
74
128
|
}
|
|
75
129
|
case "list_users": {
|
|
@@ -80,7 +134,7 @@ Output shape varies by action; see each action's docs above.`,
|
|
|
80
134
|
}, { fetchOptions }).$inspect();
|
|
81
135
|
if (!result.ok)
|
|
82
136
|
return errorResult(result.error.message);
|
|
83
|
-
const parsed = await readJson(result.value);
|
|
137
|
+
const parsed = await readJson(result.value, "User listing");
|
|
84
138
|
if (!parsed.ok)
|
|
85
139
|
return parsed.result;
|
|
86
140
|
return jsonResult(parsed.value);
|
|
@@ -96,7 +150,7 @@ Output shape varies by action; see each action's docs above.`,
|
|
|
96
150
|
}, { fetchOptions }).$inspect();
|
|
97
151
|
if (!result.ok)
|
|
98
152
|
return errorResult(result.error.message);
|
|
99
|
-
const parsed = await readJson(result.value);
|
|
153
|
+
const parsed = await readJson(result.value, "User lookup");
|
|
100
154
|
if (!parsed.ok)
|
|
101
155
|
return parsed.result;
|
|
102
156
|
return jsonResult(parsed.value);
|
|
@@ -109,7 +163,7 @@ Output shape varies by action; see each action's docs above.`,
|
|
|
109
163
|
}, { fetchOptions }).$inspect();
|
|
110
164
|
if (!result.ok)
|
|
111
165
|
return errorResult(result.error.message);
|
|
112
|
-
const parsed = await readJson(result.value);
|
|
166
|
+
const parsed = await readJson(result.value, "Group listing");
|
|
113
167
|
if (!parsed.ok)
|
|
114
168
|
return parsed.result;
|
|
115
169
|
return jsonResult(parsed.value);
|
|
@@ -122,7 +176,7 @@ Output shape varies by action; see each action's docs above.`,
|
|
|
122
176
|
}, { fetchOptions }).$inspect();
|
|
123
177
|
if (!result.ok)
|
|
124
178
|
return errorResult(result.error.message);
|
|
125
|
-
const parsed = await readJson(result.value);
|
|
179
|
+
const parsed = await readJson(result.value, "Team listing");
|
|
126
180
|
if (!parsed.ok)
|
|
127
181
|
return parsed.result;
|
|
128
182
|
return jsonResult(parsed.value);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pipeshubDirectory.js","sourceRoot":"","sources":["../../../src/mcp-server/tools/pipeshubDirectory.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,2EAA2E;AAC3E,0BAA0B;AAE1B,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AACzB,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,0BAA0B,EAAE,MAAM,2CAA2C,CAAC;AACvF,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAErE,OAAO,EACL,YAAY,EACZ,WAAW,EACX,UAAU,EACV,QAAQ,GACT,MAAM,eAAe,CAAC;AAEvB,MAAM,IAAI,GAAG;IACX,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC;QACb,QAAQ;QACR,YAAY;QACZ,UAAU;QACV,aAAa;QACb,eAAe;KAChB,CAAC,CAAC,QAAQ,CACT,eAAe;UACX,
|
|
1
|
+
{"version":3,"file":"pipeshubDirectory.js","sourceRoot":"","sources":["../../../src/mcp-server/tools/pipeshubDirectory.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,2EAA2E;AAC3E,0BAA0B;AAE1B,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AACzB,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,0BAA0B,EAAE,MAAM,2CAA2C,CAAC;AACvF,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAErE,OAAO,EACL,YAAY,EACZ,WAAW,EACX,UAAU,EACV,iBAAiB,EACjB,QAAQ,GACT,MAAM,eAAe,CAAC;AAEvB,MAAM,IAAI,GAAG;IACX,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC;QACb,QAAQ;QACR,YAAY;QACZ,UAAU;QACV,aAAa;QACb,eAAe;KAChB,CAAC,CAAC,QAAQ,CACT,eAAe;UACX,mEAAmE;UACnE,6CAA6C;UAC7C,iEAAiE;UACjE,8DAA8D;UAC9D,+DAA+D;UAC/D,qDAAqD;UACrD,uEAAuE;UACvE,oEAAoE;UACpE,mBAAmB,CACxB;IACD,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CACpC,8DAA8D,CAC/D;IACD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAC/C,2DAA2D,CAC5D;IACD,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CACzD,sDAAsD,CACvD;IACD,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CACpC,2DAA2D,CAC5D;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAgC;IACjE,IAAI,EAAE,oBAAoB;IAC1B,WAAW,EACT;;;;;;;;;;;;;6DAayD;IAC3D,MAAM,EAAE,CAAC,MAAM,CAAC;IAChB,WAAW,EAAE;QACX,KAAK,EAAE,sDAAsD;QAC7D,eAAe,EAAE,KAAK;QACtB,cAAc,EAAE,IAAI;QACpB,aAAa,EAAE,KAAK;QACpB,YAAY,EAAE,IAAI;KACnB;IACD,IAAI;IACJ,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;QAChC,MAAM,YAAY,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC;QAE5C,QAAQ,IAAI,CAAC,MAAM,EAAE,CAAC;YACpB,KAAK,QAAQ,CAAC,CAAC,CAAC;gBACd,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC;gBAC1C,IAAI,CAAC,MAAM,EAAE,CAAC;oBACZ,OAAO,WAAW,CAChB,4DAA4D;0BACxD,yDAAyD;0BACzD,iDAAiD,CACtD,CAAC;gBACJ,CAAC;gBACD,qEAAqE;gBACrE,kEAAkE;gBAClE,sEAAsE;gBACtE,kEAAkE;gBAClE,0DAA0D;gBAC1D,EAAE;gBACF,mEAAmE;gBACnE,gCAAgC;gBAChC,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;gBAC1B,MAAM,OAAO,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;gBACvC,IAAI,OAAO;oBAAE,OAAO,OAAO,CAAC;gBAC5B,MAAM,cAAc,GAAG,OAAO,GAAG,KAAK,QAAQ;oBAC5C,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE;oBACpC,CAAC,CAAC,SAAS,CAAC;gBAEd,uEAAuE;gBACvE,wEAAwE;gBACxE,mDAAmD;gBACnD,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;gBAChC,IAAI,QAAQ,GAAuB,WAAW,CAAC;gBAC/C,IAAI,gBAAgB,GAClB,6DAA6D;sBAC3D,4BAA4B,CAAC;gBAEjC,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,EAAE,CAAC;oBACzC,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,gBAAgB,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE;wBAC7D,YAAY;qBACb,CAAC,CAAC,QAAQ,EAAE,CAAC;oBAEd,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;wBACd,gBAAgB,GAAG,0CAA0C;8BACzD,aAAa,KAAK,CAAC,KAAK,CAAC,OAAO,4BAA4B;8BAC5D,wBAAwB,CAAC;oBAC/B,CAAC;yBAAM,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;wBACtC,OAAO,WAAW,CAChB,+DAA+D;8BAC3D,yDAAyD;8BACzD,wDAAwD;8BACxD,oDAAoD,CACzD,CAAC;oBACJ,CAAC;yBAAM,IAAI,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;wBAC1B,QAAQ,GAAG,IAAI,CAAC;wBAChB,gBAAgB,GAAG,SAAS,CAAC;oBAC/B,CAAC;yBAAM,CAAC;wBACN,gBAAgB,GAAG,0BAA0B,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG;8BAC9D,4DAA4D;8BAC5D,+CAA+C,CAAC;oBACtD,CAAC;gBACH,CAAC;gBAED,OAAO,UAAU,CAAC;oBAChB,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC;oBACxB,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC;oBACtB,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC;oBACtB,QAAQ,EAAE,MAAM,CAAC,UAAU,CAAC;oBAC5B,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC;oBACxB,QAAQ,EAAE,MAAM,CAAC,UAAU,CAAC;oBAC5B,cAAc;oBACd,oEAAoE;oBACpE,mEAAmE;oBACnE,4DAA4D;oBAC5D,gBAAgB,EAAE,QAAQ;oBAC1B,IAAI,EAAE,gBAAgB;iBACvB,CAAC,CAAC;YACL,CAAC;YAED,KAAK,YAAY,CAAC,CAAC,CAAC;gBAClB,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,gBAAgB,CAAC,MAAM,EAAE;oBAC9C,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,KAAK,EAAE,IAAI,CAAC,KAAK;oBACjB,MAAM,EAAE,IAAI,CAAC,MAAM;iBACpB,EAAE,EAAE,YAAY,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;gBAChC,IAAI,CAAC,MAAM,CAAC,EAAE;oBAAE,OAAO,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBACzD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;gBAC5D,IAAI,CAAC,MAAM,CAAC,EAAE;oBAAE,OAAO,MAAM,CAAC,MAAM,CAAC;gBACrC,OAAO,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAClC,CAAC;YAED,KAAK,UAAU,CAAC,CAAC,CAAC;gBAChB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;oBACjB,OAAO,WAAW,CAChB,oDAAoD;0BAChD,oDAAoD;0BACpD,6BAA6B,CAClC,CAAC;gBACJ,CAAC;gBACD,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,gBAAgB,CAAC,MAAM,EAAE;oBAC9C,EAAE,EAAE,IAAI,CAAC,MAAM;iBAChB,EAAE,EAAE,YAAY,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;gBAChC,IAAI,CAAC,MAAM,CAAC,EAAE;oBAAE,OAAO,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBACzD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;gBAC3D,IAAI,CAAC,MAAM,CAAC,EAAE;oBAAE,OAAO,MAAM,CAAC,MAAM,CAAC;gBACrC,OAAO,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAClC,CAAC;YAED,KAAK,aAAa,CAAC,CAAC,CAAC;gBACnB,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,0BAA0B,CAAC,MAAM,EAAE;oBACxD,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,KAAK,EAAE,IAAI,CAAC,KAAK;oBACjB,MAAM,EAAE,IAAI,CAAC,MAAM;iBACpB,EAAE,EAAE,YAAY,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;gBAChC,IAAI,CAAC,MAAM,CAAC,EAAE;oBAAE,OAAO,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBACzD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC;gBAC7D,IAAI,CAAC,MAAM,CAAC,EAAE;oBAAE,OAAO,MAAM,CAAC,MAAM,CAAC;gBACrC,OAAO,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAClC,CAAC;YAED,KAAK,eAAe,CAAC,CAAC,CAAC;gBACrB,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,iBAAiB,CAAC,MAAM,EAAE;oBAC/C,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,KAAK,EAAE,IAAI,CAAC,KAAK;oBACjB,MAAM,EAAE,IAAI,CAAC,MAAM;iBACpB,EAAE,EAAE,YAAY,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;gBAChC,IAAI,CAAC,MAAM,CAAC,EAAE;oBAAE,OAAO,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBACzD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;gBAC5D,IAAI,CAAC,MAAM,CAAC,EAAE;oBAAE,OAAO,MAAM,CAAC,MAAM,CAAC;gBACrC,OAAO,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAClC,CAAC;QACH,CAAC;IACH,CAAC;CACF,CAAC"}
|
|
@@ -103,8 +103,8 @@ export declare function renderedResult(response: Response): Promise<{
|
|
|
103
103
|
}>;
|
|
104
104
|
declare const args: {
|
|
105
105
|
mode: z.ZodDefault<z.ZodEnum<{
|
|
106
|
-
content: "content";
|
|
107
106
|
navigate: "navigate";
|
|
107
|
+
content: "content";
|
|
108
108
|
lookup: "lookup";
|
|
109
109
|
}>>;
|
|
110
110
|
recordId: z.ZodOptional<z.ZodString>;
|
|
@@ -61,7 +61,7 @@ When presenting results to the user, link each record using its
|
|
|
61
61
|
}, { fetchOptions: { signal: ctx.signal } }).$inspect();
|
|
62
62
|
if (!result.ok)
|
|
63
63
|
return errorResult(result.error.message);
|
|
64
|
-
const parsed = await readJson(result.value);
|
|
64
|
+
const parsed = await readJson(result.value, "PipesHub search");
|
|
65
65
|
if (!parsed.ok)
|
|
66
66
|
return parsed.result;
|
|
67
67
|
const sr = parsed.value.searchResponse ?? {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pipeshubSearch.js","sourceRoot":"","sources":["../../../src/mcp-server/tools/pipeshubSearch.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AACzB,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAE3E,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEjF,MAAM,IAAI,GAAG;IACX,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAC/B,yEAAyE,CAC1E;IACD,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CACzD,oEAAoE;UAChE,iEAAiE,CACtE;IACD,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAC3C,yDAAyD;UACrD,4DAA4D,CACjE;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAgC;IAC9D,IAAI,EAAE,iBAAiB;IACvB,WAAW,EACT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAiCuB;IACzB,MAAM,EAAE,CAAC,MAAM,CAAC;IAChB,WAAW,EAAE;QACX,KAAK,EAAE,iBAAiB;QACxB,eAAe,EAAE,KAAK;QACtB,cAAc,EAAE,IAAI;QACpB,aAAa,EAAE,IAAI;QACnB,YAAY,EAAE,KAAK;KACpB;IACD,IAAI;IACJ,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;QAChC,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,oBAAoB,CAAC,MAAM,EAAE;YAClD,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS;SAC7D,EAAE,EAAE,YAAY,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;QACxD,IAAI,CAAC,MAAM,CAAC,EAAE;YAAE,OAAO,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAEzD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAQ1B,MAAM,CAAC,KAAK,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"pipeshubSearch.js","sourceRoot":"","sources":["../../../src/mcp-server/tools/pipeshubSearch.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AACzB,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAE3E,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEjF,MAAM,IAAI,GAAG;IACX,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAC/B,yEAAyE,CAC1E;IACD,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CACzD,oEAAoE;UAChE,iEAAiE,CACtE;IACD,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAC3C,yDAAyD;UACrD,4DAA4D,CACjE;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAgC;IAC9D,IAAI,EAAE,iBAAiB;IACvB,WAAW,EACT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAiCuB;IACzB,MAAM,EAAE,CAAC,MAAM,CAAC;IAChB,WAAW,EAAE;QACX,KAAK,EAAE,iBAAiB;QACxB,eAAe,EAAE,KAAK;QACtB,cAAc,EAAE,IAAI;QACpB,aAAa,EAAE,IAAI;QACnB,YAAY,EAAE,KAAK;KACpB;IACD,IAAI;IACJ,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;QAChC,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,oBAAoB,CAAC,MAAM,EAAE;YAClD,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS;SAC7D,EAAE,EAAE,YAAY,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;QACxD,IAAI,CAAC,MAAM,CAAC,EAAE;YAAE,OAAO,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAEzD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAQ1B,MAAM,CAAC,KAAK,EAAE,iBAAiB,CAAC,CAAC;QACpC,IAAI,CAAC,MAAM,CAAC,EAAE;YAAE,OAAO,MAAM,CAAC,MAAM,CAAC;QAErC,MAAM,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,cAAc,IAAI,EAAE,CAAC;QAC7C,OAAO,UAAU,CAAC;YAChB,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,QAAQ;YAC/B,IAAI,EAAE,CAAC,EAAE,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC;YACjD,aAAa,EAAE,CAAC,EAAE,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC;gBACjD,QAAQ,EAAE,CAAC,CAAC,IAAI;gBAChB,UAAU,EAAE,CAAC,CAAC,UAAU;gBACxB,SAAS,EAAE,CAAC,CAAC,aAAa;gBAC1B,QAAQ,EAAE,CAAC,CAAC,QAAQ;gBACpB,MAAM,EAAE,CAAC,CAAC,MAAM;aACjB,CAAC,CAAC;SACJ,CAAC,CAAC;IACL,CAAC;CACF,CAAC"}
|
|
@@ -50,7 +50,7 @@ are returned by default; pass \`include\` to override.`,
|
|
|
50
50
|
}, { fetchOptions }).$inspect();
|
|
51
51
|
if (!r.ok)
|
|
52
52
|
return errorResult(`sources: ${r.error.message}`);
|
|
53
|
-
const parsed = await readJson(r.value);
|
|
53
|
+
const parsed = await readJson(r.value, "Knowledge base listing");
|
|
54
54
|
if (!parsed.ok)
|
|
55
55
|
return parsed.result;
|
|
56
56
|
result["sources"] = (parsed.value.items ?? []).map((n) => ({
|
|
@@ -72,7 +72,7 @@ are returned by default; pass \`include\` to override.`,
|
|
|
72
72
|
}, { fetchOptions }).$inspect();
|
|
73
73
|
if (!r.ok)
|
|
74
74
|
return errorResult(`${key}: ${r.error.message}`);
|
|
75
|
-
const parsed = await readJson(r.value);
|
|
75
|
+
const parsed = await readJson(r.value, "Model listing");
|
|
76
76
|
if (!parsed.ok)
|
|
77
77
|
return parsed.result;
|
|
78
78
|
result[key] = (parsed.value.models ?? []).map((m) => ({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pipeshubSources.js","sourceRoot":"","sources":["../../../src/mcp-server/tools/pipeshubSources.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AACzB,OAAO,EAAE,oCAAoC,EAAE,MAAM,qDAAqD,CAAC;AAC3G,OAAO,EAAE,yCAAyC,EAAE,MAAM,0DAA0D,CAAC;AAErH,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAElE,MAAM,IAAI,GAAG;IACX,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,WAAW,EAAE,iBAAiB,CAAC,CAAC,CAAC;SAClE,QAAQ,EAAE;SACV,QAAQ,CACP,oEAAoE;UAChE,gEAAgE,CACrE;CACJ,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAgC;IAC/D,IAAI,EAAE,kBAAkB;IACxB,WAAW,EACT;;;;;;;;;;;;;;;;;uDAiBmD;IACrD,MAAM,EAAE,CAAC,MAAM,CAAC;IAChB,WAAW,EAAE;QACX,KAAK,EAAE,qCAAqC;QAC5C,eAAe,EAAE,KAAK;QACtB,cAAc,EAAE,IAAI;QACpB,aAAa,EAAE,KAAK;QACpB,YAAY,EAAE,IAAI;KACnB;IACD,IAAI;IACJ,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;QAChC,MAAM,YAAY,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC;QAC5C,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO;eACtB,CAAC,SAAS,EAAE,WAAW,CAAW,CAAC;QACzC,MAAM,IAAI,GAAG,CAAC,CAAS,EAAE,EAAE,CAAE,OAA6B,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QAEvE,MAAM,MAAM,GAA4B,EAAE,CAAC;QAE3C,IAAI,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YACpB,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,oCAAoC,CAAC,MAAM,EAAE;gBAC7D,IAAI,EAAE,CAAC;gBACP,KAAK,EAAE,GAAG;aACX,EAAE,EAAE,YAAY,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;YAChC,IAAI,CAAC,CAAC,CAAC,EAAE;gBAAE,OAAO,WAAW,CAAC,YAAY,CAAC,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YAC7D,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAoB,CAAC,CAAC,KAAK,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"pipeshubSources.js","sourceRoot":"","sources":["../../../src/mcp-server/tools/pipeshubSources.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,8 +7,8 @@ export declare const AvailableModelsResponseStatus: {
|
|
|
7
7
|
};
|
|
8
8
|
export type AvailableModelsResponseStatus = ClosedEnum<typeof AvailableModelsResponseStatus>;
|
|
9
9
|
export declare const AvailableModelsResponseStatus$zodSchema: z.ZodEnum<{
|
|
10
|
-
error: "error";
|
|
11
10
|
success: "success";
|
|
11
|
+
error: "error";
|
|
12
12
|
}>;
|
|
13
13
|
/**
|
|
14
14
|
* Response from `GET /configurationManager/ai-models/available/{modelType}`.
|
|
@@ -35,8 +35,8 @@ export declare const ConversationStatus: {
|
|
|
35
35
|
*/
|
|
36
36
|
export type ConversationStatus = ClosedEnum<typeof ConversationStatus>;
|
|
37
37
|
export declare const ConversationStatus$zodSchema: z.ZodEnum<{
|
|
38
|
-
Complete: "Complete";
|
|
39
38
|
Inprogress: "Inprogress";
|
|
39
|
+
Complete: "Complete";
|
|
40
40
|
Failed: "Failed";
|
|
41
41
|
None: "None";
|
|
42
42
|
}>;
|
|
@@ -8,8 +8,8 @@ export declare const UserTeamsResponseStatus: {
|
|
|
8
8
|
};
|
|
9
9
|
export type UserTeamsResponseStatus = ClosedEnum<typeof UserTeamsResponseStatus>;
|
|
10
10
|
export declare const UserTeamsResponseStatus$zodSchema: z.ZodEnum<{
|
|
11
|
-
error: "error";
|
|
12
11
|
success: "success";
|
|
12
|
+
error: "error";
|
|
13
13
|
}>;
|
|
14
14
|
/**
|
|
15
15
|
* Paginated response from `GET /teams/user/teams`.
|
package/esm/tool-names.js
CHANGED
|
@@ -22,7 +22,7 @@ export const toolNames = [
|
|
|
22
22
|
},
|
|
23
23
|
{
|
|
24
24
|
"name": "pipeshub_directory",
|
|
25
|
-
"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."
|
|
25
|
+
"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."
|
|
26
26
|
},
|
|
27
27
|
{
|
|
28
28
|
"name": "pipeshub_agents",
|
package/esm/tool-names.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-names.js","sourceRoot":"","sources":["../src/tool-names.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,MAAM,CAAC,MAAM,SAAS,GAAgD;IACpE;QACE,MAAM,EAAE,kBAAkB;QAC1B,aAAa,EAAE,80BAA80B;KAC91B;IACD;QACE,MAAM,EAAE,eAAe;QACvB,aAAa,EAAE,w+EAAw+E;KACx/E;IACD;QACE,MAAM,EAAE,iBAAiB;QACzB,aAAa,EAAE,uiDAAuiD;KACvjD;IACD;QACE,MAAM,EAAE,0BAA0B;QAClC,aAAa,EAAE,8dAA8d;KAC9e;IACD;QACE,MAAM,EAAE,6BAA6B;QACrC,aAAa,EAAE,06HAA06H;KAC17H;IACD;QACE,MAAM,EAAE,oBAAoB;QAC5B,aAAa,EAAE,
|
|
1
|
+
{"version":3,"file":"tool-names.js","sourceRoot":"","sources":["../src/tool-names.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,MAAM,CAAC,MAAM,SAAS,GAAgD;IACpE;QACE,MAAM,EAAE,kBAAkB;QAC1B,aAAa,EAAE,80BAA80B;KAC91B;IACD;QACE,MAAM,EAAE,eAAe;QACvB,aAAa,EAAE,w+EAAw+E;KACx/E;IACD;QACE,MAAM,EAAE,iBAAiB;QACzB,aAAa,EAAE,uiDAAuiD;KACvjD;IACD;QACE,MAAM,EAAE,0BAA0B;QAClC,aAAa,EAAE,8dAA8d;KAC9e;IACD;QACE,MAAM,EAAE,6BAA6B;QACrC,aAAa,EAAE,06HAA06H;KAC17H;IACD;QACE,MAAM,EAAE,oBAAoB;QAC5B,aAAa,EAAE,uqBAAuqB;KACvrB;IACD;QACE,MAAM,EAAE,iBAAiB;QACzB,aAAa,EAAE,82CAA82C;KAC93C;CACF,CAAC"}
|
package/package.json
CHANGED
package/qm/sandbox/Dockerfile
CHANGED
|
@@ -13,7 +13,7 @@ FROM ghcr.io/yc-software/qm/sandbox-base
|
|
|
13
13
|
# separate package. Pin the exact version: the sandbox image and the PipesHub
|
|
14
14
|
# instance's MCP tool surface need to stay compatible, and an unpinned install
|
|
15
15
|
# turns a remote release into a silent change in agent behaviour.
|
|
16
|
-
ARG PIPESHUB_CLI_VERSION=2.3.
|
|
16
|
+
ARG PIPESHUB_CLI_VERSION=2.3.1
|
|
17
17
|
RUN npm install -g "@pipeshub-ai/mcp@${PIPESHUB_CLI_VERSION}" \
|
|
18
18
|
&& pipeshub --help >/dev/null
|
|
19
19
|
|
package/src/cli/client.ts
CHANGED
|
@@ -48,7 +48,14 @@ function statusToExit(status: number): number {
|
|
|
48
48
|
export function toolErrorToExit(message: string): number {
|
|
49
49
|
const m = message.match(/\(HTTP\s+(\d{3})/i);
|
|
50
50
|
if (m && m[1] !== undefined) return statusToExit(Number(m[1]));
|
|
51
|
-
|
|
51
|
+
// `token expired` / `been revoked` cover the credential failures that are
|
|
52
|
+
// established without an HTTP round-trip — whoami checks the token's own
|
|
53
|
+
// expiry offline, so there is no status code to key off, but "your
|
|
54
|
+
// credential is not valid" is exactly what exit 3 means.
|
|
55
|
+
if (
|
|
56
|
+
/\b401\b|unautheni?ticated|no token provided|token expired|been revoked/i
|
|
57
|
+
.test(message)
|
|
58
|
+
) {
|
|
52
59
|
return EXIT.UNAUTHENTICATED;
|
|
53
60
|
}
|
|
54
61
|
if (/\b403\b|not have permission|forbidden/i.test(message)) {
|
|
@@ -15,11 +15,23 @@ import {
|
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* Parse a fetch Response as JSON, returning a CallToolResult error when the
|
|
18
|
-
* body is missing / malformed.
|
|
18
|
+
* status is not ok, or the body is missing / malformed.
|
|
19
|
+
*
|
|
20
|
+
* The status check has to happen here rather than in each caller. The SDK funcs
|
|
21
|
+
* are generated with `errorCodes: []`, so `result.ok` reports transport
|
|
22
|
+
* failures only and a 401 arrives looking exactly like a success. Parsing that
|
|
23
|
+
* body yields an envelope with no results in it, which every caller then
|
|
24
|
+
* reports as an empty corpus — a failed credential becomes "no documents
|
|
25
|
+
* found". Guarding at the single point where a body is turned into a value
|
|
26
|
+
* closes that for every present and future caller.
|
|
19
27
|
*/
|
|
20
28
|
export async function readJson<T = unknown>(
|
|
21
29
|
response: Response,
|
|
30
|
+
context = "PipesHub request",
|
|
22
31
|
): Promise<{ ok: true; value: T } | { ok: false; result: CallToolResult }> {
|
|
32
|
+
const httpErr = await httpErrorResult(response, context);
|
|
33
|
+
if (httpErr) return { ok: false, result: httpErr };
|
|
34
|
+
|
|
23
35
|
const text = await response.text();
|
|
24
36
|
if (!text) {
|
|
25
37
|
return {
|
|
@@ -48,6 +60,24 @@ export async function readJson<T = unknown>(
|
|
|
48
60
|
}
|
|
49
61
|
}
|
|
50
62
|
|
|
63
|
+
/**
|
|
64
|
+
* Reject an access token whose own expiry has already passed.
|
|
65
|
+
*
|
|
66
|
+
* Expiry is the one part of a credential's validity that can be established
|
|
67
|
+
* without asking the server, so it is worth checking before spending a
|
|
68
|
+
* round-trip — and it still answers when the server is unreachable. Returns
|
|
69
|
+
* `null` when the token is unexpired or carries no usable `exp`.
|
|
70
|
+
*/
|
|
71
|
+
export function expiredTokenError(exp: unknown): CallToolResult | null {
|
|
72
|
+
if (typeof exp !== "number" || !Number.isFinite(exp)) return null;
|
|
73
|
+
if (exp * 1000 > Date.now()) return null;
|
|
74
|
+
return errorResult(
|
|
75
|
+
`The access token expired on ${new Date(exp * 1000).toISOString()}. `
|
|
76
|
+
+ "Mint a new personal access token in PipesHub under "
|
|
77
|
+
+ "Developer Settings → Personal Access Tokens.",
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
51
81
|
/** Return a CallToolResult holding a single JSON-stringified text block. */
|
|
52
82
|
export function jsonResult(value: unknown): CallToolResult {
|
|
53
83
|
return {
|
|
@@ -105,7 +135,12 @@ export async function httpErrorResult(
|
|
|
105
135
|
}
|
|
106
136
|
}
|
|
107
137
|
|
|
108
|
-
|
|
138
|
+
// The server's reason rarely ends in punctuation, which runs it straight
|
|
139
|
+
// into the hint below ("Invalid token Check that ...").
|
|
140
|
+
const reason = message.slice(0, 400).trim();
|
|
141
|
+
const detail = reason
|
|
142
|
+
? ` ${/[.!?]$/.test(reason) ? reason : `${reason}.`}`
|
|
143
|
+
: "";
|
|
109
144
|
const auth = (response.status === 401 || response.status === 403)
|
|
110
145
|
? " Check that the bearer token / credentials are valid and not expired."
|
|
111
146
|
: "";
|
|
@@ -122,7 +157,12 @@ export async function httpErrorResult(
|
|
|
122
157
|
export async function readValidated<T>(
|
|
123
158
|
response: Response,
|
|
124
159
|
schema: z.ZodType<T>,
|
|
160
|
+
context = "PipesHub request",
|
|
125
161
|
): Promise<{ ok: true; value: T } | { ok: false; result: CallToolResult }> {
|
|
162
|
+
// Same reasoning as readJson: never let a non-2xx body reach the parser.
|
|
163
|
+
const httpErr = await httpErrorResult(response, context);
|
|
164
|
+
if (httpErr) return { ok: false, result: httpErr };
|
|
165
|
+
|
|
126
166
|
const text = await response.text();
|
|
127
167
|
if (!text) {
|
|
128
168
|
return { ok: false, result: errorResult("Empty response from server") };
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
decodeBearer,
|
|
13
13
|
errorResult,
|
|
14
14
|
jsonResult,
|
|
15
|
+
expiredTokenError,
|
|
15
16
|
readJson,
|
|
16
17
|
} from "./_helpers.js";
|
|
17
18
|
|
|
@@ -24,8 +25,8 @@ const args = {
|
|
|
24
25
|
"list_my_teams",
|
|
25
26
|
]).describe(
|
|
26
27
|
"What to do:\n"
|
|
27
|
-
+ "- `whoami` — return the authenticated user's identity
|
|
28
|
-
+ "the
|
|
28
|
+
+ "- `whoami` — return the authenticated user's identity, confirmed "
|
|
29
|
+
+ "against the server. No other args needed.\n"
|
|
29
30
|
+ "- `list_users` — paginated list of org users. Optional `page`, "
|
|
30
31
|
+ "`limit`, `search` (substring match against name or email).\n"
|
|
31
32
|
+ "- `get_user` — full profile for one user. Required `userId`. "
|
|
@@ -56,7 +57,8 @@ actions — pick the right \`action\`:
|
|
|
56
57
|
|
|
57
58
|
- \`whoami\` — who is the caller? Use this whenever you need the
|
|
58
59
|
authenticated user's own id, email, or full name (e.g. before
|
|
59
|
-
\`get_user\` on themselves).
|
|
60
|
+
\`get_user\` on themselves). Errors if the credential is expired
|
|
61
|
+
or revoked.
|
|
60
62
|
- \`list_users\` — search / page through org users.
|
|
61
63
|
- \`get_user\` — full \`User\` document for one user (requires \`userId\`).
|
|
62
64
|
- \`list_groups\` — list user groups with \`userCount\`.
|
|
@@ -86,6 +88,56 @@ Output shape varies by action; see each action's docs above.`,
|
|
|
86
88
|
+ "their email and use `list_users` with `search`.",
|
|
87
89
|
);
|
|
88
90
|
}
|
|
91
|
+
// The claims come out of the local token, which proves nothing about
|
|
92
|
+
// whether the server still accepts it — a revoked token carries a
|
|
93
|
+
// perfectly good name and org. Since whoami is the command people run
|
|
94
|
+
// to check "is my login working?", answering from the token alone
|
|
95
|
+
// gives a confident yes in exactly the case that matters.
|
|
96
|
+
//
|
|
97
|
+
// Expiry is checkable offline, so check it first: it is the common
|
|
98
|
+
// case and costs no round-trip.
|
|
99
|
+
const exp = claims["exp"];
|
|
100
|
+
const expired = expiredTokenError(exp);
|
|
101
|
+
if (expired) return expired;
|
|
102
|
+
const tokenExpiresAt = typeof exp === "number"
|
|
103
|
+
? new Date(exp * 1000).toISOString()
|
|
104
|
+
: undefined;
|
|
105
|
+
|
|
106
|
+
// Revocation can only be established by asking the server. get_user on
|
|
107
|
+
// the caller's own id needs `user:read`, which whoami's callers already
|
|
108
|
+
// hold, and returns 401 for a rejected credential.
|
|
109
|
+
const userId = claims["userId"];
|
|
110
|
+
let verified: true | "unchecked" = "unchecked";
|
|
111
|
+
let unverifiedReason: string | undefined =
|
|
112
|
+
"No userId claim in the token, so the identity could not be "
|
|
113
|
+
+ "confirmed with the server.";
|
|
114
|
+
|
|
115
|
+
if (typeof userId === "string" && userId) {
|
|
116
|
+
const [probe] = await usersGetUserById(client, { id: userId }, {
|
|
117
|
+
fetchOptions,
|
|
118
|
+
}).$inspect();
|
|
119
|
+
|
|
120
|
+
if (!probe.ok) {
|
|
121
|
+
unverifiedReason = `Could not reach PipesHub to confirm the `
|
|
122
|
+
+ `identity (${probe.error.message}). The details below come `
|
|
123
|
+
+ `from the token itself.`;
|
|
124
|
+
} else if (probe.value.status === 401) {
|
|
125
|
+
return errorResult(
|
|
126
|
+
"PipesHub rejected this access token (HTTP 401 Unauthorized), "
|
|
127
|
+
+ "so the identity in it is no longer valid — it has most "
|
|
128
|
+
+ "likely been revoked. Mint a new personal access token "
|
|
129
|
+
+ "under Developer Settings → Personal Access Tokens.",
|
|
130
|
+
);
|
|
131
|
+
} else if (probe.value.ok) {
|
|
132
|
+
verified = true;
|
|
133
|
+
unverifiedReason = undefined;
|
|
134
|
+
} else {
|
|
135
|
+
unverifiedReason = `PipesHub returned HTTP ${probe.value.status} `
|
|
136
|
+
+ `when confirming the identity, so it could not be checked. `
|
|
137
|
+
+ `The details below come from the token itself.`;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
89
141
|
return jsonResult({
|
|
90
142
|
userId: claims["userId"],
|
|
91
143
|
orgId: claims["orgId"],
|
|
@@ -93,6 +145,12 @@ Output shape varies by action; see each action's docs above.`,
|
|
|
93
145
|
fullName: claims["fullName"],
|
|
94
146
|
mobile: claims["mobile"],
|
|
95
147
|
userSlug: claims["userSlug"],
|
|
148
|
+
tokenExpiresAt,
|
|
149
|
+
// Never `false`: that reads as "the server rejected this identity",
|
|
150
|
+
// which is a different and much more alarming claim than "this was
|
|
151
|
+
// not checked". A rejection returns an error above instead.
|
|
152
|
+
identityVerified: verified,
|
|
153
|
+
note: unverifiedReason,
|
|
96
154
|
});
|
|
97
155
|
}
|
|
98
156
|
|
|
@@ -103,7 +161,7 @@ Output shape varies by action; see each action's docs above.`,
|
|
|
103
161
|
search: args.search,
|
|
104
162
|
}, { fetchOptions }).$inspect();
|
|
105
163
|
if (!result.ok) return errorResult(result.error.message);
|
|
106
|
-
const parsed = await readJson(result.value);
|
|
164
|
+
const parsed = await readJson(result.value, "User listing");
|
|
107
165
|
if (!parsed.ok) return parsed.result;
|
|
108
166
|
return jsonResult(parsed.value);
|
|
109
167
|
}
|
|
@@ -120,7 +178,7 @@ Output shape varies by action; see each action's docs above.`,
|
|
|
120
178
|
id: args.userId,
|
|
121
179
|
}, { fetchOptions }).$inspect();
|
|
122
180
|
if (!result.ok) return errorResult(result.error.message);
|
|
123
|
-
const parsed = await readJson(result.value);
|
|
181
|
+
const parsed = await readJson(result.value, "User lookup");
|
|
124
182
|
if (!parsed.ok) return parsed.result;
|
|
125
183
|
return jsonResult(parsed.value);
|
|
126
184
|
}
|
|
@@ -132,7 +190,7 @@ Output shape varies by action; see each action's docs above.`,
|
|
|
132
190
|
search: args.search,
|
|
133
191
|
}, { fetchOptions }).$inspect();
|
|
134
192
|
if (!result.ok) return errorResult(result.error.message);
|
|
135
|
-
const parsed = await readJson(result.value);
|
|
193
|
+
const parsed = await readJson(result.value, "Group listing");
|
|
136
194
|
if (!parsed.ok) return parsed.result;
|
|
137
195
|
return jsonResult(parsed.value);
|
|
138
196
|
}
|
|
@@ -144,7 +202,7 @@ Output shape varies by action; see each action's docs above.`,
|
|
|
144
202
|
search: args.search,
|
|
145
203
|
}, { fetchOptions }).$inspect();
|
|
146
204
|
if (!result.ok) return errorResult(result.error.message);
|
|
147
|
-
const parsed = await readJson(result.value);
|
|
205
|
+
const parsed = await readJson(result.value, "Team listing");
|
|
148
206
|
if (!parsed.ok) return parsed.result;
|
|
149
207
|
return jsonResult(parsed.value);
|
|
150
208
|
}
|
|
@@ -80,7 +80,7 @@ When presenting results to the user, link each record using its
|
|
|
80
80
|
status?: string;
|
|
81
81
|
message?: string;
|
|
82
82
|
};
|
|
83
|
-
}>(result.value);
|
|
83
|
+
}>(result.value, "PipesHub search");
|
|
84
84
|
if (!parsed.ok) return parsed.result;
|
|
85
85
|
|
|
86
86
|
const sr = parsed.value.searchResponse ?? {};
|
|
@@ -57,7 +57,7 @@ are returned by default; pass \`include\` to override.`,
|
|
|
57
57
|
limit: 200,
|
|
58
58
|
}, { fetchOptions }).$inspect();
|
|
59
59
|
if (!r.ok) return errorResult(`sources: ${r.error.message}`);
|
|
60
|
-
const parsed = await readJson<{ items?: any[] }>(r.value);
|
|
60
|
+
const parsed = await readJson<{ items?: any[] }>(r.value, "Knowledge base listing");
|
|
61
61
|
if (!parsed.ok) return parsed.result;
|
|
62
62
|
result["sources"] = (parsed.value.items ?? []).map((n: any) => ({
|
|
63
63
|
id: n.id,
|
|
@@ -79,7 +79,7 @@ are returned by default; pass \`include\` to override.`,
|
|
|
79
79
|
modelType,
|
|
80
80
|
}, { fetchOptions }).$inspect();
|
|
81
81
|
if (!r.ok) return errorResult(`${key}: ${r.error.message}`);
|
|
82
|
-
const parsed = await readJson<{ models?: any[] }>(r.value);
|
|
82
|
+
const parsed = await readJson<{ models?: any[] }>(r.value, "Model listing");
|
|
83
83
|
if (!parsed.ok) return parsed.result;
|
|
84
84
|
result[key] = (parsed.value.models ?? []).map((m: any) => ({
|
|
85
85
|
modelKey: m.modelKey,
|
package/src/tool-names.ts
CHANGED
|
@@ -22,7 +22,7 @@ export const toolNames: Array<{ name: string; description: string }>= [
|
|
|
22
22
|
},
|
|
23
23
|
{
|
|
24
24
|
"name": "pipeshub_directory",
|
|
25
|
-
"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."
|
|
25
|
+
"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."
|
|
26
26
|
},
|
|
27
27
|
{
|
|
28
28
|
"name": "pipeshub_agents",
|