thorbit-kb-mcp 0.2.7 → 0.2.8

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.
@@ -169,7 +169,7 @@ var ThorbitKbAskInputSchema = {
169
169
  };
170
170
 
171
171
  // src/thorbit-kb-mcp-server.ts
172
- var VERSION = "0.2.7";
172
+ var VERSION = "0.2.8";
173
173
  function readOnlyAnnotations(title, idempotent = true) {
174
174
  return {
175
175
  title,
@@ -188,9 +188,28 @@ function ingestAnnotations(title, openWorldHint) {
188
188
  openWorldHint
189
189
  };
190
190
  }
191
+ var SERVER_INSTRUCTIONS = [
192
+ "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.",
193
+ "",
194
+ "## Set up a knowledge base",
195
+ "- New knowledge base -> **thorbit_kb_create**. Org-level by default; pass projectPublicId to scope it to one project.",
196
+ "- Find an existing one's public ID -> **thorbit_kb_list** (needed before ingesting/searching if you don't already have it).",
197
+ "",
198
+ "## Ingest content",
199
+ "- One web page -> **thorbit_kb_ingest_url** (MCP Scraper extract, up to 500,000 chars before chunking).",
200
+ "- A whole site (mapped + filtered by include/excludePatterns) -> **thorbit_kb_ingest_site** (up to 100 pages, default 25).",
201
+ "- A YouTube video (transcribed, timestamps preserved by default) -> **thorbit_kb_ingest_youtube**.",
202
+ "- Raw text/Markdown you already have -> **thorbit_kb_ingest_text** (no scraping needed).",
203
+ "- 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.",
204
+ "- Check on an ingest's progress -> **thorbit_kb_source_status** with the sourcePublicIds it returned.",
205
+ "",
206
+ "## Query a knowledge base",
207
+ "- Need citation-ready chunks yourself, not a synthesized answer -> **thorbit_kb_search**.",
208
+ '- 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.'
209
+ ].join("\n");
191
210
  function buildThorbitKnowledgeBaseMcpServer(options) {
192
211
  const callTool = (toolName, input) => options.callTool(toolName, input);
193
- const server = new import_mcp.McpServer({ name: "thorbit-kb-mcp", version: VERSION });
212
+ const server = new import_mcp.McpServer({ name: "thorbit-kb-mcp", version: VERSION }, { instructions: SERVER_INSTRUCTIONS });
194
213
  server.registerResource(
195
214
  "knowledge-bases",
196
215
  "thorbit-kb://knowledge-bases",
@@ -226,55 +245,55 @@ function buildThorbitKnowledgeBaseMcpServer(options) {
226
245
  }
227
246
  registerTool("thorbit_kb_create", {
228
247
  title: "Create Thorbit Knowledge Base",
229
- description: "Create a new Thorbit vector-backed knowledge base for MCP ingestion, smart RAG search, citations, and entity extraction.",
248
+ 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.",
230
249
  inputSchema: ThorbitKbCreateInputSchema,
231
250
  annotations: ingestAnnotations("Create Thorbit Knowledge Base", false)
232
251
  });
233
252
  registerTool("thorbit_kb_list", {
234
253
  title: "List Thorbit Knowledge Bases",
235
- description: "List Thorbit knowledge bases visible to this API key. Use before ingestion/search when the target KB public ID is unknown.",
254
+ 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).",
236
255
  inputSchema: ThorbitKbListInputSchema,
237
256
  annotations: readOnlyAnnotations("List Thorbit Knowledge Bases")
238
257
  });
239
258
  registerTool("thorbit_kb_source_status", {
240
259
  title: "Read Thorbit KB Source Status",
241
- description: "Poll ingestion status for source public IDs returned by Thorbit KB ingestion tools.",
260
+ description: "Poll ingestion status for source public IDs returned by any thorbit_kb_ingest_* tool \u2014 the only way to check whether an ingest finished, since the ingest tools may return before vectorization completes.",
242
261
  inputSchema: ThorbitKbSourceStatusInputSchema,
243
262
  annotations: readOnlyAnnotations("Read Thorbit KB Source Status")
244
263
  });
245
264
  registerTool("thorbit_kb_ingest_url", {
246
265
  title: "Ingest URL Into Thorbit KB",
247
- description: "Extract one public URL through MCP Scraper, clean the content, submit it to Thorbit, and vectorize it into the selected knowledge base.",
266
+ 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 the same URL adds a new source version rather than replacing the prior one \u2014 there is no refresh mode in this version.",
248
267
  inputSchema: ThorbitKbIngestUrlInputSchema,
249
268
  annotations: ingestAnnotations("Ingest URL Into Thorbit KB", true)
250
269
  });
251
270
  registerTool("thorbit_kb_ingest_site", {
252
271
  title: "Ingest Website Into Thorbit KB",
253
- description: "Map a website through MCP Scraper, extract selected pages, submit each page to Thorbit, and vectorize them into the selected knowledge base.",
272
+ description: "Map a website through MCP Scraper, extract selected pages (up to 100, default 25, filterable via includePatterns/excludePatterns), and vectorize each into a knowledge base. For a single known page instead of crawling a site, use thorbit_kb_ingest_url \u2014 cheaper and faster. Append-only, same as thorbit_kb_ingest_url.",
254
273
  inputSchema: ThorbitKbIngestSiteInputSchema,
255
274
  annotations: ingestAnnotations("Ingest Website Into Thorbit KB", true)
256
275
  });
257
276
  registerTool("thorbit_kb_ingest_youtube", {
258
277
  title: "Ingest YouTube Into Thorbit KB",
259
- description: "Transcribe a YouTube video through MCP Scraper, preserve timestamp chunks when available, and vectorize the transcript into Thorbit KB.",
278
+ description: "Transcribe a YouTube video through MCP Scraper and vectorize the transcript (timestamp chunks preserved by default) into a knowledge base. For web pages or raw text instead of video, use thorbit_kb_ingest_url or thorbit_kb_ingest_text.",
260
279
  inputSchema: ThorbitKbIngestYoutubeInputSchema,
261
280
  annotations: ingestAnnotations("Ingest YouTube Into Thorbit KB", true)
262
281
  });
263
282
  registerTool("thorbit_kb_ingest_text", {
264
283
  title: "Ingest Text Into Thorbit KB",
265
- description: "Submit provided text or Markdown directly to Thorbit and vectorize it into the selected knowledge base.",
284
+ description: "Submit text or Markdown you already have directly into a knowledge base \u2014 no scraping involved. Use this instead of thorbit_kb_ingest_url when you already have the content in hand rather than a URL to fetch.",
266
285
  inputSchema: ThorbitKbIngestTextInputSchema,
267
286
  annotations: ingestAnnotations("Ingest Text Into Thorbit KB", false)
268
287
  });
269
288
  registerTool("thorbit_kb_search", {
270
289
  title: "Search Thorbit Knowledge Base",
271
- description: "Search Thorbit KB content with citation-ready chunks. Use when the user needs source-backed snippets or evidence.",
290
+ description: "Search knowledge-base content and get citation-ready chunks back directly, without a synthesized answer. Use this instead of thorbit_kb_ask when you want to reason over the raw retrieved passages yourself. Omit knowledgeBasePublicId to search all KBs visible to this key.",
272
291
  inputSchema: ThorbitKbSearchInputSchema,
273
292
  annotations: readOnlyAnnotations("Search Thorbit Knowledge Base")
274
293
  });
275
294
  registerTool("thorbit_kb_ask", {
276
295
  title: "Ask Thorbit Knowledge Base",
277
- description: "Answer a question using only retrieved Thorbit KB context. Returns answer, citations, sufficiency, and retrieval strategy metadata.",
296
+ description: 'Answer a question using ONLY retrieved knowledge-base context \u2014 returns the answer, citations, sufficiency, and retrieval metadata. Set answerStyle:"extractive" for source excerpts without an LLM-written answer. Use thorbit_kb_search instead when you want the raw chunks rather than a synthesized answer.',
278
297
  inputSchema: ThorbitKbAskInputSchema,
279
298
  annotations: readOnlyAnnotations("Ask Thorbit Knowledge Base", false)
280
299
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../bin/thorbit-kb-mcp.ts","../../src/thorbit-kb-api-client.ts","../../src/thorbit-kb-mcp-env.ts","../../src/thorbit-kb-mcp-server.ts","../../src/thorbit-kb-mcp-response-formatters.ts","../../src/thorbit-kb-mcp-tool-schemas.ts"],"sourcesContent":["import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { ThorbitKnowledgeBaseApiClient } from '../src/thorbit-kb-api-client.js'\nimport { resolveThorbitKbMcpEnv } from '../src/thorbit-kb-mcp-env.js'\nimport { buildThorbitKnowledgeBaseMcpServer } from '../src/thorbit-kb-mcp-server.js'\n\nasync function main() {\n const env = resolveThorbitKbMcpEnv()\n const client = new ThorbitKnowledgeBaseApiClient(env)\n const server = buildThorbitKnowledgeBaseMcpServer(client)\n await server.connect(new StdioServerTransport())\n}\n\nmain().catch(error => {\n process.stderr.write(`${error instanceof Error ? error.message : String(error)}\\n`)\n process.exit(1)\n})\n","import type { ThorbitKnowledgeBaseMcpToolName } from './thorbit-kb-mcp-tool-names.js'\n\nexport type ThorbitKnowledgeBaseMcpEnvelope =\n | {\n ok: true\n result: unknown\n warnings?: string[]\n requestId: string\n usage?: Record<string, unknown>\n }\n | {\n ok: false\n error: {\n code: string\n message: string\n details?: unknown\n }\n requestId: string\n }\n\nexport class ThorbitKnowledgeBaseApiClient {\n private readonly baseUrl: string\n private readonly apiKey: string\n\n constructor(options: { baseUrl: string; apiKey: string }) {\n this.baseUrl = options.baseUrl.replace(/\\/$/, '')\n this.apiKey = options.apiKey\n }\n\n async callTool(toolName: ThorbitKnowledgeBaseMcpToolName, input: unknown): Promise<ThorbitKnowledgeBaseMcpEnvelope> {\n const response = await fetch(`${this.baseUrl}/api/v1/mcp/knowledge-base/${toolName}`, {\n method: 'POST',\n headers: {\n 'x-thorbit-api-key': this.apiKey,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(input ?? {}),\n })\n\n const body = await response.json().catch(() => null) as ThorbitKnowledgeBaseMcpEnvelope | null\n if (body && typeof body === 'object' && 'ok' in body) return body\n\n return {\n ok: false,\n requestId: 'unavailable',\n error: {\n code: response.ok ? 'invalid_response' : `http_${response.status}`,\n message: response.ok ? 'Thorbit returned an invalid MCP response' : `Thorbit API request failed with HTTP ${response.status}`,\n },\n }\n }\n}\n","import { readFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\n\nexport type ThorbitKbMcpEnv = {\n apiKey: string\n baseUrl: string\n}\n\nfunction readApiKeyFile(): string | undefined {\n const explicitPath = process.env.THORBIT_KB_MCP_KEY_PATH?.trim()\n const paths = [explicitPath, join(homedir(), '.thorbit-kb-mcp-key')].filter(Boolean) as string[]\n for (const path of paths) {\n try {\n const value = readFileSync(path, 'utf8').trim()\n if (value) return value\n } catch {\n continue\n }\n }\n return undefined\n}\n\nexport function resolveThorbitKbMcpEnv(): ThorbitKbMcpEnv {\n const apiKey = (\n process.env.THORBIT_API_KEY ||\n process.env.THORBIT_MCP_API_KEY ||\n process.env.THORBIT_KB_MCP_API_KEY ||\n readApiKeyFile()\n )?.trim()\n\n if (!apiKey) {\n throw new Error('THORBIT_API_KEY, THORBIT_MCP_API_KEY, or ~/.thorbit-kb-mcp-key is required')\n }\n\n return {\n apiKey,\n baseUrl: (process.env.THORBIT_BASE_URL || process.env.THORBIT_KB_MCP_BASE_URL || 'https://thorbit.ai').trim(),\n }\n}\n","import { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { ToolAnnotations } from '@modelcontextprotocol/sdk/types.js'\nimport type { ZodRawShape } from 'zod'\nimport type { ThorbitKnowledgeBaseApiClient, ThorbitKnowledgeBaseMcpEnvelope } from './thorbit-kb-api-client.js'\nimport { formatThorbitKbMcpToolResult } from './thorbit-kb-mcp-response-formatters.js'\nimport {\n ThorbitKbAskInputSchema,\n ThorbitKbCreateInputSchema,\n ThorbitKbIngestSiteInputSchema,\n ThorbitKbIngestTextInputSchema,\n ThorbitKbIngestUrlInputSchema,\n ThorbitKbIngestYoutubeInputSchema,\n ThorbitKbListInputSchema,\n ThorbitKbSearchInputSchema,\n ThorbitKbSourceStatusInputSchema,\n} from './thorbit-kb-mcp-tool-schemas.js'\nimport type { ThorbitKnowledgeBaseMcpToolName } from './thorbit-kb-mcp-tool-names.js'\n\nconst VERSION = '0.2.7'\n\ntype ThorbitKbToolConfig<InputArgs extends ZodRawShape> = {\n title: string\n description: string\n inputSchema: InputArgs\n annotations: ToolAnnotations\n}\n\nfunction readOnlyAnnotations(title: string, idempotent = true) {\n return {\n title,\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: idempotent,\n openWorldHint: false,\n }\n}\n\nfunction ingestAnnotations(title: string, openWorldHint: boolean) {\n return {\n title,\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint,\n }\n}\n\nexport type ThorbitKbCallTool = (\n toolName: ThorbitKnowledgeBaseMcpToolName,\n input: unknown,\n) => Promise<ThorbitKnowledgeBaseMcpEnvelope>\n\nexport type BuildThorbitKnowledgeBaseMcpServerOptions =\n | ThorbitKnowledgeBaseApiClient\n | { callTool: ThorbitKbCallTool }\n\nexport function buildThorbitKnowledgeBaseMcpServer(options: BuildThorbitKnowledgeBaseMcpServerOptions): McpServer {\n const callTool: ThorbitKbCallTool = (toolName, input) => options.callTool(toolName, input)\n const server = new McpServer({ name: 'thorbit-kb-mcp', version: VERSION })\n\n server.registerResource(\n 'knowledge-bases',\n 'thorbit-kb://knowledge-bases',\n {\n title: 'Thorbit Knowledge Bases',\n description: 'Knowledge bases visible to this Thorbit MCP API key.',\n mimeType: 'application/json',\n },\n async (uri) => {\n const envelope = await callTool('thorbit_kb_list', {})\n return { contents: [{ uri: uri.href, mimeType: 'application/json', text: JSON.stringify(envelope, null, 2) }] }\n },\n )\n\n server.registerResource(\n 'source-status',\n new ResourceTemplate('thorbit-kb://sources/{sourcePublicId}', { list: undefined }),\n {\n title: 'Thorbit KB Source Status',\n description: 'Status and metadata for one Thorbit knowledge-base source.',\n mimeType: 'application/json',\n },\n async (uri, variables) => {\n const sourcePublicId = Array.isArray(variables.sourcePublicId) ? variables.sourcePublicId[0] : variables.sourcePublicId\n const envelope = await callTool('thorbit_kb_source_status', { sourcePublicIds: [String(sourcePublicId)] })\n return { contents: [{ uri: uri.href, mimeType: 'application/json', text: JSON.stringify(envelope, null, 2) }] }\n },\n )\n\n function registerTool<T extends ThorbitKnowledgeBaseMcpToolName>(\n toolName: T,\n config: ThorbitKbToolConfig<ZodRawShape>,\n ): void {\n server.registerTool(toolName, config, async (input) => {\n const envelope = await callTool(toolName, input)\n return formatThorbitKbMcpToolResult(toolName, envelope)\n })\n }\n\n registerTool('thorbit_kb_create', {\n title: 'Create Thorbit Knowledge Base',\n description: 'Create a new Thorbit vector-backed knowledge base for MCP ingestion, smart RAG search, citations, and entity extraction.',\n inputSchema: ThorbitKbCreateInputSchema,\n annotations: ingestAnnotations('Create Thorbit Knowledge Base', false),\n })\n\n registerTool('thorbit_kb_list', {\n title: 'List Thorbit Knowledge Bases',\n description: 'List Thorbit knowledge bases visible to this API key. Use before ingestion/search when the target KB public ID is unknown.',\n inputSchema: ThorbitKbListInputSchema,\n annotations: readOnlyAnnotations('List Thorbit Knowledge Bases'),\n })\n\n registerTool('thorbit_kb_source_status', {\n title: 'Read Thorbit KB Source Status',\n description: 'Poll ingestion status for source public IDs returned by Thorbit KB ingestion tools.',\n inputSchema: ThorbitKbSourceStatusInputSchema,\n annotations: readOnlyAnnotations('Read Thorbit KB Source Status'),\n })\n\n registerTool('thorbit_kb_ingest_url', {\n title: 'Ingest URL Into Thorbit KB',\n description: 'Extract one public URL through MCP Scraper, clean the content, submit it to Thorbit, and vectorize it into the selected knowledge base.',\n inputSchema: ThorbitKbIngestUrlInputSchema,\n annotations: ingestAnnotations('Ingest URL Into Thorbit KB', true),\n })\n\n registerTool('thorbit_kb_ingest_site', {\n title: 'Ingest Website Into Thorbit KB',\n description: 'Map a website through MCP Scraper, extract selected pages, submit each page to Thorbit, and vectorize them into the selected knowledge base.',\n inputSchema: ThorbitKbIngestSiteInputSchema,\n annotations: ingestAnnotations('Ingest Website Into Thorbit KB', true),\n })\n\n registerTool('thorbit_kb_ingest_youtube', {\n title: 'Ingest YouTube Into Thorbit KB',\n description: 'Transcribe a YouTube video through MCP Scraper, preserve timestamp chunks when available, and vectorize the transcript into Thorbit KB.',\n inputSchema: ThorbitKbIngestYoutubeInputSchema,\n annotations: ingestAnnotations('Ingest YouTube Into Thorbit KB', true),\n })\n\n registerTool('thorbit_kb_ingest_text', {\n title: 'Ingest Text Into Thorbit KB',\n description: 'Submit provided text or Markdown directly to Thorbit and vectorize it into the selected knowledge base.',\n inputSchema: ThorbitKbIngestTextInputSchema,\n annotations: ingestAnnotations('Ingest Text Into Thorbit KB', false),\n })\n\n registerTool('thorbit_kb_search', {\n title: 'Search Thorbit Knowledge Base',\n description: 'Search Thorbit KB content with citation-ready chunks. Use when the user needs source-backed snippets or evidence.',\n inputSchema: ThorbitKbSearchInputSchema,\n annotations: readOnlyAnnotations('Search Thorbit Knowledge Base'),\n })\n\n registerTool('thorbit_kb_ask', {\n title: 'Ask Thorbit Knowledge Base',\n description: 'Answer a question using only retrieved Thorbit KB context. Returns answer, citations, sufficiency, and retrieval strategy metadata.',\n inputSchema: ThorbitKbAskInputSchema,\n annotations: readOnlyAnnotations('Ask Thorbit Knowledge Base', false),\n })\n\n return server\n}\n","import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js'\nimport type { ThorbitKnowledgeBaseMcpEnvelope } from './thorbit-kb-api-client.js'\nimport type { ThorbitKnowledgeBaseMcpToolName } from './thorbit-kb-mcp-tool-names.js'\n\nfunction summarizeResult(toolName: ThorbitKnowledgeBaseMcpToolName, result: unknown): string {\n if (toolName === 'thorbit_kb_create' && result && typeof result === 'object' && 'knowledgeBase' in result) {\n const kb = result.knowledgeBase as { name?: unknown; publicId?: unknown }\n return `Created Thorbit knowledge base ${String(kb.name ?? kb.publicId ?? '')}.`\n }\n if (toolName === 'thorbit_kb_list' && result && typeof result === 'object' && 'knowledgeBases' in result) {\n const count = Array.isArray(result.knowledgeBases) ? result.knowledgeBases.length : 0\n return `Found ${count} Thorbit knowledge base${count === 1 ? '' : 's'}.`\n }\n if (toolName.startsWith('thorbit_kb_ingest')) return 'Knowledge-base ingestion completed. Check structuredContent for source receipts.'\n if (toolName === 'thorbit_kb_source_status') return 'Source status returned. Check structuredContent for details.'\n if (toolName === 'thorbit_kb_search') return 'Knowledge-base search completed. Check structuredContent for results and citations.'\n if (toolName === 'thorbit_kb_ask') return 'Knowledge-base answer generated. Check structuredContent for citations and strategy.'\n return 'Thorbit knowledge-base tool completed.'\n}\n\nexport function formatThorbitKbMcpToolResult(\n toolName: ThorbitKnowledgeBaseMcpToolName,\n envelope: ThorbitKnowledgeBaseMcpEnvelope,\n): CallToolResult {\n if (!envelope.ok) {\n return {\n isError: true,\n content: [{\n type: 'text',\n text: `${envelope.error.code}: ${envelope.error.message}`,\n }],\n structuredContent: envelope,\n }\n }\n\n return {\n content: [{\n type: 'text',\n text: summarizeResult(toolName, envelope.result),\n }],\n structuredContent: envelope.result as Record<string, unknown>,\n }\n}\n","import { z } from 'zod'\n\nconst MetadataSchema = z.record(z.string(), z.unknown())\n\nexport const ThorbitKbCreateInputSchema = {\n name: z.string().min(1).max(255).describe('Name for the new Thorbit knowledge base.'),\n description: z.string().max(2000).optional().describe('Optional description for the new knowledge base.'),\n projectPublicId: z.string().min(1).optional().describe('Optional Thorbit project public ID. Omit to create an org-level knowledge base.'),\n folder: z.string().min(1).max(128).optional().describe('Optional organizational folder, such as research or domains.'),\n}\n\nexport const ThorbitKbListInputSchema = {\n projectPublicId: z.string().min(1).optional().describe('Optional Thorbit project public ID used to narrow knowledge-base listing.'),\n includeGlobal: z.boolean().default(true).describe('Include org-level/global knowledge bases. Default true.'),\n limit: z.number().int().min(1).max(100).default(50).describe('Maximum knowledge bases to return.'),\n}\n\nexport const ThorbitKbSourceStatusInputSchema = {\n sourcePublicIds: z.array(z.string().min(1)).min(1).max(100).describe('Source public IDs returned by Thorbit KB ingestion tools.'),\n}\n\nexport const ThorbitKbIngestUrlInputSchema = {\n knowledgeBasePublicId: z.string().min(1).describe('Target Thorbit knowledge-base public ID.'),\n url: z.string().url().describe('Public URL to extract through MCP Scraper and ingest into Thorbit.'),\n title: z.string().min(1).max(512).optional().describe('Optional title override. Provider title is used when omitted.'),\n mode: z.enum(['append']).default('append').describe('Append a new source version. Refresh mode is intentionally not enabled in V1.'),\n maxCharacters: z.number().int().min(500).max(500000).optional().describe('Optional cap before chunking/vectorization.'),\n metadata: MetadataSchema.optional().describe('Optional metadata stored on the KB source.'),\n}\n\nexport const ThorbitKbIngestSiteInputSchema = {\n knowledgeBasePublicId: z.string().min(1).describe('Target Thorbit knowledge-base public ID.'),\n startUrl: z.string().url().describe('Website start URL. Thorbit maps URLs through MCP Scraper, then ingests selected pages.'),\n includePatterns: z.array(z.string().min(1)).max(20).optional().describe('Optional regex or substring patterns that a mapped URL must match.'),\n excludePatterns: z.array(z.string().min(1)).max(20).optional().describe('Optional regex or substring patterns that remove mapped URLs.'),\n maxPages: z.number().int().min(1).max(100).default(25).describe('Maximum pages to ingest. Default 25, hard cap 100.'),\n mode: z.enum(['append']).default('append').describe('Append source versions. Refresh mode is intentionally not enabled in V1.'),\n metadata: MetadataSchema.optional().describe('Optional metadata stored on each KB source.'),\n}\n\nexport const ThorbitKbIngestYoutubeInputSchema = {\n knowledgeBasePublicId: z.string().min(1).describe('Target Thorbit knowledge-base public ID.'),\n videoUrl: z.string().url().describe('YouTube video URL. Thorbit transcribes through MCP Scraper and vectorizes transcript chunks.'),\n title: z.string().min(1).max(512).optional().describe('Optional title override.'),\n mode: z.enum(['append']).default('append').describe('Append a new source version.'),\n preserveTimestamps: z.boolean().default(true).describe('Store transcript timestamps on chunks when MCP Scraper returns them.'),\n metadata: MetadataSchema.optional().describe('Optional metadata stored on the KB source.'),\n}\n\nexport const ThorbitKbIngestTextInputSchema = {\n knowledgeBasePublicId: z.string().min(1).describe('Target Thorbit knowledge-base public ID.'),\n title: z.string().min(1).max(512).describe('Source title shown in KB citations.'),\n content: z.string().min(1).max(500000).describe('Text or Markdown to chunk, embed, and ingest.'),\n sourceUrl: z.string().url().optional().describe('Optional canonical source URL for citations.'),\n sourceType: z.enum(['manual', 'note', 'markdown']).default('manual').describe('Caller-facing source type. Thorbit stores note/markdown as manual sources in V1.'),\n metadata: MetadataSchema.optional().describe('Optional metadata stored on the KB source.'),\n}\n\nexport const ThorbitKbSearchInputSchema = {\n query: z.string().min(1).max(4000).describe('Search query. Use the user question or a focused retrieval query.'),\n knowledgeBasePublicId: z.string().min(1).optional().describe('Optional target KB. Omit to search visible KBs.'),\n projectPublicId: z.string().min(1).optional().describe('Optional project scope when no KB is specified.'),\n limit: z.number().int().min(1).max(20).default(5).describe('Maximum chunks to return.'),\n includeEntities: z.boolean().default(false).describe('Reserved for entity-rich responses.'),\n searchMode: z.enum(['smart', 'hybrid']).default('smart').describe('smart uses Thorbit intent/rerank retrieval; hybrid uses ANN plus FTS.'),\n}\n\nexport const ThorbitKbAskInputSchema = {\n question: z.string().min(1).max(8000).describe('Question to answer using Thorbit KB context only.'),\n knowledgeBasePublicId: z.string().min(1).optional().describe('Optional target KB. Omit to answer over visible KBs.'),\n projectPublicId: z.string().min(1).optional().describe('Optional project scope when no KB is specified.'),\n answerStyle: z.enum(['concise', 'detailed', 'extractive']).default('concise').describe('Use extractive to return source excerpts without an LLM answer.'),\n limit: z.number().int().min(1).max(20).default(8).describe('Maximum retrieved chunks used for the answer.'),\n requireCitations: z.boolean().default(true).describe('Keep true for grounded answers with citation arrays.'),\n}\n\nexport const ThorbitKnowledgeBaseMcpToolInputSchemas = {\n thorbit_kb_create: ThorbitKbCreateInputSchema,\n thorbit_kb_list: ThorbitKbListInputSchema,\n thorbit_kb_source_status: ThorbitKbSourceStatusInputSchema,\n thorbit_kb_ingest_url: ThorbitKbIngestUrlInputSchema,\n thorbit_kb_ingest_site: ThorbitKbIngestSiteInputSchema,\n thorbit_kb_ingest_youtube: ThorbitKbIngestYoutubeInputSchema,\n thorbit_kb_ingest_text: ThorbitKbIngestTextInputSchema,\n thorbit_kb_search: ThorbitKbSearchInputSchema,\n thorbit_kb_ask: ThorbitKbAskInputSchema,\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../bin/thorbit-kb-mcp.ts","../../src/thorbit-kb-api-client.ts","../../src/thorbit-kb-mcp-env.ts","../../src/thorbit-kb-mcp-server.ts","../../src/thorbit-kb-mcp-response-formatters.ts","../../src/thorbit-kb-mcp-tool-schemas.ts"],"sourcesContent":["import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { ThorbitKnowledgeBaseApiClient } from '../src/thorbit-kb-api-client.js'\nimport { resolveThorbitKbMcpEnv } from '../src/thorbit-kb-mcp-env.js'\nimport { buildThorbitKnowledgeBaseMcpServer } from '../src/thorbit-kb-mcp-server.js'\n\nasync function main() {\n const env = resolveThorbitKbMcpEnv()\n const client = new ThorbitKnowledgeBaseApiClient(env)\n const server = buildThorbitKnowledgeBaseMcpServer(client)\n await server.connect(new StdioServerTransport())\n}\n\nmain().catch(error => {\n process.stderr.write(`${error instanceof Error ? error.message : String(error)}\\n`)\n process.exit(1)\n})\n","import type { ThorbitKnowledgeBaseMcpToolName } from './thorbit-kb-mcp-tool-names.js'\n\nexport type ThorbitKnowledgeBaseMcpEnvelope =\n | {\n ok: true\n result: unknown\n warnings?: string[]\n requestId: string\n usage?: Record<string, unknown>\n }\n | {\n ok: false\n error: {\n code: string\n message: string\n details?: unknown\n }\n requestId: string\n }\n\nexport class ThorbitKnowledgeBaseApiClient {\n private readonly baseUrl: string\n private readonly apiKey: string\n\n constructor(options: { baseUrl: string; apiKey: string }) {\n this.baseUrl = options.baseUrl.replace(/\\/$/, '')\n this.apiKey = options.apiKey\n }\n\n async callTool(toolName: ThorbitKnowledgeBaseMcpToolName, input: unknown): Promise<ThorbitKnowledgeBaseMcpEnvelope> {\n const response = await fetch(`${this.baseUrl}/api/v1/mcp/knowledge-base/${toolName}`, {\n method: 'POST',\n headers: {\n 'x-thorbit-api-key': this.apiKey,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(input ?? {}),\n })\n\n const body = await response.json().catch(() => null) as ThorbitKnowledgeBaseMcpEnvelope | null\n if (body && typeof body === 'object' && 'ok' in body) return body\n\n return {\n ok: false,\n requestId: 'unavailable',\n error: {\n code: response.ok ? 'invalid_response' : `http_${response.status}`,\n message: response.ok ? 'Thorbit returned an invalid MCP response' : `Thorbit API request failed with HTTP ${response.status}`,\n },\n }\n }\n}\n","import { readFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\n\nexport type ThorbitKbMcpEnv = {\n apiKey: string\n baseUrl: string\n}\n\nfunction readApiKeyFile(): string | undefined {\n const explicitPath = process.env.THORBIT_KB_MCP_KEY_PATH?.trim()\n const paths = [explicitPath, join(homedir(), '.thorbit-kb-mcp-key')].filter(Boolean) as string[]\n for (const path of paths) {\n try {\n const value = readFileSync(path, 'utf8').trim()\n if (value) return value\n } catch {\n continue\n }\n }\n return undefined\n}\n\nexport function resolveThorbitKbMcpEnv(): ThorbitKbMcpEnv {\n const apiKey = (\n process.env.THORBIT_API_KEY ||\n process.env.THORBIT_MCP_API_KEY ||\n process.env.THORBIT_KB_MCP_API_KEY ||\n readApiKeyFile()\n )?.trim()\n\n if (!apiKey) {\n throw new Error('THORBIT_API_KEY, THORBIT_MCP_API_KEY, or ~/.thorbit-kb-mcp-key is required')\n }\n\n return {\n apiKey,\n baseUrl: (process.env.THORBIT_BASE_URL || process.env.THORBIT_KB_MCP_BASE_URL || 'https://thorbit.ai').trim(),\n }\n}\n","import { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { ToolAnnotations } from '@modelcontextprotocol/sdk/types.js'\nimport type { ZodRawShape } from 'zod'\nimport type { ThorbitKnowledgeBaseApiClient, ThorbitKnowledgeBaseMcpEnvelope } from './thorbit-kb-api-client.js'\nimport { formatThorbitKbMcpToolResult } from './thorbit-kb-mcp-response-formatters.js'\nimport {\n ThorbitKbAskInputSchema,\n ThorbitKbCreateInputSchema,\n ThorbitKbIngestSiteInputSchema,\n ThorbitKbIngestTextInputSchema,\n ThorbitKbIngestUrlInputSchema,\n ThorbitKbIngestYoutubeInputSchema,\n ThorbitKbListInputSchema,\n ThorbitKbSearchInputSchema,\n ThorbitKbSourceStatusInputSchema,\n} from './thorbit-kb-mcp-tool-schemas.js'\nimport type { ThorbitKnowledgeBaseMcpToolName } from './thorbit-kb-mcp-tool-names.js'\n\nconst VERSION = '0.2.8'\n\ntype ThorbitKbToolConfig<InputArgs extends ZodRawShape> = {\n title: string\n description: string\n inputSchema: InputArgs\n annotations: ToolAnnotations\n}\n\nfunction readOnlyAnnotations(title: string, idempotent = true) {\n return {\n title,\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: idempotent,\n openWorldHint: false,\n }\n}\n\nfunction ingestAnnotations(title: string, openWorldHint: boolean) {\n return {\n title,\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint,\n }\n}\n\nexport const SERVER_INSTRUCTIONS = [\n '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.',\n '',\n '## Set up a knowledge base',\n '- New knowledge base -> **thorbit_kb_create**. Org-level by default; pass projectPublicId to scope it to one project.',\n '- Find an existing one\\'s public ID -> **thorbit_kb_list** (needed before ingesting/searching if you don\\'t already have it).',\n '',\n '## Ingest content',\n '- One web page -> **thorbit_kb_ingest_url** (MCP Scraper extract, up to 500,000 chars before chunking).',\n '- A whole site (mapped + filtered by include/excludePatterns) -> **thorbit_kb_ingest_site** (up to 100 pages, default 25).',\n '- A YouTube video (transcribed, timestamps preserved by default) -> **thorbit_kb_ingest_youtube**.',\n '- Raw text/Markdown you already have -> **thorbit_kb_ingest_text** (no scraping needed).',\n '- All ingestion is append-only in this version — there\\'s no refresh/re-ingest mode; re-ingesting a URL adds a new source version rather than replacing the old one.',\n '- Check on an ingest\\'s progress -> **thorbit_kb_source_status** with the sourcePublicIds it returned.',\n '',\n '## Query a knowledge base',\n '- Need citation-ready chunks yourself, not a synthesized answer -> **thorbit_kb_search**.',\n '- 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.',\n].join('\\n')\n\nexport type ThorbitKbCallTool = (\n toolName: ThorbitKnowledgeBaseMcpToolName,\n input: unknown,\n) => Promise<ThorbitKnowledgeBaseMcpEnvelope>\n\nexport type BuildThorbitKnowledgeBaseMcpServerOptions =\n | ThorbitKnowledgeBaseApiClient\n | { callTool: ThorbitKbCallTool }\n\nexport function buildThorbitKnowledgeBaseMcpServer(options: BuildThorbitKnowledgeBaseMcpServerOptions): McpServer {\n const callTool: ThorbitKbCallTool = (toolName, input) => options.callTool(toolName, input)\n const server = new McpServer({ name: 'thorbit-kb-mcp', version: VERSION }, { instructions: SERVER_INSTRUCTIONS })\n\n server.registerResource(\n 'knowledge-bases',\n 'thorbit-kb://knowledge-bases',\n {\n title: 'Thorbit Knowledge Bases',\n description: 'Knowledge bases visible to this Thorbit MCP API key.',\n mimeType: 'application/json',\n },\n async (uri) => {\n const envelope = await callTool('thorbit_kb_list', {})\n return { contents: [{ uri: uri.href, mimeType: 'application/json', text: JSON.stringify(envelope, null, 2) }] }\n },\n )\n\n server.registerResource(\n 'source-status',\n new ResourceTemplate('thorbit-kb://sources/{sourcePublicId}', { list: undefined }),\n {\n title: 'Thorbit KB Source Status',\n description: 'Status and metadata for one Thorbit knowledge-base source.',\n mimeType: 'application/json',\n },\n async (uri, variables) => {\n const sourcePublicId = Array.isArray(variables.sourcePublicId) ? variables.sourcePublicId[0] : variables.sourcePublicId\n const envelope = await callTool('thorbit_kb_source_status', { sourcePublicIds: [String(sourcePublicId)] })\n return { contents: [{ uri: uri.href, mimeType: 'application/json', text: JSON.stringify(envelope, null, 2) }] }\n },\n )\n\n function registerTool<T extends ThorbitKnowledgeBaseMcpToolName>(\n toolName: T,\n config: ThorbitKbToolConfig<ZodRawShape>,\n ): void {\n server.registerTool(toolName, config, async (input) => {\n const envelope = await callTool(toolName, input)\n return formatThorbitKbMcpToolResult(toolName, envelope)\n })\n }\n\n registerTool('thorbit_kb_create', {\n title: 'Create Thorbit Knowledge Base',\n 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.',\n inputSchema: ThorbitKbCreateInputSchema,\n annotations: ingestAnnotations('Create Thorbit Knowledge Base', false),\n })\n\n registerTool('thorbit_kb_list', {\n title: 'List Thorbit Knowledge Bases',\n 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 — every ingest tool needs one (search/ask can omit it to query all visible KBs instead).',\n inputSchema: ThorbitKbListInputSchema,\n annotations: readOnlyAnnotations('List Thorbit Knowledge Bases'),\n })\n\n registerTool('thorbit_kb_source_status', {\n title: 'Read Thorbit KB Source Status',\n description: 'Poll ingestion status for source public IDs returned by any thorbit_kb_ingest_* tool — the only way to check whether an ingest finished, since the ingest tools may return before vectorization completes.',\n inputSchema: ThorbitKbSourceStatusInputSchema,\n annotations: readOnlyAnnotations('Read Thorbit KB Source Status'),\n })\n\n registerTool('thorbit_kb_ingest_url', {\n title: 'Ingest URL Into Thorbit KB',\n 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 the same URL adds a new source version rather than replacing the prior one — there is no refresh mode in this version.',\n inputSchema: ThorbitKbIngestUrlInputSchema,\n annotations: ingestAnnotations('Ingest URL Into Thorbit KB', true),\n })\n\n registerTool('thorbit_kb_ingest_site', {\n title: 'Ingest Website Into Thorbit KB',\n description: 'Map a website through MCP Scraper, extract selected pages (up to 100, default 25, filterable via includePatterns/excludePatterns), and vectorize each into a knowledge base. For a single known page instead of crawling a site, use thorbit_kb_ingest_url — cheaper and faster. Append-only, same as thorbit_kb_ingest_url.',\n inputSchema: ThorbitKbIngestSiteInputSchema,\n annotations: ingestAnnotations('Ingest Website Into Thorbit KB', true),\n })\n\n registerTool('thorbit_kb_ingest_youtube', {\n title: 'Ingest YouTube Into Thorbit KB',\n description: 'Transcribe a YouTube video through MCP Scraper and vectorize the transcript (timestamp chunks preserved by default) into a knowledge base. For web pages or raw text instead of video, use thorbit_kb_ingest_url or thorbit_kb_ingest_text.',\n inputSchema: ThorbitKbIngestYoutubeInputSchema,\n annotations: ingestAnnotations('Ingest YouTube Into Thorbit KB', true),\n })\n\n registerTool('thorbit_kb_ingest_text', {\n title: 'Ingest Text Into Thorbit KB',\n description: 'Submit text or Markdown you already have directly into a knowledge base — no scraping involved. Use this instead of thorbit_kb_ingest_url when you already have the content in hand rather than a URL to fetch.',\n inputSchema: ThorbitKbIngestTextInputSchema,\n annotations: ingestAnnotations('Ingest Text Into Thorbit KB', false),\n })\n\n registerTool('thorbit_kb_search', {\n title: 'Search Thorbit Knowledge Base',\n description: 'Search knowledge-base content and get citation-ready chunks back directly, without a synthesized answer. Use this instead of thorbit_kb_ask when you want to reason over the raw retrieved passages yourself. Omit knowledgeBasePublicId to search all KBs visible to this key.',\n inputSchema: ThorbitKbSearchInputSchema,\n annotations: readOnlyAnnotations('Search Thorbit Knowledge Base'),\n })\n\n registerTool('thorbit_kb_ask', {\n title: 'Ask Thorbit Knowledge Base',\n description: 'Answer a question using ONLY retrieved knowledge-base context — returns the answer, citations, sufficiency, and retrieval metadata. Set answerStyle:\"extractive\" for source excerpts without an LLM-written answer. Use thorbit_kb_search instead when you want the raw chunks rather than a synthesized answer.',\n inputSchema: ThorbitKbAskInputSchema,\n annotations: readOnlyAnnotations('Ask Thorbit Knowledge Base', false),\n })\n\n return server\n}\n","import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js'\nimport type { ThorbitKnowledgeBaseMcpEnvelope } from './thorbit-kb-api-client.js'\nimport type { ThorbitKnowledgeBaseMcpToolName } from './thorbit-kb-mcp-tool-names.js'\n\nfunction summarizeResult(toolName: ThorbitKnowledgeBaseMcpToolName, result: unknown): string {\n if (toolName === 'thorbit_kb_create' && result && typeof result === 'object' && 'knowledgeBase' in result) {\n const kb = result.knowledgeBase as { name?: unknown; publicId?: unknown }\n return `Created Thorbit knowledge base ${String(kb.name ?? kb.publicId ?? '')}.`\n }\n if (toolName === 'thorbit_kb_list' && result && typeof result === 'object' && 'knowledgeBases' in result) {\n const count = Array.isArray(result.knowledgeBases) ? result.knowledgeBases.length : 0\n return `Found ${count} Thorbit knowledge base${count === 1 ? '' : 's'}.`\n }\n if (toolName.startsWith('thorbit_kb_ingest')) return 'Knowledge-base ingestion completed. Check structuredContent for source receipts.'\n if (toolName === 'thorbit_kb_source_status') return 'Source status returned. Check structuredContent for details.'\n if (toolName === 'thorbit_kb_search') return 'Knowledge-base search completed. Check structuredContent for results and citations.'\n if (toolName === 'thorbit_kb_ask') return 'Knowledge-base answer generated. Check structuredContent for citations and strategy.'\n return 'Thorbit knowledge-base tool completed.'\n}\n\nexport function formatThorbitKbMcpToolResult(\n toolName: ThorbitKnowledgeBaseMcpToolName,\n envelope: ThorbitKnowledgeBaseMcpEnvelope,\n): CallToolResult {\n if (!envelope.ok) {\n return {\n isError: true,\n content: [{\n type: 'text',\n text: `${envelope.error.code}: ${envelope.error.message}`,\n }],\n structuredContent: envelope,\n }\n }\n\n return {\n content: [{\n type: 'text',\n text: summarizeResult(toolName, envelope.result),\n }],\n structuredContent: envelope.result as Record<string, unknown>,\n }\n}\n","import { z } from 'zod'\n\nconst MetadataSchema = z.record(z.string(), z.unknown())\n\nexport const ThorbitKbCreateInputSchema = {\n name: z.string().min(1).max(255).describe('Name for the new Thorbit knowledge base.'),\n description: z.string().max(2000).optional().describe('Optional description for the new knowledge base.'),\n projectPublicId: z.string().min(1).optional().describe('Optional Thorbit project public ID. Omit to create an org-level knowledge base.'),\n folder: z.string().min(1).max(128).optional().describe('Optional organizational folder, such as research or domains.'),\n}\n\nexport const ThorbitKbListInputSchema = {\n projectPublicId: z.string().min(1).optional().describe('Optional Thorbit project public ID used to narrow knowledge-base listing.'),\n includeGlobal: z.boolean().default(true).describe('Include org-level/global knowledge bases. Default true.'),\n limit: z.number().int().min(1).max(100).default(50).describe('Maximum knowledge bases to return.'),\n}\n\nexport const ThorbitKbSourceStatusInputSchema = {\n sourcePublicIds: z.array(z.string().min(1)).min(1).max(100).describe('Source public IDs returned by Thorbit KB ingestion tools.'),\n}\n\nexport const ThorbitKbIngestUrlInputSchema = {\n knowledgeBasePublicId: z.string().min(1).describe('Target Thorbit knowledge-base public ID.'),\n url: z.string().url().describe('Public URL to extract through MCP Scraper and ingest into Thorbit.'),\n title: z.string().min(1).max(512).optional().describe('Optional title override. Provider title is used when omitted.'),\n mode: z.enum(['append']).default('append').describe('Append a new source version. Refresh mode is intentionally not enabled in V1.'),\n maxCharacters: z.number().int().min(500).max(500000).optional().describe('Optional cap before chunking/vectorization.'),\n metadata: MetadataSchema.optional().describe('Optional metadata stored on the KB source.'),\n}\n\nexport const ThorbitKbIngestSiteInputSchema = {\n knowledgeBasePublicId: z.string().min(1).describe('Target Thorbit knowledge-base public ID.'),\n startUrl: z.string().url().describe('Website start URL. Thorbit maps URLs through MCP Scraper, then ingests selected pages.'),\n includePatterns: z.array(z.string().min(1)).max(20).optional().describe('Optional regex or substring patterns that a mapped URL must match.'),\n excludePatterns: z.array(z.string().min(1)).max(20).optional().describe('Optional regex or substring patterns that remove mapped URLs.'),\n maxPages: z.number().int().min(1).max(100).default(25).describe('Maximum pages to ingest. Default 25, hard cap 100.'),\n mode: z.enum(['append']).default('append').describe('Append source versions. Refresh mode is intentionally not enabled in V1.'),\n metadata: MetadataSchema.optional().describe('Optional metadata stored on each KB source.'),\n}\n\nexport const ThorbitKbIngestYoutubeInputSchema = {\n knowledgeBasePublicId: z.string().min(1).describe('Target Thorbit knowledge-base public ID.'),\n videoUrl: z.string().url().describe('YouTube video URL. Thorbit transcribes through MCP Scraper and vectorizes transcript chunks.'),\n title: z.string().min(1).max(512).optional().describe('Optional title override.'),\n mode: z.enum(['append']).default('append').describe('Append a new source version.'),\n preserveTimestamps: z.boolean().default(true).describe('Store transcript timestamps on chunks when MCP Scraper returns them.'),\n metadata: MetadataSchema.optional().describe('Optional metadata stored on the KB source.'),\n}\n\nexport const ThorbitKbIngestTextInputSchema = {\n knowledgeBasePublicId: z.string().min(1).describe('Target Thorbit knowledge-base public ID.'),\n title: z.string().min(1).max(512).describe('Source title shown in KB citations.'),\n content: z.string().min(1).max(500000).describe('Text or Markdown to chunk, embed, and ingest.'),\n sourceUrl: z.string().url().optional().describe('Optional canonical source URL for citations.'),\n sourceType: z.enum(['manual', 'note', 'markdown']).default('manual').describe('Caller-facing source type. Thorbit stores note/markdown as manual sources in V1.'),\n metadata: MetadataSchema.optional().describe('Optional metadata stored on the KB source.'),\n}\n\nexport const ThorbitKbSearchInputSchema = {\n query: z.string().min(1).max(4000).describe('Search query. Use the user question or a focused retrieval query.'),\n knowledgeBasePublicId: z.string().min(1).optional().describe('Optional target KB. Omit to search visible KBs.'),\n projectPublicId: z.string().min(1).optional().describe('Optional project scope when no KB is specified.'),\n limit: z.number().int().min(1).max(20).default(5).describe('Maximum chunks to return.'),\n includeEntities: z.boolean().default(false).describe('Reserved for entity-rich responses.'),\n searchMode: z.enum(['smart', 'hybrid']).default('smart').describe('smart uses Thorbit intent/rerank retrieval; hybrid uses ANN plus FTS.'),\n}\n\nexport const ThorbitKbAskInputSchema = {\n question: z.string().min(1).max(8000).describe('Question to answer using Thorbit KB context only.'),\n knowledgeBasePublicId: z.string().min(1).optional().describe('Optional target KB. Omit to answer over visible KBs.'),\n projectPublicId: z.string().min(1).optional().describe('Optional project scope when no KB is specified.'),\n answerStyle: z.enum(['concise', 'detailed', 'extractive']).default('concise').describe('Use extractive to return source excerpts without an LLM answer.'),\n limit: z.number().int().min(1).max(20).default(8).describe('Maximum retrieved chunks used for the answer.'),\n requireCitations: z.boolean().default(true).describe('Keep true for grounded answers with citation arrays.'),\n}\n\nexport const ThorbitKnowledgeBaseMcpToolInputSchemas = {\n thorbit_kb_create: ThorbitKbCreateInputSchema,\n thorbit_kb_list: ThorbitKbListInputSchema,\n thorbit_kb_source_status: ThorbitKbSourceStatusInputSchema,\n thorbit_kb_ingest_url: ThorbitKbIngestUrlInputSchema,\n thorbit_kb_ingest_site: ThorbitKbIngestSiteInputSchema,\n thorbit_kb_ingest_youtube: ThorbitKbIngestYoutubeInputSchema,\n thorbit_kb_ingest_text: ThorbitKbIngestTextInputSchema,\n thorbit_kb_search: ThorbitKbSearchInputSchema,\n thorbit_kb_ask: ThorbitKbAskInputSchema,\n}\n"],"mappings":"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","names":[]}
@@ -168,7 +168,7 @@ var ThorbitKbAskInputSchema = {
168
168
  };
169
169
 
170
170
  // src/thorbit-kb-mcp-server.ts
171
- var VERSION = "0.2.7";
171
+ var VERSION = "0.2.8";
172
172
  function readOnlyAnnotations(title, idempotent = true) {
173
173
  return {
174
174
  title,
@@ -187,9 +187,28 @@ function ingestAnnotations(title, openWorldHint) {
187
187
  openWorldHint
188
188
  };
189
189
  }
190
+ var SERVER_INSTRUCTIONS = [
191
+ "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.",
192
+ "",
193
+ "## Set up a knowledge base",
194
+ "- New knowledge base -> **thorbit_kb_create**. Org-level by default; pass projectPublicId to scope it to one project.",
195
+ "- Find an existing one's public ID -> **thorbit_kb_list** (needed before ingesting/searching if you don't already have it).",
196
+ "",
197
+ "## Ingest content",
198
+ "- One web page -> **thorbit_kb_ingest_url** (MCP Scraper extract, up to 500,000 chars before chunking).",
199
+ "- A whole site (mapped + filtered by include/excludePatterns) -> **thorbit_kb_ingest_site** (up to 100 pages, default 25).",
200
+ "- A YouTube video (transcribed, timestamps preserved by default) -> **thorbit_kb_ingest_youtube**.",
201
+ "- Raw text/Markdown you already have -> **thorbit_kb_ingest_text** (no scraping needed).",
202
+ "- 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.",
203
+ "- Check on an ingest's progress -> **thorbit_kb_source_status** with the sourcePublicIds it returned.",
204
+ "",
205
+ "## Query a knowledge base",
206
+ "- Need citation-ready chunks yourself, not a synthesized answer -> **thorbit_kb_search**.",
207
+ '- 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.'
208
+ ].join("\n");
190
209
  function buildThorbitKnowledgeBaseMcpServer(options) {
191
210
  const callTool = (toolName, input) => options.callTool(toolName, input);
192
- const server = new McpServer({ name: "thorbit-kb-mcp", version: VERSION });
211
+ const server = new McpServer({ name: "thorbit-kb-mcp", version: VERSION }, { instructions: SERVER_INSTRUCTIONS });
193
212
  server.registerResource(
194
213
  "knowledge-bases",
195
214
  "thorbit-kb://knowledge-bases",
@@ -225,55 +244,55 @@ function buildThorbitKnowledgeBaseMcpServer(options) {
225
244
  }
226
245
  registerTool("thorbit_kb_create", {
227
246
  title: "Create Thorbit Knowledge Base",
228
- description: "Create a new Thorbit vector-backed knowledge base for MCP ingestion, smart RAG search, citations, and entity extraction.",
247
+ 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.",
229
248
  inputSchema: ThorbitKbCreateInputSchema,
230
249
  annotations: ingestAnnotations("Create Thorbit Knowledge Base", false)
231
250
  });
232
251
  registerTool("thorbit_kb_list", {
233
252
  title: "List Thorbit Knowledge Bases",
234
- description: "List Thorbit knowledge bases visible to this API key. Use before ingestion/search when the target KB public ID is unknown.",
253
+ 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).",
235
254
  inputSchema: ThorbitKbListInputSchema,
236
255
  annotations: readOnlyAnnotations("List Thorbit Knowledge Bases")
237
256
  });
238
257
  registerTool("thorbit_kb_source_status", {
239
258
  title: "Read Thorbit KB Source Status",
240
- description: "Poll ingestion status for source public IDs returned by Thorbit KB ingestion tools.",
259
+ description: "Poll ingestion status for source public IDs returned by any thorbit_kb_ingest_* tool \u2014 the only way to check whether an ingest finished, since the ingest tools may return before vectorization completes.",
241
260
  inputSchema: ThorbitKbSourceStatusInputSchema,
242
261
  annotations: readOnlyAnnotations("Read Thorbit KB Source Status")
243
262
  });
244
263
  registerTool("thorbit_kb_ingest_url", {
245
264
  title: "Ingest URL Into Thorbit KB",
246
- description: "Extract one public URL through MCP Scraper, clean the content, submit it to Thorbit, and vectorize it into the selected knowledge base.",
265
+ 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 the same URL adds a new source version rather than replacing the prior one \u2014 there is no refresh mode in this version.",
247
266
  inputSchema: ThorbitKbIngestUrlInputSchema,
248
267
  annotations: ingestAnnotations("Ingest URL Into Thorbit KB", true)
249
268
  });
250
269
  registerTool("thorbit_kb_ingest_site", {
251
270
  title: "Ingest Website Into Thorbit KB",
252
- description: "Map a website through MCP Scraper, extract selected pages, submit each page to Thorbit, and vectorize them into the selected knowledge base.",
271
+ description: "Map a website through MCP Scraper, extract selected pages (up to 100, default 25, filterable via includePatterns/excludePatterns), and vectorize each into a knowledge base. For a single known page instead of crawling a site, use thorbit_kb_ingest_url \u2014 cheaper and faster. Append-only, same as thorbit_kb_ingest_url.",
253
272
  inputSchema: ThorbitKbIngestSiteInputSchema,
254
273
  annotations: ingestAnnotations("Ingest Website Into Thorbit KB", true)
255
274
  });
256
275
  registerTool("thorbit_kb_ingest_youtube", {
257
276
  title: "Ingest YouTube Into Thorbit KB",
258
- description: "Transcribe a YouTube video through MCP Scraper, preserve timestamp chunks when available, and vectorize the transcript into Thorbit KB.",
277
+ description: "Transcribe a YouTube video through MCP Scraper and vectorize the transcript (timestamp chunks preserved by default) into a knowledge base. For web pages or raw text instead of video, use thorbit_kb_ingest_url or thorbit_kb_ingest_text.",
259
278
  inputSchema: ThorbitKbIngestYoutubeInputSchema,
260
279
  annotations: ingestAnnotations("Ingest YouTube Into Thorbit KB", true)
261
280
  });
262
281
  registerTool("thorbit_kb_ingest_text", {
263
282
  title: "Ingest Text Into Thorbit KB",
264
- description: "Submit provided text or Markdown directly to Thorbit and vectorize it into the selected knowledge base.",
283
+ description: "Submit text or Markdown you already have directly into a knowledge base \u2014 no scraping involved. Use this instead of thorbit_kb_ingest_url when you already have the content in hand rather than a URL to fetch.",
265
284
  inputSchema: ThorbitKbIngestTextInputSchema,
266
285
  annotations: ingestAnnotations("Ingest Text Into Thorbit KB", false)
267
286
  });
268
287
  registerTool("thorbit_kb_search", {
269
288
  title: "Search Thorbit Knowledge Base",
270
- description: "Search Thorbit KB content with citation-ready chunks. Use when the user needs source-backed snippets or evidence.",
289
+ description: "Search knowledge-base content and get citation-ready chunks back directly, without a synthesized answer. Use this instead of thorbit_kb_ask when you want to reason over the raw retrieved passages yourself. Omit knowledgeBasePublicId to search all KBs visible to this key.",
271
290
  inputSchema: ThorbitKbSearchInputSchema,
272
291
  annotations: readOnlyAnnotations("Search Thorbit Knowledge Base")
273
292
  });
274
293
  registerTool("thorbit_kb_ask", {
275
294
  title: "Ask Thorbit Knowledge Base",
276
- description: "Answer a question using only retrieved Thorbit KB context. Returns answer, citations, sufficiency, and retrieval strategy metadata.",
295
+ description: 'Answer a question using ONLY retrieved knowledge-base context \u2014 returns the answer, citations, sufficiency, and retrieval metadata. Set answerStyle:"extractive" for source excerpts without an LLM-written answer. Use thorbit_kb_search instead when you want the raw chunks rather than a synthesized answer.',
277
296
  inputSchema: ThorbitKbAskInputSchema,
278
297
  annotations: readOnlyAnnotations("Ask Thorbit Knowledge Base", false)
279
298
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../bin/thorbit-kb-mcp.ts","../../src/thorbit-kb-api-client.ts","../../src/thorbit-kb-mcp-env.ts","../../src/thorbit-kb-mcp-server.ts","../../src/thorbit-kb-mcp-response-formatters.ts","../../src/thorbit-kb-mcp-tool-schemas.ts"],"sourcesContent":["import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { ThorbitKnowledgeBaseApiClient } from '../src/thorbit-kb-api-client.js'\nimport { resolveThorbitKbMcpEnv } from '../src/thorbit-kb-mcp-env.js'\nimport { buildThorbitKnowledgeBaseMcpServer } from '../src/thorbit-kb-mcp-server.js'\n\nasync function main() {\n const env = resolveThorbitKbMcpEnv()\n const client = new ThorbitKnowledgeBaseApiClient(env)\n const server = buildThorbitKnowledgeBaseMcpServer(client)\n await server.connect(new StdioServerTransport())\n}\n\nmain().catch(error => {\n process.stderr.write(`${error instanceof Error ? error.message : String(error)}\\n`)\n process.exit(1)\n})\n","import type { ThorbitKnowledgeBaseMcpToolName } from './thorbit-kb-mcp-tool-names.js'\n\nexport type ThorbitKnowledgeBaseMcpEnvelope =\n | {\n ok: true\n result: unknown\n warnings?: string[]\n requestId: string\n usage?: Record<string, unknown>\n }\n | {\n ok: false\n error: {\n code: string\n message: string\n details?: unknown\n }\n requestId: string\n }\n\nexport class ThorbitKnowledgeBaseApiClient {\n private readonly baseUrl: string\n private readonly apiKey: string\n\n constructor(options: { baseUrl: string; apiKey: string }) {\n this.baseUrl = options.baseUrl.replace(/\\/$/, '')\n this.apiKey = options.apiKey\n }\n\n async callTool(toolName: ThorbitKnowledgeBaseMcpToolName, input: unknown): Promise<ThorbitKnowledgeBaseMcpEnvelope> {\n const response = await fetch(`${this.baseUrl}/api/v1/mcp/knowledge-base/${toolName}`, {\n method: 'POST',\n headers: {\n 'x-thorbit-api-key': this.apiKey,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(input ?? {}),\n })\n\n const body = await response.json().catch(() => null) as ThorbitKnowledgeBaseMcpEnvelope | null\n if (body && typeof body === 'object' && 'ok' in body) return body\n\n return {\n ok: false,\n requestId: 'unavailable',\n error: {\n code: response.ok ? 'invalid_response' : `http_${response.status}`,\n message: response.ok ? 'Thorbit returned an invalid MCP response' : `Thorbit API request failed with HTTP ${response.status}`,\n },\n }\n }\n}\n","import { readFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\n\nexport type ThorbitKbMcpEnv = {\n apiKey: string\n baseUrl: string\n}\n\nfunction readApiKeyFile(): string | undefined {\n const explicitPath = process.env.THORBIT_KB_MCP_KEY_PATH?.trim()\n const paths = [explicitPath, join(homedir(), '.thorbit-kb-mcp-key')].filter(Boolean) as string[]\n for (const path of paths) {\n try {\n const value = readFileSync(path, 'utf8').trim()\n if (value) return value\n } catch {\n continue\n }\n }\n return undefined\n}\n\nexport function resolveThorbitKbMcpEnv(): ThorbitKbMcpEnv {\n const apiKey = (\n process.env.THORBIT_API_KEY ||\n process.env.THORBIT_MCP_API_KEY ||\n process.env.THORBIT_KB_MCP_API_KEY ||\n readApiKeyFile()\n )?.trim()\n\n if (!apiKey) {\n throw new Error('THORBIT_API_KEY, THORBIT_MCP_API_KEY, or ~/.thorbit-kb-mcp-key is required')\n }\n\n return {\n apiKey,\n baseUrl: (process.env.THORBIT_BASE_URL || process.env.THORBIT_KB_MCP_BASE_URL || 'https://thorbit.ai').trim(),\n }\n}\n","import { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { ToolAnnotations } from '@modelcontextprotocol/sdk/types.js'\nimport type { ZodRawShape } from 'zod'\nimport type { ThorbitKnowledgeBaseApiClient, ThorbitKnowledgeBaseMcpEnvelope } from './thorbit-kb-api-client.js'\nimport { formatThorbitKbMcpToolResult } from './thorbit-kb-mcp-response-formatters.js'\nimport {\n ThorbitKbAskInputSchema,\n ThorbitKbCreateInputSchema,\n ThorbitKbIngestSiteInputSchema,\n ThorbitKbIngestTextInputSchema,\n ThorbitKbIngestUrlInputSchema,\n ThorbitKbIngestYoutubeInputSchema,\n ThorbitKbListInputSchema,\n ThorbitKbSearchInputSchema,\n ThorbitKbSourceStatusInputSchema,\n} from './thorbit-kb-mcp-tool-schemas.js'\nimport type { ThorbitKnowledgeBaseMcpToolName } from './thorbit-kb-mcp-tool-names.js'\n\nconst VERSION = '0.2.7'\n\ntype ThorbitKbToolConfig<InputArgs extends ZodRawShape> = {\n title: string\n description: string\n inputSchema: InputArgs\n annotations: ToolAnnotations\n}\n\nfunction readOnlyAnnotations(title: string, idempotent = true) {\n return {\n title,\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: idempotent,\n openWorldHint: false,\n }\n}\n\nfunction ingestAnnotations(title: string, openWorldHint: boolean) {\n return {\n title,\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint,\n }\n}\n\nexport type ThorbitKbCallTool = (\n toolName: ThorbitKnowledgeBaseMcpToolName,\n input: unknown,\n) => Promise<ThorbitKnowledgeBaseMcpEnvelope>\n\nexport type BuildThorbitKnowledgeBaseMcpServerOptions =\n | ThorbitKnowledgeBaseApiClient\n | { callTool: ThorbitKbCallTool }\n\nexport function buildThorbitKnowledgeBaseMcpServer(options: BuildThorbitKnowledgeBaseMcpServerOptions): McpServer {\n const callTool: ThorbitKbCallTool = (toolName, input) => options.callTool(toolName, input)\n const server = new McpServer({ name: 'thorbit-kb-mcp', version: VERSION })\n\n server.registerResource(\n 'knowledge-bases',\n 'thorbit-kb://knowledge-bases',\n {\n title: 'Thorbit Knowledge Bases',\n description: 'Knowledge bases visible to this Thorbit MCP API key.',\n mimeType: 'application/json',\n },\n async (uri) => {\n const envelope = await callTool('thorbit_kb_list', {})\n return { contents: [{ uri: uri.href, mimeType: 'application/json', text: JSON.stringify(envelope, null, 2) }] }\n },\n )\n\n server.registerResource(\n 'source-status',\n new ResourceTemplate('thorbit-kb://sources/{sourcePublicId}', { list: undefined }),\n {\n title: 'Thorbit KB Source Status',\n description: 'Status and metadata for one Thorbit knowledge-base source.',\n mimeType: 'application/json',\n },\n async (uri, variables) => {\n const sourcePublicId = Array.isArray(variables.sourcePublicId) ? variables.sourcePublicId[0] : variables.sourcePublicId\n const envelope = await callTool('thorbit_kb_source_status', { sourcePublicIds: [String(sourcePublicId)] })\n return { contents: [{ uri: uri.href, mimeType: 'application/json', text: JSON.stringify(envelope, null, 2) }] }\n },\n )\n\n function registerTool<T extends ThorbitKnowledgeBaseMcpToolName>(\n toolName: T,\n config: ThorbitKbToolConfig<ZodRawShape>,\n ): void {\n server.registerTool(toolName, config, async (input) => {\n const envelope = await callTool(toolName, input)\n return formatThorbitKbMcpToolResult(toolName, envelope)\n })\n }\n\n registerTool('thorbit_kb_create', {\n title: 'Create Thorbit Knowledge Base',\n description: 'Create a new Thorbit vector-backed knowledge base for MCP ingestion, smart RAG search, citations, and entity extraction.',\n inputSchema: ThorbitKbCreateInputSchema,\n annotations: ingestAnnotations('Create Thorbit Knowledge Base', false),\n })\n\n registerTool('thorbit_kb_list', {\n title: 'List Thorbit Knowledge Bases',\n description: 'List Thorbit knowledge bases visible to this API key. Use before ingestion/search when the target KB public ID is unknown.',\n inputSchema: ThorbitKbListInputSchema,\n annotations: readOnlyAnnotations('List Thorbit Knowledge Bases'),\n })\n\n registerTool('thorbit_kb_source_status', {\n title: 'Read Thorbit KB Source Status',\n description: 'Poll ingestion status for source public IDs returned by Thorbit KB ingestion tools.',\n inputSchema: ThorbitKbSourceStatusInputSchema,\n annotations: readOnlyAnnotations('Read Thorbit KB Source Status'),\n })\n\n registerTool('thorbit_kb_ingest_url', {\n title: 'Ingest URL Into Thorbit KB',\n description: 'Extract one public URL through MCP Scraper, clean the content, submit it to Thorbit, and vectorize it into the selected knowledge base.',\n inputSchema: ThorbitKbIngestUrlInputSchema,\n annotations: ingestAnnotations('Ingest URL Into Thorbit KB', true),\n })\n\n registerTool('thorbit_kb_ingest_site', {\n title: 'Ingest Website Into Thorbit KB',\n description: 'Map a website through MCP Scraper, extract selected pages, submit each page to Thorbit, and vectorize them into the selected knowledge base.',\n inputSchema: ThorbitKbIngestSiteInputSchema,\n annotations: ingestAnnotations('Ingest Website Into Thorbit KB', true),\n })\n\n registerTool('thorbit_kb_ingest_youtube', {\n title: 'Ingest YouTube Into Thorbit KB',\n description: 'Transcribe a YouTube video through MCP Scraper, preserve timestamp chunks when available, and vectorize the transcript into Thorbit KB.',\n inputSchema: ThorbitKbIngestYoutubeInputSchema,\n annotations: ingestAnnotations('Ingest YouTube Into Thorbit KB', true),\n })\n\n registerTool('thorbit_kb_ingest_text', {\n title: 'Ingest Text Into Thorbit KB',\n description: 'Submit provided text or Markdown directly to Thorbit and vectorize it into the selected knowledge base.',\n inputSchema: ThorbitKbIngestTextInputSchema,\n annotations: ingestAnnotations('Ingest Text Into Thorbit KB', false),\n })\n\n registerTool('thorbit_kb_search', {\n title: 'Search Thorbit Knowledge Base',\n description: 'Search Thorbit KB content with citation-ready chunks. Use when the user needs source-backed snippets or evidence.',\n inputSchema: ThorbitKbSearchInputSchema,\n annotations: readOnlyAnnotations('Search Thorbit Knowledge Base'),\n })\n\n registerTool('thorbit_kb_ask', {\n title: 'Ask Thorbit Knowledge Base',\n description: 'Answer a question using only retrieved Thorbit KB context. Returns answer, citations, sufficiency, and retrieval strategy metadata.',\n inputSchema: ThorbitKbAskInputSchema,\n annotations: readOnlyAnnotations('Ask Thorbit Knowledge Base', false),\n })\n\n return server\n}\n","import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js'\nimport type { ThorbitKnowledgeBaseMcpEnvelope } from './thorbit-kb-api-client.js'\nimport type { ThorbitKnowledgeBaseMcpToolName } from './thorbit-kb-mcp-tool-names.js'\n\nfunction summarizeResult(toolName: ThorbitKnowledgeBaseMcpToolName, result: unknown): string {\n if (toolName === 'thorbit_kb_create' && result && typeof result === 'object' && 'knowledgeBase' in result) {\n const kb = result.knowledgeBase as { name?: unknown; publicId?: unknown }\n return `Created Thorbit knowledge base ${String(kb.name ?? kb.publicId ?? '')}.`\n }\n if (toolName === 'thorbit_kb_list' && result && typeof result === 'object' && 'knowledgeBases' in result) {\n const count = Array.isArray(result.knowledgeBases) ? result.knowledgeBases.length : 0\n return `Found ${count} Thorbit knowledge base${count === 1 ? '' : 's'}.`\n }\n if (toolName.startsWith('thorbit_kb_ingest')) return 'Knowledge-base ingestion completed. Check structuredContent for source receipts.'\n if (toolName === 'thorbit_kb_source_status') return 'Source status returned. Check structuredContent for details.'\n if (toolName === 'thorbit_kb_search') return 'Knowledge-base search completed. Check structuredContent for results and citations.'\n if (toolName === 'thorbit_kb_ask') return 'Knowledge-base answer generated. Check structuredContent for citations and strategy.'\n return 'Thorbit knowledge-base tool completed.'\n}\n\nexport function formatThorbitKbMcpToolResult(\n toolName: ThorbitKnowledgeBaseMcpToolName,\n envelope: ThorbitKnowledgeBaseMcpEnvelope,\n): CallToolResult {\n if (!envelope.ok) {\n return {\n isError: true,\n content: [{\n type: 'text',\n text: `${envelope.error.code}: ${envelope.error.message}`,\n }],\n structuredContent: envelope,\n }\n }\n\n return {\n content: [{\n type: 'text',\n text: summarizeResult(toolName, envelope.result),\n }],\n structuredContent: envelope.result as Record<string, unknown>,\n }\n}\n","import { z } from 'zod'\n\nconst MetadataSchema = z.record(z.string(), z.unknown())\n\nexport const ThorbitKbCreateInputSchema = {\n name: z.string().min(1).max(255).describe('Name for the new Thorbit knowledge base.'),\n description: z.string().max(2000).optional().describe('Optional description for the new knowledge base.'),\n projectPublicId: z.string().min(1).optional().describe('Optional Thorbit project public ID. Omit to create an org-level knowledge base.'),\n folder: z.string().min(1).max(128).optional().describe('Optional organizational folder, such as research or domains.'),\n}\n\nexport const ThorbitKbListInputSchema = {\n projectPublicId: z.string().min(1).optional().describe('Optional Thorbit project public ID used to narrow knowledge-base listing.'),\n includeGlobal: z.boolean().default(true).describe('Include org-level/global knowledge bases. Default true.'),\n limit: z.number().int().min(1).max(100).default(50).describe('Maximum knowledge bases to return.'),\n}\n\nexport const ThorbitKbSourceStatusInputSchema = {\n sourcePublicIds: z.array(z.string().min(1)).min(1).max(100).describe('Source public IDs returned by Thorbit KB ingestion tools.'),\n}\n\nexport const ThorbitKbIngestUrlInputSchema = {\n knowledgeBasePublicId: z.string().min(1).describe('Target Thorbit knowledge-base public ID.'),\n url: z.string().url().describe('Public URL to extract through MCP Scraper and ingest into Thorbit.'),\n title: z.string().min(1).max(512).optional().describe('Optional title override. Provider title is used when omitted.'),\n mode: z.enum(['append']).default('append').describe('Append a new source version. Refresh mode is intentionally not enabled in V1.'),\n maxCharacters: z.number().int().min(500).max(500000).optional().describe('Optional cap before chunking/vectorization.'),\n metadata: MetadataSchema.optional().describe('Optional metadata stored on the KB source.'),\n}\n\nexport const ThorbitKbIngestSiteInputSchema = {\n knowledgeBasePublicId: z.string().min(1).describe('Target Thorbit knowledge-base public ID.'),\n startUrl: z.string().url().describe('Website start URL. Thorbit maps URLs through MCP Scraper, then ingests selected pages.'),\n includePatterns: z.array(z.string().min(1)).max(20).optional().describe('Optional regex or substring patterns that a mapped URL must match.'),\n excludePatterns: z.array(z.string().min(1)).max(20).optional().describe('Optional regex or substring patterns that remove mapped URLs.'),\n maxPages: z.number().int().min(1).max(100).default(25).describe('Maximum pages to ingest. Default 25, hard cap 100.'),\n mode: z.enum(['append']).default('append').describe('Append source versions. Refresh mode is intentionally not enabled in V1.'),\n metadata: MetadataSchema.optional().describe('Optional metadata stored on each KB source.'),\n}\n\nexport const ThorbitKbIngestYoutubeInputSchema = {\n knowledgeBasePublicId: z.string().min(1).describe('Target Thorbit knowledge-base public ID.'),\n videoUrl: z.string().url().describe('YouTube video URL. Thorbit transcribes through MCP Scraper and vectorizes transcript chunks.'),\n title: z.string().min(1).max(512).optional().describe('Optional title override.'),\n mode: z.enum(['append']).default('append').describe('Append a new source version.'),\n preserveTimestamps: z.boolean().default(true).describe('Store transcript timestamps on chunks when MCP Scraper returns them.'),\n metadata: MetadataSchema.optional().describe('Optional metadata stored on the KB source.'),\n}\n\nexport const ThorbitKbIngestTextInputSchema = {\n knowledgeBasePublicId: z.string().min(1).describe('Target Thorbit knowledge-base public ID.'),\n title: z.string().min(1).max(512).describe('Source title shown in KB citations.'),\n content: z.string().min(1).max(500000).describe('Text or Markdown to chunk, embed, and ingest.'),\n sourceUrl: z.string().url().optional().describe('Optional canonical source URL for citations.'),\n sourceType: z.enum(['manual', 'note', 'markdown']).default('manual').describe('Caller-facing source type. Thorbit stores note/markdown as manual sources in V1.'),\n metadata: MetadataSchema.optional().describe('Optional metadata stored on the KB source.'),\n}\n\nexport const ThorbitKbSearchInputSchema = {\n query: z.string().min(1).max(4000).describe('Search query. Use the user question or a focused retrieval query.'),\n knowledgeBasePublicId: z.string().min(1).optional().describe('Optional target KB. Omit to search visible KBs.'),\n projectPublicId: z.string().min(1).optional().describe('Optional project scope when no KB is specified.'),\n limit: z.number().int().min(1).max(20).default(5).describe('Maximum chunks to return.'),\n includeEntities: z.boolean().default(false).describe('Reserved for entity-rich responses.'),\n searchMode: z.enum(['smart', 'hybrid']).default('smart').describe('smart uses Thorbit intent/rerank retrieval; hybrid uses ANN plus FTS.'),\n}\n\nexport const ThorbitKbAskInputSchema = {\n question: z.string().min(1).max(8000).describe('Question to answer using Thorbit KB context only.'),\n knowledgeBasePublicId: z.string().min(1).optional().describe('Optional target KB. Omit to answer over visible KBs.'),\n projectPublicId: z.string().min(1).optional().describe('Optional project scope when no KB is specified.'),\n answerStyle: z.enum(['concise', 'detailed', 'extractive']).default('concise').describe('Use extractive to return source excerpts without an LLM answer.'),\n limit: z.number().int().min(1).max(20).default(8).describe('Maximum retrieved chunks used for the answer.'),\n requireCitations: z.boolean().default(true).describe('Keep true for grounded answers with citation arrays.'),\n}\n\nexport const ThorbitKnowledgeBaseMcpToolInputSchemas = {\n thorbit_kb_create: ThorbitKbCreateInputSchema,\n thorbit_kb_list: ThorbitKbListInputSchema,\n thorbit_kb_source_status: ThorbitKbSourceStatusInputSchema,\n thorbit_kb_ingest_url: ThorbitKbIngestUrlInputSchema,\n thorbit_kb_ingest_site: ThorbitKbIngestSiteInputSchema,\n thorbit_kb_ingest_youtube: ThorbitKbIngestYoutubeInputSchema,\n thorbit_kb_ingest_text: ThorbitKbIngestTextInputSchema,\n thorbit_kb_search: ThorbitKbSearchInputSchema,\n thorbit_kb_ask: ThorbitKbAskInputSchema,\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../bin/thorbit-kb-mcp.ts","../../src/thorbit-kb-api-client.ts","../../src/thorbit-kb-mcp-env.ts","../../src/thorbit-kb-mcp-server.ts","../../src/thorbit-kb-mcp-response-formatters.ts","../../src/thorbit-kb-mcp-tool-schemas.ts"],"sourcesContent":["import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { ThorbitKnowledgeBaseApiClient } from '../src/thorbit-kb-api-client.js'\nimport { resolveThorbitKbMcpEnv } from '../src/thorbit-kb-mcp-env.js'\nimport { buildThorbitKnowledgeBaseMcpServer } from '../src/thorbit-kb-mcp-server.js'\n\nasync function main() {\n const env = resolveThorbitKbMcpEnv()\n const client = new ThorbitKnowledgeBaseApiClient(env)\n const server = buildThorbitKnowledgeBaseMcpServer(client)\n await server.connect(new StdioServerTransport())\n}\n\nmain().catch(error => {\n process.stderr.write(`${error instanceof Error ? error.message : String(error)}\\n`)\n process.exit(1)\n})\n","import type { ThorbitKnowledgeBaseMcpToolName } from './thorbit-kb-mcp-tool-names.js'\n\nexport type ThorbitKnowledgeBaseMcpEnvelope =\n | {\n ok: true\n result: unknown\n warnings?: string[]\n requestId: string\n usage?: Record<string, unknown>\n }\n | {\n ok: false\n error: {\n code: string\n message: string\n details?: unknown\n }\n requestId: string\n }\n\nexport class ThorbitKnowledgeBaseApiClient {\n private readonly baseUrl: string\n private readonly apiKey: string\n\n constructor(options: { baseUrl: string; apiKey: string }) {\n this.baseUrl = options.baseUrl.replace(/\\/$/, '')\n this.apiKey = options.apiKey\n }\n\n async callTool(toolName: ThorbitKnowledgeBaseMcpToolName, input: unknown): Promise<ThorbitKnowledgeBaseMcpEnvelope> {\n const response = await fetch(`${this.baseUrl}/api/v1/mcp/knowledge-base/${toolName}`, {\n method: 'POST',\n headers: {\n 'x-thorbit-api-key': this.apiKey,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(input ?? {}),\n })\n\n const body = await response.json().catch(() => null) as ThorbitKnowledgeBaseMcpEnvelope | null\n if (body && typeof body === 'object' && 'ok' in body) return body\n\n return {\n ok: false,\n requestId: 'unavailable',\n error: {\n code: response.ok ? 'invalid_response' : `http_${response.status}`,\n message: response.ok ? 'Thorbit returned an invalid MCP response' : `Thorbit API request failed with HTTP ${response.status}`,\n },\n }\n }\n}\n","import { readFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\n\nexport type ThorbitKbMcpEnv = {\n apiKey: string\n baseUrl: string\n}\n\nfunction readApiKeyFile(): string | undefined {\n const explicitPath = process.env.THORBIT_KB_MCP_KEY_PATH?.trim()\n const paths = [explicitPath, join(homedir(), '.thorbit-kb-mcp-key')].filter(Boolean) as string[]\n for (const path of paths) {\n try {\n const value = readFileSync(path, 'utf8').trim()\n if (value) return value\n } catch {\n continue\n }\n }\n return undefined\n}\n\nexport function resolveThorbitKbMcpEnv(): ThorbitKbMcpEnv {\n const apiKey = (\n process.env.THORBIT_API_KEY ||\n process.env.THORBIT_MCP_API_KEY ||\n process.env.THORBIT_KB_MCP_API_KEY ||\n readApiKeyFile()\n )?.trim()\n\n if (!apiKey) {\n throw new Error('THORBIT_API_KEY, THORBIT_MCP_API_KEY, or ~/.thorbit-kb-mcp-key is required')\n }\n\n return {\n apiKey,\n baseUrl: (process.env.THORBIT_BASE_URL || process.env.THORBIT_KB_MCP_BASE_URL || 'https://thorbit.ai').trim(),\n }\n}\n","import { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { ToolAnnotations } from '@modelcontextprotocol/sdk/types.js'\nimport type { ZodRawShape } from 'zod'\nimport type { ThorbitKnowledgeBaseApiClient, ThorbitKnowledgeBaseMcpEnvelope } from './thorbit-kb-api-client.js'\nimport { formatThorbitKbMcpToolResult } from './thorbit-kb-mcp-response-formatters.js'\nimport {\n ThorbitKbAskInputSchema,\n ThorbitKbCreateInputSchema,\n ThorbitKbIngestSiteInputSchema,\n ThorbitKbIngestTextInputSchema,\n ThorbitKbIngestUrlInputSchema,\n ThorbitKbIngestYoutubeInputSchema,\n ThorbitKbListInputSchema,\n ThorbitKbSearchInputSchema,\n ThorbitKbSourceStatusInputSchema,\n} from './thorbit-kb-mcp-tool-schemas.js'\nimport type { ThorbitKnowledgeBaseMcpToolName } from './thorbit-kb-mcp-tool-names.js'\n\nconst VERSION = '0.2.8'\n\ntype ThorbitKbToolConfig<InputArgs extends ZodRawShape> = {\n title: string\n description: string\n inputSchema: InputArgs\n annotations: ToolAnnotations\n}\n\nfunction readOnlyAnnotations(title: string, idempotent = true) {\n return {\n title,\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: idempotent,\n openWorldHint: false,\n }\n}\n\nfunction ingestAnnotations(title: string, openWorldHint: boolean) {\n return {\n title,\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint,\n }\n}\n\nexport const SERVER_INSTRUCTIONS = [\n '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.',\n '',\n '## Set up a knowledge base',\n '- New knowledge base -> **thorbit_kb_create**. Org-level by default; pass projectPublicId to scope it to one project.',\n '- Find an existing one\\'s public ID -> **thorbit_kb_list** (needed before ingesting/searching if you don\\'t already have it).',\n '',\n '## Ingest content',\n '- One web page -> **thorbit_kb_ingest_url** (MCP Scraper extract, up to 500,000 chars before chunking).',\n '- A whole site (mapped + filtered by include/excludePatterns) -> **thorbit_kb_ingest_site** (up to 100 pages, default 25).',\n '- A YouTube video (transcribed, timestamps preserved by default) -> **thorbit_kb_ingest_youtube**.',\n '- Raw text/Markdown you already have -> **thorbit_kb_ingest_text** (no scraping needed).',\n '- All ingestion is append-only in this version — there\\'s no refresh/re-ingest mode; re-ingesting a URL adds a new source version rather than replacing the old one.',\n '- Check on an ingest\\'s progress -> **thorbit_kb_source_status** with the sourcePublicIds it returned.',\n '',\n '## Query a knowledge base',\n '- Need citation-ready chunks yourself, not a synthesized answer -> **thorbit_kb_search**.',\n '- 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.',\n].join('\\n')\n\nexport type ThorbitKbCallTool = (\n toolName: ThorbitKnowledgeBaseMcpToolName,\n input: unknown,\n) => Promise<ThorbitKnowledgeBaseMcpEnvelope>\n\nexport type BuildThorbitKnowledgeBaseMcpServerOptions =\n | ThorbitKnowledgeBaseApiClient\n | { callTool: ThorbitKbCallTool }\n\nexport function buildThorbitKnowledgeBaseMcpServer(options: BuildThorbitKnowledgeBaseMcpServerOptions): McpServer {\n const callTool: ThorbitKbCallTool = (toolName, input) => options.callTool(toolName, input)\n const server = new McpServer({ name: 'thorbit-kb-mcp', version: VERSION }, { instructions: SERVER_INSTRUCTIONS })\n\n server.registerResource(\n 'knowledge-bases',\n 'thorbit-kb://knowledge-bases',\n {\n title: 'Thorbit Knowledge Bases',\n description: 'Knowledge bases visible to this Thorbit MCP API key.',\n mimeType: 'application/json',\n },\n async (uri) => {\n const envelope = await callTool('thorbit_kb_list', {})\n return { contents: [{ uri: uri.href, mimeType: 'application/json', text: JSON.stringify(envelope, null, 2) }] }\n },\n )\n\n server.registerResource(\n 'source-status',\n new ResourceTemplate('thorbit-kb://sources/{sourcePublicId}', { list: undefined }),\n {\n title: 'Thorbit KB Source Status',\n description: 'Status and metadata for one Thorbit knowledge-base source.',\n mimeType: 'application/json',\n },\n async (uri, variables) => {\n const sourcePublicId = Array.isArray(variables.sourcePublicId) ? variables.sourcePublicId[0] : variables.sourcePublicId\n const envelope = await callTool('thorbit_kb_source_status', { sourcePublicIds: [String(sourcePublicId)] })\n return { contents: [{ uri: uri.href, mimeType: 'application/json', text: JSON.stringify(envelope, null, 2) }] }\n },\n )\n\n function registerTool<T extends ThorbitKnowledgeBaseMcpToolName>(\n toolName: T,\n config: ThorbitKbToolConfig<ZodRawShape>,\n ): void {\n server.registerTool(toolName, config, async (input) => {\n const envelope = await callTool(toolName, input)\n return formatThorbitKbMcpToolResult(toolName, envelope)\n })\n }\n\n registerTool('thorbit_kb_create', {\n title: 'Create Thorbit Knowledge Base',\n 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.',\n inputSchema: ThorbitKbCreateInputSchema,\n annotations: ingestAnnotations('Create Thorbit Knowledge Base', false),\n })\n\n registerTool('thorbit_kb_list', {\n title: 'List Thorbit Knowledge Bases',\n 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 — every ingest tool needs one (search/ask can omit it to query all visible KBs instead).',\n inputSchema: ThorbitKbListInputSchema,\n annotations: readOnlyAnnotations('List Thorbit Knowledge Bases'),\n })\n\n registerTool('thorbit_kb_source_status', {\n title: 'Read Thorbit KB Source Status',\n description: 'Poll ingestion status for source public IDs returned by any thorbit_kb_ingest_* tool — the only way to check whether an ingest finished, since the ingest tools may return before vectorization completes.',\n inputSchema: ThorbitKbSourceStatusInputSchema,\n annotations: readOnlyAnnotations('Read Thorbit KB Source Status'),\n })\n\n registerTool('thorbit_kb_ingest_url', {\n title: 'Ingest URL Into Thorbit KB',\n 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 the same URL adds a new source version rather than replacing the prior one — there is no refresh mode in this version.',\n inputSchema: ThorbitKbIngestUrlInputSchema,\n annotations: ingestAnnotations('Ingest URL Into Thorbit KB', true),\n })\n\n registerTool('thorbit_kb_ingest_site', {\n title: 'Ingest Website Into Thorbit KB',\n description: 'Map a website through MCP Scraper, extract selected pages (up to 100, default 25, filterable via includePatterns/excludePatterns), and vectorize each into a knowledge base. For a single known page instead of crawling a site, use thorbit_kb_ingest_url — cheaper and faster. Append-only, same as thorbit_kb_ingest_url.',\n inputSchema: ThorbitKbIngestSiteInputSchema,\n annotations: ingestAnnotations('Ingest Website Into Thorbit KB', true),\n })\n\n registerTool('thorbit_kb_ingest_youtube', {\n title: 'Ingest YouTube Into Thorbit KB',\n description: 'Transcribe a YouTube video through MCP Scraper and vectorize the transcript (timestamp chunks preserved by default) into a knowledge base. For web pages or raw text instead of video, use thorbit_kb_ingest_url or thorbit_kb_ingest_text.',\n inputSchema: ThorbitKbIngestYoutubeInputSchema,\n annotations: ingestAnnotations('Ingest YouTube Into Thorbit KB', true),\n })\n\n registerTool('thorbit_kb_ingest_text', {\n title: 'Ingest Text Into Thorbit KB',\n description: 'Submit text or Markdown you already have directly into a knowledge base — no scraping involved. Use this instead of thorbit_kb_ingest_url when you already have the content in hand rather than a URL to fetch.',\n inputSchema: ThorbitKbIngestTextInputSchema,\n annotations: ingestAnnotations('Ingest Text Into Thorbit KB', false),\n })\n\n registerTool('thorbit_kb_search', {\n title: 'Search Thorbit Knowledge Base',\n description: 'Search knowledge-base content and get citation-ready chunks back directly, without a synthesized answer. Use this instead of thorbit_kb_ask when you want to reason over the raw retrieved passages yourself. Omit knowledgeBasePublicId to search all KBs visible to this key.',\n inputSchema: ThorbitKbSearchInputSchema,\n annotations: readOnlyAnnotations('Search Thorbit Knowledge Base'),\n })\n\n registerTool('thorbit_kb_ask', {\n title: 'Ask Thorbit Knowledge Base',\n description: 'Answer a question using ONLY retrieved knowledge-base context — returns the answer, citations, sufficiency, and retrieval metadata. Set answerStyle:\"extractive\" for source excerpts without an LLM-written answer. Use thorbit_kb_search instead when you want the raw chunks rather than a synthesized answer.',\n inputSchema: ThorbitKbAskInputSchema,\n annotations: readOnlyAnnotations('Ask Thorbit Knowledge Base', false),\n })\n\n return server\n}\n","import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js'\nimport type { ThorbitKnowledgeBaseMcpEnvelope } from './thorbit-kb-api-client.js'\nimport type { ThorbitKnowledgeBaseMcpToolName } from './thorbit-kb-mcp-tool-names.js'\n\nfunction summarizeResult(toolName: ThorbitKnowledgeBaseMcpToolName, result: unknown): string {\n if (toolName === 'thorbit_kb_create' && result && typeof result === 'object' && 'knowledgeBase' in result) {\n const kb = result.knowledgeBase as { name?: unknown; publicId?: unknown }\n return `Created Thorbit knowledge base ${String(kb.name ?? kb.publicId ?? '')}.`\n }\n if (toolName === 'thorbit_kb_list' && result && typeof result === 'object' && 'knowledgeBases' in result) {\n const count = Array.isArray(result.knowledgeBases) ? result.knowledgeBases.length : 0\n return `Found ${count} Thorbit knowledge base${count === 1 ? '' : 's'}.`\n }\n if (toolName.startsWith('thorbit_kb_ingest')) return 'Knowledge-base ingestion completed. Check structuredContent for source receipts.'\n if (toolName === 'thorbit_kb_source_status') return 'Source status returned. Check structuredContent for details.'\n if (toolName === 'thorbit_kb_search') return 'Knowledge-base search completed. Check structuredContent for results and citations.'\n if (toolName === 'thorbit_kb_ask') return 'Knowledge-base answer generated. Check structuredContent for citations and strategy.'\n return 'Thorbit knowledge-base tool completed.'\n}\n\nexport function formatThorbitKbMcpToolResult(\n toolName: ThorbitKnowledgeBaseMcpToolName,\n envelope: ThorbitKnowledgeBaseMcpEnvelope,\n): CallToolResult {\n if (!envelope.ok) {\n return {\n isError: true,\n content: [{\n type: 'text',\n text: `${envelope.error.code}: ${envelope.error.message}`,\n }],\n structuredContent: envelope,\n }\n }\n\n return {\n content: [{\n type: 'text',\n text: summarizeResult(toolName, envelope.result),\n }],\n structuredContent: envelope.result as Record<string, unknown>,\n }\n}\n","import { z } from 'zod'\n\nconst MetadataSchema = z.record(z.string(), z.unknown())\n\nexport const ThorbitKbCreateInputSchema = {\n name: z.string().min(1).max(255).describe('Name for the new Thorbit knowledge base.'),\n description: z.string().max(2000).optional().describe('Optional description for the new knowledge base.'),\n projectPublicId: z.string().min(1).optional().describe('Optional Thorbit project public ID. Omit to create an org-level knowledge base.'),\n folder: z.string().min(1).max(128).optional().describe('Optional organizational folder, such as research or domains.'),\n}\n\nexport const ThorbitKbListInputSchema = {\n projectPublicId: z.string().min(1).optional().describe('Optional Thorbit project public ID used to narrow knowledge-base listing.'),\n includeGlobal: z.boolean().default(true).describe('Include org-level/global knowledge bases. Default true.'),\n limit: z.number().int().min(1).max(100).default(50).describe('Maximum knowledge bases to return.'),\n}\n\nexport const ThorbitKbSourceStatusInputSchema = {\n sourcePublicIds: z.array(z.string().min(1)).min(1).max(100).describe('Source public IDs returned by Thorbit KB ingestion tools.'),\n}\n\nexport const ThorbitKbIngestUrlInputSchema = {\n knowledgeBasePublicId: z.string().min(1).describe('Target Thorbit knowledge-base public ID.'),\n url: z.string().url().describe('Public URL to extract through MCP Scraper and ingest into Thorbit.'),\n title: z.string().min(1).max(512).optional().describe('Optional title override. Provider title is used when omitted.'),\n mode: z.enum(['append']).default('append').describe('Append a new source version. Refresh mode is intentionally not enabled in V1.'),\n maxCharacters: z.number().int().min(500).max(500000).optional().describe('Optional cap before chunking/vectorization.'),\n metadata: MetadataSchema.optional().describe('Optional metadata stored on the KB source.'),\n}\n\nexport const ThorbitKbIngestSiteInputSchema = {\n knowledgeBasePublicId: z.string().min(1).describe('Target Thorbit knowledge-base public ID.'),\n startUrl: z.string().url().describe('Website start URL. Thorbit maps URLs through MCP Scraper, then ingests selected pages.'),\n includePatterns: z.array(z.string().min(1)).max(20).optional().describe('Optional regex or substring patterns that a mapped URL must match.'),\n excludePatterns: z.array(z.string().min(1)).max(20).optional().describe('Optional regex or substring patterns that remove mapped URLs.'),\n maxPages: z.number().int().min(1).max(100).default(25).describe('Maximum pages to ingest. Default 25, hard cap 100.'),\n mode: z.enum(['append']).default('append').describe('Append source versions. Refresh mode is intentionally not enabled in V1.'),\n metadata: MetadataSchema.optional().describe('Optional metadata stored on each KB source.'),\n}\n\nexport const ThorbitKbIngestYoutubeInputSchema = {\n knowledgeBasePublicId: z.string().min(1).describe('Target Thorbit knowledge-base public ID.'),\n videoUrl: z.string().url().describe('YouTube video URL. Thorbit transcribes through MCP Scraper and vectorizes transcript chunks.'),\n title: z.string().min(1).max(512).optional().describe('Optional title override.'),\n mode: z.enum(['append']).default('append').describe('Append a new source version.'),\n preserveTimestamps: z.boolean().default(true).describe('Store transcript timestamps on chunks when MCP Scraper returns them.'),\n metadata: MetadataSchema.optional().describe('Optional metadata stored on the KB source.'),\n}\n\nexport const ThorbitKbIngestTextInputSchema = {\n knowledgeBasePublicId: z.string().min(1).describe('Target Thorbit knowledge-base public ID.'),\n title: z.string().min(1).max(512).describe('Source title shown in KB citations.'),\n content: z.string().min(1).max(500000).describe('Text or Markdown to chunk, embed, and ingest.'),\n sourceUrl: z.string().url().optional().describe('Optional canonical source URL for citations.'),\n sourceType: z.enum(['manual', 'note', 'markdown']).default('manual').describe('Caller-facing source type. Thorbit stores note/markdown as manual sources in V1.'),\n metadata: MetadataSchema.optional().describe('Optional metadata stored on the KB source.'),\n}\n\nexport const ThorbitKbSearchInputSchema = {\n query: z.string().min(1).max(4000).describe('Search query. Use the user question or a focused retrieval query.'),\n knowledgeBasePublicId: z.string().min(1).optional().describe('Optional target KB. Omit to search visible KBs.'),\n projectPublicId: z.string().min(1).optional().describe('Optional project scope when no KB is specified.'),\n limit: z.number().int().min(1).max(20).default(5).describe('Maximum chunks to return.'),\n includeEntities: z.boolean().default(false).describe('Reserved for entity-rich responses.'),\n searchMode: z.enum(['smart', 'hybrid']).default('smart').describe('smart uses Thorbit intent/rerank retrieval; hybrid uses ANN plus FTS.'),\n}\n\nexport const ThorbitKbAskInputSchema = {\n question: z.string().min(1).max(8000).describe('Question to answer using Thorbit KB context only.'),\n knowledgeBasePublicId: z.string().min(1).optional().describe('Optional target KB. Omit to answer over visible KBs.'),\n projectPublicId: z.string().min(1).optional().describe('Optional project scope when no KB is specified.'),\n answerStyle: z.enum(['concise', 'detailed', 'extractive']).default('concise').describe('Use extractive to return source excerpts without an LLM answer.'),\n limit: z.number().int().min(1).max(20).default(8).describe('Maximum retrieved chunks used for the answer.'),\n requireCitations: z.boolean().default(true).describe('Keep true for grounded answers with citation arrays.'),\n}\n\nexport const ThorbitKnowledgeBaseMcpToolInputSchemas = {\n thorbit_kb_create: ThorbitKbCreateInputSchema,\n thorbit_kb_list: ThorbitKbListInputSchema,\n thorbit_kb_source_status: ThorbitKbSourceStatusInputSchema,\n thorbit_kb_ingest_url: ThorbitKbIngestUrlInputSchema,\n thorbit_kb_ingest_site: ThorbitKbIngestSiteInputSchema,\n thorbit_kb_ingest_youtube: ThorbitKbIngestYoutubeInputSchema,\n thorbit_kb_ingest_text: ThorbitKbIngestTextInputSchema,\n thorbit_kb_search: ThorbitKbSearchInputSchema,\n thorbit_kb_ask: ThorbitKbAskInputSchema,\n}\n"],"mappings":"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","names":[]}
package/dist/index.cjs CHANGED
@@ -186,7 +186,7 @@ var ThorbitKnowledgeBaseMcpToolInputSchemas = {
186
186
  };
187
187
 
188
188
  // src/thorbit-kb-mcp-server.ts
189
- var VERSION = "0.2.7";
189
+ var VERSION = "0.2.8";
190
190
  function readOnlyAnnotations(title, idempotent = true) {
191
191
  return {
192
192
  title,
@@ -205,9 +205,28 @@ function ingestAnnotations(title, openWorldHint) {
205
205
  openWorldHint
206
206
  };
207
207
  }
208
+ var SERVER_INSTRUCTIONS = [
209
+ "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.",
210
+ "",
211
+ "## Set up a knowledge base",
212
+ "- New knowledge base -> **thorbit_kb_create**. Org-level by default; pass projectPublicId to scope it to one project.",
213
+ "- Find an existing one's public ID -> **thorbit_kb_list** (needed before ingesting/searching if you don't already have it).",
214
+ "",
215
+ "## Ingest content",
216
+ "- One web page -> **thorbit_kb_ingest_url** (MCP Scraper extract, up to 500,000 chars before chunking).",
217
+ "- A whole site (mapped + filtered by include/excludePatterns) -> **thorbit_kb_ingest_site** (up to 100 pages, default 25).",
218
+ "- A YouTube video (transcribed, timestamps preserved by default) -> **thorbit_kb_ingest_youtube**.",
219
+ "- Raw text/Markdown you already have -> **thorbit_kb_ingest_text** (no scraping needed).",
220
+ "- 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.",
221
+ "- Check on an ingest's progress -> **thorbit_kb_source_status** with the sourcePublicIds it returned.",
222
+ "",
223
+ "## Query a knowledge base",
224
+ "- Need citation-ready chunks yourself, not a synthesized answer -> **thorbit_kb_search**.",
225
+ '- 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.'
226
+ ].join("\n");
208
227
  function buildThorbitKnowledgeBaseMcpServer(options) {
209
228
  const callTool = (toolName, input) => options.callTool(toolName, input);
210
- const server = new import_mcp.McpServer({ name: "thorbit-kb-mcp", version: VERSION });
229
+ const server = new import_mcp.McpServer({ name: "thorbit-kb-mcp", version: VERSION }, { instructions: SERVER_INSTRUCTIONS });
211
230
  server.registerResource(
212
231
  "knowledge-bases",
213
232
  "thorbit-kb://knowledge-bases",
@@ -243,55 +262,55 @@ function buildThorbitKnowledgeBaseMcpServer(options) {
243
262
  }
244
263
  registerTool("thorbit_kb_create", {
245
264
  title: "Create Thorbit Knowledge Base",
246
- description: "Create a new Thorbit vector-backed knowledge base for MCP ingestion, smart RAG search, citations, and entity extraction.",
265
+ 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
266
  inputSchema: ThorbitKbCreateInputSchema,
248
267
  annotations: ingestAnnotations("Create Thorbit Knowledge Base", false)
249
268
  });
250
269
  registerTool("thorbit_kb_list", {
251
270
  title: "List Thorbit Knowledge Bases",
252
- description: "List Thorbit knowledge bases visible to this API key. Use before ingestion/search when the target KB public ID is unknown.",
271
+ 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
272
  inputSchema: ThorbitKbListInputSchema,
254
273
  annotations: readOnlyAnnotations("List Thorbit Knowledge Bases")
255
274
  });
256
275
  registerTool("thorbit_kb_source_status", {
257
276
  title: "Read Thorbit KB Source Status",
258
- description: "Poll ingestion status for source public IDs returned by Thorbit KB ingestion tools.",
277
+ description: "Poll ingestion status for source public IDs returned by any thorbit_kb_ingest_* tool \u2014 the only way to check whether an ingest finished, since the ingest tools may return before vectorization completes.",
259
278
  inputSchema: ThorbitKbSourceStatusInputSchema,
260
279
  annotations: readOnlyAnnotations("Read Thorbit KB Source Status")
261
280
  });
262
281
  registerTool("thorbit_kb_ingest_url", {
263
282
  title: "Ingest URL Into Thorbit KB",
264
- description: "Extract one public URL through MCP Scraper, clean the content, submit it to Thorbit, and vectorize it into the selected knowledge base.",
283
+ 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 the same URL adds a new source version rather than replacing the prior one \u2014 there is no refresh mode in this version.",
265
284
  inputSchema: ThorbitKbIngestUrlInputSchema,
266
285
  annotations: ingestAnnotations("Ingest URL Into Thorbit KB", true)
267
286
  });
268
287
  registerTool("thorbit_kb_ingest_site", {
269
288
  title: "Ingest Website Into Thorbit KB",
270
- description: "Map a website through MCP Scraper, extract selected pages, submit each page to Thorbit, and vectorize them into the selected knowledge base.",
289
+ description: "Map a website through MCP Scraper, extract selected pages (up to 100, default 25, filterable via includePatterns/excludePatterns), and vectorize each into a knowledge base. For a single known page instead of crawling a site, use thorbit_kb_ingest_url \u2014 cheaper and faster. Append-only, same as thorbit_kb_ingest_url.",
271
290
  inputSchema: ThorbitKbIngestSiteInputSchema,
272
291
  annotations: ingestAnnotations("Ingest Website Into Thorbit KB", true)
273
292
  });
274
293
  registerTool("thorbit_kb_ingest_youtube", {
275
294
  title: "Ingest YouTube Into Thorbit KB",
276
- description: "Transcribe a YouTube video through MCP Scraper, preserve timestamp chunks when available, and vectorize the transcript into Thorbit KB.",
295
+ description: "Transcribe a YouTube video through MCP Scraper and vectorize the transcript (timestamp chunks preserved by default) into a knowledge base. For web pages or raw text instead of video, use thorbit_kb_ingest_url or thorbit_kb_ingest_text.",
277
296
  inputSchema: ThorbitKbIngestYoutubeInputSchema,
278
297
  annotations: ingestAnnotations("Ingest YouTube Into Thorbit KB", true)
279
298
  });
280
299
  registerTool("thorbit_kb_ingest_text", {
281
300
  title: "Ingest Text Into Thorbit KB",
282
- description: "Submit provided text or Markdown directly to Thorbit and vectorize it into the selected knowledge base.",
301
+ description: "Submit text or Markdown you already have directly into a knowledge base \u2014 no scraping involved. Use this instead of thorbit_kb_ingest_url when you already have the content in hand rather than a URL to fetch.",
283
302
  inputSchema: ThorbitKbIngestTextInputSchema,
284
303
  annotations: ingestAnnotations("Ingest Text Into Thorbit KB", false)
285
304
  });
286
305
  registerTool("thorbit_kb_search", {
287
306
  title: "Search Thorbit Knowledge Base",
288
- description: "Search Thorbit KB content with citation-ready chunks. Use when the user needs source-backed snippets or evidence.",
307
+ description: "Search knowledge-base content and get citation-ready chunks back directly, without a synthesized answer. Use this instead of thorbit_kb_ask when you want to reason over the raw retrieved passages yourself. Omit knowledgeBasePublicId to search all KBs visible to this key.",
289
308
  inputSchema: ThorbitKbSearchInputSchema,
290
309
  annotations: readOnlyAnnotations("Search Thorbit Knowledge Base")
291
310
  });
292
311
  registerTool("thorbit_kb_ask", {
293
312
  title: "Ask Thorbit Knowledge Base",
294
- description: "Answer a question using only retrieved Thorbit KB context. Returns answer, citations, sufficiency, and retrieval strategy metadata.",
313
+ description: 'Answer a question using ONLY retrieved knowledge-base context \u2014 returns the answer, citations, sufficiency, and retrieval metadata. Set answerStyle:"extractive" for source excerpts without an LLM-written answer. Use thorbit_kb_search instead when you want the raw chunks rather than a synthesized answer.',
295
314
  inputSchema: ThorbitKbAskInputSchema,
296
315
  annotations: readOnlyAnnotations("Ask Thorbit Knowledge Base", false)
297
316
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/thorbit-kb-api-client.ts","../src/thorbit-kb-mcp-server.ts","../src/thorbit-kb-mcp-response-formatters.ts","../src/thorbit-kb-mcp-tool-schemas.ts","../src/thorbit-kb-mcp-env.ts","../src/thorbit-kb-mcp-tool-names.ts"],"sourcesContent":["export { ThorbitKnowledgeBaseApiClient } from './thorbit-kb-api-client.js'\nexport { buildThorbitKnowledgeBaseMcpServer } from './thorbit-kb-mcp-server.js'\nexport { resolveThorbitKbMcpEnv } from './thorbit-kb-mcp-env.js'\nexport * from './thorbit-kb-mcp-tool-names.js'\nexport * from './thorbit-kb-mcp-tool-schemas.js'\n","import type { ThorbitKnowledgeBaseMcpToolName } from './thorbit-kb-mcp-tool-names.js'\n\nexport type ThorbitKnowledgeBaseMcpEnvelope =\n | {\n ok: true\n result: unknown\n warnings?: string[]\n requestId: string\n usage?: Record<string, unknown>\n }\n | {\n ok: false\n error: {\n code: string\n message: string\n details?: unknown\n }\n requestId: string\n }\n\nexport class ThorbitKnowledgeBaseApiClient {\n private readonly baseUrl: string\n private readonly apiKey: string\n\n constructor(options: { baseUrl: string; apiKey: string }) {\n this.baseUrl = options.baseUrl.replace(/\\/$/, '')\n this.apiKey = options.apiKey\n }\n\n async callTool(toolName: ThorbitKnowledgeBaseMcpToolName, input: unknown): Promise<ThorbitKnowledgeBaseMcpEnvelope> {\n const response = await fetch(`${this.baseUrl}/api/v1/mcp/knowledge-base/${toolName}`, {\n method: 'POST',\n headers: {\n 'x-thorbit-api-key': this.apiKey,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(input ?? {}),\n })\n\n const body = await response.json().catch(() => null) as ThorbitKnowledgeBaseMcpEnvelope | null\n if (body && typeof body === 'object' && 'ok' in body) return body\n\n return {\n ok: false,\n requestId: 'unavailable',\n error: {\n code: response.ok ? 'invalid_response' : `http_${response.status}`,\n message: response.ok ? 'Thorbit returned an invalid MCP response' : `Thorbit API request failed with HTTP ${response.status}`,\n },\n }\n }\n}\n","import { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { ToolAnnotations } from '@modelcontextprotocol/sdk/types.js'\nimport type { ZodRawShape } from 'zod'\nimport type { ThorbitKnowledgeBaseApiClient, ThorbitKnowledgeBaseMcpEnvelope } from './thorbit-kb-api-client.js'\nimport { formatThorbitKbMcpToolResult } from './thorbit-kb-mcp-response-formatters.js'\nimport {\n ThorbitKbAskInputSchema,\n ThorbitKbCreateInputSchema,\n ThorbitKbIngestSiteInputSchema,\n ThorbitKbIngestTextInputSchema,\n ThorbitKbIngestUrlInputSchema,\n ThorbitKbIngestYoutubeInputSchema,\n ThorbitKbListInputSchema,\n ThorbitKbSearchInputSchema,\n ThorbitKbSourceStatusInputSchema,\n} from './thorbit-kb-mcp-tool-schemas.js'\nimport type { ThorbitKnowledgeBaseMcpToolName } from './thorbit-kb-mcp-tool-names.js'\n\nconst VERSION = '0.2.7'\n\ntype ThorbitKbToolConfig<InputArgs extends ZodRawShape> = {\n title: string\n description: string\n inputSchema: InputArgs\n annotations: ToolAnnotations\n}\n\nfunction readOnlyAnnotations(title: string, idempotent = true) {\n return {\n title,\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: idempotent,\n openWorldHint: false,\n }\n}\n\nfunction ingestAnnotations(title: string, openWorldHint: boolean) {\n return {\n title,\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint,\n }\n}\n\nexport type ThorbitKbCallTool = (\n toolName: ThorbitKnowledgeBaseMcpToolName,\n input: unknown,\n) => Promise<ThorbitKnowledgeBaseMcpEnvelope>\n\nexport type BuildThorbitKnowledgeBaseMcpServerOptions =\n | ThorbitKnowledgeBaseApiClient\n | { callTool: ThorbitKbCallTool }\n\nexport function buildThorbitKnowledgeBaseMcpServer(options: BuildThorbitKnowledgeBaseMcpServerOptions): McpServer {\n const callTool: ThorbitKbCallTool = (toolName, input) => options.callTool(toolName, input)\n const server = new McpServer({ name: 'thorbit-kb-mcp', version: VERSION })\n\n server.registerResource(\n 'knowledge-bases',\n 'thorbit-kb://knowledge-bases',\n {\n title: 'Thorbit Knowledge Bases',\n description: 'Knowledge bases visible to this Thorbit MCP API key.',\n mimeType: 'application/json',\n },\n async (uri) => {\n const envelope = await callTool('thorbit_kb_list', {})\n return { contents: [{ uri: uri.href, mimeType: 'application/json', text: JSON.stringify(envelope, null, 2) }] }\n },\n )\n\n server.registerResource(\n 'source-status',\n new ResourceTemplate('thorbit-kb://sources/{sourcePublicId}', { list: undefined }),\n {\n title: 'Thorbit KB Source Status',\n description: 'Status and metadata for one Thorbit knowledge-base source.',\n mimeType: 'application/json',\n },\n async (uri, variables) => {\n const sourcePublicId = Array.isArray(variables.sourcePublicId) ? variables.sourcePublicId[0] : variables.sourcePublicId\n const envelope = await callTool('thorbit_kb_source_status', { sourcePublicIds: [String(sourcePublicId)] })\n return { contents: [{ uri: uri.href, mimeType: 'application/json', text: JSON.stringify(envelope, null, 2) }] }\n },\n )\n\n function registerTool<T extends ThorbitKnowledgeBaseMcpToolName>(\n toolName: T,\n config: ThorbitKbToolConfig<ZodRawShape>,\n ): void {\n server.registerTool(toolName, config, async (input) => {\n const envelope = await callTool(toolName, input)\n return formatThorbitKbMcpToolResult(toolName, envelope)\n })\n }\n\n registerTool('thorbit_kb_create', {\n title: 'Create Thorbit Knowledge Base',\n description: 'Create a new Thorbit vector-backed knowledge base for MCP ingestion, smart RAG search, citations, and entity extraction.',\n inputSchema: ThorbitKbCreateInputSchema,\n annotations: ingestAnnotations('Create Thorbit Knowledge Base', false),\n })\n\n registerTool('thorbit_kb_list', {\n title: 'List Thorbit Knowledge Bases',\n description: 'List Thorbit knowledge bases visible to this API key. Use before ingestion/search when the target KB public ID is unknown.',\n inputSchema: ThorbitKbListInputSchema,\n annotations: readOnlyAnnotations('List Thorbit Knowledge Bases'),\n })\n\n registerTool('thorbit_kb_source_status', {\n title: 'Read Thorbit KB Source Status',\n description: 'Poll ingestion status for source public IDs returned by Thorbit KB ingestion tools.',\n inputSchema: ThorbitKbSourceStatusInputSchema,\n annotations: readOnlyAnnotations('Read Thorbit KB Source Status'),\n })\n\n registerTool('thorbit_kb_ingest_url', {\n title: 'Ingest URL Into Thorbit KB',\n description: 'Extract one public URL through MCP Scraper, clean the content, submit it to Thorbit, and vectorize it into the selected knowledge base.',\n inputSchema: ThorbitKbIngestUrlInputSchema,\n annotations: ingestAnnotations('Ingest URL Into Thorbit KB', true),\n })\n\n registerTool('thorbit_kb_ingest_site', {\n title: 'Ingest Website Into Thorbit KB',\n description: 'Map a website through MCP Scraper, extract selected pages, submit each page to Thorbit, and vectorize them into the selected knowledge base.',\n inputSchema: ThorbitKbIngestSiteInputSchema,\n annotations: ingestAnnotations('Ingest Website Into Thorbit KB', true),\n })\n\n registerTool('thorbit_kb_ingest_youtube', {\n title: 'Ingest YouTube Into Thorbit KB',\n description: 'Transcribe a YouTube video through MCP Scraper, preserve timestamp chunks when available, and vectorize the transcript into Thorbit KB.',\n inputSchema: ThorbitKbIngestYoutubeInputSchema,\n annotations: ingestAnnotations('Ingest YouTube Into Thorbit KB', true),\n })\n\n registerTool('thorbit_kb_ingest_text', {\n title: 'Ingest Text Into Thorbit KB',\n description: 'Submit provided text or Markdown directly to Thorbit and vectorize it into the selected knowledge base.',\n inputSchema: ThorbitKbIngestTextInputSchema,\n annotations: ingestAnnotations('Ingest Text Into Thorbit KB', false),\n })\n\n registerTool('thorbit_kb_search', {\n title: 'Search Thorbit Knowledge Base',\n description: 'Search Thorbit KB content with citation-ready chunks. Use when the user needs source-backed snippets or evidence.',\n inputSchema: ThorbitKbSearchInputSchema,\n annotations: readOnlyAnnotations('Search Thorbit Knowledge Base'),\n })\n\n registerTool('thorbit_kb_ask', {\n title: 'Ask Thorbit Knowledge Base',\n description: 'Answer a question using only retrieved Thorbit KB context. Returns answer, citations, sufficiency, and retrieval strategy metadata.',\n inputSchema: ThorbitKbAskInputSchema,\n annotations: readOnlyAnnotations('Ask Thorbit Knowledge Base', false),\n })\n\n return server\n}\n","import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js'\nimport type { ThorbitKnowledgeBaseMcpEnvelope } from './thorbit-kb-api-client.js'\nimport type { ThorbitKnowledgeBaseMcpToolName } from './thorbit-kb-mcp-tool-names.js'\n\nfunction summarizeResult(toolName: ThorbitKnowledgeBaseMcpToolName, result: unknown): string {\n if (toolName === 'thorbit_kb_create' && result && typeof result === 'object' && 'knowledgeBase' in result) {\n const kb = result.knowledgeBase as { name?: unknown; publicId?: unknown }\n return `Created Thorbit knowledge base ${String(kb.name ?? kb.publicId ?? '')}.`\n }\n if (toolName === 'thorbit_kb_list' && result && typeof result === 'object' && 'knowledgeBases' in result) {\n const count = Array.isArray(result.knowledgeBases) ? result.knowledgeBases.length : 0\n return `Found ${count} Thorbit knowledge base${count === 1 ? '' : 's'}.`\n }\n if (toolName.startsWith('thorbit_kb_ingest')) return 'Knowledge-base ingestion completed. Check structuredContent for source receipts.'\n if (toolName === 'thorbit_kb_source_status') return 'Source status returned. Check structuredContent for details.'\n if (toolName === 'thorbit_kb_search') return 'Knowledge-base search completed. Check structuredContent for results and citations.'\n if (toolName === 'thorbit_kb_ask') return 'Knowledge-base answer generated. Check structuredContent for citations and strategy.'\n return 'Thorbit knowledge-base tool completed.'\n}\n\nexport function formatThorbitKbMcpToolResult(\n toolName: ThorbitKnowledgeBaseMcpToolName,\n envelope: ThorbitKnowledgeBaseMcpEnvelope,\n): CallToolResult {\n if (!envelope.ok) {\n return {\n isError: true,\n content: [{\n type: 'text',\n text: `${envelope.error.code}: ${envelope.error.message}`,\n }],\n structuredContent: envelope,\n }\n }\n\n return {\n content: [{\n type: 'text',\n text: summarizeResult(toolName, envelope.result),\n }],\n structuredContent: envelope.result as Record<string, unknown>,\n }\n}\n","import { z } from 'zod'\n\nconst MetadataSchema = z.record(z.string(), z.unknown())\n\nexport const ThorbitKbCreateInputSchema = {\n name: z.string().min(1).max(255).describe('Name for the new Thorbit knowledge base.'),\n description: z.string().max(2000).optional().describe('Optional description for the new knowledge base.'),\n projectPublicId: z.string().min(1).optional().describe('Optional Thorbit project public ID. Omit to create an org-level knowledge base.'),\n folder: z.string().min(1).max(128).optional().describe('Optional organizational folder, such as research or domains.'),\n}\n\nexport const ThorbitKbListInputSchema = {\n projectPublicId: z.string().min(1).optional().describe('Optional Thorbit project public ID used to narrow knowledge-base listing.'),\n includeGlobal: z.boolean().default(true).describe('Include org-level/global knowledge bases. Default true.'),\n limit: z.number().int().min(1).max(100).default(50).describe('Maximum knowledge bases to return.'),\n}\n\nexport const ThorbitKbSourceStatusInputSchema = {\n sourcePublicIds: z.array(z.string().min(1)).min(1).max(100).describe('Source public IDs returned by Thorbit KB ingestion tools.'),\n}\n\nexport const ThorbitKbIngestUrlInputSchema = {\n knowledgeBasePublicId: z.string().min(1).describe('Target Thorbit knowledge-base public ID.'),\n url: z.string().url().describe('Public URL to extract through MCP Scraper and ingest into Thorbit.'),\n title: z.string().min(1).max(512).optional().describe('Optional title override. Provider title is used when omitted.'),\n mode: z.enum(['append']).default('append').describe('Append a new source version. Refresh mode is intentionally not enabled in V1.'),\n maxCharacters: z.number().int().min(500).max(500000).optional().describe('Optional cap before chunking/vectorization.'),\n metadata: MetadataSchema.optional().describe('Optional metadata stored on the KB source.'),\n}\n\nexport const ThorbitKbIngestSiteInputSchema = {\n knowledgeBasePublicId: z.string().min(1).describe('Target Thorbit knowledge-base public ID.'),\n startUrl: z.string().url().describe('Website start URL. Thorbit maps URLs through MCP Scraper, then ingests selected pages.'),\n includePatterns: z.array(z.string().min(1)).max(20).optional().describe('Optional regex or substring patterns that a mapped URL must match.'),\n excludePatterns: z.array(z.string().min(1)).max(20).optional().describe('Optional regex or substring patterns that remove mapped URLs.'),\n maxPages: z.number().int().min(1).max(100).default(25).describe('Maximum pages to ingest. Default 25, hard cap 100.'),\n mode: z.enum(['append']).default('append').describe('Append source versions. Refresh mode is intentionally not enabled in V1.'),\n metadata: MetadataSchema.optional().describe('Optional metadata stored on each KB source.'),\n}\n\nexport const ThorbitKbIngestYoutubeInputSchema = {\n knowledgeBasePublicId: z.string().min(1).describe('Target Thorbit knowledge-base public ID.'),\n videoUrl: z.string().url().describe('YouTube video URL. Thorbit transcribes through MCP Scraper and vectorizes transcript chunks.'),\n title: z.string().min(1).max(512).optional().describe('Optional title override.'),\n mode: z.enum(['append']).default('append').describe('Append a new source version.'),\n preserveTimestamps: z.boolean().default(true).describe('Store transcript timestamps on chunks when MCP Scraper returns them.'),\n metadata: MetadataSchema.optional().describe('Optional metadata stored on the KB source.'),\n}\n\nexport const ThorbitKbIngestTextInputSchema = {\n knowledgeBasePublicId: z.string().min(1).describe('Target Thorbit knowledge-base public ID.'),\n title: z.string().min(1).max(512).describe('Source title shown in KB citations.'),\n content: z.string().min(1).max(500000).describe('Text or Markdown to chunk, embed, and ingest.'),\n sourceUrl: z.string().url().optional().describe('Optional canonical source URL for citations.'),\n sourceType: z.enum(['manual', 'note', 'markdown']).default('manual').describe('Caller-facing source type. Thorbit stores note/markdown as manual sources in V1.'),\n metadata: MetadataSchema.optional().describe('Optional metadata stored on the KB source.'),\n}\n\nexport const ThorbitKbSearchInputSchema = {\n query: z.string().min(1).max(4000).describe('Search query. Use the user question or a focused retrieval query.'),\n knowledgeBasePublicId: z.string().min(1).optional().describe('Optional target KB. Omit to search visible KBs.'),\n projectPublicId: z.string().min(1).optional().describe('Optional project scope when no KB is specified.'),\n limit: z.number().int().min(1).max(20).default(5).describe('Maximum chunks to return.'),\n includeEntities: z.boolean().default(false).describe('Reserved for entity-rich responses.'),\n searchMode: z.enum(['smart', 'hybrid']).default('smart').describe('smart uses Thorbit intent/rerank retrieval; hybrid uses ANN plus FTS.'),\n}\n\nexport const ThorbitKbAskInputSchema = {\n question: z.string().min(1).max(8000).describe('Question to answer using Thorbit KB context only.'),\n knowledgeBasePublicId: z.string().min(1).optional().describe('Optional target KB. Omit to answer over visible KBs.'),\n projectPublicId: z.string().min(1).optional().describe('Optional project scope when no KB is specified.'),\n answerStyle: z.enum(['concise', 'detailed', 'extractive']).default('concise').describe('Use extractive to return source excerpts without an LLM answer.'),\n limit: z.number().int().min(1).max(20).default(8).describe('Maximum retrieved chunks used for the answer.'),\n requireCitations: z.boolean().default(true).describe('Keep true for grounded answers with citation arrays.'),\n}\n\nexport const ThorbitKnowledgeBaseMcpToolInputSchemas = {\n thorbit_kb_create: ThorbitKbCreateInputSchema,\n thorbit_kb_list: ThorbitKbListInputSchema,\n thorbit_kb_source_status: ThorbitKbSourceStatusInputSchema,\n thorbit_kb_ingest_url: ThorbitKbIngestUrlInputSchema,\n thorbit_kb_ingest_site: ThorbitKbIngestSiteInputSchema,\n thorbit_kb_ingest_youtube: ThorbitKbIngestYoutubeInputSchema,\n thorbit_kb_ingest_text: ThorbitKbIngestTextInputSchema,\n thorbit_kb_search: ThorbitKbSearchInputSchema,\n thorbit_kb_ask: ThorbitKbAskInputSchema,\n}\n","import { readFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\n\nexport type ThorbitKbMcpEnv = {\n apiKey: string\n baseUrl: string\n}\n\nfunction readApiKeyFile(): string | undefined {\n const explicitPath = process.env.THORBIT_KB_MCP_KEY_PATH?.trim()\n const paths = [explicitPath, join(homedir(), '.thorbit-kb-mcp-key')].filter(Boolean) as string[]\n for (const path of paths) {\n try {\n const value = readFileSync(path, 'utf8').trim()\n if (value) return value\n } catch {\n continue\n }\n }\n return undefined\n}\n\nexport function resolveThorbitKbMcpEnv(): ThorbitKbMcpEnv {\n const apiKey = (\n process.env.THORBIT_API_KEY ||\n process.env.THORBIT_MCP_API_KEY ||\n process.env.THORBIT_KB_MCP_API_KEY ||\n readApiKeyFile()\n )?.trim()\n\n if (!apiKey) {\n throw new Error('THORBIT_API_KEY, THORBIT_MCP_API_KEY, or ~/.thorbit-kb-mcp-key is required')\n }\n\n return {\n apiKey,\n baseUrl: (process.env.THORBIT_BASE_URL || process.env.THORBIT_KB_MCP_BASE_URL || 'https://thorbit.ai').trim(),\n }\n}\n","export const ThorbitKnowledgeBaseMcpToolNames = [\n 'thorbit_kb_create',\n 'thorbit_kb_list',\n 'thorbit_kb_source_status',\n 'thorbit_kb_ingest_url',\n 'thorbit_kb_ingest_site',\n 'thorbit_kb_ingest_youtube',\n 'thorbit_kb_ingest_text',\n 'thorbit_kb_search',\n 'thorbit_kb_ask',\n] as const\n\nexport type ThorbitKnowledgeBaseMcpToolName = typeof ThorbitKnowledgeBaseMcpToolNames[number]\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/thorbit-kb-api-client.ts","../src/thorbit-kb-mcp-server.ts","../src/thorbit-kb-mcp-response-formatters.ts","../src/thorbit-kb-mcp-tool-schemas.ts","../src/thorbit-kb-mcp-env.ts","../src/thorbit-kb-mcp-tool-names.ts"],"sourcesContent":["export { ThorbitKnowledgeBaseApiClient } from './thorbit-kb-api-client.js'\nexport { buildThorbitKnowledgeBaseMcpServer } from './thorbit-kb-mcp-server.js'\nexport { resolveThorbitKbMcpEnv } from './thorbit-kb-mcp-env.js'\nexport * from './thorbit-kb-mcp-tool-names.js'\nexport * from './thorbit-kb-mcp-tool-schemas.js'\n","import type { ThorbitKnowledgeBaseMcpToolName } from './thorbit-kb-mcp-tool-names.js'\n\nexport type ThorbitKnowledgeBaseMcpEnvelope =\n | {\n ok: true\n result: unknown\n warnings?: string[]\n requestId: string\n usage?: Record<string, unknown>\n }\n | {\n ok: false\n error: {\n code: string\n message: string\n details?: unknown\n }\n requestId: string\n }\n\nexport class ThorbitKnowledgeBaseApiClient {\n private readonly baseUrl: string\n private readonly apiKey: string\n\n constructor(options: { baseUrl: string; apiKey: string }) {\n this.baseUrl = options.baseUrl.replace(/\\/$/, '')\n this.apiKey = options.apiKey\n }\n\n async callTool(toolName: ThorbitKnowledgeBaseMcpToolName, input: unknown): Promise<ThorbitKnowledgeBaseMcpEnvelope> {\n const response = await fetch(`${this.baseUrl}/api/v1/mcp/knowledge-base/${toolName}`, {\n method: 'POST',\n headers: {\n 'x-thorbit-api-key': this.apiKey,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(input ?? {}),\n })\n\n const body = await response.json().catch(() => null) as ThorbitKnowledgeBaseMcpEnvelope | null\n if (body && typeof body === 'object' && 'ok' in body) return body\n\n return {\n ok: false,\n requestId: 'unavailable',\n error: {\n code: response.ok ? 'invalid_response' : `http_${response.status}`,\n message: response.ok ? 'Thorbit returned an invalid MCP response' : `Thorbit API request failed with HTTP ${response.status}`,\n },\n }\n }\n}\n","import { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { ToolAnnotations } from '@modelcontextprotocol/sdk/types.js'\nimport type { ZodRawShape } from 'zod'\nimport type { ThorbitKnowledgeBaseApiClient, ThorbitKnowledgeBaseMcpEnvelope } from './thorbit-kb-api-client.js'\nimport { formatThorbitKbMcpToolResult } from './thorbit-kb-mcp-response-formatters.js'\nimport {\n ThorbitKbAskInputSchema,\n ThorbitKbCreateInputSchema,\n ThorbitKbIngestSiteInputSchema,\n ThorbitKbIngestTextInputSchema,\n ThorbitKbIngestUrlInputSchema,\n ThorbitKbIngestYoutubeInputSchema,\n ThorbitKbListInputSchema,\n ThorbitKbSearchInputSchema,\n ThorbitKbSourceStatusInputSchema,\n} from './thorbit-kb-mcp-tool-schemas.js'\nimport type { ThorbitKnowledgeBaseMcpToolName } from './thorbit-kb-mcp-tool-names.js'\n\nconst VERSION = '0.2.8'\n\ntype ThorbitKbToolConfig<InputArgs extends ZodRawShape> = {\n title: string\n description: string\n inputSchema: InputArgs\n annotations: ToolAnnotations\n}\n\nfunction readOnlyAnnotations(title: string, idempotent = true) {\n return {\n title,\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: idempotent,\n openWorldHint: false,\n }\n}\n\nfunction ingestAnnotations(title: string, openWorldHint: boolean) {\n return {\n title,\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint,\n }\n}\n\nexport const SERVER_INSTRUCTIONS = [\n '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.',\n '',\n '## Set up a knowledge base',\n '- New knowledge base -> **thorbit_kb_create**. Org-level by default; pass projectPublicId to scope it to one project.',\n '- Find an existing one\\'s public ID -> **thorbit_kb_list** (needed before ingesting/searching if you don\\'t already have it).',\n '',\n '## Ingest content',\n '- One web page -> **thorbit_kb_ingest_url** (MCP Scraper extract, up to 500,000 chars before chunking).',\n '- A whole site (mapped + filtered by include/excludePatterns) -> **thorbit_kb_ingest_site** (up to 100 pages, default 25).',\n '- A YouTube video (transcribed, timestamps preserved by default) -> **thorbit_kb_ingest_youtube**.',\n '- Raw text/Markdown you already have -> **thorbit_kb_ingest_text** (no scraping needed).',\n '- All ingestion is append-only in this version — there\\'s no refresh/re-ingest mode; re-ingesting a URL adds a new source version rather than replacing the old one.',\n '- Check on an ingest\\'s progress -> **thorbit_kb_source_status** with the sourcePublicIds it returned.',\n '',\n '## Query a knowledge base',\n '- Need citation-ready chunks yourself, not a synthesized answer -> **thorbit_kb_search**.',\n '- 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.',\n].join('\\n')\n\nexport type ThorbitKbCallTool = (\n toolName: ThorbitKnowledgeBaseMcpToolName,\n input: unknown,\n) => Promise<ThorbitKnowledgeBaseMcpEnvelope>\n\nexport type BuildThorbitKnowledgeBaseMcpServerOptions =\n | ThorbitKnowledgeBaseApiClient\n | { callTool: ThorbitKbCallTool }\n\nexport function buildThorbitKnowledgeBaseMcpServer(options: BuildThorbitKnowledgeBaseMcpServerOptions): McpServer {\n const callTool: ThorbitKbCallTool = (toolName, input) => options.callTool(toolName, input)\n const server = new McpServer({ name: 'thorbit-kb-mcp', version: VERSION }, { instructions: SERVER_INSTRUCTIONS })\n\n server.registerResource(\n 'knowledge-bases',\n 'thorbit-kb://knowledge-bases',\n {\n title: 'Thorbit Knowledge Bases',\n description: 'Knowledge bases visible to this Thorbit MCP API key.',\n mimeType: 'application/json',\n },\n async (uri) => {\n const envelope = await callTool('thorbit_kb_list', {})\n return { contents: [{ uri: uri.href, mimeType: 'application/json', text: JSON.stringify(envelope, null, 2) }] }\n },\n )\n\n server.registerResource(\n 'source-status',\n new ResourceTemplate('thorbit-kb://sources/{sourcePublicId}', { list: undefined }),\n {\n title: 'Thorbit KB Source Status',\n description: 'Status and metadata for one Thorbit knowledge-base source.',\n mimeType: 'application/json',\n },\n async (uri, variables) => {\n const sourcePublicId = Array.isArray(variables.sourcePublicId) ? variables.sourcePublicId[0] : variables.sourcePublicId\n const envelope = await callTool('thorbit_kb_source_status', { sourcePublicIds: [String(sourcePublicId)] })\n return { contents: [{ uri: uri.href, mimeType: 'application/json', text: JSON.stringify(envelope, null, 2) }] }\n },\n )\n\n function registerTool<T extends ThorbitKnowledgeBaseMcpToolName>(\n toolName: T,\n config: ThorbitKbToolConfig<ZodRawShape>,\n ): void {\n server.registerTool(toolName, config, async (input) => {\n const envelope = await callTool(toolName, input)\n return formatThorbitKbMcpToolResult(toolName, envelope)\n })\n }\n\n registerTool('thorbit_kb_create', {\n title: 'Create Thorbit Knowledge Base',\n 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.',\n inputSchema: ThorbitKbCreateInputSchema,\n annotations: ingestAnnotations('Create Thorbit Knowledge Base', false),\n })\n\n registerTool('thorbit_kb_list', {\n title: 'List Thorbit Knowledge Bases',\n 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 — every ingest tool needs one (search/ask can omit it to query all visible KBs instead).',\n inputSchema: ThorbitKbListInputSchema,\n annotations: readOnlyAnnotations('List Thorbit Knowledge Bases'),\n })\n\n registerTool('thorbit_kb_source_status', {\n title: 'Read Thorbit KB Source Status',\n description: 'Poll ingestion status for source public IDs returned by any thorbit_kb_ingest_* tool — the only way to check whether an ingest finished, since the ingest tools may return before vectorization completes.',\n inputSchema: ThorbitKbSourceStatusInputSchema,\n annotations: readOnlyAnnotations('Read Thorbit KB Source Status'),\n })\n\n registerTool('thorbit_kb_ingest_url', {\n title: 'Ingest URL Into Thorbit KB',\n 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 the same URL adds a new source version rather than replacing the prior one — there is no refresh mode in this version.',\n inputSchema: ThorbitKbIngestUrlInputSchema,\n annotations: ingestAnnotations('Ingest URL Into Thorbit KB', true),\n })\n\n registerTool('thorbit_kb_ingest_site', {\n title: 'Ingest Website Into Thorbit KB',\n description: 'Map a website through MCP Scraper, extract selected pages (up to 100, default 25, filterable via includePatterns/excludePatterns), and vectorize each into a knowledge base. For a single known page instead of crawling a site, use thorbit_kb_ingest_url — cheaper and faster. Append-only, same as thorbit_kb_ingest_url.',\n inputSchema: ThorbitKbIngestSiteInputSchema,\n annotations: ingestAnnotations('Ingest Website Into Thorbit KB', true),\n })\n\n registerTool('thorbit_kb_ingest_youtube', {\n title: 'Ingest YouTube Into Thorbit KB',\n description: 'Transcribe a YouTube video through MCP Scraper and vectorize the transcript (timestamp chunks preserved by default) into a knowledge base. For web pages or raw text instead of video, use thorbit_kb_ingest_url or thorbit_kb_ingest_text.',\n inputSchema: ThorbitKbIngestYoutubeInputSchema,\n annotations: ingestAnnotations('Ingest YouTube Into Thorbit KB', true),\n })\n\n registerTool('thorbit_kb_ingest_text', {\n title: 'Ingest Text Into Thorbit KB',\n description: 'Submit text or Markdown you already have directly into a knowledge base — no scraping involved. Use this instead of thorbit_kb_ingest_url when you already have the content in hand rather than a URL to fetch.',\n inputSchema: ThorbitKbIngestTextInputSchema,\n annotations: ingestAnnotations('Ingest Text Into Thorbit KB', false),\n })\n\n registerTool('thorbit_kb_search', {\n title: 'Search Thorbit Knowledge Base',\n description: 'Search knowledge-base content and get citation-ready chunks back directly, without a synthesized answer. Use this instead of thorbit_kb_ask when you want to reason over the raw retrieved passages yourself. Omit knowledgeBasePublicId to search all KBs visible to this key.',\n inputSchema: ThorbitKbSearchInputSchema,\n annotations: readOnlyAnnotations('Search Thorbit Knowledge Base'),\n })\n\n registerTool('thorbit_kb_ask', {\n title: 'Ask Thorbit Knowledge Base',\n description: 'Answer a question using ONLY retrieved knowledge-base context — returns the answer, citations, sufficiency, and retrieval metadata. Set answerStyle:\"extractive\" for source excerpts without an LLM-written answer. Use thorbit_kb_search instead when you want the raw chunks rather than a synthesized answer.',\n inputSchema: ThorbitKbAskInputSchema,\n annotations: readOnlyAnnotations('Ask Thorbit Knowledge Base', false),\n })\n\n return server\n}\n","import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js'\nimport type { ThorbitKnowledgeBaseMcpEnvelope } from './thorbit-kb-api-client.js'\nimport type { ThorbitKnowledgeBaseMcpToolName } from './thorbit-kb-mcp-tool-names.js'\n\nfunction summarizeResult(toolName: ThorbitKnowledgeBaseMcpToolName, result: unknown): string {\n if (toolName === 'thorbit_kb_create' && result && typeof result === 'object' && 'knowledgeBase' in result) {\n const kb = result.knowledgeBase as { name?: unknown; publicId?: unknown }\n return `Created Thorbit knowledge base ${String(kb.name ?? kb.publicId ?? '')}.`\n }\n if (toolName === 'thorbit_kb_list' && result && typeof result === 'object' && 'knowledgeBases' in result) {\n const count = Array.isArray(result.knowledgeBases) ? result.knowledgeBases.length : 0\n return `Found ${count} Thorbit knowledge base${count === 1 ? '' : 's'}.`\n }\n if (toolName.startsWith('thorbit_kb_ingest')) return 'Knowledge-base ingestion completed. Check structuredContent for source receipts.'\n if (toolName === 'thorbit_kb_source_status') return 'Source status returned. Check structuredContent for details.'\n if (toolName === 'thorbit_kb_search') return 'Knowledge-base search completed. Check structuredContent for results and citations.'\n if (toolName === 'thorbit_kb_ask') return 'Knowledge-base answer generated. Check structuredContent for citations and strategy.'\n return 'Thorbit knowledge-base tool completed.'\n}\n\nexport function formatThorbitKbMcpToolResult(\n toolName: ThorbitKnowledgeBaseMcpToolName,\n envelope: ThorbitKnowledgeBaseMcpEnvelope,\n): CallToolResult {\n if (!envelope.ok) {\n return {\n isError: true,\n content: [{\n type: 'text',\n text: `${envelope.error.code}: ${envelope.error.message}`,\n }],\n structuredContent: envelope,\n }\n }\n\n return {\n content: [{\n type: 'text',\n text: summarizeResult(toolName, envelope.result),\n }],\n structuredContent: envelope.result as Record<string, unknown>,\n }\n}\n","import { z } from 'zod'\n\nconst MetadataSchema = z.record(z.string(), z.unknown())\n\nexport const ThorbitKbCreateInputSchema = {\n name: z.string().min(1).max(255).describe('Name for the new Thorbit knowledge base.'),\n description: z.string().max(2000).optional().describe('Optional description for the new knowledge base.'),\n projectPublicId: z.string().min(1).optional().describe('Optional Thorbit project public ID. Omit to create an org-level knowledge base.'),\n folder: z.string().min(1).max(128).optional().describe('Optional organizational folder, such as research or domains.'),\n}\n\nexport const ThorbitKbListInputSchema = {\n projectPublicId: z.string().min(1).optional().describe('Optional Thorbit project public ID used to narrow knowledge-base listing.'),\n includeGlobal: z.boolean().default(true).describe('Include org-level/global knowledge bases. Default true.'),\n limit: z.number().int().min(1).max(100).default(50).describe('Maximum knowledge bases to return.'),\n}\n\nexport const ThorbitKbSourceStatusInputSchema = {\n sourcePublicIds: z.array(z.string().min(1)).min(1).max(100).describe('Source public IDs returned by Thorbit KB ingestion tools.'),\n}\n\nexport const ThorbitKbIngestUrlInputSchema = {\n knowledgeBasePublicId: z.string().min(1).describe('Target Thorbit knowledge-base public ID.'),\n url: z.string().url().describe('Public URL to extract through MCP Scraper and ingest into Thorbit.'),\n title: z.string().min(1).max(512).optional().describe('Optional title override. Provider title is used when omitted.'),\n mode: z.enum(['append']).default('append').describe('Append a new source version. Refresh mode is intentionally not enabled in V1.'),\n maxCharacters: z.number().int().min(500).max(500000).optional().describe('Optional cap before chunking/vectorization.'),\n metadata: MetadataSchema.optional().describe('Optional metadata stored on the KB source.'),\n}\n\nexport const ThorbitKbIngestSiteInputSchema = {\n knowledgeBasePublicId: z.string().min(1).describe('Target Thorbit knowledge-base public ID.'),\n startUrl: z.string().url().describe('Website start URL. Thorbit maps URLs through MCP Scraper, then ingests selected pages.'),\n includePatterns: z.array(z.string().min(1)).max(20).optional().describe('Optional regex or substring patterns that a mapped URL must match.'),\n excludePatterns: z.array(z.string().min(1)).max(20).optional().describe('Optional regex or substring patterns that remove mapped URLs.'),\n maxPages: z.number().int().min(1).max(100).default(25).describe('Maximum pages to ingest. Default 25, hard cap 100.'),\n mode: z.enum(['append']).default('append').describe('Append source versions. Refresh mode is intentionally not enabled in V1.'),\n metadata: MetadataSchema.optional().describe('Optional metadata stored on each KB source.'),\n}\n\nexport const ThorbitKbIngestYoutubeInputSchema = {\n knowledgeBasePublicId: z.string().min(1).describe('Target Thorbit knowledge-base public ID.'),\n videoUrl: z.string().url().describe('YouTube video URL. Thorbit transcribes through MCP Scraper and vectorizes transcript chunks.'),\n title: z.string().min(1).max(512).optional().describe('Optional title override.'),\n mode: z.enum(['append']).default('append').describe('Append a new source version.'),\n preserveTimestamps: z.boolean().default(true).describe('Store transcript timestamps on chunks when MCP Scraper returns them.'),\n metadata: MetadataSchema.optional().describe('Optional metadata stored on the KB source.'),\n}\n\nexport const ThorbitKbIngestTextInputSchema = {\n knowledgeBasePublicId: z.string().min(1).describe('Target Thorbit knowledge-base public ID.'),\n title: z.string().min(1).max(512).describe('Source title shown in KB citations.'),\n content: z.string().min(1).max(500000).describe('Text or Markdown to chunk, embed, and ingest.'),\n sourceUrl: z.string().url().optional().describe('Optional canonical source URL for citations.'),\n sourceType: z.enum(['manual', 'note', 'markdown']).default('manual').describe('Caller-facing source type. Thorbit stores note/markdown as manual sources in V1.'),\n metadata: MetadataSchema.optional().describe('Optional metadata stored on the KB source.'),\n}\n\nexport const ThorbitKbSearchInputSchema = {\n query: z.string().min(1).max(4000).describe('Search query. Use the user question or a focused retrieval query.'),\n knowledgeBasePublicId: z.string().min(1).optional().describe('Optional target KB. Omit to search visible KBs.'),\n projectPublicId: z.string().min(1).optional().describe('Optional project scope when no KB is specified.'),\n limit: z.number().int().min(1).max(20).default(5).describe('Maximum chunks to return.'),\n includeEntities: z.boolean().default(false).describe('Reserved for entity-rich responses.'),\n searchMode: z.enum(['smart', 'hybrid']).default('smart').describe('smart uses Thorbit intent/rerank retrieval; hybrid uses ANN plus FTS.'),\n}\n\nexport const ThorbitKbAskInputSchema = {\n question: z.string().min(1).max(8000).describe('Question to answer using Thorbit KB context only.'),\n knowledgeBasePublicId: z.string().min(1).optional().describe('Optional target KB. Omit to answer over visible KBs.'),\n projectPublicId: z.string().min(1).optional().describe('Optional project scope when no KB is specified.'),\n answerStyle: z.enum(['concise', 'detailed', 'extractive']).default('concise').describe('Use extractive to return source excerpts without an LLM answer.'),\n limit: z.number().int().min(1).max(20).default(8).describe('Maximum retrieved chunks used for the answer.'),\n requireCitations: z.boolean().default(true).describe('Keep true for grounded answers with citation arrays.'),\n}\n\nexport const ThorbitKnowledgeBaseMcpToolInputSchemas = {\n thorbit_kb_create: ThorbitKbCreateInputSchema,\n thorbit_kb_list: ThorbitKbListInputSchema,\n thorbit_kb_source_status: ThorbitKbSourceStatusInputSchema,\n thorbit_kb_ingest_url: ThorbitKbIngestUrlInputSchema,\n thorbit_kb_ingest_site: ThorbitKbIngestSiteInputSchema,\n thorbit_kb_ingest_youtube: ThorbitKbIngestYoutubeInputSchema,\n thorbit_kb_ingest_text: ThorbitKbIngestTextInputSchema,\n thorbit_kb_search: ThorbitKbSearchInputSchema,\n thorbit_kb_ask: ThorbitKbAskInputSchema,\n}\n","import { readFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\n\nexport type ThorbitKbMcpEnv = {\n apiKey: string\n baseUrl: string\n}\n\nfunction readApiKeyFile(): string | undefined {\n const explicitPath = process.env.THORBIT_KB_MCP_KEY_PATH?.trim()\n const paths = [explicitPath, join(homedir(), '.thorbit-kb-mcp-key')].filter(Boolean) as string[]\n for (const path of paths) {\n try {\n const value = readFileSync(path, 'utf8').trim()\n if (value) return value\n } catch {\n continue\n }\n }\n return undefined\n}\n\nexport function resolveThorbitKbMcpEnv(): ThorbitKbMcpEnv {\n const apiKey = (\n process.env.THORBIT_API_KEY ||\n process.env.THORBIT_MCP_API_KEY ||\n process.env.THORBIT_KB_MCP_API_KEY ||\n readApiKeyFile()\n )?.trim()\n\n if (!apiKey) {\n throw new Error('THORBIT_API_KEY, THORBIT_MCP_API_KEY, or ~/.thorbit-kb-mcp-key is required')\n }\n\n return {\n apiKey,\n baseUrl: (process.env.THORBIT_BASE_URL || process.env.THORBIT_KB_MCP_BASE_URL || 'https://thorbit.ai').trim(),\n }\n}\n","export const ThorbitKnowledgeBaseMcpToolNames = [\n 'thorbit_kb_create',\n 'thorbit_kb_list',\n 'thorbit_kb_source_status',\n 'thorbit_kb_ingest_url',\n 'thorbit_kb_ingest_site',\n 'thorbit_kb_ingest_youtube',\n 'thorbit_kb_ingest_text',\n 'thorbit_kb_search',\n 'thorbit_kb_ask',\n] as const\n\nexport type ThorbitKnowledgeBaseMcpToolName = typeof ThorbitKnowledgeBaseMcpToolNames[number]\n"],"mappings":"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","names":[]}
package/dist/index.js CHANGED
@@ -148,7 +148,7 @@ var ThorbitKnowledgeBaseMcpToolInputSchemas = {
148
148
  };
149
149
 
150
150
  // src/thorbit-kb-mcp-server.ts
151
- var VERSION = "0.2.7";
151
+ var VERSION = "0.2.8";
152
152
  function readOnlyAnnotations(title, idempotent = true) {
153
153
  return {
154
154
  title,
@@ -167,9 +167,28 @@ function ingestAnnotations(title, openWorldHint) {
167
167
  openWorldHint
168
168
  };
169
169
  }
170
+ var SERVER_INSTRUCTIONS = [
171
+ "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.",
172
+ "",
173
+ "## Set up a knowledge base",
174
+ "- New knowledge base -> **thorbit_kb_create**. Org-level by default; pass projectPublicId to scope it to one project.",
175
+ "- Find an existing one's public ID -> **thorbit_kb_list** (needed before ingesting/searching if you don't already have it).",
176
+ "",
177
+ "## Ingest content",
178
+ "- One web page -> **thorbit_kb_ingest_url** (MCP Scraper extract, up to 500,000 chars before chunking).",
179
+ "- A whole site (mapped + filtered by include/excludePatterns) -> **thorbit_kb_ingest_site** (up to 100 pages, default 25).",
180
+ "- A YouTube video (transcribed, timestamps preserved by default) -> **thorbit_kb_ingest_youtube**.",
181
+ "- Raw text/Markdown you already have -> **thorbit_kb_ingest_text** (no scraping needed).",
182
+ "- 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.",
183
+ "- Check on an ingest's progress -> **thorbit_kb_source_status** with the sourcePublicIds it returned.",
184
+ "",
185
+ "## Query a knowledge base",
186
+ "- Need citation-ready chunks yourself, not a synthesized answer -> **thorbit_kb_search**.",
187
+ '- 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.'
188
+ ].join("\n");
170
189
  function buildThorbitKnowledgeBaseMcpServer(options) {
171
190
  const callTool = (toolName, input) => options.callTool(toolName, input);
172
- const server = new McpServer({ name: "thorbit-kb-mcp", version: VERSION });
191
+ const server = new McpServer({ name: "thorbit-kb-mcp", version: VERSION }, { instructions: SERVER_INSTRUCTIONS });
173
192
  server.registerResource(
174
193
  "knowledge-bases",
175
194
  "thorbit-kb://knowledge-bases",
@@ -205,55 +224,55 @@ function buildThorbitKnowledgeBaseMcpServer(options) {
205
224
  }
206
225
  registerTool("thorbit_kb_create", {
207
226
  title: "Create Thorbit Knowledge Base",
208
- description: "Create a new Thorbit vector-backed knowledge base for MCP ingestion, smart RAG search, citations, and entity extraction.",
227
+ 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.",
209
228
  inputSchema: ThorbitKbCreateInputSchema,
210
229
  annotations: ingestAnnotations("Create Thorbit Knowledge Base", false)
211
230
  });
212
231
  registerTool("thorbit_kb_list", {
213
232
  title: "List Thorbit Knowledge Bases",
214
- description: "List Thorbit knowledge bases visible to this API key. Use before ingestion/search when the target KB public ID is unknown.",
233
+ 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).",
215
234
  inputSchema: ThorbitKbListInputSchema,
216
235
  annotations: readOnlyAnnotations("List Thorbit Knowledge Bases")
217
236
  });
218
237
  registerTool("thorbit_kb_source_status", {
219
238
  title: "Read Thorbit KB Source Status",
220
- description: "Poll ingestion status for source public IDs returned by Thorbit KB ingestion tools.",
239
+ description: "Poll ingestion status for source public IDs returned by any thorbit_kb_ingest_* tool \u2014 the only way to check whether an ingest finished, since the ingest tools may return before vectorization completes.",
221
240
  inputSchema: ThorbitKbSourceStatusInputSchema,
222
241
  annotations: readOnlyAnnotations("Read Thorbit KB Source Status")
223
242
  });
224
243
  registerTool("thorbit_kb_ingest_url", {
225
244
  title: "Ingest URL Into Thorbit KB",
226
- description: "Extract one public URL through MCP Scraper, clean the content, submit it to Thorbit, and vectorize it into the selected knowledge base.",
245
+ 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 the same URL adds a new source version rather than replacing the prior one \u2014 there is no refresh mode in this version.",
227
246
  inputSchema: ThorbitKbIngestUrlInputSchema,
228
247
  annotations: ingestAnnotations("Ingest URL Into Thorbit KB", true)
229
248
  });
230
249
  registerTool("thorbit_kb_ingest_site", {
231
250
  title: "Ingest Website Into Thorbit KB",
232
- description: "Map a website through MCP Scraper, extract selected pages, submit each page to Thorbit, and vectorize them into the selected knowledge base.",
251
+ description: "Map a website through MCP Scraper, extract selected pages (up to 100, default 25, filterable via includePatterns/excludePatterns), and vectorize each into a knowledge base. For a single known page instead of crawling a site, use thorbit_kb_ingest_url \u2014 cheaper and faster. Append-only, same as thorbit_kb_ingest_url.",
233
252
  inputSchema: ThorbitKbIngestSiteInputSchema,
234
253
  annotations: ingestAnnotations("Ingest Website Into Thorbit KB", true)
235
254
  });
236
255
  registerTool("thorbit_kb_ingest_youtube", {
237
256
  title: "Ingest YouTube Into Thorbit KB",
238
- description: "Transcribe a YouTube video through MCP Scraper, preserve timestamp chunks when available, and vectorize the transcript into Thorbit KB.",
257
+ description: "Transcribe a YouTube video through MCP Scraper and vectorize the transcript (timestamp chunks preserved by default) into a knowledge base. For web pages or raw text instead of video, use thorbit_kb_ingest_url or thorbit_kb_ingest_text.",
239
258
  inputSchema: ThorbitKbIngestYoutubeInputSchema,
240
259
  annotations: ingestAnnotations("Ingest YouTube Into Thorbit KB", true)
241
260
  });
242
261
  registerTool("thorbit_kb_ingest_text", {
243
262
  title: "Ingest Text Into Thorbit KB",
244
- description: "Submit provided text or Markdown directly to Thorbit and vectorize it into the selected knowledge base.",
263
+ description: "Submit text or Markdown you already have directly into a knowledge base \u2014 no scraping involved. Use this instead of thorbit_kb_ingest_url when you already have the content in hand rather than a URL to fetch.",
245
264
  inputSchema: ThorbitKbIngestTextInputSchema,
246
265
  annotations: ingestAnnotations("Ingest Text Into Thorbit KB", false)
247
266
  });
248
267
  registerTool("thorbit_kb_search", {
249
268
  title: "Search Thorbit Knowledge Base",
250
- description: "Search Thorbit KB content with citation-ready chunks. Use when the user needs source-backed snippets or evidence.",
269
+ description: "Search knowledge-base content and get citation-ready chunks back directly, without a synthesized answer. Use this instead of thorbit_kb_ask when you want to reason over the raw retrieved passages yourself. Omit knowledgeBasePublicId to search all KBs visible to this key.",
251
270
  inputSchema: ThorbitKbSearchInputSchema,
252
271
  annotations: readOnlyAnnotations("Search Thorbit Knowledge Base")
253
272
  });
254
273
  registerTool("thorbit_kb_ask", {
255
274
  title: "Ask Thorbit Knowledge Base",
256
- description: "Answer a question using only retrieved Thorbit KB context. Returns answer, citations, sufficiency, and retrieval strategy metadata.",
275
+ description: 'Answer a question using ONLY retrieved knowledge-base context \u2014 returns the answer, citations, sufficiency, and retrieval metadata. Set answerStyle:"extractive" for source excerpts without an LLM-written answer. Use thorbit_kb_search instead when you want the raw chunks rather than a synthesized answer.',
257
276
  inputSchema: ThorbitKbAskInputSchema,
258
277
  annotations: readOnlyAnnotations("Ask Thorbit Knowledge Base", false)
259
278
  });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/thorbit-kb-api-client.ts","../src/thorbit-kb-mcp-server.ts","../src/thorbit-kb-mcp-response-formatters.ts","../src/thorbit-kb-mcp-tool-schemas.ts","../src/thorbit-kb-mcp-env.ts","../src/thorbit-kb-mcp-tool-names.ts"],"sourcesContent":["import type { ThorbitKnowledgeBaseMcpToolName } from './thorbit-kb-mcp-tool-names.js'\n\nexport type ThorbitKnowledgeBaseMcpEnvelope =\n | {\n ok: true\n result: unknown\n warnings?: string[]\n requestId: string\n usage?: Record<string, unknown>\n }\n | {\n ok: false\n error: {\n code: string\n message: string\n details?: unknown\n }\n requestId: string\n }\n\nexport class ThorbitKnowledgeBaseApiClient {\n private readonly baseUrl: string\n private readonly apiKey: string\n\n constructor(options: { baseUrl: string; apiKey: string }) {\n this.baseUrl = options.baseUrl.replace(/\\/$/, '')\n this.apiKey = options.apiKey\n }\n\n async callTool(toolName: ThorbitKnowledgeBaseMcpToolName, input: unknown): Promise<ThorbitKnowledgeBaseMcpEnvelope> {\n const response = await fetch(`${this.baseUrl}/api/v1/mcp/knowledge-base/${toolName}`, {\n method: 'POST',\n headers: {\n 'x-thorbit-api-key': this.apiKey,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(input ?? {}),\n })\n\n const body = await response.json().catch(() => null) as ThorbitKnowledgeBaseMcpEnvelope | null\n if (body && typeof body === 'object' && 'ok' in body) return body\n\n return {\n ok: false,\n requestId: 'unavailable',\n error: {\n code: response.ok ? 'invalid_response' : `http_${response.status}`,\n message: response.ok ? 'Thorbit returned an invalid MCP response' : `Thorbit API request failed with HTTP ${response.status}`,\n },\n }\n }\n}\n","import { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { ToolAnnotations } from '@modelcontextprotocol/sdk/types.js'\nimport type { ZodRawShape } from 'zod'\nimport type { ThorbitKnowledgeBaseApiClient, ThorbitKnowledgeBaseMcpEnvelope } from './thorbit-kb-api-client.js'\nimport { formatThorbitKbMcpToolResult } from './thorbit-kb-mcp-response-formatters.js'\nimport {\n ThorbitKbAskInputSchema,\n ThorbitKbCreateInputSchema,\n ThorbitKbIngestSiteInputSchema,\n ThorbitKbIngestTextInputSchema,\n ThorbitKbIngestUrlInputSchema,\n ThorbitKbIngestYoutubeInputSchema,\n ThorbitKbListInputSchema,\n ThorbitKbSearchInputSchema,\n ThorbitKbSourceStatusInputSchema,\n} from './thorbit-kb-mcp-tool-schemas.js'\nimport type { ThorbitKnowledgeBaseMcpToolName } from './thorbit-kb-mcp-tool-names.js'\n\nconst VERSION = '0.2.7'\n\ntype ThorbitKbToolConfig<InputArgs extends ZodRawShape> = {\n title: string\n description: string\n inputSchema: InputArgs\n annotations: ToolAnnotations\n}\n\nfunction readOnlyAnnotations(title: string, idempotent = true) {\n return {\n title,\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: idempotent,\n openWorldHint: false,\n }\n}\n\nfunction ingestAnnotations(title: string, openWorldHint: boolean) {\n return {\n title,\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint,\n }\n}\n\nexport type ThorbitKbCallTool = (\n toolName: ThorbitKnowledgeBaseMcpToolName,\n input: unknown,\n) => Promise<ThorbitKnowledgeBaseMcpEnvelope>\n\nexport type BuildThorbitKnowledgeBaseMcpServerOptions =\n | ThorbitKnowledgeBaseApiClient\n | { callTool: ThorbitKbCallTool }\n\nexport function buildThorbitKnowledgeBaseMcpServer(options: BuildThorbitKnowledgeBaseMcpServerOptions): McpServer {\n const callTool: ThorbitKbCallTool = (toolName, input) => options.callTool(toolName, input)\n const server = new McpServer({ name: 'thorbit-kb-mcp', version: VERSION })\n\n server.registerResource(\n 'knowledge-bases',\n 'thorbit-kb://knowledge-bases',\n {\n title: 'Thorbit Knowledge Bases',\n description: 'Knowledge bases visible to this Thorbit MCP API key.',\n mimeType: 'application/json',\n },\n async (uri) => {\n const envelope = await callTool('thorbit_kb_list', {})\n return { contents: [{ uri: uri.href, mimeType: 'application/json', text: JSON.stringify(envelope, null, 2) }] }\n },\n )\n\n server.registerResource(\n 'source-status',\n new ResourceTemplate('thorbit-kb://sources/{sourcePublicId}', { list: undefined }),\n {\n title: 'Thorbit KB Source Status',\n description: 'Status and metadata for one Thorbit knowledge-base source.',\n mimeType: 'application/json',\n },\n async (uri, variables) => {\n const sourcePublicId = Array.isArray(variables.sourcePublicId) ? variables.sourcePublicId[0] : variables.sourcePublicId\n const envelope = await callTool('thorbit_kb_source_status', { sourcePublicIds: [String(sourcePublicId)] })\n return { contents: [{ uri: uri.href, mimeType: 'application/json', text: JSON.stringify(envelope, null, 2) }] }\n },\n )\n\n function registerTool<T extends ThorbitKnowledgeBaseMcpToolName>(\n toolName: T,\n config: ThorbitKbToolConfig<ZodRawShape>,\n ): void {\n server.registerTool(toolName, config, async (input) => {\n const envelope = await callTool(toolName, input)\n return formatThorbitKbMcpToolResult(toolName, envelope)\n })\n }\n\n registerTool('thorbit_kb_create', {\n title: 'Create Thorbit Knowledge Base',\n description: 'Create a new Thorbit vector-backed knowledge base for MCP ingestion, smart RAG search, citations, and entity extraction.',\n inputSchema: ThorbitKbCreateInputSchema,\n annotations: ingestAnnotations('Create Thorbit Knowledge Base', false),\n })\n\n registerTool('thorbit_kb_list', {\n title: 'List Thorbit Knowledge Bases',\n description: 'List Thorbit knowledge bases visible to this API key. Use before ingestion/search when the target KB public ID is unknown.',\n inputSchema: ThorbitKbListInputSchema,\n annotations: readOnlyAnnotations('List Thorbit Knowledge Bases'),\n })\n\n registerTool('thorbit_kb_source_status', {\n title: 'Read Thorbit KB Source Status',\n description: 'Poll ingestion status for source public IDs returned by Thorbit KB ingestion tools.',\n inputSchema: ThorbitKbSourceStatusInputSchema,\n annotations: readOnlyAnnotations('Read Thorbit KB Source Status'),\n })\n\n registerTool('thorbit_kb_ingest_url', {\n title: 'Ingest URL Into Thorbit KB',\n description: 'Extract one public URL through MCP Scraper, clean the content, submit it to Thorbit, and vectorize it into the selected knowledge base.',\n inputSchema: ThorbitKbIngestUrlInputSchema,\n annotations: ingestAnnotations('Ingest URL Into Thorbit KB', true),\n })\n\n registerTool('thorbit_kb_ingest_site', {\n title: 'Ingest Website Into Thorbit KB',\n description: 'Map a website through MCP Scraper, extract selected pages, submit each page to Thorbit, and vectorize them into the selected knowledge base.',\n inputSchema: ThorbitKbIngestSiteInputSchema,\n annotations: ingestAnnotations('Ingest Website Into Thorbit KB', true),\n })\n\n registerTool('thorbit_kb_ingest_youtube', {\n title: 'Ingest YouTube Into Thorbit KB',\n description: 'Transcribe a YouTube video through MCP Scraper, preserve timestamp chunks when available, and vectorize the transcript into Thorbit KB.',\n inputSchema: ThorbitKbIngestYoutubeInputSchema,\n annotations: ingestAnnotations('Ingest YouTube Into Thorbit KB', true),\n })\n\n registerTool('thorbit_kb_ingest_text', {\n title: 'Ingest Text Into Thorbit KB',\n description: 'Submit provided text or Markdown directly to Thorbit and vectorize it into the selected knowledge base.',\n inputSchema: ThorbitKbIngestTextInputSchema,\n annotations: ingestAnnotations('Ingest Text Into Thorbit KB', false),\n })\n\n registerTool('thorbit_kb_search', {\n title: 'Search Thorbit Knowledge Base',\n description: 'Search Thorbit KB content with citation-ready chunks. Use when the user needs source-backed snippets or evidence.',\n inputSchema: ThorbitKbSearchInputSchema,\n annotations: readOnlyAnnotations('Search Thorbit Knowledge Base'),\n })\n\n registerTool('thorbit_kb_ask', {\n title: 'Ask Thorbit Knowledge Base',\n description: 'Answer a question using only retrieved Thorbit KB context. Returns answer, citations, sufficiency, and retrieval strategy metadata.',\n inputSchema: ThorbitKbAskInputSchema,\n annotations: readOnlyAnnotations('Ask Thorbit Knowledge Base', false),\n })\n\n return server\n}\n","import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js'\nimport type { ThorbitKnowledgeBaseMcpEnvelope } from './thorbit-kb-api-client.js'\nimport type { ThorbitKnowledgeBaseMcpToolName } from './thorbit-kb-mcp-tool-names.js'\n\nfunction summarizeResult(toolName: ThorbitKnowledgeBaseMcpToolName, result: unknown): string {\n if (toolName === 'thorbit_kb_create' && result && typeof result === 'object' && 'knowledgeBase' in result) {\n const kb = result.knowledgeBase as { name?: unknown; publicId?: unknown }\n return `Created Thorbit knowledge base ${String(kb.name ?? kb.publicId ?? '')}.`\n }\n if (toolName === 'thorbit_kb_list' && result && typeof result === 'object' && 'knowledgeBases' in result) {\n const count = Array.isArray(result.knowledgeBases) ? result.knowledgeBases.length : 0\n return `Found ${count} Thorbit knowledge base${count === 1 ? '' : 's'}.`\n }\n if (toolName.startsWith('thorbit_kb_ingest')) return 'Knowledge-base ingestion completed. Check structuredContent for source receipts.'\n if (toolName === 'thorbit_kb_source_status') return 'Source status returned. Check structuredContent for details.'\n if (toolName === 'thorbit_kb_search') return 'Knowledge-base search completed. Check structuredContent for results and citations.'\n if (toolName === 'thorbit_kb_ask') return 'Knowledge-base answer generated. Check structuredContent for citations and strategy.'\n return 'Thorbit knowledge-base tool completed.'\n}\n\nexport function formatThorbitKbMcpToolResult(\n toolName: ThorbitKnowledgeBaseMcpToolName,\n envelope: ThorbitKnowledgeBaseMcpEnvelope,\n): CallToolResult {\n if (!envelope.ok) {\n return {\n isError: true,\n content: [{\n type: 'text',\n text: `${envelope.error.code}: ${envelope.error.message}`,\n }],\n structuredContent: envelope,\n }\n }\n\n return {\n content: [{\n type: 'text',\n text: summarizeResult(toolName, envelope.result),\n }],\n structuredContent: envelope.result as Record<string, unknown>,\n }\n}\n","import { z } from 'zod'\n\nconst MetadataSchema = z.record(z.string(), z.unknown())\n\nexport const ThorbitKbCreateInputSchema = {\n name: z.string().min(1).max(255).describe('Name for the new Thorbit knowledge base.'),\n description: z.string().max(2000).optional().describe('Optional description for the new knowledge base.'),\n projectPublicId: z.string().min(1).optional().describe('Optional Thorbit project public ID. Omit to create an org-level knowledge base.'),\n folder: z.string().min(1).max(128).optional().describe('Optional organizational folder, such as research or domains.'),\n}\n\nexport const ThorbitKbListInputSchema = {\n projectPublicId: z.string().min(1).optional().describe('Optional Thorbit project public ID used to narrow knowledge-base listing.'),\n includeGlobal: z.boolean().default(true).describe('Include org-level/global knowledge bases. Default true.'),\n limit: z.number().int().min(1).max(100).default(50).describe('Maximum knowledge bases to return.'),\n}\n\nexport const ThorbitKbSourceStatusInputSchema = {\n sourcePublicIds: z.array(z.string().min(1)).min(1).max(100).describe('Source public IDs returned by Thorbit KB ingestion tools.'),\n}\n\nexport const ThorbitKbIngestUrlInputSchema = {\n knowledgeBasePublicId: z.string().min(1).describe('Target Thorbit knowledge-base public ID.'),\n url: z.string().url().describe('Public URL to extract through MCP Scraper and ingest into Thorbit.'),\n title: z.string().min(1).max(512).optional().describe('Optional title override. Provider title is used when omitted.'),\n mode: z.enum(['append']).default('append').describe('Append a new source version. Refresh mode is intentionally not enabled in V1.'),\n maxCharacters: z.number().int().min(500).max(500000).optional().describe('Optional cap before chunking/vectorization.'),\n metadata: MetadataSchema.optional().describe('Optional metadata stored on the KB source.'),\n}\n\nexport const ThorbitKbIngestSiteInputSchema = {\n knowledgeBasePublicId: z.string().min(1).describe('Target Thorbit knowledge-base public ID.'),\n startUrl: z.string().url().describe('Website start URL. Thorbit maps URLs through MCP Scraper, then ingests selected pages.'),\n includePatterns: z.array(z.string().min(1)).max(20).optional().describe('Optional regex or substring patterns that a mapped URL must match.'),\n excludePatterns: z.array(z.string().min(1)).max(20).optional().describe('Optional regex or substring patterns that remove mapped URLs.'),\n maxPages: z.number().int().min(1).max(100).default(25).describe('Maximum pages to ingest. Default 25, hard cap 100.'),\n mode: z.enum(['append']).default('append').describe('Append source versions. Refresh mode is intentionally not enabled in V1.'),\n metadata: MetadataSchema.optional().describe('Optional metadata stored on each KB source.'),\n}\n\nexport const ThorbitKbIngestYoutubeInputSchema = {\n knowledgeBasePublicId: z.string().min(1).describe('Target Thorbit knowledge-base public ID.'),\n videoUrl: z.string().url().describe('YouTube video URL. Thorbit transcribes through MCP Scraper and vectorizes transcript chunks.'),\n title: z.string().min(1).max(512).optional().describe('Optional title override.'),\n mode: z.enum(['append']).default('append').describe('Append a new source version.'),\n preserveTimestamps: z.boolean().default(true).describe('Store transcript timestamps on chunks when MCP Scraper returns them.'),\n metadata: MetadataSchema.optional().describe('Optional metadata stored on the KB source.'),\n}\n\nexport const ThorbitKbIngestTextInputSchema = {\n knowledgeBasePublicId: z.string().min(1).describe('Target Thorbit knowledge-base public ID.'),\n title: z.string().min(1).max(512).describe('Source title shown in KB citations.'),\n content: z.string().min(1).max(500000).describe('Text or Markdown to chunk, embed, and ingest.'),\n sourceUrl: z.string().url().optional().describe('Optional canonical source URL for citations.'),\n sourceType: z.enum(['manual', 'note', 'markdown']).default('manual').describe('Caller-facing source type. Thorbit stores note/markdown as manual sources in V1.'),\n metadata: MetadataSchema.optional().describe('Optional metadata stored on the KB source.'),\n}\n\nexport const ThorbitKbSearchInputSchema = {\n query: z.string().min(1).max(4000).describe('Search query. Use the user question or a focused retrieval query.'),\n knowledgeBasePublicId: z.string().min(1).optional().describe('Optional target KB. Omit to search visible KBs.'),\n projectPublicId: z.string().min(1).optional().describe('Optional project scope when no KB is specified.'),\n limit: z.number().int().min(1).max(20).default(5).describe('Maximum chunks to return.'),\n includeEntities: z.boolean().default(false).describe('Reserved for entity-rich responses.'),\n searchMode: z.enum(['smart', 'hybrid']).default('smart').describe('smart uses Thorbit intent/rerank retrieval; hybrid uses ANN plus FTS.'),\n}\n\nexport const ThorbitKbAskInputSchema = {\n question: z.string().min(1).max(8000).describe('Question to answer using Thorbit KB context only.'),\n knowledgeBasePublicId: z.string().min(1).optional().describe('Optional target KB. Omit to answer over visible KBs.'),\n projectPublicId: z.string().min(1).optional().describe('Optional project scope when no KB is specified.'),\n answerStyle: z.enum(['concise', 'detailed', 'extractive']).default('concise').describe('Use extractive to return source excerpts without an LLM answer.'),\n limit: z.number().int().min(1).max(20).default(8).describe('Maximum retrieved chunks used for the answer.'),\n requireCitations: z.boolean().default(true).describe('Keep true for grounded answers with citation arrays.'),\n}\n\nexport const ThorbitKnowledgeBaseMcpToolInputSchemas = {\n thorbit_kb_create: ThorbitKbCreateInputSchema,\n thorbit_kb_list: ThorbitKbListInputSchema,\n thorbit_kb_source_status: ThorbitKbSourceStatusInputSchema,\n thorbit_kb_ingest_url: ThorbitKbIngestUrlInputSchema,\n thorbit_kb_ingest_site: ThorbitKbIngestSiteInputSchema,\n thorbit_kb_ingest_youtube: ThorbitKbIngestYoutubeInputSchema,\n thorbit_kb_ingest_text: ThorbitKbIngestTextInputSchema,\n thorbit_kb_search: ThorbitKbSearchInputSchema,\n thorbit_kb_ask: ThorbitKbAskInputSchema,\n}\n","import { readFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\n\nexport type ThorbitKbMcpEnv = {\n apiKey: string\n baseUrl: string\n}\n\nfunction readApiKeyFile(): string | undefined {\n const explicitPath = process.env.THORBIT_KB_MCP_KEY_PATH?.trim()\n const paths = [explicitPath, join(homedir(), '.thorbit-kb-mcp-key')].filter(Boolean) as string[]\n for (const path of paths) {\n try {\n const value = readFileSync(path, 'utf8').trim()\n if (value) return value\n } catch {\n continue\n }\n }\n return undefined\n}\n\nexport function resolveThorbitKbMcpEnv(): ThorbitKbMcpEnv {\n const apiKey = (\n process.env.THORBIT_API_KEY ||\n process.env.THORBIT_MCP_API_KEY ||\n process.env.THORBIT_KB_MCP_API_KEY ||\n readApiKeyFile()\n )?.trim()\n\n if (!apiKey) {\n throw new Error('THORBIT_API_KEY, THORBIT_MCP_API_KEY, or ~/.thorbit-kb-mcp-key is required')\n }\n\n return {\n apiKey,\n baseUrl: (process.env.THORBIT_BASE_URL || process.env.THORBIT_KB_MCP_BASE_URL || 'https://thorbit.ai').trim(),\n }\n}\n","export const ThorbitKnowledgeBaseMcpToolNames = [\n 'thorbit_kb_create',\n 'thorbit_kb_list',\n 'thorbit_kb_source_status',\n 'thorbit_kb_ingest_url',\n 'thorbit_kb_ingest_site',\n 'thorbit_kb_ingest_youtube',\n 'thorbit_kb_ingest_text',\n 'thorbit_kb_search',\n 'thorbit_kb_ask',\n] as const\n\nexport type ThorbitKnowledgeBaseMcpToolName = typeof ThorbitKnowledgeBaseMcpToolNames[number]\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/thorbit-kb-api-client.ts","../src/thorbit-kb-mcp-server.ts","../src/thorbit-kb-mcp-response-formatters.ts","../src/thorbit-kb-mcp-tool-schemas.ts","../src/thorbit-kb-mcp-env.ts","../src/thorbit-kb-mcp-tool-names.ts"],"sourcesContent":["import type { ThorbitKnowledgeBaseMcpToolName } from './thorbit-kb-mcp-tool-names.js'\n\nexport type ThorbitKnowledgeBaseMcpEnvelope =\n | {\n ok: true\n result: unknown\n warnings?: string[]\n requestId: string\n usage?: Record<string, unknown>\n }\n | {\n ok: false\n error: {\n code: string\n message: string\n details?: unknown\n }\n requestId: string\n }\n\nexport class ThorbitKnowledgeBaseApiClient {\n private readonly baseUrl: string\n private readonly apiKey: string\n\n constructor(options: { baseUrl: string; apiKey: string }) {\n this.baseUrl = options.baseUrl.replace(/\\/$/, '')\n this.apiKey = options.apiKey\n }\n\n async callTool(toolName: ThorbitKnowledgeBaseMcpToolName, input: unknown): Promise<ThorbitKnowledgeBaseMcpEnvelope> {\n const response = await fetch(`${this.baseUrl}/api/v1/mcp/knowledge-base/${toolName}`, {\n method: 'POST',\n headers: {\n 'x-thorbit-api-key': this.apiKey,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(input ?? {}),\n })\n\n const body = await response.json().catch(() => null) as ThorbitKnowledgeBaseMcpEnvelope | null\n if (body && typeof body === 'object' && 'ok' in body) return body\n\n return {\n ok: false,\n requestId: 'unavailable',\n error: {\n code: response.ok ? 'invalid_response' : `http_${response.status}`,\n message: response.ok ? 'Thorbit returned an invalid MCP response' : `Thorbit API request failed with HTTP ${response.status}`,\n },\n }\n }\n}\n","import { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { ToolAnnotations } from '@modelcontextprotocol/sdk/types.js'\nimport type { ZodRawShape } from 'zod'\nimport type { ThorbitKnowledgeBaseApiClient, ThorbitKnowledgeBaseMcpEnvelope } from './thorbit-kb-api-client.js'\nimport { formatThorbitKbMcpToolResult } from './thorbit-kb-mcp-response-formatters.js'\nimport {\n ThorbitKbAskInputSchema,\n ThorbitKbCreateInputSchema,\n ThorbitKbIngestSiteInputSchema,\n ThorbitKbIngestTextInputSchema,\n ThorbitKbIngestUrlInputSchema,\n ThorbitKbIngestYoutubeInputSchema,\n ThorbitKbListInputSchema,\n ThorbitKbSearchInputSchema,\n ThorbitKbSourceStatusInputSchema,\n} from './thorbit-kb-mcp-tool-schemas.js'\nimport type { ThorbitKnowledgeBaseMcpToolName } from './thorbit-kb-mcp-tool-names.js'\n\nconst VERSION = '0.2.8'\n\ntype ThorbitKbToolConfig<InputArgs extends ZodRawShape> = {\n title: string\n description: string\n inputSchema: InputArgs\n annotations: ToolAnnotations\n}\n\nfunction readOnlyAnnotations(title: string, idempotent = true) {\n return {\n title,\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: idempotent,\n openWorldHint: false,\n }\n}\n\nfunction ingestAnnotations(title: string, openWorldHint: boolean) {\n return {\n title,\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint,\n }\n}\n\nexport const SERVER_INSTRUCTIONS = [\n '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.',\n '',\n '## Set up a knowledge base',\n '- New knowledge base -> **thorbit_kb_create**. Org-level by default; pass projectPublicId to scope it to one project.',\n '- Find an existing one\\'s public ID -> **thorbit_kb_list** (needed before ingesting/searching if you don\\'t already have it).',\n '',\n '## Ingest content',\n '- One web page -> **thorbit_kb_ingest_url** (MCP Scraper extract, up to 500,000 chars before chunking).',\n '- A whole site (mapped + filtered by include/excludePatterns) -> **thorbit_kb_ingest_site** (up to 100 pages, default 25).',\n '- A YouTube video (transcribed, timestamps preserved by default) -> **thorbit_kb_ingest_youtube**.',\n '- Raw text/Markdown you already have -> **thorbit_kb_ingest_text** (no scraping needed).',\n '- All ingestion is append-only in this version — there\\'s no refresh/re-ingest mode; re-ingesting a URL adds a new source version rather than replacing the old one.',\n '- Check on an ingest\\'s progress -> **thorbit_kb_source_status** with the sourcePublicIds it returned.',\n '',\n '## Query a knowledge base',\n '- Need citation-ready chunks yourself, not a synthesized answer -> **thorbit_kb_search**.',\n '- 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.',\n].join('\\n')\n\nexport type ThorbitKbCallTool = (\n toolName: ThorbitKnowledgeBaseMcpToolName,\n input: unknown,\n) => Promise<ThorbitKnowledgeBaseMcpEnvelope>\n\nexport type BuildThorbitKnowledgeBaseMcpServerOptions =\n | ThorbitKnowledgeBaseApiClient\n | { callTool: ThorbitKbCallTool }\n\nexport function buildThorbitKnowledgeBaseMcpServer(options: BuildThorbitKnowledgeBaseMcpServerOptions): McpServer {\n const callTool: ThorbitKbCallTool = (toolName, input) => options.callTool(toolName, input)\n const server = new McpServer({ name: 'thorbit-kb-mcp', version: VERSION }, { instructions: SERVER_INSTRUCTIONS })\n\n server.registerResource(\n 'knowledge-bases',\n 'thorbit-kb://knowledge-bases',\n {\n title: 'Thorbit Knowledge Bases',\n description: 'Knowledge bases visible to this Thorbit MCP API key.',\n mimeType: 'application/json',\n },\n async (uri) => {\n const envelope = await callTool('thorbit_kb_list', {})\n return { contents: [{ uri: uri.href, mimeType: 'application/json', text: JSON.stringify(envelope, null, 2) }] }\n },\n )\n\n server.registerResource(\n 'source-status',\n new ResourceTemplate('thorbit-kb://sources/{sourcePublicId}', { list: undefined }),\n {\n title: 'Thorbit KB Source Status',\n description: 'Status and metadata for one Thorbit knowledge-base source.',\n mimeType: 'application/json',\n },\n async (uri, variables) => {\n const sourcePublicId = Array.isArray(variables.sourcePublicId) ? variables.sourcePublicId[0] : variables.sourcePublicId\n const envelope = await callTool('thorbit_kb_source_status', { sourcePublicIds: [String(sourcePublicId)] })\n return { contents: [{ uri: uri.href, mimeType: 'application/json', text: JSON.stringify(envelope, null, 2) }] }\n },\n )\n\n function registerTool<T extends ThorbitKnowledgeBaseMcpToolName>(\n toolName: T,\n config: ThorbitKbToolConfig<ZodRawShape>,\n ): void {\n server.registerTool(toolName, config, async (input) => {\n const envelope = await callTool(toolName, input)\n return formatThorbitKbMcpToolResult(toolName, envelope)\n })\n }\n\n registerTool('thorbit_kb_create', {\n title: 'Create Thorbit Knowledge Base',\n 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.',\n inputSchema: ThorbitKbCreateInputSchema,\n annotations: ingestAnnotations('Create Thorbit Knowledge Base', false),\n })\n\n registerTool('thorbit_kb_list', {\n title: 'List Thorbit Knowledge Bases',\n 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 — every ingest tool needs one (search/ask can omit it to query all visible KBs instead).',\n inputSchema: ThorbitKbListInputSchema,\n annotations: readOnlyAnnotations('List Thorbit Knowledge Bases'),\n })\n\n registerTool('thorbit_kb_source_status', {\n title: 'Read Thorbit KB Source Status',\n description: 'Poll ingestion status for source public IDs returned by any thorbit_kb_ingest_* tool — the only way to check whether an ingest finished, since the ingest tools may return before vectorization completes.',\n inputSchema: ThorbitKbSourceStatusInputSchema,\n annotations: readOnlyAnnotations('Read Thorbit KB Source Status'),\n })\n\n registerTool('thorbit_kb_ingest_url', {\n title: 'Ingest URL Into Thorbit KB',\n 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 the same URL adds a new source version rather than replacing the prior one — there is no refresh mode in this version.',\n inputSchema: ThorbitKbIngestUrlInputSchema,\n annotations: ingestAnnotations('Ingest URL Into Thorbit KB', true),\n })\n\n registerTool('thorbit_kb_ingest_site', {\n title: 'Ingest Website Into Thorbit KB',\n description: 'Map a website through MCP Scraper, extract selected pages (up to 100, default 25, filterable via includePatterns/excludePatterns), and vectorize each into a knowledge base. For a single known page instead of crawling a site, use thorbit_kb_ingest_url — cheaper and faster. Append-only, same as thorbit_kb_ingest_url.',\n inputSchema: ThorbitKbIngestSiteInputSchema,\n annotations: ingestAnnotations('Ingest Website Into Thorbit KB', true),\n })\n\n registerTool('thorbit_kb_ingest_youtube', {\n title: 'Ingest YouTube Into Thorbit KB',\n description: 'Transcribe a YouTube video through MCP Scraper and vectorize the transcript (timestamp chunks preserved by default) into a knowledge base. For web pages or raw text instead of video, use thorbit_kb_ingest_url or thorbit_kb_ingest_text.',\n inputSchema: ThorbitKbIngestYoutubeInputSchema,\n annotations: ingestAnnotations('Ingest YouTube Into Thorbit KB', true),\n })\n\n registerTool('thorbit_kb_ingest_text', {\n title: 'Ingest Text Into Thorbit KB',\n description: 'Submit text or Markdown you already have directly into a knowledge base — no scraping involved. Use this instead of thorbit_kb_ingest_url when you already have the content in hand rather than a URL to fetch.',\n inputSchema: ThorbitKbIngestTextInputSchema,\n annotations: ingestAnnotations('Ingest Text Into Thorbit KB', false),\n })\n\n registerTool('thorbit_kb_search', {\n title: 'Search Thorbit Knowledge Base',\n description: 'Search knowledge-base content and get citation-ready chunks back directly, without a synthesized answer. Use this instead of thorbit_kb_ask when you want to reason over the raw retrieved passages yourself. Omit knowledgeBasePublicId to search all KBs visible to this key.',\n inputSchema: ThorbitKbSearchInputSchema,\n annotations: readOnlyAnnotations('Search Thorbit Knowledge Base'),\n })\n\n registerTool('thorbit_kb_ask', {\n title: 'Ask Thorbit Knowledge Base',\n description: 'Answer a question using ONLY retrieved knowledge-base context — returns the answer, citations, sufficiency, and retrieval metadata. Set answerStyle:\"extractive\" for source excerpts without an LLM-written answer. Use thorbit_kb_search instead when you want the raw chunks rather than a synthesized answer.',\n inputSchema: ThorbitKbAskInputSchema,\n annotations: readOnlyAnnotations('Ask Thorbit Knowledge Base', false),\n })\n\n return server\n}\n","import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js'\nimport type { ThorbitKnowledgeBaseMcpEnvelope } from './thorbit-kb-api-client.js'\nimport type { ThorbitKnowledgeBaseMcpToolName } from './thorbit-kb-mcp-tool-names.js'\n\nfunction summarizeResult(toolName: ThorbitKnowledgeBaseMcpToolName, result: unknown): string {\n if (toolName === 'thorbit_kb_create' && result && typeof result === 'object' && 'knowledgeBase' in result) {\n const kb = result.knowledgeBase as { name?: unknown; publicId?: unknown }\n return `Created Thorbit knowledge base ${String(kb.name ?? kb.publicId ?? '')}.`\n }\n if (toolName === 'thorbit_kb_list' && result && typeof result === 'object' && 'knowledgeBases' in result) {\n const count = Array.isArray(result.knowledgeBases) ? result.knowledgeBases.length : 0\n return `Found ${count} Thorbit knowledge base${count === 1 ? '' : 's'}.`\n }\n if (toolName.startsWith('thorbit_kb_ingest')) return 'Knowledge-base ingestion completed. Check structuredContent for source receipts.'\n if (toolName === 'thorbit_kb_source_status') return 'Source status returned. Check structuredContent for details.'\n if (toolName === 'thorbit_kb_search') return 'Knowledge-base search completed. Check structuredContent for results and citations.'\n if (toolName === 'thorbit_kb_ask') return 'Knowledge-base answer generated. Check structuredContent for citations and strategy.'\n return 'Thorbit knowledge-base tool completed.'\n}\n\nexport function formatThorbitKbMcpToolResult(\n toolName: ThorbitKnowledgeBaseMcpToolName,\n envelope: ThorbitKnowledgeBaseMcpEnvelope,\n): CallToolResult {\n if (!envelope.ok) {\n return {\n isError: true,\n content: [{\n type: 'text',\n text: `${envelope.error.code}: ${envelope.error.message}`,\n }],\n structuredContent: envelope,\n }\n }\n\n return {\n content: [{\n type: 'text',\n text: summarizeResult(toolName, envelope.result),\n }],\n structuredContent: envelope.result as Record<string, unknown>,\n }\n}\n","import { z } from 'zod'\n\nconst MetadataSchema = z.record(z.string(), z.unknown())\n\nexport const ThorbitKbCreateInputSchema = {\n name: z.string().min(1).max(255).describe('Name for the new Thorbit knowledge base.'),\n description: z.string().max(2000).optional().describe('Optional description for the new knowledge base.'),\n projectPublicId: z.string().min(1).optional().describe('Optional Thorbit project public ID. Omit to create an org-level knowledge base.'),\n folder: z.string().min(1).max(128).optional().describe('Optional organizational folder, such as research or domains.'),\n}\n\nexport const ThorbitKbListInputSchema = {\n projectPublicId: z.string().min(1).optional().describe('Optional Thorbit project public ID used to narrow knowledge-base listing.'),\n includeGlobal: z.boolean().default(true).describe('Include org-level/global knowledge bases. Default true.'),\n limit: z.number().int().min(1).max(100).default(50).describe('Maximum knowledge bases to return.'),\n}\n\nexport const ThorbitKbSourceStatusInputSchema = {\n sourcePublicIds: z.array(z.string().min(1)).min(1).max(100).describe('Source public IDs returned by Thorbit KB ingestion tools.'),\n}\n\nexport const ThorbitKbIngestUrlInputSchema = {\n knowledgeBasePublicId: z.string().min(1).describe('Target Thorbit knowledge-base public ID.'),\n url: z.string().url().describe('Public URL to extract through MCP Scraper and ingest into Thorbit.'),\n title: z.string().min(1).max(512).optional().describe('Optional title override. Provider title is used when omitted.'),\n mode: z.enum(['append']).default('append').describe('Append a new source version. Refresh mode is intentionally not enabled in V1.'),\n maxCharacters: z.number().int().min(500).max(500000).optional().describe('Optional cap before chunking/vectorization.'),\n metadata: MetadataSchema.optional().describe('Optional metadata stored on the KB source.'),\n}\n\nexport const ThorbitKbIngestSiteInputSchema = {\n knowledgeBasePublicId: z.string().min(1).describe('Target Thorbit knowledge-base public ID.'),\n startUrl: z.string().url().describe('Website start URL. Thorbit maps URLs through MCP Scraper, then ingests selected pages.'),\n includePatterns: z.array(z.string().min(1)).max(20).optional().describe('Optional regex or substring patterns that a mapped URL must match.'),\n excludePatterns: z.array(z.string().min(1)).max(20).optional().describe('Optional regex or substring patterns that remove mapped URLs.'),\n maxPages: z.number().int().min(1).max(100).default(25).describe('Maximum pages to ingest. Default 25, hard cap 100.'),\n mode: z.enum(['append']).default('append').describe('Append source versions. Refresh mode is intentionally not enabled in V1.'),\n metadata: MetadataSchema.optional().describe('Optional metadata stored on each KB source.'),\n}\n\nexport const ThorbitKbIngestYoutubeInputSchema = {\n knowledgeBasePublicId: z.string().min(1).describe('Target Thorbit knowledge-base public ID.'),\n videoUrl: z.string().url().describe('YouTube video URL. Thorbit transcribes through MCP Scraper and vectorizes transcript chunks.'),\n title: z.string().min(1).max(512).optional().describe('Optional title override.'),\n mode: z.enum(['append']).default('append').describe('Append a new source version.'),\n preserveTimestamps: z.boolean().default(true).describe('Store transcript timestamps on chunks when MCP Scraper returns them.'),\n metadata: MetadataSchema.optional().describe('Optional metadata stored on the KB source.'),\n}\n\nexport const ThorbitKbIngestTextInputSchema = {\n knowledgeBasePublicId: z.string().min(1).describe('Target Thorbit knowledge-base public ID.'),\n title: z.string().min(1).max(512).describe('Source title shown in KB citations.'),\n content: z.string().min(1).max(500000).describe('Text or Markdown to chunk, embed, and ingest.'),\n sourceUrl: z.string().url().optional().describe('Optional canonical source URL for citations.'),\n sourceType: z.enum(['manual', 'note', 'markdown']).default('manual').describe('Caller-facing source type. Thorbit stores note/markdown as manual sources in V1.'),\n metadata: MetadataSchema.optional().describe('Optional metadata stored on the KB source.'),\n}\n\nexport const ThorbitKbSearchInputSchema = {\n query: z.string().min(1).max(4000).describe('Search query. Use the user question or a focused retrieval query.'),\n knowledgeBasePublicId: z.string().min(1).optional().describe('Optional target KB. Omit to search visible KBs.'),\n projectPublicId: z.string().min(1).optional().describe('Optional project scope when no KB is specified.'),\n limit: z.number().int().min(1).max(20).default(5).describe('Maximum chunks to return.'),\n includeEntities: z.boolean().default(false).describe('Reserved for entity-rich responses.'),\n searchMode: z.enum(['smart', 'hybrid']).default('smart').describe('smart uses Thorbit intent/rerank retrieval; hybrid uses ANN plus FTS.'),\n}\n\nexport const ThorbitKbAskInputSchema = {\n question: z.string().min(1).max(8000).describe('Question to answer using Thorbit KB context only.'),\n knowledgeBasePublicId: z.string().min(1).optional().describe('Optional target KB. Omit to answer over visible KBs.'),\n projectPublicId: z.string().min(1).optional().describe('Optional project scope when no KB is specified.'),\n answerStyle: z.enum(['concise', 'detailed', 'extractive']).default('concise').describe('Use extractive to return source excerpts without an LLM answer.'),\n limit: z.number().int().min(1).max(20).default(8).describe('Maximum retrieved chunks used for the answer.'),\n requireCitations: z.boolean().default(true).describe('Keep true for grounded answers with citation arrays.'),\n}\n\nexport const ThorbitKnowledgeBaseMcpToolInputSchemas = {\n thorbit_kb_create: ThorbitKbCreateInputSchema,\n thorbit_kb_list: ThorbitKbListInputSchema,\n thorbit_kb_source_status: ThorbitKbSourceStatusInputSchema,\n thorbit_kb_ingest_url: ThorbitKbIngestUrlInputSchema,\n thorbit_kb_ingest_site: ThorbitKbIngestSiteInputSchema,\n thorbit_kb_ingest_youtube: ThorbitKbIngestYoutubeInputSchema,\n thorbit_kb_ingest_text: ThorbitKbIngestTextInputSchema,\n thorbit_kb_search: ThorbitKbSearchInputSchema,\n thorbit_kb_ask: ThorbitKbAskInputSchema,\n}\n","import { readFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\n\nexport type ThorbitKbMcpEnv = {\n apiKey: string\n baseUrl: string\n}\n\nfunction readApiKeyFile(): string | undefined {\n const explicitPath = process.env.THORBIT_KB_MCP_KEY_PATH?.trim()\n const paths = [explicitPath, join(homedir(), '.thorbit-kb-mcp-key')].filter(Boolean) as string[]\n for (const path of paths) {\n try {\n const value = readFileSync(path, 'utf8').trim()\n if (value) return value\n } catch {\n continue\n }\n }\n return undefined\n}\n\nexport function resolveThorbitKbMcpEnv(): ThorbitKbMcpEnv {\n const apiKey = (\n process.env.THORBIT_API_KEY ||\n process.env.THORBIT_MCP_API_KEY ||\n process.env.THORBIT_KB_MCP_API_KEY ||\n readApiKeyFile()\n )?.trim()\n\n if (!apiKey) {\n throw new Error('THORBIT_API_KEY, THORBIT_MCP_API_KEY, or ~/.thorbit-kb-mcp-key is required')\n }\n\n return {\n apiKey,\n baseUrl: (process.env.THORBIT_BASE_URL || process.env.THORBIT_KB_MCP_BASE_URL || 'https://thorbit.ai').trim(),\n }\n}\n","export const ThorbitKnowledgeBaseMcpToolNames = [\n 'thorbit_kb_create',\n 'thorbit_kb_list',\n 'thorbit_kb_source_status',\n 'thorbit_kb_ingest_url',\n 'thorbit_kb_ingest_site',\n 'thorbit_kb_ingest_youtube',\n 'thorbit_kb_ingest_text',\n 'thorbit_kb_search',\n 'thorbit_kb_ask',\n] as const\n\nexport type ThorbitKnowledgeBaseMcpToolName = typeof ThorbitKnowledgeBaseMcpToolNames[number]\n"],"mappings":";;;AAoBO,IAAM,gCAAN,MAAoC;AAAA,EACxB;AAAA,EACA;AAAA,EAEjB,YAAY,SAA8C;AACxD,SAAK,UAAU,QAAQ,QAAQ,QAAQ,OAAO,EAAE;AAChD,SAAK,SAAS,QAAQ;AAAA,EACxB;AAAA,EAEA,MAAM,SAAS,UAA2C,OAA0D;AAClH,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,8BAA8B,QAAQ,IAAI;AAAA,MACpF,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,qBAAqB,KAAK;AAAA,QAC1B,gBAAgB;AAAA,MAClB;AAAA,MACA,MAAM,KAAK,UAAU,SAAS,CAAC,CAAC;AAAA,IAClC,CAAC;AAED,UAAM,OAAO,MAAM,SAAS,KAAK,EAAE,MAAM,MAAM,IAAI;AACnD,QAAI,QAAQ,OAAO,SAAS,YAAY,QAAQ,KAAM,QAAO;AAE7D,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,WAAW;AAAA,MACX,OAAO;AAAA,QACL,MAAM,SAAS,KAAK,qBAAqB,QAAQ,SAAS,MAAM;AAAA,QAChE,SAAS,SAAS,KAAK,6CAA6C,wCAAwC,SAAS,MAAM;AAAA,MAC7H;AAAA,IACF;AAAA,EACF;AACF;;;ACnDA,SAAS,WAAW,wBAAwB;;;ACI5C,SAAS,gBAAgB,UAA2C,QAAyB;AAC3F,MAAI,aAAa,uBAAuB,UAAU,OAAO,WAAW,YAAY,mBAAmB,QAAQ;AACzG,UAAM,KAAK,OAAO;AAClB,WAAO,kCAAkC,OAAO,GAAG,QAAQ,GAAG,YAAY,EAAE,CAAC;AAAA,EAC/E;AACA,MAAI,aAAa,qBAAqB,UAAU,OAAO,WAAW,YAAY,oBAAoB,QAAQ;AACxG,UAAM,QAAQ,MAAM,QAAQ,OAAO,cAAc,IAAI,OAAO,eAAe,SAAS;AACpF,WAAO,SAAS,KAAK,0BAA0B,UAAU,IAAI,KAAK,GAAG;AAAA,EACvE;AACA,MAAI,SAAS,WAAW,mBAAmB,EAAG,QAAO;AACrD,MAAI,aAAa,2BAA4B,QAAO;AACpD,MAAI,aAAa,oBAAqB,QAAO;AAC7C,MAAI,aAAa,iBAAkB,QAAO;AAC1C,SAAO;AACT;AAEO,SAAS,6BACd,UACA,UACgB;AAChB,MAAI,CAAC,SAAS,IAAI;AAChB,WAAO;AAAA,MACL,SAAS;AAAA,MACT,SAAS,CAAC;AAAA,QACR,MAAM;AAAA,QACN,MAAM,GAAG,SAAS,MAAM,IAAI,KAAK,SAAS,MAAM,OAAO;AAAA,MACzD,CAAC;AAAA,MACD,mBAAmB;AAAA,IACrB;AAAA,EACF;AAEA,SAAO;AAAA,IACL,SAAS,CAAC;AAAA,MACR,MAAM;AAAA,MACN,MAAM,gBAAgB,UAAU,SAAS,MAAM;AAAA,IACjD,CAAC;AAAA,IACD,mBAAmB,SAAS;AAAA,EAC9B;AACF;;;AC1CA,SAAS,SAAS;AAElB,IAAM,iBAAiB,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC;AAEhD,IAAM,6BAA6B;AAAA,EACxC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,0CAA0C;AAAA,EACpF,aAAa,EAAE,OAAO,EAAE,IAAI,GAAI,EAAE,SAAS,EAAE,SAAS,kDAAkD;AAAA,EACxG,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS,EAAE,SAAS,iFAAiF;AAAA,EACxI,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,8DAA8D;AACvH;AAEO,IAAM,2BAA2B;AAAA,EACtC,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS,EAAE,SAAS,2EAA2E;AAAA,EAClI,eAAe,EAAE,QAAQ,EAAE,QAAQ,IAAI,EAAE,SAAS,yDAAyD;AAAA,EAC3G,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,QAAQ,EAAE,EAAE,SAAS,oCAAoC;AACnG;AAEO,IAAM,mCAAmC;AAAA,EAC9C,iBAAiB,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,2DAA2D;AAClI;AAEO,IAAM,gCAAgC;AAAA,EAC3C,uBAAuB,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS,0CAA0C;AAAA,EAC5F,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,oEAAoE;AAAA,EACnG,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,+DAA+D;AAAA,EACrH,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC,EAAE,QAAQ,QAAQ,EAAE,SAAS,+EAA+E;AAAA,EACnI,eAAe,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,GAAG,EAAE,IAAI,GAAM,EAAE,SAAS,EAAE,SAAS,6CAA6C;AAAA,EACtH,UAAU,eAAe,SAAS,EAAE,SAAS,4CAA4C;AAC3F;AAEO,IAAM,iCAAiC;AAAA,EAC5C,uBAAuB,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS,0CAA0C;AAAA,EAC5F,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,wFAAwF;AAAA,EAC5H,iBAAiB,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,SAAS,oEAAoE;AAAA,EAC5I,iBAAiB,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,SAAS,+DAA+D;AAAA,EACvI,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,QAAQ,EAAE,EAAE,SAAS,oDAAoD;AAAA,EACpH,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC,EAAE,QAAQ,QAAQ,EAAE,SAAS,0EAA0E;AAAA,EAC9H,UAAU,eAAe,SAAS,EAAE,SAAS,6CAA6C;AAC5F;AAEO,IAAM,oCAAoC;AAAA,EAC/C,uBAAuB,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS,0CAA0C;AAAA,EAC5F,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,8FAA8F;AAAA,EAClI,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,0BAA0B;AAAA,EAChF,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC,EAAE,QAAQ,QAAQ,EAAE,SAAS,8BAA8B;AAAA,EAClF,oBAAoB,EAAE,QAAQ,EAAE,QAAQ,IAAI,EAAE,SAAS,sEAAsE;AAAA,EAC7H,UAAU,eAAe,SAAS,EAAE,SAAS,4CAA4C;AAC3F;AAEO,IAAM,iCAAiC;AAAA,EAC5C,uBAAuB,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS,0CAA0C;AAAA,EAC5F,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,qCAAqC;AAAA,EAChF,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAM,EAAE,SAAS,+CAA+C;AAAA,EAC/F,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,8CAA8C;AAAA,EAC9F,YAAY,EAAE,KAAK,CAAC,UAAU,QAAQ,UAAU,CAAC,EAAE,QAAQ,QAAQ,EAAE,SAAS,kFAAkF;AAAA,EAChK,UAAU,eAAe,SAAS,EAAE,SAAS,4CAA4C;AAC3F;AAEO,IAAM,6BAA6B;AAAA,EACxC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAI,EAAE,SAAS,mEAAmE;AAAA,EAC/G,uBAAuB,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS,EAAE,SAAS,iDAAiD;AAAA,EAC9G,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS,EAAE,SAAS,iDAAiD;AAAA,EACxG,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,QAAQ,CAAC,EAAE,SAAS,2BAA2B;AAAA,EACtF,iBAAiB,EAAE,QAAQ,EAAE,QAAQ,KAAK,EAAE,SAAS,qCAAqC;AAAA,EAC1F,YAAY,EAAE,KAAK,CAAC,SAAS,QAAQ,CAAC,EAAE,QAAQ,OAAO,EAAE,SAAS,uEAAuE;AAC3I;AAEO,IAAM,0BAA0B;AAAA,EACrC,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAI,EAAE,SAAS,mDAAmD;AAAA,EAClG,uBAAuB,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS,EAAE,SAAS,sDAAsD;AAAA,EACnH,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS,EAAE,SAAS,iDAAiD;AAAA,EACxG,aAAa,EAAE,KAAK,CAAC,WAAW,YAAY,YAAY,CAAC,EAAE,QAAQ,SAAS,EAAE,SAAS,iEAAiE;AAAA,EACxJ,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,QAAQ,CAAC,EAAE,SAAS,+CAA+C;AAAA,EAC1G,kBAAkB,EAAE,QAAQ,EAAE,QAAQ,IAAI,EAAE,SAAS,sDAAsD;AAC7G;AAEO,IAAM,0CAA0C;AAAA,EACrD,mBAAmB;AAAA,EACnB,iBAAiB;AAAA,EACjB,0BAA0B;AAAA,EAC1B,uBAAuB;AAAA,EACvB,wBAAwB;AAAA,EACxB,2BAA2B;AAAA,EAC3B,wBAAwB;AAAA,EACxB,mBAAmB;AAAA,EACnB,gBAAgB;AAClB;;;AFpEA,IAAM,UAAU;AAShB,SAAS,oBAAoB,OAAe,aAAa,MAAM;AAC7D,SAAO;AAAA,IACL;AAAA,IACA,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AACF;AAEA,SAAS,kBAAkB,OAAe,eAAwB;AAChE,SAAO;AAAA,IACL;AAAA,IACA,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB;AAAA,EACF;AACF;AAEO,IAAM,sBAAsB;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,IAAI;AAWJ,SAAS,mCAAmC,SAA+D;AAChH,QAAM,WAA8B,CAAC,UAAU,UAAU,QAAQ,SAAS,UAAU,KAAK;AACzF,QAAM,SAAS,IAAI,UAAU,EAAE,MAAM,kBAAkB,SAAS,QAAQ,GAAG,EAAE,cAAc,oBAAoB,CAAC;AAEhH,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,MACE,OAAO;AAAA,MACP,aAAa;AAAA,MACb,UAAU;AAAA,IACZ;AAAA,IACA,OAAO,QAAQ;AACb,YAAM,WAAW,MAAM,SAAS,mBAAmB,CAAC,CAAC;AACrD,aAAO,EAAE,UAAU,CAAC,EAAE,KAAK,IAAI,MAAM,UAAU,oBAAoB,MAAM,KAAK,UAAU,UAAU,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAChH;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA,IAAI,iBAAiB,yCAAyC,EAAE,MAAM,OAAU,CAAC;AAAA,IACjF;AAAA,MACE,OAAO;AAAA,MACP,aAAa;AAAA,MACb,UAAU;AAAA,IACZ;AAAA,IACA,OAAO,KAAK,cAAc;AACxB,YAAM,iBAAiB,MAAM,QAAQ,UAAU,cAAc,IAAI,UAAU,eAAe,CAAC,IAAI,UAAU;AACzG,YAAM,WAAW,MAAM,SAAS,4BAA4B,EAAE,iBAAiB,CAAC,OAAO,cAAc,CAAC,EAAE,CAAC;AACzG,aAAO,EAAE,UAAU,CAAC,EAAE,KAAK,IAAI,MAAM,UAAU,oBAAoB,MAAM,KAAK,UAAU,UAAU,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAChH;AAAA,EACF;AAEA,WAAS,aACP,UACA,QACM;AACN,WAAO,aAAa,UAAU,QAAQ,OAAO,UAAU;AACrD,YAAM,WAAW,MAAM,SAAS,UAAU,KAAK;AAC/C,aAAO,6BAA6B,UAAU,QAAQ;AAAA,IACxD,CAAC;AAAA,EACH;AAEA,eAAa,qBAAqB;AAAA,IAChC,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa;AAAA,IACb,aAAa,kBAAkB,iCAAiC,KAAK;AAAA,EACvE,CAAC;AAED,eAAa,mBAAmB;AAAA,IAC9B,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa;AAAA,IACb,aAAa,oBAAoB,8BAA8B;AAAA,EACjE,CAAC;AAED,eAAa,4BAA4B;AAAA,IACvC,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa;AAAA,IACb,aAAa,oBAAoB,+BAA+B;AAAA,EAClE,CAAC;AAED,eAAa,yBAAyB;AAAA,IACpC,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa;AAAA,IACb,aAAa,kBAAkB,8BAA8B,IAAI;AAAA,EACnE,CAAC;AAED,eAAa,0BAA0B;AAAA,IACrC,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa;AAAA,IACb,aAAa,kBAAkB,kCAAkC,IAAI;AAAA,EACvE,CAAC;AAED,eAAa,6BAA6B;AAAA,IACxC,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa;AAAA,IACb,aAAa,kBAAkB,kCAAkC,IAAI;AAAA,EACvE,CAAC;AAED,eAAa,0BAA0B;AAAA,IACrC,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa;AAAA,IACb,aAAa,kBAAkB,+BAA+B,KAAK;AAAA,EACrE,CAAC;AAED,eAAa,qBAAqB;AAAA,IAChC,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa;AAAA,IACb,aAAa,oBAAoB,+BAA+B;AAAA,EAClE,CAAC;AAED,eAAa,kBAAkB;AAAA,IAC7B,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa;AAAA,IACb,aAAa,oBAAoB,8BAA8B,KAAK;AAAA,EACtE,CAAC;AAED,SAAO;AACT;;;AGvLA,SAAS,oBAAoB;AAC7B,SAAS,eAAe;AACxB,SAAS,YAAY;AAOrB,SAAS,iBAAqC;AAC5C,QAAM,eAAe,QAAQ,IAAI,yBAAyB,KAAK;AAC/D,QAAM,QAAQ,CAAC,cAAc,KAAK,QAAQ,GAAG,qBAAqB,CAAC,EAAE,OAAO,OAAO;AACnF,aAAW,QAAQ,OAAO;AACxB,QAAI;AACF,YAAM,QAAQ,aAAa,MAAM,MAAM,EAAE,KAAK;AAC9C,UAAI,MAAO,QAAO;AAAA,IACpB,QAAQ;AACN;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,yBAA0C;AACxD,QAAM,UACJ,QAAQ,IAAI,mBACZ,QAAQ,IAAI,uBACZ,QAAQ,IAAI,0BACZ,eAAe,IACd,KAAK;AAER,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,MAAM,4EAA4E;AAAA,EAC9F;AAEA,SAAO;AAAA,IACL;AAAA,IACA,UAAU,QAAQ,IAAI,oBAAoB,QAAQ,IAAI,2BAA2B,sBAAsB,KAAK;AAAA,EAC9G;AACF;;;ACvCO,IAAM,mCAAmC;AAAA,EAC9C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thorbit-kb-mcp",
3
- "version": "0.2.7",
3
+ "version": "0.2.8",
4
4
  "description": "MCP server for Thorbit Knowledge Base ingestion, search, and grounded answers",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",