integrate-sdk 0.9.18-dev.0 → 0.9.20-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/ai/anthropic.js +73 -1
- package/dist/ai/google.js +73 -1
- package/dist/ai/index.js +73 -1
- package/dist/ai/openai.js +73 -1
- package/dist/ai/vercel-ai.js +73 -1
- package/dist/code-mode/executor.d.ts.map +1 -1
- package/dist/code-mode/executor.js +33 -0
- package/dist/code-mode/index.js +126 -1
- package/dist/code-mode/runtime-stub.d.ts +1 -1
- package/dist/code-mode/runtime-stub.d.ts.map +1 -1
- package/dist/code-mode/runtime-stub.js +23 -0
- package/dist/code-mode/tool-builder.d.ts.map +1 -1
- package/dist/code-mode/tool-builder.js +126 -1
- package/dist/server.js +143 -54
- package/dist/src/code-mode/executor.d.ts.map +1 -1
- package/dist/src/code-mode/runtime-stub.d.ts +1 -1
- package/dist/src/code-mode/runtime-stub.d.ts.map +1 -1
- package/dist/src/code-mode/tool-builder.d.ts.map +1 -1
- package/dist/src/server.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/code-mode/index.js
CHANGED
|
@@ -275,6 +275,19 @@ if (!MCP_URL) {
|
|
|
275
275
|
throw new Error('INTEGRATE_MCP_URL is not set — the sandbox cannot reach the MCP route.');
|
|
276
276
|
}
|
|
277
277
|
|
|
278
|
+
// Diagnostic: log sandbox env summary to stderr so it shows up in the
|
|
279
|
+
// execute_code result's stderr field for debugging auth issues.
|
|
280
|
+
console.error('[sandbox-diag] MCP_URL=' + MCP_URL);
|
|
281
|
+
console.error('[sandbox-diag] HAS_API_KEY=' + !!API_KEY);
|
|
282
|
+
console.error('[sandbox-diag] HAS_SESSION_TOKEN=' + !!SESSION_TOKEN);
|
|
283
|
+
console.error('[sandbox-diag] HAS_PROVIDER_TOKENS=' + !!PROVIDER_TOKENS);
|
|
284
|
+
if (PROVIDER_TOKENS) {
|
|
285
|
+
try {
|
|
286
|
+
const _keys = Object.keys(JSON.parse(PROVIDER_TOKENS));
|
|
287
|
+
console.error('[sandbox-diag] PROVIDER_TOKEN_KEYS=' + _keys.join(','));
|
|
288
|
+
} catch { console.error('[sandbox-diag] PROVIDER_TOKENS is not valid JSON'); }
|
|
289
|
+
}
|
|
290
|
+
|
|
278
291
|
function camelToSnake(str) {
|
|
279
292
|
return str.replace(/[A-Z]/g, (letter) => '_' + letter.toLowerCase());
|
|
280
293
|
}
|
|
@@ -290,6 +303,14 @@ async function callTool(toolName, args) {
|
|
|
290
303
|
if (INTEGRATIONS_HEADER) headers['x-integrations'] = INTEGRATIONS_HEADER;
|
|
291
304
|
if (CONTEXT_JSON) headers['x-integrate-context'] = CONTEXT_JSON;
|
|
292
305
|
|
|
306
|
+
console.error('[sandbox-diag] callTool: ' + toolName + ' → ' + MCP_URL);
|
|
307
|
+
console.error('[sandbox-diag] headers: ' + JSON.stringify({
|
|
308
|
+
hasAuth: !!headers['Authorization'],
|
|
309
|
+
hasApiKey: !!headers['x-integrate-api-key'],
|
|
310
|
+
hasTokens: !!headers['x-integrate-tokens'],
|
|
311
|
+
hasCodeMode: !!headers['x-integrate-code-mode'],
|
|
312
|
+
}));
|
|
313
|
+
|
|
293
314
|
const res = await fetch(MCP_URL, {
|
|
294
315
|
method: 'POST',
|
|
295
316
|
headers,
|
|
@@ -297,6 +318,8 @@ async function callTool(toolName, args) {
|
|
|
297
318
|
});
|
|
298
319
|
|
|
299
320
|
const text = await res.text();
|
|
321
|
+
console.error('[sandbox-diag] response: HTTP ' + res.status + ' len=' + text.length);
|
|
322
|
+
|
|
300
323
|
let payload;
|
|
301
324
|
try {
|
|
302
325
|
payload = text ? JSON.parse(text) : null;
|
|
@@ -485,6 +508,16 @@ async function executeSandboxCode(options) {
|
|
|
485
508
|
env.INTEGRATE_INTEGRATIONS = options.integrationsHeader;
|
|
486
509
|
if (options.context)
|
|
487
510
|
env.INTEGRATE_CONTEXT = JSON.stringify(options.context);
|
|
511
|
+
console.debug("[integrate-sdk] Sandbox env:", JSON.stringify({
|
|
512
|
+
mcpUrl: options.mcpUrl,
|
|
513
|
+
hasApiKey: !!options.apiKey,
|
|
514
|
+
hasSessionToken: !!options.sessionToken,
|
|
515
|
+
providerTokenKeys: options.providerTokens ? Object.keys(options.providerTokens) : [],
|
|
516
|
+
hasIntegrations: !!options.integrationsHeader,
|
|
517
|
+
hasContext: !!options.context,
|
|
518
|
+
runtime,
|
|
519
|
+
timeoutMs
|
|
520
|
+
}));
|
|
488
521
|
const cmd = await sandbox.runCommand({
|
|
489
522
|
cmd: "node",
|
|
490
523
|
args: ["user.mjs"],
|
|
@@ -540,6 +573,59 @@ function getEnv(key) {
|
|
|
540
573
|
return;
|
|
541
574
|
}
|
|
542
575
|
|
|
576
|
+
// ../utils/request-tokens.ts
|
|
577
|
+
async function getProviderTokens(manualTokens) {
|
|
578
|
+
if (manualTokens) {
|
|
579
|
+
return manualTokens;
|
|
580
|
+
}
|
|
581
|
+
let tokensString = null;
|
|
582
|
+
if (!tokensString) {
|
|
583
|
+
try {
|
|
584
|
+
const getNextHeadersPath = () => {
|
|
585
|
+
const parts = ["next", "/headers"];
|
|
586
|
+
return parts.join("");
|
|
587
|
+
};
|
|
588
|
+
const nextHeaders = await import(getNextHeadersPath()).catch(() => null);
|
|
589
|
+
if (nextHeaders && typeof nextHeaders.headers === "function") {
|
|
590
|
+
const headersList = await Promise.resolve(nextHeaders.headers());
|
|
591
|
+
tokensString = headersList.get("x-integrate-tokens");
|
|
592
|
+
}
|
|
593
|
+
} catch {}
|
|
594
|
+
}
|
|
595
|
+
if (!tokensString) {
|
|
596
|
+
try {
|
|
597
|
+
const getNuxtHeaders = new Function(`
|
|
598
|
+
try {
|
|
599
|
+
if (typeof useRequestHeaders === 'function') {
|
|
600
|
+
return useRequestHeaders();
|
|
601
|
+
}
|
|
602
|
+
} catch {}
|
|
603
|
+
return null;
|
|
604
|
+
`);
|
|
605
|
+
const headers = getNuxtHeaders();
|
|
606
|
+
if (headers && typeof headers === "object") {
|
|
607
|
+
tokensString = headers["x-integrate-tokens"];
|
|
608
|
+
}
|
|
609
|
+
} catch {}
|
|
610
|
+
}
|
|
611
|
+
if (!tokensString) {
|
|
612
|
+
if (typeof process !== "undefined" && process.env) {
|
|
613
|
+
tokensString = process.env.PROVIDER_TOKENS;
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
if (tokensString) {
|
|
617
|
+
try {
|
|
618
|
+
const parsed = JSON.parse(tokensString);
|
|
619
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
620
|
+
return parsed;
|
|
621
|
+
}
|
|
622
|
+
} catch (error) {
|
|
623
|
+
throw new Error(`Failed to parse provider tokens: ${error instanceof Error ? error.message : "Invalid JSON"}`);
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
throw new Error("Provider tokens not found. Please pass tokens manually via options.providerTokens or set the x-integrate-tokens header in your request.");
|
|
627
|
+
}
|
|
628
|
+
|
|
543
629
|
// tool-builder.ts
|
|
544
630
|
var CODE_MODE_TOOL_NAME = "execute_code";
|
|
545
631
|
var TYPES_TOOL_NAME = "get_integration_types";
|
|
@@ -616,11 +702,50 @@ ${generated.compact}`;
|
|
|
616
702
|
};
|
|
617
703
|
}
|
|
618
704
|
const mcpUrl = publicUrl.replace(/\/$/, "") + "/api/integrate/mcp";
|
|
705
|
+
let resolvedTokens = providerTokens;
|
|
706
|
+
let tokenSource = resolvedTokens && Object.keys(resolvedTokens).length > 0 ? "build-time" : "none";
|
|
707
|
+
if (!resolvedTokens || Object.keys(resolvedTokens).length === 0) {
|
|
708
|
+
try {
|
|
709
|
+
resolvedTokens = await getProviderTokens();
|
|
710
|
+
if (resolvedTokens && Object.keys(resolvedTokens).length > 0) {
|
|
711
|
+
tokenSource = "request-header";
|
|
712
|
+
}
|
|
713
|
+
} catch {}
|
|
714
|
+
}
|
|
715
|
+
if (!resolvedTokens || Object.keys(resolvedTokens).length === 0) {
|
|
716
|
+
const oauthManager = client.oauthManager;
|
|
717
|
+
if (oauthManager) {
|
|
718
|
+
resolvedTokens = {};
|
|
719
|
+
const clientIntegrations = client.integrations || [];
|
|
720
|
+
for (const integration of clientIntegrations) {
|
|
721
|
+
if (integration.oauth) {
|
|
722
|
+
const provider = integration.oauth.provider;
|
|
723
|
+
try {
|
|
724
|
+
const tokenData = await oauthManager.getProviderToken(provider, undefined, context);
|
|
725
|
+
if (tokenData?.accessToken) {
|
|
726
|
+
resolvedTokens[provider] = tokenData.accessToken;
|
|
727
|
+
}
|
|
728
|
+
} catch {}
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
if (Object.keys(resolvedTokens).length === 0) {
|
|
732
|
+
resolvedTokens = undefined;
|
|
733
|
+
} else {
|
|
734
|
+
tokenSource = "oauthManager";
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
console.debug("[integrate-sdk] execute_code token resolution:", JSON.stringify({
|
|
739
|
+
source: tokenSource,
|
|
740
|
+
keys: resolvedTokens ? Object.keys(resolvedTokens) : [],
|
|
741
|
+
hasApiKey: !!apiKey,
|
|
742
|
+
mcpUrl
|
|
743
|
+
}));
|
|
619
744
|
return executeSandboxCode({
|
|
620
745
|
code,
|
|
621
746
|
mcpUrl,
|
|
622
747
|
apiKey,
|
|
623
|
-
providerTokens,
|
|
748
|
+
providerTokens: resolvedTokens,
|
|
624
749
|
context,
|
|
625
750
|
integrationsHeader: integrationIds && integrationIds.length > 0 ? integrationIds.join(",") : undefined,
|
|
626
751
|
runtime: sandboxOverrides.runtime ?? serverCodeModeConfig.runtime,
|
|
@@ -12,5 +12,5 @@
|
|
|
12
12
|
* dependencies. It is NOT imported by the host SDK — it only ships as a
|
|
13
13
|
* literal payload to the sandbox.
|
|
14
14
|
*/
|
|
15
|
-
export declare const RUNTIME_STUB_SOURCE = "// runtime.mjs \u2014 generated by integrate-sdk code mode\nconst MCP_URL = process.env.INTEGRATE_MCP_URL;\nconst SESSION_TOKEN = process.env.INTEGRATE_SESSION_TOKEN;\nconst API_KEY = process.env.INTEGRATE_API_KEY || '';\nconst PROVIDER_TOKENS = process.env.INTEGRATE_PROVIDER_TOKENS || '';\nconst INTEGRATIONS_HEADER = process.env.INTEGRATE_INTEGRATIONS || '';\nconst CONTEXT_JSON = process.env.INTEGRATE_CONTEXT || '';\n\nif (!MCP_URL) {\n throw new Error('INTEGRATE_MCP_URL is not set \u2014 the sandbox cannot reach the MCP route.');\n}\n\nfunction camelToSnake(str) {\n return str.replace(/[A-Z]/g, (letter) => '_' + letter.toLowerCase());\n}\n\nasync function callTool(toolName, args) {\n const headers = {\n 'Content-Type': 'application/json',\n 'x-integrate-code-mode': '1',\n };\n if (SESSION_TOKEN) headers['Authorization'] = 'Bearer ' + SESSION_TOKEN;\n if (API_KEY) headers['x-integrate-api-key'] = API_KEY;\n if (PROVIDER_TOKENS) headers['x-integrate-tokens'] = PROVIDER_TOKENS;\n if (INTEGRATIONS_HEADER) headers['x-integrations'] = INTEGRATIONS_HEADER;\n if (CONTEXT_JSON) headers['x-integrate-context'] = CONTEXT_JSON;\n\n const res = await fetch(MCP_URL, {\n method: 'POST',\n headers,\n body: JSON.stringify({ name: toolName, arguments: args || {} }),\n });\n\n const text = await res.text();\n let payload;\n try {\n payload = text ? JSON.parse(text) : null;\n } catch {\n payload = { content: [{ type: 'text', text }] };\n }\n\n if (!res.ok) {\n let message = (payload && (payload.error || payload.message)) || 'Tool call failed: HTTP ' + res.status;\n if ((res.status === 401 || res.status === 403) && typeof text === 'string' && text.indexOf('Authorization header') !== -1) {\n message =\n 'Code Mode callback was rejected by the MCP server (HTTP ' + res.status + '). ' +\n 'The SDK route could not synthesize an Authorization header. Check the host-side ' +\n 'createMCPServer config (apiKey, getProviderToken) or pass providerTokens to the ' +\n 'AI helper. Original upstream message: ' + text;\n }\n const err = new Error(message);\n err.status = res.status;\n err.toolName = toolName;\n throw err;\n }\n\n return payload;\n}\n\nfunction createIntegrationProxy(integrationId) {\n return new Proxy({}, {\n get(_target, methodName) {\n if (typeof methodName !== 'string') return undefined;\n return (args) => callTool(integrationId + '_' + camelToSnake(methodName), args);\n },\n });\n}\n\nexport const client = new Proxy({}, {\n get(_target, integrationId) {\n if (typeof integrationId !== 'string') return undefined;\n return createIntegrationProxy(integrationId);\n },\n});\n\nexport { callTool };\n";
|
|
15
|
+
export declare const RUNTIME_STUB_SOURCE = "// runtime.mjs \u2014 generated by integrate-sdk code mode\nconst MCP_URL = process.env.INTEGRATE_MCP_URL;\nconst SESSION_TOKEN = process.env.INTEGRATE_SESSION_TOKEN;\nconst API_KEY = process.env.INTEGRATE_API_KEY || '';\nconst PROVIDER_TOKENS = process.env.INTEGRATE_PROVIDER_TOKENS || '';\nconst INTEGRATIONS_HEADER = process.env.INTEGRATE_INTEGRATIONS || '';\nconst CONTEXT_JSON = process.env.INTEGRATE_CONTEXT || '';\n\nif (!MCP_URL) {\n throw new Error('INTEGRATE_MCP_URL is not set \u2014 the sandbox cannot reach the MCP route.');\n}\n\n// Diagnostic: log sandbox env summary to stderr so it shows up in the\n// execute_code result's stderr field for debugging auth issues.\nconsole.error('[sandbox-diag] MCP_URL=' + MCP_URL);\nconsole.error('[sandbox-diag] HAS_API_KEY=' + !!API_KEY);\nconsole.error('[sandbox-diag] HAS_SESSION_TOKEN=' + !!SESSION_TOKEN);\nconsole.error('[sandbox-diag] HAS_PROVIDER_TOKENS=' + !!PROVIDER_TOKENS);\nif (PROVIDER_TOKENS) {\n try {\n const _keys = Object.keys(JSON.parse(PROVIDER_TOKENS));\n console.error('[sandbox-diag] PROVIDER_TOKEN_KEYS=' + _keys.join(','));\n } catch { console.error('[sandbox-diag] PROVIDER_TOKENS is not valid JSON'); }\n}\n\nfunction camelToSnake(str) {\n return str.replace(/[A-Z]/g, (letter) => '_' + letter.toLowerCase());\n}\n\nasync function callTool(toolName, args) {\n const headers = {\n 'Content-Type': 'application/json',\n 'x-integrate-code-mode': '1',\n };\n if (SESSION_TOKEN) headers['Authorization'] = 'Bearer ' + SESSION_TOKEN;\n if (API_KEY) headers['x-integrate-api-key'] = API_KEY;\n if (PROVIDER_TOKENS) headers['x-integrate-tokens'] = PROVIDER_TOKENS;\n if (INTEGRATIONS_HEADER) headers['x-integrations'] = INTEGRATIONS_HEADER;\n if (CONTEXT_JSON) headers['x-integrate-context'] = CONTEXT_JSON;\n\n console.error('[sandbox-diag] callTool: ' + toolName + ' \u2192 ' + MCP_URL);\n console.error('[sandbox-diag] headers: ' + JSON.stringify({\n hasAuth: !!headers['Authorization'],\n hasApiKey: !!headers['x-integrate-api-key'],\n hasTokens: !!headers['x-integrate-tokens'],\n hasCodeMode: !!headers['x-integrate-code-mode'],\n }));\n\n const res = await fetch(MCP_URL, {\n method: 'POST',\n headers,\n body: JSON.stringify({ name: toolName, arguments: args || {} }),\n });\n\n const text = await res.text();\n console.error('[sandbox-diag] response: HTTP ' + res.status + ' len=' + text.length);\n\n let payload;\n try {\n payload = text ? JSON.parse(text) : null;\n } catch {\n payload = { content: [{ type: 'text', text }] };\n }\n\n if (!res.ok) {\n let message = (payload && (payload.error || payload.message)) || 'Tool call failed: HTTP ' + res.status;\n if ((res.status === 401 || res.status === 403) && typeof text === 'string' && text.indexOf('Authorization header') !== -1) {\n message =\n 'Code Mode callback was rejected by the MCP server (HTTP ' + res.status + '). ' +\n 'The SDK route could not synthesize an Authorization header. Check the host-side ' +\n 'createMCPServer config (apiKey, getProviderToken) or pass providerTokens to the ' +\n 'AI helper. Original upstream message: ' + text;\n }\n const err = new Error(message);\n err.status = res.status;\n err.toolName = toolName;\n throw err;\n }\n\n return payload;\n}\n\nfunction createIntegrationProxy(integrationId) {\n return new Proxy({}, {\n get(_target, methodName) {\n if (typeof methodName !== 'string') return undefined;\n return (args) => callTool(integrationId + '_' + camelToSnake(methodName), args);\n },\n });\n}\n\nexport const client = new Proxy({}, {\n get(_target, integrationId) {\n if (typeof integrationId !== 'string') return undefined;\n return createIntegrationProxy(integrationId);\n },\n});\n\nexport { callTool };\n";
|
|
16
16
|
//# sourceMappingURL=runtime-stub.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime-stub.d.ts","sourceRoot":"","sources":["../../../src/code-mode/runtime-stub.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,eAAO,MAAM,mBAAmB,
|
|
1
|
+
{"version":3,"file":"runtime-stub.d.ts","sourceRoot":"","sources":["../../../src/code-mode/runtime-stub.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,eAAO,MAAM,mBAAmB,owHAmG/B,CAAC"}
|
|
@@ -30,6 +30,19 @@ if (!MCP_URL) {
|
|
|
30
30
|
throw new Error('INTEGRATE_MCP_URL is not set — the sandbox cannot reach the MCP route.');
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
// Diagnostic: log sandbox env summary to stderr so it shows up in the
|
|
34
|
+
// execute_code result's stderr field for debugging auth issues.
|
|
35
|
+
console.error('[sandbox-diag] MCP_URL=' + MCP_URL);
|
|
36
|
+
console.error('[sandbox-diag] HAS_API_KEY=' + !!API_KEY);
|
|
37
|
+
console.error('[sandbox-diag] HAS_SESSION_TOKEN=' + !!SESSION_TOKEN);
|
|
38
|
+
console.error('[sandbox-diag] HAS_PROVIDER_TOKENS=' + !!PROVIDER_TOKENS);
|
|
39
|
+
if (PROVIDER_TOKENS) {
|
|
40
|
+
try {
|
|
41
|
+
const _keys = Object.keys(JSON.parse(PROVIDER_TOKENS));
|
|
42
|
+
console.error('[sandbox-diag] PROVIDER_TOKEN_KEYS=' + _keys.join(','));
|
|
43
|
+
} catch { console.error('[sandbox-diag] PROVIDER_TOKENS is not valid JSON'); }
|
|
44
|
+
}
|
|
45
|
+
|
|
33
46
|
function camelToSnake(str) {
|
|
34
47
|
return str.replace(/[A-Z]/g, (letter) => '_' + letter.toLowerCase());
|
|
35
48
|
}
|
|
@@ -45,6 +58,14 @@ async function callTool(toolName, args) {
|
|
|
45
58
|
if (INTEGRATIONS_HEADER) headers['x-integrations'] = INTEGRATIONS_HEADER;
|
|
46
59
|
if (CONTEXT_JSON) headers['x-integrate-context'] = CONTEXT_JSON;
|
|
47
60
|
|
|
61
|
+
console.error('[sandbox-diag] callTool: ' + toolName + ' → ' + MCP_URL);
|
|
62
|
+
console.error('[sandbox-diag] headers: ' + JSON.stringify({
|
|
63
|
+
hasAuth: !!headers['Authorization'],
|
|
64
|
+
hasApiKey: !!headers['x-integrate-api-key'],
|
|
65
|
+
hasTokens: !!headers['x-integrate-tokens'],
|
|
66
|
+
hasCodeMode: !!headers['x-integrate-code-mode'],
|
|
67
|
+
}));
|
|
68
|
+
|
|
48
69
|
const res = await fetch(MCP_URL, {
|
|
49
70
|
method: 'POST',
|
|
50
71
|
headers,
|
|
@@ -52,6 +73,8 @@ async function callTool(toolName, args) {
|
|
|
52
73
|
});
|
|
53
74
|
|
|
54
75
|
const text = await res.text();
|
|
76
|
+
console.error('[sandbox-diag] response: HTTP ' + res.status + ' len=' + text.length);
|
|
77
|
+
|
|
55
78
|
let payload;
|
|
56
79
|
try {
|
|
57
80
|
payload = text ? JSON.parse(text) : null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-builder.d.ts","sourceRoot":"","sources":["../../../src/code-mode/tool-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAEvD,OAAO,EAIL,KAAK,wBAAwB,EAC9B,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"tool-builder.d.ts","sourceRoot":"","sources":["../../../src/code-mode/tool-builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -275,6 +275,19 @@ if (!MCP_URL) {
|
|
|
275
275
|
throw new Error('INTEGRATE_MCP_URL is not set — the sandbox cannot reach the MCP route.');
|
|
276
276
|
}
|
|
277
277
|
|
|
278
|
+
// Diagnostic: log sandbox env summary to stderr so it shows up in the
|
|
279
|
+
// execute_code result's stderr field for debugging auth issues.
|
|
280
|
+
console.error('[sandbox-diag] MCP_URL=' + MCP_URL);
|
|
281
|
+
console.error('[sandbox-diag] HAS_API_KEY=' + !!API_KEY);
|
|
282
|
+
console.error('[sandbox-diag] HAS_SESSION_TOKEN=' + !!SESSION_TOKEN);
|
|
283
|
+
console.error('[sandbox-diag] HAS_PROVIDER_TOKENS=' + !!PROVIDER_TOKENS);
|
|
284
|
+
if (PROVIDER_TOKENS) {
|
|
285
|
+
try {
|
|
286
|
+
const _keys = Object.keys(JSON.parse(PROVIDER_TOKENS));
|
|
287
|
+
console.error('[sandbox-diag] PROVIDER_TOKEN_KEYS=' + _keys.join(','));
|
|
288
|
+
} catch { console.error('[sandbox-diag] PROVIDER_TOKENS is not valid JSON'); }
|
|
289
|
+
}
|
|
290
|
+
|
|
278
291
|
function camelToSnake(str) {
|
|
279
292
|
return str.replace(/[A-Z]/g, (letter) => '_' + letter.toLowerCase());
|
|
280
293
|
}
|
|
@@ -290,6 +303,14 @@ async function callTool(toolName, args) {
|
|
|
290
303
|
if (INTEGRATIONS_HEADER) headers['x-integrations'] = INTEGRATIONS_HEADER;
|
|
291
304
|
if (CONTEXT_JSON) headers['x-integrate-context'] = CONTEXT_JSON;
|
|
292
305
|
|
|
306
|
+
console.error('[sandbox-diag] callTool: ' + toolName + ' → ' + MCP_URL);
|
|
307
|
+
console.error('[sandbox-diag] headers: ' + JSON.stringify({
|
|
308
|
+
hasAuth: !!headers['Authorization'],
|
|
309
|
+
hasApiKey: !!headers['x-integrate-api-key'],
|
|
310
|
+
hasTokens: !!headers['x-integrate-tokens'],
|
|
311
|
+
hasCodeMode: !!headers['x-integrate-code-mode'],
|
|
312
|
+
}));
|
|
313
|
+
|
|
293
314
|
const res = await fetch(MCP_URL, {
|
|
294
315
|
method: 'POST',
|
|
295
316
|
headers,
|
|
@@ -297,6 +318,8 @@ async function callTool(toolName, args) {
|
|
|
297
318
|
});
|
|
298
319
|
|
|
299
320
|
const text = await res.text();
|
|
321
|
+
console.error('[sandbox-diag] response: HTTP ' + res.status + ' len=' + text.length);
|
|
322
|
+
|
|
300
323
|
let payload;
|
|
301
324
|
try {
|
|
302
325
|
payload = text ? JSON.parse(text) : null;
|
|
@@ -485,6 +508,16 @@ async function executeSandboxCode(options) {
|
|
|
485
508
|
env.INTEGRATE_INTEGRATIONS = options.integrationsHeader;
|
|
486
509
|
if (options.context)
|
|
487
510
|
env.INTEGRATE_CONTEXT = JSON.stringify(options.context);
|
|
511
|
+
console.debug("[integrate-sdk] Sandbox env:", JSON.stringify({
|
|
512
|
+
mcpUrl: options.mcpUrl,
|
|
513
|
+
hasApiKey: !!options.apiKey,
|
|
514
|
+
hasSessionToken: !!options.sessionToken,
|
|
515
|
+
providerTokenKeys: options.providerTokens ? Object.keys(options.providerTokens) : [],
|
|
516
|
+
hasIntegrations: !!options.integrationsHeader,
|
|
517
|
+
hasContext: !!options.context,
|
|
518
|
+
runtime,
|
|
519
|
+
timeoutMs
|
|
520
|
+
}));
|
|
488
521
|
const cmd = await sandbox.runCommand({
|
|
489
522
|
cmd: "node",
|
|
490
523
|
args: ["user.mjs"],
|
|
@@ -540,6 +573,59 @@ function getEnv(key) {
|
|
|
540
573
|
return;
|
|
541
574
|
}
|
|
542
575
|
|
|
576
|
+
// ../utils/request-tokens.ts
|
|
577
|
+
async function getProviderTokens(manualTokens) {
|
|
578
|
+
if (manualTokens) {
|
|
579
|
+
return manualTokens;
|
|
580
|
+
}
|
|
581
|
+
let tokensString = null;
|
|
582
|
+
if (!tokensString) {
|
|
583
|
+
try {
|
|
584
|
+
const getNextHeadersPath = () => {
|
|
585
|
+
const parts = ["next", "/headers"];
|
|
586
|
+
return parts.join("");
|
|
587
|
+
};
|
|
588
|
+
const nextHeaders = await import(getNextHeadersPath()).catch(() => null);
|
|
589
|
+
if (nextHeaders && typeof nextHeaders.headers === "function") {
|
|
590
|
+
const headersList = await Promise.resolve(nextHeaders.headers());
|
|
591
|
+
tokensString = headersList.get("x-integrate-tokens");
|
|
592
|
+
}
|
|
593
|
+
} catch {}
|
|
594
|
+
}
|
|
595
|
+
if (!tokensString) {
|
|
596
|
+
try {
|
|
597
|
+
const getNuxtHeaders = new Function(`
|
|
598
|
+
try {
|
|
599
|
+
if (typeof useRequestHeaders === 'function') {
|
|
600
|
+
return useRequestHeaders();
|
|
601
|
+
}
|
|
602
|
+
} catch {}
|
|
603
|
+
return null;
|
|
604
|
+
`);
|
|
605
|
+
const headers = getNuxtHeaders();
|
|
606
|
+
if (headers && typeof headers === "object") {
|
|
607
|
+
tokensString = headers["x-integrate-tokens"];
|
|
608
|
+
}
|
|
609
|
+
} catch {}
|
|
610
|
+
}
|
|
611
|
+
if (!tokensString) {
|
|
612
|
+
if (typeof process !== "undefined" && process.env) {
|
|
613
|
+
tokensString = process.env.PROVIDER_TOKENS;
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
if (tokensString) {
|
|
617
|
+
try {
|
|
618
|
+
const parsed = JSON.parse(tokensString);
|
|
619
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
620
|
+
return parsed;
|
|
621
|
+
}
|
|
622
|
+
} catch (error) {
|
|
623
|
+
throw new Error(`Failed to parse provider tokens: ${error instanceof Error ? error.message : "Invalid JSON"}`);
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
throw new Error("Provider tokens not found. Please pass tokens manually via options.providerTokens or set the x-integrate-tokens header in your request.");
|
|
627
|
+
}
|
|
628
|
+
|
|
543
629
|
// tool-builder.ts
|
|
544
630
|
var CODE_MODE_TOOL_NAME = "execute_code";
|
|
545
631
|
var TYPES_TOOL_NAME = "get_integration_types";
|
|
@@ -616,11 +702,50 @@ ${generated.compact}`;
|
|
|
616
702
|
};
|
|
617
703
|
}
|
|
618
704
|
const mcpUrl = publicUrl.replace(/\/$/, "") + "/api/integrate/mcp";
|
|
705
|
+
let resolvedTokens = providerTokens;
|
|
706
|
+
let tokenSource = resolvedTokens && Object.keys(resolvedTokens).length > 0 ? "build-time" : "none";
|
|
707
|
+
if (!resolvedTokens || Object.keys(resolvedTokens).length === 0) {
|
|
708
|
+
try {
|
|
709
|
+
resolvedTokens = await getProviderTokens();
|
|
710
|
+
if (resolvedTokens && Object.keys(resolvedTokens).length > 0) {
|
|
711
|
+
tokenSource = "request-header";
|
|
712
|
+
}
|
|
713
|
+
} catch {}
|
|
714
|
+
}
|
|
715
|
+
if (!resolvedTokens || Object.keys(resolvedTokens).length === 0) {
|
|
716
|
+
const oauthManager = client.oauthManager;
|
|
717
|
+
if (oauthManager) {
|
|
718
|
+
resolvedTokens = {};
|
|
719
|
+
const clientIntegrations = client.integrations || [];
|
|
720
|
+
for (const integration of clientIntegrations) {
|
|
721
|
+
if (integration.oauth) {
|
|
722
|
+
const provider = integration.oauth.provider;
|
|
723
|
+
try {
|
|
724
|
+
const tokenData = await oauthManager.getProviderToken(provider, undefined, context);
|
|
725
|
+
if (tokenData?.accessToken) {
|
|
726
|
+
resolvedTokens[provider] = tokenData.accessToken;
|
|
727
|
+
}
|
|
728
|
+
} catch {}
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
if (Object.keys(resolvedTokens).length === 0) {
|
|
732
|
+
resolvedTokens = undefined;
|
|
733
|
+
} else {
|
|
734
|
+
tokenSource = "oauthManager";
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
console.debug("[integrate-sdk] execute_code token resolution:", JSON.stringify({
|
|
739
|
+
source: tokenSource,
|
|
740
|
+
keys: resolvedTokens ? Object.keys(resolvedTokens) : [],
|
|
741
|
+
hasApiKey: !!apiKey,
|
|
742
|
+
mcpUrl
|
|
743
|
+
}));
|
|
619
744
|
return executeSandboxCode({
|
|
620
745
|
code,
|
|
621
746
|
mcpUrl,
|
|
622
747
|
apiKey,
|
|
623
|
-
providerTokens,
|
|
748
|
+
providerTokens: resolvedTokens,
|
|
624
749
|
context,
|
|
625
750
|
integrationsHeader: integrationIds && integrationIds.length > 0 ? integrationIds.join(",") : undefined,
|
|
626
751
|
runtime: sandboxOverrides.runtime ?? serverCodeModeConfig.runtime,
|
package/dist/server.js
CHANGED
|
@@ -1154,6 +1154,59 @@ function getEnv(key) {
|
|
|
1154
1154
|
return;
|
|
1155
1155
|
}
|
|
1156
1156
|
|
|
1157
|
+
// src/utils/request-tokens.ts
|
|
1158
|
+
async function getProviderTokens(manualTokens) {
|
|
1159
|
+
if (manualTokens) {
|
|
1160
|
+
return manualTokens;
|
|
1161
|
+
}
|
|
1162
|
+
let tokensString = null;
|
|
1163
|
+
if (!tokensString) {
|
|
1164
|
+
try {
|
|
1165
|
+
const getNextHeadersPath = () => {
|
|
1166
|
+
const parts = ["next", "/headers"];
|
|
1167
|
+
return parts.join("");
|
|
1168
|
+
};
|
|
1169
|
+
const nextHeaders = await import(getNextHeadersPath()).catch(() => null);
|
|
1170
|
+
if (nextHeaders && typeof nextHeaders.headers === "function") {
|
|
1171
|
+
const headersList = await Promise.resolve(nextHeaders.headers());
|
|
1172
|
+
tokensString = headersList.get("x-integrate-tokens");
|
|
1173
|
+
}
|
|
1174
|
+
} catch {}
|
|
1175
|
+
}
|
|
1176
|
+
if (!tokensString) {
|
|
1177
|
+
try {
|
|
1178
|
+
const getNuxtHeaders = new Function(`
|
|
1179
|
+
try {
|
|
1180
|
+
if (typeof useRequestHeaders === 'function') {
|
|
1181
|
+
return useRequestHeaders();
|
|
1182
|
+
}
|
|
1183
|
+
} catch {}
|
|
1184
|
+
return null;
|
|
1185
|
+
`);
|
|
1186
|
+
const headers = getNuxtHeaders();
|
|
1187
|
+
if (headers && typeof headers === "object") {
|
|
1188
|
+
tokensString = headers["x-integrate-tokens"];
|
|
1189
|
+
}
|
|
1190
|
+
} catch {}
|
|
1191
|
+
}
|
|
1192
|
+
if (!tokensString) {
|
|
1193
|
+
if (typeof process !== "undefined" && process.env) {
|
|
1194
|
+
tokensString = process.env.PROVIDER_TOKENS;
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
if (tokensString) {
|
|
1198
|
+
try {
|
|
1199
|
+
const parsed = JSON.parse(tokensString);
|
|
1200
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
1201
|
+
return parsed;
|
|
1202
|
+
}
|
|
1203
|
+
} catch (error) {
|
|
1204
|
+
throw new Error(`Failed to parse provider tokens: ${error instanceof Error ? error.message : "Invalid JSON"}`);
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
throw new Error("Provider tokens not found. Please pass tokens manually via options.providerTokens or set the x-integrate-tokens header in your request.");
|
|
1208
|
+
}
|
|
1209
|
+
|
|
1157
1210
|
// node_modules/nanoid/url-alphabet/index.js
|
|
1158
1211
|
var urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
|
|
1159
1212
|
var init_url_alphabet = () => {};
|
|
@@ -1481,6 +1534,19 @@ if (!MCP_URL) {
|
|
|
1481
1534
|
throw new Error('INTEGRATE_MCP_URL is not set — the sandbox cannot reach the MCP route.');
|
|
1482
1535
|
}
|
|
1483
1536
|
|
|
1537
|
+
// Diagnostic: log sandbox env summary to stderr so it shows up in the
|
|
1538
|
+
// execute_code result's stderr field for debugging auth issues.
|
|
1539
|
+
console.error('[sandbox-diag] MCP_URL=' + MCP_URL);
|
|
1540
|
+
console.error('[sandbox-diag] HAS_API_KEY=' + !!API_KEY);
|
|
1541
|
+
console.error('[sandbox-diag] HAS_SESSION_TOKEN=' + !!SESSION_TOKEN);
|
|
1542
|
+
console.error('[sandbox-diag] HAS_PROVIDER_TOKENS=' + !!PROVIDER_TOKENS);
|
|
1543
|
+
if (PROVIDER_TOKENS) {
|
|
1544
|
+
try {
|
|
1545
|
+
const _keys = Object.keys(JSON.parse(PROVIDER_TOKENS));
|
|
1546
|
+
console.error('[sandbox-diag] PROVIDER_TOKEN_KEYS=' + _keys.join(','));
|
|
1547
|
+
} catch { console.error('[sandbox-diag] PROVIDER_TOKENS is not valid JSON'); }
|
|
1548
|
+
}
|
|
1549
|
+
|
|
1484
1550
|
function camelToSnake(str) {
|
|
1485
1551
|
return str.replace(/[A-Z]/g, (letter) => '_' + letter.toLowerCase());
|
|
1486
1552
|
}
|
|
@@ -1496,6 +1562,14 @@ async function callTool(toolName, args) {
|
|
|
1496
1562
|
if (INTEGRATIONS_HEADER) headers['x-integrations'] = INTEGRATIONS_HEADER;
|
|
1497
1563
|
if (CONTEXT_JSON) headers['x-integrate-context'] = CONTEXT_JSON;
|
|
1498
1564
|
|
|
1565
|
+
console.error('[sandbox-diag] callTool: ' + toolName + ' → ' + MCP_URL);
|
|
1566
|
+
console.error('[sandbox-diag] headers: ' + JSON.stringify({
|
|
1567
|
+
hasAuth: !!headers['Authorization'],
|
|
1568
|
+
hasApiKey: !!headers['x-integrate-api-key'],
|
|
1569
|
+
hasTokens: !!headers['x-integrate-tokens'],
|
|
1570
|
+
hasCodeMode: !!headers['x-integrate-code-mode'],
|
|
1571
|
+
}));
|
|
1572
|
+
|
|
1499
1573
|
const res = await fetch(MCP_URL, {
|
|
1500
1574
|
method: 'POST',
|
|
1501
1575
|
headers,
|
|
@@ -1503,6 +1577,8 @@ async function callTool(toolName, args) {
|
|
|
1503
1577
|
});
|
|
1504
1578
|
|
|
1505
1579
|
const text = await res.text();
|
|
1580
|
+
console.error('[sandbox-diag] response: HTTP ' + res.status + ' len=' + text.length);
|
|
1581
|
+
|
|
1506
1582
|
let payload;
|
|
1507
1583
|
try {
|
|
1508
1584
|
payload = text ? JSON.parse(text) : null;
|
|
@@ -1694,6 +1770,16 @@ async function executeSandboxCode(options) {
|
|
|
1694
1770
|
env.INTEGRATE_INTEGRATIONS = options.integrationsHeader;
|
|
1695
1771
|
if (options.context)
|
|
1696
1772
|
env.INTEGRATE_CONTEXT = JSON.stringify(options.context);
|
|
1773
|
+
console.debug("[integrate-sdk] Sandbox env:", JSON.stringify({
|
|
1774
|
+
mcpUrl: options.mcpUrl,
|
|
1775
|
+
hasApiKey: !!options.apiKey,
|
|
1776
|
+
hasSessionToken: !!options.sessionToken,
|
|
1777
|
+
providerTokenKeys: options.providerTokens ? Object.keys(options.providerTokens) : [],
|
|
1778
|
+
hasIntegrations: !!options.integrationsHeader,
|
|
1779
|
+
hasContext: !!options.context,
|
|
1780
|
+
runtime,
|
|
1781
|
+
timeoutMs
|
|
1782
|
+
}));
|
|
1697
1783
|
const cmd = await sandbox.runCommand({
|
|
1698
1784
|
cmd: "node",
|
|
1699
1785
|
args: ["user.mjs"],
|
|
@@ -1804,11 +1890,50 @@ ${generated.compact}`;
|
|
|
1804
1890
|
};
|
|
1805
1891
|
}
|
|
1806
1892
|
const mcpUrl = publicUrl.replace(/\/$/, "") + "/api/integrate/mcp";
|
|
1893
|
+
let resolvedTokens = providerTokens;
|
|
1894
|
+
let tokenSource = resolvedTokens && Object.keys(resolvedTokens).length > 0 ? "build-time" : "none";
|
|
1895
|
+
if (!resolvedTokens || Object.keys(resolvedTokens).length === 0) {
|
|
1896
|
+
try {
|
|
1897
|
+
resolvedTokens = await getProviderTokens();
|
|
1898
|
+
if (resolvedTokens && Object.keys(resolvedTokens).length > 0) {
|
|
1899
|
+
tokenSource = "request-header";
|
|
1900
|
+
}
|
|
1901
|
+
} catch {}
|
|
1902
|
+
}
|
|
1903
|
+
if (!resolvedTokens || Object.keys(resolvedTokens).length === 0) {
|
|
1904
|
+
const oauthManager = client.oauthManager;
|
|
1905
|
+
if (oauthManager) {
|
|
1906
|
+
resolvedTokens = {};
|
|
1907
|
+
const clientIntegrations = client.integrations || [];
|
|
1908
|
+
for (const integration of clientIntegrations) {
|
|
1909
|
+
if (integration.oauth) {
|
|
1910
|
+
const provider = integration.oauth.provider;
|
|
1911
|
+
try {
|
|
1912
|
+
const tokenData = await oauthManager.getProviderToken(provider, undefined, context);
|
|
1913
|
+
if (tokenData?.accessToken) {
|
|
1914
|
+
resolvedTokens[provider] = tokenData.accessToken;
|
|
1915
|
+
}
|
|
1916
|
+
} catch {}
|
|
1917
|
+
}
|
|
1918
|
+
}
|
|
1919
|
+
if (Object.keys(resolvedTokens).length === 0) {
|
|
1920
|
+
resolvedTokens = undefined;
|
|
1921
|
+
} else {
|
|
1922
|
+
tokenSource = "oauthManager";
|
|
1923
|
+
}
|
|
1924
|
+
}
|
|
1925
|
+
}
|
|
1926
|
+
console.debug("[integrate-sdk] execute_code token resolution:", JSON.stringify({
|
|
1927
|
+
source: tokenSource,
|
|
1928
|
+
keys: resolvedTokens ? Object.keys(resolvedTokens) : [],
|
|
1929
|
+
hasApiKey: !!apiKey,
|
|
1930
|
+
mcpUrl
|
|
1931
|
+
}));
|
|
1807
1932
|
return executeSandboxCode({
|
|
1808
1933
|
code,
|
|
1809
1934
|
mcpUrl,
|
|
1810
1935
|
apiKey,
|
|
1811
|
-
providerTokens,
|
|
1936
|
+
providerTokens: resolvedTokens,
|
|
1812
1937
|
context,
|
|
1813
1938
|
integrationsHeader: integrationIds && integrationIds.length > 0 ? integrationIds.join(",") : undefined,
|
|
1814
1939
|
runtime: sandboxOverrides.runtime ?? serverCodeModeConfig.runtime,
|
|
@@ -9683,59 +9808,6 @@ var coerce = {
|
|
|
9683
9808
|
date: (arg) => ZodDate.create({ ...arg, coerce: true })
|
|
9684
9809
|
};
|
|
9685
9810
|
var NEVER = INVALID;
|
|
9686
|
-
// src/utils/request-tokens.ts
|
|
9687
|
-
async function getProviderTokens(manualTokens) {
|
|
9688
|
-
if (manualTokens) {
|
|
9689
|
-
return manualTokens;
|
|
9690
|
-
}
|
|
9691
|
-
let tokensString = null;
|
|
9692
|
-
if (!tokensString) {
|
|
9693
|
-
try {
|
|
9694
|
-
const getNextHeadersPath = () => {
|
|
9695
|
-
const parts = ["next", "/headers"];
|
|
9696
|
-
return parts.join("");
|
|
9697
|
-
};
|
|
9698
|
-
const nextHeaders = await import(getNextHeadersPath()).catch(() => null);
|
|
9699
|
-
if (nextHeaders && typeof nextHeaders.headers === "function") {
|
|
9700
|
-
const headersList = await Promise.resolve(nextHeaders.headers());
|
|
9701
|
-
tokensString = headersList.get("x-integrate-tokens");
|
|
9702
|
-
}
|
|
9703
|
-
} catch {}
|
|
9704
|
-
}
|
|
9705
|
-
if (!tokensString) {
|
|
9706
|
-
try {
|
|
9707
|
-
const getNuxtHeaders = new Function(`
|
|
9708
|
-
try {
|
|
9709
|
-
if (typeof useRequestHeaders === 'function') {
|
|
9710
|
-
return useRequestHeaders();
|
|
9711
|
-
}
|
|
9712
|
-
} catch {}
|
|
9713
|
-
return null;
|
|
9714
|
-
`);
|
|
9715
|
-
const headers = getNuxtHeaders();
|
|
9716
|
-
if (headers && typeof headers === "object") {
|
|
9717
|
-
tokensString = headers["x-integrate-tokens"];
|
|
9718
|
-
}
|
|
9719
|
-
} catch {}
|
|
9720
|
-
}
|
|
9721
|
-
if (!tokensString) {
|
|
9722
|
-
if (typeof process !== "undefined" && process.env) {
|
|
9723
|
-
tokensString = process.env.PROVIDER_TOKENS;
|
|
9724
|
-
}
|
|
9725
|
-
}
|
|
9726
|
-
if (tokensString) {
|
|
9727
|
-
try {
|
|
9728
|
-
const parsed = JSON.parse(tokensString);
|
|
9729
|
-
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
9730
|
-
return parsed;
|
|
9731
|
-
}
|
|
9732
|
-
} catch (error) {
|
|
9733
|
-
throw new Error(`Failed to parse provider tokens: ${error instanceof Error ? error.message : "Invalid JSON"}`);
|
|
9734
|
-
}
|
|
9735
|
-
}
|
|
9736
|
-
throw new Error("Provider tokens not found. Please pass tokens manually via options.providerTokens or set the x-integrate-tokens header in your request.");
|
|
9737
|
-
}
|
|
9738
|
-
|
|
9739
9811
|
// src/ai/utils.ts
|
|
9740
9812
|
function getProviderForTool(client, toolName) {
|
|
9741
9813
|
return client.getProviderForTool?.(toolName);
|
|
@@ -12102,6 +12174,23 @@ function createMCPServer(config) {
|
|
|
12102
12174
|
const tokensHeader = webRequest.headers.get("x-integrate-tokens");
|
|
12103
12175
|
const toolName = typeof body?.name === "string" ? body.name : "";
|
|
12104
12176
|
let tokensResolvedProvider = null;
|
|
12177
|
+
if (codeModeHeader === "1") {
|
|
12178
|
+
logger33.debug("[MCP Code Mode Callback]", JSON.stringify({
|
|
12179
|
+
toolName,
|
|
12180
|
+
hasAuthHeader: !!authHeader,
|
|
12181
|
+
hasTokensHeader: !!tokensHeader,
|
|
12182
|
+
tokenKeys: tokensHeader ? (() => {
|
|
12183
|
+
try {
|
|
12184
|
+
return Object.keys(JSON.parse(tokensHeader));
|
|
12185
|
+
} catch {
|
|
12186
|
+
return "PARSE_ERROR";
|
|
12187
|
+
}
|
|
12188
|
+
})() : [],
|
|
12189
|
+
hasApiKey: !!callbackApiKey,
|
|
12190
|
+
hasContext: !!contextHeader,
|
|
12191
|
+
hasIntegrations: !!integrationsHeader
|
|
12192
|
+
}));
|
|
12193
|
+
}
|
|
12105
12194
|
if (codeModeHeader === "1" && tokensHeader && toolName) {
|
|
12106
12195
|
try {
|
|
12107
12196
|
const tokens = JSON.parse(tokensHeader);
|