@signaliz/sdk 1.0.3 → 1.0.5

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.
@@ -171,13 +171,14 @@ var HttpClient = class {
171
171
  details: { responseText: text.slice(0, 500) }
172
172
  });
173
173
  }
174
- if (data.error) {
174
+ const responseError = isRecord(data) && isRecord(data.error) ? data.error : null;
175
+ if (responseError) {
175
176
  const err = new SignalizError({
176
- code: data.error.code?.toString() || data.error.data?.error_code || "MCP_ERROR",
177
- message: data.error.message || "MCP request failed",
178
- errorType: mapMcpErrorType(data.error),
179
- retryAfter: data.error.data?.retry_after,
180
- details: data.error.data
177
+ code: firstString(responseError.code, isRecord(responseError.data) ? responseError.data.error_code : void 0) || "MCP_ERROR",
178
+ message: firstString(responseError.message) || "MCP request failed",
179
+ errorType: mapMcpErrorType(responseError),
180
+ retryAfter: isRecord(responseError.data) && typeof responseError.data.retry_after === "number" ? responseError.data.retry_after : void 0,
181
+ details: isRecord(responseError.data) ? responseError.data : void 0
181
182
  });
182
183
  if (err.isRetryable && attempt < this.maxRetries) {
183
184
  lastError = err;
@@ -254,35 +255,63 @@ function normalizeMcpParams(method, params) {
254
255
  }
255
256
  };
256
257
  }
258
+ function isRecord(value) {
259
+ return typeof value === "object" && value !== null;
260
+ }
261
+ function firstString(...values) {
262
+ const value = values.find((item) => typeof item === "string" && item.length > 0);
263
+ return typeof value === "string" ? value : void 0;
264
+ }
265
+ function firstPayloadError(payload) {
266
+ const errors = payload.errors;
267
+ const first = Array.isArray(errors) ? errors[0] : void 0;
268
+ return isRecord(first) ? first : {};
269
+ }
257
270
  function unwrapMcpResponse(data) {
258
- if (data?.result?.structuredContent !== void 0) {
259
- return unwrapMcpPayload(data.result.structuredContent);
271
+ const result = isRecord(data) ? data.result : void 0;
272
+ if (isRecord(result) && result.structuredContent !== void 0) {
273
+ return unwrapMcpPayload(result.structuredContent);
260
274
  }
261
- const text = data?.result?.content?.[0]?.text;
275
+ const content = isRecord(result) ? result.content : void 0;
276
+ const firstContent = Array.isArray(content) ? content[0] : void 0;
277
+ const text = isRecord(firstContent) ? firstContent.text : void 0;
262
278
  if (typeof text === "string") {
263
279
  const parsed = safeJson(text);
264
280
  return unwrapMcpPayload(parsed ?? text);
265
281
  }
266
- return unwrapMcpPayload(data?.result);
282
+ return unwrapMcpPayload(result);
267
283
  }
268
284
  function unwrapMcpPayload(payload) {
269
- if (payload && typeof payload === "object") {
285
+ if (isRecord(payload)) {
270
286
  if (payload.ok === true && Object.prototype.hasOwnProperty.call(payload, "result")) {
271
- return payload.result;
287
+ return unwrapMcpPayload(payload.result);
288
+ }
289
+ if (payload.ok === false) {
290
+ const first = firstPayloadError(payload);
291
+ const code = firstString(first.code, payload.error_code, payload.code) || (payload.approval_required ? "APPROVAL_REQUIRED" : "MCP_ERROR");
292
+ throw new SignalizError({
293
+ code,
294
+ message: firstString(first.message, payload.message, payload.summary, payload.error) || "MCP request failed",
295
+ errorType: mapErrorTypeFromCode(code),
296
+ details: {
297
+ ...payload,
298
+ ...isRecord(first.details) ? first.details : {}
299
+ }
300
+ });
272
301
  }
273
302
  if (payload.success === true && Object.prototype.hasOwnProperty.call(payload, "data")) {
274
303
  return payload.data;
275
304
  }
276
305
  if (payload.success === false) {
277
- const first = Array.isArray(payload.errors) ? payload.errors[0] ?? {} : {};
278
- const code = first.code || payload.error_code || (payload.approval_required ? "APPROVAL_REQUIRED" : "MCP_ERROR");
306
+ const first = firstPayloadError(payload);
307
+ const code = firstString(first.code, payload.error_code) || (payload.approval_required ? "APPROVAL_REQUIRED" : "MCP_ERROR");
279
308
  throw new SignalizError({
280
309
  code,
281
- message: first.message || payload.message || payload.summary || "MCP request failed",
310
+ message: firstString(first.message, payload.message, payload.summary) || "MCP request failed",
282
311
  errorType: mapErrorTypeFromCode(code),
283
312
  details: {
284
313
  ...payload,
285
- ...first.details && typeof first.details === "object" ? first.details : {}
314
+ ...isRecord(first.details) ? first.details : {}
286
315
  }
287
316
  });
288
317
  }
@@ -290,8 +319,10 @@ function unwrapMcpPayload(payload) {
290
319
  return payload;
291
320
  }
292
321
  function mapMcpErrorType(error) {
293
- const code = String(error?.data?.error_code || error?.code || "");
294
- const message = String(error?.message || "").toLowerCase();
322
+ const errorRecord = isRecord(error) ? error : {};
323
+ const data = isRecord(errorRecord.data) ? errorRecord.data : {};
324
+ const code = String(data.error_code || errorRecord.code || "");
325
+ const message = String(errorRecord.message || "").toLowerCase();
295
326
  if (code === "429" || message.includes("rate limit")) return "rate_limited";
296
327
  if (code === "401" || code === "AUTH_001" || message.includes("auth")) return "auth_expired";
297
328
  if (code === "400" || code === "-32602" || message.includes("invalid")) return "validation";
@@ -774,15 +805,17 @@ var Campaigns = class {
774
805
  args.idempotency_key = options.idempotencyKey;
775
806
  }
776
807
  const data = await this.callMcp("build_campaign", args);
808
+ const isDryRun = request.dryRun === true || data.dry_run === true || data.status === "dry_run";
809
+ const message = data.message ?? data.summary ?? (isDryRun && data.planned_target_count !== void 0 && data.estimated_credits !== void 0 && data.estimated_duration_seconds !== void 0 ? `Dry-run plan: ${data.planned_target_count} fresh leads. ~${data.estimated_credits} credits, ~${data.estimated_duration_seconds}s.` : "");
777
810
  return {
778
811
  campaignBuildId: data.campaign_build_id ?? null,
779
812
  campaignId: data.campaign_id ?? null,
780
813
  campaignObject: data.campaign_object ?? null,
781
- status: data.dry_run ? "dry_run" : data.status ?? "queued",
782
- currentPhase: data.dry_run ? "plan" : data.current_phase ?? "acquisition",
814
+ status: isDryRun ? "dry_run" : data.status ?? "queued",
815
+ currentPhase: isDryRun ? "plan" : data.current_phase ?? "acquisition",
783
816
  nextPollAfterSeconds: data.next_poll_after_seconds ?? 10,
784
- message: data.message ?? data.summary ?? "",
785
- dryRun: data.dry_run === true,
817
+ message,
818
+ dryRun: isDryRun,
786
819
  requestedTargetCount: data.requested_target_count,
787
820
  plannedTargetCount: data.planned_target_count,
788
821
  estimatedCredits: data.estimated_credits,
@@ -896,8 +929,8 @@ function mapStatus(data) {
896
929
  recordsProcessed: data.records_processed ?? 0,
897
930
  recordsSucceeded: data.records_succeeded ?? 0,
898
931
  recordsFailed: data.records_failed ?? 0,
899
- warnings: data.warnings ?? [],
900
- errors: data.errors ?? [],
932
+ warnings: diagnosticMessages(data.warnings),
933
+ errors: diagnosticMessages(data.errors),
901
934
  artifactCount: data.artifact_count ?? 0,
902
935
  providerRoute: mapProviderRoute(data),
903
936
  nextAction: data.next_action ?? "",
@@ -932,6 +965,14 @@ function recordOrNull(value) {
932
965
  function stringArray(value) {
933
966
  return Array.isArray(value) ? value.map((item) => String(item || "").trim()).filter(Boolean) : [];
934
967
  }
968
+ function diagnosticMessages(value) {
969
+ if (!Array.isArray(value)) return [];
970
+ return value.map((item) => {
971
+ if (typeof item === "string") return item;
972
+ const record = recordOrNull(item);
973
+ return typeof record?.message === "string" ? record.message : null;
974
+ }).filter((item) => typeof item === "string" && item.length > 0);
975
+ }
935
976
  function booleanOrNull(value) {
936
977
  return typeof value === "boolean" ? value : null;
937
978
  }
@@ -2259,22 +2300,22 @@ function queryFieldFor(kind) {
2259
2300
  function statusCommandFor(kind, id) {
2260
2301
  switch (kind) {
2261
2302
  case "op":
2262
- return `signaliz status ${id}`;
2303
+ return `signaliz ops status ${id}`;
2263
2304
  case "trigger_run":
2264
2305
  case "dataplane_run":
2265
2306
  case "replay_run":
2266
- return `signaliz watch ${id}`;
2307
+ return `signaliz ops run-status ${id} --watch`;
2267
2308
  case "queue_job":
2268
- return `signaliz queue --job-id ${id}`;
2309
+ return `signaliz ops queue --job-id ${id}`;
2269
2310
  case "routine":
2270
- return `signaliz routine ${id}`;
2311
+ return `signaliz ops routine ${id}`;
2271
2312
  default:
2272
2313
  return void 0;
2273
2314
  }
2274
2315
  }
2275
2316
  function replayCommandFor(kind, id) {
2276
2317
  if (kind !== "execution_event") return void 0;
2277
- return `signaliz replay ${id}`;
2318
+ return `signaliz ops replay ${id}`;
2278
2319
  }
2279
2320
 
2280
2321
  // src/resources/ops.ts
@@ -2922,6 +2963,10 @@ function normalizeOpsProofResult(data) {
2922
2963
  failed30d: numberValue(summary.failed_30d ?? summary.failed30d),
2923
2964
  external_delivered_30d: numberValue(summary.external_delivered_30d ?? summary.externalDelivered30d),
2924
2965
  externalDelivered30d: numberValue(summary.external_delivered_30d ?? summary.externalDelivered30d),
2966
+ nango_proofs_30d: numberValue(summary.nango_proofs_30d ?? summary.nangoProofs30d),
2967
+ nangoProofs30d: numberValue(summary.nango_proofs_30d ?? summary.nangoProofs30d),
2968
+ nango_failures_30d: numberValue(summary.nango_failures_30d ?? summary.nangoFailures30d),
2969
+ nangoFailures30d: numberValue(summary.nango_failures_30d ?? summary.nangoFailures30d),
2925
2970
  airbyte_configured: numberValue(summary.airbyte_configured ?? summary.airbyteConfigured),
2926
2971
  airbyteConfigured: numberValue(summary.airbyte_configured ?? summary.airbyteConfigured),
2927
2972
  airbyte_proofs_30d: numberValue(summary.airbyte_proofs_30d ?? summary.airbyteProofs30d),
@@ -3336,9 +3381,10 @@ function buildOpsDebugOptions(params) {
3336
3381
  }
3337
3382
  function buildCreateRoutineBody(params) {
3338
3383
  const { outputSinks, wakeOnEvents, ...rest } = params;
3384
+ const sinks = rest.output_sinks ?? outputSinks;
3339
3385
  return {
3340
3386
  ...rest,
3341
- output_sinks: rest.output_sinks ?? outputSinks,
3387
+ output_sinks: Array.isArray(sinks) ? sinks.map(normalizeOpsSinkRequest) : sinks,
3342
3388
  wake_on_events: rest.wake_on_events ?? wakeOnEvents
3343
3389
  };
3344
3390
  }
@@ -3372,6 +3418,97 @@ function buildCreateOutputSinkBody(params) {
3372
3418
  webhook_url: rest.webhook_url ?? webhookUrl
3373
3419
  };
3374
3420
  }
3421
+ function normalizeOpsSinkRequest(sink) {
3422
+ const {
3423
+ sinkId,
3424
+ connectionId,
3425
+ connectorId,
3426
+ connectorName,
3427
+ deliveryMode,
3428
+ providerConfigKey,
3429
+ integrationId,
3430
+ nangoConnectionId,
3431
+ actionName,
3432
+ nangoAction,
3433
+ proxyPath,
3434
+ nangoProxyPath,
3435
+ fieldMap,
3436
+ requiredFields,
3437
+ writeConfirmed,
3438
+ agentWriteConfirmed,
3439
+ config,
3440
+ ...rest
3441
+ } = sink;
3442
+ const normalizedConfig = normalizeOpsSinkConfigRequest(config);
3443
+ const connection_id = rest.connection_id ?? connectionId;
3444
+ const connector_id = rest.connector_id ?? connectorId;
3445
+ const delivery_mode = rest.delivery_mode ?? deliveryMode;
3446
+ const provider_config_key = rest.provider_config_key ?? providerConfigKey;
3447
+ const integration_id = rest.integration_id ?? integrationId;
3448
+ const nango_connection_id = rest.nango_connection_id ?? nangoConnectionId;
3449
+ const action_name = rest.action_name ?? actionName;
3450
+ const nango_action = rest.nango_action ?? nangoAction;
3451
+ const proxy_path = rest.proxy_path ?? proxyPath;
3452
+ const nango_proxy_path = rest.nango_proxy_path ?? nangoProxyPath;
3453
+ const field_map = rest.field_map ?? fieldMap;
3454
+ const required_fields = rest.required_fields ?? requiredFields;
3455
+ const write_confirmed = rest.write_confirmed ?? writeConfirmed;
3456
+ const agent_write_confirmed = rest.agent_write_confirmed ?? agentWriteConfirmed;
3457
+ if (connection_id !== void 0 && normalizedConfig.connection_id === void 0) normalizedConfig.connection_id = connection_id;
3458
+ if (connector_id !== void 0 && normalizedConfig.connector_id === void 0) normalizedConfig.connector_id = connector_id;
3459
+ if (delivery_mode !== void 0 && normalizedConfig.delivery_mode === void 0) normalizedConfig.delivery_mode = delivery_mode;
3460
+ if (provider_config_key !== void 0 && normalizedConfig.provider_config_key === void 0) normalizedConfig.provider_config_key = provider_config_key;
3461
+ if (integration_id !== void 0 && normalizedConfig.integration_id === void 0) normalizedConfig.integration_id = integration_id;
3462
+ if (nango_connection_id !== void 0 && normalizedConfig.nango_connection_id === void 0) normalizedConfig.nango_connection_id = nango_connection_id;
3463
+ if (action_name !== void 0 && normalizedConfig.action_name === void 0) normalizedConfig.action_name = action_name;
3464
+ if (nango_action !== void 0 && normalizedConfig.nango_action === void 0) normalizedConfig.nango_action = nango_action;
3465
+ if (proxy_path !== void 0 && normalizedConfig.proxy_path === void 0) normalizedConfig.proxy_path = proxy_path;
3466
+ if (nango_proxy_path !== void 0 && normalizedConfig.nango_proxy_path === void 0) normalizedConfig.nango_proxy_path = nango_proxy_path;
3467
+ if (field_map !== void 0 && normalizedConfig.field_map === void 0) normalizedConfig.field_map = field_map;
3468
+ if (required_fields !== void 0 && normalizedConfig.required_fields === void 0) normalizedConfig.required_fields = required_fields;
3469
+ if (write_confirmed !== void 0 && normalizedConfig.write_confirmed === void 0) normalizedConfig.write_confirmed = write_confirmed;
3470
+ if (agent_write_confirmed !== void 0 && normalizedConfig.agent_write_confirmed === void 0) normalizedConfig.agent_write_confirmed = agent_write_confirmed;
3471
+ if (sink.type === "nango" && normalizedConfig.integration_platform === void 0) normalizedConfig.integration_platform = "nango";
3472
+ return {
3473
+ ...rest,
3474
+ sink_id: rest.sink_id ?? sinkId,
3475
+ connection_id,
3476
+ connector_id,
3477
+ connector_name: rest.connector_name ?? connectorName,
3478
+ delivery_mode,
3479
+ provider_config_key,
3480
+ integration_id,
3481
+ nango_connection_id,
3482
+ action_name,
3483
+ nango_action,
3484
+ proxy_path,
3485
+ nango_proxy_path,
3486
+ field_map,
3487
+ required_fields,
3488
+ write_confirmed,
3489
+ agent_write_confirmed,
3490
+ config: normalizedConfig
3491
+ };
3492
+ }
3493
+ function normalizeOpsSinkConfigRequest(config) {
3494
+ const out = { ...config ?? {} };
3495
+ if (out.connection_id === void 0 && out.connectionId !== void 0) out.connection_id = out.connectionId;
3496
+ if (out.connector_id === void 0 && out.connectorId !== void 0) out.connector_id = out.connectorId;
3497
+ if (out.connector_name === void 0 && out.connectorName !== void 0) out.connector_name = out.connectorName;
3498
+ if (out.delivery_mode === void 0 && out.deliveryMode !== void 0) out.delivery_mode = out.deliveryMode;
3499
+ if (out.provider_config_key === void 0 && out.providerConfigKey !== void 0) out.provider_config_key = out.providerConfigKey;
3500
+ if (out.integration_id === void 0 && out.integrationId !== void 0) out.integration_id = out.integrationId;
3501
+ if (out.nango_connection_id === void 0 && out.nangoConnectionId !== void 0) out.nango_connection_id = out.nangoConnectionId;
3502
+ if (out.action_name === void 0 && out.actionName !== void 0) out.action_name = out.actionName;
3503
+ if (out.nango_action === void 0 && out.nangoAction !== void 0) out.nango_action = out.nangoAction;
3504
+ if (out.proxy_path === void 0 && out.proxyPath !== void 0) out.proxy_path = out.proxyPath;
3505
+ if (out.nango_proxy_path === void 0 && out.nangoProxyPath !== void 0) out.nango_proxy_path = out.nangoProxyPath;
3506
+ if (out.field_map === void 0 && out.fieldMap !== void 0) out.field_map = out.fieldMap;
3507
+ if (out.required_fields === void 0 && out.requiredFields !== void 0) out.required_fields = out.requiredFields;
3508
+ if (out.write_confirmed === void 0 && out.writeConfirmed !== void 0) out.write_confirmed = out.writeConfirmed;
3509
+ if (out.agent_write_confirmed === void 0 && out.agentWriteConfirmed !== void 0) out.agent_write_confirmed = out.agentWriteConfirmed;
3510
+ return out;
3511
+ }
3375
3512
  function buildApproveBody(params) {
3376
3513
  const { tokenId, tokenIds, reviewerNotes, ...rest } = params;
3377
3514
  return {
@@ -3520,6 +3657,57 @@ var GtmKernel = class {
3520
3657
  limit: options.limit
3521
3658
  });
3522
3659
  }
3660
+ /** Discover existing provider campaigns, starting with live/Kernel-linked Instantly campaigns, before audit or import preview. */
3661
+ async discoverExistingCampaigns(options = {}) {
3662
+ return this.callMcp("gtm_existing_campaign_discover", {
3663
+ provider: options.provider,
3664
+ integration_id: options.integrationId,
3665
+ search: options.search,
3666
+ limit: options.limit,
3667
+ include_kernel_linked: options.includeKernelLinked,
3668
+ include_provider_live: options.includeProviderLive
3669
+ });
3670
+ }
3671
+ /** Run a read-only existing campaign audit with completeness, recommendations, safe next MCP JSON, and approval boundaries. */
3672
+ async auditExistingCampaign(options) {
3673
+ return this.callMcp("gtm_existing_campaign_audit", {
3674
+ campaign_id: options.campaignId,
3675
+ provider: options.provider,
3676
+ provider_campaign_id: options.providerCampaignId,
3677
+ campaign_name: options.campaignName,
3678
+ days: options.days,
3679
+ include_route_preview: options.includeRoutePreview,
3680
+ include_memory: options.includeMemory,
3681
+ include_brain: options.includeBrain
3682
+ });
3683
+ }
3684
+ /** Discover the first matching existing provider campaign, then run the same read-only audit against that match. */
3685
+ async auditExistingCampaignBySearch(options) {
3686
+ const discovery = await this.discoverExistingCampaigns({
3687
+ provider: options.provider,
3688
+ integrationId: options.integrationId,
3689
+ search: options.search,
3690
+ limit: 1,
3691
+ includeKernelLinked: options.includeKernelLinked,
3692
+ includeProviderLive: options.includeProviderLive
3693
+ });
3694
+ const match = discovery.campaigns?.[0];
3695
+ const campaignId = match?.linked_kernel_campaign_id || void 0;
3696
+ const providerCampaignId = match?.provider_campaign_id || void 0;
3697
+ if (!campaignId && !providerCampaignId) {
3698
+ throw new Error(`No existing ${options.provider || discovery.provider || "provider"} campaign matched "${options.search}"`);
3699
+ }
3700
+ return this.auditExistingCampaign({
3701
+ provider: options.provider || discovery.provider || match?.provider,
3702
+ campaignId,
3703
+ providerCampaignId,
3704
+ campaignName: match?.name || match?.linked_kernel_campaign_name || void 0,
3705
+ days: options.days,
3706
+ includeRoutePreview: options.includeRoutePreview,
3707
+ includeMemory: options.includeMemory,
3708
+ includeBrain: options.includeBrain
3709
+ });
3710
+ }
3523
3711
  /** Create a first-class GTM campaign object in the current workspace. */
3524
3712
  async createCampaign(input) {
3525
3713
  return this.callMcp("gtm_campaign_create", campaignCreateArgs(input));
@@ -3725,6 +3913,47 @@ var GtmKernel = class {
3725
3913
  brain_cycle_min_interval_minutes: input.brainCycleMinIntervalMinutes
3726
3914
  });
3727
3915
  }
3916
+ /** Preview anonymized Instantly workspace sources registered for Kernel import. */
3917
+ async previewKernelImport(input = {}) {
3918
+ return this.callMcp("gtm_kernel_import_preview", {
3919
+ source_ids: input.sourceIds,
3920
+ include_leads: input.includeLeads,
3921
+ include_replies: input.includeReplies,
3922
+ include_private_copy: input.includePrivateCopy,
3923
+ max_pages: input.maxPages,
3924
+ limit: input.limit
3925
+ });
3926
+ }
3927
+ /** Queue the read-only Instantly-to-GTM Kernel import. Live writes require writeApproved. */
3928
+ async runKernelImport(input = {}) {
3929
+ return this.callMcp("gtm_kernel_import_run", {
3930
+ source_ids: input.sourceIds,
3931
+ dry_run: input.dryRun,
3932
+ write_approved: input.writeApproved,
3933
+ include_leads: input.includeLeads,
3934
+ include_replies: input.includeReplies,
3935
+ include_private_copy: input.includePrivateCopy,
3936
+ private_copy_approved: input.privateCopyApproved,
3937
+ promote_global_patterns: input.promoteGlobalPatterns,
3938
+ min_global_privacy_k: input.minGlobalPrivacyK,
3939
+ max_pages: input.maxPages,
3940
+ limit: input.limit
3941
+ });
3942
+ }
3943
+ /** Queue Brain distillation over imported Instantly memory with abstracted-only outputs. */
3944
+ async runBrainDistillation(input = {}) {
3945
+ return this.callMcp("gtm_brain_distill_run", {
3946
+ source_ids: input.sourceIds,
3947
+ write_mode: input.writeMode,
3948
+ write_approved: input.writeApproved,
3949
+ brain_cycle_phases: input.brainCyclePhases,
3950
+ days: input.days,
3951
+ network_days: input.networkDays,
3952
+ min_sample_size: input.minSampleSize,
3953
+ min_workspace_count: input.minWorkspaceCount,
3954
+ min_privacy_k: input.minPrivacyK
3955
+ });
3956
+ }
3728
3957
  /** Prepare a provider-agnostic feedback webhook URL for Smartlead, HeyReach, Airbyte, or custom sender events. */
3729
3958
  async prepareFeedbackWebhook(input) {
3730
3959
  return this.callMcp("gtm_feedback_webhook_prepare", {
@@ -4152,6 +4381,43 @@ var GtmKernel = class {
4152
4381
  context: input.context
4153
4382
  });
4154
4383
  }
4384
+ /** List Nango-backed action tools for a workspace connection without executing them. */
4385
+ async listNangoTools(options = {}) {
4386
+ return this.callMcp("nango_mcp_tools_list", {
4387
+ workspace_connection_id: options.workspaceConnectionId,
4388
+ connection_id: options.connectionId,
4389
+ provider_config_key: options.providerConfigKey,
4390
+ integration_id: options.integrationId,
4391
+ nango_connection_id: options.nangoConnectionId,
4392
+ format: options.format,
4393
+ include_raw: options.includeRaw
4394
+ });
4395
+ }
4396
+ /** Dry-run or execute a Nango-backed action tool through the approval-aware MCP bridge. */
4397
+ async callNangoTool(input) {
4398
+ return this.callMcp("nango_mcp_tool_call", {
4399
+ workspace_connection_id: input.workspaceConnectionId,
4400
+ connection_id: input.connectionId,
4401
+ provider_config_key: input.providerConfigKey,
4402
+ integration_id: input.integrationId,
4403
+ nango_connection_id: input.nangoConnectionId,
4404
+ action_name: input.actionName,
4405
+ tool_name: input.toolName,
4406
+ input: input.input,
4407
+ async: input.async,
4408
+ max_retries: input.maxRetries,
4409
+ dry_run: input.dryRun,
4410
+ confirm: input.confirm,
4411
+ confirm_write: input.confirmWrite
4412
+ });
4413
+ }
4414
+ /** Poll an async Nango action result by action id or status URL. */
4415
+ async getNangoActionResult(input) {
4416
+ return this.callMcp("nango_mcp_action_result_get", {
4417
+ action_id: input.actionId,
4418
+ status_url: input.statusUrl
4419
+ });
4420
+ }
4155
4421
  /** Deliver approved campaign-layer records to a webhook recipe, starting with Clay-style webhooks. */
4156
4422
  async deliverWebhook(input) {
4157
4423
  return this.callMcp("gtm_webhook_deliver", {
@@ -4286,6 +4552,82 @@ function compact2(value) {
4286
4552
  }
4287
4553
 
4288
4554
  // src/index.ts
4555
+ function inferMcpToolCategory(toolName) {
4556
+ if (typeof toolName !== "string" || !toolName) return void 0;
4557
+ if (toolName.startsWith("ops_") || toolName === "get_ops_readiness" || toolName === "get_gtm_ops_readiness" || toolName.startsWith("gtm_") || [
4558
+ "list_routines",
4559
+ "create_routine",
4560
+ "update_routine",
4561
+ "run_routine_now",
4562
+ "get_routine",
4563
+ "get_routine_ticks",
4564
+ "get_tick_items",
4565
+ "get_last_tick_items",
4566
+ "chain_routines",
4567
+ "get_chain_status",
4568
+ "launch_campaign",
4569
+ "quickstart_gtm_book",
4570
+ "list_campaigns",
4571
+ "campaign_performance",
4572
+ "tune_campaign",
4573
+ "emit_event",
4574
+ "approvals_list",
4575
+ "list_output_sinks",
4576
+ "create_output_sink",
4577
+ "update_output_sink",
4578
+ "delete_output_sink",
4579
+ "attach_sink_to_routine"
4580
+ ].includes(toolName)) {
4581
+ return "ops";
4582
+ }
4583
+ if ([
4584
+ "find_emails_with_verification",
4585
+ "verify_email",
4586
+ "enrich_company_signals",
4587
+ "company_intelligence",
4588
+ "find_contacts_with_email",
4589
+ "execute_primitive"
4590
+ ].includes(toolName)) {
4591
+ return "enrichment";
4592
+ }
4593
+ if (toolName.includes("icp")) return "icp";
4594
+ if (toolName.startsWith("ai_clean_")) return "data_cleaning";
4595
+ if (toolName.includes("system") || toolName.includes("workflow")) return "automation";
4596
+ if (toolName.includes("agent") || toolName.includes("platform_health") || toolName === "discover_capabilities") return "observability";
4597
+ return void 0;
4598
+ }
4599
+ function mapMcpToolInfo(t) {
4600
+ const annotations = asRecord3(t.annotations);
4601
+ const execution = asRecord3(t.execution);
4602
+ const schemas = asRecord3(t.schemas);
4603
+ const name = typeof t.name === "string" ? t.name : typeof t.id === "string" ? t.id : "";
4604
+ return {
4605
+ name,
4606
+ description: String(t.description ?? t.short_description ?? "").slice(0, 120),
4607
+ category: typeof t.category === "string" ? t.category : typeof annotations?.category === "string" ? annotations.category : inferMcpToolCategory(name),
4608
+ costCredits: typeof (execution?.cost_credits ?? annotations?.cost_credits) === "number" ? execution?.cost_credits ?? annotations?.cost_credits : void 0,
4609
+ contractVersion: typeof t.contract_version === "string" ? t.contract_version : typeof (annotations?.contract_version ?? annotations?.contract?.contract_version) === "string" ? annotations?.contract_version ?? annotations?.contract?.contract_version : void 0,
4610
+ permissionLevel: typeof (execution?.permission_level ?? annotations?.permission_level ?? annotations?.contract?.permission_level) === "string" ? execution?.permission_level ?? annotations?.permission_level ?? annotations?.contract?.permission_level : void 0,
4611
+ authScopes: asStringArray(execution?.auth_scopes ?? annotations?.auth_scopes ?? annotations?.contract?.auth_scopes),
4612
+ idempotent: typeof (execution?.idempotent ?? annotations?.idempotentHint ?? annotations?.idempotent ?? annotations?.contract?.idempotent) === "boolean" ? execution?.idempotent ?? annotations?.idempotentHint ?? annotations?.idempotent ?? annotations?.contract?.idempotent : void 0,
4613
+ destructive: typeof (execution?.destructive ?? annotations?.destructiveHint ?? annotations?.destructive ?? annotations?.contract?.destructive) === "boolean" ? execution?.destructive ?? annotations?.destructiveHint ?? annotations?.destructive ?? annotations?.contract?.destructive : void 0,
4614
+ retryable: typeof (execution?.retryable ?? annotations?.retryable ?? annotations?.contract?.retryable) === "boolean" ? execution?.retryable ?? annotations?.retryable ?? annotations?.contract?.retryable : void 0,
4615
+ rateLimitKey: typeof (execution?.rate_limit_key ?? annotations?.rate_limit_key ?? annotations?.contract?.rate_limit_key) === "string" ? execution?.rate_limit_key ?? annotations?.rate_limit_key ?? annotations?.contract?.rate_limit_key : void 0,
4616
+ observability: asRecord3(annotations?.observability ?? annotations?.contract?.observability),
4617
+ inputSchema: asObjectSchema(schemas?.input ?? t.inputSchema ?? t.input_schema ?? annotations?.contract?.input_schema),
4618
+ outputSchema: asObjectSchema(schemas?.output ?? t.outputSchema ?? t.output_schema ?? annotations?.contract?.output_schema),
4619
+ annotations
4620
+ };
4621
+ }
4622
+ function asRecord3(value) {
4623
+ return value && typeof value === "object" ? value : void 0;
4624
+ }
4625
+ function asStringArray(value) {
4626
+ return Array.isArray(value) ? value.filter((item) => typeof item === "string") : void 0;
4627
+ }
4628
+ function asObjectSchema(value) {
4629
+ return asRecord3(value);
4630
+ }
4289
4631
  var Signaliz = class {
4290
4632
  constructor(config) {
4291
4633
  this.client = new HttpClient(config);
@@ -4341,25 +4683,18 @@ var Signaliz = class {
4341
4683
  }
4342
4684
  /** List all available MCP tools */
4343
4685
  async listTools() {
4686
+ try {
4687
+ const manifest = await this.client.mcp("tools/call", {
4688
+ name: "get_tool_manifest",
4689
+ arguments: { include_schemas: true }
4690
+ });
4691
+ const tools2 = manifest?.tools ?? manifest ?? [];
4692
+ if (Array.isArray(tools2)) return tools2.map(mapMcpToolInfo);
4693
+ } catch (_err) {
4694
+ }
4344
4695
  const data = await this.client.mcp("tools/list", {});
4345
4696
  const tools = data?.tools ?? data ?? [];
4346
- return tools.map((t) => ({
4347
- name: t.name,
4348
- description: (t.description ?? "").slice(0, 120),
4349
- category: t.annotations?.category,
4350
- costCredits: t.annotations?.cost_credits,
4351
- contractVersion: t.annotations?.contract_version ?? t.annotations?.contract?.contract_version,
4352
- permissionLevel: t.annotations?.permission_level ?? t.annotations?.contract?.permission_level,
4353
- authScopes: t.annotations?.auth_scopes ?? t.annotations?.contract?.auth_scopes,
4354
- idempotent: t.annotations?.idempotentHint ?? t.annotations?.idempotent ?? t.annotations?.contract?.idempotent,
4355
- destructive: t.annotations?.destructiveHint ?? t.annotations?.destructive ?? t.annotations?.contract?.destructive,
4356
- retryable: t.annotations?.retryable ?? t.annotations?.contract?.retryable,
4357
- rateLimitKey: t.annotations?.rate_limit_key ?? t.annotations?.contract?.rate_limit_key,
4358
- observability: t.annotations?.observability ?? t.annotations?.contract?.observability,
4359
- inputSchema: t.inputSchema ?? t.input_schema ?? t.annotations?.contract?.input_schema,
4360
- outputSchema: t.outputSchema ?? t.output_schema ?? t.annotations?.contract?.output_schema,
4361
- annotations: t.annotations
4362
- }));
4697
+ return tools.map(mapMcpToolInfo);
4363
4698
  }
4364
4699
  /** Discover tools by natural language query */
4365
4700
  async discover(query, category) {