n8n
Version:
n8n Workflow Automation Tool
133 lines • 5.46 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.mapApprovalToSdk = mapApprovalToSdk;
exports.buildMcpClientForServer = buildMcpClientForServer;
exports.listMcpServerTools = listMcpServerTools;
const n8n_workflow_1 = require("n8n-workflow");
const auth_fetch_1 = require("../../../utils/auth-fetch");
function mapApprovalToSdk(approval) {
if (!approval)
return undefined;
if (approval.mode === 'global')
return true;
return approval.tools;
}
function isTokenData(tokenData) {
return (typeof tokenData === 'object' &&
tokenData !== null &&
'access_token' in tokenData &&
typeof tokenData.access_token === 'string');
}
function withCredentialData(headers, credentialData) {
return { headers, credentialData };
}
function deriveOAuth2Headers(resolved, credentialData) {
const tokenData = resolved.oauthTokenData;
return withCredentialData(isTokenData(tokenData) ? { Authorization: `Bearer ${tokenData.access_token}` } : {}, credentialData);
}
function deriveBearerHeaders(resolved, credentialData) {
const token = typeof resolved.token === 'string' ? resolved.token : '';
return withCredentialData(token ? { Authorization: `Bearer ${token}` } : {}, credentialData);
}
function deriveHeaderAuthHeaders(resolved, credentialData) {
const name = typeof resolved.name === 'string' ? resolved.name : '';
const value = typeof resolved.value === 'string' ? resolved.value : '';
return withCredentialData(name && value ? { [name]: value } : {}, credentialData);
}
function readMultipleHeaderValues(headers) {
if (!headers ||
typeof headers !== 'object' ||
!('values' in headers) ||
!Array.isArray(headers.values)) {
return undefined;
}
return headers.values;
}
function deriveMultipleHeadersAuthHeaders(resolved, credentialData) {
const values = readMultipleHeaderValues(resolved.headers);
if (!values)
return withCredentialData({}, credentialData);
const headers = {};
for (const entry of values) {
if (typeof entry.name === 'string' && typeof entry.value === 'string') {
headers[entry.name] = entry.value;
}
}
return withCredentialData(headers, credentialData);
}
function deriveHeadersForAuthentication(server, resolved, credentialData) {
if ((0, n8n_workflow_1.isMcpOAuth2Authentication)(server.authentication)) {
return deriveOAuth2Headers(resolved, credentialData);
}
switch (server.authentication) {
case 'bearerAuth':
return deriveBearerHeaders(resolved, credentialData);
case 'headerAuth':
return deriveHeaderAuthHeaders(resolved, credentialData);
case 'multipleHeadersAuth':
return deriveMultipleHeadersAuthHeaders(resolved, credentialData);
default:
return withCredentialData({}, credentialData);
}
}
async function deriveAuthHeaders(server, credentialProvider) {
if (server.authentication === 'none' || !server.credential)
return { headers: {} };
const resolved = await credentialProvider.resolve(server.credential).catch(() => null);
if (!resolved)
return { headers: {} };
const credentialData = resolved;
return deriveHeadersForAuthentication(server, credentialData, credentialData);
}
async function buildMcpClientForServer(server, deps) {
const { credentialProvider, oauthService, projectId, proxyFetch, onConnectionFailed, onToolCallSettled, } = deps;
const { McpClient } = await import('@n8n/agents');
const { headers: initialHeaders, credentialData } = await deriveAuthHeaders(server, credentialProvider);
const allowedDomains = credentialData ? (0, auth_fetch_1.resolveAllowedDomains)(credentialData) : undefined;
const onUnauthorized = (0, n8n_workflow_1.isMcpOAuth2Authentication)(server.authentication) && server.credential
? async () => {
const credentialId = server.credential;
if (!credentialId)
return null;
return await oauthService
.refreshOAuth2CredentialById(credentialId, projectId)
.catch(() => null);
}
: undefined;
const authFetch = (0, auth_fetch_1.createAuthFetch)({
baseFetch: proxyFetch,
initialHeaders,
onUnauthorized,
allowedDomains,
});
const sdkServerConfig = {
name: server.name,
url: server.url,
transport: server.transport,
fetch: authFetch,
toolFilter: server.toolFilter,
requireApproval: mapApprovalToSdk(server.approval),
...(onToolCallSettled !== undefined && { onToolCallSettled }),
...(server.connectionTimeoutMs !== undefined && {
connectionTimeoutMs: server.connectionTimeoutMs,
}),
...(onConnectionFailed
? {
onConnectionFailed: (event) => onConnectionFailed(event),
}
: {}),
};
return new McpClient([sdkServerConfig]);
}
async function listMcpServerTools(server, deps) {
let client;
try {
client = await buildMcpClientForServer(server, deps);
const tools = await client.listTools();
return tools.map((tool) => ({ name: tool.name, description: tool.description ?? '' }));
}
finally {
await client?.close().catch(() => { });
}
}
//# sourceMappingURL=mcp-client-factory.js.map