@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.
- package/README.md +92 -2
- package/bin/mcp-server.js +976 -169
- package/bin/mcp-server.js.map +28 -15
- package/bin/pipeshub.js +946 -0
- package/bin/pipeshub.js.map +14 -0
- package/esm/cli/client.d.ts +54 -0
- package/esm/cli/client.d.ts.map +1 -0
- package/esm/cli/client.js +230 -0
- package/esm/cli/client.js.map +1 -0
- package/esm/cli/commands.d.ts +30 -0
- package/esm/cli/commands.d.ts.map +1 -0
- package/esm/cli/commands.js +321 -0
- package/esm/cli/commands.js.map +1 -0
- package/esm/cli/config.d.ts +73 -0
- package/esm/cli/config.d.ts.map +1 -0
- package/esm/cli/config.js +218 -0
- package/esm/cli/config.js.map +1 -0
- package/esm/cli/init-qm.d.ts +11 -0
- package/esm/cli/init-qm.d.ts.map +1 -0
- package/esm/cli/init-qm.js +170 -0
- package/esm/cli/init-qm.js.map +1 -0
- package/esm/cli/pipeshub.d.ts +2 -0
- package/esm/cli/pipeshub.d.ts.map +1 -0
- package/esm/cli/pipeshub.js +296 -0
- package/esm/cli/pipeshub.js.map +1 -0
- package/esm/funcs/connectorGetRecordContent.d.ts +43 -0
- package/esm/funcs/connectorGetRecordContent.d.ts.map +1 -0
- package/esm/funcs/connectorGetRecordContent.js +114 -0
- package/esm/funcs/connectorGetRecordContent.js.map +1 -0
- package/esm/funcs/connectorLookupRecordByIdentifier.d.ts +68 -0
- package/esm/funcs/connectorLookupRecordByIdentifier.d.ts.map +1 -0
- package/esm/funcs/connectorLookupRecordByIdentifier.js +138 -0
- package/esm/funcs/connectorLookupRecordByIdentifier.js.map +1 -0
- package/esm/funcs/connectorNavigateKnowledgeGraph.d.ts +75 -0
- package/esm/funcs/connectorNavigateKnowledgeGraph.d.ts.map +1 -0
- package/esm/funcs/connectorNavigateKnowledgeGraph.js +152 -0
- package/esm/funcs/connectorNavigateKnowledgeGraph.js.map +1 -0
- package/esm/funcs/conversationsStreamConversation.js +1 -1
- package/esm/funcs/conversationsStreamConversation.js.map +1 -1
- package/esm/funcs/userGroupsGetAllUserGroups.js +1 -1
- package/esm/funcs/userGroupsGetAllUserGroups.js.map +1 -1
- package/esm/hooks/registration.d.ts.map +1 -1
- package/esm/hooks/registration.js +2 -1
- package/esm/hooks/registration.js.map +1 -1
- package/esm/hooks/request-context.d.ts +10 -0
- package/esm/hooks/request-context.d.ts.map +1 -0
- package/esm/hooks/request-context.js +38 -0
- package/esm/hooks/request-context.js.map +1 -0
- package/esm/hooks/requestid.d.ts +5 -0
- package/esm/hooks/requestid.d.ts.map +1 -0
- package/esm/hooks/requestid.js +58 -0
- package/esm/hooks/requestid.js.map +1 -0
- package/esm/lib/base64.d.ts +1 -1
- package/esm/lib/base64.d.ts.map +1 -1
- package/esm/lib/base64.js +6 -3
- package/esm/lib/base64.js.map +1 -1
- package/esm/lib/bytes-to-base64.d.ts +16 -0
- package/esm/lib/bytes-to-base64.d.ts.map +1 -0
- package/esm/lib/bytes-to-base64.js +23 -0
- package/esm/lib/bytes-to-base64.js.map +1 -0
- package/esm/mcp-server/instructions.d.ts +1 -1
- package/esm/mcp-server/instructions.d.ts.map +1 -1
- package/esm/mcp-server/instructions.js +62 -9
- package/esm/mcp-server/instructions.js.map +1 -1
- package/esm/mcp-server/server.d.ts.map +1 -1
- package/esm/mcp-server/server.js +10 -3
- package/esm/mcp-server/server.js.map +1 -1
- package/esm/mcp-server/shared.d.ts +2 -2
- package/esm/mcp-server/shared.d.ts.map +1 -1
- package/esm/mcp-server/shared.js +7 -3
- package/esm/mcp-server/shared.js.map +1 -1
- package/esm/mcp-server/tools/_agui.d.ts +34 -0
- package/esm/mcp-server/tools/_agui.d.ts.map +1 -0
- package/esm/mcp-server/tools/_agui.js +91 -0
- package/esm/mcp-server/tools/_agui.js.map +1 -0
- package/esm/mcp-server/tools/_helpers.d.ts.map +1 -1
- package/esm/mcp-server/tools/_helpers.js +13 -6
- package/esm/mcp-server/tools/_helpers.js.map +1 -1
- package/esm/mcp-server/tools/pipeshubChat.d.ts +0 -3
- package/esm/mcp-server/tools/pipeshubChat.d.ts.map +1 -1
- package/esm/mcp-server/tools/pipeshubChat.js +75 -92
- package/esm/mcp-server/tools/pipeshubChat.js.map +1 -1
- package/esm/mcp-server/tools/pipeshubGetRecordContent.d.ts +125 -0
- package/esm/mcp-server/tools/pipeshubGetRecordContent.d.ts.map +1 -0
- package/esm/mcp-server/tools/pipeshubGetRecordContent.js +214 -0
- package/esm/mcp-server/tools/pipeshubGetRecordContent.js.map +1 -0
- package/esm/mcp-server/tools/pipeshubSearch.d.ts.map +1 -1
- package/esm/mcp-server/tools/pipeshubSearch.js +22 -5
- package/esm/mcp-server/tools/pipeshubSearch.js.map +1 -1
- package/esm/mcp-server/tools.d.ts.map +1 -1
- package/esm/mcp-server/tools.js +13 -1
- package/esm/mcp-server/tools.js.map +1 -1
- package/esm/models/availablemodelsresponse.d.ts +1 -1
- package/esm/models/conversation.d.ts +1 -1
- package/esm/models/getrecordcontentop.d.ts +6 -0
- package/esm/models/getrecordcontentop.d.ts.map +1 -0
- package/esm/models/getrecordcontentop.js +5 -0
- package/esm/models/getrecordcontentop.js.map +1 -0
- package/esm/models/lookuprecordbyidentifierop.d.ts +7 -0
- package/esm/models/lookuprecordbyidentifierop.d.ts.map +1 -0
- package/esm/models/lookuprecordbyidentifierop.js +14 -0
- package/esm/models/lookuprecordbyidentifierop.js.map +1 -0
- package/esm/models/navigateknowledgegraphop.d.ts +14 -0
- package/esm/models/navigateknowledgegraphop.d.ts.map +1 -0
- package/esm/models/navigateknowledgegraphop.js +25 -0
- package/esm/models/navigateknowledgegraphop.js.map +1 -0
- package/esm/models/userteamsresponse.d.ts +1 -1
- package/esm/tool-names.d.ts.map +1 -1
- package/esm/tool-names.js +6 -2
- package/esm/tool-names.js.map +1 -1
- package/package.json +4 -2
- package/qm/README.md +247 -0
- package/qm/SECURITY.md +134 -0
- package/qm/TROUBLESHOOTING.md +218 -0
- package/qm/qm.config.fragment.jsonc +42 -0
- package/qm/sandbox/Dockerfile +22 -0
- package/qm/sandbox/skills/pipeshub/SKILL.md +69 -0
- package/qm/sandbox/tools/pipeshub/tool.json +36 -0
- package/src/cli/client.ts +272 -0
- package/src/cli/commands.ts +403 -0
- package/src/cli/config.ts +229 -0
- package/src/cli/init-qm.ts +215 -0
- package/src/cli/pipeshub.ts +333 -0
- package/src/funcs/connectorGetRecordContent.ts +179 -0
- package/src/funcs/connectorLookupRecordByIdentifier.ts +200 -0
- package/src/funcs/connectorNavigateKnowledgeGraph.ts +215 -0
- package/src/funcs/conversationsStreamConversation.ts +1 -1
- package/src/funcs/userGroupsGetAllUserGroups.ts +1 -1
- package/src/hooks/registration.ts +2 -1
- package/src/hooks/request-context.ts +47 -0
- package/src/hooks/requestid.ts +62 -0
- package/src/lib/base64.ts +6 -3
- package/src/lib/bytes-to-base64.ts +24 -0
- package/src/mcp-server/instructions.ts +62 -9
- package/src/mcp-server/server.ts +11 -3
- package/src/mcp-server/shared.ts +7 -3
- package/src/mcp-server/tools/_agui.ts +138 -0
- package/src/mcp-server/tools/_helpers.ts +13 -6
- package/src/mcp-server/tools/pipeshubChat.ts +78 -91
- package/src/mcp-server/tools/pipeshubGetRecordContent.ts +251 -0
- package/src/mcp-server/tools/pipeshubSearch.ts +22 -5
- package/src/mcp-server/tools.ts +14 -1
- package/src/models/getrecordcontentop.ts +11 -0
- package/src/models/lookuprecordbyidentifierop.ts +26 -0
- package/src/models/navigateknowledgegraphop.ts +56 -0
- package/src/tool-names.ts +6 -2
package/bin/mcp-server.js
CHANGED
|
@@ -50394,14 +50394,35 @@ PipesHub is the user's workplace AI platform. It indexes their documents,
|
|
|
50394
50394
|
knowledge base content, and connector sources (Drive, Box, Confluence,
|
|
50395
50395
|
Slack, Jira, Gmail, ...). When in doubt, the answer is in PipesHub.
|
|
50396
50396
|
|
|
50397
|
+
## Full-document tasks: \`pipeshub_search\` → \`pipeshub_get_record_content\`
|
|
50398
|
+
|
|
50399
|
+
\`pipeshub_chat\` answers from a handful of retrieved passages — it never
|
|
50400
|
+
reads a whole document. Whenever the task depends on a document's
|
|
50401
|
+
COMPLETE content, fetch the document itself:
|
|
50402
|
+
|
|
50403
|
+
1. \`pipeshub_search\` with the document's name / topic.
|
|
50404
|
+
2. Take the top hit's \`recordId\`.
|
|
50405
|
+
3. \`pipeshub_get_record_content\`, and answer from the returned content.
|
|
50406
|
+
|
|
50407
|
+
Tasks that need this path — anything where missing part of the document
|
|
50408
|
+
could make the answer wrong:
|
|
50409
|
+
|
|
50410
|
+
- Summarize / TL;DR / key points / takeaways / action items of a doc.
|
|
50411
|
+
- Extract or list ALL of something (dates, owners, requirements, ...).
|
|
50412
|
+
- Check whether / where a doc mentions something.
|
|
50413
|
+
- Translate, rewrite, outline, review, or reformat a doc.
|
|
50414
|
+
- Compare named docs (fetch each \`recordId\`).
|
|
50415
|
+
- Any question explicitly scoped to ONE named document — chat retrieval
|
|
50416
|
+
cannot be restricted to a single record.
|
|
50417
|
+
|
|
50397
50418
|
## Default tool: \`pipeshub_chat\`
|
|
50398
50419
|
|
|
50399
50420
|
**Use \`pipeshub_chat\` for any question that could plausibly be answered
|
|
50400
|
-
by the user's PipesHub-indexed data
|
|
50421
|
+
by the user's PipesHub-indexed data** and is not a full-document task:
|
|
50401
50422
|
|
|
50402
|
-
-
|
|
50403
|
-
|
|
50404
|
-
|
|
50423
|
+
- A question that may span several documents, or where you don't yet
|
|
50424
|
+
know which record holds the answer (e.g. "what did Aashil say about
|
|
50425
|
+
onboarding?").
|
|
50405
50426
|
- Anything about company / org policies, processes, decisions, or
|
|
50406
50427
|
history (e.g. "what's our vacation policy?", "who owns the auth
|
|
50407
50428
|
service?").
|
|
@@ -50417,15 +50438,17 @@ the user can verify.
|
|
|
50417
50438
|
|
|
50418
50439
|
## When to use the other tools
|
|
50419
50440
|
|
|
50420
|
-
- \`pipeshub_search\` —
|
|
50421
|
-
|
|
50422
|
-
|
|
50423
|
-
the doc say?" use \`pipeshub_chat\` instead — it does the retrieval
|
|
50424
|
-
internally.
|
|
50441
|
+
- \`pipeshub_search\` — locate a document by name or topic and resolve it
|
|
50442
|
+
to a \`recordId\`. To read or summarize one specific document, search,
|
|
50443
|
+
then pass the top hit's \`recordId\` to \`pipeshub_get_record_content\`.
|
|
50425
50444
|
- \`pipeshub_download_record\` — when the user wants the actual file
|
|
50426
50445
|
bytes (download, attach, open). Get the \`recordId\` either from
|
|
50427
50446
|
citations on a prior \`pipeshub_chat\` response or from
|
|
50428
50447
|
\`pipeshub_search\`.
|
|
50448
|
+
- \`pipeshub_get_record_content\` — when you need a record's full parsed
|
|
50449
|
+
content (returned as a single \`content\` string: metadata header plus
|
|
50450
|
+
the document's text) without downloading the original file. Prefer this
|
|
50451
|
+
over download when the question is about what the record says.
|
|
50429
50452
|
- \`pipeshub_directory\` — people, groups, teams, and \`whoami\` lookups.
|
|
50430
50453
|
Not for documents.
|
|
50431
50454
|
- \`pipeshub_sources\` — call once at the start of a session to discover
|
|
@@ -50433,6 +50456,36 @@ the user can verify.
|
|
|
50433
50456
|
- \`pipeshub_agents\` — list the org's configured **agents** (specialized
|
|
50434
50457
|
assistants with their own prompt, tools, and knowledge scope).
|
|
50435
50458
|
|
|
50459
|
+
## Knowledge Sources
|
|
50460
|
+
|
|
50461
|
+
A source (an app connector or a KB) holds record groups (a project, space,
|
|
50462
|
+
drive, folder), which hold records (one ticket, page, file). Records nest —
|
|
50463
|
+
an epic over its stories, a page over its child pages.
|
|
50464
|
+
|
|
50465
|
+
**Every tool returns metadata or content.**
|
|
50466
|
+
|
|
50467
|
+
- \`pipeshub_search\` / \`pipeshub_chat\` — content, but only a ranked sample of
|
|
50468
|
+
blocks: never all blocks of a record, never every record that matches, never
|
|
50469
|
+
a complete list of what exists.
|
|
50470
|
+
- \`mode:"lookup"\` and \`mode:"navigate"\` — metadata: recordIds, fields, and
|
|
50471
|
+
structure. No document text. \`mode:"content"\` — one whole record.
|
|
50472
|
+
|
|
50473
|
+
**Combining them.** Search finds a starting point by wording; navigate on a
|
|
50474
|
+
\`recordId\` reveals what search structurally cannot — siblings, children,
|
|
50475
|
+
linked records, and the group's total count. For a question that must be
|
|
50476
|
+
exhaustive ("all", "how many", "every"), do NOT count search hits or trust a
|
|
50477
|
+
chat answer: navigate the record group, which reports the real total. For a
|
|
50478
|
+
record's siblings, navigate its parent — take the id from the \`Path\` line.
|
|
50479
|
+
|
|
50480
|
+
**A named record** — an issue key, a Confluence / Drive / Slack link, an
|
|
50481
|
+
external ID → \`mode:"lookup"\` FIRST. It returns that record's metadata (for a
|
|
50482
|
+
ticket: status, assignee, priority, dates) plus its \`recordId\`, which often
|
|
50483
|
+
answers the question outright. Never guess a \`recordId\`.
|
|
50484
|
+
|
|
50485
|
+
Pass a source's id from \`pipeshub_sources\` as \`apps: ["<id>"]\` to search or
|
|
50486
|
+
chat, and as \`nodeId\` to navigate. Navigate and lookup end in a \`Next:\` line
|
|
50487
|
+
naming the exact follow-up call — follow it.
|
|
50488
|
+
|
|
50436
50489
|
## Agents
|
|
50437
50490
|
|
|
50438
50491
|
Some orgs configure **agents** for specific jobs (e.g. a Slack messenger, a
|
|
@@ -50467,13 +50520,122 @@ replay prior messages. Only start a fresh conversation when the user
|
|
|
50467
50520
|
explicitly asks to clear context.
|
|
50468
50521
|
`;
|
|
50469
50522
|
|
|
50523
|
+
// node_modules/nanoid/url-alphabet/index.js
|
|
50524
|
+
var urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
|
|
50525
|
+
|
|
50526
|
+
// node_modules/nanoid/index.js
|
|
50527
|
+
import { webcrypto as crypto3 } from "node:crypto";
|
|
50528
|
+
function fillPool(bytes) {
|
|
50529
|
+
if (bytes < 0)
|
|
50530
|
+
throw new RangeError("Wrong ID size");
|
|
50531
|
+
try {
|
|
50532
|
+
if (!pool || pool.length < bytes) {
|
|
50533
|
+
pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER);
|
|
50534
|
+
crypto3.getRandomValues(pool);
|
|
50535
|
+
poolOffset = 0;
|
|
50536
|
+
} else if (poolOffset + bytes > pool.length) {
|
|
50537
|
+
crypto3.getRandomValues(pool);
|
|
50538
|
+
poolOffset = 0;
|
|
50539
|
+
}
|
|
50540
|
+
} catch (e) {
|
|
50541
|
+
pool = undefined;
|
|
50542
|
+
throw e;
|
|
50543
|
+
}
|
|
50544
|
+
poolOffset += bytes;
|
|
50545
|
+
}
|
|
50546
|
+
function nanoid2(size = 21) {
|
|
50547
|
+
fillPool(size |= 0);
|
|
50548
|
+
let id = "";
|
|
50549
|
+
for (let i = poolOffset - size;i < poolOffset; i++) {
|
|
50550
|
+
id += urlAlphabet[pool[i] & 63];
|
|
50551
|
+
}
|
|
50552
|
+
return id;
|
|
50553
|
+
}
|
|
50554
|
+
var POOL_SIZE_MULTIPLIER = 128, pool, poolOffset;
|
|
50555
|
+
var init_nanoid = () => {};
|
|
50556
|
+
|
|
50557
|
+
// src/hooks/request-context.ts
|
|
50558
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
50559
|
+
function bindNewRequestId() {
|
|
50560
|
+
storage.enterWith({ random: nanoid2() });
|
|
50561
|
+
}
|
|
50562
|
+
function getRequestContextStore() {
|
|
50563
|
+
return storage.getStore();
|
|
50564
|
+
}
|
|
50565
|
+
function newRequestId() {
|
|
50566
|
+
return `mcp-${nanoid2()}`;
|
|
50567
|
+
}
|
|
50568
|
+
var storage;
|
|
50569
|
+
var init_request_context = __esm(() => {
|
|
50570
|
+
init_nanoid();
|
|
50571
|
+
storage = new AsyncLocalStorage;
|
|
50572
|
+
});
|
|
50573
|
+
|
|
50574
|
+
// src/hooks/requestid.ts
|
|
50575
|
+
function decodeJwtPayload(token) {
|
|
50576
|
+
try {
|
|
50577
|
+
const base64Url = token.split(".")[1];
|
|
50578
|
+
if (!base64Url)
|
|
50579
|
+
return null;
|
|
50580
|
+
const base642 = base64Url.replace(/-/g, "+").replace(/_/g, "/");
|
|
50581
|
+
const padded = base642 + "=".repeat((4 - base642.length % 4) % 4);
|
|
50582
|
+
const claims = JSON.parse(Buffer.from(padded, "base64").toString("utf8"));
|
|
50583
|
+
return typeof claims === "object" && claims !== null ? claims : null;
|
|
50584
|
+
} catch {
|
|
50585
|
+
return null;
|
|
50586
|
+
}
|
|
50587
|
+
}
|
|
50588
|
+
function userIdFromRequest(request) {
|
|
50589
|
+
const auth = request.headers.get("authorization") ?? "";
|
|
50590
|
+
if (!auth.toLowerCase().startsWith("bearer "))
|
|
50591
|
+
return null;
|
|
50592
|
+
const token = auth.slice(7).trim();
|
|
50593
|
+
const claims = decodeJwtPayload(token);
|
|
50594
|
+
return claims?.["userId"] || null;
|
|
50595
|
+
}
|
|
50596
|
+
|
|
50597
|
+
class RequestIDHook {
|
|
50598
|
+
beforeRequest(_hookCtx, request) {
|
|
50599
|
+
if (request.headers.get(REQUEST_ID_HEADER)) {
|
|
50600
|
+
return request;
|
|
50601
|
+
}
|
|
50602
|
+
const store = getRequestContextStore();
|
|
50603
|
+
if (!store) {
|
|
50604
|
+
request.headers.set(REQUEST_ID_HEADER, newRequestId());
|
|
50605
|
+
return request;
|
|
50606
|
+
}
|
|
50607
|
+
if (!store.finalId) {
|
|
50608
|
+
const userId = userIdFromRequest(request);
|
|
50609
|
+
store.finalId = userId ? `mcp-${userId}-${store.random}` : `mcp-${store.random}`;
|
|
50610
|
+
}
|
|
50611
|
+
request.headers.set(REQUEST_ID_HEADER, store.finalId);
|
|
50612
|
+
return request;
|
|
50613
|
+
}
|
|
50614
|
+
}
|
|
50615
|
+
var REQUEST_ID_HEADER = "x-request-id";
|
|
50616
|
+
var init_requestid = __esm(() => {
|
|
50617
|
+
init_request_context();
|
|
50618
|
+
});
|
|
50619
|
+
|
|
50470
50620
|
// src/hooks/registration.ts
|
|
50471
|
-
function initHooks(hooks) {
|
|
50621
|
+
function initHooks(hooks) {
|
|
50622
|
+
hooks.registerBeforeRequestHook(new RequestIDHook);
|
|
50623
|
+
}
|
|
50624
|
+
var init_registration = __esm(() => {
|
|
50625
|
+
init_requestid();
|
|
50626
|
+
});
|
|
50472
50627
|
|
|
50473
|
-
// src/lib/base64.ts
|
|
50628
|
+
// src/lib/bytes-to-base64.ts
|
|
50474
50629
|
function bytesToBase64(u8arr) {
|
|
50475
|
-
|
|
50630
|
+
let binary = "";
|
|
50631
|
+
for (let i = 0;i < u8arr.length; i += BASE64_CHUNK) {
|
|
50632
|
+
binary += String.fromCharCode(...u8arr.subarray(i, i + BASE64_CHUNK));
|
|
50633
|
+
}
|
|
50634
|
+
return btoa(binary);
|
|
50476
50635
|
}
|
|
50636
|
+
var BASE64_CHUNK = 32768;
|
|
50637
|
+
|
|
50638
|
+
// src/lib/base64.ts
|
|
50477
50639
|
function bytesFromBase64(encoded) {
|
|
50478
50640
|
return Uint8Array.from(atob(encoded), (c) => c.charCodeAt(0));
|
|
50479
50641
|
}
|
|
@@ -51058,6 +51220,7 @@ class SDKHooks {
|
|
|
51058
51220
|
}
|
|
51059
51221
|
}
|
|
51060
51222
|
var init_hooks = __esm(() => {
|
|
51223
|
+
init_registration();
|
|
51061
51224
|
init_clientcredentials();
|
|
51062
51225
|
});
|
|
51063
51226
|
|
|
@@ -51793,9 +51956,6 @@ function createRegisterPrompt(logger, server, getSDK, allowedScopes) {
|
|
|
51793
51956
|
}
|
|
51794
51957
|
|
|
51795
51958
|
// src/mcp-server/shared.ts
|
|
51796
|
-
function bytesToBase642(u8arr) {
|
|
51797
|
-
return btoa(String.fromCodePoint(...u8arr));
|
|
51798
|
-
}
|
|
51799
51959
|
async function consumeStream(stream) {
|
|
51800
51960
|
const reader = stream.getReader();
|
|
51801
51961
|
const chunks = [];
|
|
@@ -51816,13 +51976,13 @@ async function valueToBase64(value) {
|
|
|
51816
51976
|
if (value == null) {
|
|
51817
51977
|
return null;
|
|
51818
51978
|
} else if (value instanceof Uint8Array) {
|
|
51819
|
-
return
|
|
51979
|
+
return bytesToBase64(value);
|
|
51820
51980
|
} else if (value instanceof ArrayBuffer) {
|
|
51821
|
-
return
|
|
51981
|
+
return bytesToBase64(new Uint8Array(value));
|
|
51822
51982
|
} else if (value instanceof Response || value instanceof Blob) {
|
|
51823
|
-
return
|
|
51983
|
+
return bytesToBase64(new Uint8Array(await value.arrayBuffer()));
|
|
51824
51984
|
} else if (value instanceof ReadableStream) {
|
|
51825
|
-
return
|
|
51985
|
+
return bytesToBase64(await consumeStream(value));
|
|
51826
51986
|
} else if (typeof value === "string") {
|
|
51827
51987
|
return base64Schema.parse(value);
|
|
51828
51988
|
} else {
|
|
@@ -51882,9 +52042,15 @@ async function formatResult(response) {
|
|
|
51882
52042
|
} else if (contentType.startsWith("audio/")) {
|
|
51883
52043
|
const data = await valueToBase64(await response.arrayBuffer());
|
|
51884
52044
|
content = data == null ? [] : [{ type: "audio", data, mimeType: contentType }];
|
|
51885
|
-
} else {
|
|
52045
|
+
} else if (contentType.startsWith("text/") || contentType.includes("json") || contentType.includes("xml") || contentType.includes("yaml")) {
|
|
51886
52046
|
const text = await response.text();
|
|
51887
52047
|
content = [{ type: "text", text }];
|
|
52048
|
+
} else {
|
|
52049
|
+
const blob = await valueToBase64(await response.arrayBuffer());
|
|
52050
|
+
content = blob == null ? [] : [{
|
|
52051
|
+
type: "resource",
|
|
52052
|
+
resource: { uri: response.url, mimeType: contentType, blob }
|
|
52053
|
+
}];
|
|
51888
52054
|
}
|
|
51889
52055
|
return response.ok ? { content } : { content, isError: true };
|
|
51890
52056
|
}
|
|
@@ -52382,7 +52548,7 @@ async function $do(client$, request, options) {
|
|
|
52382
52548
|
options: client$._options,
|
|
52383
52549
|
baseURL: options?.serverURL ?? client$._baseURL ?? "",
|
|
52384
52550
|
operationID: "streamConversation",
|
|
52385
|
-
oAuth2Scopes: ["conversation:
|
|
52551
|
+
oAuth2Scopes: ["conversation:chat"],
|
|
52386
52552
|
resolvedSecurity: requestSecurity,
|
|
52387
52553
|
securitySource: client$._options.security,
|
|
52388
52554
|
retryConfig: options?.retries || client$._options.retryConfig || { strategy: "none" },
|
|
@@ -52780,6 +52946,77 @@ var init_agentsStreamMessage = __esm(() => {
|
|
|
52780
52946
|
init_async();
|
|
52781
52947
|
});
|
|
52782
52948
|
|
|
52949
|
+
// src/mcp-server/tools/_agui.ts
|
|
52950
|
+
function newChatStreamState() {
|
|
52951
|
+
return {
|
|
52952
|
+
conversation: null,
|
|
52953
|
+
recordsUsed: undefined,
|
|
52954
|
+
error: null,
|
|
52955
|
+
conversationId: null,
|
|
52956
|
+
title: null,
|
|
52957
|
+
text: new Map,
|
|
52958
|
+
rootMessageIds: new Set
|
|
52959
|
+
};
|
|
52960
|
+
}
|
|
52961
|
+
function applyAGUIFrame(state, frame) {
|
|
52962
|
+
const data = frame.data;
|
|
52963
|
+
const d = data && typeof data === "object" ? data : {};
|
|
52964
|
+
switch (frame.event) {
|
|
52965
|
+
case AGUIEvent.RUN_FINISHED: {
|
|
52966
|
+
const result = d.result;
|
|
52967
|
+
if (!result || typeof result !== "object")
|
|
52968
|
+
return false;
|
|
52969
|
+
state.conversation = result.conversation ?? null;
|
|
52970
|
+
state.recordsUsed = result.recordsUsed ?? result.meta?.recordsUsed;
|
|
52971
|
+
return true;
|
|
52972
|
+
}
|
|
52973
|
+
case AGUIEvent.RUN_ERROR: {
|
|
52974
|
+
state.error = (typeof data === "string" ? data : null) ?? d.message ?? d.error ?? frame.raw ?? "Stream error";
|
|
52975
|
+
return true;
|
|
52976
|
+
}
|
|
52977
|
+
case AGUIEvent.CUSTOM: {
|
|
52978
|
+
if (d.name === "conversation_created") {
|
|
52979
|
+
const value = d.value ?? {};
|
|
52980
|
+
state.conversationId = value.conversationId ?? state.conversationId;
|
|
52981
|
+
state.title = value.title ?? state.title;
|
|
52982
|
+
}
|
|
52983
|
+
return false;
|
|
52984
|
+
}
|
|
52985
|
+
case AGUIEvent.TEXT_MESSAGE_CONTENT: {
|
|
52986
|
+
if (typeof d.delta !== "string" || d.delta.length === 0)
|
|
52987
|
+
return false;
|
|
52988
|
+
const id = typeof d.messageId === "string" ? d.messageId : "";
|
|
52989
|
+
state.text.set(id, (state.text.get(id) ?? "") + d.delta);
|
|
52990
|
+
if (d.parentRunId == null)
|
|
52991
|
+
state.rootMessageIds.add(id);
|
|
52992
|
+
return false;
|
|
52993
|
+
}
|
|
52994
|
+
default:
|
|
52995
|
+
return false;
|
|
52996
|
+
}
|
|
52997
|
+
}
|
|
52998
|
+
function salvagedText(state) {
|
|
52999
|
+
const pick2 = (ids) => {
|
|
53000
|
+
let best = null;
|
|
53001
|
+
for (const id of ids) {
|
|
53002
|
+
const text = state.text.get(id);
|
|
53003
|
+
if (text && (best === null || text.length > best.length))
|
|
53004
|
+
best = text;
|
|
53005
|
+
}
|
|
53006
|
+
return best;
|
|
53007
|
+
};
|
|
53008
|
+
return pick2(state.rootMessageIds) ?? pick2(state.text.keys());
|
|
53009
|
+
}
|
|
53010
|
+
var AGUIEvent;
|
|
53011
|
+
var init__agui = __esm(() => {
|
|
53012
|
+
AGUIEvent = {
|
|
53013
|
+
RUN_FINISHED: "RUN_FINISHED",
|
|
53014
|
+
RUN_ERROR: "RUN_ERROR",
|
|
53015
|
+
CUSTOM: "CUSTOM",
|
|
53016
|
+
TEXT_MESSAGE_CONTENT: "TEXT_MESSAGE_CONTENT"
|
|
53017
|
+
};
|
|
53018
|
+
});
|
|
53019
|
+
|
|
52783
53020
|
// src/funcs/agentsListAgents.ts
|
|
52784
53021
|
function agentsListAgents(client$, request, options) {
|
|
52785
53022
|
return new APIPromise($do5(client$, request, options));
|
|
@@ -52989,15 +53226,17 @@ function trimCitations(citations) {
|
|
|
52989
53226
|
if (!Array.isArray(citations))
|
|
52990
53227
|
return [];
|
|
52991
53228
|
return citations.map((c) => {
|
|
52992
|
-
const
|
|
53229
|
+
const cd = c?.citationData ?? c;
|
|
53230
|
+
const md = cd?.metadata ?? c?.metadata ?? {};
|
|
53231
|
+
const content = typeof cd?.content === "string" ? cd.content : c?.content;
|
|
52993
53232
|
return {
|
|
52994
|
-
recordId: md.recordId ?? c?.recordId,
|
|
52995
|
-
recordName: md.recordName ?? c?.recordName,
|
|
52996
|
-
snippet: typeof
|
|
53233
|
+
recordId: md.recordId ?? cd?.recordId ?? c?.recordId,
|
|
53234
|
+
recordName: md.recordName ?? cd?.recordName ?? c?.recordName,
|
|
53235
|
+
snippet: typeof content === "string" ? content.slice(0, 280) : md.blockText ?? null,
|
|
52997
53236
|
mimeType: md.mimeType,
|
|
52998
53237
|
webUrl: md.webUrl,
|
|
52999
53238
|
pageNum: md.pageNum,
|
|
53000
|
-
chunkIndex: c?.chunkIndex ?? md.chunkIndex
|
|
53239
|
+
chunkIndex: cd?.chunkIndex ?? c?.chunkIndex ?? md.chunkIndex
|
|
53001
53240
|
};
|
|
53002
53241
|
});
|
|
53003
53242
|
}
|
|
@@ -53170,9 +53409,10 @@ var init_pipeshubChat = __esm(() => {
|
|
|
53170
53409
|
init_conversationsStreamMessage();
|
|
53171
53410
|
init_agentsStreamConversation();
|
|
53172
53411
|
init_agentsStreamMessage();
|
|
53412
|
+
init__agui();
|
|
53173
53413
|
init__helpers();
|
|
53174
53414
|
FiltersShape = object({
|
|
53175
|
-
apps: array(string2()).optional().describe("Source-scoping ids
|
|
53415
|
+
apps: array(string2()).optional().describe("Source-scoping ids from `pipeshub_sources` — connector instance and / " + "or knowledge base ids, mixed freely. The legacy org-wide " + "`knowledgeBase_<orgId>` id is still accepted on deployments that " + "predate per-KB sources. Empty / omitted means no app-side " + "restriction."),
|
|
53176
53416
|
kb: array(string2()).optional().describe("Legacy / unused. Leave empty.")
|
|
53177
53417
|
}).optional();
|
|
53178
53418
|
args = {
|
|
@@ -53186,34 +53426,45 @@ var init_pipeshubChat = __esm(() => {
|
|
|
53186
53426
|
chatMode: _enum([
|
|
53187
53427
|
"internal_search",
|
|
53188
53428
|
"web_search",
|
|
53189
|
-
"
|
|
53190
|
-
"quick",
|
|
53191
|
-
"verification",
|
|
53192
|
-
"deep"
|
|
53429
|
+
"quick"
|
|
53193
53430
|
]).optional().describe("Response strategy. The valid values depend on whether `agentId` is set:\n" + "- WITHOUT `agentId` (plain chat): `internal_search` — answer from the " + "org's indexed knowledge (default) — or `web_search` — answer from the " + `live web.
|
|
53194
|
-
` + "- WITH `agentId` (agent chat): `
|
|
53431
|
+
` + "- WITH `agentId` (agent chat): `quick` is the only supported mode and " + "is sent automatically, so this argument can be omitted.")
|
|
53195
53432
|
};
|
|
53196
53433
|
tool$pipeshubChat = {
|
|
53197
53434
|
name: "pipeshub_chat",
|
|
53198
|
-
description:
|
|
53199
|
-
|
|
53200
|
-
|
|
53201
|
-
|
|
53202
|
-
|
|
53203
|
-
|
|
53204
|
-
|
|
53205
|
-
|
|
53206
|
-
|
|
53207
|
-
|
|
53208
|
-
|
|
53209
|
-
|
|
53210
|
-
|
|
53211
|
-
|
|
53212
|
-
|
|
53213
|
-
|
|
53435
|
+
description: `Ask a question, get an answer grounded in the org's indexed data with
|
|
53436
|
+
citations. It reads a few retrieved passages — never a whole document,
|
|
53437
|
+
never a complete list.
|
|
53438
|
+
|
|
53439
|
+
**Three questions this tool gets WRONG. Check them first:**
|
|
53440
|
+
- **Structure** — "what's under this epic?", "which pages are in this
|
|
53441
|
+
space?", "what links to this ticket?", "what's in this folder?" →
|
|
53442
|
+
\`pipeshub_get_record_content\` \`mode:"navigate"\`. Ranking cannot see how
|
|
53443
|
+
records relate.
|
|
53444
|
+
- **Exhaustive** — "how many X?", "list ALL the Y", "every Z" →
|
|
53445
|
+
\`mode:"navigate"\`, which reports the group's real total. This tool
|
|
53446
|
+
undercounts and will not say so.
|
|
53447
|
+
- **One named document** — summarize it, extract from it, what does it say
|
|
53448
|
+
about X → \`pipeshub_search\` for the \`recordId\`, then \`mode:"content"\`.
|
|
53449
|
+
|
|
53450
|
+
Everything else about the org's knowledge belongs here: policies,
|
|
53451
|
+
processes, decisions, history, "what do we know about X", and any question
|
|
53452
|
+
spanning several documents.
|
|
53453
|
+
|
|
53454
|
+
**Internal search** (default, \`chatMode: "internal_search"\`): the user's
|
|
53455
|
+
documents, files, knowledge base, company policies — anything in their
|
|
53456
|
+
PipesHub-indexed sources (Drive, Box, Confluence, Slack, Gmail, Jira, the
|
|
53457
|
+
org's KB, ...).
|
|
53458
|
+
|
|
53459
|
+
**Web search** (\`chatMode: "web_search"\`): current events or public
|
|
53460
|
+
information unlikely to be in the org's knowledge base.
|
|
53461
|
+
|
|
53462
|
+
Both are plain-chat modes. **Agent chat** — pass an \`agentId\` from
|
|
53463
|
+
\`pipeshub_agents\` — runs against that agent's own prompt, tools and knowledge;
|
|
53464
|
+
\`quick\` is its only mode, requires the \`agentId\`, and is sent automatically.
|
|
53465
|
+
|
|
53214
53466
|
- "What's our policy on Y?" → \`pipeshub_chat\` (internal_search)
|
|
53215
53467
|
- "What's in the news about Z?" → \`pipeshub_chat\` (web_search)
|
|
53216
|
-
- "What is the latest version of <library>?" → \`pipeshub_chat\` (web_search)
|
|
53217
53468
|
- "Find / locate the file named X" → \`pipeshub_search\` (then
|
|
53218
53469
|
\`pipeshub_download_record\` if the user wants the bytes).
|
|
53219
53470
|
|
|
@@ -53243,9 +53494,10 @@ cited document, take \`citations[*].recordId\` and call
|
|
|
53243
53494
|
args,
|
|
53244
53495
|
tool: async (client, args2, ctx) => {
|
|
53245
53496
|
const fetchOptions = { signal: ctx.signal };
|
|
53497
|
+
const plainChatMode = args2.chatMode === "web_search" ? "web_search" : "internal_search";
|
|
53246
53498
|
let response;
|
|
53247
53499
|
if (args2.agentId) {
|
|
53248
|
-
const agentChatMode =
|
|
53500
|
+
const agentChatMode = "quick";
|
|
53249
53501
|
if (args2.conversationId) {
|
|
53250
53502
|
const [result] = await agentsStreamMessage(client, {
|
|
53251
53503
|
agentKey: args2.agentId,
|
|
@@ -53285,7 +53537,7 @@ cited document, take \`citations[*].recordId\` and call
|
|
|
53285
53537
|
modelKey: args2.modelKey,
|
|
53286
53538
|
modelName: args2.modelName,
|
|
53287
53539
|
modelFriendlyName: args2.modelFriendlyName,
|
|
53288
|
-
chatMode:
|
|
53540
|
+
chatMode: plainChatMode
|
|
53289
53541
|
}
|
|
53290
53542
|
}, { fetchOptions }).$inspect();
|
|
53291
53543
|
if (!result.ok)
|
|
@@ -53298,7 +53550,7 @@ cited document, take \`citations[*].recordId\` and call
|
|
|
53298
53550
|
modelKey: args2.modelKey,
|
|
53299
53551
|
modelName: args2.modelName,
|
|
53300
53552
|
modelFriendlyName: args2.modelFriendlyName,
|
|
53301
|
-
chatMode:
|
|
53553
|
+
chatMode: plainChatMode
|
|
53302
53554
|
}, { fetchOptions }).$inspect();
|
|
53303
53555
|
if (!result.ok)
|
|
53304
53556
|
return errorResult(result.error.message);
|
|
@@ -53307,62 +53559,36 @@ cited document, take \`citations[*].recordId\` and call
|
|
|
53307
53559
|
const httpErr = await httpErrorResult(response, "PipesHub chat request");
|
|
53308
53560
|
if (httpErr)
|
|
53309
53561
|
return httpErr;
|
|
53310
|
-
|
|
53311
|
-
let recordsUsed;
|
|
53312
|
-
let lastAccumulated = null;
|
|
53313
|
-
let errorMessage = null;
|
|
53562
|
+
const state = newChatStreamState();
|
|
53314
53563
|
try {
|
|
53315
53564
|
for await (const frame of iterateSSE(response)) {
|
|
53316
|
-
|
|
53317
|
-
case "complete": {
|
|
53318
|
-
const d = frame.data ?? {};
|
|
53319
|
-
finalConversation = d.conversation ?? null;
|
|
53320
|
-
recordsUsed = d.recordsUsed ?? d.meta?.recordsUsed;
|
|
53321
|
-
break;
|
|
53322
|
-
}
|
|
53323
|
-
case "error": {
|
|
53324
|
-
const d = frame.data ?? {};
|
|
53325
|
-
errorMessage = typeof d === "string" ? d : d.error ?? d.message ?? frame.raw ?? "Stream error";
|
|
53326
|
-
break;
|
|
53327
|
-
}
|
|
53328
|
-
case "answer_chunk": {
|
|
53329
|
-
const d = frame.data ?? {};
|
|
53330
|
-
if (typeof d.accumulated === "string") {
|
|
53331
|
-
lastAccumulated = d.accumulated;
|
|
53332
|
-
} else if (typeof d.content === "string") {
|
|
53333
|
-
lastAccumulated = (lastAccumulated ?? "") + d.content;
|
|
53334
|
-
}
|
|
53335
|
-
break;
|
|
53336
|
-
}
|
|
53337
|
-
default:
|
|
53338
|
-
break;
|
|
53339
|
-
}
|
|
53340
|
-
if (finalConversation || errorMessage)
|
|
53565
|
+
if (applyAGUIFrame(state, frame))
|
|
53341
53566
|
break;
|
|
53342
53567
|
}
|
|
53343
53568
|
} catch (e) {
|
|
53344
53569
|
return errorResult(`SSE stream failed: ${e.message}`);
|
|
53345
53570
|
}
|
|
53346
|
-
if (
|
|
53347
|
-
return errorResult(
|
|
53348
|
-
if (
|
|
53571
|
+
if (state.error)
|
|
53572
|
+
return errorResult(state.error);
|
|
53573
|
+
if (state.conversation) {
|
|
53349
53574
|
return jsonResult({
|
|
53350
|
-
...trimConversation(
|
|
53351
|
-
recordsUsed
|
|
53575
|
+
...trimConversation(state.conversation),
|
|
53576
|
+
recordsUsed: state.recordsUsed
|
|
53352
53577
|
});
|
|
53353
53578
|
}
|
|
53354
|
-
|
|
53579
|
+
const salvaged = salvagedText(state);
|
|
53580
|
+
if (salvaged) {
|
|
53355
53581
|
return jsonResult({
|
|
53356
|
-
conversationId:
|
|
53357
|
-
title:
|
|
53582
|
+
conversationId: state.conversationId,
|
|
53583
|
+
title: state.title,
|
|
53358
53584
|
status: "Inprogress",
|
|
53359
|
-
answer:
|
|
53585
|
+
answer: salvaged,
|
|
53360
53586
|
confidence: null,
|
|
53361
53587
|
citations: [],
|
|
53362
53588
|
followUpQuestions: [],
|
|
53363
53589
|
messageCount: 0,
|
|
53364
|
-
recordsUsed,
|
|
53365
|
-
warning: "Stream ended without a
|
|
53590
|
+
recordsUsed: state.recordsUsed,
|
|
53591
|
+
warning: "Stream ended without a terminal RUN_FINISHED; answer is the " + "accumulated TEXT_MESSAGE_CONTENT and citations are unavailable."
|
|
53366
53592
|
});
|
|
53367
53593
|
}
|
|
53368
53594
|
return errorResult("Stream ended without any usable frames.");
|
|
@@ -53516,21 +53742,38 @@ var init_pipeshubSearch = __esm(() => {
|
|
|
53516
53742
|
name: "pipeshub_search",
|
|
53517
53743
|
description: `Vector / semantic search across the org's indexed documents.
|
|
53518
53744
|
|
|
53519
|
-
**Use this
|
|
53520
|
-
|
|
53521
|
-
|
|
53522
|
-
does the retrieval internally and grounds the answer in
|
|
53745
|
+
**Use this when the user wants to LOCATE a document** — by name, topic,
|
|
53746
|
+
or a phrase to grep for — and to resolve it to a \`recordId\`. For
|
|
53747
|
+
open-ended questions across many documents, use \`pipeshub_chat\`
|
|
53748
|
+
instead, which does the retrieval internally and grounds the answer in
|
|
53749
|
+
citations.
|
|
53523
53750
|
|
|
53524
53751
|
Typical uses:
|
|
53752
|
+
- Resolve a doc name / topic into a \`recordId\` for
|
|
53753
|
+
\`pipeshub_get_record_content\` — step 1 of any full-document task
|
|
53754
|
+
(summarize, extract, review, "what does the doc say?").
|
|
53525
53755
|
- Resolve a filename / phrase into a \`recordId\` for
|
|
53526
53756
|
\`pipeshub_download_record\`.
|
|
53527
53757
|
- Show the user a ranked list of matching files when they ask "find /
|
|
53528
53758
|
search for X".
|
|
53529
53759
|
|
|
53760
|
+
Not for structural questions — what is under this epic, which pages are
|
|
53761
|
+
in this space, what links to this ticket. Ranking by content cannot show
|
|
53762
|
+
how records relate; use \`pipeshub_get_record_content\` \`mode:"navigate"\`.
|
|
53763
|
+
|
|
53764
|
+
**A ranked sample, never a complete list.** Hits are the top-scoring
|
|
53765
|
+
blocks from the best-matching records — not all blocks of any record, and
|
|
53766
|
+
not every record that matches. Never count them to answer "how many" /
|
|
53767
|
+
"all" / "every"; navigate the record group instead, which reports its
|
|
53768
|
+
real total.
|
|
53769
|
+
|
|
53530
53770
|
The response is trimmed to one row per hit:
|
|
53531
53771
|
\`{ recordId, recordName, score, snippet, mimeType, webUrl, ... }\`.
|
|
53532
53772
|
Highest \`score\` first; multiple hits may share the same \`recordId\`
|
|
53533
|
-
(different
|
|
53773
|
+
(different blocks of the same record).
|
|
53774
|
+
|
|
53775
|
+
When presenting results to the user, link each record using its
|
|
53776
|
+
\`webUrl\` (when present).`,
|
|
53534
53777
|
scopes: ["read"],
|
|
53535
53778
|
annotations: {
|
|
53536
53779
|
title: "Semantic search",
|
|
@@ -53737,6 +53980,455 @@ returned base64-encoded; text content is returned inline.`,
|
|
|
53737
53980
|
};
|
|
53738
53981
|
});
|
|
53739
53982
|
|
|
53983
|
+
// src/models/getrecordcontentop.ts
|
|
53984
|
+
var GetRecordContentRequest$zodSchema;
|
|
53985
|
+
var init_getrecordcontentop = __esm(() => {
|
|
53986
|
+
init_zod();
|
|
53987
|
+
GetRecordContentRequest$zodSchema = object({
|
|
53988
|
+
recordId: string2().describe("Record ID to fetch. Obtain it from a `pipeshub_search` result (`hits[*].recordId`) or a chat citation (`citations[*].recordId`).")
|
|
53989
|
+
});
|
|
53990
|
+
});
|
|
53991
|
+
|
|
53992
|
+
// src/funcs/connectorGetRecordContent.ts
|
|
53993
|
+
function connectorGetRecordContent(client$, request, options) {
|
|
53994
|
+
return new APIPromise($do8(client$, request, options));
|
|
53995
|
+
}
|
|
53996
|
+
async function $do8(client$, request, options) {
|
|
53997
|
+
const parsed$ = safeParse4(request, (value$) => GetRecordContentRequest$zodSchema.parse(value$), "Input validation failed");
|
|
53998
|
+
if (!parsed$.ok) {
|
|
53999
|
+
return [parsed$, { status: "invalid" }];
|
|
54000
|
+
}
|
|
54001
|
+
const payload$ = parsed$.value;
|
|
54002
|
+
const body$ = null;
|
|
54003
|
+
const pathParams$ = {
|
|
54004
|
+
recordId: encodeSimple("recordId", payload$.recordId, {
|
|
54005
|
+
explode: false,
|
|
54006
|
+
charEncoding: "percent"
|
|
54007
|
+
})
|
|
54008
|
+
};
|
|
54009
|
+
const path$ = pathToFunc("/connectors/record/{recordId}/content")(pathParams$);
|
|
54010
|
+
const headers$ = new Headers(compactMap({
|
|
54011
|
+
Accept: "application/json"
|
|
54012
|
+
}));
|
|
54013
|
+
const securityInput = await extractSecurity(client$._options.security);
|
|
54014
|
+
const requestSecurity = resolveGlobalSecurity(securityInput);
|
|
54015
|
+
const context = {
|
|
54016
|
+
options: client$._options,
|
|
54017
|
+
baseURL: options?.serverURL ?? client$._baseURL ?? "",
|
|
54018
|
+
operationID: "getRecordContent",
|
|
54019
|
+
oAuth2Scopes: ["connector:read"],
|
|
54020
|
+
resolvedSecurity: requestSecurity,
|
|
54021
|
+
securitySource: client$._options.security,
|
|
54022
|
+
retryConfig: options?.retries || client$._options.retryConfig || { strategy: "none" },
|
|
54023
|
+
retryCodes: options?.retryCodes || [
|
|
54024
|
+
"429",
|
|
54025
|
+
"500",
|
|
54026
|
+
"502",
|
|
54027
|
+
"503",
|
|
54028
|
+
"504"
|
|
54029
|
+
]
|
|
54030
|
+
};
|
|
54031
|
+
const requestRes = client$._createRequest(context, {
|
|
54032
|
+
security: requestSecurity,
|
|
54033
|
+
method: "GET",
|
|
54034
|
+
baseURL: options?.serverURL,
|
|
54035
|
+
path: path$,
|
|
54036
|
+
headers: headers$,
|
|
54037
|
+
body: body$,
|
|
54038
|
+
userAgent: client$._options.userAgent,
|
|
54039
|
+
timeoutMs: options?.timeoutMs || client$._options.timeoutMs || -1
|
|
54040
|
+
}, options);
|
|
54041
|
+
if (!requestRes.ok) {
|
|
54042
|
+
return [requestRes, { status: "invalid" }];
|
|
54043
|
+
}
|
|
54044
|
+
const req$ = requestRes.value;
|
|
54045
|
+
const doResult = await client$._do(req$, {
|
|
54046
|
+
context,
|
|
54047
|
+
errorCodes: [],
|
|
54048
|
+
retryConfig: context.retryConfig,
|
|
54049
|
+
retryCodes: context.retryCodes
|
|
54050
|
+
});
|
|
54051
|
+
if (!doResult.ok) {
|
|
54052
|
+
return [doResult, { status: "request-error", request: req$ }];
|
|
54053
|
+
}
|
|
54054
|
+
return [doResult, {
|
|
54055
|
+
status: "complete",
|
|
54056
|
+
request: req$,
|
|
54057
|
+
response: doResult.value
|
|
54058
|
+
}];
|
|
54059
|
+
}
|
|
54060
|
+
var init_connectorGetRecordContent = __esm(() => {
|
|
54061
|
+
init_encodings();
|
|
54062
|
+
init_primitives();
|
|
54063
|
+
init_schemas4();
|
|
54064
|
+
init_security2();
|
|
54065
|
+
init_url();
|
|
54066
|
+
init_getrecordcontentop();
|
|
54067
|
+
init_async();
|
|
54068
|
+
});
|
|
54069
|
+
|
|
54070
|
+
// src/models/lookuprecordbyidentifierop.ts
|
|
54071
|
+
var LookupRecordByIdentifierRequest$zodSchema;
|
|
54072
|
+
var init_lookuprecordbyidentifierop = __esm(() => {
|
|
54073
|
+
init_zod();
|
|
54074
|
+
LookupRecordByIdentifierRequest$zodSchema = object({
|
|
54075
|
+
connectorName: string2().describe("Connector hint to prioritise resolution order, e.g. `JIRA`, `CONFLUENCE`, `GOOGLE_DRIVE`, `SLACK`. Cannot widen beyond the connectors the caller can access.").optional(),
|
|
54076
|
+
identifiers: array(string2().min(1).max(2048)).min(1).max(10).describe("The references to resolve: URLs, issue keys such as `PA-1787`, or bare external system IDs. Paste each exactly as you found it — tracking parameters and fragments are handled. Up to 10 per call.")
|
|
54077
|
+
});
|
|
54078
|
+
});
|
|
54079
|
+
|
|
54080
|
+
// src/funcs/connectorLookupRecordByIdentifier.ts
|
|
54081
|
+
function connectorLookupRecordByIdentifier(client$, request, options) {
|
|
54082
|
+
return new APIPromise($do9(client$, request, options));
|
|
54083
|
+
}
|
|
54084
|
+
async function $do9(client$, request, options) {
|
|
54085
|
+
const parsed$ = safeParse4(request, (value$) => LookupRecordByIdentifierRequest$zodSchema.parse(value$), "Input validation failed");
|
|
54086
|
+
if (!parsed$.ok) {
|
|
54087
|
+
return [parsed$, { status: "invalid" }];
|
|
54088
|
+
}
|
|
54089
|
+
const payload$ = parsed$.value;
|
|
54090
|
+
const body$ = null;
|
|
54091
|
+
const path$ = pathToFunc("/connectors/record/lookup")();
|
|
54092
|
+
const query$ = encodeFormQuery({
|
|
54093
|
+
connectorName: payload$.connectorName,
|
|
54094
|
+
identifiers: payload$.identifiers
|
|
54095
|
+
});
|
|
54096
|
+
const headers$ = new Headers(compactMap({
|
|
54097
|
+
Accept: "application/json"
|
|
54098
|
+
}));
|
|
54099
|
+
const securityInput = await extractSecurity(client$._options.security);
|
|
54100
|
+
const requestSecurity = resolveGlobalSecurity(securityInput);
|
|
54101
|
+
const context = {
|
|
54102
|
+
options: client$._options,
|
|
54103
|
+
baseURL: options?.serverURL ?? client$._baseURL ?? "",
|
|
54104
|
+
operationID: "lookupRecordByIdentifier",
|
|
54105
|
+
oAuth2Scopes: ["kb:read", "connector:read"],
|
|
54106
|
+
resolvedSecurity: requestSecurity,
|
|
54107
|
+
securitySource: client$._options.security,
|
|
54108
|
+
retryConfig: options?.retries || client$._options.retryConfig || { strategy: "none" },
|
|
54109
|
+
retryCodes: options?.retryCodes || [
|
|
54110
|
+
"429",
|
|
54111
|
+
"500",
|
|
54112
|
+
"502",
|
|
54113
|
+
"503",
|
|
54114
|
+
"504"
|
|
54115
|
+
]
|
|
54116
|
+
};
|
|
54117
|
+
const requestRes = client$._createRequest(context, {
|
|
54118
|
+
security: requestSecurity,
|
|
54119
|
+
method: "GET",
|
|
54120
|
+
baseURL: options?.serverURL,
|
|
54121
|
+
path: path$,
|
|
54122
|
+
headers: headers$,
|
|
54123
|
+
query: query$,
|
|
54124
|
+
body: body$,
|
|
54125
|
+
userAgent: client$._options.userAgent,
|
|
54126
|
+
timeoutMs: options?.timeoutMs || client$._options.timeoutMs || -1
|
|
54127
|
+
}, options);
|
|
54128
|
+
if (!requestRes.ok) {
|
|
54129
|
+
return [requestRes, { status: "invalid" }];
|
|
54130
|
+
}
|
|
54131
|
+
const req$ = requestRes.value;
|
|
54132
|
+
const doResult = await client$._do(req$, {
|
|
54133
|
+
context,
|
|
54134
|
+
errorCodes: [],
|
|
54135
|
+
retryConfig: context.retryConfig,
|
|
54136
|
+
retryCodes: context.retryCodes
|
|
54137
|
+
});
|
|
54138
|
+
if (!doResult.ok) {
|
|
54139
|
+
return [doResult, { status: "request-error", request: req$ }];
|
|
54140
|
+
}
|
|
54141
|
+
return [doResult, {
|
|
54142
|
+
status: "complete",
|
|
54143
|
+
request: req$,
|
|
54144
|
+
response: doResult.value
|
|
54145
|
+
}];
|
|
54146
|
+
}
|
|
54147
|
+
var init_connectorLookupRecordByIdentifier = __esm(() => {
|
|
54148
|
+
init_encodings();
|
|
54149
|
+
init_primitives();
|
|
54150
|
+
init_schemas4();
|
|
54151
|
+
init_security2();
|
|
54152
|
+
init_url();
|
|
54153
|
+
init_lookuprecordbyidentifierop();
|
|
54154
|
+
init_async();
|
|
54155
|
+
});
|
|
54156
|
+
|
|
54157
|
+
// src/models/navigateknowledgegraphop.ts
|
|
54158
|
+
var NavigateKnowledgeGraphRequest$zodSchema;
|
|
54159
|
+
var init_navigateknowledgegraphop = __esm(() => {
|
|
54160
|
+
init_zod();
|
|
54161
|
+
NavigateKnowledgeGraphRequest$zodSchema = object({
|
|
54162
|
+
createdAfter: string2().describe("Filter children by source creation time. ISO 8601 `YYYY-MM-DD`, or a full datetime that MUST carry a timezone offset — a naive datetime is rejected rather than assumed to be UTC.").optional(),
|
|
54163
|
+
createdBefore: string2().describe("Filter children by source creation time. `YYYY-MM-DD` is inclusive of the whole day.").optional(),
|
|
54164
|
+
depth: int().min(1).max(3).describe("Levels of descendants to return in one call. Above 1, `rows` is a flat list of all descendants down to that level rather than only direct children, and each row carries its own `level`.").optional(),
|
|
54165
|
+
limit: int().min(50).max(200).describe("Children per page. The minimum is 50 — smaller values are rejected rather than silently raised.").optional(),
|
|
54166
|
+
modifiedAfter: string2().describe("Filter children by source modification time.").optional(),
|
|
54167
|
+
modifiedBefore: string2().describe("Filter children by source modification time.").optional(),
|
|
54168
|
+
nodeId: string2().min(1).max(2048).describe("The node to open. Take it from an `id` in a previous navigate or lookup response. Omit it entirely for the flat listing of everything reachable — the usual starting point. A URL or an issue key such as `PA-1787` also works: it is resolved to its record automatically.").optional(),
|
|
54169
|
+
nodeTypes: array(string2()).describe("Restrict children to these node types. Repeat the parameter for multiple types: `?nodeTypes=record&nodeTypes=folder`.").optional(),
|
|
54170
|
+
page: int().min(1).describe("Page number, 1-indexed.").optional()
|
|
54171
|
+
});
|
|
54172
|
+
});
|
|
54173
|
+
|
|
54174
|
+
// src/funcs/connectorNavigateKnowledgeGraph.ts
|
|
54175
|
+
function connectorNavigateKnowledgeGraph(client$, request, options) {
|
|
54176
|
+
return new APIPromise($do10(client$, request, options));
|
|
54177
|
+
}
|
|
54178
|
+
async function $do10(client$, request, options) {
|
|
54179
|
+
const parsed$ = safeParse4(request, (value$) => NavigateKnowledgeGraphRequest$zodSchema.optional().parse(value$), "Input validation failed");
|
|
54180
|
+
if (!parsed$.ok) {
|
|
54181
|
+
return [parsed$, { status: "invalid" }];
|
|
54182
|
+
}
|
|
54183
|
+
const payload$ = parsed$.value;
|
|
54184
|
+
const body$ = null;
|
|
54185
|
+
const path$ = pathToFunc("/connectors/navigate")();
|
|
54186
|
+
const query$ = encodeFormQuery({
|
|
54187
|
+
createdAfter: payload$?.createdAfter,
|
|
54188
|
+
createdBefore: payload$?.createdBefore,
|
|
54189
|
+
depth: payload$?.depth,
|
|
54190
|
+
limit: payload$?.limit,
|
|
54191
|
+
modifiedAfter: payload$?.modifiedAfter,
|
|
54192
|
+
modifiedBefore: payload$?.modifiedBefore,
|
|
54193
|
+
nodeId: payload$?.nodeId,
|
|
54194
|
+
nodeTypes: payload$?.nodeTypes,
|
|
54195
|
+
page: payload$?.page
|
|
54196
|
+
});
|
|
54197
|
+
const headers$ = new Headers(compactMap({
|
|
54198
|
+
Accept: "application/json"
|
|
54199
|
+
}));
|
|
54200
|
+
const securityInput = await extractSecurity(client$._options.security);
|
|
54201
|
+
const requestSecurity = resolveGlobalSecurity(securityInput);
|
|
54202
|
+
const context = {
|
|
54203
|
+
options: client$._options,
|
|
54204
|
+
baseURL: options?.serverURL ?? client$._baseURL ?? "",
|
|
54205
|
+
operationID: "navigateKnowledgeGraph",
|
|
54206
|
+
oAuth2Scopes: ["kb:read", "connector:read"],
|
|
54207
|
+
resolvedSecurity: requestSecurity,
|
|
54208
|
+
securitySource: client$._options.security,
|
|
54209
|
+
retryConfig: options?.retries || client$._options.retryConfig || { strategy: "none" },
|
|
54210
|
+
retryCodes: options?.retryCodes || [
|
|
54211
|
+
"429",
|
|
54212
|
+
"500",
|
|
54213
|
+
"502",
|
|
54214
|
+
"503",
|
|
54215
|
+
"504"
|
|
54216
|
+
]
|
|
54217
|
+
};
|
|
54218
|
+
const requestRes = client$._createRequest(context, {
|
|
54219
|
+
security: requestSecurity,
|
|
54220
|
+
method: "GET",
|
|
54221
|
+
baseURL: options?.serverURL,
|
|
54222
|
+
path: path$,
|
|
54223
|
+
headers: headers$,
|
|
54224
|
+
query: query$,
|
|
54225
|
+
body: body$,
|
|
54226
|
+
userAgent: client$._options.userAgent,
|
|
54227
|
+
timeoutMs: options?.timeoutMs || client$._options.timeoutMs || -1
|
|
54228
|
+
}, options);
|
|
54229
|
+
if (!requestRes.ok) {
|
|
54230
|
+
return [requestRes, { status: "invalid" }];
|
|
54231
|
+
}
|
|
54232
|
+
const req$ = requestRes.value;
|
|
54233
|
+
const doResult = await client$._do(req$, {
|
|
54234
|
+
context,
|
|
54235
|
+
errorCodes: [],
|
|
54236
|
+
retryConfig: context.retryConfig,
|
|
54237
|
+
retryCodes: context.retryCodes
|
|
54238
|
+
});
|
|
54239
|
+
if (!doResult.ok) {
|
|
54240
|
+
return [doResult, { status: "request-error", request: req$ }];
|
|
54241
|
+
}
|
|
54242
|
+
return [doResult, {
|
|
54243
|
+
status: "complete",
|
|
54244
|
+
request: req$,
|
|
54245
|
+
response: doResult.value
|
|
54246
|
+
}];
|
|
54247
|
+
}
|
|
54248
|
+
var init_connectorNavigateKnowledgeGraph = __esm(() => {
|
|
54249
|
+
init_encodings();
|
|
54250
|
+
init_primitives();
|
|
54251
|
+
init_schemas4();
|
|
54252
|
+
init_security2();
|
|
54253
|
+
init_url();
|
|
54254
|
+
init_navigateknowledgegraphop();
|
|
54255
|
+
init_async();
|
|
54256
|
+
});
|
|
54257
|
+
|
|
54258
|
+
// src/mcp-server/tools/pipeshubGetRecordContent.ts
|
|
54259
|
+
async function renderedResult(response) {
|
|
54260
|
+
const parsed = await readJson(response);
|
|
54261
|
+
if (!parsed.ok)
|
|
54262
|
+
return parsed.result;
|
|
54263
|
+
const text = parsed.value?.text;
|
|
54264
|
+
return typeof text === "string" && text.trim().length > 0 ? { content: [{ type: "text", text }] } : jsonResult(parsed.value);
|
|
54265
|
+
}
|
|
54266
|
+
var args4, tool$pipeshubGetRecordContent;
|
|
54267
|
+
var init_pipeshubGetRecordContent = __esm(() => {
|
|
54268
|
+
init_zod();
|
|
54269
|
+
init_connectorGetRecordContent();
|
|
54270
|
+
init_connectorLookupRecordByIdentifier();
|
|
54271
|
+
init_connectorNavigateKnowledgeGraph();
|
|
54272
|
+
init__helpers();
|
|
54273
|
+
args4 = {
|
|
54274
|
+
mode: _enum(["content", "navigate", "lookup"]).default("content").describe("`content` (default) reads a record's full text by `recordId`. " + "`lookup` resolves a URL / issue key / external ID to a recordId. " + "`navigate` browses the knowledge graph tree."),
|
|
54275
|
+
recordId: string2().min(1).optional().describe("Record identifier — usually a UUID for connector-sourced records or " + "a 24-character ObjectId for uploaded records. Get it from a chat " + "citation (`citations[*].recordId`) or from a `pipeshub_search` hit. " + "Required when `mode` is `content`."),
|
|
54276
|
+
nodeId: string2().min(1).max(2048).optional().describe("The node to open. Take it from a `record_id=` or `node_id=` shown in a " + "previous navigate or lookup response, from a search hit's `recordId`, " + "or from a `pipeshub_sources` id — a KB or connector id opens that " + "source directly. Omit it entirely for the flat listing of everything " + "reachable, newest first — the usual starting point. A URL or an issue " + "key such as `PA-1787` also works: it is resolved to its record " + "automatically, so no separate lookup is needed."),
|
|
54277
|
+
page: int().min(1).default(1).describe("Page number, 1-indexed."),
|
|
54278
|
+
limit: int().min(50).max(200).default(50).describe("Children per page. The minimum is 50 — smaller values are rejected " + "rather than silently raised."),
|
|
54279
|
+
depth: int().min(1).max(3).default(1).describe("Levels of descendants to return in one call. Above 1, the listing is a " + "flat list of all descendants down to that level rather than only " + "direct children, and each row carries its own `level`."),
|
|
54280
|
+
nodeTypes: array(string2()).optional().describe('Restrict children to these node types, e.g. `["record", "folder"]`.'),
|
|
54281
|
+
createdAfter: string2().optional().describe("Filter children by source creation time. ISO 8601 `YYYY-MM-DD`, or a " + "full datetime that MUST carry a timezone offset — a naive datetime is " + "rejected rather than assumed to be UTC."),
|
|
54282
|
+
createdBefore: string2().optional().describe("Filter children by source creation time. `YYYY-MM-DD` is inclusive of " + "the whole day."),
|
|
54283
|
+
modifiedAfter: string2().optional().describe("Filter children by source modification time. Same formats as " + "`createdAfter`."),
|
|
54284
|
+
modifiedBefore: string2().optional().describe("Filter children by source modification time. Same formats as " + "`createdBefore`."),
|
|
54285
|
+
identifiers: union([
|
|
54286
|
+
string2().min(1).max(2048),
|
|
54287
|
+
array(string2().min(1).max(2048)).min(1).max(10)
|
|
54288
|
+
]).optional().describe("The reference(s) to resolve: a URL, an issue key such as `PA-1787`, or " + "a bare external system ID. Paste each exactly as you found it — " + "tracking parameters and fragments are handled. Pass a single string, " + "or an array of up to 10 to resolve them in one call. Required when " + "`mode` is `lookup`."),
|
|
54289
|
+
connectorName: string2().optional().describe("Optional hint that prioritises resolution order, e.g. `JIRA`, " + "`CONFLUENCE`, `GOOGLE_DRIVE`, `SLACK`. It cannot widen the search beyond the " + "connectors you can already access. Useful on a retry when a lookup " + "came back empty.")
|
|
54290
|
+
};
|
|
54291
|
+
tool$pipeshubGetRecordContent = {
|
|
54292
|
+
name: "pipeshub_get_record_content",
|
|
54293
|
+
description: `Three operations on the org's records. Pick by what you hold:
|
|
54294
|
+
|
|
54295
|
+
\`mode:"lookup"\` — a URL, issue key (PA-1787), or external ID
|
|
54296
|
+
→ its recordId plus the record's metadata
|
|
54297
|
+
\`mode:"navigate"\` — a question about structure: what is under X,
|
|
54298
|
+
what links to Y → browses the hierarchy
|
|
54299
|
+
\`mode:"content"\` — a recordId, and you need the document's COMPLETE text
|
|
54300
|
+
|
|
54301
|
+
**\`mode:"content"\` (default)** — the only way to see a document's complete
|
|
54302
|
+
text. Use it whenever missing part of the document could make the answer
|
|
54303
|
+
wrong: summarize, extract or list ALL of something, check whether or where
|
|
54304
|
+
a doc mentions X, review, or compare named docs. \`pipeshub_chat\` cannot do
|
|
54305
|
+
these — it never sees a whole document.
|
|
54306
|
+
|
|
54307
|
+
Judge by the user's INTENT, not their keywords: "what's this doc about?",
|
|
54308
|
+
"walk me through the report", "anything in here about Y?" are all
|
|
54309
|
+
full-content tasks. Get the \`recordId\` from a \`pipeshub_search\` top hit, a
|
|
54310
|
+
chat citation, or \`mode:"lookup"\`.
|
|
54311
|
+
|
|
54312
|
+
Returns one \`content\` string: a metadata header (title, source, key fields,
|
|
54313
|
+
pre-generated summary) then the full parsed text. A record with no
|
|
54314
|
+
extractable content returns the literal \`No record found\`. Use
|
|
54315
|
+
\`pipeshub_download_record\` only for the original file bytes.
|
|
54316
|
+
|
|
54317
|
+
**\`mode:"navigate"\`** — browse the hierarchy: RecordGroup (project /
|
|
54318
|
+
space / drive / folder) → Record (epic / story / page / file) → children,
|
|
54319
|
+
with breadcrumbs, related links and record IDs.
|
|
54320
|
+
|
|
54321
|
+
Use it when the question depends on structure rather than wording: what is
|
|
54322
|
+
under this epic, which pages sit in this space, what is linked to this
|
|
54323
|
+
ticket, what is in this folder — and every "how many" / "all of" / "every"
|
|
54324
|
+
question. Search ranks by content; only this shows how records relate, and
|
|
54325
|
+
only this gives a count you can trust.
|
|
54326
|
+
|
|
54327
|
+
Omit \`nodeId\` for a flat listing of everything reachable, most recently
|
|
54328
|
+
updated first — the usual starting point. A URL, an issue key, or a
|
|
54329
|
+
\`pipeshub_sources\` id also works and resolves automatically.
|
|
54330
|
+
|
|
54331
|
+
Pass \`depth:2\` or \`depth:3\` to see several levels in ONE call — an epic's
|
|
54332
|
+
stories AND their subtasks, a space's pages AND their children — instead of
|
|
54333
|
+
one call per level. Use it whenever the question needs an overview of a
|
|
54334
|
+
hierarchy rather than a single node.
|
|
54335
|
+
|
|
54336
|
+
Opening a record also prints that record's own metadata — for a ticket,
|
|
54337
|
+
status, assignee, priority and dates — so a question about one record is
|
|
54338
|
+
often answered by this call alone. It returns no document text; for that,
|
|
54339
|
+
re-call with \`mode:"content"\`.
|
|
54340
|
+
|
|
54341
|
+
Returns \`Path\` breadcrumbs, the current node's metadata, a children listing
|
|
54342
|
+
carrying \`record_id=\` or \`node_id=\` per row plus the group's total
|
|
54343
|
+
(\`Children 1-50 of 61\`), \`Related\` cross-references, and a \`Next:\` line.
|
|
54344
|
+
One page is usually every child, so only pass \`page:2\` when that \`Next:\`
|
|
54345
|
+
line says more exist.
|
|
54346
|
+
|
|
54347
|
+
**\`mode:"lookup"\`** — turn an external reference into a recordId, the first
|
|
54348
|
+
step whenever the question names one. Returns that record's metadata (for a
|
|
54349
|
+
ticket: status, assignee, priority, dates) plus its recordId, which
|
|
54350
|
+
\`mode:"navigate"\` takes to list what is under it and \`mode:"content"\` takes
|
|
54351
|
+
to read it.
|
|
54352
|
+
|
|
54353
|
+
Handles Jira keys and URLs, Confluence, Drive, Slack permalinks, Linear,
|
|
54354
|
+
Notion, ServiceNow sys_id, SharePoint, Gmail/Outlook, and any connector
|
|
54355
|
+
whose records index a web URL. Resolution searches ALL connectors you can
|
|
54356
|
+
access, regardless of any source filter you used elsewhere.
|
|
54357
|
+
|
|
54358
|
+
A miss is a 200 with empty \`matches\` and the input echoed in
|
|
54359
|
+
\`not_found_identifiers\` — that may mean no-access, not non-existence. Use
|
|
54360
|
+
\`mode:"navigate"\` to confirm the record exists before telling the user it
|
|
54361
|
+
does not. If \`ambiguous\` is true, pick from \`matches\` rather than taking
|
|
54362
|
+
the first.
|
|
54363
|
+
|
|
54364
|
+
Navigate and lookup return a rendered text view whose closing \`Next:\` line
|
|
54365
|
+
names the exact follow-up call — follow it. When presenting a record, link
|
|
54366
|
+
it using the \`Web URL\` from its metadata header (when present).`,
|
|
54367
|
+
scopes: ["read"],
|
|
54368
|
+
annotations: {
|
|
54369
|
+
title: "Read, browse, or resolve records",
|
|
54370
|
+
destructiveHint: false,
|
|
54371
|
+
idempotentHint: true,
|
|
54372
|
+
openWorldHint: false,
|
|
54373
|
+
readOnlyHint: true
|
|
54374
|
+
},
|
|
54375
|
+
args: args4,
|
|
54376
|
+
tool: async (client, args5, ctx) => {
|
|
54377
|
+
const fetchOptions = { fetchOptions: { signal: ctx.signal } };
|
|
54378
|
+
if (args5.mode === "navigate") {
|
|
54379
|
+
const [r] = await connectorNavigateKnowledgeGraph(client, {
|
|
54380
|
+
nodeId: args5.nodeId,
|
|
54381
|
+
page: args5.page,
|
|
54382
|
+
limit: args5.limit,
|
|
54383
|
+
depth: args5.depth,
|
|
54384
|
+
nodeTypes: args5.nodeTypes,
|
|
54385
|
+
createdAfter: args5.createdAfter,
|
|
54386
|
+
createdBefore: args5.createdBefore,
|
|
54387
|
+
modifiedAfter: args5.modifiedAfter,
|
|
54388
|
+
modifiedBefore: args5.modifiedBefore
|
|
54389
|
+
}, fetchOptions).$inspect();
|
|
54390
|
+
if (!r.ok)
|
|
54391
|
+
return errorResult(r.error.message);
|
|
54392
|
+
const httpErr2 = await httpErrorResult(r.value, "Navigate knowledge graph");
|
|
54393
|
+
if (httpErr2)
|
|
54394
|
+
return httpErr2;
|
|
54395
|
+
return renderedResult(r.value);
|
|
54396
|
+
}
|
|
54397
|
+
if (args5.mode === "lookup") {
|
|
54398
|
+
const identifiers = typeof args5.identifiers === "string" ? [args5.identifiers] : args5.identifiers ?? [];
|
|
54399
|
+
if (identifiers.length === 0) {
|
|
54400
|
+
return errorResult('`identifiers` is required when mode is "lookup".');
|
|
54401
|
+
}
|
|
54402
|
+
const [r] = await connectorLookupRecordByIdentifier(client, {
|
|
54403
|
+
identifiers,
|
|
54404
|
+
connectorName: args5.connectorName
|
|
54405
|
+
}, fetchOptions).$inspect();
|
|
54406
|
+
if (!r.ok)
|
|
54407
|
+
return errorResult(r.error.message);
|
|
54408
|
+
const httpErr2 = await httpErrorResult(r.value, "Record lookup");
|
|
54409
|
+
if (httpErr2)
|
|
54410
|
+
return httpErr2;
|
|
54411
|
+
return renderedResult(r.value);
|
|
54412
|
+
}
|
|
54413
|
+
if (!args5.recordId) {
|
|
54414
|
+
return errorResult('`recordId` is required when mode is "content".');
|
|
54415
|
+
}
|
|
54416
|
+
const [result] = await connectorGetRecordContent(client, {
|
|
54417
|
+
recordId: args5.recordId
|
|
54418
|
+
}, fetchOptions).$inspect();
|
|
54419
|
+
if (!result.ok)
|
|
54420
|
+
return errorResult(result.error.message);
|
|
54421
|
+
const httpErr = await httpErrorResult(result.value, "Get record content");
|
|
54422
|
+
if (httpErr)
|
|
54423
|
+
return httpErr;
|
|
54424
|
+
const parsed = await readJson(result.value);
|
|
54425
|
+
if (!parsed.ok)
|
|
54426
|
+
return parsed.result;
|
|
54427
|
+
return { content: [{ type: "text", text: parsed.value.content ?? "" }] };
|
|
54428
|
+
}
|
|
54429
|
+
};
|
|
54430
|
+
});
|
|
54431
|
+
|
|
53740
54432
|
// src/models/getallusersop.ts
|
|
53741
54433
|
var GetAllUsersRequest$zodSchema;
|
|
53742
54434
|
var init_getallusersop = __esm(() => {
|
|
@@ -53750,9 +54442,9 @@ var init_getallusersop = __esm(() => {
|
|
|
53750
54442
|
|
|
53751
54443
|
// src/funcs/usersGetAllUsers.ts
|
|
53752
54444
|
function usersGetAllUsers(client$, request, options) {
|
|
53753
|
-
return new APIPromise($
|
|
54445
|
+
return new APIPromise($do11(client$, request, options));
|
|
53754
54446
|
}
|
|
53755
|
-
async function $
|
|
54447
|
+
async function $do11(client$, request, options) {
|
|
53756
54448
|
const parsed$ = safeParse4(request, (value$) => GetAllUsersRequest$zodSchema.optional().parse(value$), "Input validation failed");
|
|
53757
54449
|
if (!parsed$.ok) {
|
|
53758
54450
|
return [parsed$, { status: "invalid" }];
|
|
@@ -53837,9 +54529,9 @@ var init_getuserbyidop = __esm(() => {
|
|
|
53837
54529
|
|
|
53838
54530
|
// src/funcs/usersGetUserById.ts
|
|
53839
54531
|
function usersGetUserById(client$, request, options) {
|
|
53840
|
-
return new APIPromise($
|
|
54532
|
+
return new APIPromise($do12(client$, request, options));
|
|
53841
54533
|
}
|
|
53842
|
-
async function $
|
|
54534
|
+
async function $do12(client$, request, options) {
|
|
53843
54535
|
const parsed$ = safeParse4(request, (value$) => GetUserByIdRequest$zodSchema.parse(value$), "Input validation failed");
|
|
53844
54536
|
if (!parsed$.ok) {
|
|
53845
54537
|
return [parsed$, { status: "invalid" }];
|
|
@@ -53926,9 +54618,9 @@ var init_getallusergroupsop = __esm(() => {
|
|
|
53926
54618
|
|
|
53927
54619
|
// src/funcs/userGroupsGetAllUserGroups.ts
|
|
53928
54620
|
function userGroupsGetAllUserGroups(client$, request, options) {
|
|
53929
|
-
return new APIPromise($
|
|
54621
|
+
return new APIPromise($do13(client$, request, options));
|
|
53930
54622
|
}
|
|
53931
|
-
async function $
|
|
54623
|
+
async function $do13(client$, request, options) {
|
|
53932
54624
|
const parsed$ = safeParse4(request, (value$) => GetAllUserGroupsRequest$zodSchema.optional().parse(value$), "Input validation failed");
|
|
53933
54625
|
if (!parsed$.ok) {
|
|
53934
54626
|
return [parsed$, { status: "invalid" }];
|
|
@@ -53950,7 +54642,7 @@ async function $do10(client$, request, options) {
|
|
|
53950
54642
|
options: client$._options,
|
|
53951
54643
|
baseURL: options?.serverURL ?? client$._baseURL ?? "",
|
|
53952
54644
|
operationID: "getAllUserGroups",
|
|
53953
|
-
oAuth2Scopes: [],
|
|
54645
|
+
oAuth2Scopes: ["usergroup:read"],
|
|
53954
54646
|
resolvedSecurity: requestSecurity,
|
|
53955
54647
|
securitySource: client$._options.security,
|
|
53956
54648
|
retryConfig: options?.retries || client$._options.retryConfig || { strategy: "none" },
|
|
@@ -54018,9 +54710,9 @@ var init_getuserteamsop = __esm(() => {
|
|
|
54018
54710
|
|
|
54019
54711
|
// src/funcs/teamsGetUserTeams.ts
|
|
54020
54712
|
function teamsGetUserTeams(client$, request, options) {
|
|
54021
|
-
return new APIPromise($
|
|
54713
|
+
return new APIPromise($do14(client$, request, options));
|
|
54022
54714
|
}
|
|
54023
|
-
async function $
|
|
54715
|
+
async function $do14(client$, request, options) {
|
|
54024
54716
|
const parsed$ = safeParse4(request, (value$) => GetUserTeamsRequest$zodSchema.optional().parse(value$), "Input validation failed");
|
|
54025
54717
|
if (!parsed$.ok) {
|
|
54026
54718
|
return [parsed$, { status: "invalid" }];
|
|
@@ -54098,7 +54790,7 @@ var init_teamsGetUserTeams = __esm(() => {
|
|
|
54098
54790
|
});
|
|
54099
54791
|
|
|
54100
54792
|
// src/mcp-server/tools/pipeshubDirectory.ts
|
|
54101
|
-
var
|
|
54793
|
+
var args5, tool$pipeshubDirectory;
|
|
54102
54794
|
var init_pipeshubDirectory = __esm(() => {
|
|
54103
54795
|
init_zod();
|
|
54104
54796
|
init_usersGetAllUsers();
|
|
@@ -54106,7 +54798,7 @@ var init_pipeshubDirectory = __esm(() => {
|
|
|
54106
54798
|
init_userGroupsGetAllUserGroups();
|
|
54107
54799
|
init_teamsGetUserTeams();
|
|
54108
54800
|
init__helpers();
|
|
54109
|
-
|
|
54801
|
+
args5 = {
|
|
54110
54802
|
action: _enum([
|
|
54111
54803
|
"whoami",
|
|
54112
54804
|
"list_users",
|
|
@@ -54144,10 +54836,10 @@ Output shape varies by action; see each action's docs above.`,
|
|
|
54144
54836
|
openWorldHint: false,
|
|
54145
54837
|
readOnlyHint: true
|
|
54146
54838
|
},
|
|
54147
|
-
args:
|
|
54148
|
-
tool: async (client,
|
|
54839
|
+
args: args5,
|
|
54840
|
+
tool: async (client, args6, ctx) => {
|
|
54149
54841
|
const fetchOptions = { signal: ctx.signal };
|
|
54150
|
-
switch (
|
|
54842
|
+
switch (args6.action) {
|
|
54151
54843
|
case "whoami": {
|
|
54152
54844
|
const claims = await decodeBearer(client);
|
|
54153
54845
|
if (!claims) {
|
|
@@ -54164,9 +54856,9 @@ Output shape varies by action; see each action's docs above.`,
|
|
|
54164
54856
|
}
|
|
54165
54857
|
case "list_users": {
|
|
54166
54858
|
const [result] = await usersGetAllUsers(client, {
|
|
54167
|
-
page:
|
|
54168
|
-
limit:
|
|
54169
|
-
search:
|
|
54859
|
+
page: args6.page,
|
|
54860
|
+
limit: args6.limit,
|
|
54861
|
+
search: args6.search
|
|
54170
54862
|
}, { fetchOptions }).$inspect();
|
|
54171
54863
|
if (!result.ok)
|
|
54172
54864
|
return errorResult(result.error.message);
|
|
@@ -54176,11 +54868,11 @@ Output shape varies by action; see each action's docs above.`,
|
|
|
54176
54868
|
return jsonResult(parsed.value);
|
|
54177
54869
|
}
|
|
54178
54870
|
case "get_user": {
|
|
54179
|
-
if (!
|
|
54871
|
+
if (!args6.userId) {
|
|
54180
54872
|
return errorResult("`userId` is required when `action` is `get_user`. " + "Use `whoami` to find your own id, or `list_users` " + "to look up by name / email.");
|
|
54181
54873
|
}
|
|
54182
54874
|
const [result] = await usersGetUserById(client, {
|
|
54183
|
-
id:
|
|
54875
|
+
id: args6.userId
|
|
54184
54876
|
}, { fetchOptions }).$inspect();
|
|
54185
54877
|
if (!result.ok)
|
|
54186
54878
|
return errorResult(result.error.message);
|
|
@@ -54191,9 +54883,9 @@ Output shape varies by action; see each action's docs above.`,
|
|
|
54191
54883
|
}
|
|
54192
54884
|
case "list_groups": {
|
|
54193
54885
|
const [result] = await userGroupsGetAllUserGroups(client, {
|
|
54194
|
-
page:
|
|
54195
|
-
limit:
|
|
54196
|
-
search:
|
|
54886
|
+
page: args6.page,
|
|
54887
|
+
limit: args6.limit,
|
|
54888
|
+
search: args6.search
|
|
54197
54889
|
}, { fetchOptions }).$inspect();
|
|
54198
54890
|
if (!result.ok)
|
|
54199
54891
|
return errorResult(result.error.message);
|
|
@@ -54204,9 +54896,9 @@ Output shape varies by action; see each action's docs above.`,
|
|
|
54204
54896
|
}
|
|
54205
54897
|
case "list_my_teams": {
|
|
54206
54898
|
const [result] = await teamsGetUserTeams(client, {
|
|
54207
|
-
page:
|
|
54208
|
-
limit:
|
|
54209
|
-
search:
|
|
54899
|
+
page: args6.page,
|
|
54900
|
+
limit: args6.limit,
|
|
54901
|
+
search: args6.search
|
|
54210
54902
|
}, { fetchOptions }).$inspect();
|
|
54211
54903
|
if (!result.ok)
|
|
54212
54904
|
return errorResult(result.error.message);
|
|
@@ -54250,9 +54942,9 @@ var init_getknowledgehubrootnodesop = __esm(() => {
|
|
|
54250
54942
|
|
|
54251
54943
|
// src/funcs/knowledgeHubGetKnowledgeHubRootNodes.ts
|
|
54252
54944
|
function knowledgeHubGetKnowledgeHubRootNodes(client$, request, options) {
|
|
54253
|
-
return new APIPromise($
|
|
54945
|
+
return new APIPromise($do15(client$, request, options));
|
|
54254
54946
|
}
|
|
54255
|
-
async function $
|
|
54947
|
+
async function $do15(client$, request, options) {
|
|
54256
54948
|
const parsed$ = safeParse4(request, (value$) => GetKnowledgeHubRootNodesRequest$zodSchema.optional().parse(value$), "Input validation failed");
|
|
54257
54949
|
if (!parsed$.ok) {
|
|
54258
54950
|
return [parsed$, { status: "invalid" }];
|
|
@@ -54368,9 +55060,9 @@ var init_getavailablemodelsbytypeop = __esm(() => {
|
|
|
54368
55060
|
|
|
54369
55061
|
// src/funcs/aiModelsProvidersGetAvailableModelsByType.ts
|
|
54370
55062
|
function aiModelsProvidersGetAvailableModelsByType(client$, request, options) {
|
|
54371
|
-
return new APIPromise($
|
|
55063
|
+
return new APIPromise($do16(client$, request, options));
|
|
54372
55064
|
}
|
|
54373
|
-
async function $
|
|
55065
|
+
async function $do16(client$, request, options) {
|
|
54374
55066
|
const parsed$ = safeParse4(request, (value$) => GetAvailableModelsByTypeRequest$zodSchema.parse(value$), "Input validation failed");
|
|
54375
55067
|
if (!parsed$.ok) {
|
|
54376
55068
|
return [parsed$, { status: "invalid" }];
|
|
@@ -54445,13 +55137,13 @@ var init_aiModelsProvidersGetAvailableModelsByType = __esm(() => {
|
|
|
54445
55137
|
});
|
|
54446
55138
|
|
|
54447
55139
|
// src/mcp-server/tools/pipeshubSources.ts
|
|
54448
|
-
var
|
|
55140
|
+
var args6, tool$pipeshubSources;
|
|
54449
55141
|
var init_pipeshubSources = __esm(() => {
|
|
54450
55142
|
init_zod();
|
|
54451
55143
|
init_knowledgeHubGetKnowledgeHubRootNodes();
|
|
54452
55144
|
init_aiModelsProvidersGetAvailableModelsByType();
|
|
54453
55145
|
init__helpers();
|
|
54454
|
-
|
|
55146
|
+
args6 = {
|
|
54455
55147
|
include: array(_enum(["sources", "llmModels", "embeddingModels"])).optional().describe('Which sections to fetch. Default: `["sources", "llmModels"]`. ' + "Add `embeddingModels` if the user is configuring re-embedding.")
|
|
54456
55148
|
};
|
|
54457
55149
|
tool$pipeshubSources = {
|
|
@@ -54482,10 +55174,10 @@ are returned by default; pass \`include\` to override.`,
|
|
|
54482
55174
|
openWorldHint: false,
|
|
54483
55175
|
readOnlyHint: true
|
|
54484
55176
|
},
|
|
54485
|
-
args:
|
|
54486
|
-
tool: async (client,
|
|
55177
|
+
args: args6,
|
|
55178
|
+
tool: async (client, args7, ctx) => {
|
|
54487
55179
|
const fetchOptions = { signal: ctx.signal };
|
|
54488
|
-
const include =
|
|
55180
|
+
const include = args7.include ?? ["sources", "llmModels"];
|
|
54489
55181
|
const want = (s) => include.includes(s);
|
|
54490
55182
|
const result = {};
|
|
54491
55183
|
if (want("sources")) {
|
|
@@ -54535,11 +55227,11 @@ are returned by default; pass \`include\` to override.`,
|
|
|
54535
55227
|
});
|
|
54536
55228
|
|
|
54537
55229
|
// src/mcp-server/tools/pipeshubAgents.ts
|
|
54538
|
-
var
|
|
55230
|
+
var args7, tool$pipeshubAgents;
|
|
54539
55231
|
var init_pipeshubAgents = __esm(() => {
|
|
54540
55232
|
init_zod();
|
|
54541
55233
|
init__helpers();
|
|
54542
|
-
|
|
55234
|
+
args7 = {
|
|
54543
55235
|
search: string2().optional().describe("Optional case-insensitive substring match across agent name, " + "description, and tags. Omit to return every agent.")
|
|
54544
55236
|
};
|
|
54545
55237
|
tool$pipeshubAgents = {
|
|
@@ -54578,10 +55270,10 @@ specific agent is needed, use \`pipeshub_chat\` WITHOUT \`agentId\` and pick a
|
|
|
54578
55270
|
openWorldHint: false,
|
|
54579
55271
|
readOnlyHint: true
|
|
54580
55272
|
},
|
|
54581
|
-
args:
|
|
54582
|
-
tool: async (client,
|
|
55273
|
+
args: args7,
|
|
55274
|
+
tool: async (client, args8, ctx) => {
|
|
54583
55275
|
const all = await listAllAgents(client, {
|
|
54584
|
-
search:
|
|
55276
|
+
search: args8.search,
|
|
54585
55277
|
signal: ctx.signal
|
|
54586
55278
|
});
|
|
54587
55279
|
if (!all.ok)
|
|
@@ -54596,25 +55288,25 @@ specific agent is needed, use \`pipeshub_chat\` WITHOUT \`agentId\` and pick a
|
|
|
54596
55288
|
});
|
|
54597
55289
|
|
|
54598
55290
|
// src/mcp-server/prompts/pipeshubAssistant.ts
|
|
54599
|
-
var
|
|
55291
|
+
var args8, prompt$pipeshubAssistant;
|
|
54600
55292
|
var init_pipeshubAssistant = __esm(() => {
|
|
54601
55293
|
init_zod();
|
|
54602
|
-
|
|
55294
|
+
args8 = {
|
|
54603
55295
|
query: string2().optional().describe("Optional. The user's request to route. Provide it to have the guidance " + "applied to a concrete request; omit it to just load the routing " + "guidance as a seed system prompt at the start of a session.")
|
|
54604
55296
|
};
|
|
54605
55297
|
prompt$pipeshubAssistant = {
|
|
54606
55298
|
name: "pipeshub-assistant",
|
|
54607
55299
|
description: "Load PipesHub tool-routing guidance so the assistant picks the correct " + "tool (pipeshub_chat / search / agents / directory) and lists agents " + "with pipeshub_agents when unsure which route fits the query.",
|
|
54608
55300
|
scopes: ["read"],
|
|
54609
|
-
args:
|
|
54610
|
-
prompt: (_client,
|
|
54611
|
-
const text =
|
|
55301
|
+
args: args8,
|
|
55302
|
+
prompt: (_client, args9, _extra) => {
|
|
55303
|
+
const text = args9.query ? `${PIPESHUB_INSTRUCTIONS}
|
|
54612
55304
|
|
|
54613
55305
|
---
|
|
54614
55306
|
|
|
54615
55307
|
Follow the routing rules above to ` + `handle this request, picking the right tool (and listing agents via ` + `\`pipeshub_agents\` if unsure which route fits):
|
|
54616
55308
|
|
|
54617
|
-
${
|
|
55309
|
+
${args9.query}` : PIPESHUB_INSTRUCTIONS;
|
|
54618
55310
|
return {
|
|
54619
55311
|
messages: [
|
|
54620
55312
|
{
|
|
@@ -54635,17 +55327,21 @@ function createMCPServer(deps) {
|
|
|
54635
55327
|
}, {
|
|
54636
55328
|
instructions: PIPESHUB_INSTRUCTIONS
|
|
54637
55329
|
});
|
|
54638
|
-
const
|
|
55330
|
+
const resolveClient = deps.getSDK || (() => new PipeshubCore({
|
|
54639
55331
|
security: deps.security,
|
|
54640
55332
|
serverURL: deps.serverURL,
|
|
54641
55333
|
serverIdx: deps.serverIdx,
|
|
54642
55334
|
instance_url: deps.instance_url,
|
|
54643
55335
|
debugLogger: deps.logger.level === "debug" ? {
|
|
54644
|
-
log: (...
|
|
54645
|
-
group: (...
|
|
54646
|
-
groupEnd: (...
|
|
55336
|
+
log: (...args9) => console.log(...args9),
|
|
55337
|
+
group: (...args9) => console.group(...args9),
|
|
55338
|
+
groupEnd: (...args9) => console.groupEnd(...args9)
|
|
54647
55339
|
} : undefined
|
|
54648
55340
|
}));
|
|
55341
|
+
const getClient = () => {
|
|
55342
|
+
bindNewRequestId();
|
|
55343
|
+
return resolveClient();
|
|
55344
|
+
};
|
|
54649
55345
|
const scopes = new Set(deps.scopes);
|
|
54650
55346
|
const allowedTools = deps.allowedTools && new Set(deps.allowedTools);
|
|
54651
55347
|
const [tool, tools, toolMap] = createRegisterTool(deps.logger, server, getClient, scopes, allowedTools, deps.dynamic);
|
|
@@ -54657,6 +55353,7 @@ function createMCPServer(deps) {
|
|
|
54657
55353
|
tool(tool$pipeshubChat);
|
|
54658
55354
|
tool(tool$pipeshubSearch);
|
|
54659
55355
|
tool(tool$pipeshubDownloadRecord);
|
|
55356
|
+
tool(tool$pipeshubGetRecordContent);
|
|
54660
55357
|
tool(tool$pipeshubDirectory);
|
|
54661
55358
|
tool(tool$pipeshubAgents);
|
|
54662
55359
|
prompt(prompt$pipeshubAssistant);
|
|
@@ -54668,11 +55365,13 @@ function createMCPServer(deps) {
|
|
|
54668
55365
|
var init_server2 = __esm(() => {
|
|
54669
55366
|
init_mcp();
|
|
54670
55367
|
init_core3();
|
|
55368
|
+
init_request_context();
|
|
54671
55369
|
init_resources();
|
|
54672
55370
|
init_tools();
|
|
54673
55371
|
init_pipeshubChat();
|
|
54674
55372
|
init_pipeshubSearch();
|
|
54675
55373
|
init_pipeshubDownloadRecord();
|
|
55374
|
+
init_pipeshubGetRecordContent();
|
|
54676
55375
|
init_pipeshubDirectory();
|
|
54677
55376
|
init_pipeshubSources();
|
|
54678
55377
|
init_pipeshubAgents();
|
|
@@ -54689,25 +55388,39 @@ var init_tool_names = __esm(() => {
|
|
|
54689
55388
|
},
|
|
54690
55389
|
{
|
|
54691
55390
|
name: "pipeshub_chat",
|
|
54692
|
-
description:
|
|
54693
|
-
|
|
54694
|
-
|
|
54695
|
-
|
|
54696
|
-
|
|
54697
|
-
|
|
54698
|
-
|
|
54699
|
-
|
|
54700
|
-
|
|
54701
|
-
|
|
54702
|
-
|
|
54703
|
-
|
|
54704
|
-
|
|
54705
|
-
|
|
54706
|
-
|
|
54707
|
-
|
|
55391
|
+
description: `Ask a question, get an answer grounded in the org's indexed data with
|
|
55392
|
+
citations. It reads a few retrieved passages — never a whole document,
|
|
55393
|
+
never a complete list.
|
|
55394
|
+
|
|
55395
|
+
**Three questions this tool gets WRONG. Check them first:**
|
|
55396
|
+
- **Structure** — "what's under this epic?", "which pages are in this
|
|
55397
|
+
space?", "what links to this ticket?", "what's in this folder?" →
|
|
55398
|
+
\`pipeshub_get_record_content\` \`mode:"navigate"\`. Ranking cannot see how
|
|
55399
|
+
records relate.
|
|
55400
|
+
- **Exhaustive** — "how many X?", "list ALL the Y", "every Z" →
|
|
55401
|
+
\`mode:"navigate"\`, which reports the group's real total. This tool
|
|
55402
|
+
undercounts and will not say so.
|
|
55403
|
+
- **One named document** — summarize it, extract from it, what does it say
|
|
55404
|
+
about X → \`pipeshub_search\` for the \`recordId\`, then \`mode:"content"\`.
|
|
55405
|
+
|
|
55406
|
+
Everything else about the org's knowledge belongs here: policies,
|
|
55407
|
+
processes, decisions, history, "what do we know about X", and any question
|
|
55408
|
+
spanning several documents.
|
|
55409
|
+
|
|
55410
|
+
**Internal search** (default, \`chatMode: "internal_search"\`): the user's
|
|
55411
|
+
documents, files, knowledge base, company policies — anything in their
|
|
55412
|
+
PipesHub-indexed sources (Drive, Box, Confluence, Slack, Gmail, Jira, the
|
|
55413
|
+
org's KB, ...).
|
|
55414
|
+
|
|
55415
|
+
**Web search** (\`chatMode: "web_search"\`): current events or public
|
|
55416
|
+
information unlikely to be in the org's knowledge base.
|
|
55417
|
+
|
|
55418
|
+
Both are plain-chat modes. **Agent chat** — pass an \`agentId\` from
|
|
55419
|
+
\`pipeshub_agents\` — runs against that agent's own prompt, tools and knowledge;
|
|
55420
|
+
\`quick\` is its only mode, requires the \`agentId\`, and is sent automatically.
|
|
55421
|
+
|
|
54708
55422
|
- "What's our policy on Y?" → \`pipeshub_chat\` (internal_search)
|
|
54709
55423
|
- "What's in the news about Z?" → \`pipeshub_chat\` (web_search)
|
|
54710
|
-
- "What is the latest version of <library>?" → \`pipeshub_chat\` (web_search)
|
|
54711
55424
|
- "Find / locate the file named X" → \`pipeshub_search\` (then
|
|
54712
55425
|
\`pipeshub_download_record\` if the user wants the bytes).
|
|
54713
55426
|
|
|
@@ -54731,26 +55444,120 @@ cited document, take \`citations[*].recordId\` and call
|
|
|
54731
55444
|
name: "pipeshub_search",
|
|
54732
55445
|
description: `Vector / semantic search across the org's indexed documents.
|
|
54733
55446
|
|
|
54734
|
-
**Use this
|
|
54735
|
-
|
|
54736
|
-
|
|
54737
|
-
does the retrieval internally and grounds the answer in
|
|
55447
|
+
**Use this when the user wants to LOCATE a document** — by name, topic,
|
|
55448
|
+
or a phrase to grep for — and to resolve it to a \`recordId\`. For
|
|
55449
|
+
open-ended questions across many documents, use \`pipeshub_chat\`
|
|
55450
|
+
instead, which does the retrieval internally and grounds the answer in
|
|
55451
|
+
citations.
|
|
54738
55452
|
|
|
54739
55453
|
Typical uses:
|
|
55454
|
+
- Resolve a doc name / topic into a \`recordId\` for
|
|
55455
|
+
\`pipeshub_get_record_content\` — step 1 of any full-document task
|
|
55456
|
+
(summarize, extract, review, "what does the doc say?").
|
|
54740
55457
|
- Resolve a filename / phrase into a \`recordId\` for
|
|
54741
55458
|
\`pipeshub_download_record\`.
|
|
54742
55459
|
- Show the user a ranked list of matching files when they ask "find /
|
|
54743
55460
|
search for X".
|
|
54744
55461
|
|
|
55462
|
+
Not for structural questions — what is under this epic, which pages are
|
|
55463
|
+
in this space, what links to this ticket. Ranking by content cannot show
|
|
55464
|
+
how records relate; use \`pipeshub_get_record_content\` \`mode:"navigate"\`.
|
|
55465
|
+
|
|
55466
|
+
**A ranked sample, never a complete list.** Hits are the top-scoring
|
|
55467
|
+
blocks from the best-matching records — not all blocks of any record, and
|
|
55468
|
+
not every record that matches. Never count them to answer "how many" /
|
|
55469
|
+
"all" / "every"; navigate the record group instead, which reports its
|
|
55470
|
+
real total.
|
|
55471
|
+
|
|
54745
55472
|
The response is trimmed to one row per hit:
|
|
54746
55473
|
\`{ recordId, recordName, score, snippet, mimeType, webUrl, ... }\`.
|
|
54747
55474
|
Highest \`score\` first; multiple hits may share the same \`recordId\`
|
|
54748
|
-
(different
|
|
55475
|
+
(different blocks of the same record).
|
|
55476
|
+
|
|
55477
|
+
When presenting results to the user, link each record using its
|
|
55478
|
+
\`webUrl\` (when present).`
|
|
54749
55479
|
},
|
|
54750
55480
|
{
|
|
54751
55481
|
name: "pipeshub_download_record",
|
|
54752
55482
|
description: "Stream the binary content of a single record from PipesHub.\n\nTypical sources for the `recordId`:\n- A chat citation:\n `pipeshub_chat` response → `citations[*].recordId`.\n- A search result:\n `pipeshub_search` response → `hits[*].recordId` /\n `uniqueRecords[*].recordId`.\n\nResponse `Content-Type` is forwarded from the upstream service —\n`application/pdf`, `application/octet-stream`, etc. Binary content is\nreturned base64-encoded; text content is returned inline."
|
|
54753
55483
|
},
|
|
55484
|
+
{
|
|
55485
|
+
name: "pipeshub_get_record_content",
|
|
55486
|
+
description: `Three operations on the org's records. Pick by what you hold:
|
|
55487
|
+
|
|
55488
|
+
\`mode:"lookup"\` — a URL, issue key (PA-1787), or external ID
|
|
55489
|
+
→ its recordId plus the record's metadata
|
|
55490
|
+
\`mode:"navigate"\` — a question about structure: what is under X,
|
|
55491
|
+
what links to Y → browses the hierarchy
|
|
55492
|
+
\`mode:"content"\` — a recordId, and you need the document's COMPLETE text
|
|
55493
|
+
|
|
55494
|
+
**\`mode:"content"\` (default)** — the only way to see a document's complete
|
|
55495
|
+
text. Use it whenever missing part of the document could make the answer
|
|
55496
|
+
wrong: summarize, extract or list ALL of something, check whether or where
|
|
55497
|
+
a doc mentions X, review, or compare named docs. \`pipeshub_chat\` cannot do
|
|
55498
|
+
these — it never sees a whole document.
|
|
55499
|
+
|
|
55500
|
+
Judge by the user's INTENT, not their keywords: "what's this doc about?",
|
|
55501
|
+
"walk me through the report", "anything in here about Y?" are all
|
|
55502
|
+
full-content tasks. Get the \`recordId\` from a \`pipeshub_search\` top hit, a
|
|
55503
|
+
chat citation, or \`mode:"lookup"\`.
|
|
55504
|
+
|
|
55505
|
+
Returns one \`content\` string: a metadata header (title, source, key fields,
|
|
55506
|
+
pre-generated summary) then the full parsed text. A record with no
|
|
55507
|
+
extractable content returns the literal \`No record found\`. Use
|
|
55508
|
+
\`pipeshub_download_record\` only for the original file bytes.
|
|
55509
|
+
|
|
55510
|
+
**\`mode:"navigate"\`** — browse the hierarchy: RecordGroup (project /
|
|
55511
|
+
space / drive / folder) → Record (epic / story / page / file) → children,
|
|
55512
|
+
with breadcrumbs, related links and record IDs.
|
|
55513
|
+
|
|
55514
|
+
Use it when the question depends on structure rather than wording: what is
|
|
55515
|
+
under this epic, which pages sit in this space, what is linked to this
|
|
55516
|
+
ticket, what is in this folder — and every "how many" / "all of" / "every"
|
|
55517
|
+
question. Search ranks by content; only this shows how records relate, and
|
|
55518
|
+
only this gives a count you can trust.
|
|
55519
|
+
|
|
55520
|
+
Omit \`nodeId\` for a flat listing of everything reachable, most recently
|
|
55521
|
+
updated first — the usual starting point. A URL, an issue key, or a
|
|
55522
|
+
\`pipeshub_sources\` id also works and resolves automatically.
|
|
55523
|
+
|
|
55524
|
+
Pass \`depth:2\` or \`depth:3\` to see several levels in ONE call — an epic's
|
|
55525
|
+
stories AND their subtasks, a space's pages AND their children — instead of
|
|
55526
|
+
one call per level. Use it whenever the question needs an overview of a
|
|
55527
|
+
hierarchy rather than a single node.
|
|
55528
|
+
|
|
55529
|
+
Opening a record also prints that record's own metadata — for a ticket,
|
|
55530
|
+
status, assignee, priority and dates — so a question about one record is
|
|
55531
|
+
often answered by this call alone. It returns no document text; for that,
|
|
55532
|
+
re-call with \`mode:"content"\`.
|
|
55533
|
+
|
|
55534
|
+
Returns \`Path\` breadcrumbs, the current node's metadata, a children listing
|
|
55535
|
+
carrying \`record_id=\` or \`node_id=\` per row plus the group's total
|
|
55536
|
+
(\`Children 1-50 of 61\`), \`Related\` cross-references, and a \`Next:\` line.
|
|
55537
|
+
One page is usually every child, so only pass \`page:2\` when that \`Next:\`
|
|
55538
|
+
line says more exist.
|
|
55539
|
+
|
|
55540
|
+
**\`mode:"lookup"\`** — turn an external reference into a recordId, the first
|
|
55541
|
+
step whenever the question names one. Returns that record's metadata (for a
|
|
55542
|
+
ticket: status, assignee, priority, dates) plus its recordId, which
|
|
55543
|
+
\`mode:"navigate"\` takes to list what is under it and \`mode:"content"\` takes
|
|
55544
|
+
to read it.
|
|
55545
|
+
|
|
55546
|
+
Handles Jira keys and URLs, Confluence, Drive, Slack permalinks, Linear,
|
|
55547
|
+
Notion, ServiceNow sys_id, SharePoint, Gmail/Outlook, and any connector
|
|
55548
|
+
whose records index a web URL. Resolution searches ALL connectors you can
|
|
55549
|
+
access, regardless of any source filter you used elsewhere.
|
|
55550
|
+
|
|
55551
|
+
A miss is a 200 with empty \`matches\` and the input echoed in
|
|
55552
|
+
\`not_found_identifiers\` — that may mean no-access, not non-existence. Use
|
|
55553
|
+
\`mode:"navigate"\` to confirm the record exists before telling the user it
|
|
55554
|
+
does not. If \`ambiguous\` is true, pick from \`matches\` rather than taking
|
|
55555
|
+
the first.
|
|
55556
|
+
|
|
55557
|
+
Navigate and lookup return a rendered text view whose closing \`Next:\` line
|
|
55558
|
+
names the exact follow-up call — follow it. When presenting a record, link
|
|
55559
|
+
it using the \`Web URL\` from its metadata header (when present).`
|
|
55560
|
+
},
|
|
54754
55561
|
{
|
|
54755
55562
|
name: "pipeshub_directory",
|
|
54756
55563
|
description: "Look up people, groups, and teams in PipesHub. One tool with five\nactions — pick the right `action`:\n\n- `whoami` — who is the caller? Use this whenever you need the\n authenticated user's own id, email, or full name (e.g. before\n `get_user` on themselves).\n- `list_users` — search / page through org users.\n- `get_user` — full `User` document for one user (requires `userId`).\n- `list_groups` — list user groups with `userCount`.\n- `list_my_teams` — teams the caller belongs to, with capability flags\n (`canEdit` / `canDelete` / `canManageMembers`).\n\nOutput shape varies by action; see each action's docs above."
|
|
@@ -58386,5 +59193,5 @@ export {
|
|
|
58386
59193
|
app
|
|
58387
59194
|
};
|
|
58388
59195
|
|
|
58389
|
-
//# debugId=
|
|
59196
|
+
//# debugId=90FD24D95D2C4D3664756E2164756E21
|
|
58390
59197
|
//# sourceMappingURL=mcp-server.js.map
|