@kadoa/mcp 0.5.15 → 0.5.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +19 -14
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -52171,7 +52171,8 @@ function mapRunStatus(state) {
52171
52171
  case "NOT_SUPPORTED":
52172
52172
  return "failed";
52173
52173
  default:
52174
- return "failed";
52174
+ console.error(`[list_workflow_runs] unmapped run state, passing through verbatim: ${state}`);
52175
+ return state ?? "unknown";
52175
52176
  }
52176
52177
  }
52177
52178
  function workflowDashboardUrl(workflowId) {
@@ -52397,7 +52398,7 @@ function registerTools(server, ctx, capabilities) {
52397
52398
  prompt: exports_external.string().optional().describe('Natural language description of what to extract (e.g., "Extract product prices and names"). Required unless templateId is provided.'),
52398
52399
  name: exports_external.string().optional().describe("Optional name for the workflow"),
52399
52400
  entity: exports_external.string().optional().describe("Entity name for extraction (e.g., 'Product', 'Job Posting')"),
52400
- schema: exports_external.preprocess(coerceArray(), exports_external.array(exports_external.object(SchemaFieldShape))).optional().describe("Extraction schema fields. If omitted, the AI agent auto-detects the schema.")
52401
+ schema: exports_external.preprocess(coerceArray(), exports_external.array(exports_external.object(SchemaFieldShape).strict())).optional().describe("Extraction schema fields. If omitted, the AI agent auto-detects the schema. When you do supply fields, mark the one that identifies a record with isKey — change detection needs it.")
52401
52402
  };
52402
52403
  const webhookAuthShape = exports_external.object({
52403
52404
  type: exports_external.enum(["bearer", "basic", "header"]).describe("Authentication type"),
@@ -52769,7 +52770,7 @@ function registerTools(server, ctx, capabilities) {
52769
52770
  });
52770
52771
  }));
52771
52772
  server.registerTool("list_workflow_runs", {
52772
- description: "List a workflow's execution run history — each run's status, start/finish time, " + "record count, and errors. Use to answer 'when did this last succeed?' " + "(status='success', limit=1) or 'recent success/failure pattern?'. Distinct from " + "get_workflow_history, which is the config audit log.",
52773
+ description: "List a workflow's execution run history — each run's status, start/finish time, " + "record count, and errors. Use to answer 'when did this last succeed?' " + "(status='success', limit=1) or 'recent success/failure pattern?'. Distinct from " + "get_workflow_history, which is the config audit log. `status` is normally " + "success | failed | in_progress; a run whose backend state this server does not " + "recognize reports that raw state verbatim, so treat any other value as unknown " + "rather than as a failure.",
52773
52774
  inputSchema: {
52774
52775
  workflowId: exports_external.string().describe("The workflow ID"),
52775
52776
  status: exports_external.enum(["success", "failed", "in_progress"]).optional().describe("Filter runs by outcome"),
@@ -52998,13 +52999,15 @@ function registerTools(server, ctx, capabilities) {
52998
52999
  server.registerTool("update_workflow", {
52999
53000
  description: `Update a workflow's configuration. All fields are optional — only provided fields will be updated. Use this to change the name, URLs, extraction schema, entity, prompt, schedule, or other metadata.
53000
53001
 
53001
- ` + "IMPORTANT: You cannot change a workflow's interval to or from REAL_TIME. Real-time workflows are architecturally different (Observer service vs Scraper) and must be created as real-time from the start using create_workflow with interval='REAL_TIME'. To switch a workflow between real-time and regular, delete it and create a new one with the correct interval.",
53002
+ ` + `IMPORTANT: You cannot change a workflow's interval to or from REAL_TIME. Real-time workflows are architecturally different (Observer service vs Scraper) and must be created as real-time from the start using create_workflow with interval='REAL_TIME'. To switch a workflow between real-time and regular, delete it and create a new one with the correct interval.
53003
+
53004
+ ` + "PROMPT EDITS: `userPrompt` works on most workflows and re-derives the extraction intent. Some agent-built (Shelly) scheduled workflows reject it with `SHELLY_INTENT_REQUIRES_EXTRACTION_SPEC` because their intent is owned elsewhere. " + "If that happens, tell the user to change the extraction intent in Lighthouse chat in the Kadoa dashboard. NEVER delete and recreate the workflow to work around it — that mints a new workflowId, breaking anything downstream keyed to the old one (warehouse tables, connectors) and discarding the workflow's history.",
53002
53005
  inputSchema: strictSchema({
53003
53006
  workflowId: exports_external.string().describe("The workflow ID to update"),
53004
53007
  name: exports_external.string().optional().describe("New name for the workflow"),
53005
53008
  urls: exports_external.preprocess(coerceArray(true), exports_external.array(exports_external.string()).min(1)).optional().describe("New target URLs for the workflow (array of strings). Also accepts a single URL string."),
53006
53009
  entity: exports_external.string().optional().describe("Entity name for extraction (e.g., 'Product', 'Job Posting')"),
53007
- schema: exports_external.preprocess(coerceArray(), exports_external.array(exports_external.object(SchemaFieldShape))).optional().describe("New extraction schema fields"),
53010
+ schema: exports_external.preprocess(coerceArray(), exports_external.array(exports_external.object(SchemaFieldShape).strict())).optional().describe("New extraction schema fields. This REPLACES the whole schema — list every field you want to keep, each with its isKey flag, or the omitted ones and their flags are lost. Call get_workflow first and edit the schema it returns."),
53008
53011
  description: exports_external.string().max(500).optional().describe("Workflow description (max 500 characters)"),
53009
53012
  tags: exports_external.preprocess(coerceArray(true), exports_external.array(exports_external.string())).optional().describe("Tags for organizing workflows"),
53010
53013
  userPrompt: exports_external.string().optional().describe("Navigation prompt for agentic-navigation mode (10-5000 characters)"),
@@ -53471,11 +53474,13 @@ function registerTools(server, ctx, capabilities) {
53471
53474
  });
53472
53475
  }));
53473
53476
  server.registerTool("update_template", {
53474
- description: "Update a template's name or description. At least one field must be provided.",
53477
+ description: `Update a template's name or description ONLY. At least one of the two must be provided.
53478
+
53479
+ ` + "This tool CANNOT change what linked workflows inherit — prompt, schema, validation rules, notifications and frequency all live in template *versions*, which are immutable snapshots. " + "To change any of those, publish a new version with `create_template_version` (the version IS the edit), then roll it out to linked workflows with `apply_template_version`. " + "There is no in-place edit of a published version, and never report a prompt or schema change as impossible — versioning is the supported path.",
53475
53480
  inputSchema: strictSchema({
53476
53481
  templateId: exports_external.string().describe("The template ID to update"),
53477
- name: exports_external.preprocess(coerceNull(), exports_external.string().optional()).describe("New template name"),
53478
- description: exports_external.preprocess(coerceNull(), exports_external.string().optional()).describe("New template description")
53482
+ name: exports_external.preprocess(coerceNull(), exports_external.string().optional()).optional().describe("New template name"),
53483
+ description: exports_external.preprocess(coerceNull(), exports_external.string().optional()).optional().describe("New template description")
53479
53484
  }),
53480
53485
  annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true }
53481
53486
  }, withErrorHandling("update_template", async (args) => {
@@ -53527,12 +53532,14 @@ function registerTools(server, ctx, capabilities) {
53527
53532
  }))).optional().describe("Predefined categories for a CLASSIFICATION field ({title, definition}[]). Required for fieldType=CLASSIFICATION; omitted otherwise.")
53528
53533
  };
53529
53534
  server.registerTool("create_template_version", {
53530
- description: "Publish a new version of a template. Versions capture the full workflow config: prompt, schema, and notifications. All fields are optional — include only what this version should set.",
53535
+ description: `Publish a new version of a template. Versions capture the full workflow config: prompt, schema, and notifications. All fields are optional — include only what this version should set.
53536
+
53537
+ ` + "THIS IS HOW YOU EDIT A TEMPLATE'S PROMPT OR SCHEMA. Published versions are immutable, so 'changing the template prompt' means publishing a new version here and then calling `apply_template_version` to push it onto linked workflows. " + "`update_template` only renames a template; it cannot touch prompt or schema.",
53531
53538
  inputSchema: strictSchema({
53532
53539
  templateId: exports_external.string().describe("The template ID to publish a version for"),
53533
53540
  prompt: exports_external.string().optional().describe("User prompt to copy into workflow config"),
53534
53541
  schemaId: exports_external.string().optional().describe("Existing schema ID to reference (mutually exclusive with schemaFields)"),
53535
- schemaFields: exports_external.preprocess(coerceArray(), exports_external.array(exports_external.object(TemplateSchemaFieldShape))).optional().describe("Inline schema fields to create a new schema (mutually exclusive with schemaId)"),
53542
+ schemaFields: exports_external.preprocess(coerceArray(), exports_external.array(exports_external.object(TemplateSchemaFieldShape).strict())).optional().describe("Inline schema fields to create a new schema (mutually exclusive with schemaId)"),
53536
53543
  schemaEntity: exports_external.string().optional().describe("Entity name for the inline schema"),
53537
53544
  schemaValidationRules: exports_external.preprocess(coerceJson(), exports_external.record(exports_external.string(), exports_external.record(exports_external.string(), exports_external.unknown()))).optional().describe("Per-field schema validation rules, keyed by field name. Not inherited from prior versions — omitting this on a new version drops any rules the previous version had."),
53538
53545
  notifications: exports_external.preprocess(coerceArray(), exports_external.array(exports_external.object({
@@ -53702,9 +53709,7 @@ var init_tools = __esm(() => {
53702
53709
  description: exports_external.string().optional().describe("What this field contains"),
53703
53710
  example: exports_external.string().describe("Example value"),
53704
53711
  dataType: exports_external.enum(["STRING", "NUMBER", "BOOLEAN", "DATE", "DATETIME", "MONEY", "IMAGE", "LINK", "OBJECT", "ARRAY"]).optional().describe("Data type for the field"),
53705
- isPrimaryKey: exports_external.boolean().optional(),
53706
- isRequired: exports_external.boolean().optional(),
53707
- isUnique: exports_external.boolean().optional()
53712
+ isKey: exports_external.preprocess(coerceBoolean(), exports_external.boolean()).optional().describe("Marks this field as a key field — the stable identity used to match records across runs. Change detection diffs records by their key fields, so a monitored or real-time workflow without one cannot tell an updated record from a new one. Set it on whatever uniquely identifies a row (a detail URL, an ID, a ticker).")
53708
53713
  };
53709
53714
  WORKFLOW_AUDIT_WATCHED_KEYS = [
53710
53715
  "name",
@@ -53724,7 +53729,7 @@ var package_default;
53724
53729
  var init_package = __esm(() => {
53725
53730
  package_default = {
53726
53731
  name: "@kadoa/mcp",
53727
- version: "0.5.15",
53732
+ version: "0.5.16",
53728
53733
  description: "Kadoa MCP Server — manage workflows from Claude Desktop, Cursor, and other MCP clients",
53729
53734
  type: "module",
53730
53735
  main: "dist/index.js",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kadoa/mcp",
3
- "version": "0.5.15",
3
+ "version": "0.5.16",
4
4
  "description": "Kadoa MCP Server — manage workflows from Claude Desktop, Cursor, and other MCP clients",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",