@kadoa/mcp 0.3.5-rc.0 → 0.3.5-rc.2

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 +28 -6
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -49167,6 +49167,9 @@ var init_client2 = __esm(() => {
49167
49167
  });
49168
49168
 
49169
49169
  // src/tools.ts
49170
+ function isRealTimeInterval(interval) {
49171
+ return interval?.toUpperCase().replace("-", "_") === "REAL_TIME";
49172
+ }
49170
49173
  function jsonResult(data) {
49171
49174
  return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
49172
49175
  }
@@ -49275,7 +49278,13 @@ function registerTools(server, ctx) {
49275
49278
  });
49276
49279
  }));
49277
49280
  server.registerTool("create_workflow", {
49278
- description: "Create a new workflow that extracts data using agentic navigation. Supports one-time, scheduled, and real-time (continuous monitoring) modes via the interval parameter. If entity and schema are provided, they guide the extraction. Otherwise, the AI agent auto-detects the schema from the page based on the prompt. The workflow runs asynchronously and may take several minutes. Do NOT poll or sleep-wait for completion. Instead, return the workflow ID to the user and let them check back later with get_workflow or fetch_data.",
49281
+ description: `Create a new workflow that extracts data using agentic navigation. Supports one-time, scheduled, and real-time (continuous monitoring) modes via the interval parameter. If entity and schema are provided, they guide the extraction. Otherwise, the AI agent auto-detects the schema from the page based on the prompt. The workflow runs asynchronously and may take several minutes. Do NOT poll or sleep-wait for completion. Instead, return the workflow ID to the user and let them check back later with get_workflow or fetch_data.
49282
+
49283
+ ` + `IMPORTANT — REAL_TIME vs regular workflows:
49284
+ ` + `• REAL_TIME workflows are fundamentally different from regular extraction workflows. They route to a separate Observer service, run continuously, and cannot be triggered manually.
49285
+ ` + `• A regular workflow CANNOT be converted to real-time after creation (and vice versa). The interval=REAL_TIME flag MUST be set at creation time.
49286
+ ` + `• If the user wants to monitor a page for changes, set interval='REAL_TIME' here. Do NOT create a regular workflow and then try to change its interval to REAL_TIME via update_workflow — this will be rejected.
49287
+ ` + "• When unclear whether the user wants monitoring (real-time) or data extraction (regular), ask them to clarify before creating the workflow.",
49279
49288
  inputSchema: {
49280
49289
  prompt: exports_external.string().describe('Natural language description of what to extract (e.g., "Extract product prices and names")'),
49281
49290
  urls: exports_external.array(exports_external.string()).min(1).describe("Starting URLs for the workflow"),
@@ -49327,10 +49336,11 @@ function registerTools(server, ctx) {
49327
49336
  }
49328
49337
  return entity;
49329
49338
  } : undefined;
49339
+ const isRealTime = args.interval === "REAL_TIME";
49330
49340
  let builder = ctx.client.extract({
49331
49341
  urls: args.urls,
49332
49342
  name: args.name || "Untitled Workflow",
49333
- navigationMode: "agentic-navigation",
49343
+ ...isRealTime ? {} : { navigationMode: "agentic-navigation" },
49334
49344
  userPrompt: args.prompt,
49335
49345
  extraction,
49336
49346
  interval: args.interval
@@ -49454,7 +49464,7 @@ function registerTools(server, ctx) {
49454
49464
  annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false }
49455
49465
  }, withErrorHandling("run_workflow", async (args) => {
49456
49466
  const workflow = await ctx.client.workflow.get(args.workflowId);
49457
- if (workflow.updateInterval === "REAL_TIME") {
49467
+ if (isRealTimeInterval(workflow.updateInterval)) {
49458
49468
  return errorResult("Real-time workflows run continuously and cannot be triggered manually. " + "Use fetch_data to retrieve the latest extracted results.");
49459
49469
  }
49460
49470
  const result = await ctx.client.workflow.runWorkflow(args.workflowId, {
@@ -49514,7 +49524,9 @@ function registerTools(server, ctx) {
49514
49524
  });
49515
49525
  }));
49516
49526
  server.registerTool("update_workflow", {
49517
- 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.",
49527
+ 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.
49528
+
49529
+ ` + "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.",
49518
49530
  inputSchema: {
49519
49531
  workflowId: exports_external.string().describe("The workflow ID to update"),
49520
49532
  name: exports_external.string().optional().describe("New name for the workflow"),
@@ -49541,15 +49553,25 @@ function registerTools(server, ctx) {
49541
49553
  "TRIWEEKLY",
49542
49554
  "FOUR_WEEKS",
49543
49555
  "MONTHLY",
49544
- "REAL_TIME",
49545
49556
  "CUSTOM"
49546
- ]).optional().describe("How often the workflow should run. Use REAL_TIME for continuous monitoring, CUSTOM with schedules for cron-based."),
49557
+ ]).optional().describe("How often the workflow should run. CUSTOM requires schedules. Note: REAL_TIME is NOT allowed here real-time workflows must be created via create_workflow."),
49547
49558
  schedules: exports_external.array(exports_external.string()).optional().describe("Cron expressions for CUSTOM update interval"),
49548
49559
  limit: exports_external.number().optional().describe("Maximum number of records to extract per run")
49549
49560
  },
49550
49561
  annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true }
49551
49562
  }, withErrorHandling("update_workflow", async (args) => {
49552
49563
  const { workflowId, ...updates } = args;
49564
+ if (updates.updateInterval) {
49565
+ const workflow = await ctx.client.workflow.get(workflowId);
49566
+ const isCurrentlyRealTime = isRealTimeInterval(workflow.updateInterval);
49567
+ const isRequestingRealTime = isRealTimeInterval(updates.updateInterval);
49568
+ if (isRequestingRealTime && !isCurrentlyRealTime) {
49569
+ return errorResult("Cannot change a regular workflow's interval to REAL_TIME. " + "Real-time workflows use a different service (Observer) and must be created as real-time from the start. " + "Delete this workflow and create a new one with interval='REAL_TIME' using create_workflow.");
49570
+ }
49571
+ if (!isRequestingRealTime && isCurrentlyRealTime) {
49572
+ return errorResult("Cannot change a real-time workflow's interval to a scheduled interval. " + "Real-time workflows are architecturally different and cannot be converted to regular workflows. " + "Delete this workflow and create a new one with the desired interval using create_workflow.");
49573
+ }
49574
+ }
49553
49575
  const result = await ctx.client.workflow.update(workflowId, updates);
49554
49576
  return jsonResult({
49555
49577
  success: true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kadoa/mcp",
3
- "version": "0.3.5-rc.0",
3
+ "version": "0.3.5-rc.2",
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",