integrate-sdk 0.8.60-dev.0 → 0.8.62-dev.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -8303,6 +8303,7 @@ var init_index_browser = () => {};
8303
8303
  // src/triggers/utils.ts
8304
8304
  var exports_utils = {};
8305
8305
  __export(exports_utils, {
8306
+ validateStepLimit: () => validateStepLimit,
8306
8307
  validateStatusTransition: () => validateStatusTransition,
8307
8308
  generateTriggerId: () => generateTriggerId,
8308
8309
  extractProviderFromToolName: () => extractProviderFromToolName,
@@ -8330,6 +8331,15 @@ function validateStatusTransition(currentStatus, targetStatus) {
8330
8331
  }
8331
8332
  return { valid: true };
8332
8333
  }
8334
+ function validateStepLimit(stepIndex, maxSteps) {
8335
+ if (stepIndex >= maxSteps) {
8336
+ return {
8337
+ valid: false,
8338
+ error: `Step index ${stepIndex} exceeds maximum of ${maxSteps} steps`
8339
+ };
8340
+ }
8341
+ return { valid: true };
8342
+ }
8333
8343
  function calculateHasMore(offset, returnedCount, total) {
8334
8344
  return offset + returnedCount < total;
8335
8345
  }
@@ -10337,6 +10347,204 @@ var init_ai = __esm(() => {
10337
10347
  init_trigger_tools();
10338
10348
  });
10339
10349
 
10350
+ // src/triggers/webhooks.ts
10351
+ async function signPayload(payload, secret) {
10352
+ const encoder = new TextEncoder;
10353
+ const data = encoder.encode(JSON.stringify(payload));
10354
+ const key = await crypto.subtle.importKey("raw", encoder.encode(secret), { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
10355
+ const signature = await crypto.subtle.sign("HMAC", key, data);
10356
+ return Array.from(new Uint8Array(signature)).map((b) => b.toString(16).padStart(2, "0")).join("");
10357
+ }
10358
+ async function deliverWebhook(webhook, payload, timeoutMs) {
10359
+ const headers = {
10360
+ "Content-Type": "application/json",
10361
+ ...webhook.headers
10362
+ };
10363
+ if (webhook.secret) {
10364
+ headers["X-Webhook-Signature"] = await signPayload(payload, webhook.secret);
10365
+ }
10366
+ const controller = new AbortController;
10367
+ const timeout = setTimeout(() => controller.abort(), timeoutMs);
10368
+ try {
10369
+ const response = await fetch(webhook.url, {
10370
+ method: "POST",
10371
+ headers,
10372
+ body: JSON.stringify(payload),
10373
+ signal: controller.signal
10374
+ });
10375
+ if (!response.ok) {
10376
+ logger30.warn(`Webhook delivery to ${webhook.url} returned ${response.status}`);
10377
+ }
10378
+ } finally {
10379
+ clearTimeout(timeout);
10380
+ }
10381
+ }
10382
+ async function deliverWebhooks(webhooks, payload, timeoutMs) {
10383
+ if (webhooks.length === 0)
10384
+ return;
10385
+ const results = await Promise.allSettled(webhooks.map((webhook) => deliverWebhook(webhook, payload, timeoutMs)));
10386
+ for (let i = 0;i < results.length; i++) {
10387
+ const result = results[i];
10388
+ if (result.status === "rejected") {
10389
+ logger30.warn(`Webhook delivery to ${webhooks[i].url} failed:`, result.reason);
10390
+ }
10391
+ }
10392
+ }
10393
+ var logger30;
10394
+ var init_webhooks = __esm(() => {
10395
+ init_logger();
10396
+ logger30 = createLogger("Webhooks", "server");
10397
+ });
10398
+
10399
+ // src/triggers/types.ts
10400
+ var MAX_TRIGGER_STEPS = 20, WEBHOOK_DELIVERY_TIMEOUT_MS = 1e4;
10401
+
10402
+ // src/triggers/executor.ts
10403
+ var exports_executor = {};
10404
+ __export(exports_executor, {
10405
+ executeTrigger: () => executeTrigger
10406
+ });
10407
+ async function executeTrigger(trigger, config, context) {
10408
+ const steps = [];
10409
+ let currentToolName = trigger.toolName;
10410
+ let currentToolArguments = trigger.toolArguments;
10411
+ let currentProvider = trigger.provider;
10412
+ let stepIndex = 0;
10413
+ while (stepIndex < MAX_TRIGGER_STEPS) {
10414
+ const stepValidation = validateStepLimit(stepIndex, MAX_TRIGGER_STEPS);
10415
+ if (!stepValidation.valid) {
10416
+ logger31.error(`[Trigger ${trigger.id}] ${stepValidation.error}`);
10417
+ break;
10418
+ }
10419
+ const providerToken = await config.getProviderToken(currentProvider, undefined, context);
10420
+ if (!providerToken) {
10421
+ const error = `No OAuth token available for provider '${currentProvider}'`;
10422
+ logger31.error(`[Trigger ${trigger.id}] ${error}`);
10423
+ steps.push({
10424
+ stepIndex,
10425
+ toolName: currentToolName,
10426
+ success: false,
10427
+ error,
10428
+ duration: 0,
10429
+ executedAt: new Date().toISOString()
10430
+ });
10431
+ await config.triggers.update(trigger.id, {
10432
+ lastRunAt: new Date().toISOString(),
10433
+ runCount: (trigger.runCount || 0) + 1,
10434
+ lastError: error,
10435
+ status: "failed"
10436
+ }, context);
10437
+ return { success: false, steps, error };
10438
+ }
10439
+ const startTime = Date.now();
10440
+ let toolResult;
10441
+ let stepSuccess = true;
10442
+ let stepError;
10443
+ try {
10444
+ toolResult = await config.handleToolCall({ name: currentToolName, arguments: currentToolArguments }, `${providerToken.tokenType || "Bearer"} ${providerToken.accessToken}`, null);
10445
+ } catch (err) {
10446
+ stepSuccess = false;
10447
+ stepError = err.message || "Tool execution failed";
10448
+ logger31.error(`[Trigger ${trigger.id}] Step ${stepIndex} failed:`, err);
10449
+ }
10450
+ const duration = Date.now() - startTime;
10451
+ const executedAt = new Date().toISOString();
10452
+ steps.push({
10453
+ stepIndex,
10454
+ toolName: currentToolName,
10455
+ success: stepSuccess,
10456
+ result: stepSuccess ? toolResult : undefined,
10457
+ error: stepError,
10458
+ duration,
10459
+ executedAt
10460
+ });
10461
+ if (!config.triggers.onComplete || !stepSuccess) {
10462
+ const updates = {
10463
+ lastRunAt: executedAt,
10464
+ runCount: (trigger.runCount || 0) + 1
10465
+ };
10466
+ if (stepSuccess) {
10467
+ updates.lastResult = toolResult;
10468
+ updates.lastError = undefined;
10469
+ if (trigger.schedule.type === "once") {
10470
+ updates.status = "completed";
10471
+ }
10472
+ } else {
10473
+ updates.lastError = stepError;
10474
+ updates.status = "failed";
10475
+ }
10476
+ await config.triggers.update(trigger.id, updates, context);
10477
+ return { success: stepSuccess, steps, error: stepError };
10478
+ }
10479
+ const completeRequest = {
10480
+ success: stepSuccess,
10481
+ result: stepSuccess ? toolResult : undefined,
10482
+ error: stepError,
10483
+ executedAt,
10484
+ duration,
10485
+ stepIndex,
10486
+ previousResults: steps,
10487
+ final: false
10488
+ };
10489
+ const completeResponse = await config.triggers.onComplete({
10490
+ trigger,
10491
+ request: completeRequest,
10492
+ context
10493
+ });
10494
+ if (completeResponse.hasMore && completeResponse.nextStep) {
10495
+ currentToolName = completeResponse.nextStep.toolName;
10496
+ currentToolArguments = completeResponse.nextStep.toolArguments;
10497
+ currentProvider = completeResponse.nextStep.provider;
10498
+ stepIndex++;
10499
+ continue;
10500
+ }
10501
+ const finalUpdates = {
10502
+ lastRunAt: executedAt,
10503
+ runCount: (trigger.runCount || 0) + 1
10504
+ };
10505
+ if (stepSuccess) {
10506
+ finalUpdates.lastResult = toolResult;
10507
+ finalUpdates.lastError = undefined;
10508
+ if (trigger.schedule.type === "once") {
10509
+ finalUpdates.status = "completed";
10510
+ }
10511
+ } else {
10512
+ finalUpdates.lastError = stepError;
10513
+ finalUpdates.status = "failed";
10514
+ }
10515
+ await config.triggers.update(trigger.id, finalUpdates, context);
10516
+ if (completeResponse.webhooks && completeResponse.webhooks.length > 0) {
10517
+ const totalDuration = steps.reduce((sum, s) => sum + (s.duration || 0), 0);
10518
+ const payload = {
10519
+ triggerId: trigger.id,
10520
+ success: steps.every((s) => s.success),
10521
+ steps,
10522
+ totalSteps: steps.length,
10523
+ totalDuration,
10524
+ executedAt
10525
+ };
10526
+ deliverWebhooks(completeResponse.webhooks, payload, WEBHOOK_DELIVERY_TIMEOUT_MS).catch(() => {});
10527
+ }
10528
+ return { success: stepSuccess, steps, error: stepError };
10529
+ }
10530
+ const limitError = `Trigger execution exceeded maximum of ${MAX_TRIGGER_STEPS} steps`;
10531
+ logger31.error(`[Trigger ${trigger.id}] ${limitError}`);
10532
+ await config.triggers.update(trigger.id, {
10533
+ lastRunAt: new Date().toISOString(),
10534
+ runCount: (trigger.runCount || 0) + 1,
10535
+ lastError: limitError,
10536
+ status: "failed"
10537
+ }, context);
10538
+ return { success: false, steps, error: limitError };
10539
+ }
10540
+ var logger31;
10541
+ var init_executor = __esm(() => {
10542
+ init_logger();
10543
+ init_utils2();
10544
+ init_webhooks();
10545
+ logger31 = createLogger("TriggerExecutor", "server");
10546
+ });
10547
+
10340
10548
  // src/server.ts
10341
10549
  var exports_server = {};
10342
10550
  __export(exports_server, {
@@ -10430,7 +10638,7 @@ function createMCPServer(config) {
10430
10638
  if (integration.oauth) {
10431
10639
  const { clientId, clientSecret, redirectUri: integrationRedirectUri, config: oauthConfig } = integration.oauth;
10432
10640
  if (!clientId || !clientSecret) {
10433
- logger30.warn(`Warning: Integration "${integration.id}" is missing OAuth credentials. ` + `Provide clientId and clientSecret in the integration configuration.`);
10641
+ logger32.warn(`Warning: Integration "${integration.id}" is missing OAuth credentials. ` + `Provide clientId and clientSecret in the integration configuration.`);
10434
10642
  return integration;
10435
10643
  }
10436
10644
  const redirectUri = integrationRedirectUri || config.redirectUri || getDefaultRedirectUri();
@@ -10561,7 +10769,7 @@ function createMCPServer(config) {
10561
10769
  }
10562
10770
  return response2;
10563
10771
  } catch (error) {
10564
- logger30.error("[MCP Tool Call] Error:", error);
10772
+ logger32.error("[MCP Tool Call] Error:", error);
10565
10773
  return Response.json({ error: error.message || "Failed to execute tool call" }, { status: error.statusCode || 500 });
10566
10774
  }
10567
10775
  }
@@ -10577,6 +10785,57 @@ function createMCPServer(config) {
10577
10785
  }));
10578
10786
  return Response.json({ integrations });
10579
10787
  }
10788
+ if (segments.length === 2 && segments[0] === "triggers" && segments[1] === "notify" && method === "POST") {
10789
+ if (!config.triggers) {
10790
+ return Response.json({ error: "Triggers not configured. Add triggers callbacks to createMCPServer config." }, { status: 501 });
10791
+ }
10792
+ try {
10793
+ const apiKey = webRequest.headers.get("x-api-key");
10794
+ if (!apiKey || apiKey !== config.apiKey) {
10795
+ return Response.json({ error: "Unauthorized" }, { status: 401 });
10796
+ }
10797
+ const body = await webRequest.json();
10798
+ const { triggerId } = body;
10799
+ if (!triggerId) {
10800
+ return Response.json({ error: "triggerId is required" }, { status: 400 });
10801
+ }
10802
+ const trigger = await config.triggers.get(triggerId);
10803
+ if (!trigger) {
10804
+ return Response.json({ error: "Trigger not found" }, { status: 404 });
10805
+ }
10806
+ if (!trigger.provider) {
10807
+ return Response.json({ error: "Trigger has no provider configured" }, { status: 400 });
10808
+ }
10809
+ const triggerContext = trigger.userId ? { userId: trigger.userId } : undefined;
10810
+ const { executeTrigger: executeTrigger2 } = await Promise.resolve().then(() => (init_executor(), exports_executor));
10811
+ const { OAuthHandler: OAuthHandler2 } = await Promise.resolve().then(() => (init_base_handler(), exports_base_handler));
10812
+ const oauthHandler = new OAuthHandler2({
10813
+ providers,
10814
+ serverUrl: config.serverUrl,
10815
+ apiKey: config.apiKey,
10816
+ setProviderToken: config.setProviderToken,
10817
+ removeProviderToken: config.removeProviderToken,
10818
+ getSessionContext: config.getSessionContext
10819
+ });
10820
+ const executionResult = await executeTrigger2(trigger, {
10821
+ triggers: config.triggers,
10822
+ getProviderToken: async (provider, email, ctx) => {
10823
+ return config.getProviderToken ? await config.getProviderToken(provider, email, ctx) : undefined;
10824
+ },
10825
+ handleToolCall: (toolBody, authHeader, integrationsHeader) => {
10826
+ return oauthHandler.handleToolCall(toolBody, authHeader, integrationsHeader);
10827
+ }
10828
+ }, triggerContext);
10829
+ return Response.json({
10830
+ success: executionResult.success,
10831
+ steps: executionResult.steps,
10832
+ error: executionResult.error
10833
+ });
10834
+ } catch (error) {
10835
+ logger32.error("[Trigger Notify] Error:", error);
10836
+ return Response.json({ error: error.message || "Failed to execute trigger" }, { status: 500 });
10837
+ }
10838
+ }
10580
10839
  if (segments.length >= 1 && segments[0] === "triggers") {
10581
10840
  if (!config.triggers) {
10582
10841
  return Response.json({ error: "Triggers not configured. Add triggers callbacks to createMCPServer config." }, { status: 501 });
@@ -10617,8 +10876,9 @@ function createMCPServer(config) {
10617
10876
  };
10618
10877
  const created = await config.triggers.create(trigger, context2);
10619
10878
  const schedulerUrl = config.schedulerUrl || config.serverUrl || "https://mcp.integrate.dev";
10620
- const callbackBaseUrl = process.env.INTEGRATE_URL || (typeof window !== "undefined" ? window.location.origin : "http://localhost:3000");
10879
+ const defaultCallbackBaseUrl = process.env.INTEGRATE_URL || (typeof window !== "undefined" ? window.location.origin : "http://localhost:3000");
10621
10880
  try {
10881
+ const callbackBaseUrl = config.triggers.getCallbackUrl ? await config.triggers.getCallbackUrl(context2) : defaultCallbackBaseUrl;
10622
10882
  await fetch(`${schedulerUrl}/scheduler/register`, {
10623
10883
  method: "POST",
10624
10884
  headers: {
@@ -10628,8 +10888,7 @@ function createMCPServer(config) {
10628
10888
  body: JSON.stringify({
10629
10889
  triggerId: created.id,
10630
10890
  schedule: created.schedule,
10631
- callbackUrl: `${callbackBaseUrl}/api/integrate/triggers/${created.id}/execute`,
10632
- completeUrl: `${callbackBaseUrl}/api/integrate/triggers/${created.id}/complete`,
10891
+ callbackUrl: `${callbackBaseUrl}/api/integrate/triggers/notify`,
10633
10892
  metadata: {
10634
10893
  userId: context2?.userId,
10635
10894
  provider: created.provider
@@ -10637,7 +10896,7 @@ function createMCPServer(config) {
10637
10896
  })
10638
10897
  });
10639
10898
  } catch (scheduleError) {
10640
- logger30.error("[Trigger] Failed to register with scheduler:", scheduleError);
10899
+ logger32.error("[Trigger] Failed to register with scheduler:", scheduleError);
10641
10900
  }
10642
10901
  return Response.json(created, { status: 201 });
10643
10902
  }
@@ -10672,7 +10931,7 @@ function createMCPServer(config) {
10672
10931
  body: JSON.stringify({ triggerId })
10673
10932
  });
10674
10933
  } catch (error) {
10675
- logger30.error("[Trigger] Failed to pause in scheduler:", error);
10934
+ logger32.error("[Trigger] Failed to pause in scheduler:", error);
10676
10935
  }
10677
10936
  return Response.json(updated);
10678
10937
  } else if (subAction === "resume" && method === "POST") {
@@ -10700,7 +10959,7 @@ function createMCPServer(config) {
10700
10959
  body: JSON.stringify({ triggerId })
10701
10960
  });
10702
10961
  } catch (error) {
10703
- logger30.error("[Trigger] Failed to resume in scheduler:", error);
10962
+ logger32.error("[Trigger] Failed to resume in scheduler:", error);
10704
10963
  }
10705
10964
  return Response.json(updated);
10706
10965
  } else if (subAction === "run" && method === "POST") {
@@ -10711,10 +10970,7 @@ function createMCPServer(config) {
10711
10970
  if (!trigger.provider) {
10712
10971
  return Response.json({ error: "Trigger has no provider configured" }, { status: 400 });
10713
10972
  }
10714
- const providerToken = config.getProviderToken ? await config.getProviderToken(trigger.provider, undefined, context2) : undefined;
10715
- if (!providerToken) {
10716
- return Response.json({ error: "No OAuth token available for this trigger" }, { status: 401 });
10717
- }
10973
+ const { executeTrigger: executeTrigger2 } = await Promise.resolve().then(() => (init_executor(), exports_executor));
10718
10974
  const { OAuthHandler: OAuthHandler2 } = await Promise.resolve().then(() => (init_base_handler(), exports_base_handler));
10719
10975
  const oauthHandler = new OAuthHandler2({
10720
10976
  providers,
@@ -10724,91 +10980,23 @@ function createMCPServer(config) {
10724
10980
  removeProviderToken: config.removeProviderToken,
10725
10981
  getSessionContext: config.getSessionContext
10726
10982
  });
10727
- const startTime = Date.now();
10728
- try {
10729
- const result = await oauthHandler.handleToolCall({ name: trigger.toolName, arguments: trigger.toolArguments }, `Bearer ${providerToken.accessToken}`, null);
10730
- const duration = Date.now() - startTime;
10731
- const executionResult = {
10732
- success: true,
10733
- result,
10734
- executedAt: new Date().toISOString(),
10735
- duration
10736
- };
10737
- await config.triggers.update(triggerId, {
10738
- lastRunAt: executionResult.executedAt,
10739
- runCount: (trigger.runCount || 0) + 1,
10740
- lastResult: result,
10741
- lastError: undefined
10742
- }, context2);
10743
- return Response.json(executionResult);
10744
- } catch (error) {
10745
- const duration = Date.now() - startTime;
10746
- const executionResult = {
10747
- success: false,
10748
- error: error.message || "Tool execution failed",
10749
- executedAt: new Date().toISOString(),
10750
- duration
10751
- };
10752
- await config.triggers.update(triggerId, {
10753
- lastRunAt: executionResult.executedAt,
10754
- runCount: (trigger.runCount || 0) + 1,
10755
- lastError: error.message,
10756
- status: "failed"
10757
- }, context2);
10758
- return Response.json(executionResult, { status: 500 });
10759
- }
10760
- } else if (subAction === "execute" && method === "GET") {
10761
- const apiKey = webRequest.headers.get("x-api-key");
10762
- if (!apiKey || apiKey !== config.apiKey) {
10763
- return Response.json({ error: "Unauthorized" }, { status: 401 });
10764
- }
10765
- const trigger = await config.triggers.get(triggerId, context2);
10766
- if (!trigger) {
10767
- return Response.json({ error: "Trigger not found" }, { status: 404 });
10768
- }
10769
- if (!trigger.provider) {
10770
- return Response.json({ error: "Trigger has no provider configured" }, { status: 400 });
10771
- }
10772
- const providerToken = config.getProviderToken ? await config.getProviderToken(trigger.provider, undefined, context2) : undefined;
10773
- if (!providerToken) {
10774
- return Response.json({ error: "No OAuth token available for this trigger" }, { status: 401 });
10775
- }
10776
- return Response.json({
10777
- trigger: {
10778
- id: trigger.id,
10779
- toolName: trigger.toolName,
10780
- toolArguments: trigger.toolArguments,
10781
- provider: trigger.provider
10983
+ const executionResult = await executeTrigger2(trigger, {
10984
+ triggers: config.triggers,
10985
+ getProviderToken: async (provider, email, ctx) => {
10986
+ return config.getProviderToken ? await config.getProviderToken(provider, email, ctx) : undefined;
10782
10987
  },
10783
- accessToken: providerToken.accessToken,
10784
- tokenType: providerToken.tokenType || "Bearer"
10785
- });
10786
- } else if (subAction === "complete" && method === "POST") {
10787
- const apiKey = webRequest.headers.get("x-api-key");
10788
- if (!apiKey || apiKey !== config.apiKey) {
10789
- return Response.json({ error: "Unauthorized" }, { status: 401 });
10790
- }
10791
- const body = await webRequest.json();
10792
- const trigger = await config.triggers.get(triggerId, context2);
10793
- if (!trigger) {
10794
- return Response.json({ error: "Trigger not found" }, { status: 404 });
10795
- }
10796
- const updates = {
10797
- lastRunAt: body.executedAt,
10798
- runCount: (trigger.runCount || 0) + 1
10799
- };
10800
- if (body.success) {
10801
- updates.lastResult = body.result;
10802
- updates.lastError = undefined;
10803
- if (trigger.schedule.type === "once") {
10804
- updates.status = "completed";
10988
+ handleToolCall: (toolBody, authHeader, integrationsHeader) => {
10989
+ return oauthHandler.handleToolCall(toolBody, authHeader, integrationsHeader);
10805
10990
  }
10806
- } else {
10807
- updates.lastError = body.error;
10808
- updates.status = "failed";
10809
- }
10810
- await config.triggers.update(triggerId, updates, context2);
10811
- return Response.json({ success: true });
10991
+ }, context2);
10992
+ return Response.json({
10993
+ success: executionResult.success,
10994
+ result: executionResult.steps[0]?.result,
10995
+ executedAt: executionResult.steps[0]?.executedAt || new Date().toISOString(),
10996
+ duration: executionResult.steps[0]?.duration,
10997
+ error: executionResult.error,
10998
+ steps: executionResult.steps
10999
+ }, { status: executionResult.success ? 200 : 500 });
10812
11000
  } else if (!subAction && method === "GET") {
10813
11001
  const trigger = await config.triggers.get(triggerId, context2);
10814
11002
  if (!trigger) {
@@ -10841,7 +11029,7 @@ function createMCPServer(config) {
10841
11029
  })
10842
11030
  });
10843
11031
  } catch (error) {
10844
- logger30.error("[Trigger] Failed to update scheduler:", error);
11032
+ logger32.error("[Trigger] Failed to update scheduler:", error);
10845
11033
  }
10846
11034
  }
10847
11035
  return Response.json(updated);
@@ -10858,14 +11046,14 @@ function createMCPServer(config) {
10858
11046
  body: JSON.stringify({ triggerId })
10859
11047
  });
10860
11048
  } catch (error) {
10861
- logger30.error("[Trigger] Failed to unregister from scheduler:", error);
11049
+ logger32.error("[Trigger] Failed to unregister from scheduler:", error);
10862
11050
  }
10863
11051
  return new Response(null, { status: 204 });
10864
11052
  }
10865
11053
  }
10866
11054
  return Response.json({ error: "Invalid trigger route or method" }, { status: 404 });
10867
11055
  } catch (error) {
10868
- logger30.error("[Trigger] Error:", error);
11056
+ logger32.error("[Trigger] Error:", error);
10869
11057
  return Response.json({ error: error.message || "Failed to process trigger request" }, { status: error.statusCode || 500 });
10870
11058
  }
10871
11059
  }
@@ -10891,11 +11079,11 @@ function createMCPServer(config) {
10891
11079
  const errorRedirectUrl = "/auth-error";
10892
11080
  if (error) {
10893
11081
  const errorMsg = errorDescription || error;
10894
- logger30.error("[OAuth Redirect] Error:", errorMsg);
11082
+ logger32.error("[OAuth Redirect] Error:", errorMsg);
10895
11083
  return Response.redirect(new URL(`${errorRedirectUrl}?error=${encodeURIComponent(errorMsg)}`, webRequest.url));
10896
11084
  }
10897
11085
  if (!code || !state) {
10898
- logger30.error("[OAuth Redirect] Missing code or state parameter");
11086
+ logger32.error("[OAuth Redirect] Missing code or state parameter");
10899
11087
  return Response.redirect(new URL(`${errorRedirectUrl}?error=${encodeURIComponent("Invalid OAuth callback")}`, webRequest.url));
10900
11088
  }
10901
11089
  let returnUrl = defaultRedirectUrl;
@@ -10971,7 +11159,7 @@ function createMCPServer(config) {
10971
11159
  frontendUrl.hash = `oauth_callback=${encodeURIComponent(JSON.stringify({ code, state, tokenData }))}`;
10972
11160
  return Response.redirect(frontendUrl);
10973
11161
  } catch (error2) {
10974
- logger30.error("[OAuth Backend Callback] Error:", error2);
11162
+ logger32.error("[OAuth Backend Callback] Error:", error2);
10975
11163
  return Response.redirect(new URL(`${errorRedirectUrl}?error=${encodeURIComponent(error2.message || "Failed to exchange token")}`, webRequest.url));
10976
11164
  }
10977
11165
  } else {
@@ -11190,7 +11378,7 @@ function toSvelteKitHandler(clientOrHandlerOrOptions, _redirectOptions) {
11190
11378
  }
11191
11379
  };
11192
11380
  }
11193
- var SERVER_LOG_CONTEXT2 = "server", logger30, globalServerConfig = null, codeVerifierStorage, POST = async (req, context) => {
11381
+ var SERVER_LOG_CONTEXT2 = "server", logger32, globalServerConfig = null, codeVerifierStorage, POST = async (req, context) => {
11194
11382
  if (!globalServerConfig) {
11195
11383
  return Response.json({ error: "OAuth not configured. Call createMCPServer() in your server initialization file first." }, { status: 500 });
11196
11384
  }
@@ -11238,7 +11426,7 @@ var init_server = __esm(() => {
11238
11426
  init_anthropic();
11239
11427
  init_google();
11240
11428
  init_ai();
11241
- logger30 = createLogger("MCPServer", SERVER_LOG_CONTEXT2);
11429
+ logger32 = createLogger("MCPServer", SERVER_LOG_CONTEXT2);
11242
11430
  codeVerifierStorage = new Map;
11243
11431
  });
11244
11432
 
@@ -11589,7 +11777,7 @@ class OAuthHandler {
11589
11777
  url.searchParams.set("state", authorizeRequest.state);
11590
11778
  url.searchParams.set("code_challenge", authorizeRequest.codeChallenge);
11591
11779
  url.searchParams.set("code_challenge_method", authorizeRequest.codeChallengeMethod);
11592
- const redirectUri = authorizeRequest.redirectUri || providerConfig.redirectUri;
11780
+ const redirectUri = providerConfig.redirectUri;
11593
11781
  if (redirectUri) {
11594
11782
  url.searchParams.set("redirect_uri", redirectUri);
11595
11783
  }
@@ -11701,7 +11889,7 @@ class OAuthHandler {
11701
11889
  tokenType: result.tokenType,
11702
11890
  expiresIn: result.expiresIn,
11703
11891
  expiresAt: result.expiresAt,
11704
- scopes: result.scopes
11892
+ scopes: result.scopes ? result.scopes.flatMap((s) => s.split(" ").filter(Boolean)) : result.scopes
11705
11893
  };
11706
11894
  await this.config.setProviderToken(callbackRequest.provider, tokenData, undefined, context);
11707
11895
  } catch (error) {}
@@ -11751,11 +11939,11 @@ class OAuthHandler {
11751
11939
  try {
11752
11940
  await this.config.removeProviderToken(request.provider, undefined, context);
11753
11941
  } catch (error) {
11754
- logger31.error(`Failed to delete token for ${request.provider} from database via removeProviderToken:`, error);
11942
+ logger33.error(`Failed to delete token for ${request.provider} from database via removeProviderToken:`, error);
11755
11943
  }
11756
11944
  }
11757
11945
  } catch (error) {
11758
- logger31.error(`Failed to extract context for disconnect:`, error);
11946
+ logger33.error(`Failed to extract context for disconnect:`, error);
11759
11947
  }
11760
11948
  }
11761
11949
  const url = new URL("/oauth/disconnect", this.serverUrl);
@@ -11815,10 +12003,10 @@ class OAuthHandler {
11815
12003
  return jsonRpcResponse.result;
11816
12004
  }
11817
12005
  }
11818
- var SERVER_LOG_CONTEXT3 = "server", logger31, MCP_SERVER_URL2 = "https://mcp.integrate.dev/api/v1/mcp";
12006
+ var SERVER_LOG_CONTEXT3 = "server", logger33, MCP_SERVER_URL2 = "https://mcp.integrate.dev/api/v1/mcp";
11819
12007
  var init_base_handler = __esm(() => {
11820
12008
  init_logger();
11821
- logger31 = createLogger("OAuthHandler", SERVER_LOG_CONTEXT3);
12009
+ logger33 = createLogger("OAuthHandler", SERVER_LOG_CONTEXT3);
11822
12010
  });
11823
12011
 
11824
12012
  // src/index.ts
@@ -11831,7 +12019,7 @@ init_nextjs();
11831
12019
  // src/adapters/nextjs-oauth-redirect.ts
11832
12020
  init_logger();
11833
12021
  var SERVER_LOG_CONTEXT4 = "server";
11834
- var logger32 = createLogger("OAuthRedirect", SERVER_LOG_CONTEXT4);
12022
+ var logger34 = createLogger("OAuthRedirect", SERVER_LOG_CONTEXT4);
11835
12023
  function createOAuthRedirectHandler(config) {
11836
12024
  const defaultRedirectUrl = config?.redirectUrl || "/";
11837
12025
  const errorRedirectUrl = config?.errorRedirectUrl || "/auth-error";
@@ -11843,11 +12031,11 @@ function createOAuthRedirectHandler(config) {
11843
12031
  const errorDescription = searchParams.get("error_description");
11844
12032
  if (error) {
11845
12033
  const errorMsg = errorDescription || error;
11846
- logger32.error("[OAuth Redirect] Error:", errorMsg);
12034
+ logger34.error("[OAuth Redirect] Error:", errorMsg);
11847
12035
  return Response.redirect(new URL(`${errorRedirectUrl}?error=${encodeURIComponent(errorMsg)}`, req.url));
11848
12036
  }
11849
12037
  if (!code || !state) {
11850
- logger32.error("[OAuth Redirect] Missing code or state parameter");
12038
+ logger34.error("[OAuth Redirect] Missing code or state parameter");
11851
12039
  return Response.redirect(new URL(`${errorRedirectUrl}?error=${encodeURIComponent("Invalid OAuth callback")}`, req.url));
11852
12040
  }
11853
12041
  let returnUrl = defaultRedirectUrl;
@@ -11927,6 +12115,8 @@ init_intercom();
11927
12115
  init_hubspot();
11928
12116
  init_youtube();
11929
12117
  init_cursor();
12118
+ init_utils2();
12119
+ init_webhooks();
11930
12120
  init_generic();
11931
12121
  init_messages();
11932
12122
  init_http_session();
@@ -11989,6 +12179,7 @@ export {
11989
12179
  youtubeIntegration,
11990
12180
  whatsappIntegration,
11991
12181
  vercelIntegration,
12182
+ validateStepLimit,
11992
12183
  todoistIntegration,
11993
12184
  toWebRequest,
11994
12185
  toTanStackStartHandler,
@@ -12022,6 +12213,7 @@ export {
12022
12213
  gcalIntegration,
12023
12214
  fromNodeHeaders,
12024
12215
  figmaIntegration,
12216
+ deliverWebhooks,
12025
12217
  cursorIntegration,
12026
12218
  createTanStackOAuthHandler,
12027
12219
  createSimpleIntegration,
@@ -12032,6 +12224,7 @@ export {
12032
12224
  clearClientCache,
12033
12225
  calcomIntegration,
12034
12226
  airtableIntegration,
12227
+ WEBHOOK_DELIVERY_TIMEOUT_MS,
12035
12228
  TriggerClient,
12036
12229
  ToolCallError,
12037
12230
  TokenExpiredError,
@@ -12040,6 +12233,7 @@ export {
12040
12233
  OAuthHandler,
12041
12234
  MCPMethod,
12042
12235
  MCPClientBase,
12236
+ MAX_TRIGGER_STEPS,
12043
12237
  IntegrateSDKError,
12044
12238
  HttpSessionTransport,
12045
12239
  ConnectionError,