integrate-sdk 0.8.31 → 0.8.35
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/README.md +60 -0
- package/dist/adapters/auto-routes.js +475 -4
- package/dist/adapters/base-handler.d.ts +2 -1
- package/dist/adapters/base-handler.d.ts.map +1 -1
- package/dist/adapters/index.js +475 -4
- package/dist/adapters/nextjs.d.ts.map +1 -1
- package/dist/adapters/nextjs.js +475 -4
- package/dist/adapters/node.js +475 -4
- package/dist/adapters/svelte-kit.js +475 -4
- package/dist/adapters/tanstack-start.js +475 -4
- package/dist/index.js +464 -4
- package/dist/oauth.js +475 -4
- package/dist/server.js +475 -4
- package/dist/src/adapters/base-handler.d.ts +2 -1
- package/dist/src/adapters/base-handler.d.ts.map +1 -1
- package/dist/src/adapters/nextjs.d.ts.map +1 -1
- package/dist/src/client.d.ts +6 -0
- package/dist/src/client.d.ts.map +1 -1
- package/dist/src/config/types.d.ts +62 -0
- package/dist/src/config/types.d.ts.map +1 -1
- package/dist/src/index.d.ts +3 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/integrations/server-client.d.ts +18 -0
- package/dist/src/integrations/server-client.d.ts.map +1 -1
- package/dist/src/server.d.ts.map +1 -1
- package/dist/src/triggers/client.d.ts +157 -0
- package/dist/src/triggers/client.d.ts.map +1 -0
- package/dist/src/triggers/index.d.ts +10 -0
- package/dist/src/triggers/index.d.ts.map +1 -0
- package/dist/src/triggers/types.d.ts +197 -0
- package/dist/src/triggers/types.d.ts.map +1 -0
- package/dist/src/triggers/utils.d.ts +78 -0
- package/dist/src/triggers/utils.d.ts.map +1 -0
- package/package.json +6 -5
package/dist/index.js
CHANGED
|
@@ -370,6 +370,81 @@ function methodToToolName(methodName, integrationId) {
|
|
|
370
370
|
return `${integrationId}_${snakeCaseMethod}`;
|
|
371
371
|
}
|
|
372
372
|
|
|
373
|
+
// src/triggers/client.ts
|
|
374
|
+
class TriggerClient {
|
|
375
|
+
config;
|
|
376
|
+
constructor(config) {
|
|
377
|
+
this.config = config;
|
|
378
|
+
}
|
|
379
|
+
async create(params) {
|
|
380
|
+
return this.request("POST", "/triggers", params);
|
|
381
|
+
}
|
|
382
|
+
async list(params) {
|
|
383
|
+
let path = "/triggers";
|
|
384
|
+
if (params) {
|
|
385
|
+
const searchParams = new URLSearchParams;
|
|
386
|
+
if (params.status)
|
|
387
|
+
searchParams.set("status", params.status);
|
|
388
|
+
if (params.toolName)
|
|
389
|
+
searchParams.set("toolName", params.toolName);
|
|
390
|
+
if (params.limit !== undefined)
|
|
391
|
+
searchParams.set("limit", params.limit.toString());
|
|
392
|
+
if (params.offset !== undefined)
|
|
393
|
+
searchParams.set("offset", params.offset.toString());
|
|
394
|
+
const query = searchParams.toString();
|
|
395
|
+
if (query)
|
|
396
|
+
path += `?${query}`;
|
|
397
|
+
}
|
|
398
|
+
return this.request("GET", path);
|
|
399
|
+
}
|
|
400
|
+
async get(triggerId) {
|
|
401
|
+
return this.request("GET", `/triggers/${triggerId}`);
|
|
402
|
+
}
|
|
403
|
+
async update(triggerId, params) {
|
|
404
|
+
return this.request("PATCH", `/triggers/${triggerId}`, params);
|
|
405
|
+
}
|
|
406
|
+
async delete(triggerId) {
|
|
407
|
+
await this.request("DELETE", `/triggers/${triggerId}`);
|
|
408
|
+
}
|
|
409
|
+
async pause(triggerId) {
|
|
410
|
+
return this.request("POST", `/triggers/${triggerId}/pause`);
|
|
411
|
+
}
|
|
412
|
+
async resume(triggerId) {
|
|
413
|
+
return this.request("POST", `/triggers/${triggerId}/resume`);
|
|
414
|
+
}
|
|
415
|
+
async run(triggerId) {
|
|
416
|
+
return this.request("POST", `/triggers/${triggerId}/run`);
|
|
417
|
+
}
|
|
418
|
+
async request(method, path, body) {
|
|
419
|
+
const url = this.config.apiBaseUrl ? `${this.config.apiBaseUrl}${this.config.apiRouteBase}${path}` : `${this.config.apiRouteBase}${path}`;
|
|
420
|
+
const options = {
|
|
421
|
+
method,
|
|
422
|
+
headers: {
|
|
423
|
+
"Content-Type": "application/json",
|
|
424
|
+
...this.config.getHeaders()
|
|
425
|
+
}
|
|
426
|
+
};
|
|
427
|
+
if (body !== undefined) {
|
|
428
|
+
options.body = JSON.stringify(body);
|
|
429
|
+
}
|
|
430
|
+
const response = await fetch(url, options);
|
|
431
|
+
if (!response.ok) {
|
|
432
|
+
let errorMessage = `Request failed: ${response.statusText}`;
|
|
433
|
+
try {
|
|
434
|
+
const errorData = await response.json();
|
|
435
|
+
if (errorData.error) {
|
|
436
|
+
errorMessage = typeof errorData.error === "string" ? errorData.error : errorData.error.message || errorMessage;
|
|
437
|
+
}
|
|
438
|
+
} catch {}
|
|
439
|
+
throw new Error(errorMessage);
|
|
440
|
+
}
|
|
441
|
+
if (method === "DELETE" && response.status === 204) {
|
|
442
|
+
return;
|
|
443
|
+
}
|
|
444
|
+
return response.json();
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
|
|
373
448
|
// src/oauth/pkce.ts
|
|
374
449
|
var exports_pkce = {};
|
|
375
450
|
__export(exports_pkce, {
|
|
@@ -1565,6 +1640,7 @@ class MCPClientBase {
|
|
|
1565
1640
|
databaseDetected = false;
|
|
1566
1641
|
oauthCallbackPromise;
|
|
1567
1642
|
server;
|
|
1643
|
+
trigger;
|
|
1568
1644
|
constructor(config) {
|
|
1569
1645
|
this.transport = new HttpSessionTransport({
|
|
1570
1646
|
url: config.serverUrl || MCP_SERVER_URL,
|
|
@@ -1607,6 +1683,10 @@ class MCPClientBase {
|
|
|
1607
1683
|
this.authState.set(provider, { authenticated: false });
|
|
1608
1684
|
}
|
|
1609
1685
|
}
|
|
1686
|
+
const integrationHeaderValue = this.getIntegrationHeaderValue();
|
|
1687
|
+
if (integrationHeaderValue && this.transport.setHeader) {
|
|
1688
|
+
this.transport.setHeader("X-Integrations", integrationHeaderValue);
|
|
1689
|
+
}
|
|
1610
1690
|
const providers = this.integrations.filter((p) => p.oauth).map((p) => p.oauth.provider);
|
|
1611
1691
|
const usingDatabaseCallbacks = !!config.getProviderToken;
|
|
1612
1692
|
if (usingDatabaseCallbacks) {
|
|
@@ -1682,6 +1762,13 @@ class MCPClientBase {
|
|
|
1682
1762
|
this.todoist = this.createIntegrationProxy("todoist");
|
|
1683
1763
|
}
|
|
1684
1764
|
this.server = this.createServerProxy();
|
|
1765
|
+
this.trigger = new TriggerClient({
|
|
1766
|
+
apiRouteBase: this.apiRouteBase,
|
|
1767
|
+
apiBaseUrl: this.apiBaseUrl,
|
|
1768
|
+
getHeaders: () => ({
|
|
1769
|
+
"X-Integrations": this.getIntegrationHeaderValue()
|
|
1770
|
+
})
|
|
1771
|
+
});
|
|
1685
1772
|
this.initializeIntegrations();
|
|
1686
1773
|
}
|
|
1687
1774
|
getDefaultRedirectUri(oauthApiBase, apiBaseUrl) {
|
|
@@ -1711,9 +1798,24 @@ class MCPClientBase {
|
|
|
1711
1798
|
}
|
|
1712
1799
|
});
|
|
1713
1800
|
}
|
|
1801
|
+
getIntegrationHeaderValue() {
|
|
1802
|
+
return this.integrations.map((integration) => integration.id).join(",");
|
|
1803
|
+
}
|
|
1714
1804
|
createServerProxy() {
|
|
1715
1805
|
return new Proxy({}, {
|
|
1716
1806
|
get: (_target, methodName) => {
|
|
1807
|
+
if (methodName === "listConfiguredIntegrations") {
|
|
1808
|
+
return async () => ({
|
|
1809
|
+
integrations: this.integrations.map((integration) => ({
|
|
1810
|
+
id: integration.id,
|
|
1811
|
+
name: integration.name || integration.id,
|
|
1812
|
+
tools: integration.tools,
|
|
1813
|
+
hasOAuth: !!integration.oauth,
|
|
1814
|
+
scopes: integration.oauth?.scopes,
|
|
1815
|
+
provider: integration.oauth?.provider
|
|
1816
|
+
}))
|
|
1817
|
+
});
|
|
1818
|
+
}
|
|
1717
1819
|
return async (args, options) => {
|
|
1718
1820
|
const toolName = methodToToolName(methodName, "");
|
|
1719
1821
|
const finalToolName = toolName.startsWith("_") ? toolName.substring(1) : toolName;
|
|
@@ -1819,6 +1921,10 @@ class MCPClientBase {
|
|
|
1819
1921
|
const headers = {
|
|
1820
1922
|
"Content-Type": "application/json"
|
|
1821
1923
|
};
|
|
1924
|
+
const integrationsHeader = this.getIntegrationHeaderValue();
|
|
1925
|
+
if (integrationsHeader) {
|
|
1926
|
+
headers["X-Integrations"] = integrationsHeader;
|
|
1927
|
+
}
|
|
1822
1928
|
if (provider) {
|
|
1823
1929
|
const tokenData = await this.oauthManager.getProviderToken(provider, undefined, options?.context);
|
|
1824
1930
|
if (tokenData) {
|
|
@@ -2433,7 +2539,8 @@ function createNextOAuthHandler(config) {
|
|
|
2433
2539
|
try {
|
|
2434
2540
|
const body = await req.json();
|
|
2435
2541
|
const authHeader = req.headers.get("authorization");
|
|
2436
|
-
const
|
|
2542
|
+
const integrationsHeader = req.headers.get("x-integrations");
|
|
2543
|
+
const result = await handler.handleToolCall(body, authHeader, integrationsHeader);
|
|
2437
2544
|
return Response.json(result);
|
|
2438
2545
|
} catch (error) {
|
|
2439
2546
|
console.error("[MCP Tool Call] Error:", error);
|
|
@@ -7997,6 +8104,59 @@ var init_ai = __esm(() => {
|
|
|
7997
8104
|
init_google();
|
|
7998
8105
|
});
|
|
7999
8106
|
|
|
8107
|
+
// node_modules/nanoid/index.browser.js
|
|
8108
|
+
var nanoid = (size = 21) => crypto.getRandomValues(new Uint8Array(size)).reduce((id, byte) => {
|
|
8109
|
+
byte &= 63;
|
|
8110
|
+
if (byte < 36) {
|
|
8111
|
+
id += byte.toString(36);
|
|
8112
|
+
} else if (byte < 62) {
|
|
8113
|
+
id += (byte - 26).toString(36).toUpperCase();
|
|
8114
|
+
} else if (byte > 62) {
|
|
8115
|
+
id += "-";
|
|
8116
|
+
} else {
|
|
8117
|
+
id += "_";
|
|
8118
|
+
}
|
|
8119
|
+
return id;
|
|
8120
|
+
}, "");
|
|
8121
|
+
var init_index_browser = () => {};
|
|
8122
|
+
|
|
8123
|
+
// src/triggers/utils.ts
|
|
8124
|
+
var exports_utils = {};
|
|
8125
|
+
__export(exports_utils, {
|
|
8126
|
+
validateStatusTransition: () => validateStatusTransition,
|
|
8127
|
+
generateTriggerId: () => generateTriggerId,
|
|
8128
|
+
extractProviderFromToolName: () => extractProviderFromToolName,
|
|
8129
|
+
calculateHasMore: () => calculateHasMore
|
|
8130
|
+
});
|
|
8131
|
+
function generateTriggerId() {
|
|
8132
|
+
return `trig_${nanoid(12)}`;
|
|
8133
|
+
}
|
|
8134
|
+
function extractProviderFromToolName(toolName) {
|
|
8135
|
+
const parts = toolName.split("_");
|
|
8136
|
+
return parts[0] || toolName;
|
|
8137
|
+
}
|
|
8138
|
+
function validateStatusTransition(currentStatus, targetStatus) {
|
|
8139
|
+
if (targetStatus === "paused" && currentStatus !== "active") {
|
|
8140
|
+
return {
|
|
8141
|
+
valid: false,
|
|
8142
|
+
error: `Cannot pause trigger with status '${currentStatus}'. Only 'active' triggers can be paused.`
|
|
8143
|
+
};
|
|
8144
|
+
}
|
|
8145
|
+
if (targetStatus === "active" && currentStatus !== "paused") {
|
|
8146
|
+
return {
|
|
8147
|
+
valid: false,
|
|
8148
|
+
error: `Cannot resume trigger with status '${currentStatus}'. Only 'paused' triggers can be resumed.`
|
|
8149
|
+
};
|
|
8150
|
+
}
|
|
8151
|
+
return { valid: true };
|
|
8152
|
+
}
|
|
8153
|
+
function calculateHasMore(offset, returnedCount, total) {
|
|
8154
|
+
return offset + returnedCount < total;
|
|
8155
|
+
}
|
|
8156
|
+
var init_utils2 = __esm(() => {
|
|
8157
|
+
init_index_browser();
|
|
8158
|
+
});
|
|
8159
|
+
|
|
8000
8160
|
// src/server.ts
|
|
8001
8161
|
var exports_server = {};
|
|
8002
8162
|
__export(exports_server, {
|
|
@@ -8196,6 +8356,7 @@ function createMCPServer(config) {
|
|
|
8196
8356
|
try {
|
|
8197
8357
|
const body = await webRequest.json();
|
|
8198
8358
|
const authHeader = webRequest.headers.get("authorization");
|
|
8359
|
+
const integrationsHeader = webRequest.headers.get("x-integrations");
|
|
8199
8360
|
const { OAuthHandler: OAuthHandler2 } = await Promise.resolve().then(() => exports_base_handler);
|
|
8200
8361
|
const oauthHandler = new OAuthHandler2({
|
|
8201
8362
|
providers,
|
|
@@ -8205,7 +8366,7 @@ function createMCPServer(config) {
|
|
|
8205
8366
|
removeProviderToken: config.removeProviderToken,
|
|
8206
8367
|
getSessionContext: config.getSessionContext
|
|
8207
8368
|
});
|
|
8208
|
-
const result = await oauthHandler.handleToolCall(body, authHeader);
|
|
8369
|
+
const result = await oauthHandler.handleToolCall(body, authHeader, integrationsHeader);
|
|
8209
8370
|
const response2 = Response.json(result);
|
|
8210
8371
|
if (oauthHandler.hasDatabaseCallbacks()) {
|
|
8211
8372
|
response2.headers.set("X-Integrate-Use-Database", "true");
|
|
@@ -8216,13 +8377,308 @@ function createMCPServer(config) {
|
|
|
8216
8377
|
return Response.json({ error: error.message || "Failed to execute tool call" }, { status: error.statusCode || 500 });
|
|
8217
8378
|
}
|
|
8218
8379
|
}
|
|
8380
|
+
if (segments.length >= 1 && segments[0] === "triggers") {
|
|
8381
|
+
if (!config.triggers) {
|
|
8382
|
+
return Response.json({ error: "Triggers not configured. Add triggers callbacks to createMCPServer config." }, { status: 501 });
|
|
8383
|
+
}
|
|
8384
|
+
try {
|
|
8385
|
+
const context2 = config.getSessionContext ? await config.getSessionContext(webRequest) : undefined;
|
|
8386
|
+
if (segments.length === 1) {
|
|
8387
|
+
if (method === "GET") {
|
|
8388
|
+
const url = new URL(webRequest.url);
|
|
8389
|
+
const params = {
|
|
8390
|
+
status: url.searchParams.get("status"),
|
|
8391
|
+
toolName: url.searchParams.get("toolName") || undefined,
|
|
8392
|
+
limit: url.searchParams.get("limit") ? parseInt(url.searchParams.get("limit")) : undefined,
|
|
8393
|
+
offset: url.searchParams.get("offset") ? parseInt(url.searchParams.get("offset")) : undefined
|
|
8394
|
+
};
|
|
8395
|
+
const callbackResult = await config.triggers.list(params, context2);
|
|
8396
|
+
const { calculateHasMore: calculateHasMore2 } = await Promise.resolve().then(() => (init_utils2(), exports_utils));
|
|
8397
|
+
const offset = params.offset || 0;
|
|
8398
|
+
const hasMore = calculateHasMore2(offset, callbackResult.triggers.length, callbackResult.total);
|
|
8399
|
+
return Response.json({
|
|
8400
|
+
triggers: callbackResult.triggers,
|
|
8401
|
+
total: callbackResult.total,
|
|
8402
|
+
hasMore
|
|
8403
|
+
});
|
|
8404
|
+
} else if (method === "POST") {
|
|
8405
|
+
const body = await webRequest.json();
|
|
8406
|
+
const { generateTriggerId: generateTriggerId2, extractProviderFromToolName: extractProviderFromToolName2 } = await Promise.resolve().then(() => (init_utils2(), exports_utils));
|
|
8407
|
+
const triggerId = generateTriggerId2();
|
|
8408
|
+
const provider = body.toolName ? extractProviderFromToolName2(body.toolName) : undefined;
|
|
8409
|
+
const trigger = {
|
|
8410
|
+
id: triggerId,
|
|
8411
|
+
...body,
|
|
8412
|
+
provider,
|
|
8413
|
+
status: body.status || "active",
|
|
8414
|
+
createdAt: new Date().toISOString(),
|
|
8415
|
+
updatedAt: new Date().toISOString(),
|
|
8416
|
+
runCount: 0
|
|
8417
|
+
};
|
|
8418
|
+
const created = await config.triggers.create(trigger, context2);
|
|
8419
|
+
const schedulerUrl = config.schedulerUrl || config.serverUrl || "https://mcp.integrate.dev";
|
|
8420
|
+
const callbackBaseUrl = process.env.INTEGRATE_URL || (typeof window !== "undefined" ? window.location.origin : "http://localhost:3000");
|
|
8421
|
+
try {
|
|
8422
|
+
await fetch(`${schedulerUrl}/scheduler/register`, {
|
|
8423
|
+
method: "POST",
|
|
8424
|
+
headers: {
|
|
8425
|
+
"Content-Type": "application/json",
|
|
8426
|
+
"X-API-KEY": config.apiKey || ""
|
|
8427
|
+
},
|
|
8428
|
+
body: JSON.stringify({
|
|
8429
|
+
triggerId: created.id,
|
|
8430
|
+
schedule: created.schedule,
|
|
8431
|
+
callbackUrl: `${callbackBaseUrl}/api/integrate/triggers/${created.id}/execute`,
|
|
8432
|
+
completeUrl: `${callbackBaseUrl}/api/integrate/triggers/${created.id}/complete`,
|
|
8433
|
+
metadata: {
|
|
8434
|
+
userId: context2?.userId,
|
|
8435
|
+
provider: created.provider
|
|
8436
|
+
}
|
|
8437
|
+
})
|
|
8438
|
+
});
|
|
8439
|
+
} catch (scheduleError) {
|
|
8440
|
+
console.error("[Trigger] Failed to register with scheduler:", scheduleError);
|
|
8441
|
+
}
|
|
8442
|
+
return Response.json(created, { status: 201 });
|
|
8443
|
+
}
|
|
8444
|
+
} else if (segments.length >= 2) {
|
|
8445
|
+
const triggerId = segments[1];
|
|
8446
|
+
if (!triggerId) {
|
|
8447
|
+
return Response.json({ error: "Trigger ID is required" }, { status: 400 });
|
|
8448
|
+
}
|
|
8449
|
+
const subAction = segments.length > 2 ? segments[2] : undefined;
|
|
8450
|
+
if (subAction === "pause" && method === "POST") {
|
|
8451
|
+
const trigger = await config.triggers.get(triggerId, context2);
|
|
8452
|
+
if (!trigger) {
|
|
8453
|
+
return Response.json({ error: "Trigger not found" }, { status: 404 });
|
|
8454
|
+
}
|
|
8455
|
+
const { validateStatusTransition: validateStatusTransition2 } = await Promise.resolve().then(() => (init_utils2(), exports_utils));
|
|
8456
|
+
const validation = validateStatusTransition2(trigger.status, "paused");
|
|
8457
|
+
if (!validation.valid) {
|
|
8458
|
+
return Response.json({ error: validation.error }, { status: 400 });
|
|
8459
|
+
}
|
|
8460
|
+
const updated = await config.triggers.update(triggerId, {
|
|
8461
|
+
status: "paused",
|
|
8462
|
+
updatedAt: new Date().toISOString()
|
|
8463
|
+
}, context2);
|
|
8464
|
+
const schedulerUrl = config.schedulerUrl || config.serverUrl || "https://mcp.integrate.dev";
|
|
8465
|
+
try {
|
|
8466
|
+
await fetch(`${schedulerUrl}/scheduler/pause`, {
|
|
8467
|
+
method: "POST",
|
|
8468
|
+
headers: {
|
|
8469
|
+
"Content-Type": "application/json",
|
|
8470
|
+
"X-API-KEY": config.apiKey || ""
|
|
8471
|
+
},
|
|
8472
|
+
body: JSON.stringify({ triggerId })
|
|
8473
|
+
});
|
|
8474
|
+
} catch (error) {
|
|
8475
|
+
console.error("[Trigger] Failed to pause in scheduler:", error);
|
|
8476
|
+
}
|
|
8477
|
+
return Response.json(updated);
|
|
8478
|
+
} else if (subAction === "resume" && method === "POST") {
|
|
8479
|
+
const trigger = await config.triggers.get(triggerId, context2);
|
|
8480
|
+
if (!trigger) {
|
|
8481
|
+
return Response.json({ error: "Trigger not found" }, { status: 404 });
|
|
8482
|
+
}
|
|
8483
|
+
const { validateStatusTransition: validateStatusTransition2 } = await Promise.resolve().then(() => (init_utils2(), exports_utils));
|
|
8484
|
+
const validation = validateStatusTransition2(trigger.status, "active");
|
|
8485
|
+
if (!validation.valid) {
|
|
8486
|
+
return Response.json({ error: validation.error }, { status: 400 });
|
|
8487
|
+
}
|
|
8488
|
+
const updated = await config.triggers.update(triggerId, {
|
|
8489
|
+
status: "active",
|
|
8490
|
+
updatedAt: new Date().toISOString()
|
|
8491
|
+
}, context2);
|
|
8492
|
+
const schedulerUrl = config.schedulerUrl || config.serverUrl || "https://mcp.integrate.dev";
|
|
8493
|
+
try {
|
|
8494
|
+
await fetch(`${schedulerUrl}/scheduler/resume`, {
|
|
8495
|
+
method: "POST",
|
|
8496
|
+
headers: {
|
|
8497
|
+
"Content-Type": "application/json",
|
|
8498
|
+
"X-API-KEY": config.apiKey || ""
|
|
8499
|
+
},
|
|
8500
|
+
body: JSON.stringify({ triggerId })
|
|
8501
|
+
});
|
|
8502
|
+
} catch (error) {
|
|
8503
|
+
console.error("[Trigger] Failed to resume in scheduler:", error);
|
|
8504
|
+
}
|
|
8505
|
+
return Response.json(updated);
|
|
8506
|
+
} else if (subAction === "run" && method === "POST") {
|
|
8507
|
+
const trigger = await config.triggers.get(triggerId, context2);
|
|
8508
|
+
if (!trigger) {
|
|
8509
|
+
return Response.json({ error: "Trigger not found" }, { status: 404 });
|
|
8510
|
+
}
|
|
8511
|
+
if (!trigger.provider) {
|
|
8512
|
+
return Response.json({ error: "Trigger has no provider configured" }, { status: 400 });
|
|
8513
|
+
}
|
|
8514
|
+
const providerToken = config.getProviderToken ? await config.getProviderToken(trigger.provider, undefined, context2) : undefined;
|
|
8515
|
+
if (!providerToken) {
|
|
8516
|
+
return Response.json({ error: "No OAuth token available for this trigger" }, { status: 401 });
|
|
8517
|
+
}
|
|
8518
|
+
const { OAuthHandler: OAuthHandler2 } = await Promise.resolve().then(() => exports_base_handler);
|
|
8519
|
+
const oauthHandler = new OAuthHandler2({
|
|
8520
|
+
providers,
|
|
8521
|
+
serverUrl: config.serverUrl,
|
|
8522
|
+
apiKey: config.apiKey,
|
|
8523
|
+
setProviderToken: config.setProviderToken,
|
|
8524
|
+
removeProviderToken: config.removeProviderToken,
|
|
8525
|
+
getSessionContext: config.getSessionContext
|
|
8526
|
+
});
|
|
8527
|
+
const startTime = Date.now();
|
|
8528
|
+
try {
|
|
8529
|
+
const result = await oauthHandler.handleToolCall({ name: trigger.toolName, arguments: trigger.toolArguments }, `Bearer ${providerToken.accessToken}`, null);
|
|
8530
|
+
const duration = Date.now() - startTime;
|
|
8531
|
+
const executionResult = {
|
|
8532
|
+
success: true,
|
|
8533
|
+
result,
|
|
8534
|
+
executedAt: new Date().toISOString(),
|
|
8535
|
+
duration
|
|
8536
|
+
};
|
|
8537
|
+
await config.triggers.update(triggerId, {
|
|
8538
|
+
lastRunAt: executionResult.executedAt,
|
|
8539
|
+
runCount: (trigger.runCount || 0) + 1,
|
|
8540
|
+
lastResult: result,
|
|
8541
|
+
lastError: undefined
|
|
8542
|
+
}, context2);
|
|
8543
|
+
return Response.json(executionResult);
|
|
8544
|
+
} catch (error) {
|
|
8545
|
+
const duration = Date.now() - startTime;
|
|
8546
|
+
const executionResult = {
|
|
8547
|
+
success: false,
|
|
8548
|
+
error: error.message || "Tool execution failed",
|
|
8549
|
+
executedAt: new Date().toISOString(),
|
|
8550
|
+
duration
|
|
8551
|
+
};
|
|
8552
|
+
await config.triggers.update(triggerId, {
|
|
8553
|
+
lastRunAt: executionResult.executedAt,
|
|
8554
|
+
runCount: (trigger.runCount || 0) + 1,
|
|
8555
|
+
lastError: error.message,
|
|
8556
|
+
status: "failed"
|
|
8557
|
+
}, context2);
|
|
8558
|
+
return Response.json(executionResult, { status: 500 });
|
|
8559
|
+
}
|
|
8560
|
+
} else if (subAction === "execute" && method === "GET") {
|
|
8561
|
+
const apiKey = webRequest.headers.get("x-api-key");
|
|
8562
|
+
if (!apiKey || apiKey !== config.apiKey) {
|
|
8563
|
+
return Response.json({ error: "Unauthorized" }, { status: 401 });
|
|
8564
|
+
}
|
|
8565
|
+
const trigger = await config.triggers.get(triggerId, context2);
|
|
8566
|
+
if (!trigger) {
|
|
8567
|
+
return Response.json({ error: "Trigger not found" }, { status: 404 });
|
|
8568
|
+
}
|
|
8569
|
+
if (!trigger.provider) {
|
|
8570
|
+
return Response.json({ error: "Trigger has no provider configured" }, { status: 400 });
|
|
8571
|
+
}
|
|
8572
|
+
const providerToken = config.getProviderToken ? await config.getProviderToken(trigger.provider, undefined, context2) : undefined;
|
|
8573
|
+
if (!providerToken) {
|
|
8574
|
+
return Response.json({ error: "No OAuth token available for this trigger" }, { status: 401 });
|
|
8575
|
+
}
|
|
8576
|
+
return Response.json({
|
|
8577
|
+
trigger: {
|
|
8578
|
+
id: trigger.id,
|
|
8579
|
+
toolName: trigger.toolName,
|
|
8580
|
+
toolArguments: trigger.toolArguments,
|
|
8581
|
+
provider: trigger.provider
|
|
8582
|
+
},
|
|
8583
|
+
accessToken: providerToken.accessToken,
|
|
8584
|
+
tokenType: providerToken.tokenType || "Bearer"
|
|
8585
|
+
});
|
|
8586
|
+
} else if (subAction === "complete" && method === "POST") {
|
|
8587
|
+
const apiKey = webRequest.headers.get("x-api-key");
|
|
8588
|
+
if (!apiKey || apiKey !== config.apiKey) {
|
|
8589
|
+
return Response.json({ error: "Unauthorized" }, { status: 401 });
|
|
8590
|
+
}
|
|
8591
|
+
const body = await webRequest.json();
|
|
8592
|
+
const trigger = await config.triggers.get(triggerId, context2);
|
|
8593
|
+
if (!trigger) {
|
|
8594
|
+
return Response.json({ error: "Trigger not found" }, { status: 404 });
|
|
8595
|
+
}
|
|
8596
|
+
const updates = {
|
|
8597
|
+
lastRunAt: body.executedAt,
|
|
8598
|
+
runCount: (trigger.runCount || 0) + 1
|
|
8599
|
+
};
|
|
8600
|
+
if (body.success) {
|
|
8601
|
+
updates.lastResult = body.result;
|
|
8602
|
+
updates.lastError = undefined;
|
|
8603
|
+
if (trigger.schedule.type === "once") {
|
|
8604
|
+
updates.status = "completed";
|
|
8605
|
+
}
|
|
8606
|
+
} else {
|
|
8607
|
+
updates.lastError = body.error;
|
|
8608
|
+
updates.status = "failed";
|
|
8609
|
+
}
|
|
8610
|
+
await config.triggers.update(triggerId, updates, context2);
|
|
8611
|
+
return Response.json({ success: true });
|
|
8612
|
+
} else if (!subAction && method === "GET") {
|
|
8613
|
+
const trigger = await config.triggers.get(triggerId, context2);
|
|
8614
|
+
if (!trigger) {
|
|
8615
|
+
return Response.json({ error: "Trigger not found" }, { status: 404 });
|
|
8616
|
+
}
|
|
8617
|
+
return Response.json(trigger);
|
|
8618
|
+
} else if (!subAction && method === "PATCH") {
|
|
8619
|
+
const body = await webRequest.json();
|
|
8620
|
+
const trigger = await config.triggers.get(triggerId, context2);
|
|
8621
|
+
if (!trigger) {
|
|
8622
|
+
return Response.json({ error: "Trigger not found" }, { status: 404 });
|
|
8623
|
+
}
|
|
8624
|
+
const updates = {
|
|
8625
|
+
...body,
|
|
8626
|
+
updatedAt: new Date().toISOString()
|
|
8627
|
+
};
|
|
8628
|
+
const updated = await config.triggers.update(triggerId, updates, context2);
|
|
8629
|
+
if (body.schedule) {
|
|
8630
|
+
const schedulerUrl = config.schedulerUrl || config.serverUrl || "https://mcp.integrate.dev";
|
|
8631
|
+
try {
|
|
8632
|
+
await fetch(`${schedulerUrl}/scheduler/update`, {
|
|
8633
|
+
method: "POST",
|
|
8634
|
+
headers: {
|
|
8635
|
+
"Content-Type": "application/json",
|
|
8636
|
+
"X-API-KEY": config.apiKey || ""
|
|
8637
|
+
},
|
|
8638
|
+
body: JSON.stringify({
|
|
8639
|
+
triggerId,
|
|
8640
|
+
schedule: body.schedule
|
|
8641
|
+
})
|
|
8642
|
+
});
|
|
8643
|
+
} catch (error) {
|
|
8644
|
+
console.error("[Trigger] Failed to update scheduler:", error);
|
|
8645
|
+
}
|
|
8646
|
+
}
|
|
8647
|
+
return Response.json(updated);
|
|
8648
|
+
} else if (!subAction && method === "DELETE") {
|
|
8649
|
+
await config.triggers.delete(triggerId, context2);
|
|
8650
|
+
const schedulerUrl = config.schedulerUrl || config.serverUrl || "https://mcp.integrate.dev";
|
|
8651
|
+
try {
|
|
8652
|
+
await fetch(`${schedulerUrl}/scheduler/unregister`, {
|
|
8653
|
+
method: "POST",
|
|
8654
|
+
headers: {
|
|
8655
|
+
"Content-Type": "application/json",
|
|
8656
|
+
"X-API-KEY": config.apiKey || ""
|
|
8657
|
+
},
|
|
8658
|
+
body: JSON.stringify({ triggerId })
|
|
8659
|
+
});
|
|
8660
|
+
} catch (error) {
|
|
8661
|
+
console.error("[Trigger] Failed to unregister from scheduler:", error);
|
|
8662
|
+
}
|
|
8663
|
+
return new Response(null, { status: 204 });
|
|
8664
|
+
}
|
|
8665
|
+
}
|
|
8666
|
+
return Response.json({ error: "Invalid trigger route or method" }, { status: 404 });
|
|
8667
|
+
} catch (error) {
|
|
8668
|
+
console.error("[Trigger] Error:", error);
|
|
8669
|
+
return Response.json({ error: error.message || "Failed to process trigger request" }, { status: error.statusCode || 500 });
|
|
8670
|
+
}
|
|
8671
|
+
}
|
|
8219
8672
|
if (segments.length > 0) {
|
|
8220
|
-
if (segments.length === 2 && segments[0] !== "oauth") {
|
|
8673
|
+
if (segments.length === 2 && segments[0] !== "oauth" && segments[0] !== "triggers") {
|
|
8221
8674
|
return Response.json({ error: `Invalid route: /${segments.join("/")}` }, { status: 404 });
|
|
8222
8675
|
}
|
|
8223
8676
|
if (segments.length === 1 && segments[0] === "mcp") {
|
|
8224
8677
|
return Response.json({ error: `Method ${method} not allowed for /mcp route. Use POST.` }, { status: 405 });
|
|
8225
8678
|
}
|
|
8679
|
+
if (segments.length >= 1 && segments[0] === "triggers") {
|
|
8680
|
+
return Response.json({ error: `Invalid trigger route or method` }, { status: 404 });
|
|
8681
|
+
}
|
|
8226
8682
|
}
|
|
8227
8683
|
if (method === "GET" && action === "callback") {
|
|
8228
8684
|
const url = new URL(webRequest.url);
|
|
@@ -9104,7 +9560,7 @@ class OAuthHandler {
|
|
|
9104
9560
|
const data = await response.json();
|
|
9105
9561
|
return data;
|
|
9106
9562
|
}
|
|
9107
|
-
async handleToolCall(request, authHeader) {
|
|
9563
|
+
async handleToolCall(request, authHeader, integrationsHeader) {
|
|
9108
9564
|
const url = this.serverUrl;
|
|
9109
9565
|
const headers = this.getHeaders({
|
|
9110
9566
|
"Content-Type": "application/json"
|
|
@@ -9112,6 +9568,9 @@ class OAuthHandler {
|
|
|
9112
9568
|
if (authHeader && authHeader.startsWith("Bearer ")) {
|
|
9113
9569
|
headers["Authorization"] = authHeader;
|
|
9114
9570
|
}
|
|
9571
|
+
if (integrationsHeader) {
|
|
9572
|
+
headers["X-Integrations"] = integrationsHeader;
|
|
9573
|
+
}
|
|
9115
9574
|
const jsonRpcRequest = {
|
|
9116
9575
|
jsonrpc: "2.0",
|
|
9117
9576
|
id: Date.now() + Math.random(),
|
|
@@ -9325,6 +9784,7 @@ export {
|
|
|
9325
9784
|
clearClientCache,
|
|
9326
9785
|
calcomIntegration,
|
|
9327
9786
|
airtableIntegration,
|
|
9787
|
+
TriggerClient,
|
|
9328
9788
|
ToolCallError,
|
|
9329
9789
|
TokenExpiredError,
|
|
9330
9790
|
OAuthWindowManager,
|