integrate-sdk 0.6.9 → 0.7.1
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/adapters/auto-routes.js +36 -2
- package/dist/adapters/base-handler.js +36 -2
- package/dist/adapters/nextjs.js +149 -98
- package/dist/adapters/node.js +36 -2
- package/dist/adapters/solid-start.js +236 -158
- package/dist/adapters/svelte-kit.js +236 -158
- package/dist/index.js +258 -157
- package/dist/oauth.js +40 -1
- package/dist/server.js +258 -158
- package/dist/src/adapters/base-handler.d.ts +34 -0
- package/dist/src/adapters/base-handler.d.ts.map +1 -1
- package/dist/src/adapters/nextjs.d.ts +26 -0
- 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 +18 -0
- package/dist/src/config/types.d.ts.map +1 -1
- package/dist/src/server.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -244,6 +244,176 @@ function base64UrlDecode(str) {
|
|
|
244
244
|
}
|
|
245
245
|
}
|
|
246
246
|
|
|
247
|
+
// src/adapters/base-handler.ts
|
|
248
|
+
var exports_base_handler = {};
|
|
249
|
+
__export(exports_base_handler, {
|
|
250
|
+
OAuthHandler: () => OAuthHandler
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
class OAuthHandler {
|
|
254
|
+
config;
|
|
255
|
+
serverUrl;
|
|
256
|
+
apiKey;
|
|
257
|
+
constructor(config) {
|
|
258
|
+
this.config = config;
|
|
259
|
+
if (!config || !config.providers) {
|
|
260
|
+
throw new Error("OAuthHandler requires a valid config with providers");
|
|
261
|
+
}
|
|
262
|
+
this.serverUrl = config.serverUrl || MCP_SERVER_URL2;
|
|
263
|
+
this.apiKey = config.apiKey;
|
|
264
|
+
}
|
|
265
|
+
getHeaders(additionalHeaders) {
|
|
266
|
+
const headers = {
|
|
267
|
+
...additionalHeaders
|
|
268
|
+
};
|
|
269
|
+
if (this.apiKey) {
|
|
270
|
+
headers["X-API-KEY"] = this.apiKey;
|
|
271
|
+
}
|
|
272
|
+
return headers;
|
|
273
|
+
}
|
|
274
|
+
async handleAuthorize(request) {
|
|
275
|
+
const providerConfig = this.config.providers[request.provider];
|
|
276
|
+
if (!providerConfig) {
|
|
277
|
+
throw new Error(`Provider ${request.provider} not configured. Add OAuth credentials to your API route configuration.`);
|
|
278
|
+
}
|
|
279
|
+
if (!providerConfig.clientId || !providerConfig.clientSecret) {
|
|
280
|
+
throw new Error(`Missing OAuth credentials for ${request.provider}. Check your environment variables.`);
|
|
281
|
+
}
|
|
282
|
+
const url = new URL("/oauth/authorize", this.serverUrl);
|
|
283
|
+
url.searchParams.set("provider", request.provider);
|
|
284
|
+
url.searchParams.set("client_id", providerConfig.clientId);
|
|
285
|
+
url.searchParams.set("client_secret", providerConfig.clientSecret);
|
|
286
|
+
url.searchParams.set("scope", request.scopes.join(","));
|
|
287
|
+
url.searchParams.set("state", request.state);
|
|
288
|
+
url.searchParams.set("code_challenge", request.codeChallenge);
|
|
289
|
+
url.searchParams.set("code_challenge_method", request.codeChallengeMethod);
|
|
290
|
+
const redirectUri = request.redirectUri || providerConfig.redirectUri;
|
|
291
|
+
if (redirectUri) {
|
|
292
|
+
url.searchParams.set("redirect_uri", redirectUri);
|
|
293
|
+
}
|
|
294
|
+
const response = await fetch(url.toString(), {
|
|
295
|
+
method: "GET",
|
|
296
|
+
headers: this.getHeaders()
|
|
297
|
+
});
|
|
298
|
+
if (!response.ok) {
|
|
299
|
+
const error = await response.text();
|
|
300
|
+
throw new Error(`MCP server failed to generate authorization URL: ${error}`);
|
|
301
|
+
}
|
|
302
|
+
const data = await response.json();
|
|
303
|
+
return data;
|
|
304
|
+
}
|
|
305
|
+
async handleCallback(request) {
|
|
306
|
+
const providerConfig = this.config.providers[request.provider];
|
|
307
|
+
if (!providerConfig) {
|
|
308
|
+
throw new Error(`Provider ${request.provider} not configured. Add OAuth credentials to your API route configuration.`);
|
|
309
|
+
}
|
|
310
|
+
if (!providerConfig.clientId || !providerConfig.clientSecret) {
|
|
311
|
+
throw new Error(`Missing OAuth credentials for ${request.provider}. Check your environment variables.`);
|
|
312
|
+
}
|
|
313
|
+
const url = new URL("/oauth/callback", this.serverUrl);
|
|
314
|
+
const response = await fetch(url.toString(), {
|
|
315
|
+
method: "POST",
|
|
316
|
+
headers: this.getHeaders({
|
|
317
|
+
"Content-Type": "application/json"
|
|
318
|
+
}),
|
|
319
|
+
body: JSON.stringify({
|
|
320
|
+
provider: request.provider,
|
|
321
|
+
code: request.code,
|
|
322
|
+
code_verifier: request.codeVerifier,
|
|
323
|
+
state: request.state,
|
|
324
|
+
client_id: providerConfig.clientId,
|
|
325
|
+
client_secret: providerConfig.clientSecret,
|
|
326
|
+
redirect_uri: providerConfig.redirectUri
|
|
327
|
+
})
|
|
328
|
+
});
|
|
329
|
+
if (!response.ok) {
|
|
330
|
+
const error = await response.text();
|
|
331
|
+
throw new Error(`MCP server failed to exchange authorization code: ${error}`);
|
|
332
|
+
}
|
|
333
|
+
const data = await response.json();
|
|
334
|
+
return data;
|
|
335
|
+
}
|
|
336
|
+
async handleStatus(provider, accessToken) {
|
|
337
|
+
const url = new URL("/oauth/status", this.serverUrl);
|
|
338
|
+
url.searchParams.set("provider", provider);
|
|
339
|
+
const response = await fetch(url.toString(), {
|
|
340
|
+
method: "GET",
|
|
341
|
+
headers: this.getHeaders({
|
|
342
|
+
Authorization: `Bearer ${accessToken}`
|
|
343
|
+
})
|
|
344
|
+
});
|
|
345
|
+
if (!response.ok) {
|
|
346
|
+
if (response.status === 401) {
|
|
347
|
+
return {
|
|
348
|
+
authorized: false
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
const error = await response.text();
|
|
352
|
+
throw new Error(`MCP server failed to check authorization status: ${error}`);
|
|
353
|
+
}
|
|
354
|
+
const data = await response.json();
|
|
355
|
+
return data;
|
|
356
|
+
}
|
|
357
|
+
async handleDisconnect(request, accessToken) {
|
|
358
|
+
if (!accessToken) {
|
|
359
|
+
throw new Error("No access token provided. Cannot disconnect provider.");
|
|
360
|
+
}
|
|
361
|
+
const url = new URL("/oauth/disconnect", this.serverUrl);
|
|
362
|
+
const response = await fetch(url.toString(), {
|
|
363
|
+
method: "POST",
|
|
364
|
+
headers: this.getHeaders({
|
|
365
|
+
"Content-Type": "application/json",
|
|
366
|
+
Authorization: `Bearer ${accessToken}`
|
|
367
|
+
}),
|
|
368
|
+
body: JSON.stringify({
|
|
369
|
+
provider: request.provider
|
|
370
|
+
})
|
|
371
|
+
});
|
|
372
|
+
if (!response.ok) {
|
|
373
|
+
const error = await response.text();
|
|
374
|
+
throw new Error(`MCP server failed to disconnect provider: ${error}`);
|
|
375
|
+
}
|
|
376
|
+
const data = await response.json();
|
|
377
|
+
return data;
|
|
378
|
+
}
|
|
379
|
+
async handleToolCall(request, authHeader) {
|
|
380
|
+
const url = new URL("/tools/call", this.serverUrl);
|
|
381
|
+
const headers = this.getHeaders({
|
|
382
|
+
"Content-Type": "application/json"
|
|
383
|
+
});
|
|
384
|
+
if (authHeader && authHeader.startsWith("Bearer ")) {
|
|
385
|
+
headers["Authorization"] = authHeader;
|
|
386
|
+
}
|
|
387
|
+
const jsonRpcRequest = {
|
|
388
|
+
jsonrpc: "2.0",
|
|
389
|
+
id: Date.now() + Math.random(),
|
|
390
|
+
method: "tools/call",
|
|
391
|
+
params: {
|
|
392
|
+
name: request.name,
|
|
393
|
+
arguments: request.arguments || {}
|
|
394
|
+
}
|
|
395
|
+
};
|
|
396
|
+
const response = await fetch(url.toString(), {
|
|
397
|
+
method: "POST",
|
|
398
|
+
headers,
|
|
399
|
+
body: JSON.stringify(jsonRpcRequest)
|
|
400
|
+
});
|
|
401
|
+
if (!response.ok) {
|
|
402
|
+
const error = await response.text();
|
|
403
|
+
throw new Error(`MCP server failed to execute tool call: ${error}`);
|
|
404
|
+
}
|
|
405
|
+
const jsonRpcResponse = await response.json();
|
|
406
|
+
if (jsonRpcResponse.error) {
|
|
407
|
+
const error = new Error(jsonRpcResponse.error.message || "Tool call failed");
|
|
408
|
+
error.code = jsonRpcResponse.error.code;
|
|
409
|
+
error.data = jsonRpcResponse.error.data;
|
|
410
|
+
throw error;
|
|
411
|
+
}
|
|
412
|
+
return jsonRpcResponse.result;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
var MCP_SERVER_URL2 = "https://mcp.integrate.dev/api/v1/mcp";
|
|
416
|
+
|
|
247
417
|
// src/protocol/jsonrpc.ts
|
|
248
418
|
function parseMessage(message) {
|
|
249
419
|
try {
|
|
@@ -1014,6 +1184,7 @@ class MCPClient {
|
|
|
1014
1184
|
connecting = null;
|
|
1015
1185
|
oauthManager;
|
|
1016
1186
|
eventEmitter = new SimpleEventEmitter;
|
|
1187
|
+
apiRouteBase;
|
|
1017
1188
|
github;
|
|
1018
1189
|
gmail;
|
|
1019
1190
|
server;
|
|
@@ -1025,6 +1196,7 @@ class MCPClient {
|
|
|
1025
1196
|
});
|
|
1026
1197
|
const oauthApiBase = config.oauthApiBase || "/api/integrate/oauth";
|
|
1027
1198
|
const defaultRedirectUri = this.getDefaultRedirectUri(oauthApiBase);
|
|
1199
|
+
this.apiRouteBase = config.apiRouteBase || "/api/integrate";
|
|
1028
1200
|
this.plugins = config.plugins.map((plugin) => {
|
|
1029
1201
|
if (plugin.oauth && !plugin.oauth.redirectUri) {
|
|
1030
1202
|
return {
|
|
@@ -1116,12 +1288,8 @@ class MCPClient {
|
|
|
1116
1288
|
if (!this.availableTools.has(name)) {
|
|
1117
1289
|
throw new Error(`Tool "${name}" is not available on the server. Available tools: ${Array.from(this.availableTools.keys()).join(", ")}`);
|
|
1118
1290
|
}
|
|
1119
|
-
const params = {
|
|
1120
|
-
name,
|
|
1121
|
-
arguments: args
|
|
1122
|
-
};
|
|
1123
1291
|
try {
|
|
1124
|
-
const response = await this.
|
|
1292
|
+
const response = await this.callToolThroughHandler(name, args);
|
|
1125
1293
|
return response;
|
|
1126
1294
|
} catch (error) {
|
|
1127
1295
|
const parsedError = parseServerError(error, { toolName: name });
|
|
@@ -1180,18 +1348,58 @@ class MCPClient {
|
|
|
1180
1348
|
if (!this.availableTools.has(name)) {
|
|
1181
1349
|
throw new Error(`Tool "${name}" is not available on the server. Available tools: ${Array.from(this.availableTools.keys()).join(", ")}`);
|
|
1182
1350
|
}
|
|
1183
|
-
const params = {
|
|
1184
|
-
name,
|
|
1185
|
-
arguments: args
|
|
1186
|
-
};
|
|
1187
1351
|
try {
|
|
1188
|
-
const response = await this.
|
|
1352
|
+
const response = await this.callToolThroughHandler(name, args);
|
|
1189
1353
|
return response;
|
|
1190
1354
|
} catch (error) {
|
|
1191
1355
|
const parsedError = parseServerError(error, { toolName: name });
|
|
1192
1356
|
throw parsedError;
|
|
1193
1357
|
}
|
|
1194
1358
|
}
|
|
1359
|
+
async callToolThroughHandler(name, args, provider) {
|
|
1360
|
+
const url = `${this.apiRouteBase}/mcp`;
|
|
1361
|
+
const headers = {
|
|
1362
|
+
"Content-Type": "application/json"
|
|
1363
|
+
};
|
|
1364
|
+
if (provider) {
|
|
1365
|
+
const tokenData = this.oauthManager.getProviderToken(provider);
|
|
1366
|
+
if (tokenData) {
|
|
1367
|
+
headers["Authorization"] = `Bearer ${tokenData.accessToken}`;
|
|
1368
|
+
}
|
|
1369
|
+
}
|
|
1370
|
+
const response = await fetch(url, {
|
|
1371
|
+
method: "POST",
|
|
1372
|
+
headers,
|
|
1373
|
+
body: JSON.stringify({
|
|
1374
|
+
name,
|
|
1375
|
+
arguments: args
|
|
1376
|
+
})
|
|
1377
|
+
});
|
|
1378
|
+
if (!response.ok) {
|
|
1379
|
+
let errorMessage = `Request failed: ${response.statusText}`;
|
|
1380
|
+
const error = new Error(errorMessage);
|
|
1381
|
+
error.statusCode = response.status;
|
|
1382
|
+
try {
|
|
1383
|
+
const errorData = await response.json();
|
|
1384
|
+
if (errorData.error) {
|
|
1385
|
+
errorMessage = typeof errorData.error === "string" ? errorData.error : errorData.error.message || errorMessage;
|
|
1386
|
+
error.message = errorMessage;
|
|
1387
|
+
}
|
|
1388
|
+
if (errorData.code) {
|
|
1389
|
+
error.code = errorData.code;
|
|
1390
|
+
}
|
|
1391
|
+
if (errorData.data) {
|
|
1392
|
+
error.data = errorData.data;
|
|
1393
|
+
}
|
|
1394
|
+
if (errorData.error && typeof errorData.error === "object") {
|
|
1395
|
+
error.jsonrpcError = errorData.error;
|
|
1396
|
+
}
|
|
1397
|
+
} catch {}
|
|
1398
|
+
throw error;
|
|
1399
|
+
}
|
|
1400
|
+
const result = await response.json();
|
|
1401
|
+
return result;
|
|
1402
|
+
}
|
|
1195
1403
|
async callToolWithRetry(name, args, retryCount = 0) {
|
|
1196
1404
|
if (!this.initialized) {
|
|
1197
1405
|
throw new Error("Client not initialized. Call connect() first.");
|
|
@@ -1203,35 +1411,24 @@ class MCPClient {
|
|
|
1203
1411
|
throw new Error(`Tool "${name}" is not available on the server. Available tools: ${Array.from(this.availableTools.keys()).join(", ")}`);
|
|
1204
1412
|
}
|
|
1205
1413
|
const provider = this.getProviderForTool(name);
|
|
1206
|
-
if (provider) {
|
|
1207
|
-
const tokenData = this.oauthManager.getProviderToken(provider);
|
|
1208
|
-
if (tokenData) {
|
|
1209
|
-
this.transport.setHeader("Authorization", `Bearer ${tokenData.accessToken}`);
|
|
1210
|
-
}
|
|
1211
|
-
}
|
|
1212
|
-
const params = {
|
|
1213
|
-
name,
|
|
1214
|
-
arguments: args
|
|
1215
|
-
};
|
|
1216
1414
|
try {
|
|
1217
|
-
const response = await this.
|
|
1415
|
+
const response = await this.callToolThroughHandler(name, args, provider);
|
|
1218
1416
|
if (provider) {
|
|
1219
1417
|
this.authState.set(provider, { authenticated: true });
|
|
1220
1418
|
}
|
|
1221
1419
|
return response;
|
|
1222
1420
|
} catch (error) {
|
|
1223
|
-
const
|
|
1224
|
-
const parsedError = parseServerError(error, { toolName: name, provider: provider2 });
|
|
1421
|
+
const parsedError = parseServerError(error, { toolName: name, provider });
|
|
1225
1422
|
if (isAuthError(parsedError) && retryCount < this.maxReauthRetries) {
|
|
1226
|
-
if (
|
|
1227
|
-
this.authState.set(
|
|
1423
|
+
if (provider) {
|
|
1424
|
+
this.authState.set(provider, {
|
|
1228
1425
|
authenticated: false,
|
|
1229
1426
|
lastError: parsedError
|
|
1230
1427
|
});
|
|
1231
1428
|
}
|
|
1232
|
-
if (this.onReauthRequired &&
|
|
1429
|
+
if (this.onReauthRequired && provider) {
|
|
1233
1430
|
const reauthSuccess = await this.onReauthRequired({
|
|
1234
|
-
provider
|
|
1431
|
+
provider,
|
|
1235
1432
|
error: parsedError,
|
|
1236
1433
|
toolName: name
|
|
1237
1434
|
});
|
|
@@ -1555,136 +1752,6 @@ async function clearClientCache() {
|
|
|
1555
1752
|
}
|
|
1556
1753
|
}));
|
|
1557
1754
|
}
|
|
1558
|
-
// src/adapters/base-handler.ts
|
|
1559
|
-
var MCP_SERVER_URL2 = "https://mcp.integrate.dev/api/v1/mcp";
|
|
1560
|
-
|
|
1561
|
-
class OAuthHandler {
|
|
1562
|
-
config;
|
|
1563
|
-
serverUrl;
|
|
1564
|
-
apiKey;
|
|
1565
|
-
constructor(config) {
|
|
1566
|
-
this.config = config;
|
|
1567
|
-
if (!config || !config.providers) {
|
|
1568
|
-
throw new Error("OAuthHandler requires a valid config with providers");
|
|
1569
|
-
}
|
|
1570
|
-
this.serverUrl = config.serverUrl || MCP_SERVER_URL2;
|
|
1571
|
-
this.apiKey = config.apiKey;
|
|
1572
|
-
}
|
|
1573
|
-
getHeaders(additionalHeaders) {
|
|
1574
|
-
const headers = {
|
|
1575
|
-
...additionalHeaders
|
|
1576
|
-
};
|
|
1577
|
-
if (this.apiKey) {
|
|
1578
|
-
headers["X-API-KEY"] = this.apiKey;
|
|
1579
|
-
}
|
|
1580
|
-
return headers;
|
|
1581
|
-
}
|
|
1582
|
-
async handleAuthorize(request) {
|
|
1583
|
-
const providerConfig = this.config.providers[request.provider];
|
|
1584
|
-
if (!providerConfig) {
|
|
1585
|
-
throw new Error(`Provider ${request.provider} not configured. Add OAuth credentials to your API route configuration.`);
|
|
1586
|
-
}
|
|
1587
|
-
if (!providerConfig.clientId || !providerConfig.clientSecret) {
|
|
1588
|
-
throw new Error(`Missing OAuth credentials for ${request.provider}. Check your environment variables.`);
|
|
1589
|
-
}
|
|
1590
|
-
const url = new URL("/oauth/authorize", this.serverUrl);
|
|
1591
|
-
url.searchParams.set("provider", request.provider);
|
|
1592
|
-
url.searchParams.set("client_id", providerConfig.clientId);
|
|
1593
|
-
url.searchParams.set("client_secret", providerConfig.clientSecret);
|
|
1594
|
-
url.searchParams.set("scope", request.scopes.join(","));
|
|
1595
|
-
url.searchParams.set("state", request.state);
|
|
1596
|
-
url.searchParams.set("code_challenge", request.codeChallenge);
|
|
1597
|
-
url.searchParams.set("code_challenge_method", request.codeChallengeMethod);
|
|
1598
|
-
const redirectUri = request.redirectUri || providerConfig.redirectUri;
|
|
1599
|
-
if (redirectUri) {
|
|
1600
|
-
url.searchParams.set("redirect_uri", redirectUri);
|
|
1601
|
-
}
|
|
1602
|
-
const response = await fetch(url.toString(), {
|
|
1603
|
-
method: "GET",
|
|
1604
|
-
headers: this.getHeaders()
|
|
1605
|
-
});
|
|
1606
|
-
if (!response.ok) {
|
|
1607
|
-
const error = await response.text();
|
|
1608
|
-
throw new Error(`MCP server failed to generate authorization URL: ${error}`);
|
|
1609
|
-
}
|
|
1610
|
-
const data = await response.json();
|
|
1611
|
-
return data;
|
|
1612
|
-
}
|
|
1613
|
-
async handleCallback(request) {
|
|
1614
|
-
const providerConfig = this.config.providers[request.provider];
|
|
1615
|
-
if (!providerConfig) {
|
|
1616
|
-
throw new Error(`Provider ${request.provider} not configured. Add OAuth credentials to your API route configuration.`);
|
|
1617
|
-
}
|
|
1618
|
-
if (!providerConfig.clientId || !providerConfig.clientSecret) {
|
|
1619
|
-
throw new Error(`Missing OAuth credentials for ${request.provider}. Check your environment variables.`);
|
|
1620
|
-
}
|
|
1621
|
-
const url = new URL("/oauth/callback", this.serverUrl);
|
|
1622
|
-
const response = await fetch(url.toString(), {
|
|
1623
|
-
method: "POST",
|
|
1624
|
-
headers: this.getHeaders({
|
|
1625
|
-
"Content-Type": "application/json"
|
|
1626
|
-
}),
|
|
1627
|
-
body: JSON.stringify({
|
|
1628
|
-
provider: request.provider,
|
|
1629
|
-
code: request.code,
|
|
1630
|
-
code_verifier: request.codeVerifier,
|
|
1631
|
-
state: request.state,
|
|
1632
|
-
client_id: providerConfig.clientId,
|
|
1633
|
-
client_secret: providerConfig.clientSecret,
|
|
1634
|
-
redirect_uri: providerConfig.redirectUri
|
|
1635
|
-
})
|
|
1636
|
-
});
|
|
1637
|
-
if (!response.ok) {
|
|
1638
|
-
const error = await response.text();
|
|
1639
|
-
throw new Error(`MCP server failed to exchange authorization code: ${error}`);
|
|
1640
|
-
}
|
|
1641
|
-
const data = await response.json();
|
|
1642
|
-
return data;
|
|
1643
|
-
}
|
|
1644
|
-
async handleStatus(provider, accessToken) {
|
|
1645
|
-
const url = new URL("/oauth/status", this.serverUrl);
|
|
1646
|
-
url.searchParams.set("provider", provider);
|
|
1647
|
-
const response = await fetch(url.toString(), {
|
|
1648
|
-
method: "GET",
|
|
1649
|
-
headers: this.getHeaders({
|
|
1650
|
-
Authorization: `Bearer ${accessToken}`
|
|
1651
|
-
})
|
|
1652
|
-
});
|
|
1653
|
-
if (!response.ok) {
|
|
1654
|
-
if (response.status === 401) {
|
|
1655
|
-
return {
|
|
1656
|
-
authorized: false
|
|
1657
|
-
};
|
|
1658
|
-
}
|
|
1659
|
-
const error = await response.text();
|
|
1660
|
-
throw new Error(`MCP server failed to check authorization status: ${error}`);
|
|
1661
|
-
}
|
|
1662
|
-
const data = await response.json();
|
|
1663
|
-
return data;
|
|
1664
|
-
}
|
|
1665
|
-
async handleDisconnect(request, accessToken) {
|
|
1666
|
-
if (!accessToken) {
|
|
1667
|
-
throw new Error("No access token provided. Cannot disconnect provider.");
|
|
1668
|
-
}
|
|
1669
|
-
const url = new URL("/oauth/disconnect", this.serverUrl);
|
|
1670
|
-
const response = await fetch(url.toString(), {
|
|
1671
|
-
method: "POST",
|
|
1672
|
-
headers: this.getHeaders({
|
|
1673
|
-
"Content-Type": "application/json",
|
|
1674
|
-
Authorization: `Bearer ${accessToken}`
|
|
1675
|
-
}),
|
|
1676
|
-
body: JSON.stringify({
|
|
1677
|
-
provider: request.provider
|
|
1678
|
-
})
|
|
1679
|
-
});
|
|
1680
|
-
if (!response.ok) {
|
|
1681
|
-
const error = await response.text();
|
|
1682
|
-
throw new Error(`MCP server failed to disconnect provider: ${error}`);
|
|
1683
|
-
}
|
|
1684
|
-
const data = await response.json();
|
|
1685
|
-
return data;
|
|
1686
|
-
}
|
|
1687
|
-
}
|
|
1688
1755
|
// src/adapters/nextjs.ts
|
|
1689
1756
|
function createNextOAuthHandler(config) {
|
|
1690
1757
|
const handler = new OAuthHandler(config);
|
|
@@ -1760,6 +1827,9 @@ function createNextOAuthHandler(config) {
|
|
|
1760
1827
|
if (action === "disconnect") {
|
|
1761
1828
|
return handlers.disconnect(req);
|
|
1762
1829
|
}
|
|
1830
|
+
if (action === "mcp") {
|
|
1831
|
+
return handlers.mcp(req);
|
|
1832
|
+
}
|
|
1763
1833
|
return Response.json({ error: `Unknown action: ${action}` }, { status: 404 });
|
|
1764
1834
|
},
|
|
1765
1835
|
async GET(req, context) {
|
|
@@ -1772,6 +1842,17 @@ function createNextOAuthHandler(config) {
|
|
|
1772
1842
|
}
|
|
1773
1843
|
};
|
|
1774
1844
|
},
|
|
1845
|
+
async mcp(req) {
|
|
1846
|
+
try {
|
|
1847
|
+
const body = await req.json();
|
|
1848
|
+
const authHeader = req.headers.get("authorization");
|
|
1849
|
+
const result = await handler.handleToolCall(body, authHeader);
|
|
1850
|
+
return Response.json(result);
|
|
1851
|
+
} catch (error) {
|
|
1852
|
+
console.error("[MCP Tool Call] Error:", error);
|
|
1853
|
+
return Response.json({ error: error.message || "Failed to execute tool call" }, { status: error.statusCode || 500 });
|
|
1854
|
+
}
|
|
1855
|
+
},
|
|
1775
1856
|
toNextJsHandler(redirectConfig) {
|
|
1776
1857
|
const defaultRedirectUrl = redirectConfig?.redirectUrl || "/";
|
|
1777
1858
|
const errorRedirectUrl = redirectConfig?.errorRedirectUrl || "/auth-error";
|
|
@@ -1792,6 +1873,9 @@ function createNextOAuthHandler(config) {
|
|
|
1792
1873
|
}
|
|
1793
1874
|
return Response.json({ error: `Unknown action: ${action}` }, { status: 404 });
|
|
1794
1875
|
}
|
|
1876
|
+
if (segments.length === 1 && segments[0] === "mcp") {
|
|
1877
|
+
return handlers.mcp(req);
|
|
1878
|
+
}
|
|
1795
1879
|
return Response.json({ error: `Invalid route: /${segments.join("/")}` }, { status: 404 });
|
|
1796
1880
|
},
|
|
1797
1881
|
async GET(req, context) {
|
|
@@ -2259,6 +2343,23 @@ function createMCPServer(config) {
|
|
|
2259
2343
|
if (segments.length === 2 && segments[0] !== "oauth") {
|
|
2260
2344
|
return Response.json({ error: `Invalid route: /${segments.join("/")}` }, { status: 404 });
|
|
2261
2345
|
}
|
|
2346
|
+
if (segments.length === 1 && segments[0] === "mcp" && method === "POST") {
|
|
2347
|
+
try {
|
|
2348
|
+
const body = await request.json();
|
|
2349
|
+
const authHeader = request.headers.get("authorization");
|
|
2350
|
+
const { OAuthHandler: OAuthHandler2 } = await Promise.resolve().then(() => exports_base_handler);
|
|
2351
|
+
const oauthHandler = new OAuthHandler2({
|
|
2352
|
+
providers,
|
|
2353
|
+
serverUrl: config.serverUrl,
|
|
2354
|
+
apiKey: config.apiKey
|
|
2355
|
+
});
|
|
2356
|
+
const result = await oauthHandler.handleToolCall(body, authHeader);
|
|
2357
|
+
return Response.json(result);
|
|
2358
|
+
} catch (error) {
|
|
2359
|
+
console.error("[MCP Tool Call] Error:", error);
|
|
2360
|
+
return Response.json({ error: error.message || "Failed to execute tool call" }, { status: error.statusCode || 500 });
|
|
2361
|
+
}
|
|
2362
|
+
}
|
|
2262
2363
|
}
|
|
2263
2364
|
if (method === "GET" && action === "callback") {
|
|
2264
2365
|
const url = new URL(request.url);
|
package/dist/oauth.js
CHANGED
|
@@ -11,7 +11,10 @@ var __export = (target, all) => {
|
|
|
11
11
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
12
12
|
|
|
13
13
|
// src/adapters/base-handler.ts
|
|
14
|
-
var
|
|
14
|
+
var exports_base_handler = {};
|
|
15
|
+
__export(exports_base_handler, {
|
|
16
|
+
OAuthHandler: () => OAuthHandler
|
|
17
|
+
});
|
|
15
18
|
|
|
16
19
|
class OAuthHandler {
|
|
17
20
|
config;
|
|
@@ -139,7 +142,43 @@ class OAuthHandler {
|
|
|
139
142
|
const data = await response.json();
|
|
140
143
|
return data;
|
|
141
144
|
}
|
|
145
|
+
async handleToolCall(request, authHeader) {
|
|
146
|
+
const url = new URL("/tools/call", this.serverUrl);
|
|
147
|
+
const headers = this.getHeaders({
|
|
148
|
+
"Content-Type": "application/json"
|
|
149
|
+
});
|
|
150
|
+
if (authHeader && authHeader.startsWith("Bearer ")) {
|
|
151
|
+
headers["Authorization"] = authHeader;
|
|
152
|
+
}
|
|
153
|
+
const jsonRpcRequest = {
|
|
154
|
+
jsonrpc: "2.0",
|
|
155
|
+
id: Date.now() + Math.random(),
|
|
156
|
+
method: "tools/call",
|
|
157
|
+
params: {
|
|
158
|
+
name: request.name,
|
|
159
|
+
arguments: request.arguments || {}
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
const response = await fetch(url.toString(), {
|
|
163
|
+
method: "POST",
|
|
164
|
+
headers,
|
|
165
|
+
body: JSON.stringify(jsonRpcRequest)
|
|
166
|
+
});
|
|
167
|
+
if (!response.ok) {
|
|
168
|
+
const error = await response.text();
|
|
169
|
+
throw new Error(`MCP server failed to execute tool call: ${error}`);
|
|
170
|
+
}
|
|
171
|
+
const jsonRpcResponse = await response.json();
|
|
172
|
+
if (jsonRpcResponse.error) {
|
|
173
|
+
const error = new Error(jsonRpcResponse.error.message || "Tool call failed");
|
|
174
|
+
error.code = jsonRpcResponse.error.code;
|
|
175
|
+
error.data = jsonRpcResponse.error.data;
|
|
176
|
+
throw error;
|
|
177
|
+
}
|
|
178
|
+
return jsonRpcResponse.result;
|
|
179
|
+
}
|
|
142
180
|
}
|
|
181
|
+
var MCP_SERVER_URL = "https://mcp.integrate.dev/api/v1/mcp";
|
|
143
182
|
|
|
144
183
|
// src/adapters/auto-routes.ts
|
|
145
184
|
var globalOAuthConfig = null;
|