@docrouter/mcp 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -197,13 +197,14 @@ function validateSchemaFormat(schema) {
197
197
  errors.push("Schema must be an object");
198
198
  return { valid: false, errors, warnings };
199
199
  }
200
- if (!schema.type || schema.type !== "json_schema") {
200
+ const schemaObj = schema;
201
+ if (!schemaObj.type || schemaObj.type !== "json_schema") {
201
202
  errors.push('Schema must have type: "json_schema"');
202
203
  }
203
- if (!schema.json_schema || typeof schema.json_schema !== "object") {
204
+ if (!schemaObj.json_schema || typeof schemaObj.json_schema !== "object") {
204
205
  errors.push("Schema must have json_schema object");
205
206
  } else {
206
- const jsonSchema = schema.json_schema;
207
+ const jsonSchema = schemaObj.json_schema;
207
208
  if (!jsonSchema.name || typeof jsonSchema.name !== "string") {
208
209
  errors.push("json_schema must have a name field");
209
210
  }
@@ -245,8 +246,14 @@ function validateSchemaFormat(schema) {
245
246
  }
246
247
  }
247
248
  }
248
- if (schema.json_schema?.schema?.properties) {
249
- checkForNonPortableFeatures(schema.json_schema.schema.properties, warnings);
249
+ if (schemaObj.json_schema && typeof schemaObj.json_schema === "object") {
250
+ const jsonSchema = schemaObj.json_schema;
251
+ if (jsonSchema.schema && typeof jsonSchema.schema === "object") {
252
+ const innerSchema = jsonSchema.schema;
253
+ if (innerSchema.properties) {
254
+ checkForNonPortableFeatures(innerSchema.properties, warnings);
255
+ }
256
+ }
250
257
  }
251
258
  } catch (error) {
252
259
  errors.push(`Schema validation error: ${error instanceof Error ? error.message : "Unknown error"}`);
@@ -276,18 +283,19 @@ function validateNestedObjects(properties, errors, warnings) {
276
283
  }
277
284
  }
278
285
  if (prop.type === "array" && prop.items) {
279
- if (prop.items.type === "object") {
280
- if (!prop.items.properties || typeof prop.items.properties !== "object") {
286
+ const items = prop.items;
287
+ if (items.type === "object") {
288
+ if (!items.properties || typeof items.properties !== "object") {
281
289
  errors.push(`Array items object "${propName}" must have properties object`);
282
290
  }
283
- if (!Array.isArray(prop.items.required)) {
291
+ if (!Array.isArray(items.required)) {
284
292
  errors.push(`Array items object "${propName}" must have required array`);
285
293
  }
286
- if (prop.items.additionalProperties !== false) {
294
+ if (items.additionalProperties !== false) {
287
295
  errors.push(`Array items object "${propName}" must have additionalProperties: false`);
288
296
  }
289
- if (prop.items.properties) {
290
- validateNestedObjects(prop.items.properties, errors);
297
+ if (items.properties) {
298
+ validateNestedObjects(items.properties, errors);
291
299
  }
292
300
  }
293
301
  }
@@ -316,8 +324,11 @@ function checkForNonPortableFeatures(properties, warnings) {
316
324
  if (prop.type === "object" && prop.properties) {
317
325
  checkForNonPortableFeatures(prop.properties, warnings);
318
326
  }
319
- if (prop.type === "array" && prop.items && prop.items.type === "object" && prop.items.properties) {
320
- checkForNonPortableFeatures(prop.items.properties, warnings);
327
+ if (prop.type === "array" && prop.items) {
328
+ const items = prop.items;
329
+ if (items.type === "object" && items.properties) {
330
+ checkForNonPortableFeatures(items.properties, warnings);
331
+ }
321
332
  }
322
333
  }
323
334
  }
@@ -330,13 +341,14 @@ function validateFormFormat(form) {
330
341
  errors.push("Form must be an object");
331
342
  return { valid: false, errors, warnings };
332
343
  }
333
- if (!form.json_formio || !Array.isArray(form.json_formio)) {
344
+ const formObj = form;
345
+ if (!formObj.json_formio || !Array.isArray(formObj.json_formio)) {
334
346
  errors.push("Form must have json_formio array");
335
347
  return { valid: false, errors, warnings };
336
348
  }
337
- validateFormComponents(form.json_formio, errors, warnings, "");
338
- if (form.json_formio_mapping) {
339
- validateFieldMappings(form.json_formio_mapping, form.json_formio, errors, warnings);
349
+ validateFormComponents(formObj.json_formio, errors, warnings, "");
350
+ if (formObj.json_formio_mapping) {
351
+ validateFieldMappings(formObj.json_formio_mapping, formObj.json_formio, errors, warnings);
340
352
  }
341
353
  } catch (error) {
342
354
  errors.push(`Form validation error: ${error instanceof Error ? error.message : "Unknown error"}`);
@@ -377,49 +389,50 @@ function validateFormComponents(components, errors, warnings, path) {
377
389
  errors.push(`${componentPath}: Component must be an object`);
378
390
  continue;
379
391
  }
380
- if (!component.type) {
392
+ const comp = component;
393
+ if (!comp.type) {
381
394
  errors.push(`${componentPath}: Component must have a "type" field`);
382
- } else if (!validFieldTypes.includes(component.type)) {
383
- warnings.push(`${componentPath}: Unknown field type "${component.type}" - may not render correctly`);
395
+ } else if (!validFieldTypes.includes(comp.type)) {
396
+ warnings.push(`${componentPath}: Unknown field type "${comp.type}" - may not render correctly`);
384
397
  }
385
- if (component.input === true || ["textfield", "email", "number", "select", "textarea", "checkbox", "datetime", "phoneNumber"].includes(component.type)) {
386
- if (!component.key) {
398
+ if (comp.input === true || ["textfield", "email", "number", "select", "textarea", "checkbox", "datetime", "phoneNumber"].includes(comp.type)) {
399
+ if (!comp.key) {
387
400
  errors.push(`${componentPath}: Input component must have a "key" field`);
388
401
  } else {
389
- if (collectedKeys.has(component.key)) {
390
- errors.push(`${componentPath}: Duplicate key "${component.key}" found`);
402
+ if (collectedKeys.has(comp.key)) {
403
+ errors.push(`${componentPath}: Duplicate key "${comp.key}" found`);
391
404
  }
392
- collectedKeys.add(component.key);
393
- if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(component.key)) {
394
- warnings.push(`${componentPath}: Key "${component.key}" should be a valid identifier (alphanumeric and underscore only)`);
405
+ collectedKeys.add(comp.key);
406
+ if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(comp.key)) {
407
+ warnings.push(`${componentPath}: Key "${comp.key}" should be a valid identifier (alphanumeric and underscore only)`);
395
408
  }
396
409
  }
397
- if (!component.label) {
410
+ if (!comp.label) {
398
411
  warnings.push(`${componentPath}: Input component should have a "label" field for better UX`);
399
412
  }
400
413
  }
401
- if (component.type === "select") {
402
- if (!component.data || !component.data.values) {
414
+ if (comp.type === "select") {
415
+ if (!comp.data || !comp.data.values) {
403
416
  errors.push(`${componentPath}: Select field must have data.values array`);
404
- } else if (!Array.isArray(component.data.values)) {
417
+ } else if (!Array.isArray(comp.data.values)) {
405
418
  errors.push(`${componentPath}: data.values must be an array`);
406
- } else if (component.data.values.length === 0) {
419
+ } else if (comp.data.values.length === 0) {
407
420
  warnings.push(`${componentPath}: Select field has empty values array`);
408
421
  }
409
422
  }
410
- if (component.type === "panel" || component.type === "fieldset") {
411
- if (!component.components || !Array.isArray(component.components)) {
412
- errors.push(`${componentPath}: ${component.type} must have components array`);
423
+ if (comp.type === "panel" || comp.type === "fieldset") {
424
+ if (!comp.components || !Array.isArray(comp.components)) {
425
+ errors.push(`${componentPath}: ${comp.type} must have components array`);
413
426
  } else {
414
- validateFormComponents(component.components, errors, warnings, `${componentPath}.components`);
427
+ validateFormComponents(comp.components, errors, warnings, `${componentPath}.components`);
415
428
  }
416
429
  }
417
- if (component.type === "columns") {
418
- if (!component.columns || !Array.isArray(component.columns)) {
430
+ if (comp.type === "columns") {
431
+ if (!comp.columns || !Array.isArray(comp.columns)) {
419
432
  errors.push(`${componentPath}: columns layout must have columns array`);
420
433
  } else {
421
- for (let j = 0; j < component.columns.length; j++) {
422
- const column = component.columns[j];
434
+ for (let j = 0; j < comp.columns.length; j++) {
435
+ const column = comp.columns[j];
423
436
  if (!column.components || !Array.isArray(column.components)) {
424
437
  errors.push(`${componentPath}.columns[${j}]: Column must have components array`);
425
438
  } else {
@@ -428,8 +441,8 @@ function validateFormComponents(components, errors, warnings, path) {
428
441
  }
429
442
  }
430
443
  }
431
- if (component.validate) {
432
- if (typeof component.validate !== "object") {
444
+ if (comp.validate) {
445
+ if (typeof comp.validate !== "object") {
433
446
  errors.push(`${componentPath}: validate must be an object`);
434
447
  }
435
448
  }
@@ -443,11 +456,13 @@ function validateFieldMappings(mappings, formComponents, errors, warnings) {
443
456
  const formKeys = /* @__PURE__ */ new Set();
444
457
  const collectKeys = (components) => {
445
458
  for (const comp of components) {
446
- if (comp.key) formKeys.add(comp.key);
447
- if (comp.components) collectKeys(comp.components);
448
- if (comp.columns) {
449
- for (const col of comp.columns) {
450
- if (col.components) collectKeys(col.components);
459
+ const compObj = comp;
460
+ if (compObj.key) formKeys.add(compObj.key);
461
+ if (compObj.components) collectKeys(compObj.components);
462
+ if (compObj.columns) {
463
+ for (const col of compObj.columns) {
464
+ const colObj = col;
465
+ if (colObj.components) collectKeys(colObj.components);
451
466
  }
452
467
  }
453
468
  }
@@ -503,11 +518,11 @@ var tools = [
503
518
  type: "object",
504
519
  properties: {
505
520
  name: { type: "string", description: "Document name" },
506
- content: { type: "string", description: "Base64 encoded document content" },
507
- type: { type: "string", description: "Document type (pdf, image, etc.)" },
521
+ content: { type: "string", description: "Base64 encoded document content (supports both plain base64 and data URLs)" },
522
+ tag_ids: { type: "array", items: { type: "string" }, description: "Optional list of tag IDs" },
508
523
  metadata: { type: "object", description: "Optional metadata" }
509
524
  },
510
- required: ["name", "content", "type"]
525
+ required: ["name", "content"]
511
526
  }
512
527
  }
513
528
  },
@@ -1005,7 +1020,7 @@ var tools = [
1005
1020
  max_tokens: { type: "number", description: "Maximum tokens" },
1006
1021
  stream: { type: "boolean", description: "Enable streaming" }
1007
1022
  },
1008
- required: ["messages"]
1023
+ required: ["messages", "model"]
1009
1024
  }
1010
1025
  },
1011
1026
  // ========== HELPER TOOLS ==========
@@ -1206,11 +1221,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
1206
1221
  // ========== DOCUMENTS ==========
1207
1222
  case "upload_documents": {
1208
1223
  const documentsInput = getArg(args, "documents");
1209
- const documents = documentsInput.map((doc) => ({
1210
- ...doc,
1211
- content: Buffer.from(doc.content, "base64")
1212
- }));
1213
- const result = await docrouterClient.uploadDocuments({ documents });
1224
+ const result = await docrouterClient.uploadDocuments({ documents: documentsInput });
1214
1225
  return {
1215
1226
  content: [
1216
1227
  {
@@ -1636,7 +1647,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
1636
1647
  case "run_llm_chat": {
1637
1648
  const result = await docrouterClient.runLLMChat({
1638
1649
  messages: getArg(args, "messages"),
1639
- model: getOptionalArg(args, "model"),
1650
+ model: getArg(args, "model"),
1640
1651
  temperature: getOptionalArg(args, "temperature"),
1641
1652
  max_tokens: getOptionalArg(args, "max_tokens"),
1642
1653
  stream: getOptionalArg(args, "stream")
@@ -1757,9 +1768,9 @@ This server provides access to DocRouter resources and tools.
1757
1768
  }
1758
1769
  case "help_prompts": {
1759
1770
  try {
1760
- const __filename = fileURLToPath(import.meta.url);
1761
- const __dirname = dirname(__filename);
1762
- const promptsPath = join(__dirname, "docs/knowledge_base/prompts.md");
1771
+ const currentFile = fileURLToPath(import.meta.url);
1772
+ const currentDir = dirname(currentFile);
1773
+ const promptsPath = join(currentDir, "docs/knowledge_base/prompts.md");
1763
1774
  const promptsContent = readFileSync(promptsPath, "utf-8");
1764
1775
  return {
1765
1776
  content: [
@@ -1783,9 +1794,9 @@ This server provides access to DocRouter resources and tools.
1783
1794
  }
1784
1795
  case "help_schemas": {
1785
1796
  try {
1786
- const __filename = fileURLToPath(import.meta.url);
1787
- const __dirname = dirname(__filename);
1788
- const schemasPath = join(__dirname, "docs/knowledge_base/schemas.md");
1797
+ const currentFile = fileURLToPath(import.meta.url);
1798
+ const currentDir = dirname(currentFile);
1799
+ const schemasPath = join(currentDir, "docs/knowledge_base/schemas.md");
1789
1800
  const schemasContent = readFileSync(schemasPath, "utf-8");
1790
1801
  return {
1791
1802
  content: [
@@ -1809,9 +1820,9 @@ This server provides access to DocRouter resources and tools.
1809
1820
  }
1810
1821
  case "help_forms": {
1811
1822
  try {
1812
- const __filename = fileURLToPath(import.meta.url);
1813
- const __dirname = dirname(__filename);
1814
- const formsPath = join(__dirname, "docs/knowledge_base/forms.md");
1823
+ const currentFile = fileURLToPath(import.meta.url);
1824
+ const currentDir = dirname(currentFile);
1825
+ const formsPath = join(currentDir, "docs/knowledge_base/forms.md");
1815
1826
  const formsContent = readFileSync(formsPath, "utf-8");
1816
1827
  return {
1817
1828
  content: [