thorbit-kb-mcp 0.2.7 → 0.2.9
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/dist/bin/thorbit-kb-mcp.cjs +709 -66
- package/dist/bin/thorbit-kb-mcp.cjs.map +1 -1
- package/dist/bin/thorbit-kb-mcp.js +714 -66
- package/dist/bin/thorbit-kb-mcp.js.map +1 -1
- package/dist/index.cjs +789 -102
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5049 -15
- package/dist/index.d.ts +5049 -15
- package/dist/index.js +781 -102
- package/dist/index.js.map +1 -1
- package/package.json +5 -1
package/dist/index.cjs
CHANGED
|
@@ -21,6 +21,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
// src/index.ts
|
|
22
22
|
var src_exports = {};
|
|
23
23
|
__export(src_exports, {
|
|
24
|
+
SERVER_INSTRUCTIONS: () => SERVER_INSTRUCTIONS,
|
|
24
25
|
ThorbitKbAskInputSchema: () => ThorbitKbAskInputSchema,
|
|
25
26
|
ThorbitKbCreateInputSchema: () => ThorbitKbCreateInputSchema,
|
|
26
27
|
ThorbitKbIngestSiteInputSchema: () => ThorbitKbIngestSiteInputSchema,
|
|
@@ -30,10 +31,22 @@ __export(src_exports, {
|
|
|
30
31
|
ThorbitKbListInputSchema: () => ThorbitKbListInputSchema,
|
|
31
32
|
ThorbitKbSearchInputSchema: () => ThorbitKbSearchInputSchema,
|
|
32
33
|
ThorbitKbSourceStatusInputSchema: () => ThorbitKbSourceStatusInputSchema,
|
|
34
|
+
ThorbitKnowledgeBaseAnswerResultSchema: () => ThorbitKnowledgeBaseAnswerResultSchema,
|
|
33
35
|
ThorbitKnowledgeBaseApiClient: () => ThorbitKnowledgeBaseApiClient,
|
|
36
|
+
ThorbitKnowledgeBaseCitationSchema: () => ThorbitKnowledgeBaseCitationSchema,
|
|
37
|
+
ThorbitKnowledgeBaseIngestResultSchema: () => ThorbitKnowledgeBaseIngestResultSchema,
|
|
38
|
+
ThorbitKnowledgeBaseListResultSchema: () => ThorbitKnowledgeBaseListResultSchema,
|
|
34
39
|
ThorbitKnowledgeBaseMcpToolInputSchemas: () => ThorbitKnowledgeBaseMcpToolInputSchemas,
|
|
35
40
|
ThorbitKnowledgeBaseMcpToolNames: () => ThorbitKnowledgeBaseMcpToolNames,
|
|
41
|
+
ThorbitKnowledgeBaseMcpToolOutputSchemas: () => ThorbitKnowledgeBaseMcpToolOutputSchemas,
|
|
42
|
+
ThorbitKnowledgeBaseMcpToolRegistrar: () => ThorbitKnowledgeBaseMcpToolRegistrar,
|
|
43
|
+
ThorbitKnowledgeBaseMcpToolResultSchemas: () => ThorbitKnowledgeBaseMcpToolResultSchemas,
|
|
44
|
+
ThorbitKnowledgeBaseMcpToolStrictOutputSchemas: () => ThorbitKnowledgeBaseMcpToolStrictOutputSchemas,
|
|
45
|
+
ThorbitKnowledgeBaseResultSchema: () => ThorbitKnowledgeBaseResultSchema,
|
|
46
|
+
ThorbitKnowledgeBaseSearchResultSchema: () => ThorbitKnowledgeBaseSearchResultSchema,
|
|
47
|
+
ThorbitKnowledgeBaseSourceStatusResultSchema: () => ThorbitKnowledgeBaseSourceStatusResultSchema,
|
|
36
48
|
buildThorbitKnowledgeBaseMcpServer: () => buildThorbitKnowledgeBaseMcpServer,
|
|
49
|
+
registerThorbitKnowledgeBaseMcpTools: () => registerThorbitKnowledgeBaseMcpTools,
|
|
37
50
|
resolveThorbitKbMcpEnv: () => resolveThorbitKbMcpEnv
|
|
38
51
|
});
|
|
39
52
|
module.exports = __toCommonJS(src_exports);
|
|
@@ -68,48 +81,42 @@ var ThorbitKnowledgeBaseApiClient = class {
|
|
|
68
81
|
}
|
|
69
82
|
};
|
|
70
83
|
|
|
71
|
-
// src/thorbit-kb-mcp-
|
|
72
|
-
var
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
function
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
84
|
+
// src/thorbit-kb-mcp-env.ts
|
|
85
|
+
var import_node_fs = require("fs");
|
|
86
|
+
var import_node_os = require("os");
|
|
87
|
+
var import_node_path = require("path");
|
|
88
|
+
function readApiKeyFile() {
|
|
89
|
+
const explicitPath = process.env.THORBIT_KB_MCP_KEY_PATH?.trim();
|
|
90
|
+
const paths = [explicitPath, (0, import_node_path.join)((0, import_node_os.homedir)(), ".thorbit-kb-mcp-key")].filter(Boolean);
|
|
91
|
+
for (const path of paths) {
|
|
92
|
+
try {
|
|
93
|
+
const value = (0, import_node_fs.readFileSync)(path, "utf8").trim();
|
|
94
|
+
if (value) return value;
|
|
95
|
+
} catch {
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
83
98
|
}
|
|
84
|
-
|
|
85
|
-
if (toolName === "thorbit_kb_source_status") return "Source status returned. Check structuredContent for details.";
|
|
86
|
-
if (toolName === "thorbit_kb_search") return "Knowledge-base search completed. Check structuredContent for results and citations.";
|
|
87
|
-
if (toolName === "thorbit_kb_ask") return "Knowledge-base answer generated. Check structuredContent for citations and strategy.";
|
|
88
|
-
return "Thorbit knowledge-base tool completed.";
|
|
99
|
+
return void 0;
|
|
89
100
|
}
|
|
90
|
-
function
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
content: [{
|
|
95
|
-
type: "text",
|
|
96
|
-
text: `${envelope.error.code}: ${envelope.error.message}`
|
|
97
|
-
}],
|
|
98
|
-
structuredContent: envelope
|
|
99
|
-
};
|
|
101
|
+
function resolveThorbitKbMcpEnv() {
|
|
102
|
+
const apiKey = (process.env.THORBIT_API_KEY || process.env.THORBIT_MCP_API_KEY || process.env.THORBIT_KB_MCP_API_KEY || readApiKeyFile())?.trim();
|
|
103
|
+
if (!apiKey) {
|
|
104
|
+
throw new Error("THORBIT_API_KEY, THORBIT_MCP_API_KEY, or ~/.thorbit-kb-mcp-key is required");
|
|
100
105
|
}
|
|
101
106
|
return {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
text: summarizeResult(toolName, envelope.result)
|
|
105
|
-
}],
|
|
106
|
-
structuredContent: envelope.result
|
|
107
|
+
apiKey,
|
|
108
|
+
baseUrl: (process.env.THORBIT_BASE_URL || process.env.THORBIT_KB_MCP_BASE_URL || "https://thorbit.ai").trim()
|
|
107
109
|
};
|
|
108
110
|
}
|
|
109
111
|
|
|
112
|
+
// src/thorbit-kb-mcp-server.ts
|
|
113
|
+
var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
114
|
+
var import_thorbit_mcp_core2 = require("thorbit-mcp-core");
|
|
115
|
+
|
|
110
116
|
// src/thorbit-kb-mcp-tool-schemas.ts
|
|
117
|
+
var import_thorbit_mcp_core = require("thorbit-mcp-core");
|
|
111
118
|
var import_zod = require("zod");
|
|
112
|
-
var MetadataSchema = import_zod.z.record(
|
|
119
|
+
var MetadataSchema = import_zod.z.record(import_thorbit_mcp_core.JsonValueSchema);
|
|
113
120
|
var ThorbitKbCreateInputSchema = {
|
|
114
121
|
name: import_zod.z.string().min(1).max(255).describe("Name for the new Thorbit knowledge base."),
|
|
115
122
|
description: import_zod.z.string().max(2e3).optional().describe("Optional description for the new knowledge base."),
|
|
@@ -184,16 +191,566 @@ var ThorbitKnowledgeBaseMcpToolInputSchemas = {
|
|
|
184
191
|
thorbit_kb_search: ThorbitKbSearchInputSchema,
|
|
185
192
|
thorbit_kb_ask: ThorbitKbAskInputSchema
|
|
186
193
|
};
|
|
194
|
+
var ThorbitKnowledgeBasePublicIdSchema = import_zod.z.string().min(1).max(128);
|
|
195
|
+
var ThorbitKnowledgeBaseStatusSchema = import_zod.z.string().min(1).max(64);
|
|
196
|
+
var ThorbitKnowledgeBaseSourceTypeSchema = import_zod.z.string().min(1).max(64);
|
|
197
|
+
var ThorbitKnowledgeBaseSourceStatusSchema = import_zod.z.enum([
|
|
198
|
+
"pending",
|
|
199
|
+
"processing",
|
|
200
|
+
"ready",
|
|
201
|
+
"failed"
|
|
202
|
+
]);
|
|
203
|
+
var ThorbitKnowledgeBaseResultSchema = import_zod.z.object({
|
|
204
|
+
knowledgeBasePublicId: ThorbitKnowledgeBasePublicIdSchema,
|
|
205
|
+
name: import_zod.z.string().min(1).max(255),
|
|
206
|
+
status: ThorbitKnowledgeBaseStatusSchema,
|
|
207
|
+
createdAt: import_zod.z.string().datetime(),
|
|
208
|
+
updatedAt: import_zod.z.string().datetime()
|
|
209
|
+
}).strict();
|
|
210
|
+
var ThorbitKnowledgeBaseListResultSchema = import_zod.z.object({
|
|
211
|
+
knowledgeBases: import_zod.z.array(ThorbitKnowledgeBaseResultSchema).max(100),
|
|
212
|
+
nextCursor: import_zod.z.string().min(1).max(512).nullable()
|
|
213
|
+
}).strict();
|
|
214
|
+
var ThorbitKnowledgeBaseSourceStatusResultSchema = import_zod.z.object({
|
|
215
|
+
knowledgeBasePublicId: ThorbitKnowledgeBasePublicIdSchema,
|
|
216
|
+
sourcePublicId: ThorbitKnowledgeBasePublicIdSchema,
|
|
217
|
+
sourceType: ThorbitKnowledgeBaseSourceTypeSchema,
|
|
218
|
+
status: ThorbitKnowledgeBaseSourceStatusSchema,
|
|
219
|
+
progressPercent: import_zod.z.number().finite().min(0).max(100),
|
|
220
|
+
error: import_zod.z.string().min(1).max(4e3).nullable(),
|
|
221
|
+
updatedAt: import_zod.z.string().datetime()
|
|
222
|
+
}).strict();
|
|
223
|
+
var ThorbitKnowledgeBaseSourceStatusPollInputSchema = import_zod.z.object({
|
|
224
|
+
sourcePublicIds: import_zod.z.array(ThorbitKnowledgeBasePublicIdSchema).min(1).max(100)
|
|
225
|
+
}).strict();
|
|
226
|
+
var ThorbitKnowledgeBaseIngestResultSchema = import_zod.z.object({
|
|
227
|
+
knowledgeBasePublicId: ThorbitKnowledgeBasePublicIdSchema,
|
|
228
|
+
sourcePublicId: ThorbitKnowledgeBasePublicIdSchema,
|
|
229
|
+
sourceType: ThorbitKnowledgeBaseSourceTypeSchema,
|
|
230
|
+
status: ThorbitKnowledgeBaseSourceStatusSchema,
|
|
231
|
+
pollToolName: import_zod.z.literal("thorbit_kb_source_status"),
|
|
232
|
+
pollInput: ThorbitKnowledgeBaseSourceStatusPollInputSchema
|
|
233
|
+
}).strict();
|
|
234
|
+
var ThorbitKnowledgeBaseCitationSchema = import_zod.z.object({
|
|
235
|
+
index: import_zod.z.number().int().positive().max(1e4),
|
|
236
|
+
chunkPublicId: ThorbitKnowledgeBasePublicIdSchema,
|
|
237
|
+
sourcePublicId: ThorbitKnowledgeBasePublicIdSchema.nullable(),
|
|
238
|
+
sourceTitle: import_zod.z.string().min(1).max(1e3),
|
|
239
|
+
sourceType: ThorbitKnowledgeBaseSourceTypeSchema,
|
|
240
|
+
sourceUrl: import_zod.z.string().url().max(2048).nullable(),
|
|
241
|
+
chunkIndex: import_zod.z.number().int().nonnegative().max(1e7).nullable(),
|
|
242
|
+
timestampStart: import_zod.z.number().finite().nonnegative().max(1e7).nullable(),
|
|
243
|
+
excerpt: import_zod.z.string().max(1e4)
|
|
244
|
+
}).strict();
|
|
245
|
+
var ThorbitKnowledgeBaseSearchMatchSchema = import_zod.z.object({
|
|
246
|
+
chunkPublicId: ThorbitKnowledgeBasePublicIdSchema,
|
|
247
|
+
text: import_zod.z.string().max(5e4),
|
|
248
|
+
score: import_zod.z.number().finite().min(0).max(1)
|
|
249
|
+
}).strict();
|
|
250
|
+
var ThorbitKnowledgeBaseSearchResultSchema = import_zod.z.object({
|
|
251
|
+
query: import_zod.z.string().min(1).max(4e3),
|
|
252
|
+
results: import_zod.z.array(ThorbitKnowledgeBaseSearchMatchSchema).max(50),
|
|
253
|
+
citations: import_zod.z.array(ThorbitKnowledgeBaseCitationSchema).max(50)
|
|
254
|
+
}).strict();
|
|
255
|
+
var ThorbitKnowledgeBaseAnswerResultSchema = import_zod.z.object({
|
|
256
|
+
answer: import_zod.z.string().max(5e5),
|
|
257
|
+
citations: import_zod.z.array(ThorbitKnowledgeBaseCitationSchema).max(50),
|
|
258
|
+
followUps: import_zod.z.array(import_zod.z.string().min(1).max(8e3)).max(20),
|
|
259
|
+
modelId: import_zod.z.string().min(1).max(255).nullable()
|
|
260
|
+
}).strict();
|
|
261
|
+
var ThorbitKnowledgeBaseMcpToolResultSchemas = {
|
|
262
|
+
thorbit_kb_create: ThorbitKnowledgeBaseResultSchema,
|
|
263
|
+
thorbit_kb_list: ThorbitKnowledgeBaseListResultSchema,
|
|
264
|
+
thorbit_kb_source_status: ThorbitKnowledgeBaseSourceStatusResultSchema,
|
|
265
|
+
thorbit_kb_ingest_url: ThorbitKnowledgeBaseIngestResultSchema,
|
|
266
|
+
thorbit_kb_ingest_site: ThorbitKnowledgeBaseIngestResultSchema,
|
|
267
|
+
thorbit_kb_ingest_youtube: ThorbitKnowledgeBaseIngestResultSchema,
|
|
268
|
+
thorbit_kb_ingest_text: ThorbitKnowledgeBaseIngestResultSchema,
|
|
269
|
+
thorbit_kb_search: ThorbitKnowledgeBaseSearchResultSchema,
|
|
270
|
+
thorbit_kb_ask: ThorbitKnowledgeBaseAnswerResultSchema
|
|
271
|
+
};
|
|
272
|
+
function createThorbitKnowledgeBaseMcpOutputContract(resultSchema) {
|
|
273
|
+
const strictSchema = (0, import_thorbit_mcp_core.createThorbitMcpStructuredResultSchema)(resultSchema);
|
|
274
|
+
const successShape = strictSchema.options[0].shape;
|
|
275
|
+
const errorShape = strictSchema.options[1].shape;
|
|
276
|
+
const advertisedSchema = import_zod.z.object({
|
|
277
|
+
ok: import_zod.z.boolean(),
|
|
278
|
+
toolName: successShape.toolName,
|
|
279
|
+
requestId: successShape.requestId,
|
|
280
|
+
summary: successShape.summary.optional(),
|
|
281
|
+
result: resultSchema.optional(),
|
|
282
|
+
artifacts: successShape.artifacts.optional(),
|
|
283
|
+
next: successShape.next,
|
|
284
|
+
warnings: successShape.warnings.optional(),
|
|
285
|
+
usage: successShape.usage.optional(),
|
|
286
|
+
error: errorShape.error.optional()
|
|
287
|
+
}).strict();
|
|
288
|
+
return { strictSchema, advertisedSchema };
|
|
289
|
+
}
|
|
290
|
+
var thorbitKnowledgeBaseOutputContracts = {
|
|
291
|
+
thorbit_kb_create: createThorbitKnowledgeBaseMcpOutputContract(ThorbitKnowledgeBaseResultSchema),
|
|
292
|
+
thorbit_kb_list: createThorbitKnowledgeBaseMcpOutputContract(ThorbitKnowledgeBaseListResultSchema),
|
|
293
|
+
thorbit_kb_source_status: createThorbitKnowledgeBaseMcpOutputContract(ThorbitKnowledgeBaseSourceStatusResultSchema),
|
|
294
|
+
thorbit_kb_ingest_url: createThorbitKnowledgeBaseMcpOutputContract(ThorbitKnowledgeBaseIngestResultSchema),
|
|
295
|
+
thorbit_kb_ingest_site: createThorbitKnowledgeBaseMcpOutputContract(ThorbitKnowledgeBaseIngestResultSchema),
|
|
296
|
+
thorbit_kb_ingest_youtube: createThorbitKnowledgeBaseMcpOutputContract(ThorbitKnowledgeBaseIngestResultSchema),
|
|
297
|
+
thorbit_kb_ingest_text: createThorbitKnowledgeBaseMcpOutputContract(ThorbitKnowledgeBaseIngestResultSchema),
|
|
298
|
+
thorbit_kb_search: createThorbitKnowledgeBaseMcpOutputContract(ThorbitKnowledgeBaseSearchResultSchema),
|
|
299
|
+
thorbit_kb_ask: createThorbitKnowledgeBaseMcpOutputContract(ThorbitKnowledgeBaseAnswerResultSchema)
|
|
300
|
+
};
|
|
301
|
+
var ThorbitKnowledgeBaseMcpToolStrictOutputSchemas = {
|
|
302
|
+
thorbit_kb_create: thorbitKnowledgeBaseOutputContracts.thorbit_kb_create.strictSchema,
|
|
303
|
+
thorbit_kb_list: thorbitKnowledgeBaseOutputContracts.thorbit_kb_list.strictSchema,
|
|
304
|
+
thorbit_kb_source_status: thorbitKnowledgeBaseOutputContracts.thorbit_kb_source_status.strictSchema,
|
|
305
|
+
thorbit_kb_ingest_url: thorbitKnowledgeBaseOutputContracts.thorbit_kb_ingest_url.strictSchema,
|
|
306
|
+
thorbit_kb_ingest_site: thorbitKnowledgeBaseOutputContracts.thorbit_kb_ingest_site.strictSchema,
|
|
307
|
+
thorbit_kb_ingest_youtube: thorbitKnowledgeBaseOutputContracts.thorbit_kb_ingest_youtube.strictSchema,
|
|
308
|
+
thorbit_kb_ingest_text: thorbitKnowledgeBaseOutputContracts.thorbit_kb_ingest_text.strictSchema,
|
|
309
|
+
thorbit_kb_search: thorbitKnowledgeBaseOutputContracts.thorbit_kb_search.strictSchema,
|
|
310
|
+
thorbit_kb_ask: thorbitKnowledgeBaseOutputContracts.thorbit_kb_ask.strictSchema
|
|
311
|
+
};
|
|
312
|
+
var ThorbitKnowledgeBaseMcpToolOutputSchemas = {
|
|
313
|
+
thorbit_kb_create: thorbitKnowledgeBaseOutputContracts.thorbit_kb_create.advertisedSchema,
|
|
314
|
+
thorbit_kb_list: thorbitKnowledgeBaseOutputContracts.thorbit_kb_list.advertisedSchema,
|
|
315
|
+
thorbit_kb_source_status: thorbitKnowledgeBaseOutputContracts.thorbit_kb_source_status.advertisedSchema,
|
|
316
|
+
thorbit_kb_ingest_url: thorbitKnowledgeBaseOutputContracts.thorbit_kb_ingest_url.advertisedSchema,
|
|
317
|
+
thorbit_kb_ingest_site: thorbitKnowledgeBaseOutputContracts.thorbit_kb_ingest_site.advertisedSchema,
|
|
318
|
+
thorbit_kb_ingest_youtube: thorbitKnowledgeBaseOutputContracts.thorbit_kb_ingest_youtube.advertisedSchema,
|
|
319
|
+
thorbit_kb_ingest_text: thorbitKnowledgeBaseOutputContracts.thorbit_kb_ingest_text.advertisedSchema,
|
|
320
|
+
thorbit_kb_search: thorbitKnowledgeBaseOutputContracts.thorbit_kb_search.advertisedSchema,
|
|
321
|
+
thorbit_kb_ask: thorbitKnowledgeBaseOutputContracts.thorbit_kb_ask.advertisedSchema
|
|
322
|
+
};
|
|
323
|
+
|
|
324
|
+
// src/thorbit-kb-mcp-response-formatters.ts
|
|
325
|
+
var PUBLIC_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
326
|
+
"unauthorized",
|
|
327
|
+
"forbidden",
|
|
328
|
+
"payment_required",
|
|
329
|
+
"not_found",
|
|
330
|
+
"validation_error",
|
|
331
|
+
"provider_error",
|
|
332
|
+
"rate_limited",
|
|
333
|
+
"conflict",
|
|
334
|
+
"internal_error"
|
|
335
|
+
]);
|
|
336
|
+
var SENSITIVE_DETAIL_KEY = /(?:authorization|cookie|credential|password|secret|token|api.?key|private.?key)/i;
|
|
337
|
+
var CREDENTIAL_TEXT = /(?:Bearer\s+[^\s,;]+|\b(?:sk|pk|key|token|thbt)[_-][A-Za-z0-9._-]{6,}\b|\bAIza[A-Za-z0-9_-]{20,}\b)/gi;
|
|
338
|
+
var SAFE_METADATA_IDENTIFIER = /^[A-Za-z0-9._/:-]+$/;
|
|
339
|
+
var CREDENTIAL_METADATA = /(?:\b(?:Bearer|Basic|Digest)\s+\S+|\b(?:authorization|api[\s_-]?key|token|secret)\s*[:=]|\b[a-z][a-z0-9+.-]*:\/\/[^/@\s]+@|\b(?:sk|pk|rk|key|token|thbt)[_-][A-Za-z0-9._-]{6,}\b|\bAIza[A-Za-z0-9_-]{20,}\b|\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{20,}\b|\bgithub_pat_[A-Za-z0-9_]{20,}\b|\bxox[baprs]-[A-Za-z0-9-]{10,}\b|\b(?:AKIA|ASIA)[A-Z0-9]{16}\b)/i;
|
|
340
|
+
var IDEMPOTENT_READ_TOOLS = /* @__PURE__ */ new Set([
|
|
341
|
+
"thorbit_kb_list",
|
|
342
|
+
"thorbit_kb_source_status",
|
|
343
|
+
"thorbit_kb_search"
|
|
344
|
+
]);
|
|
345
|
+
function asRecord(value) {
|
|
346
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
347
|
+
}
|
|
348
|
+
function safeText(value, fallback, maxLength = 4e3) {
|
|
349
|
+
if (typeof value !== "string" || value.trim().length === 0) return fallback;
|
|
350
|
+
return value.trim().slice(0, maxLength).replace(CREDENTIAL_TEXT, "[redacted]");
|
|
351
|
+
}
|
|
352
|
+
function safeDetails(value, depth = 0, active = /* @__PURE__ */ new WeakSet()) {
|
|
353
|
+
if (depth > 4) return "[detail depth omitted]";
|
|
354
|
+
if (typeof value === "string") return safeText(value, "[empty detail]");
|
|
355
|
+
if (typeof value === "number" || typeof value === "boolean" || value === null) return value;
|
|
356
|
+
if (Array.isArray(value)) return value.slice(0, 25).map((item) => safeDetails(item, depth + 1, active));
|
|
357
|
+
if (!value || typeof value !== "object") return void 0;
|
|
358
|
+
if (active.has(value)) return "[cyclic detail omitted]";
|
|
359
|
+
active.add(value);
|
|
360
|
+
try {
|
|
361
|
+
const output = {};
|
|
362
|
+
for (const [key, detail] of Object.entries(value).slice(0, 40)) {
|
|
363
|
+
output[key] = SENSITIVE_DETAIL_KEY.test(key) ? "[redacted]" : safeDetails(detail, depth + 1, active);
|
|
364
|
+
}
|
|
365
|
+
return output;
|
|
366
|
+
} catch {
|
|
367
|
+
return "[unavailable detail]";
|
|
368
|
+
} finally {
|
|
369
|
+
active.delete(value);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
function requiredString(record, key) {
|
|
373
|
+
const value = record[key];
|
|
374
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
375
|
+
throw new TypeError(`Knowledge Base result is missing ${key}`);
|
|
376
|
+
}
|
|
377
|
+
return value.trim();
|
|
378
|
+
}
|
|
379
|
+
function optionalString(record, key) {
|
|
380
|
+
const value = record[key];
|
|
381
|
+
return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
|
|
382
|
+
}
|
|
383
|
+
function safeMetadataIdentifier(value, maxLength = 255) {
|
|
384
|
+
if (typeof value !== "string") return null;
|
|
385
|
+
const candidate = value.trim();
|
|
386
|
+
if (candidate.length === 0 || candidate.length > maxLength || !SAFE_METADATA_IDENTIFIER.test(candidate) || CREDENTIAL_METADATA.test(candidate)) return null;
|
|
387
|
+
return candidate;
|
|
388
|
+
}
|
|
389
|
+
function requiredDateTime(record, key) {
|
|
390
|
+
const value = requiredString(record, key);
|
|
391
|
+
if (Number.isNaN(Date.parse(value))) {
|
|
392
|
+
throw new TypeError(`Knowledge Base result has an invalid ${key}`);
|
|
393
|
+
}
|
|
394
|
+
return value;
|
|
395
|
+
}
|
|
396
|
+
function requiredNumber(record, key) {
|
|
397
|
+
const value = record[key];
|
|
398
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
399
|
+
throw new TypeError(`Knowledge Base result is missing ${key}`);
|
|
400
|
+
}
|
|
401
|
+
return value;
|
|
402
|
+
}
|
|
403
|
+
function normalizeSourceStatus(value) {
|
|
404
|
+
switch (value) {
|
|
405
|
+
case "pending":
|
|
406
|
+
case "processing":
|
|
407
|
+
case "ready":
|
|
408
|
+
case "failed":
|
|
409
|
+
return value;
|
|
410
|
+
default:
|
|
411
|
+
throw new TypeError(`Unsupported Knowledge Base source status: ${String(value)}`);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
function normalizeKnowledgeBase(value) {
|
|
415
|
+
const record = asRecord(value);
|
|
416
|
+
if (!record) throw new TypeError("Knowledge Base record must be an object");
|
|
417
|
+
return {
|
|
418
|
+
knowledgeBasePublicId: optionalString(record, "knowledgeBasePublicId") ?? requiredString(record, "publicId"),
|
|
419
|
+
name: requiredString(record, "name"),
|
|
420
|
+
status: requiredString(record, "status"),
|
|
421
|
+
createdAt: requiredDateTime(record, "createdAt"),
|
|
422
|
+
updatedAt: requiredDateTime(record, "updatedAt")
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
function normalizeCitation(value) {
|
|
426
|
+
const citation = asRecord(value);
|
|
427
|
+
if (!citation) throw new TypeError("Knowledge Base citation must be an object");
|
|
428
|
+
const sourceUrl = optionalString(citation, "sourceUrl");
|
|
429
|
+
const rawChunkIndex = citation.chunkIndex;
|
|
430
|
+
const rawTimestampStart = citation.timestampStart;
|
|
431
|
+
return {
|
|
432
|
+
index: requiredNumber(citation, "index"),
|
|
433
|
+
chunkPublicId: requiredString(citation, "chunkPublicId"),
|
|
434
|
+
sourcePublicId: optionalString(citation, "sourcePublicId"),
|
|
435
|
+
sourceTitle: requiredString(citation, "sourceTitle"),
|
|
436
|
+
sourceType: requiredString(citation, "sourceType"),
|
|
437
|
+
sourceUrl,
|
|
438
|
+
chunkIndex: typeof rawChunkIndex === "number" && Number.isFinite(rawChunkIndex) ? rawChunkIndex : null,
|
|
439
|
+
timestampStart: typeof rawTimestampStart === "number" && Number.isFinite(rawTimestampStart) ? rawTimestampStart : null,
|
|
440
|
+
excerpt: typeof citation.excerpt === "string" ? citation.excerpt.slice(0, 1e4) : ""
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
function normalizeCitationList(value) {
|
|
444
|
+
if (!Array.isArray(value)) {
|
|
445
|
+
throw new TypeError("Knowledge Base result is missing citations");
|
|
446
|
+
}
|
|
447
|
+
return value.slice(0, 50).map(normalizeCitation);
|
|
448
|
+
}
|
|
449
|
+
function normalizeIngestReceipt(result) {
|
|
450
|
+
let receipt = result;
|
|
451
|
+
const wrappedReceipt = asRecord(result.receipt);
|
|
452
|
+
if (wrappedReceipt) {
|
|
453
|
+
receipt = wrappedReceipt;
|
|
454
|
+
} else if (Array.isArray(result.receipts)) {
|
|
455
|
+
if (result.receipts.length !== 1) {
|
|
456
|
+
throw new TypeError("The exact Knowledge Base ingest contract requires one provider source receipt");
|
|
457
|
+
}
|
|
458
|
+
const onlyReceipt = asRecord(result.receipts[0]);
|
|
459
|
+
if (!onlyReceipt) throw new TypeError("Knowledge Base ingest receipt must be an object");
|
|
460
|
+
receipt = onlyReceipt;
|
|
461
|
+
}
|
|
462
|
+
const sourcePublicId = requiredString(receipt, "sourcePublicId");
|
|
463
|
+
return {
|
|
464
|
+
knowledgeBasePublicId: requiredString(receipt, "knowledgeBasePublicId"),
|
|
465
|
+
sourcePublicId,
|
|
466
|
+
sourceType: requiredString(receipt, "sourceType"),
|
|
467
|
+
status: normalizeSourceStatus(receipt.status),
|
|
468
|
+
pollToolName: "thorbit_kb_source_status",
|
|
469
|
+
pollInput: { sourcePublicIds: [sourcePublicId] }
|
|
470
|
+
};
|
|
471
|
+
}
|
|
472
|
+
function normalizeSuccessResult(toolName, value, envelopeUsage) {
|
|
473
|
+
const result = asRecord(value);
|
|
474
|
+
if (!result) throw new TypeError("Knowledge Base result must be an object");
|
|
475
|
+
switch (toolName) {
|
|
476
|
+
case "thorbit_kb_create":
|
|
477
|
+
return normalizeKnowledgeBase(asRecord(result.knowledgeBase) ?? result);
|
|
478
|
+
case "thorbit_kb_list": {
|
|
479
|
+
if (!Array.isArray(result.knowledgeBases)) {
|
|
480
|
+
throw new TypeError("Knowledge Base list is missing knowledgeBases");
|
|
481
|
+
}
|
|
482
|
+
return {
|
|
483
|
+
knowledgeBases: result.knowledgeBases.slice(0, 100).map(normalizeKnowledgeBase),
|
|
484
|
+
nextCursor: optionalString(result, "nextCursor")
|
|
485
|
+
};
|
|
486
|
+
}
|
|
487
|
+
case "thorbit_kb_source_status": {
|
|
488
|
+
let source = result;
|
|
489
|
+
if (Array.isArray(result.sources)) {
|
|
490
|
+
if (result.sources.length !== 1) {
|
|
491
|
+
throw new TypeError("The exact Knowledge Base source-status contract requires one provider source");
|
|
492
|
+
}
|
|
493
|
+
const onlySource = asRecord(result.sources[0]);
|
|
494
|
+
if (!onlySource) throw new TypeError("Knowledge Base source status must be an object");
|
|
495
|
+
source = onlySource;
|
|
496
|
+
}
|
|
497
|
+
const rawError = optionalString(source, "error") ?? optionalString(source, "errorMessage");
|
|
498
|
+
return {
|
|
499
|
+
knowledgeBasePublicId: requiredString(source, "knowledgeBasePublicId"),
|
|
500
|
+
sourcePublicId: requiredString(source, "sourcePublicId"),
|
|
501
|
+
sourceType: requiredString(source, "sourceType"),
|
|
502
|
+
status: normalizeSourceStatus(source.status),
|
|
503
|
+
progressPercent: requiredNumber(source, "progressPercent"),
|
|
504
|
+
error: rawError ? rawError.slice(0, 4e3) : null,
|
|
505
|
+
updatedAt: requiredDateTime(source, "updatedAt")
|
|
506
|
+
};
|
|
507
|
+
}
|
|
508
|
+
case "thorbit_kb_ingest_url":
|
|
509
|
+
case "thorbit_kb_ingest_site":
|
|
510
|
+
case "thorbit_kb_ingest_youtube":
|
|
511
|
+
case "thorbit_kb_ingest_text":
|
|
512
|
+
return normalizeIngestReceipt(result);
|
|
513
|
+
case "thorbit_kb_search": {
|
|
514
|
+
if (!Array.isArray(result.results)) {
|
|
515
|
+
throw new TypeError("Knowledge Base search is missing results");
|
|
516
|
+
}
|
|
517
|
+
return {
|
|
518
|
+
query: requiredString(result, "query"),
|
|
519
|
+
results: result.results.slice(0, 50).map((value2) => {
|
|
520
|
+
const match = asRecord(value2);
|
|
521
|
+
if (!match) throw new TypeError("Knowledge Base search match must be an object");
|
|
522
|
+
const text = typeof match.text === "string" ? match.text : requiredString(match, "content");
|
|
523
|
+
return {
|
|
524
|
+
chunkPublicId: requiredString(match, "chunkPublicId"),
|
|
525
|
+
text: text.slice(0, 5e4),
|
|
526
|
+
score: requiredNumber(match, "score")
|
|
527
|
+
};
|
|
528
|
+
}),
|
|
529
|
+
citations: normalizeCitationList(result.citations)
|
|
530
|
+
};
|
|
531
|
+
}
|
|
532
|
+
case "thorbit_kb_ask": {
|
|
533
|
+
const sufficiency = asRecord(result.sufficiency);
|
|
534
|
+
const followUpValue = Array.isArray(result.followUps) ? result.followUps : sufficiency?.followUpSuggestions;
|
|
535
|
+
const followUps = Array.isArray(followUpValue) ? followUpValue.filter((item) => typeof item === "string" && item.trim().length > 0).map((item) => item.trim().slice(0, 8e3)).slice(0, 20) : [];
|
|
536
|
+
const usage = asRecord(envelopeUsage);
|
|
537
|
+
const explicitModelId = optionalString(result, "modelId");
|
|
538
|
+
return {
|
|
539
|
+
answer: requiredString(result, "answer").slice(0, 5e5),
|
|
540
|
+
citations: normalizeCitationList(result.citations),
|
|
541
|
+
followUps,
|
|
542
|
+
modelId: explicitModelId !== null ? safeMetadataIdentifier(explicitModelId) : safeMetadataIdentifier(usage?.modelId)
|
|
543
|
+
};
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
function normalizeUsage(value) {
|
|
548
|
+
const usage = asRecord(value);
|
|
549
|
+
if (!usage) return void 0;
|
|
550
|
+
const output = {};
|
|
551
|
+
for (const key of ["creditsConsumed", "estimatedUsd"]) {
|
|
552
|
+
const candidate = usage[key];
|
|
553
|
+
if (typeof candidate === "number" && Number.isFinite(candidate) && candidate >= 0) {
|
|
554
|
+
output[key] = candidate;
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
for (const key of ["inputTokens", "outputTokens"]) {
|
|
558
|
+
const candidate = usage[key];
|
|
559
|
+
if (typeof candidate === "number" && Number.isInteger(candidate) && candidate >= 0) {
|
|
560
|
+
output[key] = candidate;
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
for (const key of ["provider", "modelId"]) {
|
|
564
|
+
const candidate = safeMetadataIdentifier(usage[key]);
|
|
565
|
+
if (candidate !== null) output[key] = candidate;
|
|
566
|
+
}
|
|
567
|
+
return Object.keys(output).length > 0 ? output : void 0;
|
|
568
|
+
}
|
|
569
|
+
function successNextActions(toolName, result) {
|
|
570
|
+
const record = asRecord(result);
|
|
571
|
+
if (!record) return [];
|
|
572
|
+
if (toolName.startsWith("thorbit_kb_ingest_")) {
|
|
573
|
+
return [{
|
|
574
|
+
toolName: "thorbit_kb_source_status",
|
|
575
|
+
reason: "Check the real provider-backed source status after ingestion.",
|
|
576
|
+
input: record.pollInput
|
|
577
|
+
}];
|
|
578
|
+
}
|
|
579
|
+
if (toolName === "thorbit_kb_source_status") {
|
|
580
|
+
if (record.status === "pending" || record.status === "processing") {
|
|
581
|
+
return [{
|
|
582
|
+
toolName: "thorbit_kb_source_status",
|
|
583
|
+
reason: "Poll this source until it is ready or failed.",
|
|
584
|
+
input: { sourcePublicIds: [record.sourcePublicId] }
|
|
585
|
+
}];
|
|
586
|
+
}
|
|
587
|
+
if (record.status === "ready") {
|
|
588
|
+
return [
|
|
589
|
+
{
|
|
590
|
+
toolName: "thorbit_kb_search",
|
|
591
|
+
reason: "Retrieve bounded citation-ready chunks from the ready knowledge base.",
|
|
592
|
+
input: { knowledgeBasePublicId: record.knowledgeBasePublicId }
|
|
593
|
+
},
|
|
594
|
+
{
|
|
595
|
+
toolName: "thorbit_kb_ask",
|
|
596
|
+
reason: "Ask a grounded question against the ready knowledge base.",
|
|
597
|
+
input: { knowledgeBasePublicId: record.knowledgeBasePublicId }
|
|
598
|
+
}
|
|
599
|
+
];
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
if (toolName === "thorbit_kb_search") {
|
|
603
|
+
return [{
|
|
604
|
+
toolName: "thorbit_kb_ask",
|
|
605
|
+
reason: "Synthesize a grounded answer when the retrieved chunks are sufficient.",
|
|
606
|
+
input: { question: record.query }
|
|
607
|
+
}];
|
|
608
|
+
}
|
|
609
|
+
return [];
|
|
610
|
+
}
|
|
611
|
+
function normalizedErrorCode(code) {
|
|
612
|
+
if (PUBLIC_ERROR_CODES.has(code)) return code;
|
|
613
|
+
if (code === "ingestion_error" || code === "invalid_response" || code.startsWith("http_")) {
|
|
614
|
+
return "provider_error";
|
|
615
|
+
}
|
|
616
|
+
return "internal_error";
|
|
617
|
+
}
|
|
618
|
+
function errorRecovery(toolName, code) {
|
|
619
|
+
const transient = code === "provider_error" || code === "rate_limited" || code === "internal_error";
|
|
620
|
+
if (!transient || !IDEMPOTENT_READ_TOOLS.has(toolName)) {
|
|
621
|
+
return { retryable: false, next: [] };
|
|
622
|
+
}
|
|
623
|
+
return {
|
|
624
|
+
retryable: true,
|
|
625
|
+
next: [{
|
|
626
|
+
toolName,
|
|
627
|
+
reason: code === "rate_limited" ? "Retry this idempotent read after the rate limit resets." : "Retry this idempotent read after the transient service issue is resolved."
|
|
628
|
+
}]
|
|
629
|
+
};
|
|
630
|
+
}
|
|
631
|
+
function projectionErrorDetails(error) {
|
|
632
|
+
const issueRecord = asRecord(error);
|
|
633
|
+
const issues = Array.isArray(issueRecord?.issues) ? issueRecord.issues.slice(0, 25).map((issue) => {
|
|
634
|
+
const issueValue = asRecord(issue);
|
|
635
|
+
return {
|
|
636
|
+
path: Array.isArray(issueValue?.path) ? issueValue.path.map(String).join(".") : "",
|
|
637
|
+
code: typeof issueValue?.code === "string" ? issueValue.code : "invalid_result"
|
|
638
|
+
};
|
|
639
|
+
}) : [];
|
|
640
|
+
return {
|
|
641
|
+
reason: "Hosted result did not satisfy the exact public Knowledge Base result contract.",
|
|
642
|
+
...issues.length > 0 ? { schemaIssues: issues } : {}
|
|
643
|
+
};
|
|
644
|
+
}
|
|
645
|
+
function successSummary(toolName, result) {
|
|
646
|
+
const record = asRecord(result);
|
|
647
|
+
switch (toolName) {
|
|
648
|
+
case "thorbit_kb_create":
|
|
649
|
+
return `Created Thorbit knowledge base ${String(record?.name ?? "")}.`;
|
|
650
|
+
case "thorbit_kb_list":
|
|
651
|
+
return `Found ${Array.isArray(record?.knowledgeBases) ? record.knowledgeBases.length : 0} Thorbit knowledge bases.`;
|
|
652
|
+
case "thorbit_kb_source_status":
|
|
653
|
+
return `Knowledge Base source ${String(record?.sourcePublicId ?? "")} is ${String(record?.status ?? "unknown")}.`;
|
|
654
|
+
case "thorbit_kb_ingest_url":
|
|
655
|
+
case "thorbit_kb_ingest_site":
|
|
656
|
+
case "thorbit_kb_ingest_youtube":
|
|
657
|
+
case "thorbit_kb_ingest_text":
|
|
658
|
+
return `Knowledge Base source ${String(record?.sourcePublicId ?? "")} was accepted with status ${String(record?.status ?? "unknown")}.`;
|
|
659
|
+
case "thorbit_kb_search":
|
|
660
|
+
return `Retrieved ${Array.isArray(record?.results) ? record.results.length : 0} bounded Knowledge Base chunks with citations.`;
|
|
661
|
+
case "thorbit_kb_ask":
|
|
662
|
+
return `Generated a grounded Knowledge Base answer with ${Array.isArray(record?.citations) ? record.citations.length : 0} citations.`;
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
function formatThorbitKbMcpToolResult(toolName, envelope, _requestInput) {
|
|
666
|
+
const requestId = safeText(envelope.requestId, "unavailable", 256);
|
|
667
|
+
const outputSchema = ThorbitKnowledgeBaseMcpToolStrictOutputSchemas[toolName];
|
|
668
|
+
if (!envelope.ok) {
|
|
669
|
+
const code = normalizedErrorCode(envelope.error.code);
|
|
670
|
+
const message = safeText(envelope.error.message, "Knowledge Base operation failed.");
|
|
671
|
+
const recovery = errorRecovery(toolName, code);
|
|
672
|
+
const structuredContent = outputSchema.parse({
|
|
673
|
+
ok: false,
|
|
674
|
+
toolName,
|
|
675
|
+
requestId,
|
|
676
|
+
error: {
|
|
677
|
+
code,
|
|
678
|
+
message,
|
|
679
|
+
retryable: recovery.retryable,
|
|
680
|
+
...envelope.error.details !== void 0 ? { details: safeDetails(envelope.error.details) } : {}
|
|
681
|
+
},
|
|
682
|
+
next: recovery.next
|
|
683
|
+
});
|
|
684
|
+
return {
|
|
685
|
+
content: [{ type: "text", text: `${message} Request ID: ${requestId}.` }],
|
|
686
|
+
structuredContent,
|
|
687
|
+
isError: true
|
|
688
|
+
};
|
|
689
|
+
}
|
|
690
|
+
try {
|
|
691
|
+
const result = normalizeSuccessResult(toolName, envelope.result, envelope.usage);
|
|
692
|
+
const summary = successSummary(toolName, result);
|
|
693
|
+
const usage = normalizeUsage(envelope.usage);
|
|
694
|
+
const structuredContent = outputSchema.parse({
|
|
695
|
+
ok: true,
|
|
696
|
+
toolName,
|
|
697
|
+
requestId,
|
|
698
|
+
summary,
|
|
699
|
+
result,
|
|
700
|
+
artifacts: [],
|
|
701
|
+
next: successNextActions(toolName, result),
|
|
702
|
+
warnings: (envelope.warnings ?? []).map((warning) => safeText(warning, "Hosted warning")),
|
|
703
|
+
...usage ? { usage } : {}
|
|
704
|
+
});
|
|
705
|
+
return {
|
|
706
|
+
content: [{ type: "text", text: summary }],
|
|
707
|
+
structuredContent,
|
|
708
|
+
isError: false
|
|
709
|
+
};
|
|
710
|
+
} catch (error) {
|
|
711
|
+
const message = "Thorbit completed the Knowledge Base operation, but its hosted result could not be projected to the exact public contract.";
|
|
712
|
+
const structuredContent = outputSchema.parse({
|
|
713
|
+
ok: false,
|
|
714
|
+
toolName,
|
|
715
|
+
requestId,
|
|
716
|
+
error: {
|
|
717
|
+
code: "provider_error",
|
|
718
|
+
message,
|
|
719
|
+
retryable: false,
|
|
720
|
+
details: projectionErrorDetails(error)
|
|
721
|
+
},
|
|
722
|
+
next: []
|
|
723
|
+
});
|
|
724
|
+
return {
|
|
725
|
+
content: [{ type: "text", text: `${message} Request ID: ${requestId}.` }],
|
|
726
|
+
structuredContent,
|
|
727
|
+
isError: true
|
|
728
|
+
};
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
// src/thorbit-kb-mcp-tool-names.ts
|
|
733
|
+
var ThorbitKnowledgeBaseMcpToolNames = [
|
|
734
|
+
"thorbit_kb_create",
|
|
735
|
+
"thorbit_kb_list",
|
|
736
|
+
"thorbit_kb_source_status",
|
|
737
|
+
"thorbit_kb_ingest_url",
|
|
738
|
+
"thorbit_kb_ingest_site",
|
|
739
|
+
"thorbit_kb_ingest_youtube",
|
|
740
|
+
"thorbit_kb_ingest_text",
|
|
741
|
+
"thorbit_kb_search",
|
|
742
|
+
"thorbit_kb_ask"
|
|
743
|
+
];
|
|
187
744
|
|
|
188
745
|
// src/thorbit-kb-mcp-server.ts
|
|
189
|
-
var VERSION = "0.2.
|
|
190
|
-
function readOnlyAnnotations(title, idempotent = true) {
|
|
746
|
+
var VERSION = "0.2.9";
|
|
747
|
+
function readOnlyAnnotations(title, idempotent = true, openWorldHint = false) {
|
|
191
748
|
return {
|
|
192
749
|
title,
|
|
193
750
|
readOnlyHint: true,
|
|
194
751
|
destructiveHint: false,
|
|
195
752
|
idempotentHint: idempotent,
|
|
196
|
-
openWorldHint
|
|
753
|
+
openWorldHint
|
|
197
754
|
};
|
|
198
755
|
}
|
|
199
756
|
function ingestAnnotations(title, openWorldHint) {
|
|
@@ -205,9 +762,121 @@ function ingestAnnotations(title, openWorldHint) {
|
|
|
205
762
|
openWorldHint
|
|
206
763
|
};
|
|
207
764
|
}
|
|
208
|
-
function
|
|
209
|
-
|
|
210
|
-
|
|
765
|
+
function defineKnowledgeBaseQuality(quality) {
|
|
766
|
+
return import_thorbit_mcp_core2.ThorbitMcpToolQualityMetadataSchema.parse({ productId: "kb", ...quality });
|
|
767
|
+
}
|
|
768
|
+
var KNOWLEDGE_BASE_TOOL_QUALITY = {
|
|
769
|
+
thorbit_kb_create: defineKnowledgeBaseQuality({
|
|
770
|
+
requiredScopes: ["knowledge_base:ingest"],
|
|
771
|
+
whenToUse: ["Use to create a new caller-organization or project Knowledge Base."],
|
|
772
|
+
avoidWhen: ["Avoid when a suitable Knowledge Base already exists; list first."],
|
|
773
|
+
userPhrases: ["create a knowledge base", "make a RAG library", "start a KB"],
|
|
774
|
+
costSummary: "Low-cost durable Knowledge Base record creation.",
|
|
775
|
+
resultMode: "inline",
|
|
776
|
+
nextTools: ["thorbit_kb_ingest_url", "thorbit_kb_ingest_text"],
|
|
777
|
+
sideEffects: ["Creates a durable caller-organization Knowledge Base."]
|
|
778
|
+
}),
|
|
779
|
+
thorbit_kb_list: defineKnowledgeBaseQuality({
|
|
780
|
+
requiredScopes: ["knowledge_base:read"],
|
|
781
|
+
whenToUse: ["Use to find a visible Knowledge Base public ID before ingestion or retrieval."],
|
|
782
|
+
avoidWhen: ["Avoid when the exact Knowledge Base public ID is already known."],
|
|
783
|
+
userPhrases: ["list knowledge bases", "find my KB", "show RAG libraries"],
|
|
784
|
+
costSummary: "Low-cost caller-organization database read.",
|
|
785
|
+
resultMode: "paginated",
|
|
786
|
+
nextTools: ["thorbit_kb_search", "thorbit_kb_ask"],
|
|
787
|
+
sideEffects: []
|
|
788
|
+
}),
|
|
789
|
+
thorbit_kb_source_status: defineKnowledgeBaseQuality({
|
|
790
|
+
requiredScopes: ["knowledge_base:read"],
|
|
791
|
+
whenToUse: ["Use to poll one provider-backed source receipt returned by ingestion."],
|
|
792
|
+
avoidWhen: ["Avoid for retrieving chunks or synthesizing an answer."],
|
|
793
|
+
userPhrases: ["check ingest status", "is this source ready", "poll KB source"],
|
|
794
|
+
costSummary: "Low-cost caller-organization source status read.",
|
|
795
|
+
resultMode: "async",
|
|
796
|
+
nextTools: ["thorbit_kb_search", "thorbit_kb_ask"],
|
|
797
|
+
sideEffects: []
|
|
798
|
+
}),
|
|
799
|
+
thorbit_kb_ingest_url: defineKnowledgeBaseQuality({
|
|
800
|
+
requiredScopes: ["knowledge_base:ingest"],
|
|
801
|
+
whenToUse: ["Use to extract and ingest one public URL into a known Knowledge Base."],
|
|
802
|
+
avoidWhen: ["Avoid for whole websites, YouTube videos, or content already in hand."],
|
|
803
|
+
userPhrases: ["ingest this URL", "add this page to the KB", "vectorize this web page"],
|
|
804
|
+
costSummary: "External MCP Scraper extraction plus durable chunking and vectorization.",
|
|
805
|
+
resultMode: "async",
|
|
806
|
+
nextTools: ["thorbit_kb_source_status"],
|
|
807
|
+
sideEffects: ["Creates an append-only durable Knowledge Base source and chunks."]
|
|
808
|
+
}),
|
|
809
|
+
thorbit_kb_ingest_site: defineKnowledgeBaseQuality({
|
|
810
|
+
requiredScopes: ["knowledge_base:ingest"],
|
|
811
|
+
whenToUse: ["Use to map and ingest a bounded set of pages from one website."],
|
|
812
|
+
avoidWhen: ["Avoid for one known URL, which is cheaper through URL ingestion."],
|
|
813
|
+
userPhrases: ["ingest this website", "crawl pages into the KB", "build a KB from this site"],
|
|
814
|
+
costSummary: "Bounded MCP Scraper mapping and extraction plus durable vectorization per page.",
|
|
815
|
+
resultMode: "async",
|
|
816
|
+
nextTools: ["thorbit_kb_source_status"],
|
|
817
|
+
sideEffects: ["Creates append-only Knowledge Base sources and chunks for accepted pages."]
|
|
818
|
+
}),
|
|
819
|
+
thorbit_kb_ingest_youtube: defineKnowledgeBaseQuality({
|
|
820
|
+
requiredScopes: ["knowledge_base:ingest"],
|
|
821
|
+
whenToUse: ["Use to transcribe and ingest one YouTube video into a known Knowledge Base."],
|
|
822
|
+
avoidWhen: ["Avoid for web pages or caller-supplied text."],
|
|
823
|
+
userPhrases: ["ingest this YouTube video", "add this transcript to the KB", "vectorize this video"],
|
|
824
|
+
costSummary: "External transcription plus durable chunking and vectorization.",
|
|
825
|
+
resultMode: "async",
|
|
826
|
+
nextTools: ["thorbit_kb_source_status"],
|
|
827
|
+
sideEffects: ["Creates an append-only durable transcript source and chunks."]
|
|
828
|
+
}),
|
|
829
|
+
thorbit_kb_ingest_text: defineKnowledgeBaseQuality({
|
|
830
|
+
requiredScopes: ["knowledge_base:ingest"],
|
|
831
|
+
whenToUse: ["Use to ingest text or Markdown already supplied by the caller."],
|
|
832
|
+
avoidWhen: ["Avoid when Thorbit must fetch a URL, website, or YouTube transcript."],
|
|
833
|
+
userPhrases: ["ingest this text", "add these notes to the KB", "vectorize this Markdown"],
|
|
834
|
+
costSummary: "Durable chunking and vectorization without external scraping.",
|
|
835
|
+
resultMode: "async",
|
|
836
|
+
nextTools: ["thorbit_kb_source_status"],
|
|
837
|
+
sideEffects: ["Creates an append-only durable Knowledge Base source and chunks."]
|
|
838
|
+
}),
|
|
839
|
+
thorbit_kb_search: defineKnowledgeBaseQuality({
|
|
840
|
+
requiredScopes: ["knowledge_base:read"],
|
|
841
|
+
whenToUse: ["Use to retrieve bounded citation-ready chunks without answer synthesis."],
|
|
842
|
+
avoidWhen: ["Avoid when the caller wants a direct grounded answer."],
|
|
843
|
+
userPhrases: ["search the KB", "retrieve source chunks", "find citation evidence"],
|
|
844
|
+
costSummary: "Bounded vector or hybrid retrieval and optional reranking.",
|
|
845
|
+
resultMode: "inline",
|
|
846
|
+
nextTools: ["thorbit_kb_ask"],
|
|
847
|
+
sideEffects: []
|
|
848
|
+
}),
|
|
849
|
+
thorbit_kb_ask: defineKnowledgeBaseQuality({
|
|
850
|
+
requiredScopes: ["knowledge_base:read", "knowledge_base:ask"],
|
|
851
|
+
whenToUse: ["Use to synthesize a direct answer grounded in bounded Knowledge Base citations."],
|
|
852
|
+
avoidWhen: ["Avoid when raw retrieved passages are required for caller-side reasoning."],
|
|
853
|
+
userPhrases: ["ask the knowledge base", "answer from my KB", "give me a cited answer"],
|
|
854
|
+
costSummary: "Bounded retrieval plus potentially metered model answer generation.",
|
|
855
|
+
resultMode: "inline",
|
|
856
|
+
nextTools: ["thorbit_kb_search"],
|
|
857
|
+
sideEffects: []
|
|
858
|
+
})
|
|
859
|
+
};
|
|
860
|
+
var SERVER_INSTRUCTIONS = [
|
|
861
|
+
"Thorbit Knowledge Base MCP. Vector-backed knowledge bases for ingestion, smart RAG search, and grounded Q&A with citations. This server is a thin client, authenticated and metered against your Thorbit MCP API key.",
|
|
862
|
+
"",
|
|
863
|
+
"## Set up a knowledge base",
|
|
864
|
+
"- New knowledge base -> **thorbit_kb_create**. Org-level by default; pass projectPublicId to scope it to one project.",
|
|
865
|
+
"- Find an existing one's public ID -> **thorbit_kb_list** (needed before ingesting/searching if you don't already have it).",
|
|
866
|
+
"",
|
|
867
|
+
"## Ingest content",
|
|
868
|
+
"- One web page -> **thorbit_kb_ingest_url** (MCP Scraper extract, up to 500,000 chars before chunking).",
|
|
869
|
+
"- A whole site (mapped + filtered by include/excludePatterns) -> **thorbit_kb_ingest_site** (up to 100 pages, default 25).",
|
|
870
|
+
"- A YouTube video (transcribed, timestamps preserved by default) -> **thorbit_kb_ingest_youtube**.",
|
|
871
|
+
"- Raw text/Markdown you already have -> **thorbit_kb_ingest_text** (no scraping needed).",
|
|
872
|
+
"- All ingestion is append-only in this version \u2014 there's no refresh/re-ingest mode; re-ingesting a URL adds a new source version rather than replacing the old one.",
|
|
873
|
+
"- Check on an ingest's progress -> **thorbit_kb_source_status** with the sourcePublicIds it returned.",
|
|
874
|
+
"",
|
|
875
|
+
"## Query a knowledge base",
|
|
876
|
+
"- Need citation-ready chunks yourself, not a synthesized answer -> **thorbit_kb_search**.",
|
|
877
|
+
'- Need a direct answer grounded in retrieved context -> **thorbit_kb_ask** (set answerStyle:"extractive" for source excerpts without an LLM-written answer). Use thorbit_kb_search instead when you want the raw chunks to reason over yourself.'
|
|
878
|
+
].join("\n");
|
|
879
|
+
function registerThorbitKnowledgeBaseResources(server, callTool) {
|
|
211
880
|
server.registerResource(
|
|
212
881
|
"knowledge-bases",
|
|
213
882
|
"thorbit-kb://knowledge-bases",
|
|
@@ -231,115 +900,121 @@ function buildThorbitKnowledgeBaseMcpServer(options) {
|
|
|
231
900
|
},
|
|
232
901
|
async (uri, variables) => {
|
|
233
902
|
const sourcePublicId = Array.isArray(variables.sourcePublicId) ? variables.sourcePublicId[0] : variables.sourcePublicId;
|
|
234
|
-
const envelope = await callTool("thorbit_kb_source_status", {
|
|
903
|
+
const envelope = await callTool("thorbit_kb_source_status", {
|
|
904
|
+
sourcePublicIds: [String(sourcePublicId)]
|
|
905
|
+
});
|
|
235
906
|
return { contents: [{ uri: uri.href, mimeType: "application/json", text: JSON.stringify(envelope, null, 2) }] };
|
|
236
907
|
}
|
|
237
908
|
);
|
|
909
|
+
}
|
|
910
|
+
function registerThorbitKnowledgeBaseMcpTools(server, callTool) {
|
|
238
911
|
function registerTool(toolName, config) {
|
|
239
|
-
server.registerTool(toolName,
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
912
|
+
server.registerTool(toolName, {
|
|
913
|
+
title: config.title,
|
|
914
|
+
description: config.description,
|
|
915
|
+
inputSchema: config.inputSchema,
|
|
916
|
+
outputSchema: config.outputSchema,
|
|
917
|
+
annotations: config.annotations,
|
|
918
|
+
_meta: { thorbit: config.quality }
|
|
919
|
+
}, async (input) => formatThorbitKbMcpToolResult(
|
|
920
|
+
toolName,
|
|
921
|
+
await callTool(toolName, input),
|
|
922
|
+
input
|
|
923
|
+
));
|
|
243
924
|
}
|
|
244
925
|
registerTool("thorbit_kb_create", {
|
|
245
926
|
title: "Create Thorbit Knowledge Base",
|
|
246
|
-
description: "Create a new
|
|
927
|
+
description: "Create a new vector-backed knowledge base for ingestion, RAG search, and grounded Q&A. Org-level by default; pass projectPublicId to scope it to one project. Use thorbit_kb_list first if you're not sure whether a suitable knowledge base already exists.",
|
|
247
928
|
inputSchema: ThorbitKbCreateInputSchema,
|
|
248
|
-
|
|
929
|
+
outputSchema: ThorbitKnowledgeBaseMcpToolOutputSchemas.thorbit_kb_create,
|
|
930
|
+
annotations: ingestAnnotations("Create Thorbit Knowledge Base", false),
|
|
931
|
+
quality: KNOWLEDGE_BASE_TOOL_QUALITY.thorbit_kb_create
|
|
249
932
|
});
|
|
250
933
|
registerTool("thorbit_kb_list", {
|
|
251
934
|
title: "List Thorbit Knowledge Bases",
|
|
252
|
-
description: "List
|
|
935
|
+
description: "List knowledge bases visible to this API key, org-level and project-scoped. Use before ingestion/search when you don't already have the target knowledgeBasePublicId \u2014 every ingest tool needs one (search/ask can omit it to query all visible KBs instead).",
|
|
253
936
|
inputSchema: ThorbitKbListInputSchema,
|
|
254
|
-
|
|
937
|
+
outputSchema: ThorbitKnowledgeBaseMcpToolOutputSchemas.thorbit_kb_list,
|
|
938
|
+
annotations: readOnlyAnnotations("List Thorbit Knowledge Bases"),
|
|
939
|
+
quality: KNOWLEDGE_BASE_TOOL_QUALITY.thorbit_kb_list
|
|
255
940
|
});
|
|
256
941
|
registerTool("thorbit_kb_source_status", {
|
|
257
942
|
title: "Read Thorbit KB Source Status",
|
|
258
|
-
description: "Poll ingestion status for source public
|
|
943
|
+
description: "Poll ingestion status for a source public ID returned by a thorbit_kb_ingest_* tool. Returns the real source state, progress, safe error, and updated time; continue polling until ready or failed, then use thorbit_kb_search or thorbit_kb_ask.",
|
|
259
944
|
inputSchema: ThorbitKbSourceStatusInputSchema,
|
|
260
|
-
|
|
945
|
+
outputSchema: ThorbitKnowledgeBaseMcpToolOutputSchemas.thorbit_kb_source_status,
|
|
946
|
+
annotations: readOnlyAnnotations("Read Thorbit KB Source Status"),
|
|
947
|
+
quality: KNOWLEDGE_BASE_TOOL_QUALITY.thorbit_kb_source_status
|
|
261
948
|
});
|
|
262
949
|
registerTool("thorbit_kb_ingest_url", {
|
|
263
950
|
title: "Ingest URL Into Thorbit KB",
|
|
264
|
-
description: "Extract
|
|
951
|
+
description: "Extract ONE public URL through MCP Scraper, clean it, and vectorize it into a knowledge base (up to 500,000 chars before chunking). For a whole site instead of one page, use thorbit_kb_ingest_site. Append-only: re-ingesting adds a new source version. Returns a real source receipt and thorbit_kb_source_status follow-up.",
|
|
265
952
|
inputSchema: ThorbitKbIngestUrlInputSchema,
|
|
266
|
-
|
|
953
|
+
outputSchema: ThorbitKnowledgeBaseMcpToolOutputSchemas.thorbit_kb_ingest_url,
|
|
954
|
+
annotations: ingestAnnotations("Ingest URL Into Thorbit KB", true),
|
|
955
|
+
quality: KNOWLEDGE_BASE_TOOL_QUALITY.thorbit_kb_ingest_url
|
|
267
956
|
});
|
|
268
957
|
registerTool("thorbit_kb_ingest_site", {
|
|
269
958
|
title: "Ingest Website Into Thorbit KB",
|
|
270
|
-
description: "Map a website through MCP Scraper, extract selected pages
|
|
959
|
+
description: "Map a website through MCP Scraper, extract selected pages (up to 100, default 25), and vectorize them. For one known page, use thorbit_kb_ingest_url because it is cheaper and faster. The exact public receipt succeeds only when Phoenix supplies one unambiguous source; multi-source provider batches fail closed rather than hiding source IDs.",
|
|
271
960
|
inputSchema: ThorbitKbIngestSiteInputSchema,
|
|
272
|
-
|
|
961
|
+
outputSchema: ThorbitKnowledgeBaseMcpToolOutputSchemas.thorbit_kb_ingest_site,
|
|
962
|
+
annotations: ingestAnnotations("Ingest Website Into Thorbit KB", true),
|
|
963
|
+
quality: KNOWLEDGE_BASE_TOOL_QUALITY.thorbit_kb_ingest_site
|
|
273
964
|
});
|
|
274
965
|
registerTool("thorbit_kb_ingest_youtube", {
|
|
275
966
|
title: "Ingest YouTube Into Thorbit KB",
|
|
276
|
-
description: "Transcribe
|
|
967
|
+
description: "Transcribe one YouTube video through MCP Scraper and vectorize the transcript, preserving timestamp chunks by default. For web pages or raw text, use thorbit_kb_ingest_url or thorbit_kb_ingest_text. Returns the real source receipt and a thorbit_kb_source_status follow-up.",
|
|
277
968
|
inputSchema: ThorbitKbIngestYoutubeInputSchema,
|
|
278
|
-
|
|
969
|
+
outputSchema: ThorbitKnowledgeBaseMcpToolOutputSchemas.thorbit_kb_ingest_youtube,
|
|
970
|
+
annotations: ingestAnnotations("Ingest YouTube Into Thorbit KB", true),
|
|
971
|
+
quality: KNOWLEDGE_BASE_TOOL_QUALITY.thorbit_kb_ingest_youtube
|
|
279
972
|
});
|
|
280
973
|
registerTool("thorbit_kb_ingest_text", {
|
|
281
974
|
title: "Ingest Text Into Thorbit KB",
|
|
282
|
-
description: "Submit
|
|
975
|
+
description: "Submit bounded text or Markdown already in hand directly into a knowledge base with no scraping. Use thorbit_kb_ingest_url when content must be fetched. Returns the real source receipt and a thorbit_kb_source_status follow-up after durable chunking and vectorization.",
|
|
283
976
|
inputSchema: ThorbitKbIngestTextInputSchema,
|
|
284
|
-
|
|
977
|
+
outputSchema: ThorbitKnowledgeBaseMcpToolOutputSchemas.thorbit_kb_ingest_text,
|
|
978
|
+
annotations: ingestAnnotations("Ingest Text Into Thorbit KB", false),
|
|
979
|
+
quality: KNOWLEDGE_BASE_TOOL_QUALITY.thorbit_kb_ingest_text
|
|
285
980
|
});
|
|
286
981
|
registerTool("thorbit_kb_search", {
|
|
287
982
|
title: "Search Thorbit Knowledge Base",
|
|
288
|
-
description: "Search
|
|
983
|
+
description: "Search visible knowledge-base content and return at most 50 bounded, scored chunks plus bounded provider citations, without synthesizing an answer. Use thorbit_kb_ask for a direct grounded response. Omit knowledgeBasePublicId to search visible KBs.",
|
|
289
984
|
inputSchema: ThorbitKbSearchInputSchema,
|
|
290
|
-
|
|
985
|
+
outputSchema: ThorbitKnowledgeBaseMcpToolOutputSchemas.thorbit_kb_search,
|
|
986
|
+
annotations: readOnlyAnnotations("Search Thorbit Knowledge Base", true, true),
|
|
987
|
+
quality: KNOWLEDGE_BASE_TOOL_QUALITY.thorbit_kb_search
|
|
291
988
|
});
|
|
292
989
|
registerTool("thorbit_kb_ask", {
|
|
293
990
|
title: "Ask Thorbit Knowledge Base",
|
|
294
|
-
description: "Answer a question using only retrieved
|
|
991
|
+
description: "Answer a question using only retrieved Knowledge Base context and return a bounded answer, citations, follow-ups, and nullable real model ID. Use extractive style for excerpts; use thorbit_kb_search for raw scored chunks. This may invoke a metered answer model.",
|
|
295
992
|
inputSchema: ThorbitKbAskInputSchema,
|
|
296
|
-
|
|
993
|
+
outputSchema: ThorbitKnowledgeBaseMcpToolOutputSchemas.thorbit_kb_ask,
|
|
994
|
+
annotations: readOnlyAnnotations("Ask Thorbit Knowledge Base", false, true),
|
|
995
|
+
quality: KNOWLEDGE_BASE_TOOL_QUALITY.thorbit_kb_ask
|
|
297
996
|
});
|
|
298
|
-
return server;
|
|
299
997
|
}
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
function readApiKeyFile() {
|
|
306
|
-
const explicitPath = process.env.THORBIT_KB_MCP_KEY_PATH?.trim();
|
|
307
|
-
const paths = [explicitPath, (0, import_node_path.join)((0, import_node_os.homedir)(), ".thorbit-kb-mcp-key")].filter(Boolean);
|
|
308
|
-
for (const path of paths) {
|
|
309
|
-
try {
|
|
310
|
-
const value = (0, import_node_fs.readFileSync)(path, "utf8").trim();
|
|
311
|
-
if (value) return value;
|
|
312
|
-
} catch {
|
|
313
|
-
continue;
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
return void 0;
|
|
317
|
-
}
|
|
318
|
-
function resolveThorbitKbMcpEnv() {
|
|
319
|
-
const apiKey = (process.env.THORBIT_API_KEY || process.env.THORBIT_MCP_API_KEY || process.env.THORBIT_KB_MCP_API_KEY || readApiKeyFile())?.trim();
|
|
320
|
-
if (!apiKey) {
|
|
321
|
-
throw new Error("THORBIT_API_KEY, THORBIT_MCP_API_KEY, or ~/.thorbit-kb-mcp-key is required");
|
|
998
|
+
var ThorbitKnowledgeBaseMcpToolRegistrar = class {
|
|
999
|
+
productId = "kb";
|
|
1000
|
+
toolNames = ThorbitKnowledgeBaseMcpToolNames;
|
|
1001
|
+
registerTools(server, callTool) {
|
|
1002
|
+
registerThorbitKnowledgeBaseMcpTools(server, callTool);
|
|
322
1003
|
}
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
1004
|
+
};
|
|
1005
|
+
function buildThorbitKnowledgeBaseMcpServer(options) {
|
|
1006
|
+
const callTool = (toolName, input) => options.callTool(toolName, input);
|
|
1007
|
+
const server = new import_mcp.McpServer(
|
|
1008
|
+
{ name: "thorbit-kb-mcp", version: VERSION },
|
|
1009
|
+
{ instructions: SERVER_INSTRUCTIONS }
|
|
1010
|
+
);
|
|
1011
|
+
registerThorbitKnowledgeBaseResources(server, callTool);
|
|
1012
|
+
registerThorbitKnowledgeBaseMcpTools(server, callTool);
|
|
1013
|
+
return server;
|
|
327
1014
|
}
|
|
328
|
-
|
|
329
|
-
// src/thorbit-kb-mcp-tool-names.ts
|
|
330
|
-
var ThorbitKnowledgeBaseMcpToolNames = [
|
|
331
|
-
"thorbit_kb_create",
|
|
332
|
-
"thorbit_kb_list",
|
|
333
|
-
"thorbit_kb_source_status",
|
|
334
|
-
"thorbit_kb_ingest_url",
|
|
335
|
-
"thorbit_kb_ingest_site",
|
|
336
|
-
"thorbit_kb_ingest_youtube",
|
|
337
|
-
"thorbit_kb_ingest_text",
|
|
338
|
-
"thorbit_kb_search",
|
|
339
|
-
"thorbit_kb_ask"
|
|
340
|
-
];
|
|
341
1015
|
// Annotate the CommonJS export names for ESM import in node:
|
|
342
1016
|
0 && (module.exports = {
|
|
1017
|
+
SERVER_INSTRUCTIONS,
|
|
343
1018
|
ThorbitKbAskInputSchema,
|
|
344
1019
|
ThorbitKbCreateInputSchema,
|
|
345
1020
|
ThorbitKbIngestSiteInputSchema,
|
|
@@ -349,10 +1024,22 @@ var ThorbitKnowledgeBaseMcpToolNames = [
|
|
|
349
1024
|
ThorbitKbListInputSchema,
|
|
350
1025
|
ThorbitKbSearchInputSchema,
|
|
351
1026
|
ThorbitKbSourceStatusInputSchema,
|
|
1027
|
+
ThorbitKnowledgeBaseAnswerResultSchema,
|
|
352
1028
|
ThorbitKnowledgeBaseApiClient,
|
|
1029
|
+
ThorbitKnowledgeBaseCitationSchema,
|
|
1030
|
+
ThorbitKnowledgeBaseIngestResultSchema,
|
|
1031
|
+
ThorbitKnowledgeBaseListResultSchema,
|
|
353
1032
|
ThorbitKnowledgeBaseMcpToolInputSchemas,
|
|
354
1033
|
ThorbitKnowledgeBaseMcpToolNames,
|
|
1034
|
+
ThorbitKnowledgeBaseMcpToolOutputSchemas,
|
|
1035
|
+
ThorbitKnowledgeBaseMcpToolRegistrar,
|
|
1036
|
+
ThorbitKnowledgeBaseMcpToolResultSchemas,
|
|
1037
|
+
ThorbitKnowledgeBaseMcpToolStrictOutputSchemas,
|
|
1038
|
+
ThorbitKnowledgeBaseResultSchema,
|
|
1039
|
+
ThorbitKnowledgeBaseSearchResultSchema,
|
|
1040
|
+
ThorbitKnowledgeBaseSourceStatusResultSchema,
|
|
355
1041
|
buildThorbitKnowledgeBaseMcpServer,
|
|
1042
|
+
registerThorbitKnowledgeBaseMcpTools,
|
|
356
1043
|
resolveThorbitKbMcpEnv
|
|
357
1044
|
});
|
|
358
1045
|
//# sourceMappingURL=index.cjs.map
|