@kadoa/mcp 0.5.19 → 0.5.20

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 (3) hide show
  1. package/README.md +15 -0
  2. package/dist/index.js +236 -41
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -63,6 +63,7 @@ Point your client to `https://mcp.kadoa.com/mcp` with OAuth authentication.
63
63
  |------|-------------|
64
64
  | `scrape` | Immediately fetch one URL as markdown or raw HTML (shown only for enabled workspaces) |
65
65
  | `create_workflow` | Create an agentic navigation workflow from a prompt |
66
+ | `create_realtime_monitor` | Create an asynchronous Julie realtime monitor after persisting notification channels; returns workflow/session/thread/job IDs |
66
67
  | `list_workflows` | List all workflows with status |
67
68
  | `get_workflow` | Get canonical intent, Assistant/session, template ownership, run health, schedule, location, monitoring, and validation details |
68
69
  | `request_workflow_update` | Ask the workflow Assistant to change extraction intent, navigation, sourcing, pagination, or generated behavior without changing the workflow ID |
@@ -163,6 +164,20 @@ in `America/New_York`, monitoring fields/conditions, and `limit: null` for all
163
164
  rows.
164
165
  ```
165
166
 
167
+ ### Create a Julie realtime monitor
168
+
169
+ ```
170
+ > You: Watch https://example-shop.com/products for price changes and alert me by webhook.
171
+
172
+ Claude calls create_realtime_monitor with the URL, schema/change intent, and notification settings. Kadoa persists reusable notification channels first, then Julie asynchronously accepts creation and returns workflow, session, thread, job, and dashboard identifiers.
173
+
174
+ > You: Does Julie need anything from me?
175
+
176
+ Claude uses get_workflow_assistant and the other workflow Assistant tools for follow-up status, questions, interrupts, resumes, or stops. It does not poll or sleep-wait.
177
+ ```
178
+
179
+ Realtime monitors cannot be converted in place to or from scheduled workflows; create them with `create_realtime_monitor` from the start.
180
+
166
181
  ### Update an Assistant-built workflow without replacing it
167
182
 
168
183
  ```
package/dist/index.js CHANGED
@@ -45747,6 +45747,25 @@ var import_debug, __require2, FREEFORM_ASSISTANT_ANSWER_KEY = "_freeform", Kadoa
45747
45747
  constructor(agentApi) {
45748
45748
  this.agentApi = agentApi;
45749
45749
  }
45750
+ async createRealtimeWorkflow(input) {
45751
+ const response = await this.agentApi.v5AgentPrompt({
45752
+ agentPromptRequest: {
45753
+ prompt: input.instructions,
45754
+ productType: "realtime",
45755
+ notificationChannelIds: input.notificationChannelIds,
45756
+ ...input.tags != null && { tags: input.tags },
45757
+ ...input.newSessionId != null && { newSessionId: input.newSessionId }
45758
+ }
45759
+ });
45760
+ const data = response.data?.data;
45761
+ if (!data?.workflowId || !data.sessionId || !data.threadId || !Object.keys(data ?? {}).includes("jobId") || data.jobId === undefined) {
45762
+ throw new KadoaSdkException("Realtime Assistant creation response is missing required identifiers", {
45763
+ code: "INTERNAL_ERROR",
45764
+ details: { response: response.data }
45765
+ });
45766
+ }
45767
+ return data;
45768
+ }
45750
45769
  async requestWorkflowUpdate(workflowId, input) {
45751
45770
  const response = await this.agentApi.v5AgentWorkflowAssistantMessage({
45752
45771
  workflowId,
@@ -45927,6 +45946,28 @@ var import_debug, __require2, FREEFORM_ASSISTANT_ANSWER_KEY = "_freeform", Kadoa
45927
45946
  options: localVarRequestOptions
45928
45947
  };
45929
45948
  },
45949
+ v5AgentPrompt: async (agentPromptRequest, options = {}) => {
45950
+ assertParamExists("v5AgentPrompt", "agentPromptRequest", agentPromptRequest);
45951
+ const localVarPath = `/v5/agent`;
45952
+ const localVarUrlObj = new URL$1(localVarPath, DUMMY_BASE_URL);
45953
+ let baseOptions;
45954
+ if (configuration) {
45955
+ baseOptions = configuration.baseOptions;
45956
+ }
45957
+ const localVarRequestOptions = { method: "POST", ...baseOptions, ...options };
45958
+ const localVarHeaderParameter = {};
45959
+ const localVarQueryParameter = {};
45960
+ localVarHeaderParameter["Content-Type"] = "application/json";
45961
+ localVarHeaderParameter["Accept"] = "application/json";
45962
+ setSearchParams(localVarUrlObj, localVarQueryParameter);
45963
+ let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
45964
+ localVarRequestOptions.headers = { ...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers };
45965
+ localVarRequestOptions.data = serializeDataIfNeeded(agentPromptRequest, localVarRequestOptions, configuration);
45966
+ return {
45967
+ url: toPathString(localVarUrlObj),
45968
+ options: localVarRequestOptions
45969
+ };
45970
+ },
45930
45971
  v5AgentResume: async (sessionId, options = {}) => {
45931
45972
  assertParamExists("v5AgentResume", "sessionId", sessionId);
45932
45973
  const localVarPath = `/v5/agent/{sessionId}/resume`.replace(`{${"sessionId"}}`, encodeURIComponent(String(sessionId)));
@@ -46032,6 +46073,12 @@ var import_debug, __require2, FREEFORM_ASSISTANT_ANSWER_KEY = "_freeform", Kadoa
46032
46073
  const localVarOperationServerBasePath = operationServerMap["AgentApi.v5AgentPauseState"]?.[localVarOperationServerIndex]?.url;
46033
46074
  return (axios2, basePath) => createRequestFunction(localVarAxiosArgs, axios_default, BASE_PATH, configuration)(axios2, localVarOperationServerBasePath || basePath);
46034
46075
  },
46076
+ async v5AgentPrompt(agentPromptRequest, options) {
46077
+ const localVarAxiosArgs = await localVarAxiosParamCreator.v5AgentPrompt(agentPromptRequest, options);
46078
+ const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
46079
+ const localVarOperationServerBasePath = operationServerMap["AgentApi.v5AgentPrompt"]?.[localVarOperationServerIndex]?.url;
46080
+ return (axios2, basePath) => createRequestFunction(localVarAxiosArgs, axios_default, BASE_PATH, configuration)(axios2, localVarOperationServerBasePath || basePath);
46081
+ },
46035
46082
  async v5AgentResume(sessionId, options) {
46036
46083
  const localVarAxiosArgs = await localVarAxiosParamCreator.v5AgentResume(sessionId, options);
46037
46084
  const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
@@ -47817,6 +47864,29 @@ var import_debug, __require2, FREEFORM_ASSISTANT_ANSWER_KEY = "_freeform", Kadoa
47817
47864
  options: localVarRequestOptions
47818
47865
  };
47819
47866
  },
47867
+ v4TemplatesTemplateIdDuplicatePost: async (templateId, duplicateTemplateBody, options = {}) => {
47868
+ assertParamExists("v4TemplatesTemplateIdDuplicatePost", "templateId", templateId);
47869
+ const localVarPath = `/v4/templates/{templateId}/duplicate`.replace(`{${"templateId"}}`, encodeURIComponent(String(templateId)));
47870
+ const localVarUrlObj = new URL$1(localVarPath, DUMMY_BASE_URL);
47871
+ let baseOptions;
47872
+ if (configuration) {
47873
+ baseOptions = configuration.baseOptions;
47874
+ }
47875
+ const localVarRequestOptions = { method: "POST", ...baseOptions, ...options };
47876
+ const localVarHeaderParameter = {};
47877
+ const localVarQueryParameter = {};
47878
+ await setApiKeyToObject(localVarHeaderParameter, "x-api-key", configuration);
47879
+ localVarHeaderParameter["Content-Type"] = "application/json";
47880
+ localVarHeaderParameter["Accept"] = "application/json";
47881
+ setSearchParams(localVarUrlObj, localVarQueryParameter);
47882
+ let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
47883
+ localVarRequestOptions.headers = { ...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers };
47884
+ localVarRequestOptions.data = serializeDataIfNeeded(duplicateTemplateBody, localVarRequestOptions, configuration);
47885
+ return {
47886
+ url: toPathString(localVarUrlObj),
47887
+ options: localVarRequestOptions
47888
+ };
47889
+ },
47820
47890
  v4TemplatesTemplateIdGet: async (templateId, options = {}) => {
47821
47891
  assertParamExists("v4TemplatesTemplateIdGet", "templateId", templateId);
47822
47892
  const localVarPath = `/v4/templates/{templateId}`.replace(`{${"templateId"}}`, encodeURIComponent(String(templateId)));
@@ -48030,6 +48100,12 @@ var import_debug, __require2, FREEFORM_ASSISTANT_ANSWER_KEY = "_freeform", Kadoa
48030
48100
  const localVarOperationServerBasePath = operationServerMap["TemplatesApi.v4TemplatesTemplateIdDelete"]?.[localVarOperationServerIndex]?.url;
48031
48101
  return (axios2, basePath) => createRequestFunction(localVarAxiosArgs, axios_default, BASE_PATH, configuration)(axios2, localVarOperationServerBasePath || basePath);
48032
48102
  },
48103
+ async v4TemplatesTemplateIdDuplicatePost(templateId, duplicateTemplateBody, options) {
48104
+ const localVarAxiosArgs = await localVarAxiosParamCreator.v4TemplatesTemplateIdDuplicatePost(templateId, duplicateTemplateBody, options);
48105
+ const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
48106
+ const localVarOperationServerBasePath = operationServerMap["TemplatesApi.v4TemplatesTemplateIdDuplicatePost"]?.[localVarOperationServerIndex]?.url;
48107
+ return (axios2, basePath) => createRequestFunction(localVarAxiosArgs, axios_default, BASE_PATH, configuration)(axios2, localVarOperationServerBasePath || basePath);
48108
+ },
48033
48109
  async v4TemplatesTemplateIdGet(templateId, options) {
48034
48110
  const localVarAxiosArgs = await localVarAxiosParamCreator.v4TemplatesTemplateIdGet(templateId, options);
48035
48111
  const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
@@ -48349,7 +48425,7 @@ var import_debug, __require2, FREEFORM_ASSISTANT_ANSWER_KEY = "_freeform", Kadoa
48349
48425
  options: localVarRequestOptions
48350
48426
  };
48351
48427
  },
48352
- v4WorkflowsGet: async (search, skip, limit, state, runState, displayState, inSupport, tags, userId, monitoring, updateInterval, scheduleType, includeDeleted, format, options = {}) => {
48428
+ v4WorkflowsGet: async (search, skip, limit, state, runState, displayState, inSupport, tags, statusFilters, userId, channelId, monitoring, updateInterval, scheduleType, templateId, includeDeleted, format, options = {}) => {
48353
48429
  const localVarPath = `/v4/workflows`;
48354
48430
  const localVarUrlObj = new URL$1(localVarPath, DUMMY_BASE_URL);
48355
48431
  let baseOptions;
@@ -48384,9 +48460,15 @@ var import_debug, __require2, FREEFORM_ASSISTANT_ANSWER_KEY = "_freeform", Kadoa
48384
48460
  if (tags) {
48385
48461
  localVarQueryParameter["tags"] = tags;
48386
48462
  }
48387
- if (userId !== undefined) {
48463
+ if (statusFilters) {
48464
+ localVarQueryParameter["statusFilters"] = statusFilters;
48465
+ }
48466
+ if (userId) {
48388
48467
  localVarQueryParameter["userId"] = userId;
48389
48468
  }
48469
+ if (channelId) {
48470
+ localVarQueryParameter["channelId"] = channelId;
48471
+ }
48390
48472
  if (monitoring !== undefined) {
48391
48473
  localVarQueryParameter["monitoring"] = monitoring;
48392
48474
  }
@@ -48396,6 +48478,9 @@ var import_debug, __require2, FREEFORM_ASSISTANT_ANSWER_KEY = "_freeform", Kadoa
48396
48478
  if (scheduleType !== undefined) {
48397
48479
  localVarQueryParameter["scheduleType"] = scheduleType;
48398
48480
  }
48481
+ if (templateId) {
48482
+ localVarQueryParameter["templateId"] = templateId;
48483
+ }
48399
48484
  if (includeDeleted !== undefined) {
48400
48485
  localVarQueryParameter["includeDeleted"] = includeDeleted;
48401
48486
  }
@@ -48745,6 +48830,30 @@ var import_debug, __require2, FREEFORM_ASSISTANT_ANSWER_KEY = "_freeform", Kadoa
48745
48830
  options: localVarRequestOptions
48746
48831
  };
48747
48832
  },
48833
+ v4WorkflowsWorkflowIdHistoryMetricsGet: async (workflowId, days, options = {}) => {
48834
+ assertParamExists("v4WorkflowsWorkflowIdHistoryMetricsGet", "workflowId", workflowId);
48835
+ const localVarPath = `/v4/workflows/{workflowId}/history/metrics`.replace(`{${"workflowId"}}`, encodeURIComponent(String(workflowId)));
48836
+ const localVarUrlObj = new URL$1(localVarPath, DUMMY_BASE_URL);
48837
+ let baseOptions;
48838
+ if (configuration) {
48839
+ baseOptions = configuration.baseOptions;
48840
+ }
48841
+ const localVarRequestOptions = { method: "GET", ...baseOptions, ...options };
48842
+ const localVarHeaderParameter = {};
48843
+ const localVarQueryParameter = {};
48844
+ await setApiKeyToObject(localVarHeaderParameter, "x-api-key", configuration);
48845
+ if (days !== undefined) {
48846
+ localVarQueryParameter["days"] = days;
48847
+ }
48848
+ localVarHeaderParameter["Accept"] = "application/json";
48849
+ setSearchParams(localVarUrlObj, localVarQueryParameter);
48850
+ let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
48851
+ localVarRequestOptions.headers = { ...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers };
48852
+ return {
48853
+ url: toPathString(localVarUrlObj),
48854
+ options: localVarRequestOptions
48855
+ };
48856
+ },
48748
48857
  v4WorkflowsWorkflowIdJobsJobIdGet: async (workflowId, jobId, options = {}) => {
48749
48858
  assertParamExists("v4WorkflowsWorkflowIdJobsJobIdGet", "workflowId", workflowId);
48750
48859
  assertParamExists("v4WorkflowsWorkflowIdJobsJobIdGet", "jobId", jobId);
@@ -48812,6 +48921,31 @@ var import_debug, __require2, FREEFORM_ASSISTANT_ANSWER_KEY = "_freeform", Kadoa
48812
48921
  options: localVarRequestOptions
48813
48922
  };
48814
48923
  },
48924
+ v4WorkflowsWorkflowIdQualityMetricsGet: async (workflowId, jobId, options = {}) => {
48925
+ assertParamExists("v4WorkflowsWorkflowIdQualityMetricsGet", "workflowId", workflowId);
48926
+ const localVarPath = `/v4/workflows/{workflowId}/quality-metrics`.replace(`{${"workflowId"}}`, encodeURIComponent(String(workflowId)));
48927
+ const localVarUrlObj = new URL$1(localVarPath, DUMMY_BASE_URL);
48928
+ let baseOptions;
48929
+ if (configuration) {
48930
+ baseOptions = configuration.baseOptions;
48931
+ }
48932
+ const localVarRequestOptions = { method: "GET", ...baseOptions, ...options };
48933
+ const localVarHeaderParameter = {};
48934
+ const localVarQueryParameter = {};
48935
+ await setApiKeyToObject(localVarHeaderParameter, "x-api-key", configuration);
48936
+ await setBearerAuthToObject(localVarHeaderParameter, configuration);
48937
+ if (jobId !== undefined) {
48938
+ localVarQueryParameter["jobId"] = jobId;
48939
+ }
48940
+ localVarHeaderParameter["Accept"] = "application/json";
48941
+ setSearchParams(localVarUrlObj, localVarQueryParameter);
48942
+ let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
48943
+ localVarRequestOptions.headers = { ...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers };
48944
+ return {
48945
+ url: toPathString(localVarUrlObj),
48946
+ options: localVarRequestOptions
48947
+ };
48948
+ },
48815
48949
  v4WorkflowsWorkflowIdResumePut: async (workflowId, options = {}) => {
48816
48950
  assertParamExists("v4WorkflowsWorkflowIdResumePut", "workflowId", workflowId);
48817
48951
  const localVarPath = `/v4/workflows/{workflowId}/resume`.replace(`{${"workflowId"}}`, encodeURIComponent(String(workflowId)));
@@ -49033,8 +49167,8 @@ var import_debug, __require2, FREEFORM_ASSISTANT_ANSWER_KEY = "_freeform", Kadoa
49033
49167
  const localVarOperationServerBasePath = operationServerMap["WorkflowsApi.v4WorkflowsBulkPost"]?.[localVarOperationServerIndex]?.url;
49034
49168
  return (axios2, basePath) => createRequestFunction(localVarAxiosArgs, axios_default, BASE_PATH, configuration)(axios2, localVarOperationServerBasePath || basePath);
49035
49169
  },
49036
- async v4WorkflowsGet(search, skip, limit, state, runState, displayState, inSupport, tags, userId, monitoring, updateInterval, scheduleType, includeDeleted, format, options) {
49037
- const localVarAxiosArgs = await localVarAxiosParamCreator.v4WorkflowsGet(search, skip, limit, state, runState, displayState, inSupport, tags, userId, monitoring, updateInterval, scheduleType, includeDeleted, format, options);
49170
+ async v4WorkflowsGet(search, skip, limit, state, runState, displayState, inSupport, tags, statusFilters, userId, channelId, monitoring, updateInterval, scheduleType, templateId, includeDeleted, format, options) {
49171
+ const localVarAxiosArgs = await localVarAxiosParamCreator.v4WorkflowsGet(search, skip, limit, state, runState, displayState, inSupport, tags, statusFilters, userId, channelId, monitoring, updateInterval, scheduleType, templateId, includeDeleted, format, options);
49038
49172
  const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
49039
49173
  const localVarOperationServerBasePath = operationServerMap["WorkflowsApi.v4WorkflowsGet"]?.[localVarOperationServerIndex]?.url;
49040
49174
  return (axios2, basePath) => createRequestFunction(localVarAxiosArgs, axios_default, BASE_PATH, configuration)(axios2, localVarOperationServerBasePath || basePath);
@@ -49105,6 +49239,12 @@ var import_debug, __require2, FREEFORM_ASSISTANT_ANSWER_KEY = "_freeform", Kadoa
49105
49239
  const localVarOperationServerBasePath = operationServerMap["WorkflowsApi.v4WorkflowsWorkflowIdHistoryGet"]?.[localVarOperationServerIndex]?.url;
49106
49240
  return (axios2, basePath) => createRequestFunction(localVarAxiosArgs, axios_default, BASE_PATH, configuration)(axios2, localVarOperationServerBasePath || basePath);
49107
49241
  },
49242
+ async v4WorkflowsWorkflowIdHistoryMetricsGet(workflowId, days, options) {
49243
+ const localVarAxiosArgs = await localVarAxiosParamCreator.v4WorkflowsWorkflowIdHistoryMetricsGet(workflowId, days, options);
49244
+ const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
49245
+ const localVarOperationServerBasePath = operationServerMap["WorkflowsApi.v4WorkflowsWorkflowIdHistoryMetricsGet"]?.[localVarOperationServerIndex]?.url;
49246
+ return (axios2, basePath) => createRequestFunction(localVarAxiosArgs, axios_default, BASE_PATH, configuration)(axios2, localVarOperationServerBasePath || basePath);
49247
+ },
49108
49248
  async v4WorkflowsWorkflowIdJobsJobIdGet(workflowId, jobId, options) {
49109
49249
  const localVarAxiosArgs = await localVarAxiosParamCreator.v4WorkflowsWorkflowIdJobsJobIdGet(workflowId, jobId, options);
49110
49250
  const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
@@ -49123,6 +49263,12 @@ var import_debug, __require2, FREEFORM_ASSISTANT_ANSWER_KEY = "_freeform", Kadoa
49123
49263
  const localVarOperationServerBasePath = operationServerMap["WorkflowsApi.v4WorkflowsWorkflowIdPausePut"]?.[localVarOperationServerIndex]?.url;
49124
49264
  return (axios2, basePath) => createRequestFunction(localVarAxiosArgs, axios_default, BASE_PATH, configuration)(axios2, localVarOperationServerBasePath || basePath);
49125
49265
  },
49266
+ async v4WorkflowsWorkflowIdQualityMetricsGet(workflowId, jobId, options) {
49267
+ const localVarAxiosArgs = await localVarAxiosParamCreator.v4WorkflowsWorkflowIdQualityMetricsGet(workflowId, jobId, options);
49268
+ const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
49269
+ const localVarOperationServerBasePath = operationServerMap["WorkflowsApi.v4WorkflowsWorkflowIdQualityMetricsGet"]?.[localVarOperationServerIndex]?.url;
49270
+ return (axios2, basePath) => createRequestFunction(localVarAxiosArgs, axios_default, BASE_PATH, configuration)(axios2, localVarOperationServerBasePath || basePath);
49271
+ },
49126
49272
  async v4WorkflowsWorkflowIdResumePut(workflowId, options) {
49127
49273
  const localVarAxiosArgs = await localVarAxiosParamCreator.v4WorkflowsWorkflowIdResumePut(workflowId, options);
49128
49274
  const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
@@ -50276,7 +50422,7 @@ var import_debug, __require2, FREEFORM_ASSISTANT_ANSWER_KEY = "_freeform", Kadoa
50276
50422
  }));
50277
50423
  return channels;
50278
50424
  }
50279
- }, PUBLIC_API_URI, WSS_API_URI, REALTIME_API_URI, SDK_VERSION = "0.37.1", SDK_NAME = "kadoa-node-sdk", SDK_LANGUAGE = "node", debug6, isDrainControlMessage = (message) => message.type === "control.draining", isRealtimeEvent = (message) => message.type !== "heartbeat" && message.type !== "control.draining", _Realtime = class _Realtime2 {
50425
+ }, PUBLIC_API_URI, WSS_API_URI, REALTIME_API_URI, SDK_VERSION = "0.38.0", SDK_NAME = "kadoa-node-sdk", SDK_LANGUAGE = "node", debug6, isDrainControlMessage = (message) => message.type === "control.draining", isRealtimeEvent = (message) => message.type !== "heartbeat" && message.type !== "control.draining", _Realtime = class _Realtime2 {
50280
50426
  constructor(config2) {
50281
50427
  this.drainingSockets = /* @__PURE__ */ new Set;
50282
50428
  this.lastHeartbeat = Date.now();
@@ -51181,7 +51327,17 @@ var import_debug, __require2, FREEFORM_ASSISTANT_ANSWER_KEY = "_freeform", Kadoa
51181
51327
  return response.data;
51182
51328
  }
51183
51329
  async list(filters) {
51184
- const response = await this.workflowsApi.v4WorkflowsGet(filters);
51330
+ if (filters == null) {
51331
+ const response2 = await this.workflowsApi.v4WorkflowsGet();
51332
+ return response2.data?.workflows ?? [];
51333
+ }
51334
+ const { templateId, ...rest2 } = filters;
51335
+ const response = await this.workflowsApi.v4WorkflowsGet({
51336
+ ...rest2,
51337
+ ...templateId != null && {
51338
+ templateId: Array.isArray(templateId) ? templateId : [templateId]
51339
+ }
51340
+ });
51185
51341
  return response.data?.workflows ?? [];
51186
51342
  }
51187
51343
  async getByName(name) {
@@ -51693,6 +51849,9 @@ var init_dist2 = __esm(() => {
51693
51849
  v5AgentPauseState(requestParameters, options) {
51694
51850
  return AgentApiFp(this.configuration).v5AgentPauseState(requestParameters.sessionId, options).then((request) => request(this.axios, this.basePath));
51695
51851
  }
51852
+ v5AgentPrompt(requestParameters, options) {
51853
+ return AgentApiFp(this.configuration).v5AgentPrompt(requestParameters.agentPromptRequest, options).then((request) => request(this.axios, this.basePath));
51854
+ }
51696
51855
  v5AgentResume(requestParameters, options) {
51697
51856
  return AgentApiFp(this.configuration).v5AgentResume(requestParameters.sessionId, options).then((request) => request(this.axios, this.basePath));
51698
51857
  }
@@ -51907,6 +52066,9 @@ var init_dist2 = __esm(() => {
51907
52066
  v4TemplatesTemplateIdDelete(requestParameters, options) {
51908
52067
  return TemplatesApiFp(this.configuration).v4TemplatesTemplateIdDelete(requestParameters.templateId, options).then((request) => request(this.axios, this.basePath));
51909
52068
  }
52069
+ v4TemplatesTemplateIdDuplicatePost(requestParameters, options) {
52070
+ return TemplatesApiFp(this.configuration).v4TemplatesTemplateIdDuplicatePost(requestParameters.templateId, requestParameters.duplicateTemplateBody, options).then((request) => request(this.axios, this.basePath));
52071
+ }
51910
52072
  v4TemplatesTemplateIdGet(requestParameters, options) {
51911
52073
  return TemplatesApiFp(this.configuration).v4TemplatesTemplateIdGet(requestParameters.templateId, options).then((request) => request(this.axios, this.basePath));
51912
52074
  }
@@ -51963,7 +52125,7 @@ var init_dist2 = __esm(() => {
51963
52125
  return WorkflowsApiFp(this.configuration).v4WorkflowsBulkPost(requestParameters.v4WorkflowsBulkPostRequest, options).then((request) => request(this.axios, this.basePath));
51964
52126
  }
51965
52127
  v4WorkflowsGet(requestParameters = {}, options) {
51966
- return WorkflowsApiFp(this.configuration).v4WorkflowsGet(requestParameters.search, requestParameters.skip, requestParameters.limit, requestParameters.state, requestParameters.runState, requestParameters.displayState, requestParameters.inSupport, requestParameters.tags, requestParameters.userId, requestParameters.monitoring, requestParameters.updateInterval, requestParameters.scheduleType, requestParameters.includeDeleted, requestParameters.format, options).then((request) => request(this.axios, this.basePath));
52128
+ return WorkflowsApiFp(this.configuration).v4WorkflowsGet(requestParameters.search, requestParameters.skip, requestParameters.limit, requestParameters.state, requestParameters.runState, requestParameters.displayState, requestParameters.inSupport, requestParameters.tags, requestParameters.statusFilters, requestParameters.userId, requestParameters.channelId, requestParameters.monitoring, requestParameters.updateInterval, requestParameters.scheduleType, requestParameters.templateId, requestParameters.includeDeleted, requestParameters.format, options).then((request) => request(this.axios, this.basePath));
51967
52129
  }
51968
52130
  v4WorkflowsPost(requestParameters = {}, options) {
51969
52131
  return WorkflowsApiFp(this.configuration).v4WorkflowsPost(requestParameters.publicWorkflowCreateRequest, options).then((request) => request(this.axios, this.basePath));
@@ -51998,6 +52160,9 @@ var init_dist2 = __esm(() => {
51998
52160
  v4WorkflowsWorkflowIdHistoryGet(requestParameters, options) {
51999
52161
  return WorkflowsApiFp(this.configuration).v4WorkflowsWorkflowIdHistoryGet(requestParameters.workflowId, requestParameters.page, requestParameters.limit, requestParameters.status, options).then((request) => request(this.axios, this.basePath));
52000
52162
  }
52163
+ v4WorkflowsWorkflowIdHistoryMetricsGet(requestParameters, options) {
52164
+ return WorkflowsApiFp(this.configuration).v4WorkflowsWorkflowIdHistoryMetricsGet(requestParameters.workflowId, requestParameters.days, options).then((request) => request(this.axios, this.basePath));
52165
+ }
52001
52166
  v4WorkflowsWorkflowIdJobsJobIdGet(requestParameters, options) {
52002
52167
  return WorkflowsApiFp(this.configuration).v4WorkflowsWorkflowIdJobsJobIdGet(requestParameters.workflowId, requestParameters.jobId, options).then((request) => request(this.axios, this.basePath));
52003
52168
  }
@@ -52007,6 +52172,9 @@ var init_dist2 = __esm(() => {
52007
52172
  v4WorkflowsWorkflowIdPausePut(requestParameters, options) {
52008
52173
  return WorkflowsApiFp(this.configuration).v4WorkflowsWorkflowIdPausePut(requestParameters.workflowId, options).then((request) => request(this.axios, this.basePath));
52009
52174
  }
52175
+ v4WorkflowsWorkflowIdQualityMetricsGet(requestParameters, options) {
52176
+ return WorkflowsApiFp(this.configuration).v4WorkflowsWorkflowIdQualityMetricsGet(requestParameters.workflowId, requestParameters.jobId, options).then((request) => request(this.axios, this.basePath));
52177
+ }
52010
52178
  v4WorkflowsWorkflowIdResumePut(requestParameters, options) {
52011
52179
  return WorkflowsApiFp(this.configuration).v4WorkflowsWorkflowIdResumePut(requestParameters.workflowId, options).then((request) => request(this.axios, this.basePath));
52012
52180
  }
@@ -52765,6 +52933,33 @@ function registerTools(server, ctx, capabilities) {
52765
52933
  const urls = args.urls ?? (args.url ? [args.url] : []);
52766
52934
  return urls.length > 0 ? urls : null;
52767
52935
  }
52936
+ function buildRealtimeAssistantInstructions(args, urls) {
52937
+ const lines = ["Create a realtime monitoring workflow with Julie.", "", "Source URLs:"];
52938
+ for (const url3 of urls)
52939
+ lines.push(`- ${url3}`);
52940
+ if (args.prompt)
52941
+ lines.push("", "User prompt:", args.prompt);
52942
+ if (args.name)
52943
+ lines.push("", `Requested workflow name: ${args.name}`);
52944
+ if (args.description)
52945
+ lines.push(`Requested workflow description: ${args.description}`);
52946
+ if (args.entity)
52947
+ lines.push("", `Entity to monitor: ${args.entity}`);
52948
+ if (args.schema?.length) {
52949
+ lines.push("", "Schema fields to preserve:");
52950
+ for (const field of args.schema) {
52951
+ lines.push(`- ${field.name}`);
52952
+ lines.push(` Data type: ${field.dataType || "STRING"}`);
52953
+ lines.push(` Key field: ${field.isKey ? "yes" : "no"}`);
52954
+ if (field.description)
52955
+ lines.push(` Description: ${field.description}`);
52956
+ lines.push(` Example: ${field.example}`);
52957
+ }
52958
+ }
52959
+ lines.push("", "Monitor continuously for data changes and preserve these requirements while building the workflow.");
52960
+ return lines.join(`
52961
+ `);
52962
+ }
52768
52963
  function buildExtraction(args) {
52769
52964
  if (!args.schema)
52770
52965
  return;
@@ -52839,7 +53034,7 @@ function registerTools(server, ctx, capabilities) {
52839
53034
 
52840
53035
  ` + "Create a data extraction workflow using agentic navigation. Supports one-time or scheduled runs. " + "If entity and schema are provided, they guide the extraction; otherwise the AI agent auto-detects the schema from the page. " + "The workflow runs asynchronously and may take several minutes. Do NOT poll or sleep-wait for completion. " + `Return the workflow ID to the user and let them check back later with get_workflow or fetch_data.
52841
53036
 
52842
- ` + "PREFER TEMPLATES: If the user's request matches an existing template, instantiate it via `templateId` instead of writing a fresh prompt/schema. " + "Use `list_templates` to discover available templates and `get_template` to inspect schemas before deciding. " + "When `templateId` is set, only `urls` is required — `prompt`, `entity`, and `schema` must NOT be supplied; they are inherited from the template version.\n\n" + "NOTE: This tool is for one-time or scheduled extraction ONLY. " + "For continuous real-time monitoring (watching a page for changes and alerting), use the create_realtime_monitor tool instead.",
53037
+ ` + "PREFER TEMPLATES: If the user's request matches an existing template, instantiate it via `templateId` instead of writing a fresh prompt/schema. " + "Use `list_templates` to discover available templates and `get_template` to inspect schemas before deciding. " + "When `templateId` is set, only `urls` is required — `prompt`, `entity`, and `schema` must NOT be supplied; they are inherited from the template version.\n\n" + "NOTE: This tool is for one-time or scheduled extraction ONLY. " + "For continuous Julie realtime monitoring (watching a page for data changes and alerting), use the create_realtime_monitor tool instead.",
52843
53038
  inputSchema: strictSchema({
52844
53039
  ...extractionInputShape,
52845
53040
  ...urlInputShape,
@@ -52950,9 +53145,9 @@ function registerTools(server, ctx, capabilities) {
52950
53145
  });
52951
53146
  }));
52952
53147
  server.registerTool("create_realtime_monitor", {
52953
- description: "Create a real-time monitoring workflow that continuously watches a page for changes and sends alerts. " + "Use this when the user wants to monitor, track, or watch a page in real-time. " + "At least one notification channel (email, webhook, slack, or websocket) is required so the user gets alerted on changes. " + `Real-time monitors route to a separate Observer service and CANNOT be converted to/from regular extraction workflows after creation.
53148
+ description: "Create a Julie realtime monitoring workflow that continuously watches a page for data changes and sends alerts. " + "Use this when the user wants to monitor, track, or watch a page in realtime. " + "At least one notification channel (email, webhook, slack, or websocket) is required; notification settings are persisted before Julie is dispatched. " + `Realtime monitors CANNOT be converted to/from regular extraction workflows after creation.
52954
53149
 
52955
- ` + "If entity and schema are provided, they guide what to monitor; otherwise the AI agent auto-detects what to watch. " + "Do NOT poll or sleep-wait for completion. Return the workflow ID and let the user check back with get_workflow or fetch_data.",
53150
+ ` + "If entity and schema are provided, they guide what Julie should monitor; otherwise Julie auto-detects what to watch. " + "Creation is asynchronous and the response includes workflow, session, thread, and job IDs plus a dashboard URL. " + "Use generic workflow Assistant tools (get_workflow_assistant, answer_workflow_assistant_question, interrupt_workflow_assistant, resume_workflow_assistant, stop_workflow_assistant) for follow-up status, questions, and controls. " + "Do NOT poll or sleep-wait for completion.",
52956
53151
  inputSchema: strictSchema({
52957
53152
  ...extractionInputShape,
52958
53153
  ...urlInputShape,
@@ -52971,33 +53166,33 @@ function registerTools(server, ctx, capabilities) {
52971
53166
  if (!hasNotifications) {
52972
53167
  return errorResult("Real-time monitors require at least one notification channel so you get alerted when data changes. " + "Add a notifications object with one or more channels: email, webhook, slack, or websocket.");
52973
53168
  }
52974
- let builder = ctx.client.extract({
52975
- urls,
52976
- name: args.name || "Untitled Monitor",
52977
- userPrompt: args.prompt,
52978
- extraction: buildExtraction(args),
52979
- interval: "REAL_TIME",
52980
- description: args.description
52981
- });
52982
- builder = builder.withNotifications({
52983
- events: ["workflow_data_change"],
53169
+ const channels = await ctx.client.notification.setup.setupChannels({
52984
53170
  channels: buildNotificationChannels(n)
52985
53171
  });
52986
- const workflow = await builder.create();
52987
- if (args.tags && args.tags.length > 0) {
52988
- await ctx.client.workflow.update(workflow.workflowId, { tags: args.tags });
53172
+ const notificationChannelIds = channels.map((channel) => channel.id).filter((id) => typeof id === "string" && id.length > 0);
53173
+ if (notificationChannelIds.length === 0) {
53174
+ return errorResult("No usable notification channels were configured for the realtime monitor.");
52989
53175
  }
52990
- const enabledChannels = await describeNotifications(n);
52991
- let message = "Real-time monitor created successfully. It will continuously watch for changes — no manual runs needed.";
52992
- if (enabledChannels.length > 0) {
52993
- message += ` Notifications on data changes via: ${enabledChannels.join(", ")}.`;
53176
+ const result = await ctx.client.assistant.createRealtimeWorkflow({
53177
+ instructions: buildRealtimeAssistantInstructions(args, urls),
53178
+ notificationChannelIds,
53179
+ ...args.tags?.length ? { tags: args.tags } : {}
53180
+ });
53181
+ if (!result || typeof result.workflowId !== "string" || result.workflowId.length === 0 || typeof result.sessionId !== "string" || result.sessionId.length === 0 || typeof result.threadId !== "string" || result.threadId.length === 0 || typeof result.jobId !== "string" || result.jobId.length === 0) {
53182
+ throw new KadoaSdkException("Realtime Assistant creation response is missing required identifiers", {
53183
+ code: "INTERNAL_ERROR",
53184
+ details: { response: result }
53185
+ });
52994
53186
  }
52995
- message += " Use fetch_data to retrieve the latest data.";
52996
53187
  return jsonResult({
52997
53188
  success: true,
52998
- workflowId: workflow.workflowId,
52999
- dashboardUrl: workflowDashboardUrl(workflow.workflowId),
53000
- message
53189
+ status: "accepted",
53190
+ workflowId: result.workflowId,
53191
+ sessionId: result.sessionId,
53192
+ threadId: result.threadId,
53193
+ jobId: result.jobId,
53194
+ dashboardUrl: workflowDashboardUrl(result.workflowId),
53195
+ message: "Julie realtime workflow creation accepted. Notification settings were persisted before Julie dispatch. Creation is asynchronous; use get_workflow_assistant for status, questions, or controls, and do not poll or sleep-wait."
53001
53196
  });
53002
53197
  }));
53003
53198
  server.registerTool("list_workflows", {
@@ -53523,7 +53718,7 @@ function registerTools(server, ctx, capabilities) {
53523
53718
  });
53524
53719
  }));
53525
53720
  server.registerTool("list_changes", {
53526
- description: "List detected data changes across one or more real-time monitoring workflows. " + "Returns structured diffs showing added, removed, and changed records. " + "Only works for workflows with real-time monitoring enabled.",
53721
+ description: "List detected data changes across one or more Julie realtime monitoring workflows. " + "Returns structured diffs showing added, removed, and changed records. " + "Only works for workflows with realtime monitoring enabled.",
53527
53722
  inputSchema: {
53528
53723
  workflowIds: exports_external.preprocess(coerceArray(true), exports_external.array(exports_external.string())).optional().describe("Workflow IDs to filter by. If omitted, returns changes for all ACTIVE monitoring workflows."),
53529
53724
  startDate: exports_external.string().optional().describe("Start date filter (ISO format, e.g. 2025-01-01)"),
@@ -53633,7 +53828,7 @@ function registerTools(server, ctx, capabilities) {
53633
53828
  server.registerTool("update_workflow", {
53634
53829
  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.
53635
53830
 
53636
- ` + `IMPORTANT: You cannot change a workflow's interval to or from REAL_TIME. Real-time workflows are architecturally different from scheduled workflows and must be created with create_realtime_monitor from the start. Existing workflows cannot be converted between these modes in place; do not delete and recreate a workflow as an update workaround.
53831
+ ` + `IMPORTANT: You cannot change a workflow's interval to or from REAL_TIME. Julie realtime workflows are architecturally different from scheduled workflows and must be created with create_realtime_monitor from the start. Existing workflows cannot be converted between these modes in place; do not delete and recreate a workflow as an update workaround.
53637
53832
 
53638
53833
  ` + "ASSISTANT-OWNED INTENT: Use request_workflow_update—not `userPrompt`—for agent-built workflow changes to extraction intent, navigation, pagination, data sourcing, repair, or generated scripts. `userPrompt` may be rejected with `SHELLY_INTENT_REQUIRES_EXTRACTION_SPEC` because those workflows' canonical intent is owned by the Assistant. " + "Call get_workflow first. If its template.controlledParts contains the setting, create and apply a template version instead of overriding the workflow directly. NEVER delete and recreate a workflow to work around an update limitation—that changes workflowId, breaks downstream tables/connectors, and discards history.",
53639
53834
  inputSchema: strictSchema({
@@ -53663,7 +53858,7 @@ function registerTools(server, ctx, capabilities) {
53663
53858
  "FOUR_WEEKS",
53664
53859
  "MONTHLY",
53665
53860
  "CUSTOM"
53666
- ]).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."),
53861
+ ]).optional().describe("How often the workflow should run. CUSTOM requires schedules. Note: REAL_TIME is NOT allowed here — realtime workflows must be created via create_realtime_monitor."),
53667
53862
  schedules: exports_external.preprocess(coerceArray(true), exports_external.array(exports_external.string())).optional().describe("Cron expressions for CUSTOM update interval"),
53668
53863
  timezone: exports_external.string().min(1).optional().describe("IANA timezone for cron schedules, for example America/New_York. A timezone-only update preserves existing cron expressions."),
53669
53864
  location: exports_external.preprocess(coerceJson(), LocationSchema).optional().describe("Scraping location: {type:'auto'} or {type:'manual', isoCode:'US'}"),
@@ -53678,10 +53873,10 @@ function registerTools(server, ctx, capabilities) {
53678
53873
  const isCurrentlyRealTime = isRealTimeInterval(workflow.updateInterval);
53679
53874
  const isRequestingRealTime = isRealTimeInterval(updates.updateInterval);
53680
53875
  if (isRequestingRealTime && !isCurrentlyRealTime) {
53681
- return errorResult("Cannot change a regular workflow's interval to REAL_TIME. " + "Real-time workflows use a different service and cannot replace this workflow in place. " + "The existing workflow was left unchanged.");
53876
+ return errorResult("Cannot change a regular workflow's interval to REAL_TIME. " + "Julie realtime workflows cannot replace this workflow in place. " + "The existing workflow was left unchanged.");
53682
53877
  }
53683
53878
  if (!isRequestingRealTime && isCurrentlyRealTime) {
53684
- return errorResult("Cannot change a real-time workflow's interval to a scheduled interval. " + "Real-time workflows are architecturally different and cannot be converted in place. " + "The existing workflow was left unchanged.");
53879
+ return errorResult("Cannot change a Julie realtime workflow's interval to a scheduled interval. " + "Julie realtime workflows are architecturally different and cannot be converted in place. " + "The existing workflow was left unchanged.");
53685
53880
  }
53686
53881
  }
53687
53882
  if (updates.updateInterval === "CUSTOM" && (!updates.schedules || updates.schedules.length === 0)) {
@@ -54443,7 +54638,7 @@ var package_default;
54443
54638
  var init_package = __esm(() => {
54444
54639
  package_default = {
54445
54640
  name: "@kadoa/mcp",
54446
- version: "0.5.19",
54641
+ version: "0.5.20",
54447
54642
  description: "Kadoa MCP Server — manage workflows from Claude Desktop, Cursor, and other MCP clients",
54448
54643
  type: "module",
54449
54644
  main: "dist/index.js",
@@ -54467,7 +54662,7 @@ var init_package = __esm(() => {
54467
54662
  prepublishOnly: "bun run check-types && bun run test:unit && bun run build"
54468
54663
  },
54469
54664
  dependencies: {
54470
- "@kadoa/node-sdk": "^0.37.1",
54665
+ "@kadoa/node-sdk": "^0.38.0",
54471
54666
  "@modelcontextprotocol/sdk": "^1.26.0",
54472
54667
  express: "^5.2.1",
54473
54668
  "express-rate-limit": "^8.2.1",
@@ -60053,9 +60248,9 @@ async function createServer(auth, options) {
60053
60248
  "",
60054
60249
  "Workflow lifecycle: create_workflow \u2192 get_workflow (check status) \u2192 fetch_data (get results). Workflows run asynchronously \u2014 never poll or sleep-wait.",
60055
60250
  "",
60056
- "Use create_realtime_monitor only when the user wants continuous change detection with alerts. For one-time or scheduled extraction, use create_workflow.",
60057
- "Use scrape for an immediate raw HTML or markdown fetch from one URL. Use create_workflow for structured extraction, recurring runs, monitoring, or navigation-heavy jobs.",
60058
- "Use list_changes and get_change to retrieve detected diffs from real-time monitoring workflows.",
60251
+ "Use create_realtime_monitor only when the user wants continuous Julie change detection with alerts. It first persists notification channels, then asynchronously returns workflow/session/thread/job IDs; use the workflow Assistant tools for follow-up status, questions, and controls.",
60252
+ "For one-time or scheduled extraction, use create_workflow. Use scrape for an immediate raw HTML or markdown fetch from one URL. Use create_workflow for structured extraction, recurring runs, monitoring, or navigation-heavy jobs.",
60253
+ "Use list_changes and get_change to retrieve detected diffs from realtime monitoring workflows.",
60059
60254
  "",
60060
60255
  "Schema tips: Use descriptive field names and examples. Group related data under one entity.",
60061
60256
  "The AI agent uses the schema + prompt to understand what to extract \u2014 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.5.19",
3
+ "version": "0.5.20",
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",
@@ -24,7 +24,7 @@
24
24
  "prepublishOnly": "bun run check-types && bun run test:unit && bun run build"
25
25
  },
26
26
  "dependencies": {
27
- "@kadoa/node-sdk": "^0.37.1",
27
+ "@kadoa/node-sdk": "^0.38.0",
28
28
  "@modelcontextprotocol/sdk": "^1.26.0",
29
29
  "express": "^5.2.1",
30
30
  "express-rate-limit": "^8.2.1",