@kadoa/mcp 0.5.22 → 0.5.24

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 +28 -13
  2. package/dist/index.js +244 -62
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -62,16 +62,18 @@ Point your client to `https://mcp.kadoa.com/mcp` with OAuth authentication.
62
62
  | Tool | Description |
63
63
  |------|-------------|
64
64
  | `scrape` | Immediately fetch one URL as markdown or raw HTML (shown only for enabled workspaces) |
65
+ | `list_inbox` | List personal unread Inbox items across workflows, optionally including read history |
66
+ | `mark_inbox_item_read` | Acknowledge one Inbox item without performing its underlying workflow action |
65
67
  | `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 |
68
+ | `create_realtime_monitor` | Create an asynchronous realtime monitoring workflow after persisting notification channels; returns workflow/session/thread/job IDs |
67
69
  | `list_workflows` | List all workflows with status |
68
70
  | `get_workflow` | Get canonical intent, Assistant/session, template ownership, run health, schedule, location, monitoring, and validation details |
69
71
  | `request_workflow_update` | Ask the workflow Assistant to change extraction intent, navigation, sourcing, pagination, or generated behavior without changing the workflow ID |
70
72
  | `get_workflow_assistant` | Get the workflow Assistant's current activity and any pending clarification question |
71
- | `get_workflow_assistant_timeline` | Read paginated customer-visible Assistant messages and questions for Lighthouse or Julie |
73
+ | `get_workflow_assistant_timeline` | Read paginated customer-visible Assistant messages and questions for one-time, scheduled, or realtime workflows |
72
74
  | `answer_workflow_assistant_question` | Answer the workflow Assistant's current clarification question and resume it |
73
75
  | `interrupt_workflow_assistant` | Safely interrupt active Assistant work without pausing the workflow schedule |
74
- | `resume_workflow_assistant` | Resume an idle/interrupted Lighthouse or Julie session with its persisted persona |
76
+ | `resume_workflow_assistant` | Resume an idle/interrupted workflow Assistant with its persisted role and conversation |
75
77
  | `stop_workflow_assistant` | Stop active Assistant work without deleting or replacing the workflow |
76
78
  | `get_workflow_strategy` | Get the current customer-safe extraction/build strategy for an Assistant or custom-script workflow |
77
79
  | `get_workflow_history` | Get the workflow's configuration revision history (audit log) — who changed it, when, from which channel, and a `changedFields` summary per revision |
@@ -102,6 +104,17 @@ its own when a site blocks bots. Ask for HTML when you need the raw source.
102
104
 
103
105
  The `scrape` tool is available only to workspaces enabled for the Scrape API. Use a workflow instead for structured extraction, recurring runs, monitoring, or multi-page navigation.
104
106
 
107
+ ### Review work that needs attention
108
+
109
+ ```
110
+ > You: What needs my attention in Kadoa?
111
+
112
+ Claude calls list_inbox and shows unread questions and review items across
113
+ workflows. For an Assistant question, it calls get_workflow_assistant to load
114
+ the authoritative question before asking whether you want to answer it.
115
+ Marking the Inbox item read only acknowledges it.
116
+ ```
117
+
105
118
  ### Create and run a workflow
106
119
 
107
120
  ```
@@ -126,12 +139,14 @@ to retrieve the extracted records and display them as a table.
126
139
 
127
140
  ```
128
141
  > You: Use my "Product Scraper" template to scrape https://example-shop.com.
142
+ > For this source, only include products that are in stock.
129
143
 
130
144
  Claude calls list_templates to find the matching template, then
131
- create_workflow with `templateId` and `urls` only - never copy the prompt,
132
- entity, or schema into standalone creation. Those values are inherited from
133
- the template version. Returns the workflow ID for follow-up with get_workflow
134
- or fetch_data.
145
+ create_workflow with `templateId`, `urls`, and `prompt` containing only the
146
+ source-specific instruction. The template's shared prompt, entity, and schema
147
+ are inherited and must not be copied into the call. The optional workflow
148
+ instruction remains workflow-owned when the template is updated. Returns the
149
+ workflow ID for follow-up with get_workflow or fetch_data.
135
150
  ```
136
151
 
137
152
  ### Update a workflow and re-run
@@ -168,14 +183,14 @@ in `America/New_York`, monitoring fields/conditions, and `limit: null` for all
168
183
  rows.
169
184
  ```
170
185
 
171
- ### Create a Julie realtime monitor
186
+ ### Create a realtime monitoring workflow
172
187
 
173
188
  ```
174
189
  > You: Watch https://example-shop.com/products for price changes and alert me by webhook.
175
190
 
176
- 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.
191
+ Claude calls create_realtime_monitor with the URL, schema/change intent, and notification settings. Kadoa persists reusable notification channels first, then asynchronously accepts creation and returns workflow, session, thread, job, and dashboard identifiers.
177
192
 
178
- > You: Does Julie need anything from me?
193
+ > You: Does the workflow Assistant need anything from me?
179
194
 
180
195
  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.
181
196
  ```
@@ -206,9 +221,9 @@ navigation, and extraction approach.
206
221
  > You: Interrupt the Assistant for now, then resume it later.
207
222
 
208
223
  Claude calls interrupt_workflow_assistant. When asked later, it calls
209
- resume_workflow_assistant, which preserves whether the session is Lighthouse
210
- or Julie. stop_workflow_assistant cancels active Assistant work without
211
- pausing or deleting the workflow itself.
224
+ resume_workflow_assistant, which continues the same Assistant role and
225
+ conversation for either workflow mode. stop_workflow_assistant cancels active
226
+ Assistant work without pausing or deleting the workflow itself.
212
227
  ```
213
228
 
214
229
  Use `update_workflow` for deterministic metadata such as name, schedule, tags,
package/dist/index.js CHANGED
@@ -45506,6 +45506,29 @@ function buildAgenticPrompt2(params) {
45506
45506
  }
45507
45507
  return `extract all records from this page and return these fields: ${fieldList}`;
45508
45508
  }
45509
+ function mapInboxItem(item) {
45510
+ return {
45511
+ id: item.id,
45512
+ type: knownInboxItemTypes[item.type] ?? item.type,
45513
+ subjectId: item.subjectId,
45514
+ workflowId: item.workflowId,
45515
+ title: item.title,
45516
+ payload: item.payload,
45517
+ isRead: item.isRead,
45518
+ readAt: item.readAt,
45519
+ createdAt: item.createdAt,
45520
+ updatedAt: item.updatedAt
45521
+ };
45522
+ }
45523
+ function mapInboxListResponse(response) {
45524
+ return {
45525
+ unreadCount: response.data.unreadCount,
45526
+ items: response.data.items.map(mapInboxItem)
45527
+ };
45528
+ }
45529
+ function mapInboxMarkReadResponse(response) {
45530
+ return { readCount: response.data.readCount };
45531
+ }
45509
45532
  function validateEmailChannelConfig(config2) {
45510
45533
  const issues = [];
45511
45534
  if (!config2.recipients?.length) {
@@ -45668,6 +45691,7 @@ function createClientDomains(params) {
45668
45691
  const { client } = params;
45669
45692
  const assistantService = new AssistantService(client.apis.agent);
45670
45693
  const changesService = new ChangesService(client);
45694
+ const inboxService = new InboxService(client.apis.inbox);
45671
45695
  const userService = new UserService(client);
45672
45696
  const dataFetcherService = new DataFetcherService(client.apis.workflows);
45673
45697
  const channelsService = new NotificationChannelsService(client.apis.notifications, userService);
@@ -45675,7 +45699,7 @@ function createClientDomains(params) {
45675
45699
  const schemasService = new SchemasService(client);
45676
45700
  const scrapeService = new ScrapeService(client);
45677
45701
  const templatesService = new TemplatesService(client);
45678
- const workflowsCoreService = new WorkflowsCoreService(client.apis.workflows, templatesService);
45702
+ const workflowsCoreService = new WorkflowsCoreService(client.apis.workflows);
45679
45703
  const variablesService = new VariablesService(client);
45680
45704
  const channelSetupService = new NotificationSetupService(channelsService, settingsService);
45681
45705
  const coreService = new ValidationCoreService(client);
@@ -45697,6 +45721,7 @@ function createClientDomains(params) {
45697
45721
  extraction: extractionService,
45698
45722
  workflow: workflowsCoreService,
45699
45723
  notification,
45724
+ inbox: inboxService,
45700
45725
  schema: schemasService,
45701
45726
  scrape: scrapeService,
45702
45727
  user: userService,
@@ -45885,8 +45910,8 @@ var import_debug, __require2, FREEFORM_ASSISTANT_ANSWER_KEY = "_freeform", Kadoa
45885
45910
  return needsSerialization ? JSON.stringify(value !== undefined ? value : {}, replaceWithSerializableTypeIfNeeded) : value || "";
45886
45911
  }, toPathString = function(url3) {
45887
45912
  return url3.pathname + url3.search + url3.hash;
45888
- }, createRequestFunction = function(axiosArgs, globalAxios12, BASE_PATH2, configuration) {
45889
- return (axios2 = globalAxios12, basePath = BASE_PATH2) => {
45913
+ }, createRequestFunction = function(axiosArgs, globalAxios13, BASE_PATH2, configuration) {
45914
+ return (axios2 = globalAxios13, basePath = BASE_PATH2) => {
45890
45915
  const axiosRequestArgs = { ...axiosArgs.options, url: (axios2.defaults.baseURL ? "" : configuration?.basePath ?? basePath) + axiosArgs.url };
45891
45916
  return axios2.request(axiosRequestArgs);
45892
45917
  };
@@ -47156,7 +47181,67 @@ var import_debug, __require2, FREEFORM_ASSISTANT_ANSWER_KEY = "_freeform", Kadoa
47156
47181
  return (axios2, basePath) => createRequestFunction(localVarAxiosArgs, axios_default, BASE_PATH, configuration)(axios2, localVarOperationServerBasePath || basePath);
47157
47182
  }
47158
47183
  };
47159
- }, DataValidationApi, MeApiAxiosParamCreator = function(configuration) {
47184
+ }, DataValidationApi, InboxApiAxiosParamCreator = function(configuration) {
47185
+ return {
47186
+ v5InboxList: async (options = {}) => {
47187
+ const localVarPath = `/v5/inbox`;
47188
+ const localVarUrlObj = new URL$1(localVarPath, DUMMY_BASE_URL);
47189
+ let baseOptions;
47190
+ if (configuration) {
47191
+ baseOptions = configuration.baseOptions;
47192
+ }
47193
+ const localVarRequestOptions = { method: "GET", ...baseOptions, ...options };
47194
+ const localVarHeaderParameter = {};
47195
+ const localVarQueryParameter = {};
47196
+ await setApiKeyToObject(localVarHeaderParameter, "x-api-key", configuration);
47197
+ localVarHeaderParameter["Accept"] = "application/json";
47198
+ setSearchParams(localVarUrlObj, localVarQueryParameter);
47199
+ let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
47200
+ localVarRequestOptions.headers = { ...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers };
47201
+ return {
47202
+ url: toPathString(localVarUrlObj),
47203
+ options: localVarRequestOptions
47204
+ };
47205
+ },
47206
+ v5InboxMarkRead: async (itemId, options = {}) => {
47207
+ assertParamExists("v5InboxMarkRead", "itemId", itemId);
47208
+ const localVarPath = `/v5/inbox/{itemId}/mark-read`.replace(`{${"itemId"}}`, encodeURIComponent(String(itemId)));
47209
+ const localVarUrlObj = new URL$1(localVarPath, DUMMY_BASE_URL);
47210
+ let baseOptions;
47211
+ if (configuration) {
47212
+ baseOptions = configuration.baseOptions;
47213
+ }
47214
+ const localVarRequestOptions = { method: "POST", ...baseOptions, ...options };
47215
+ const localVarHeaderParameter = {};
47216
+ const localVarQueryParameter = {};
47217
+ await setApiKeyToObject(localVarHeaderParameter, "x-api-key", configuration);
47218
+ localVarHeaderParameter["Accept"] = "application/json";
47219
+ setSearchParams(localVarUrlObj, localVarQueryParameter);
47220
+ let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
47221
+ localVarRequestOptions.headers = { ...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers };
47222
+ return {
47223
+ url: toPathString(localVarUrlObj),
47224
+ options: localVarRequestOptions
47225
+ };
47226
+ }
47227
+ };
47228
+ }, InboxApiFp = function(configuration) {
47229
+ const localVarAxiosParamCreator = InboxApiAxiosParamCreator(configuration);
47230
+ return {
47231
+ async v5InboxList(options) {
47232
+ const localVarAxiosArgs = await localVarAxiosParamCreator.v5InboxList(options);
47233
+ const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
47234
+ const localVarOperationServerBasePath = operationServerMap["InboxApi.v5InboxList"]?.[localVarOperationServerIndex]?.url;
47235
+ return (axios2, basePath) => createRequestFunction(localVarAxiosArgs, axios_default, BASE_PATH, configuration)(axios2, localVarOperationServerBasePath || basePath);
47236
+ },
47237
+ async v5InboxMarkRead(itemId, options) {
47238
+ const localVarAxiosArgs = await localVarAxiosParamCreator.v5InboxMarkRead(itemId, options);
47239
+ const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
47240
+ const localVarOperationServerBasePath = operationServerMap["InboxApi.v5InboxMarkRead"]?.[localVarOperationServerIndex]?.url;
47241
+ return (axios2, basePath) => createRequestFunction(localVarAxiosArgs, axios_default, BASE_PATH, configuration)(axios2, localVarOperationServerBasePath || basePath);
47242
+ }
47243
+ };
47244
+ }, InboxApi, MeApiAxiosParamCreator = function(configuration) {
47160
47245
  return {
47161
47246
  v4MeFeaturesGet: async (options = {}) => {
47162
47247
  const localVarPath = `/v4/me/features`;
@@ -47971,6 +48056,29 @@ var import_debug, __require2, FREEFORM_ASSISTANT_ANSWER_KEY = "_freeform", Kadoa
47971
48056
  options: localVarRequestOptions
47972
48057
  };
47973
48058
  },
48059
+ v4TemplatesTemplateIdPreviewSchemaChangePost: async (templateId, schemaChangePreviewBody, options = {}) => {
48060
+ assertParamExists("v4TemplatesTemplateIdPreviewSchemaChangePost", "templateId", templateId);
48061
+ const localVarPath = `/v4/templates/{templateId}/preview-schema-change`.replace(`{${"templateId"}}`, encodeURIComponent(String(templateId)));
48062
+ const localVarUrlObj = new URL$1(localVarPath, DUMMY_BASE_URL);
48063
+ let baseOptions;
48064
+ if (configuration) {
48065
+ baseOptions = configuration.baseOptions;
48066
+ }
48067
+ const localVarRequestOptions = { method: "POST", ...baseOptions, ...options };
48068
+ const localVarHeaderParameter = {};
48069
+ const localVarQueryParameter = {};
48070
+ await setApiKeyToObject(localVarHeaderParameter, "x-api-key", configuration);
48071
+ localVarHeaderParameter["Content-Type"] = "application/json";
48072
+ localVarHeaderParameter["Accept"] = "application/json";
48073
+ setSearchParams(localVarUrlObj, localVarQueryParameter);
48074
+ let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
48075
+ localVarRequestOptions.headers = { ...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers };
48076
+ localVarRequestOptions.data = serializeDataIfNeeded(schemaChangePreviewBody, localVarRequestOptions, configuration);
48077
+ return {
48078
+ url: toPathString(localVarUrlObj),
48079
+ options: localVarRequestOptions
48080
+ };
48081
+ },
47974
48082
  v4TemplatesTemplateIdPut: async (templateId, updateTemplateBody, options = {}) => {
47975
48083
  assertParamExists("v4TemplatesTemplateIdPut", "templateId", templateId);
47976
48084
  const localVarPath = `/v4/templates/{templateId}`.replace(`{${"templateId"}}`, encodeURIComponent(String(templateId)));
@@ -48158,6 +48266,12 @@ var import_debug, __require2, FREEFORM_ASSISTANT_ANSWER_KEY = "_freeform", Kadoa
48158
48266
  const localVarOperationServerBasePath = operationServerMap["TemplatesApi.v4TemplatesTemplateIdLinkPost"]?.[localVarOperationServerIndex]?.url;
48159
48267
  return (axios2, basePath) => createRequestFunction(localVarAxiosArgs, axios_default, BASE_PATH, configuration)(axios2, localVarOperationServerBasePath || basePath);
48160
48268
  },
48269
+ async v4TemplatesTemplateIdPreviewSchemaChangePost(templateId, schemaChangePreviewBody, options) {
48270
+ const localVarAxiosArgs = await localVarAxiosParamCreator.v4TemplatesTemplateIdPreviewSchemaChangePost(templateId, schemaChangePreviewBody, options);
48271
+ const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
48272
+ const localVarOperationServerBasePath = operationServerMap["TemplatesApi.v4TemplatesTemplateIdPreviewSchemaChangePost"]?.[localVarOperationServerIndex]?.url;
48273
+ return (axios2, basePath) => createRequestFunction(localVarAxiosArgs, axios_default, BASE_PATH, configuration)(axios2, localVarOperationServerBasePath || basePath);
48274
+ },
48161
48275
  async v4TemplatesTemplateIdPut(templateId, updateTemplateBody, options) {
48162
48276
  const localVarAxiosArgs = await localVarAxiosParamCreator.v4TemplatesTemplateIdPut(templateId, updateTemplateBody, options);
48163
48277
  const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
@@ -48673,7 +48787,7 @@ var import_debug, __require2, FREEFORM_ASSISTANT_ANSWER_KEY = "_freeform", Kadoa
48673
48787
  options: localVarRequestOptions
48674
48788
  };
48675
48789
  },
48676
- v4WorkflowsPost: async (publicWorkflowCreateRequest, options = {}) => {
48790
+ v4WorkflowsPost: async (createWorkflowBody, options = {}) => {
48677
48791
  const localVarPath = `/v4/workflows`;
48678
48792
  const localVarUrlObj = new URL$1(localVarPath, DUMMY_BASE_URL);
48679
48793
  let baseOptions;
@@ -48689,7 +48803,7 @@ var import_debug, __require2, FREEFORM_ASSISTANT_ANSWER_KEY = "_freeform", Kadoa
48689
48803
  setSearchParams(localVarUrlObj, localVarQueryParameter);
48690
48804
  let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
48691
48805
  localVarRequestOptions.headers = { ...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers };
48692
- localVarRequestOptions.data = serializeDataIfNeeded(publicWorkflowCreateRequest, localVarRequestOptions, configuration);
48806
+ localVarRequestOptions.data = serializeDataIfNeeded(createWorkflowBody, localVarRequestOptions, configuration);
48693
48807
  return {
48694
48808
  url: toPathString(localVarUrlObj),
48695
48809
  options: localVarRequestOptions
@@ -49350,8 +49464,8 @@ var import_debug, __require2, FREEFORM_ASSISTANT_ANSWER_KEY = "_freeform", Kadoa
49350
49464
  const localVarOperationServerBasePath = operationServerMap["WorkflowsApi.v4WorkflowsGet"]?.[localVarOperationServerIndex]?.url;
49351
49465
  return (axios2, basePath) => createRequestFunction(localVarAxiosArgs, axios_default, BASE_PATH, configuration)(axios2, localVarOperationServerBasePath || basePath);
49352
49466
  },
49353
- async v4WorkflowsPost(publicWorkflowCreateRequest, options) {
49354
- const localVarAxiosArgs = await localVarAxiosParamCreator.v4WorkflowsPost(publicWorkflowCreateRequest, options);
49467
+ async v4WorkflowsPost(createWorkflowBody, options) {
49468
+ const localVarAxiosArgs = await localVarAxiosParamCreator.v4WorkflowsPost(createWorkflowBody, options);
49355
49469
  const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
49356
49470
  const localVarOperationServerBasePath = operationServerMap["WorkflowsApi.v4WorkflowsPost"]?.[localVarOperationServerIndex]?.url;
49357
49471
  return (axios2, basePath) => createRequestFunction(localVarAxiosArgs, axios_default, BASE_PATH, configuration)(axios2, localVarOperationServerBasePath || basePath);
@@ -49510,7 +49624,7 @@ var import_debug, __require2, FREEFORM_ASSISTANT_ANSWER_KEY = "_freeform", Kadoa
49510
49624
  const jsonMime = new RegExp("^(application/json|[^;/ \t]+/[^;/ \t]+[+]json)[ \t]*(;.*)?$", "i");
49511
49625
  return mime !== null && (jsonMime.test(mime) || mime.toLowerCase() === "application/json-patch+json");
49512
49626
  }
49513
- }, DataFieldDataTypeEnum, CrawlerConfigService = class {
49627
+ }, DataFieldDataTypeEnum, InboxItemTypeEnum, CrawlerConfigService = class {
49514
49628
  constructor(client) {
49515
49629
  this.client = client;
49516
49630
  }
@@ -50273,6 +50387,18 @@ var import_debug, __require2, FREEFORM_ASSISTANT_ANSWER_KEY = "_freeform", Kadoa
50273
50387
  }
50274
50388
  return typeof error48.message === "string" ? error48.message.includes(BUILD_NOT_READY_ERROR) : false;
50275
50389
  }
50390
+ }, InboxItemType, knownInboxItemTypes, InboxService = class {
50391
+ constructor(inboxApi) {
50392
+ this.inboxApi = inboxApi;
50393
+ }
50394
+ async list() {
50395
+ const response = await this.inboxApi.v5InboxList();
50396
+ return mapInboxListResponse(response.data);
50397
+ }
50398
+ async markRead(itemId) {
50399
+ const response = await this.inboxApi.v5InboxMarkRead({ itemId });
50400
+ return mapInboxMarkReadResponse(response.data);
50401
+ }
50276
50402
  }, NotificationChannelType, EMAIL_REGEX, _NotificationChannelsService = class _NotificationChannelsService2 {
50277
50403
  constructor(notificationsApi, userService) {
50278
50404
  this.api = notificationsApi;
@@ -50599,7 +50725,7 @@ var import_debug, __require2, FREEFORM_ASSISTANT_ANSWER_KEY = "_freeform", Kadoa
50599
50725
  }));
50600
50726
  return channels;
50601
50727
  }
50602
- }, PUBLIC_API_URI, WSS_API_URI, REALTIME_API_URI, SDK_VERSION = "0.39.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 {
50728
+ }, PUBLIC_API_URI, WSS_API_URI, REALTIME_API_URI, SDK_VERSION = "0.40.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 {
50603
50729
  constructor(config2) {
50604
50730
  this.drainingSockets = /* @__PURE__ */ new Set;
50605
50731
  this.lastHeartbeat = Date.now();
@@ -51393,17 +51519,14 @@ var import_debug, __require2, FREEFORM_ASSISTANT_ANSWER_KEY = "_freeform", Kadoa
51393
51519
  });
51394
51520
  }
51395
51521
  }, JobStateEnum, TERMINAL_JOB_STATES, TERMINAL_RUN_STATES2, debug9, WorkflowsCoreService = class {
51396
- constructor(workflowsApi, templatesService) {
51522
+ constructor(workflowsApi) {
51397
51523
  this.workflowsApi = workflowsApi;
51398
- this.templatesService = templatesService;
51399
51524
  }
51400
51525
  async create(input) {
51401
51526
  validateAdditionalData(input.additionalData);
51402
51527
  const isFromTemplate = input.templateId != null;
51403
51528
  if (isFromTemplate) {
51404
51529
  const conflicting = [];
51405
- if (input.userPrompt != null)
51406
- conflicting.push("userPrompt");
51407
51530
  if (input.entity != null)
51408
51531
  conflicting.push("entity");
51409
51532
  if (input.fields != null)
@@ -51427,12 +51550,13 @@ var import_debug, __require2, FREEFORM_ASSISTANT_ANSWER_KEY = "_freeform", Kadoa
51427
51550
  const domainName = new URL(input.urls[0]).hostname;
51428
51551
  let request;
51429
51552
  if (isFromTemplate) {
51430
- const templateId = input.templateId;
51431
- const templateVersion = input.templateVersion ?? await this.resolveLatestVersion(templateId);
51432
51553
  request = {
51433
51554
  urls: input.urls,
51434
- templateId,
51435
- templateVersion,
51555
+ templateId: input.templateId,
51556
+ ...input.templateVersion != null && {
51557
+ templateVersion: input.templateVersion
51558
+ },
51559
+ ...input.userPrompt != null && { userPrompt: input.userPrompt },
51436
51560
  ...input.name != null && { name: input.name },
51437
51561
  ...input.description != null && { description: input.description },
51438
51562
  ...input.tags != null && { tags: input.tags },
@@ -51467,7 +51591,7 @@ var import_debug, __require2, FREEFORM_ASSISTANT_ANSWER_KEY = "_freeform", Kadoa
51467
51591
  };
51468
51592
  }
51469
51593
  const response = await this.workflowsApi.v4WorkflowsPost({
51470
- publicWorkflowCreateRequest: request
51594
+ createWorkflowBody: request
51471
51595
  });
51472
51596
  const workflowId = response.data?.workflowId;
51473
51597
  if (!workflowId) {
@@ -51480,23 +51604,6 @@ var import_debug, __require2, FREEFORM_ASSISTANT_ANSWER_KEY = "_freeform", Kadoa
51480
51604
  }
51481
51605
  return { id: workflowId };
51482
51606
  }
51483
- async resolveLatestVersion(templateId) {
51484
- if (!this.templatesService) {
51485
- throw new KadoaSdkException("TemplatesService is required to resolve a template's latest version. Pass `templateVersion` explicitly or construct WorkflowsCoreService with a TemplatesService.", {
51486
- code: "INTERNAL_ERROR",
51487
- details: { templateId }
51488
- });
51489
- }
51490
- const template = await this.templatesService.get(templateId);
51491
- const latest = template.latestVersion;
51492
- if (latest == null) {
51493
- throw new KadoaSdkException(`Template ${templateId} has no published versions; supply templateVersion explicitly or publish a version first.`, {
51494
- code: "VALIDATION_ERROR",
51495
- details: { templateId }
51496
- });
51497
- }
51498
- return latest;
51499
- }
51500
51607
  async get(id) {
51501
51608
  const response = await this.workflowsApi.v4WorkflowsWorkflowIdGet({
51502
51609
  workflowId: id
@@ -51666,6 +51773,9 @@ var import_debug, __require2, FREEFORM_ASSISTANT_ANSWER_KEY = "_freeform", Kadoa
51666
51773
  get notifications() {
51667
51774
  return this.get(NotificationsApi);
51668
51775
  }
51776
+ get inbox() {
51777
+ return this.get(InboxApi);
51778
+ }
51669
51779
  get templates() {
51670
51780
  return this.get(TemplatesApi);
51671
51781
  }
@@ -51705,6 +51815,7 @@ var import_debug, __require2, FREEFORM_ASSISTANT_ANSWER_KEY = "_freeform", Kadoa
51705
51815
  this.schema = domains.schema;
51706
51816
  this.scrape = domains.scrape;
51707
51817
  this.notification = domains.notification;
51818
+ this.inbox = domains.inbox;
51708
51819
  this.template = domains.template;
51709
51820
  this.validation = domains.validation;
51710
51821
  this.variable = domains.variable;
@@ -52148,6 +52259,14 @@ var init_dist2 = __esm(() => {
52148
52259
  return DataValidationApiFp(this.configuration).v4DataValidationWorkflowsWorkflowIdValidationsLatestGet(requestParameters.workflowId, requestParameters.includeDryRun, options).then((request) => request(this.axios, this.basePath));
52149
52260
  }
52150
52261
  };
52262
+ InboxApi = class extends BaseAPI {
52263
+ v5InboxList(options) {
52264
+ return InboxApiFp(this.configuration).v5InboxList(options).then((request) => request(this.axios, this.basePath));
52265
+ }
52266
+ v5InboxMarkRead(requestParameters, options) {
52267
+ return InboxApiFp(this.configuration).v5InboxMarkRead(requestParameters.itemId, options).then((request) => request(this.axios, this.basePath));
52268
+ }
52269
+ };
52151
52270
  MeApi = class extends BaseAPI {
52152
52271
  v4MeFeaturesGet(options) {
52153
52272
  return MeApiFp(this.configuration).v4MeFeaturesGet(options).then((request) => request(this.axios, this.basePath));
@@ -52255,6 +52374,9 @@ var init_dist2 = __esm(() => {
52255
52374
  v4TemplatesTemplateIdLinkPost(requestParameters, options) {
52256
52375
  return TemplatesApiFp(this.configuration).v4TemplatesTemplateIdLinkPost(requestParameters.templateId, requestParameters.linkWorkflowsBody, options).then((request) => request(this.axios, this.basePath));
52257
52376
  }
52377
+ v4TemplatesTemplateIdPreviewSchemaChangePost(requestParameters, options) {
52378
+ return TemplatesApiFp(this.configuration).v4TemplatesTemplateIdPreviewSchemaChangePost(requestParameters.templateId, requestParameters.schemaChangePreviewBody, options).then((request) => request(this.axios, this.basePath));
52379
+ }
52258
52380
  v4TemplatesTemplateIdPut(requestParameters, options) {
52259
52381
  return TemplatesApiFp(this.configuration).v4TemplatesTemplateIdPut(requestParameters.templateId, requestParameters.updateTemplateBody, options).then((request) => request(this.axios, this.basePath));
52260
52382
  }
@@ -52323,7 +52445,7 @@ var init_dist2 = __esm(() => {
52323
52445
  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));
52324
52446
  }
52325
52447
  v4WorkflowsPost(requestParameters = {}, options) {
52326
- return WorkflowsApiFp(this.configuration).v4WorkflowsPost(requestParameters.publicWorkflowCreateRequest, options).then((request) => request(this.axios, this.basePath));
52448
+ return WorkflowsApiFp(this.configuration).v4WorkflowsPost(requestParameters.createWorkflowBody, options).then((request) => request(this.axios, this.basePath));
52327
52449
  }
52328
52450
  v4WorkflowsWorkflowIdAuditlogGet(requestParameters, options) {
52329
52451
  return WorkflowsApiFp(this.configuration).v4WorkflowsWorkflowIdAuditlogGet(requestParameters.workflowId, requestParameters.xApiKey, requestParameters.authorization, requestParameters.page, requestParameters.limit, options).then((request) => request(this.axios, this.basePath));
@@ -52404,6 +52526,11 @@ var init_dist2 = __esm(() => {
52404
52526
  Object: "OBJECT",
52405
52527
  Array: "ARRAY"
52406
52528
  };
52529
+ InboxItemTypeEnum = {
52530
+ ShellyQuestion: "shelly_question",
52531
+ DataQualityIssues: "data_quality_issues",
52532
+ SampleDataReady: "sample_data_ready"
52533
+ };
52407
52534
  CanonicalSchemaFieldDataType = {
52408
52535
  String: DataFieldDataTypeEnum.String,
52409
52536
  Number: DataFieldDataTypeEnum.Number,
@@ -52462,6 +52589,16 @@ This is the main page content.`
52462
52589
  };
52463
52590
  debug4 = logger.extraction;
52464
52591
  TERMINAL_RUN_STATES = /* @__PURE__ */ new Set(["FINISHED", "SUCCESS", "FAILED", "ERROR", "STOPPED", "CANCELLED"]);
52592
+ InboxItemType = {
52593
+ AssistantQuestion: InboxItemTypeEnum.ShellyQuestion,
52594
+ DataQualityIssues: InboxItemTypeEnum.DataQualityIssues,
52595
+ PreviewDataReady: InboxItemTypeEnum.SampleDataReady
52596
+ };
52597
+ knownInboxItemTypes = {
52598
+ [InboxItemTypeEnum.ShellyQuestion]: InboxItemType.AssistantQuestion,
52599
+ [InboxItemTypeEnum.DataQualityIssues]: InboxItemType.DataQualityIssues,
52600
+ [InboxItemTypeEnum.SampleDataReady]: InboxItemType.PreviewDataReady
52601
+ };
52465
52602
  NotificationChannelType = {
52466
52603
  EMAIL: "EMAIL",
52467
52604
  SLACK: "SLACK",
@@ -53089,12 +53226,53 @@ function registerTools(server, ctx, capabilities) {
53089
53226
  }))
53090
53227
  });
53091
53228
  }));
53229
+ server.registerTool("list_inbox", {
53230
+ description: "List personal Kadoa Inbox items that need attention across workflows. " + "Returns unread items by default; set includeRead to true to include acknowledged history. " + "For an Assistant question, use get_workflow_assistant and answer_workflow_assistant_question. " + "For preview data, use workflow detail and data tools to inspect it. " + "This Inbox is separate from notification channel and notification setting tools.",
53231
+ inputSchema: strictSchema({
53232
+ includeRead: exports_external.preprocess(coerceBoolean(), exports_external.boolean()).optional().describe("Include read Inbox history; defaults to false")
53233
+ }),
53234
+ annotations: {
53235
+ readOnlyHint: true,
53236
+ destructiveHint: false,
53237
+ idempotentHint: true
53238
+ }
53239
+ }, withErrorHandling("list_inbox", async (args) => {
53240
+ const inbox = await ctx.client.inbox.list();
53241
+ const includeRead = args.includeRead ?? false;
53242
+ const items = (includeRead ? inbox.items : inbox.items.filter((item) => !item.isRead)).map((item) => ({
53243
+ ...item,
53244
+ dashboardUrl: item.workflowId ? workflowDashboardUrl(item.workflowId) : null
53245
+ }));
53246
+ return jsonResult({
53247
+ unreadCount: inbox.unreadCount,
53248
+ includeRead,
53249
+ returnedCount: items.length,
53250
+ items
53251
+ });
53252
+ }));
53253
+ server.registerTool("mark_inbox_item_read", {
53254
+ description: "Acknowledge one personal Kadoa Inbox item as read. " + "This does not answer an Assistant question, resume the Assistant, approve preview data, or change workflow state.",
53255
+ inputSchema: strictSchema({
53256
+ itemId: exports_external.string().uuid().describe("Inbox item UUID returned by list_inbox")
53257
+ }),
53258
+ annotations: {
53259
+ readOnlyHint: false,
53260
+ destructiveHint: false,
53261
+ idempotentHint: true
53262
+ }
53263
+ }, withErrorHandling("mark_inbox_item_read", async (args) => {
53264
+ const result = await ctx.client.inbox.markRead(args.itemId);
53265
+ return jsonResult({
53266
+ itemId: args.itemId,
53267
+ changed: result.readCount === 1
53268
+ });
53269
+ }));
53092
53270
  const urlInputShape = {
53093
53271
  url: exports_external.string().optional().describe("Single URL - prefer using 'urls' instead. If both are provided, 'urls' takes precedence."),
53094
53272
  urls: exports_external.preprocess(coerceArray(true), exports_external.array(exports_external.string()).min(1)).optional().describe("Starting URLs for the workflow (array of strings). Also accepts a single URL string.")
53095
53273
  };
53274
+ const extractionPromptInput = exports_external.string().optional();
53096
53275
  const extractionInputShape = {
53097
- 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.'),
53098
53276
  name: exports_external.string().optional().describe("Optional name for the workflow"),
53099
53277
  entity: exports_external.string().optional().describe("Entity name for extraction (e.g., 'Product', 'Job Posting')"),
53100
53278
  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.")
@@ -53129,7 +53307,7 @@ function registerTools(server, ctx, capabilities) {
53129
53307
  return urls.length > 0 ? urls : null;
53130
53308
  }
53131
53309
  function buildRealtimeAssistantInstructions(args, urls) {
53132
- const lines = ["Create a realtime monitoring workflow with Julie.", "", "Source URLs:"];
53310
+ const lines = ["Create a realtime monitoring workflow.", "", "Source URLs:"];
53133
53311
  for (const url3 of urls)
53134
53312
  lines.push(`- ${url3}`);
53135
53313
  if (args.prompt)
@@ -53229,11 +53407,12 @@ function registerTools(server, ctx, capabilities) {
53229
53407
 
53230
53408
  ` + "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.
53231
53409
 
53232
- ` + "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 creating from a template, call this tool with the template's `templateId`, the source `urls`, and optional `templateVersion` only. Never copy the template prompt, entity, or schema into standalone creation, and never silently match or rewrite inline configuration.\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.",
53410
+ ` + "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 creating from a template, call this tool with the template's `templateId`, the source `urls`, optional `templateVersion`, and optional `prompt` containing only workflow-specific additional instructions. Never copy the template prompt, entity, or schema into the call, and never silently match or rewrite inline configuration.\n\n" + "NOTE: This tool is for one-time or scheduled extraction ONLY. " + "For continuous realtime monitoring that watches a page for data changes and sends alerts, use the create_realtime_monitor tool instead.",
53233
53411
  inputSchema: strictSchema({
53412
+ prompt: extractionPromptInput.describe('Natural language description of what to extract (e.g., "Extract product prices and names"). Required unless templateId is provided. With templateId, use it only for workflow-specific instructions to add to the template prompt.'),
53234
53413
  ...extractionInputShape,
53235
53414
  ...urlInputShape,
53236
- templateId: exports_external.string().optional().describe("Instantiate this workflow from a published template. Pass the templateId, source urls, and optional templateVersion. Do not copy prompt/entity/schema from the template into this call - they are inherited from the published template version, and the workflow's output conforms to its declared schema. Discover templates via list_templates and get_template."),
53415
+ templateId: exports_external.string().optional().describe("Instantiate this workflow from a published template. Pass the templateId, source urls, optional templateVersion, and optional prompt with workflow-specific additional instructions. Do not copy the template's shared prompt, entity, or schema into this call - they are inherited from the published template version, and the workflow's output conforms to its declared schema. Discover templates via list_templates and get_template."),
53237
53416
  templateVersion: exports_external.preprocess(coerceNumber(), exports_external.number()).optional().describe("Specific published template version (integer) to instantiate. Defaults to the latest published version when templateId is set."),
53238
53417
  description: exports_external.string().max(500).optional().describe("Description of what this workflow does (max 500 characters)"),
53239
53418
  tags: exports_external.preprocess(coerceArray(true), exports_external.array(exports_external.string())).optional().describe("Tags for organizing workflows"),
@@ -53273,8 +53452,8 @@ function registerTools(server, ctx, capabilities) {
53273
53452
  const hasNotifications = !!(n && (n.email || n.webhook || n.slack || n.websocket));
53274
53453
  let workflowId;
53275
53454
  if (args.templateId) {
53276
- if (args.prompt || args.entity || args.schema) {
53277
- return errorResult("When 'templateId' is set, 'prompt', 'entity', and 'schema' must NOT be supplied - they are inherited from the template version.");
53455
+ if (args.entity || args.schema) {
53456
+ return errorResult("When 'templateId' is set, 'entity' and 'schema' must NOT be supplied - they are inherited from the template version. Use 'prompt' only for workflow-specific additional instructions.");
53278
53457
  }
53279
53458
  const { id } = await ctx.client.workflow.create({
53280
53459
  urls,
@@ -53285,7 +53464,8 @@ function registerTools(server, ctx, capabilities) {
53285
53464
  tags: args.tags && args.tags.length > 0 ? args.tags : undefined,
53286
53465
  limit: args.limit,
53287
53466
  templateId: args.templateId,
53288
- templateVersion: args.templateVersion
53467
+ templateVersion: args.templateVersion,
53468
+ userPrompt: args.prompt
53289
53469
  });
53290
53470
  workflowId = id;
53291
53471
  if (hasNotifications) {
@@ -53340,10 +53520,11 @@ function registerTools(server, ctx, capabilities) {
53340
53520
  });
53341
53521
  }));
53342
53522
  server.registerTool("create_realtime_monitor", {
53343
- 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.
53523
+ description: "Create a 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 Assistant creation is dispatched. " + `Realtime monitors CANNOT be converted to/from one-time or scheduled extraction workflows after creation.
53344
53524
 
53345
- ` + "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.",
53525
+ ` + "If entity and schema are provided, they guide what the Assistant should monitor; otherwise the Assistant determines 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.",
53346
53526
  inputSchema: strictSchema({
53527
+ prompt: extractionPromptInput.describe("Optional natural language instructions describing what to monitor and which changes matter. If omitted, the Assistant determines what to watch."),
53347
53528
  ...extractionInputShape,
53348
53529
  ...urlInputShape,
53349
53530
  description: exports_external.string().max(500).optional().describe("Description of what this monitor watches (max 500 characters)"),
@@ -53387,7 +53568,7 @@ function registerTools(server, ctx, capabilities) {
53387
53568
  threadId: result.threadId,
53388
53569
  jobId: result.jobId,
53389
53570
  dashboardUrl: workflowDashboardUrl(result.workflowId),
53390
- 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."
53571
+ message: "Realtime monitoring workflow creation accepted. Notification settings were persisted before Assistant dispatch. Creation is asynchronous; use get_workflow_assistant for status, questions, or controls, and do not poll or sleep-wait."
53391
53572
  });
53392
53573
  }));
53393
53574
  server.registerTool("list_workflows", {
@@ -53545,7 +53726,7 @@ function registerTools(server, ctx, capabilities) {
53545
53726
  });
53546
53727
  }));
53547
53728
  server.registerTool("get_workflow_assistant", {
53548
- description: "Get the current Assistant lifecycle for a workflow, including whether it is working, waiting for input, idle, interrupted, or closed and any pending customer question. Works for both Shelly/Lighthouse and Julie workflows.",
53729
+ description: "Get the current Assistant lifecycle for a workflow, including whether it is working, waiting for input, idle, interrupted, or closed and any pending customer question. Works for one-time or scheduled extraction workflows and realtime monitoring workflows.",
53549
53730
  inputSchema: strictSchema({
53550
53731
  workflowId: exports_external.string().min(1).describe("The workflow ID")
53551
53732
  }),
@@ -53583,7 +53764,7 @@ function registerTools(server, ctx, capabilities) {
53583
53764
  });
53584
53765
  }));
53585
53766
  server.registerTool("get_workflow_assistant_timeline", {
53586
- description: "Read the customer-visible conversation history for a workflow Assistant, including user messages, Assistant messages, and clarification questions with answers. " + "Works for both Shelly/Lighthouse and Julie workflows. Use get_workflow_history instead for configuration revisions. Results are chronological within each page; use nextCursor to request older items when hasMore is true.",
53767
+ description: "Read the customer-visible conversation history for a workflow Assistant, including user messages, Assistant messages, and clarification questions with answers. " + "Use this when the user asks what the Assistant said or asked, how a clarification was answered, or to show the latest conversation for a workflow. " + "Supports one-time or scheduled extraction workflows and realtime monitoring workflows. Use get_workflow_history instead for configuration revisions. " + "Results are chronological within each page; use nextCursor to request older items when hasMore is true.",
53587
53768
  inputSchema: strictSchema({
53588
53769
  workflowId: exports_external.string().min(1).describe("The workflow ID"),
53589
53770
  cursor: exports_external.string().min(1).optional().describe("Opaque nextCursor from the previous page"),
@@ -53685,7 +53866,7 @@ function registerTools(server, ctx, capabilities) {
53685
53866
  });
53686
53867
  }));
53687
53868
  server.registerTool("resume_workflow_assistant", {
53688
- description: "Resume an idle or interrupted workflow Assistant using the persona and conversation persisted on its session. Works for both Lighthouse and Julie. This does not resume a paused workflow schedule; use approve_workflow for that.",
53869
+ description: "Resume an idle or interrupted workflow Assistant using the role and conversation persisted on its session. Works for one-time or scheduled extraction workflows and realtime monitoring workflows. This does not resume a paused workflow schedule; use approve_workflow for that.",
53689
53870
  inputSchema: strictSchema({
53690
53871
  workflowId: exports_external.string().min(1).describe("Workflow whose Assistant session should resume")
53691
53872
  }),
@@ -53937,7 +54118,7 @@ function registerTools(server, ctx, capabilities) {
53937
54118
  });
53938
54119
  }));
53939
54120
  server.registerTool("list_changes", {
53940
- 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.",
54121
+ description: "List detected data changes across one or more realtime monitoring workflows. " + "Returns structured diffs showing added, removed, and changed records. " + "Only works for workflows with realtime monitoring enabled.",
53941
54122
  inputSchema: {
53942
54123
  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."),
53943
54124
  startDate: exports_external.string().optional().describe("Start date filter (ISO format, e.g. 2025-01-01)"),
@@ -54047,9 +54228,9 @@ function registerTools(server, ctx, capabilities) {
54047
54228
  server.registerTool("update_workflow", {
54048
54229
  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.
54049
54230
 
54050
- ` + `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.
54231
+ ` + `IMPORTANT: You cannot change a workflow's interval to or from REAL_TIME. Realtime monitoring workflows are architecturally different from one-time or scheduled extraction 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.
54051
54232
 
54052
- ` + "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.",
54233
+ ` + "ASSISTANT-OWNED INTENT: Use request_workflow_update - not `userPrompt` - for Assistant-built workflow changes to extraction intent, navigation, pagination, data sourcing, repair, or generated scripts. The API may reject `userPrompt` because these 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.",
54053
54234
  inputSchema: strictSchema({
54054
54235
  workflowId: exports_external.string().describe("The workflow ID to update"),
54055
54236
  name: exports_external.string().optional().describe("New name for the workflow"),
@@ -54092,10 +54273,10 @@ function registerTools(server, ctx, capabilities) {
54092
54273
  const isCurrentlyRealTime = isRealTimeInterval(workflow.updateInterval);
54093
54274
  const isRequestingRealTime = isRealTimeInterval(updates.updateInterval);
54094
54275
  if (isRequestingRealTime && !isCurrentlyRealTime) {
54095
- 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.");
54276
+ return errorResult("Cannot change a regular workflow's interval to REAL_TIME. " + "Realtime monitoring workflows cannot replace this workflow in place. " + "The existing workflow was left unchanged.");
54096
54277
  }
54097
54278
  if (!isRequestingRealTime && isCurrentlyRealTime) {
54098
- 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.");
54279
+ return errorResult("Cannot change a realtime monitoring workflow's interval to a scheduled interval. " + "Realtime monitoring workflows are architecturally different and cannot be converted in place. " + "The existing workflow was left unchanged.");
54099
54280
  }
54100
54281
  }
54101
54282
  if (updates.updateInterval === "CUSTOM" && (!updates.schedules || updates.schedules.length === 0)) {
@@ -54496,7 +54677,7 @@ function registerTools(server, ctx, capabilities) {
54496
54677
  });
54497
54678
  }));
54498
54679
  server.registerTool("list_templates", {
54499
- description: "List all templates in the current team. Templates define reusable configurations (prompt, schema, validation rules, notifications, and frequency). Use this to find a matching template before creating a workflow. To instantiate a template, call create_workflow with its templateId, source URLs, and optional templateVersion - never copy the template prompt, entity, or schema into standalone creation.",
54680
+ description: "List all templates in the current team. Templates define reusable configurations (prompt, schema, validation rules, notifications, and frequency). Use this to find a matching template before creating a workflow. To instantiate a template, call create_workflow with its templateId, source URLs, optional templateVersion, and optional prompt containing only workflow-specific additional instructions - never copy the template prompt, entity, or schema into the call.",
54500
54681
  inputSchema: strictSchema({}),
54501
54682
  annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true }
54502
54683
  }, withErrorHandling("list_templates", async () => {
@@ -54504,11 +54685,11 @@ function registerTools(server, ctx, capabilities) {
54504
54685
  return jsonResult({
54505
54686
  templates,
54506
54687
  count: templates.length,
54507
- instructions: "To instantiate a listed template, call create_workflow with the matching templateId, source URLs, and optional templateVersion. Do not copy the template prompt, entity, or schema into standalone creation."
54688
+ instructions: "To instantiate a listed template, call create_workflow with the matching templateId, source URLs, optional templateVersion, and optional prompt containing only workflow-specific additional instructions. Do not copy the template prompt, entity, or schema into the call."
54508
54689
  });
54509
54690
  }));
54510
54691
  server.registerTool("get_template", {
54511
- description: "Get a template by ID, including all published versions and their schemas. After inspecting it, instantiate the template with create_workflow using templateId, source URLs, and optional templateVersion. Never copy the returned prompt, entity, or schema into standalone creation - those values are inherited when templateId is passed.",
54692
+ description: "Get a template by ID, including all published versions and their schemas. After inspecting it, instantiate the template with create_workflow using templateId, source URLs, optional templateVersion, and optional prompt containing only workflow-specific additional instructions. Never copy the returned prompt, entity, or schema into the call - those shared values are inherited when templateId is passed.",
54512
54693
  inputSchema: strictSchema({
54513
54694
  templateId: exports_external.string().describe("The template ID")
54514
54695
  }),
@@ -54517,7 +54698,7 @@ function registerTools(server, ctx, capabilities) {
54517
54698
  const template = await ctx.client.template.get(args.templateId);
54518
54699
  return jsonResult({
54519
54700
  template,
54520
- instructions: `To instantiate this template, call create_workflow with templateId "${args.templateId}", source URLs, and optional templateVersion. Do not copy this template's prompt, entity, or schema into standalone creation.`
54701
+ instructions: `To instantiate this template, call create_workflow with templateId "${args.templateId}", source URLs, optional templateVersion, and optional prompt containing only workflow-specific additional instructions. Do not copy this template's prompt, entity, or schema into the call.`
54521
54702
  });
54522
54703
  }));
54523
54704
  server.registerTool("create_template", {
@@ -54961,7 +55142,7 @@ var package_default;
54961
55142
  var init_package = __esm(() => {
54962
55143
  package_default = {
54963
55144
  name: "@kadoa/mcp",
54964
- version: "0.5.22",
55145
+ version: "0.5.24",
54965
55146
  description: "Kadoa MCP Server — manage workflows from Claude Desktop, Cursor, and other MCP clients",
54966
55147
  type: "module",
54967
55148
  main: "dist/index.js",
@@ -54985,7 +55166,7 @@ var init_package = __esm(() => {
54985
55166
  prepublishOnly: "bun run check-types && bun run test:unit && bun run build"
54986
55167
  },
54987
55168
  dependencies: {
54988
- "@kadoa/node-sdk": "^0.39.0",
55169
+ "@kadoa/node-sdk": "^0.40.0",
54989
55170
  "@modelcontextprotocol/sdk": "^1.26.0",
54990
55171
  express: "^5.2.1",
54991
55172
  "express-rate-limit": "^8.2.1",
@@ -60571,10 +60752,11 @@ async function createServer(auth, options) {
60571
60752
  "",
60572
60753
  "Workflow lifecycle: create_workflow \u2192 get_workflow (check status) \u2192 fetch_data (get results). Workflows run asynchronously - never poll or sleep-wait.",
60573
60754
  "",
60574
- "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.",
60755
+ "Use create_realtime_monitor only when the user wants continuous realtime 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.",
60575
60756
  "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.",
60576
60757
  "If a one-time or scheduled workflow fails, retry it with run_workflow using the existing workflow ID. Do NOT delete and recreate the workflow just to retry it - preserve its workflow ID and configuration. Realtime workflows cannot be manually run.",
60577
60758
  "Use list_changes and get_change to retrieve detected diffs from realtime monitoring workflows.",
60759
+ "Use list_inbox when the user asks what needs attention across workflows. Inbox questions are discovered there, then inspected and answered through the workflow Assistant tools; marking an Inbox item read only acknowledges it.",
60578
60760
  "",
60579
60761
  "Schema tips: Use descriptive field names and examples. Group related data under one entity.",
60580
60762
  "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.5.22",
3
+ "version": "0.5.24",
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.39.0",
27
+ "@kadoa/node-sdk": "^0.40.0",
28
28
  "@modelcontextprotocol/sdk": "^1.26.0",
29
29
  "express": "^5.2.1",
30
30
  "express-rate-limit": "^8.2.1",