@kadoa/mcp 0.7.0 → 0.7.1
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 +129 -60
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -17,7 +17,7 @@ var package_default;
|
|
|
17
17
|
var init_package = __esm(() => {
|
|
18
18
|
package_default = {
|
|
19
19
|
name: "@kadoa/mcp",
|
|
20
|
-
version: "0.7.
|
|
20
|
+
version: "0.7.1",
|
|
21
21
|
description: "Kadoa MCP Server — manage workflows from Claude Desktop, Cursor, and other MCP clients",
|
|
22
22
|
type: "module",
|
|
23
23
|
main: "dist/index.js",
|
|
@@ -44,7 +44,7 @@ var init_package = __esm(() => {
|
|
|
44
44
|
prepublishOnly: "bun run check-types && bun run test:unit && bun run build"
|
|
45
45
|
},
|
|
46
46
|
dependencies: {
|
|
47
|
-
"@kadoa/node-sdk": "^0.
|
|
47
|
+
"@kadoa/node-sdk": "^0.48.0",
|
|
48
48
|
"@modelcontextprotocol/client": "2.1.0",
|
|
49
49
|
"@modelcontextprotocol/express": "2.0.1",
|
|
50
50
|
"@modelcontextprotocol/node": "2.1.0",
|
|
@@ -214,7 +214,7 @@ function withVariableDashboardUrl(variable) {
|
|
|
214
214
|
|
|
215
215
|
// src/tools/shared/output-schemas.ts
|
|
216
216
|
import { z } from "zod";
|
|
217
|
-
var apiField, nullableString, PaginationOutput, WorkflowRowOutput, ListWorkflowsOutput, GetWorkflowOutput, FetchDataOutput, ASSISTANT_ACTIVITIES, WorkflowAssistantOutput, AssistantTimelineOutput, AssistantAnswerOutput, AssistantControlOutput, WorkflowStrategyOutput;
|
|
217
|
+
var apiField, nullableString, PaginationOutput, workflowStatusFields, WorkflowRowOutput, ListWorkflowsOutput, GetWorkflowOutput, FetchDataOutput, ASSISTANT_ACTIVITIES, WorkflowAssistantOutput, AssistantTimelineOutput, AssistantAnswerOutput, AssistantControlOutput, WorkflowStrategyOutput;
|
|
218
218
|
var init_output_schemas = __esm(() => {
|
|
219
219
|
apiField = z.unknown().optional();
|
|
220
220
|
nullableString = z.string().nullable();
|
|
@@ -229,11 +229,20 @@ var init_output_schemas = __esm(() => {
|
|
|
229
229
|
nextCursor: nullableString.optional(),
|
|
230
230
|
next: z.record(z.string(), z.unknown()).optional()
|
|
231
231
|
}).loose();
|
|
232
|
+
workflowStatusFields = {
|
|
233
|
+
status: z.string(),
|
|
234
|
+
badges: z.array(z.object({ kind: z.string(), status: z.string(), label: z.string() }).loose()),
|
|
235
|
+
group: nullableString,
|
|
236
|
+
reviewReason: z.object({ code: z.string(), explanation: z.string() }).loose().nullable(),
|
|
237
|
+
execution: apiField,
|
|
238
|
+
assistantState: apiField,
|
|
239
|
+
workspaceActivity: apiField
|
|
240
|
+
};
|
|
232
241
|
WorkflowRowOutput = z.object({
|
|
233
242
|
id: apiField,
|
|
234
243
|
name: apiField,
|
|
235
244
|
dashboardUrl: z.string(),
|
|
236
|
-
|
|
245
|
+
...workflowStatusFields,
|
|
237
246
|
state: nullableString,
|
|
238
247
|
displayState: nullableString,
|
|
239
248
|
runState: nullableString,
|
|
@@ -244,7 +253,6 @@ var init_output_schemas = __esm(() => {
|
|
|
244
253
|
createdAt: apiField,
|
|
245
254
|
assistant: z.object({
|
|
246
255
|
eligible: z.boolean(),
|
|
247
|
-
dataStale: z.boolean(),
|
|
248
256
|
session: z.object({ id: z.string(), threadId: apiField, status: apiField }).loose().nullable()
|
|
249
257
|
}).loose(),
|
|
250
258
|
template: z.object({ id: z.string(), pinnedVersion: apiField, latestVersion: apiField, isOutdated: z.boolean() }).loose().nullable(),
|
|
@@ -257,7 +265,7 @@ var init_output_schemas = __esm(() => {
|
|
|
257
265
|
name: apiField,
|
|
258
266
|
dashboardUrl: z.string(),
|
|
259
267
|
description: apiField,
|
|
260
|
-
|
|
268
|
+
...workflowStatusFields,
|
|
261
269
|
state: nullableString,
|
|
262
270
|
displayState: nullableString,
|
|
263
271
|
runState: nullableString,
|
|
@@ -268,7 +276,6 @@ var init_output_schemas = __esm(() => {
|
|
|
268
276
|
entity: apiField,
|
|
269
277
|
schema: apiField,
|
|
270
278
|
navigationMode: apiField,
|
|
271
|
-
dataStale: apiField,
|
|
272
279
|
assistantEligible: z.boolean(),
|
|
273
280
|
assistantSessionId: apiField,
|
|
274
281
|
assistantThreadId: apiField,
|
|
@@ -297,8 +304,6 @@ var init_output_schemas = __esm(() => {
|
|
|
297
304
|
createdAt: apiField,
|
|
298
305
|
notificationConfig: apiField,
|
|
299
306
|
channelCounts: apiField,
|
|
300
|
-
dataValidation: apiField,
|
|
301
|
-
validationStatistics: apiField,
|
|
302
307
|
realtime: z.object({ lastDataChangedAt: apiField, observerHealth: apiField }).loose().nullable()
|
|
303
308
|
}).loose();
|
|
304
309
|
FetchDataOutput = z.object({
|
|
@@ -2662,49 +2667,109 @@ var init_variables = __esm(() => {
|
|
|
2662
2667
|
init_schemas();
|
|
2663
2668
|
});
|
|
2664
2669
|
|
|
2665
|
-
// src/tools/
|
|
2666
|
-
|
|
2667
|
-
|
|
2670
|
+
// src/tools/shared/workflow-status.ts
|
|
2671
|
+
function reviewReasonExplanation(reason) {
|
|
2672
|
+
return reason && REVIEW_REASON_EXPLANATIONS[reason] || UNKNOWN_REVIEW_REASON;
|
|
2673
|
+
}
|
|
2668
2674
|
function isRealTimeInterval(interval) {
|
|
2669
2675
|
return interval?.toUpperCase().replace("-", "_") === "REAL_TIME";
|
|
2670
2676
|
}
|
|
2671
|
-
function
|
|
2672
|
-
const ds =
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
if (!workflow.updateInterval || workflow.updateInterval === "only once")
|
|
2678
|
-
return "Complete";
|
|
2679
|
-
return "Scheduled";
|
|
2680
|
-
case "RUNNING":
|
|
2681
|
-
return "Running";
|
|
2682
|
-
case "VALIDATING":
|
|
2683
|
-
return "Validating";
|
|
2684
|
-
case "FAILED":
|
|
2685
|
-
return "Failed";
|
|
2686
|
-
case "PAUSED":
|
|
2687
|
-
return "Paused";
|
|
2688
|
-
case "SETUP":
|
|
2689
|
-
return "Sample Processing";
|
|
2690
|
-
case "QUEUED":
|
|
2691
|
-
return "Queued";
|
|
2692
|
-
case "PENDING_START":
|
|
2693
|
-
return "Not Started";
|
|
2694
|
-
case "PREVIEW":
|
|
2695
|
-
return "Pending Review";
|
|
2696
|
-
case "DEGRADED":
|
|
2697
|
-
return "Degraded";
|
|
2698
|
-
case "DELETED":
|
|
2699
|
-
return "Deleted";
|
|
2700
|
-
case "COMPLIANCE_REVIEW":
|
|
2701
|
-
return "Compliance Review";
|
|
2702
|
-
case "COMPLIANCE_REJECTED":
|
|
2703
|
-
return "Rejected";
|
|
2704
|
-
default:
|
|
2705
|
-
return ds ?? "Unknown";
|
|
2677
|
+
function fallbackStatusCode(w) {
|
|
2678
|
+
const ds = w.displayState ?? w.state ?? null;
|
|
2679
|
+
if (ds === "ACTIVE") {
|
|
2680
|
+
if (w.isRealTime === true || isRealTimeInterval(w.updateInterval))
|
|
2681
|
+
return "RUNNING";
|
|
2682
|
+
return w.updateInterval && !["ONLY_ONCE", "only once"].includes(w.updateInterval) ? "SCHEDULED" : "COMPLETE";
|
|
2706
2683
|
}
|
|
2684
|
+
if (ds === "VALIDATING")
|
|
2685
|
+
return "AWAITING_REVIEW";
|
|
2686
|
+
return ds;
|
|
2687
|
+
}
|
|
2688
|
+
function labelFor(code, previewReady) {
|
|
2689
|
+
const label = WORKFLOW_STATUS_LABELS[code === "PREVIEW" && previewReady ? "PREVIEW_READY" : code];
|
|
2690
|
+
if (label)
|
|
2691
|
+
return label;
|
|
2692
|
+
console.error(`[workflow-status] unmapped workflow status, passing through verbatim: ${code}`);
|
|
2693
|
+
return code;
|
|
2694
|
+
}
|
|
2695
|
+
function workflowStatusLabel(w) {
|
|
2696
|
+
const code = w.presentation?.status ?? fallbackStatusCode(w);
|
|
2697
|
+
if (!code)
|
|
2698
|
+
return "Unknown";
|
|
2699
|
+
return labelFor(code, w.availableActions?.approve?.allowed === true);
|
|
2700
|
+
}
|
|
2701
|
+
function workflowStatusView(w) {
|
|
2702
|
+
const previewReady = w.availableActions?.approve?.allowed === true;
|
|
2703
|
+
return {
|
|
2704
|
+
status: workflowStatusLabel(w),
|
|
2705
|
+
badges: (w.presentation?.badges ?? []).map((b) => ({
|
|
2706
|
+
kind: b.kind,
|
|
2707
|
+
status: b.status,
|
|
2708
|
+
label: labelFor(b.status, previewReady)
|
|
2709
|
+
})),
|
|
2710
|
+
group: w.presentation?.group ?? null,
|
|
2711
|
+
reviewReason: w.reviewReason ? { code: w.reviewReason, explanation: reviewReasonExplanation(w.reviewReason) } : null
|
|
2712
|
+
};
|
|
2707
2713
|
}
|
|
2714
|
+
function runStatusLabel(state) {
|
|
2715
|
+
if (!state)
|
|
2716
|
+
return "Unknown";
|
|
2717
|
+
return RUN_STATE_LABELS[state] ?? state;
|
|
2718
|
+
}
|
|
2719
|
+
var REVIEW_STATUS_LABEL = "Verifying data", WORKFLOW_STATUS_LABELS, REVIEW_REASON_EXPLANATIONS, UNKNOWN_REVIEW_REASON = "Kadoa's quality or compliance checks selected this run for review.", RUN_STATE_LABELS;
|
|
2720
|
+
var init_workflow_status = __esm(() => {
|
|
2721
|
+
WORKFLOW_STATUS_LABELS = {
|
|
2722
|
+
ASSISTANT_WORKING: "Agent working",
|
|
2723
|
+
AWAITING_REVIEW: REVIEW_STATUS_LABEL,
|
|
2724
|
+
COMPLETE: "Complete",
|
|
2725
|
+
COMPLIANCE_REJECTED: "Rejected",
|
|
2726
|
+
COMPLIANCE_REVIEW: "Compliance review",
|
|
2727
|
+
DEGRADED: "Degraded",
|
|
2728
|
+
DELETED: "Deleted",
|
|
2729
|
+
DRAFT: "Draft",
|
|
2730
|
+
ERROR: "Failed",
|
|
2731
|
+
FAILED: "Failed",
|
|
2732
|
+
IN_SUPPORT: "In support",
|
|
2733
|
+
NOT_SUPPORTED: "Not supported",
|
|
2734
|
+
PAUSED: "Paused",
|
|
2735
|
+
PENDING_START: "Not started",
|
|
2736
|
+
PREVIEW: "Preview",
|
|
2737
|
+
PREVIEW_READY: "Preview ready",
|
|
2738
|
+
QUEUED: "Queued",
|
|
2739
|
+
REPLY_NEEDED: "Reply needed",
|
|
2740
|
+
RUNNING: "Running",
|
|
2741
|
+
SCHEDULED: "Scheduled",
|
|
2742
|
+
SETUP: "Setup",
|
|
2743
|
+
STOPPED: "Stopped",
|
|
2744
|
+
UPDATE_FAILED: "Update failed",
|
|
2745
|
+
UPDATING: "Updating"
|
|
2746
|
+
};
|
|
2747
|
+
REVIEW_REASON_EXPLANATIONS = {
|
|
2748
|
+
COMPLIANCE_REVIEW: "This run triggered a compliance check before delivery.",
|
|
2749
|
+
HARD_FAIL: "An error stopped this run from completing normally.",
|
|
2750
|
+
TRANSFORMATION_REPAIR_REQUIRED: "A data transformation could not be fixed automatically.",
|
|
2751
|
+
MINIMUM_HUMAN_APPROVALS: "Kadoa's quality checks selected this run for review before delivery.",
|
|
2752
|
+
DATA_QUALITY_SCHEMA_ADHERENCE: "The extracted data did not match this workflow's fields and data types.",
|
|
2753
|
+
DATA_QUALITY_SCHEMA_VALIDATION: "Extracted values did not match this workflow's validation rules.",
|
|
2754
|
+
DATA_QUALITY_COMPLETENESS: "The extracted record count did not match the expected source count.",
|
|
2755
|
+
DATA_QUALITY_SEMANTIC_PLAUSIBILITY: "Some extracted values look unusual for their fields.",
|
|
2756
|
+
ROW_COUNT_CHANGED: "This run's row count changed significantly.",
|
|
2757
|
+
WORKFLOW_REVISION_DRIFT: "This run no longer matches the workflow's current setup.",
|
|
2758
|
+
ZERO_RESULTS: "The source returned no data."
|
|
2759
|
+
};
|
|
2760
|
+
RUN_STATE_LABELS = {
|
|
2761
|
+
FINISHED: "Success",
|
|
2762
|
+
IN_PROGRESS: "Running",
|
|
2763
|
+
VALIDATING: REVIEW_STATUS_LABEL,
|
|
2764
|
+
FAILED: "Failed",
|
|
2765
|
+
FAILED_INSUFFICIENT_FUNDS: "Failed",
|
|
2766
|
+
NOT_SUPPORTED: "Failed"
|
|
2767
|
+
};
|
|
2768
|
+
});
|
|
2769
|
+
|
|
2770
|
+
// src/tools/workflows.ts
|
|
2771
|
+
import { WorkflowStatusFilter } from "@kadoa/node-sdk";
|
|
2772
|
+
import { z as z12 } from "zod";
|
|
2708
2773
|
function mapRunStatus(state) {
|
|
2709
2774
|
switch (state) {
|
|
2710
2775
|
case "FINISHED":
|
|
@@ -3120,7 +3185,7 @@ function registerWorkflowCoreTools(server, ctx, helpers, defaultProductType) {
|
|
|
3120
3185
|
}));
|
|
3121
3186
|
server.registerTool("list_workflows", {
|
|
3122
3187
|
title: "List Workflows",
|
|
3123
|
-
description: `List workflows with customer-visible status, raw workflow and run states, Assistant session availability, template version drift, realtime freshness or health, and awaitingUserInput when the requesting user must act. Uses one paginated list request; use get_workflow only when you need full details for a selected workflow. To answer "what needs my attention", pass statusFilters: ["group:attention"]; this returns exactly the dashboard's "Needs your attention" group. In group:attention, a row with awaitingUserInput.prompt is an Assistant question: use get_workflow_assistant then answer_workflow_assistant_question. A row with awaitingUserInput but no prompt is a setup the user left unfinished: use get_workflow_assistant to see where it stopped, then resume_workflow_assistant or request_workflow_update. A row with
|
|
3188
|
+
description: `List workflows with customer-visible status, raw workflow and run states, Assistant session availability, template version drift, realtime freshness or health, and awaitingUserInput when the requesting user must act. Uses one paginated list request; use get_workflow only when you need full details for a selected workflow. To answer "what needs my attention", pass statusFilters: ["group:attention"]; this returns exactly the dashboard's "Needs your attention" group. In group:attention, a row with awaitingUserInput.prompt is an Assistant question: use get_workflow_assistant then answer_workflow_assistant_question. A row with awaitingUserInput but no prompt is a setup the user left unfinished: use get_workflow_assistant to see where it stopped, then resume_workflow_assistant or request_workflow_update. A row with status "Preview ready" is preview data ready to approve with approve_workflow; "Preview" means preview data exists but approval isn't available yet. Workflows with an open support ticket are excluded from group:attention and appear under group:support. badges[].label is exactly what the Kadoa dashboard displays (lifecycle, activity, and support badges, e.g. "Setup" + "Agent working"): use these labels when describing the workflow to the user. status is the one-line summary in dashboard wording (e.g. "Verifying data" = the latest run is held for quality review before delivery; see reviewReason for why).`,
|
|
3124
3189
|
inputSchema: strictSchema({
|
|
3125
3190
|
limit: limitInput({
|
|
3126
3191
|
noun: "Workflows",
|
|
@@ -3158,10 +3223,13 @@ function registerWorkflowCoreTools(server, ctx, helpers, defaultProductType) {
|
|
|
3158
3223
|
id: w.id,
|
|
3159
3224
|
name: w.name,
|
|
3160
3225
|
dashboardUrl: workflowDashboardUrl(w.id),
|
|
3161
|
-
|
|
3226
|
+
...workflowStatusView(w),
|
|
3162
3227
|
state: w.state ?? null,
|
|
3163
3228
|
displayState: w.displayState ?? null,
|
|
3164
3229
|
runState: w.runState ?? null,
|
|
3230
|
+
execution: w.execution ?? null,
|
|
3231
|
+
assistantState: w.assistantState ?? null,
|
|
3232
|
+
workspaceActivity: w.workspaceActivity ?? null,
|
|
3165
3233
|
urls: w.urls,
|
|
3166
3234
|
totalRecords: w.totalRecords,
|
|
3167
3235
|
startedAt: w.startedAt,
|
|
@@ -3169,7 +3237,6 @@ function registerWorkflowCoreTools(server, ctx, helpers, defaultProductType) {
|
|
|
3169
3237
|
createdAt: w.createdAt,
|
|
3170
3238
|
assistant: {
|
|
3171
3239
|
eligible: w.assistantEligible === true,
|
|
3172
|
-
dataStale: w.dataStale === true,
|
|
3173
3240
|
session: w.assistantSessionId ? {
|
|
3174
3241
|
id: w.assistantSessionId,
|
|
3175
3242
|
threadId: w.assistantThreadId ?? null,
|
|
@@ -3201,7 +3268,7 @@ function registerWorkflowCoreTools(server, ctx, helpers, defaultProductType) {
|
|
|
3201
3268
|
}));
|
|
3202
3269
|
server.registerTool("get_workflow", {
|
|
3203
3270
|
title: "Get Workflow",
|
|
3204
|
-
description:
|
|
3271
|
+
description: 'Get canonical workflow details, including Assistant/session linkage, extraction intent, template-controlled parts, job/run state, schedule timezone, location, monitoring, and realtime health. For Assistant-built workflows, extractionSpec - not the legacy prompt - is authoritative. badges[].label is exactly what the Kadoa dashboard displays (lifecycle, activity, and support badges, e.g. "Setup" + "Agent working"): use these labels when describing the workflow to the user. status is the one-line summary in dashboard wording (e.g. "Verifying data" = the latest run is held for quality review before delivery; see reviewReason for why).',
|
|
3205
3272
|
inputSchema: strictSchema({
|
|
3206
3273
|
workflowId: z12.string().min(1).describe("The workflow ID")
|
|
3207
3274
|
}),
|
|
@@ -3226,10 +3293,13 @@ function registerWorkflowCoreTools(server, ctx, helpers, defaultProductType) {
|
|
|
3226
3293
|
name: workflow.name,
|
|
3227
3294
|
dashboardUrl: workflowDashboardUrl(workflow.id ?? args.workflowId),
|
|
3228
3295
|
description: workflow.description,
|
|
3229
|
-
|
|
3296
|
+
...workflowStatusView(workflow),
|
|
3230
3297
|
state: workflow.state ?? null,
|
|
3231
3298
|
displayState: workflow.displayState ?? null,
|
|
3232
3299
|
runState: workflow.runState ?? null,
|
|
3300
|
+
execution: workflow.execution ?? null,
|
|
3301
|
+
assistantState: workflow.assistantState ?? null,
|
|
3302
|
+
workspaceActivity: workflow.workspaceActivity ?? null,
|
|
3233
3303
|
urls: workflow.urls,
|
|
3234
3304
|
prompt: extractionSpec ? null : legacyPrompt,
|
|
3235
3305
|
intentSource: extractionSpec ? "extraction_spec" : legacyPrompt ? "legacy_prompt" : null,
|
|
@@ -3237,7 +3307,6 @@ function registerWorkflowCoreTools(server, ctx, helpers, defaultProductType) {
|
|
|
3237
3307
|
entity: workflow.entity,
|
|
3238
3308
|
schema: workflow.schema,
|
|
3239
3309
|
navigationMode: workflow.navigationMode,
|
|
3240
|
-
dataStale: workflow.dataStale ?? false,
|
|
3241
3310
|
assistantEligible: workflow.assistantEligible === true,
|
|
3242
3311
|
assistantSessionId: workflow.assistantSessionId ?? null,
|
|
3243
3312
|
assistantThreadId: workflow.assistantThreadId ?? null,
|
|
@@ -3280,8 +3349,6 @@ function registerWorkflowCoreTools(server, ctx, helpers, defaultProductType) {
|
|
|
3280
3349
|
createdAt: workflow.createdAt,
|
|
3281
3350
|
notificationConfig: workflow.notificationConfig,
|
|
3282
3351
|
channelCounts: workflow.channelCounts ?? {},
|
|
3283
|
-
dataValidation: workflow.dataValidation ?? null,
|
|
3284
|
-
validationStatistics: workflow.validationStatistics ?? null,
|
|
3285
3352
|
realtime: isRealtime ? {
|
|
3286
3353
|
lastDataChangedAt: workflow.lastDataChangedAt ?? null,
|
|
3287
3354
|
observerHealth: workflow.observerHealth ?? null
|
|
@@ -3381,7 +3448,7 @@ function registerWorkflowHistoryTools(server, ctx, helpers) {
|
|
|
3381
3448
|
}));
|
|
3382
3449
|
server.registerTool("list_workflow_runs", {
|
|
3383
3450
|
title: "List Workflow Runs",
|
|
3384
|
-
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.",
|
|
3451
|
+
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. `label` is the dashboard's wording for the run " + "(Success, Failed, Running, or 'Verifying data' = held for quality review before delivery); " + "prefer it when describing a run to the user.",
|
|
3385
3452
|
inputSchema: strictSchema({
|
|
3386
3453
|
workflowId: z12.string().min(1).describe("The workflow ID"),
|
|
3387
3454
|
status: z12.enum(["success", "failed", "in_progress"]).optional().describe("Filter runs by outcome"),
|
|
@@ -3400,6 +3467,7 @@ function registerWorkflowHistoryTools(server, ctx, helpers) {
|
|
|
3400
3467
|
const runs = (response.workflowRuns ?? []).map((r) => ({
|
|
3401
3468
|
id: r.id,
|
|
3402
3469
|
status: mapRunStatus(r.state),
|
|
3470
|
+
label: runStatusLabel(r.state),
|
|
3403
3471
|
startedAt: r.startedAt,
|
|
3404
3472
|
finishedAt: r.finishedAt,
|
|
3405
3473
|
records: r.records,
|
|
@@ -3449,7 +3517,7 @@ function registerWorkflowRunTools(server, ctx, helpers) {
|
|
|
3449
3517
|
const FETCH_DATA_MAX_LIMIT = 500;
|
|
3450
3518
|
server.registerTool("fetch_data", {
|
|
3451
3519
|
title: "Fetch Workflow Data",
|
|
3452
|
-
description: "Get a PAGE of extracted data from a workflow. Use ONLY for previews, sorted/filtered slices, or explicit 'first N rows' / 'top N' queries (capped at 500 rows per call). Do NOT use this to retrieve a full dataset, 'all rows', or anything the user wants to analyze in Excel / pandas / duckdb - use export_data for those. Data is only available after the workflow run has completed (status is no longer 'Running' or '
|
|
3520
|
+
description: "Get a PAGE of extracted data from a workflow. Use ONLY for previews, sorted/filtered slices, or explicit 'first N rows' / 'top N' queries (capped at 500 rows per call). Do NOT use this to retrieve a full dataset, 'all rows', or anything the user wants to analyze in Excel / pandas / duckdb - use export_data for those. Data is only available after the workflow run has completed (status is no longer 'Running' or 'Verifying data'). Do NOT poll or sleep-wait for completion.",
|
|
3453
3521
|
inputSchema: strictSchema({
|
|
3454
3522
|
workflowId: z12.string().min(1).describe("The workflow ID"),
|
|
3455
3523
|
limit: limitInput({
|
|
@@ -3611,7 +3679,7 @@ function registerWorkflowRunTools(server, ctx, helpers) {
|
|
|
3611
3679
|
try {
|
|
3612
3680
|
const workflow = await ctx.client.workflow.get(args.workflowId);
|
|
3613
3681
|
workflowName = workflow.name || args.workflowId;
|
|
3614
|
-
workflowStatus =
|
|
3682
|
+
workflowStatus = workflowStatusLabel(workflow);
|
|
3615
3683
|
} catch {}
|
|
3616
3684
|
if (!args.confirmed) {
|
|
3617
3685
|
return jsonResult({
|
|
@@ -3723,6 +3791,7 @@ var init_workflows = __esm(() => {
|
|
|
3723
3791
|
init_output_schemas();
|
|
3724
3792
|
init_pagination();
|
|
3725
3793
|
init_schemas();
|
|
3794
|
+
init_workflow_status();
|
|
3726
3795
|
WORKFLOW_AUDIT_WATCHED_KEYS = [
|
|
3727
3796
|
"name",
|
|
3728
3797
|
"tags",
|
|
@@ -4476,7 +4545,7 @@ async function createServer3(auth, options) {
|
|
|
4476
4545
|
"Use list_changes and get_change to retrieve detected diffs from realtime monitoring workflows.",
|
|
4477
4546
|
"List tools, plus fetch_data, get_workflow_history, and get_workflow_assistant_timeline, all return pagination {totalCount?, hasMore, next?}. When hasMore is true, call the same tool again with pagination.next as its arguments to get the next page. totalCount is present only when the total is known; never treat the page size as the total.",
|
|
4478
4547
|
"Large results (fetch_data, get_workflow_history, get_change) are cut to whole rows or entries under about 80 KB and marked truncated: true with a hint; follow pagination.next, narrow the filters, or use export_data, and never conclude the data ends there.",
|
|
4479
|
-
|
|
4548
|
+
`When the user asks what needs their attention, call list_workflows with statusFilters group:attention. A row with awaitingUserInput.prompt is the Assistant's pending question: answer it with get_workflow_assistant then answer_workflow_assistant_question. A row with awaitingUserInput but no prompt is a setup the user left unfinished: use get_workflow_assistant to see where it stopped, then resume_workflow_assistant or request_workflow_update. A row with status "Preview ready" is preview data ready to approve with approve_workflow; "Preview" means preview data exists but approval isn't available yet. Workflows with an open support ticket are excluded from group:attention and appear under group:support.`,
|
|
4480
4549
|
"",
|
|
4481
4550
|
"Schema tips: Use descriptive field names and examples. Group related data under one entity.",
|
|
4482
4551
|
"The AI agent uses the schema + prompt to understand what to extract - a detailed prompt with a comprehensive schema produces better results than multiple simple workflows.",
|
|
@@ -4954,7 +5023,7 @@ async function createServer(auth, options) {
|
|
|
4954
5023
|
"Use list_changes and get_change to retrieve detected diffs from realtime monitoring workflows.",
|
|
4955
5024
|
"List tools, plus fetch_data, get_workflow_history, and get_workflow_assistant_timeline, all return pagination {totalCount?, hasMore, next?}. When hasMore is true, call the same tool again with pagination.next as its arguments to get the next page. totalCount is present only when the total is known; never treat the page size as the total.",
|
|
4956
5025
|
"Large results (fetch_data, get_workflow_history, get_change) are cut to whole rows or entries under about 80 KB and marked truncated: true with a hint; follow pagination.next, narrow the filters, or use export_data, and never conclude the data ends there.",
|
|
4957
|
-
|
|
5026
|
+
`When the user asks what needs their attention, call list_workflows with statusFilters group:attention. A row with awaitingUserInput.prompt is the Assistant's pending question: answer it with get_workflow_assistant then answer_workflow_assistant_question. A row with awaitingUserInput but no prompt is a setup the user left unfinished: use get_workflow_assistant to see where it stopped, then resume_workflow_assistant or request_workflow_update. A row with status "Preview ready" is preview data ready to approve with approve_workflow; "Preview" means preview data exists but approval isn't available yet. Workflows with an open support ticket are excluded from group:attention and appear under group:support.`,
|
|
4958
5027
|
"",
|
|
4959
5028
|
"Schema tips: Use descriptive field names and examples. Group related data under one entity.",
|
|
4960
5029
|
"The AI agent uses the schema + prompt to understand what to extract - a detailed prompt with a comprehensive schema produces better results than multiple simple workflows.",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kadoa/mcp",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.1",
|
|
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",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"prepublishOnly": "bun run check-types && bun run test:unit && bun run build"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@kadoa/node-sdk": "^0.
|
|
30
|
+
"@kadoa/node-sdk": "^0.48.0",
|
|
31
31
|
"@modelcontextprotocol/client": "2.1.0",
|
|
32
32
|
"@modelcontextprotocol/express": "2.0.1",
|
|
33
33
|
"@modelcontextprotocol/node": "2.1.0",
|