@kadoa/mcp 0.5.15 → 0.5.17
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.js +23 -15
- 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
|
-
|
|
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"),
|
|
@@ -52434,7 +52435,10 @@ function registerTools(server, ctx, capabilities) {
|
|
|
52434
52435
|
return (builder) => {
|
|
52435
52436
|
const entity = builder.entity(args.entity || "Data");
|
|
52436
52437
|
for (const field of args.schema) {
|
|
52437
|
-
entity.field(field.name, field.description || field.name, field.dataType || "STRING", {
|
|
52438
|
+
entity.field(field.name, field.description || field.name, field.dataType || "STRING", {
|
|
52439
|
+
example: field.example,
|
|
52440
|
+
isKey: field.isKey
|
|
52441
|
+
});
|
|
52438
52442
|
}
|
|
52439
52443
|
return entity;
|
|
52440
52444
|
};
|
|
@@ -52769,7 +52773,7 @@ function registerTools(server, ctx, capabilities) {
|
|
|
52769
52773
|
});
|
|
52770
52774
|
}));
|
|
52771
52775
|
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.",
|
|
52776
|
+
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
52777
|
inputSchema: {
|
|
52774
52778
|
workflowId: exports_external.string().describe("The workflow ID"),
|
|
52775
52779
|
status: exports_external.enum(["success", "failed", "in_progress"]).optional().describe("Filter runs by outcome"),
|
|
@@ -52998,13 +53002,15 @@ function registerTools(server, ctx, capabilities) {
|
|
|
52998
53002
|
server.registerTool("update_workflow", {
|
|
52999
53003
|
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
53004
|
|
|
53001
|
-
` +
|
|
53005
|
+
` + `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.
|
|
53006
|
+
|
|
53007
|
+
` + "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
53008
|
inputSchema: strictSchema({
|
|
53003
53009
|
workflowId: exports_external.string().describe("The workflow ID to update"),
|
|
53004
53010
|
name: exports_external.string().optional().describe("New name for the workflow"),
|
|
53005
53011
|
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
53012
|
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"),
|
|
53013
|
+
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
53014
|
description: exports_external.string().max(500).optional().describe("Workflow description (max 500 characters)"),
|
|
53009
53015
|
tags: exports_external.preprocess(coerceArray(true), exports_external.array(exports_external.string())).optional().describe("Tags for organizing workflows"),
|
|
53010
53016
|
userPrompt: exports_external.string().optional().describe("Navigation prompt for agentic-navigation mode (10-5000 characters)"),
|
|
@@ -53471,11 +53477,13 @@ function registerTools(server, ctx, capabilities) {
|
|
|
53471
53477
|
});
|
|
53472
53478
|
}));
|
|
53473
53479
|
server.registerTool("update_template", {
|
|
53474
|
-
description:
|
|
53480
|
+
description: `Update a template's name or description ONLY. At least one of the two must be provided.
|
|
53481
|
+
|
|
53482
|
+
` + "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
53483
|
inputSchema: strictSchema({
|
|
53476
53484
|
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")
|
|
53485
|
+
name: exports_external.preprocess(coerceNull(), exports_external.string().optional()).optional().describe("New template name"),
|
|
53486
|
+
description: exports_external.preprocess(coerceNull(), exports_external.string().optional()).optional().describe("New template description")
|
|
53479
53487
|
}),
|
|
53480
53488
|
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true }
|
|
53481
53489
|
}, withErrorHandling("update_template", async (args) => {
|
|
@@ -53527,12 +53535,14 @@ function registerTools(server, ctx, capabilities) {
|
|
|
53527
53535
|
}))).optional().describe("Predefined categories for a CLASSIFICATION field ({title, definition}[]). Required for fieldType=CLASSIFICATION; omitted otherwise.")
|
|
53528
53536
|
};
|
|
53529
53537
|
server.registerTool("create_template_version", {
|
|
53530
|
-
description:
|
|
53538
|
+
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.
|
|
53539
|
+
|
|
53540
|
+
` + "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
53541
|
inputSchema: strictSchema({
|
|
53532
53542
|
templateId: exports_external.string().describe("The template ID to publish a version for"),
|
|
53533
53543
|
prompt: exports_external.string().optional().describe("User prompt to copy into workflow config"),
|
|
53534
53544
|
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)"),
|
|
53545
|
+
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
53546
|
schemaEntity: exports_external.string().optional().describe("Entity name for the inline schema"),
|
|
53537
53547
|
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
53548
|
notifications: exports_external.preprocess(coerceArray(), exports_external.array(exports_external.object({
|
|
@@ -53702,9 +53712,7 @@ var init_tools = __esm(() => {
|
|
|
53702
53712
|
description: exports_external.string().optional().describe("What this field contains"),
|
|
53703
53713
|
example: exports_external.string().describe("Example value"),
|
|
53704
53714
|
dataType: exports_external.enum(["STRING", "NUMBER", "BOOLEAN", "DATE", "DATETIME", "MONEY", "IMAGE", "LINK", "OBJECT", "ARRAY"]).optional().describe("Data type for the field"),
|
|
53705
|
-
|
|
53706
|
-
isRequired: exports_external.boolean().optional(),
|
|
53707
|
-
isUnique: exports_external.boolean().optional()
|
|
53715
|
+
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
53716
|
};
|
|
53709
53717
|
WORKFLOW_AUDIT_WATCHED_KEYS = [
|
|
53710
53718
|
"name",
|
|
@@ -53724,7 +53732,7 @@ var package_default;
|
|
|
53724
53732
|
var init_package = __esm(() => {
|
|
53725
53733
|
package_default = {
|
|
53726
53734
|
name: "@kadoa/mcp",
|
|
53727
|
-
version: "0.5.
|
|
53735
|
+
version: "0.5.17",
|
|
53728
53736
|
description: "Kadoa MCP Server — manage workflows from Claude Desktop, Cursor, and other MCP clients",
|
|
53729
53737
|
type: "module",
|
|
53730
53738
|
main: "dist/index.js",
|