@pipeshub-ai/mcp 2.1.0 → 2.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.
Files changed (146) hide show
  1. package/README.md +92 -2
  2. package/bin/mcp-server.js +976 -169
  3. package/bin/mcp-server.js.map +28 -15
  4. package/bin/pipeshub.js +946 -0
  5. package/bin/pipeshub.js.map +14 -0
  6. package/esm/cli/client.d.ts +54 -0
  7. package/esm/cli/client.d.ts.map +1 -0
  8. package/esm/cli/client.js +230 -0
  9. package/esm/cli/client.js.map +1 -0
  10. package/esm/cli/commands.d.ts +30 -0
  11. package/esm/cli/commands.d.ts.map +1 -0
  12. package/esm/cli/commands.js +321 -0
  13. package/esm/cli/commands.js.map +1 -0
  14. package/esm/cli/config.d.ts +73 -0
  15. package/esm/cli/config.d.ts.map +1 -0
  16. package/esm/cli/config.js +218 -0
  17. package/esm/cli/config.js.map +1 -0
  18. package/esm/cli/init-qm.d.ts +11 -0
  19. package/esm/cli/init-qm.d.ts.map +1 -0
  20. package/esm/cli/init-qm.js +170 -0
  21. package/esm/cli/init-qm.js.map +1 -0
  22. package/esm/cli/pipeshub.d.ts +2 -0
  23. package/esm/cli/pipeshub.d.ts.map +1 -0
  24. package/esm/cli/pipeshub.js +296 -0
  25. package/esm/cli/pipeshub.js.map +1 -0
  26. package/esm/funcs/connectorGetRecordContent.d.ts +43 -0
  27. package/esm/funcs/connectorGetRecordContent.d.ts.map +1 -0
  28. package/esm/funcs/connectorGetRecordContent.js +114 -0
  29. package/esm/funcs/connectorGetRecordContent.js.map +1 -0
  30. package/esm/funcs/connectorLookupRecordByIdentifier.d.ts +68 -0
  31. package/esm/funcs/connectorLookupRecordByIdentifier.d.ts.map +1 -0
  32. package/esm/funcs/connectorLookupRecordByIdentifier.js +138 -0
  33. package/esm/funcs/connectorLookupRecordByIdentifier.js.map +1 -0
  34. package/esm/funcs/connectorNavigateKnowledgeGraph.d.ts +75 -0
  35. package/esm/funcs/connectorNavigateKnowledgeGraph.d.ts.map +1 -0
  36. package/esm/funcs/connectorNavigateKnowledgeGraph.js +152 -0
  37. package/esm/funcs/connectorNavigateKnowledgeGraph.js.map +1 -0
  38. package/esm/funcs/conversationsStreamConversation.js +1 -1
  39. package/esm/funcs/conversationsStreamConversation.js.map +1 -1
  40. package/esm/funcs/userGroupsGetAllUserGroups.js +1 -1
  41. package/esm/funcs/userGroupsGetAllUserGroups.js.map +1 -1
  42. package/esm/hooks/registration.d.ts.map +1 -1
  43. package/esm/hooks/registration.js +2 -1
  44. package/esm/hooks/registration.js.map +1 -1
  45. package/esm/hooks/request-context.d.ts +10 -0
  46. package/esm/hooks/request-context.d.ts.map +1 -0
  47. package/esm/hooks/request-context.js +38 -0
  48. package/esm/hooks/request-context.js.map +1 -0
  49. package/esm/hooks/requestid.d.ts +5 -0
  50. package/esm/hooks/requestid.d.ts.map +1 -0
  51. package/esm/hooks/requestid.js +58 -0
  52. package/esm/hooks/requestid.js.map +1 -0
  53. package/esm/lib/base64.d.ts +1 -1
  54. package/esm/lib/base64.d.ts.map +1 -1
  55. package/esm/lib/base64.js +6 -3
  56. package/esm/lib/base64.js.map +1 -1
  57. package/esm/lib/bytes-to-base64.d.ts +16 -0
  58. package/esm/lib/bytes-to-base64.d.ts.map +1 -0
  59. package/esm/lib/bytes-to-base64.js +23 -0
  60. package/esm/lib/bytes-to-base64.js.map +1 -0
  61. package/esm/mcp-server/instructions.d.ts +1 -1
  62. package/esm/mcp-server/instructions.d.ts.map +1 -1
  63. package/esm/mcp-server/instructions.js +62 -9
  64. package/esm/mcp-server/instructions.js.map +1 -1
  65. package/esm/mcp-server/server.d.ts.map +1 -1
  66. package/esm/mcp-server/server.js +10 -3
  67. package/esm/mcp-server/server.js.map +1 -1
  68. package/esm/mcp-server/shared.d.ts +2 -2
  69. package/esm/mcp-server/shared.d.ts.map +1 -1
  70. package/esm/mcp-server/shared.js +7 -3
  71. package/esm/mcp-server/shared.js.map +1 -1
  72. package/esm/mcp-server/tools/_agui.d.ts +34 -0
  73. package/esm/mcp-server/tools/_agui.d.ts.map +1 -0
  74. package/esm/mcp-server/tools/_agui.js +91 -0
  75. package/esm/mcp-server/tools/_agui.js.map +1 -0
  76. package/esm/mcp-server/tools/_helpers.d.ts.map +1 -1
  77. package/esm/mcp-server/tools/_helpers.js +13 -6
  78. package/esm/mcp-server/tools/_helpers.js.map +1 -1
  79. package/esm/mcp-server/tools/pipeshubChat.d.ts +0 -3
  80. package/esm/mcp-server/tools/pipeshubChat.d.ts.map +1 -1
  81. package/esm/mcp-server/tools/pipeshubChat.js +75 -92
  82. package/esm/mcp-server/tools/pipeshubChat.js.map +1 -1
  83. package/esm/mcp-server/tools/pipeshubGetRecordContent.d.ts +125 -0
  84. package/esm/mcp-server/tools/pipeshubGetRecordContent.d.ts.map +1 -0
  85. package/esm/mcp-server/tools/pipeshubGetRecordContent.js +214 -0
  86. package/esm/mcp-server/tools/pipeshubGetRecordContent.js.map +1 -0
  87. package/esm/mcp-server/tools/pipeshubSearch.d.ts.map +1 -1
  88. package/esm/mcp-server/tools/pipeshubSearch.js +22 -5
  89. package/esm/mcp-server/tools/pipeshubSearch.js.map +1 -1
  90. package/esm/mcp-server/tools.d.ts.map +1 -1
  91. package/esm/mcp-server/tools.js +13 -1
  92. package/esm/mcp-server/tools.js.map +1 -1
  93. package/esm/models/availablemodelsresponse.d.ts +1 -1
  94. package/esm/models/conversation.d.ts +1 -1
  95. package/esm/models/getrecordcontentop.d.ts +6 -0
  96. package/esm/models/getrecordcontentop.d.ts.map +1 -0
  97. package/esm/models/getrecordcontentop.js +5 -0
  98. package/esm/models/getrecordcontentop.js.map +1 -0
  99. package/esm/models/lookuprecordbyidentifierop.d.ts +7 -0
  100. package/esm/models/lookuprecordbyidentifierop.d.ts.map +1 -0
  101. package/esm/models/lookuprecordbyidentifierop.js +14 -0
  102. package/esm/models/lookuprecordbyidentifierop.js.map +1 -0
  103. package/esm/models/navigateknowledgegraphop.d.ts +14 -0
  104. package/esm/models/navigateknowledgegraphop.d.ts.map +1 -0
  105. package/esm/models/navigateknowledgegraphop.js +25 -0
  106. package/esm/models/navigateknowledgegraphop.js.map +1 -0
  107. package/esm/models/userteamsresponse.d.ts +1 -1
  108. package/esm/tool-names.d.ts.map +1 -1
  109. package/esm/tool-names.js +6 -2
  110. package/esm/tool-names.js.map +1 -1
  111. package/package.json +4 -2
  112. package/qm/README.md +247 -0
  113. package/qm/SECURITY.md +134 -0
  114. package/qm/TROUBLESHOOTING.md +218 -0
  115. package/qm/qm.config.fragment.jsonc +42 -0
  116. package/qm/sandbox/Dockerfile +22 -0
  117. package/qm/sandbox/skills/pipeshub/SKILL.md +69 -0
  118. package/qm/sandbox/tools/pipeshub/tool.json +36 -0
  119. package/src/cli/client.ts +272 -0
  120. package/src/cli/commands.ts +403 -0
  121. package/src/cli/config.ts +229 -0
  122. package/src/cli/init-qm.ts +215 -0
  123. package/src/cli/pipeshub.ts +333 -0
  124. package/src/funcs/connectorGetRecordContent.ts +179 -0
  125. package/src/funcs/connectorLookupRecordByIdentifier.ts +200 -0
  126. package/src/funcs/connectorNavigateKnowledgeGraph.ts +215 -0
  127. package/src/funcs/conversationsStreamConversation.ts +1 -1
  128. package/src/funcs/userGroupsGetAllUserGroups.ts +1 -1
  129. package/src/hooks/registration.ts +2 -1
  130. package/src/hooks/request-context.ts +47 -0
  131. package/src/hooks/requestid.ts +62 -0
  132. package/src/lib/base64.ts +6 -3
  133. package/src/lib/bytes-to-base64.ts +24 -0
  134. package/src/mcp-server/instructions.ts +62 -9
  135. package/src/mcp-server/server.ts +11 -3
  136. package/src/mcp-server/shared.ts +7 -3
  137. package/src/mcp-server/tools/_agui.ts +138 -0
  138. package/src/mcp-server/tools/_helpers.ts +13 -6
  139. package/src/mcp-server/tools/pipeshubChat.ts +78 -91
  140. package/src/mcp-server/tools/pipeshubGetRecordContent.ts +251 -0
  141. package/src/mcp-server/tools/pipeshubSearch.ts +22 -5
  142. package/src/mcp-server/tools.ts +14 -1
  143. package/src/models/getrecordcontentop.ts +11 -0
  144. package/src/models/lookuprecordbyidentifierop.ts +26 -0
  145. package/src/models/navigateknowledgegraphop.ts +56 -0
  146. package/src/tool-names.ts +6 -2
@@ -0,0 +1,58 @@
1
+ /*
2
+ * Stamp an x-request-id trace header onto every outbound SDK request, reusing
3
+ * the id bound for the current MCP tool/resource/prompt call (see
4
+ * request-context.ts) so all backend calls from one invocation share it.
5
+ *
6
+ * Format mirrors the TypeScript SDK's own RequestIDHook: `mcp-<userId>-<random>`
7
+ * when the bearer JWT carries a userId claim, else `mcp-<random>`. The userId
8
+ * is only knowable once a request actually carries a resolved Authorization
9
+ * header, so it's decoded off the first outbound request of the tool call and
10
+ * cached on the bound context for every subsequent call to reuse verbatim.
11
+ */
12
+ import { getRequestContextStore, newRequestId } from "./request-context.js";
13
+ const REQUEST_ID_HEADER = "x-request-id";
14
+ /** Decodes the JWT payload without verifying the signature. */
15
+ function decodeJwtPayload(token) {
16
+ try {
17
+ const base64Url = token.split(".")[1];
18
+ if (!base64Url)
19
+ return null;
20
+ const base64 = base64Url.replace(/-/g, "+").replace(/_/g, "/");
21
+ const padded = base64 + "=".repeat((4 - (base64.length % 4)) % 4);
22
+ const claims = JSON.parse(Buffer.from(padded, "base64").toString("utf8"));
23
+ return typeof claims === "object" && claims !== null ? claims : null;
24
+ }
25
+ catch {
26
+ return null;
27
+ }
28
+ }
29
+ function userIdFromRequest(request) {
30
+ const auth = request.headers.get("authorization") ?? "";
31
+ if (!auth.toLowerCase().startsWith("bearer "))
32
+ return null;
33
+ const token = auth.slice(7).trim();
34
+ const claims = decodeJwtPayload(token);
35
+ return claims?.["userId"] || null;
36
+ }
37
+ export class RequestIDHook {
38
+ beforeRequest(_hookCtx, request) {
39
+ if (request.headers.get(REQUEST_ID_HEADER)) {
40
+ return request;
41
+ }
42
+ const store = getRequestContextStore();
43
+ if (!store) {
44
+ // No bound tool-call context (shouldn't happen in practice).
45
+ request.headers.set(REQUEST_ID_HEADER, newRequestId());
46
+ return request;
47
+ }
48
+ if (!store.finalId) {
49
+ const userId = userIdFromRequest(request);
50
+ store.finalId = userId
51
+ ? `mcp-${userId}-${store.random}`
52
+ : `mcp-${store.random}`;
53
+ }
54
+ request.headers.set(REQUEST_ID_HEADER, store.finalId);
55
+ return request;
56
+ }
57
+ }
58
+ //# sourceMappingURL=requestid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requestid.js","sourceRoot":"","sources":["../../src/hooks/requestid.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,sBAAsB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAG5E,MAAM,iBAAiB,GAAG,cAAc,CAAC;AAEzC,+DAA+D;AAC/D,SAAS,gBAAgB,CAAC,KAAa;IACrC,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACtC,IAAI,CAAC,SAAS;YAAE,OAAO,IAAI,CAAC;QAC5B,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAC/D,MAAM,MAAM,GAAG,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAClE,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;QAC1E,OAAO,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;IACvE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,iBAAiB,CAAC,OAAgB;IACzC,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,EAAE,CAAC;IACxD,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,IAAI,CAAC;IAC3D,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACnC,MAAM,MAAM,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;IACvC,OAAQ,MAAM,EAAE,CAAC,QAAQ,CAAY,IAAI,IAAI,CAAC;AAChD,CAAC;AAED,MAAM,OAAO,aAAa;IACxB,aAAa,CAAC,QAA8B,EAAE,OAAgB;QAC5D,IAAI,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,EAAE,CAAC;YAC3C,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,MAAM,KAAK,GAAG,sBAAsB,EAAE,CAAC;QACvC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,6DAA6D;YAC7D,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,YAAY,EAAE,CAAC,CAAC;YACvD,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;YACnB,MAAM,MAAM,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;YAC1C,KAAK,CAAC,OAAO,GAAG,MAAM;gBACpB,CAAC,CAAC,OAAO,MAAM,IAAI,KAAK,CAAC,MAAM,EAAE;gBACjC,CAAC,CAAC,OAAO,KAAK,CAAC,MAAM,EAAE,CAAC;QAC5B,CAAC;QACD,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QACtD,OAAO,OAAO,CAAC;IACjB,CAAC;CACF"}
@@ -1,5 +1,5 @@
1
1
  import * as z from "zod";
2
- export declare function bytesToBase64(u8arr: Uint8Array): string;
2
+ export { bytesToBase64 } from "./bytes-to-base64.js";
3
3
  export declare function bytesFromBase64(encoded: string): Uint8Array;
4
4
  export declare function stringToBytes(str: string): Uint8Array;
5
5
  export declare function stringFromBytes(u8arr: Uint8Array): string;
@@ -1 +1 @@
1
- {"version":3,"file":"base64.d.ts","sourceRoot":"","sources":["../../src/lib/base64.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAEzB,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAEvD;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,CAE3D;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAErD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAEzD;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED,eAAO,MAAM,WAAW,kKAEkB,CAAC;AAE3C,eAAO,MAAM,UAAU,kKAEqB,CAAC"}
1
+ {"version":3,"file":"base64.d.ts","sourceRoot":"","sources":["../../src/lib/base64.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAEzB,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAGrD,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,CAE3D;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAErD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAEzD;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED,eAAO,MAAM,WAAW,kKAEkB,CAAC;AAE3C,eAAO,MAAM,UAAU,kKAEqB,CAAC"}
package/esm/lib/base64.js CHANGED
@@ -1,10 +1,13 @@
1
1
  /*
2
2
  * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
3
+ *
4
+ * Exception: `bytesToBase64` is re-exported from the hand-maintained
5
+ * `./bytes-to-base64.js` (see that file and `.genignore`). Do not restore
6
+ * the generated one-liner — it overflows the stack on binary payloads.
3
7
  */
4
8
  import * as z from "zod";
5
- export function bytesToBase64(u8arr) {
6
- return btoa(String.fromCodePoint(...u8arr));
7
- }
9
+ export { bytesToBase64 } from "./bytes-to-base64.js";
10
+ import { bytesToBase64 } from "./bytes-to-base64.js";
8
11
  export function bytesFromBase64(encoded) {
9
12
  return Uint8Array.from(atob(encoded), (c) => c.charCodeAt(0));
10
13
  }
@@ -1 +1 @@
1
- {"version":3,"file":"base64.js","sourceRoot":"","sources":["../../src/lib/base64.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAEzB,MAAM,UAAU,aAAa,CAAC,KAAiB;IAC7C,OAAO,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAAe;IAC7C,OAAO,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAiB;IAC/C,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,OAAO,aAAa,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,MAAc;IAC7C,OAAO,eAAe,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC;KACzB,MAAM,CAAa,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,YAAY,UAAU,CAAC;KAClD,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC;AAE3C,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC;KACxB,MAAM,CAAa,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,YAAY,UAAU,CAAC;KAClD,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"base64.js","sourceRoot":"","sources":["../../src/lib/base64.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAEzB,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,MAAM,UAAU,eAAe,CAAC,OAAe;IAC7C,OAAO,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAiB;IAC/C,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,OAAO,aAAa,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,MAAc;IAC7C,OAAO,eAAe,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC;KACzB,MAAM,CAAa,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,YAAY,UAAU,CAAC;KAClD,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC;AAE3C,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC;KACxB,MAAM,CAAa,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,YAAY,UAAU,CAAC;KAClD,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Hand-maintained base64 encoder for binary payloads.
3
+ *
4
+ * Speakeasy's generated helper is:
5
+ * btoa(String.fromCodePoint(...u8arr))
6
+ * which passes one argument per byte and throws "Maximum call stack size
7
+ * exceeded" once the array is larger than the engine's argument limit
8
+ * (between 64 KB and 128 KB on Node 24). That is smaller than a typical
9
+ * PDF or image, so binary MCP results fail outright.
10
+ *
11
+ * Keep this file out of Speakeasy regeneration (see `.genignore`). The
12
+ * generated wrappers in `src/lib/base64.ts` and `src/mcp-server/shared.ts`
13
+ * re-export / call through here.
14
+ */
15
+ export declare function bytesToBase64(u8arr: Uint8Array): string;
16
+ //# sourceMappingURL=bytes-to-base64.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bytes-to-base64.d.ts","sourceRoot":"","sources":["../../src/lib/bytes-to-base64.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAMvD"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Hand-maintained base64 encoder for binary payloads.
3
+ *
4
+ * Speakeasy's generated helper is:
5
+ * btoa(String.fromCodePoint(...u8arr))
6
+ * which passes one argument per byte and throws "Maximum call stack size
7
+ * exceeded" once the array is larger than the engine's argument limit
8
+ * (between 64 KB and 128 KB on Node 24). That is smaller than a typical
9
+ * PDF or image, so binary MCP results fail outright.
10
+ *
11
+ * Keep this file out of Speakeasy regeneration (see `.genignore`). The
12
+ * generated wrappers in `src/lib/base64.ts` and `src/mcp-server/shared.ts`
13
+ * re-export / call through here.
14
+ */
15
+ const BASE64_CHUNK = 0x8000;
16
+ export function bytesToBase64(u8arr) {
17
+ let binary = "";
18
+ for (let i = 0; i < u8arr.length; i += BASE64_CHUNK) {
19
+ binary += String.fromCharCode(...u8arr.subarray(i, i + BASE64_CHUNK));
20
+ }
21
+ return btoa(binary);
22
+ }
23
+ //# sourceMappingURL=bytes-to-base64.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bytes-to-base64.js","sourceRoot":"","sources":["../../src/lib/bytes-to-base64.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,MAAM,YAAY,GAAG,MAAM,CAAC;AAE5B,MAAM,UAAU,aAAa,CAAC,KAAiB;IAC7C,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,YAAY,EAAE,CAAC;QACpD,MAAM,IAAI,MAAM,CAAC,YAAY,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC;AACtB,CAAC"}
@@ -1,2 +1,2 @@
1
- export declare const PIPESHUB_INSTRUCTIONS = "# PipesHub MCP \u2014 instructions for the LLM\n\nPipesHub is the user's workplace AI platform. It indexes their documents,\nknowledge base content, and connector sources (Drive, Box, Confluence,\nSlack, Jira, Gmail, ...). When in doubt, the answer is in PipesHub.\n\n## Default tool: `pipeshub_chat`\n\n**Use `pipeshub_chat` for any question that could plausibly be answered\nby the user's PipesHub-indexed data.** That includes:\n\n- Anything about a specific document, file, report, ticket, message, or\n page (e.g. \"what's in the Q4 sales report?\", \"summarize the langchain\n doc\", \"what did Aashil say about onboarding?\").\n- Anything about company / org policies, processes, decisions, or\n history (e.g. \"what's our vacation policy?\", \"who owns the auth\n service?\").\n- Anything explicitly mentioning PipesHub itself, or its sources\n (Drive / Box / Confluence / Slack / Gmail / Jira / etc.) when the\n user has those connected.\n- Open-ended \"what do we know about X\" questions where the answer\n likely lives in the org's documents.\n\nDo NOT answer those from your own knowledge \u2014 `pipeshub_chat` grounds\nthe answer in the user's actual indexed content and returns citations\nthe user can verify.\n\n## When to use the other tools\n\n- `pipeshub_search` \u2014 only when the user asks specifically to **find /\n locate** a document by name or topic (so you can hand them a list, or\n resolve a filename to a `recordId` for download). For \"what does\n the doc say?\" use `pipeshub_chat` instead \u2014 it does the retrieval\n internally.\n- `pipeshub_download_record` \u2014 when the user wants the actual file\n bytes (download, attach, open). Get the `recordId` either from\n citations on a prior `pipeshub_chat` response or from\n `pipeshub_search`.\n- `pipeshub_directory` \u2014 people, groups, teams, and `whoami` lookups.\n Not for documents.\n- `pipeshub_sources` \u2014 call once at the start of a session to discover\n which connectors / KB / models are available, then cache the result.\n- `pipeshub_agents` \u2014 list the org's configured **agents** (specialized\n assistants with their own prompt, tools, and knowledge scope).\n\n## Agents\n\nSome orgs configure **agents** for specific jobs (e.g. a Slack messenger, a\nJira ticket creator, a Salesforce CRM updater). To run a turn against an\nagent, call `pipeshub_chat` with its `agentId` (from `pipeshub_agents`)\n\u2014 optionally with an agent `chatMode` (`auto` by default, or `quick` /\n`verification` / `deep`). Keep passing the same `agentId` plus the\nreturned `conversationId` on follow-up turns.\n\n**When to route to an agent vs plain chat:**\n- The user names a system/action that maps to an agent (e.g. \"post to\n Slack\", \"create a Jira ticket\", \"update the Salesforce deal\") \u2192 call\n `pipeshub_agents`, pick the matching agent, and use it.\n- Plain question about the org's knowledge or the public web \u2192 just use\n `pipeshub_chat` (no `agentId`) with `internal_search` or `web_search`.\n\n**If you are unsure which agent or route fits the request**, call\n`pipeshub_agents` FIRST and read the returned names/descriptions, then\neither pick the best match or present the list to the user and let them\nchoose. Do NOT guess an agent blindly, and do NOT refuse \u2014 list the agents\nand decide from real data. The list may be empty (no agents configured),\nin which case fall back to plain `pipeshub_chat`.\n\n## Conversation lifecycle\n\n`pipeshub_chat` is a single tool that handles both starting and\ncontinuing conversations (plain or with an `agentId`). On the first turn\nomit `conversationId`; on every subsequent turn pass back the\n`conversationId` returned by the previous call (along with the same\n`agentId` if you used one). Server-side context is preserved \u2014 do NOT\nreplay prior messages. Only start a fresh conversation when the user\nexplicitly asks to clear context.\n";
1
+ export declare const PIPESHUB_INSTRUCTIONS = "# PipesHub MCP \u2014 instructions for the LLM\n\nPipesHub is the user's workplace AI platform. It indexes their documents,\nknowledge base content, and connector sources (Drive, Box, Confluence,\nSlack, Jira, Gmail, ...). When in doubt, the answer is in PipesHub.\n\n## Full-document tasks: `pipeshub_search` \u2192 `pipeshub_get_record_content`\n\n`pipeshub_chat` answers from a handful of retrieved passages \u2014 it never\nreads a whole document. Whenever the task depends on a document's\nCOMPLETE content, fetch the document itself:\n\n1. `pipeshub_search` with the document's name / topic.\n2. Take the top hit's `recordId`.\n3. `pipeshub_get_record_content`, and answer from the returned content.\n\nTasks that need this path \u2014 anything where missing part of the document\ncould make the answer wrong:\n\n- Summarize / TL;DR / key points / takeaways / action items of a doc.\n- Extract or list ALL of something (dates, owners, requirements, ...).\n- Check whether / where a doc mentions something.\n- Translate, rewrite, outline, review, or reformat a doc.\n- Compare named docs (fetch each `recordId`).\n- Any question explicitly scoped to ONE named document \u2014 chat retrieval\n cannot be restricted to a single record.\n\n## Default tool: `pipeshub_chat`\n\n**Use `pipeshub_chat` for any question that could plausibly be answered\nby the user's PipesHub-indexed data** and is not a full-document task:\n\n- A question that may span several documents, or where you don't yet\n know which record holds the answer (e.g. \"what did Aashil say about\n onboarding?\").\n- Anything about company / org policies, processes, decisions, or\n history (e.g. \"what's our vacation policy?\", \"who owns the auth\n service?\").\n- Anything explicitly mentioning PipesHub itself, or its sources\n (Drive / Box / Confluence / Slack / Gmail / Jira / etc.) when the\n user has those connected.\n- Open-ended \"what do we know about X\" questions where the answer\n likely lives in the org's documents.\n\nDo NOT answer those from your own knowledge \u2014 `pipeshub_chat` grounds\nthe answer in the user's actual indexed content and returns citations\nthe user can verify.\n\n## When to use the other tools\n\n- `pipeshub_search` \u2014 locate a document by name or topic and resolve it\n to a `recordId`. To read or summarize one specific document, search,\n then pass the top hit's `recordId` to `pipeshub_get_record_content`.\n- `pipeshub_download_record` \u2014 when the user wants the actual file\n bytes (download, attach, open). Get the `recordId` either from\n citations on a prior `pipeshub_chat` response or from\n `pipeshub_search`.\n- `pipeshub_get_record_content` \u2014 when you need a record's full parsed\n content (returned as a single `content` string: metadata header plus\n the document's text) without downloading the original file. Prefer this\n over download when the question is about what the record says.\n- `pipeshub_directory` \u2014 people, groups, teams, and `whoami` lookups.\n Not for documents.\n- `pipeshub_sources` \u2014 call once at the start of a session to discover\n which connectors / KB / models are available, then cache the result.\n- `pipeshub_agents` \u2014 list the org's configured **agents** (specialized\n assistants with their own prompt, tools, and knowledge scope).\n\n## Knowledge Sources\n\nA source (an app connector or a KB) holds record groups (a project, space,\ndrive, folder), which hold records (one ticket, page, file). Records nest \u2014\nan epic over its stories, a page over its child pages.\n\n**Every tool returns metadata or content.**\n\n- `pipeshub_search` / `pipeshub_chat` \u2014 content, but only a ranked sample of\n blocks: never all blocks of a record, never every record that matches, never\n a complete list of what exists.\n- `mode:\"lookup\"` and `mode:\"navigate\"` \u2014 metadata: recordIds, fields, and\n structure. No document text. `mode:\"content\"` \u2014 one whole record.\n\n**Combining them.** Search finds a starting point by wording; navigate on a\n`recordId` reveals what search structurally cannot \u2014 siblings, children,\nlinked records, and the group's total count. For a question that must be\nexhaustive (\"all\", \"how many\", \"every\"), do NOT count search hits or trust a\nchat answer: navigate the record group, which reports the real total. For a\nrecord's siblings, navigate its parent \u2014 take the id from the `Path` line.\n\n**A named record** \u2014 an issue key, a Confluence / Drive / Slack link, an\nexternal ID \u2192 `mode:\"lookup\"` FIRST. It returns that record's metadata (for a\nticket: status, assignee, priority, dates) plus its `recordId`, which often\nanswers the question outright. Never guess a `recordId`.\n\nPass a source's id from `pipeshub_sources` as `apps: [\"<id>\"]` to search or\nchat, and as `nodeId` to navigate. Navigate and lookup end in a `Next:` line\nnaming the exact follow-up call \u2014 follow it.\n\n## Agents\n\nSome orgs configure **agents** for specific jobs (e.g. a Slack messenger, a\nJira ticket creator, a Salesforce CRM updater). To run a turn against an\nagent, call `pipeshub_chat` with its `agentId` (from `pipeshub_agents`)\n\u2014 optionally with an agent `chatMode` (`auto` by default, or `quick` /\n`verification` / `deep`). Keep passing the same `agentId` plus the\nreturned `conversationId` on follow-up turns.\n\n**When to route to an agent vs plain chat:**\n- The user names a system/action that maps to an agent (e.g. \"post to\n Slack\", \"create a Jira ticket\", \"update the Salesforce deal\") \u2192 call\n `pipeshub_agents`, pick the matching agent, and use it.\n- Plain question about the org's knowledge or the public web \u2192 just use\n `pipeshub_chat` (no `agentId`) with `internal_search` or `web_search`.\n\n**If you are unsure which agent or route fits the request**, call\n`pipeshub_agents` FIRST and read the returned names/descriptions, then\neither pick the best match or present the list to the user and let them\nchoose. Do NOT guess an agent blindly, and do NOT refuse \u2014 list the agents\nand decide from real data. The list may be empty (no agents configured),\nin which case fall back to plain `pipeshub_chat`.\n\n## Conversation lifecycle\n\n`pipeshub_chat` is a single tool that handles both starting and\ncontinuing conversations (plain or with an `agentId`). On the first turn\nomit `conversationId`; on every subsequent turn pass back the\n`conversationId` returned by the previous call (along with the same\n`agentId` if you used one). Server-side context is preserved \u2014 do NOT\nreplay prior messages. Only start a fresh conversation when the user\nexplicitly asks to clear context.\n";
2
2
  //# sourceMappingURL=instructions.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"instructions.d.ts","sourceRoot":"","sources":["../../src/mcp-server/instructions.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,qBAAqB,o2HA6EjC,CAAC"}
1
+ {"version":3,"file":"instructions.d.ts","sourceRoot":"","sources":["../../src/mcp-server/instructions.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,qBAAqB,ukNAkIjC,CAAC"}
@@ -8,14 +8,35 @@ PipesHub is the user's workplace AI platform. It indexes their documents,
8
8
  knowledge base content, and connector sources (Drive, Box, Confluence,
9
9
  Slack, Jira, Gmail, ...). When in doubt, the answer is in PipesHub.
10
10
 
11
+ ## Full-document tasks: \`pipeshub_search\` → \`pipeshub_get_record_content\`
12
+
13
+ \`pipeshub_chat\` answers from a handful of retrieved passages — it never
14
+ reads a whole document. Whenever the task depends on a document's
15
+ COMPLETE content, fetch the document itself:
16
+
17
+ 1. \`pipeshub_search\` with the document's name / topic.
18
+ 2. Take the top hit's \`recordId\`.
19
+ 3. \`pipeshub_get_record_content\`, and answer from the returned content.
20
+
21
+ Tasks that need this path — anything where missing part of the document
22
+ could make the answer wrong:
23
+
24
+ - Summarize / TL;DR / key points / takeaways / action items of a doc.
25
+ - Extract or list ALL of something (dates, owners, requirements, ...).
26
+ - Check whether / where a doc mentions something.
27
+ - Translate, rewrite, outline, review, or reformat a doc.
28
+ - Compare named docs (fetch each \`recordId\`).
29
+ - Any question explicitly scoped to ONE named document — chat retrieval
30
+ cannot be restricted to a single record.
31
+
11
32
  ## Default tool: \`pipeshub_chat\`
12
33
 
13
34
  **Use \`pipeshub_chat\` for any question that could plausibly be answered
14
- by the user's PipesHub-indexed data.** That includes:
35
+ by the user's PipesHub-indexed data** and is not a full-document task:
15
36
 
16
- - Anything about a specific document, file, report, ticket, message, or
17
- page (e.g. "what's in the Q4 sales report?", "summarize the langchain
18
- doc", "what did Aashil say about onboarding?").
37
+ - A question that may span several documents, or where you don't yet
38
+ know which record holds the answer (e.g. "what did Aashil say about
39
+ onboarding?").
19
40
  - Anything about company / org policies, processes, decisions, or
20
41
  history (e.g. "what's our vacation policy?", "who owns the auth
21
42
  service?").
@@ -31,15 +52,17 @@ the user can verify.
31
52
 
32
53
  ## When to use the other tools
33
54
 
34
- - \`pipeshub_search\` — only when the user asks specifically to **find /
35
- locate** a document by name or topic (so you can hand them a list, or
36
- resolve a filename to a \`recordId\` for download). For "what does
37
- the doc say?" use \`pipeshub_chat\` instead — it does the retrieval
38
- internally.
55
+ - \`pipeshub_search\` — locate a document by name or topic and resolve it
56
+ to a \`recordId\`. To read or summarize one specific document, search,
57
+ then pass the top hit's \`recordId\` to \`pipeshub_get_record_content\`.
39
58
  - \`pipeshub_download_record\` — when the user wants the actual file
40
59
  bytes (download, attach, open). Get the \`recordId\` either from
41
60
  citations on a prior \`pipeshub_chat\` response or from
42
61
  \`pipeshub_search\`.
62
+ - \`pipeshub_get_record_content\` — when you need a record's full parsed
63
+ content (returned as a single \`content\` string: metadata header plus
64
+ the document's text) without downloading the original file. Prefer this
65
+ over download when the question is about what the record says.
43
66
  - \`pipeshub_directory\` — people, groups, teams, and \`whoami\` lookups.
44
67
  Not for documents.
45
68
  - \`pipeshub_sources\` — call once at the start of a session to discover
@@ -47,6 +70,36 @@ the user can verify.
47
70
  - \`pipeshub_agents\` — list the org's configured **agents** (specialized
48
71
  assistants with their own prompt, tools, and knowledge scope).
49
72
 
73
+ ## Knowledge Sources
74
+
75
+ A source (an app connector or a KB) holds record groups (a project, space,
76
+ drive, folder), which hold records (one ticket, page, file). Records nest —
77
+ an epic over its stories, a page over its child pages.
78
+
79
+ **Every tool returns metadata or content.**
80
+
81
+ - \`pipeshub_search\` / \`pipeshub_chat\` — content, but only a ranked sample of
82
+ blocks: never all blocks of a record, never every record that matches, never
83
+ a complete list of what exists.
84
+ - \`mode:"lookup"\` and \`mode:"navigate"\` — metadata: recordIds, fields, and
85
+ structure. No document text. \`mode:"content"\` — one whole record.
86
+
87
+ **Combining them.** Search finds a starting point by wording; navigate on a
88
+ \`recordId\` reveals what search structurally cannot — siblings, children,
89
+ linked records, and the group's total count. For a question that must be
90
+ exhaustive ("all", "how many", "every"), do NOT count search hits or trust a
91
+ chat answer: navigate the record group, which reports the real total. For a
92
+ record's siblings, navigate its parent — take the id from the \`Path\` line.
93
+
94
+ **A named record** — an issue key, a Confluence / Drive / Slack link, an
95
+ external ID → \`mode:"lookup"\` FIRST. It returns that record's metadata (for a
96
+ ticket: status, assignee, priority, dates) plus its \`recordId\`, which often
97
+ answers the question outright. Never guess a \`recordId\`.
98
+
99
+ Pass a source's id from \`pipeshub_sources\` as \`apps: ["<id>"]\` to search or
100
+ chat, and as \`nodeId\` to navigate. Navigate and lookup end in a \`Next:\` line
101
+ naming the exact follow-up call — follow it.
102
+
50
103
  ## Agents
51
104
 
52
105
  Some orgs configure **agents** for specific jobs (e.g. a Slack messenger, a
@@ -1 +1 @@
1
- {"version":3,"file":"instructions.js","sourceRoot":"","sources":["../../src/mcp-server/instructions.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,sEAAsE;AACtE,sEAAsE;AACtE,gEAAgE;AAEhE,MAAM,CAAC,MAAM,qBAAqB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6EpC,CAAC"}
1
+ {"version":3,"file":"instructions.js","sourceRoot":"","sources":["../../src/mcp-server/instructions.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAC/D,sEAAsE;AACtE,sEAAsE;AACtE,gEAAgE;AAEhE,MAAM,CAAC,MAAM,qBAAqB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkIpC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp-server/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGpE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAMzD,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAUvC,wBAAgB,eAAe,CAAC,IAAI,EAAE;IACpC,MAAM,EAAE,aAAa,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IACpC,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,MAAM,CAAC,EAAE,QAAQ,EAAE,GAAG,SAAS,CAAC;IAChC,MAAM,CAAC,EAAE,MAAM,YAAY,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,QAAQ,CAAC,EAAE,UAAU,CAAC,UAAU,CAAC,GAAG,SAAS,CAAC;IAC9C,SAAS,CAAC,EAAE,UAAU,CAAC,WAAW,CAAC,GAAG,SAAS,CAAC;IAChD,YAAY,CAAC,EAAE,UAAU,CAAC,cAAc,CAAC,GAAG,SAAS,CAAC;CACvD;;;;;;EAqEA"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp-server/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGpE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAMzD,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAWvC,wBAAgB,eAAe,CAAC,IAAI,EAAE;IACpC,MAAM,EAAE,aAAa,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IACpC,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,MAAM,CAAC,EAAE,QAAQ,EAAE,GAAG,SAAS,CAAC;IAChC,MAAM,CAAC,EAAE,MAAM,YAAY,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,QAAQ,CAAC,EAAE,UAAU,CAAC,UAAU,CAAC,GAAG,SAAS,CAAC;IAC9C,SAAS,CAAC,EAAE,UAAU,CAAC,WAAW,CAAC,GAAG,SAAS,CAAC;IAChD,YAAY,CAAC,EAAE,UAAU,CAAC,cAAc,CAAC,GAAG,SAAS,CAAC;CACvD;;;;;;EA2EA"}
@@ -1,12 +1,14 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { PIPESHUB_INSTRUCTIONS } from "./instructions.js";
3
3
  import { PipeshubCore } from "../core.js";
4
+ import { bindNewRequestId } from "../hooks/request-context.js";
4
5
  import { createRegisterPrompt } from "./prompts.js";
5
6
  import { createRegisterResource, createRegisterResourceTemplate, } from "./resources.js";
6
7
  import { createRegisterTool, registerDynamicTools } from "./tools.js";
7
8
  import { tool$pipeshubChat } from "./tools/pipeshubChat.js";
8
9
  import { tool$pipeshubSearch } from "./tools/pipeshubSearch.js";
9
10
  import { tool$pipeshubDownloadRecord } from "./tools/pipeshubDownloadRecord.js";
11
+ import { tool$pipeshubGetRecordContent } from "./tools/pipeshubGetRecordContent.js";
10
12
  import { tool$pipeshubDirectory } from "./tools/pipeshubDirectory.js";
11
13
  import { tool$pipeshubSources } from "./tools/pipeshubSources.js";
12
14
  import { tool$pipeshubAgents } from "./tools/pipeshubAgents.js";
@@ -18,7 +20,7 @@ export function createMCPServer(deps) {
18
20
  }, {
19
21
  instructions: PIPESHUB_INSTRUCTIONS,
20
22
  });
21
- const getClient = deps.getSDK || (() => new PipeshubCore({
23
+ const resolveClient = deps.getSDK || (() => new PipeshubCore({
22
24
  security: deps.security,
23
25
  serverURL: deps.serverURL,
24
26
  serverIdx: deps.serverIdx,
@@ -31,6 +33,10 @@ export function createMCPServer(deps) {
31
33
  }
32
34
  : undefined,
33
35
  }));
36
+ const getClient = () => {
37
+ bindNewRequestId();
38
+ return resolveClient();
39
+ };
34
40
  const scopes = new Set(deps.scopes);
35
41
  const allowedTools = deps.allowedTools && new Set(deps.allowedTools);
36
42
  const [tool, tools, toolMap] = createRegisterTool(deps.logger, server, getClient, scopes, allowedTools, deps.dynamic);
@@ -44,8 +50,9 @@ export function createMCPServer(deps) {
44
50
  tool(tool$pipeshubChat); // 2. ask questions (start + continue)
45
51
  tool(tool$pipeshubSearch); // 3. resolve filename → recordId
46
52
  tool(tool$pipeshubDownloadRecord); // 4. fetch a document by id
47
- tool(tool$pipeshubDirectory); // 5. people / groups / teams / whoami
48
- tool(tool$pipeshubAgents); // 6. discover org agents
53
+ tool(tool$pipeshubGetRecordContent); // 5. fetch a record's parsed content
54
+ tool(tool$pipeshubDirectory); // 6. people / groups / teams / whoami
55
+ tool(tool$pipeshubAgents); // 7. discover org agents
49
56
  // Curated prompt: user-invokable tool-routing guidance.
50
57
  prompt(prompt$pipeshubAssistant);
51
58
  if (deps.dynamic) {
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp-server/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp-server/server.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,8 @@
1
+ import { bytesToBase64 } from "../lib/bytes-to-base64.js";
1
2
  type BinaryData = Uint8Array | ArrayBuffer | Blob | ReadableStream | Response | string;
2
- export declare function bytesToBase64(u8arr: Uint8Array): string;
3
+ export { bytesToBase64 };
3
4
  export declare function consumeStream(stream: ReadableStream<Uint8Array>): Promise<Uint8Array>;
4
5
  export declare function isAsyncIterable(value: unknown): value is AsyncIterable<string>;
5
6
  export declare function isBinaryData(value: unknown): value is BinaryData;
6
7
  export declare function valueToBase64(value: BinaryData | null | undefined): Promise<string | null>;
7
- export {};
8
8
  //# sourceMappingURL=shared.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/mcp-server/shared.ts"],"names":[],"mappings":"AAMA,KAAK,UAAU,GACX,UAAU,GACV,WAAW,GACX,IAAI,GACJ,cAAc,GACd,QAAQ,GACR,MAAM,CAAC;AAIX,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAEvD;AAED,wBAAsB,aAAa,CACjC,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,GACjC,OAAO,CAAC,UAAU,CAAC,CAerB;AAED,wBAAgB,eAAe,CAC7B,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,aAAa,CAAC,MAAM,CAAC,CAIhC;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,UAAU,CAShE;AAED,wBAAsB,aAAa,CACjC,KAAK,EAAE,UAAU,GAAG,IAAI,GAAG,SAAS,GACnC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAiBxB"}
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/mcp-server/shared.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE1D,KAAK,UAAU,GACX,UAAU,GACV,WAAW,GACX,IAAI,GACJ,cAAc,GACd,QAAQ,GACR,MAAM,CAAC;AAIX,OAAO,EAAE,aAAa,EAAE,CAAC;AAEzB,wBAAsB,aAAa,CACjC,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,GACjC,OAAO,CAAC,UAAU,CAAC,CAerB;AAED,wBAAgB,eAAe,CAC7B,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,aAAa,CAAC,MAAM,CAAC,CAIhC;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,UAAU,CAShE;AAED,wBAAsB,aAAa,CACjC,KAAK,EAAE,UAAU,GAAG,IAAI,GAAG,SAAS,GACnC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAiBxB"}
@@ -1,11 +1,15 @@
1
1
  /*
2
2
  * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
3
+ *
4
+ * Exception: `bytesToBase64` is imported from the hand-maintained
5
+ * `../lib/bytes-to-base64.js` (see that file and `.genignore`). Do not
6
+ * restore the generated one-liner — it overflows the stack on binary
7
+ * payloads.
3
8
  */
4
9
  import * as z from "zod";
10
+ import { bytesToBase64 } from "../lib/bytes-to-base64.js";
5
11
  const base64Schema = z.string().base64();
6
- export function bytesToBase64(u8arr) {
7
- return btoa(String.fromCodePoint(...u8arr));
8
- }
12
+ export { bytesToBase64 };
9
13
  export async function consumeStream(stream) {
10
14
  const reader = stream.getReader();
11
15
  const chunks = [];
@@ -1 +1 @@
1
- {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/mcp-server/shared.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAUzB,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,CAAC;AAEzC,MAAM,UAAU,aAAa,CAAC,KAAiB;IAC7C,OAAO,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAAkC;IAElC,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,EAAE,CAAC;IAClC,MAAM,MAAM,GAAiB,EAAE,CAAC;IAEhC,IAAI,CAAC;QACH,OAAO,IAAI,EAAE,CAAC;YACZ,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;YAC5C,IAAI,KAAK,IAAI,IAAI;gBAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACtC,IAAI,IAAI;gBAAE,MAAM;QAClB,CAAC;IACH,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,WAAW,EAAE,CAAC;IACvB,CAAC;IAED,OAAO,IAAI,UAAU,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,KAAc;IAEd,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,IAAI,IAAI,IAAI,MAAM,CAAC,aAAa,IAAI,KAAK,CAC5E,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAc;IACzC,OAAO,CACL,KAAK,YAAY,UAAU;WACxB,KAAK,YAAY,WAAW;WAC5B,KAAK,YAAY,IAAI;WACrB,KAAK,YAAY,cAAc;WAC/B,KAAK,YAAY,QAAQ;WACzB,OAAO,KAAK,KAAK,QAAQ,CAC7B,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,KAAoC;IAEpC,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;QAClB,OAAO,IAAI,CAAC;IACd,CAAC;SAAM,IAAI,KAAK,YAAY,UAAU,EAAE,CAAC;QACvC,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;SAAM,IAAI,KAAK,YAAY,WAAW,EAAE,CAAC;QACxC,OAAO,aAAa,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;IAC9C,CAAC;SAAM,IAAI,KAAK,YAAY,QAAQ,IAAI,KAAK,YAAY,IAAI,EAAE,CAAC;QAC9D,OAAO,aAAa,CAAC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IAClE,CAAC;SAAM,IAAI,KAAK,YAAY,cAAc,EAAE,CAAC;QAC3C,OAAO,aAAa,CAAC,MAAM,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC;IACnD,CAAC;SAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACrC,OAAO,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC;SAAM,CAAC;QACN,KAAqB,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,iCAAiC,OAAO,KAAK,EAAE,CAAC,CAAC;IACnE,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/mcp-server/shared.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAU1D,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,CAAC;AAEzC,OAAO,EAAE,aAAa,EAAE,CAAC;AAEzB,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAAkC;IAElC,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,EAAE,CAAC;IAClC,MAAM,MAAM,GAAiB,EAAE,CAAC;IAEhC,IAAI,CAAC;QACH,OAAO,IAAI,EAAE,CAAC;YACZ,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;YAC5C,IAAI,KAAK,IAAI,IAAI;gBAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACtC,IAAI,IAAI;gBAAE,MAAM;QAClB,CAAC;IACH,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,WAAW,EAAE,CAAC;IACvB,CAAC;IAED,OAAO,IAAI,UAAU,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,KAAc;IAEd,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,IAAI,IAAI,IAAI,MAAM,CAAC,aAAa,IAAI,KAAK,CAC5E,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAc;IACzC,OAAO,CACL,KAAK,YAAY,UAAU;WACxB,KAAK,YAAY,WAAW;WAC5B,KAAK,YAAY,IAAI;WACrB,KAAK,YAAY,cAAc;WAC/B,KAAK,YAAY,QAAQ;WACzB,OAAO,KAAK,KAAK,QAAQ,CAC7B,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,KAAoC;IAEpC,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;QAClB,OAAO,IAAI,CAAC;IACd,CAAC;SAAM,IAAI,KAAK,YAAY,UAAU,EAAE,CAAC;QACvC,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;SAAM,IAAI,KAAK,YAAY,WAAW,EAAE,CAAC;QACxC,OAAO,aAAa,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;IAC9C,CAAC;SAAM,IAAI,KAAK,YAAY,QAAQ,IAAI,KAAK,YAAY,IAAI,EAAE,CAAC;QAC9D,OAAO,aAAa,CAAC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IAClE,CAAC;SAAM,IAAI,KAAK,YAAY,cAAc,EAAE,CAAC;QAC3C,OAAO,aAAa,CAAC,MAAM,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC;IACnD,CAAC;SAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACrC,OAAO,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC;SAAM,CAAC;QACN,KAAqB,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,iCAAiC,OAAO,KAAK,EAAE,CAAC,CAAC;IACnE,CAAC;AACH,CAAC"}
@@ -0,0 +1,34 @@
1
+ import type { SSEFrame } from "./_helpers.js";
2
+ export declare const AGUIEvent: {
3
+ readonly RUN_FINISHED: "RUN_FINISHED";
4
+ readonly RUN_ERROR: "RUN_ERROR";
5
+ readonly CUSTOM: "CUSTOM";
6
+ readonly TEXT_MESSAGE_CONTENT: "TEXT_MESSAGE_CONTENT";
7
+ };
8
+ export type ChatStreamState = {
9
+ /** Persisted conversation from the terminal frame; null until then. */
10
+ conversation: any | null;
11
+ recordsUsed: number | undefined;
12
+ error: string | null;
13
+ /** From `CUSTOM{name:"conversation_created"}`, available before the answer. */
14
+ conversationId: string | null;
15
+ title: string | null;
16
+ /**
17
+ * Answer text accumulated per `messageId`. Universal `agent` mode forwards
18
+ * child-run text alongside the root answer, so a single buffer would splice
19
+ * sub-agent output into the middle of the reply.
20
+ */
21
+ text: Map<string, string>;
22
+ /** messageIds seen on frames with no `parentRunId` — i.e. the root run. */
23
+ rootMessageIds: Set<string>;
24
+ };
25
+ export declare function newChatStreamState(): ChatStreamState;
26
+ export declare function applyAGUIFrame(state: ChatStreamState, frame: SSEFrame): boolean;
27
+ /**
28
+ * Best-effort answer when the stream ended without a terminal frame.
29
+ *
30
+ * Prefers the longest root-run buffer; falls back to the longest buffer of any
31
+ * run so a partial answer still reaches the caller.
32
+ */
33
+ export declare function salvagedText(state: ChatStreamState): string | null;
34
+ //# sourceMappingURL=_agui.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_agui.d.ts","sourceRoot":"","sources":["../../../src/mcp-server/tools/_agui.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,eAAO,MAAM,SAAS;;;;;CAKZ,CAAC;AAEX,MAAM,MAAM,eAAe,GAAG;IAC5B,uEAAuE;IACvE,YAAY,EAAE,GAAG,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,+EAA+E;IAC/E,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB;;;;OAIG;IACH,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1B,2EAA2E;IAC3E,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAC7B,CAAC;AAEF,wBAAgB,kBAAkB,IAAI,eAAe,CAUpD;AAsBD,wBAAgB,cAAc,CAC5B,KAAK,EAAE,eAAe,EACtB,KAAK,EAAE,QAAQ,GACd,OAAO,CAgDT;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,GAAG,IAAI,CAUlE"}
@@ -0,0 +1,91 @@
1
+ // AG-UI frame folding for the chat stream.
2
+ //
3
+ // AG-UI is the only wire protocol the conversation and agent stream routes
4
+ // speak; the legacy `connected` / `answer_chunk` / `complete` / `error`
5
+ // vocabulary was removed with the new agent loop and is never emitted.
6
+ //
7
+ // Kept separate from `pipeshubChat.ts` so the fold is a pure function over
8
+ // frames and can be exercised without a live stream.
9
+ export const AGUIEvent = {
10
+ RUN_FINISHED: "RUN_FINISHED",
11
+ RUN_ERROR: "RUN_ERROR",
12
+ CUSTOM: "CUSTOM",
13
+ TEXT_MESSAGE_CONTENT: "TEXT_MESSAGE_CONTENT",
14
+ };
15
+ export function newChatStreamState() {
16
+ return {
17
+ conversation: null,
18
+ recordsUsed: undefined,
19
+ error: null,
20
+ conversationId: null,
21
+ title: null,
22
+ text: new Map(),
23
+ rootMessageIds: new Set(),
24
+ };
25
+ }
26
+ export function applyAGUIFrame(state, frame) {
27
+ const data = frame.data;
28
+ const d = data && typeof data === "object"
29
+ ? data
30
+ : {};
31
+ switch (frame.event) {
32
+ case AGUIEvent.RUN_FINISHED: {
33
+ // Only the gateway's own re-emitted frame carries `result` — it swallows
34
+ // the AI backend's root RUN_FINISHED and re-sends an enriched one after
35
+ // persisting. Sub-agent RUN_FINISHED frames are forwarded verbatim with
36
+ // no `result`, so keying off the event name alone would end the stream
37
+ // as soon as the first sub-agent finished.
38
+ const result = d.result;
39
+ if (!result || typeof result !== "object")
40
+ return false;
41
+ state.conversation = result.conversation ?? null;
42
+ state.recordsUsed = result.recordsUsed ?? result.meta?.recordsUsed;
43
+ return true;
44
+ }
45
+ case AGUIEvent.RUN_ERROR: {
46
+ state.error = (typeof data === "string" ? data : null)
47
+ ?? d.message ?? d.error ?? frame.raw ?? "Stream error";
48
+ return true;
49
+ }
50
+ case AGUIEvent.CUSTOM: {
51
+ if (d.name === "conversation_created") {
52
+ const value = d.value ?? {};
53
+ state.conversationId = value.conversationId ?? state.conversationId;
54
+ state.title = value.title ?? state.title;
55
+ }
56
+ return false;
57
+ }
58
+ case AGUIEvent.TEXT_MESSAGE_CONTENT: {
59
+ if (typeof d.delta !== "string" || d.delta.length === 0)
60
+ return false;
61
+ const id = typeof d.messageId === "string" ? d.messageId : "";
62
+ state.text.set(id, (state.text.get(id) ?? "") + d.delta);
63
+ if (d.parentRunId == null)
64
+ state.rootMessageIds.add(id);
65
+ return false;
66
+ }
67
+ // RUN_STARTED, STEP_*, TOOL_CALL_*, REASONING_*, STATE_*,
68
+ // TEXT_MESSAGE_START/END, HEARTBEAT — lifecycle noise.
69
+ default:
70
+ return false;
71
+ }
72
+ }
73
+ /**
74
+ * Best-effort answer when the stream ended without a terminal frame.
75
+ *
76
+ * Prefers the longest root-run buffer; falls back to the longest buffer of any
77
+ * run so a partial answer still reaches the caller.
78
+ */
79
+ export function salvagedText(state) {
80
+ const pick = (ids) => {
81
+ let best = null;
82
+ for (const id of ids) {
83
+ const text = state.text.get(id);
84
+ if (text && (best === null || text.length > best.length))
85
+ best = text;
86
+ }
87
+ return best;
88
+ };
89
+ return pick(state.rootMessageIds) ?? pick(state.text.keys());
90
+ }
91
+ //# sourceMappingURL=_agui.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_agui.js","sourceRoot":"","sources":["../../../src/mcp-server/tools/_agui.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"_helpers.d.ts","sourceRoot":"","sources":["../../../src/mcp-server/tools/_helpers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"_helpers.d.ts","sourceRoot":"","sources":["../../../src/mcp-server/tools/_helpers.ts"],"names":[],"mappings":"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"}
@@ -184,17 +184,24 @@ export function trimCitations(citations) {
184
184
  if (!Array.isArray(citations))
185
185
  return [];
186
186
  return citations.map((c) => {
187
- const md = c?.metadata ?? {};
187
+ // Two wire shapes exist. Flat: `{ content, chunkIndex, metadata }`.
188
+ // Nested (current backend): `{ citationId, citationData: { content,
189
+ // chunkIndex, metadata } }`. Reading only the flat one silently yields
190
+ // a citation with every field `undefined` — which JSON.stringify drops,
191
+ // leaving `{"snippet": null}` and no way to identify the source at all.
192
+ const cd = c?.citationData ?? c;
193
+ const md = cd?.metadata ?? c?.metadata ?? {};
194
+ const content = typeof cd?.content === "string" ? cd.content : c?.content;
188
195
  return {
189
- recordId: md.recordId ?? c?.recordId,
190
- recordName: md.recordName ?? c?.recordName,
191
- snippet: typeof c?.content === "string"
192
- ? c.content.slice(0, 280)
196
+ recordId: md.recordId ?? cd?.recordId ?? c?.recordId,
197
+ recordName: md.recordName ?? cd?.recordName ?? c?.recordName,
198
+ snippet: typeof content === "string"
199
+ ? content.slice(0, 280)
193
200
  : md.blockText ?? null,
194
201
  mimeType: md.mimeType,
195
202
  webUrl: md.webUrl,
196
203
  pageNum: md.pageNum,
197
- chunkIndex: c?.chunkIndex ?? md.chunkIndex,
204
+ chunkIndex: cd?.chunkIndex ?? c?.chunkIndex ?? md.chunkIndex,
198
205
  };
199
206
  });
200
207
  }