UNPKG

n8n

Version:

n8n Workflow Automation Tool

211 lines 8.15 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MCP_BASE_OAUTH2_CREDENTIAL_NAME = exports.MCP_REGISTRY_BASE_NODE_NAME = exports.LANGCHAIN_PACKAGE_NAME = exports.MCP_REGISTRY_PACKAGE_NAME = void 0; exports.getMcpRegistryCredentialTypeName = getMcpRegistryCredentialTypeName; exports.serverToCredentialDescription = serverToCredentialDescription; exports.serverToNodeDescription = serverToNodeDescription; const change_case_1 = require("change-case"); const mcp_registry_types_1 = require("./registry/mcp-registry.types"); exports.MCP_REGISTRY_PACKAGE_NAME = '@n8n/mcp-registry'; exports.LANGCHAIN_PACKAGE_NAME = '@n8n/n8n-nodes-langchain'; exports.MCP_REGISTRY_BASE_NODE_NAME = 'mcpRegistryClientTool'; exports.MCP_BASE_OAUTH2_CREDENTIAL_NAME = 'mcpOAuth2Api'; function getMcpRegistryNodeTypeName(server) { return (0, change_case_1.camelCase)(server.slug); } function getMcpRegistryCredentialTypeName(server) { return `${(0, change_case_1.camelCase)(server.slug)}McpOAuth2Api`; } function getMcpRegistryCredentialHeader(server) { return { name: getMcpRegistryCredentialTypeName(server), icon: `node:${exports.MCP_REGISTRY_PACKAGE_NAME}.${getMcpRegistryNodeTypeName(server)}`, displayName: `${server.title} MCP OAuth2`, }; } function resolveCredentialRemote(server) { const remote = pickRemote(server); if (!remote) return null; try { return { endpointUrl: remote.endpointUrl, hostname: new URL(remote.endpointUrl).hostname }; } catch { return null; } } function buildDomainRestrictionProperties(hostname) { return [ { displayName: 'Allowed HTTP Request Domains', name: 'allowedHttpRequestDomains', type: 'hidden', default: 'domains', }, { displayName: 'Allowed Domains', name: 'allowedDomains', type: 'hidden', default: hostname, }, ]; } function serverToOAuth2CredentialDescription(server) { const remote = resolveCredentialRemote(server); if (!remote) return null; return { ...getMcpRegistryCredentialHeader(server), extends: [exports.MCP_BASE_OAUTH2_CREDENTIAL_NAME], properties: [ { displayName: 'Use Dynamic Client Registration', name: 'useDynamicClientRegistration', type: 'hidden', default: true, }, { displayName: 'Server URL', name: 'serverUrl', type: 'hidden', default: remote.endpointUrl, }, { displayName: 'Resource URL', name: 'resourceUrl', type: 'hidden', default: '', }, ...buildDomainRestrictionProperties(remote.hostname), ], }; } function getValidatedExtendsCredential(server, isKnownCredentialType) { if (!server.extendsCredential) return null; const parseResult = mcp_registry_types_1.mcpRegistryExtendsCredentialSchema.safeParse(server.extendsCredential); if (!parseResult.success) return null; const { extends: parentType, ...rawOverrides } = parseResult.data; if (!isKnownCredentialType(parentType)) return null; const overrides = Object.fromEntries(Object.entries(rawOverrides).filter(([, value]) => value !== null && value !== undefined)); return { parentType, overrides }; } function serverToExtendedCredentialDescription(server, isKnownCredentialType) { const validated = getValidatedExtendsCredential(server, isKnownCredentialType); if (!validated) return null; const remote = resolveCredentialRemote(server); if (!remote) return null; const overrideProperties = Object.entries(validated.overrides).map(([name, value]) => ({ displayName: name, name, type: 'hidden', default: value, })); return { ...getMcpRegistryCredentialHeader(server), extends: [validated.parentType], properties: [...overrideProperties, ...buildDomainRestrictionProperties(remote.hostname)], }; } function getNodeDescriptionCredentials(server, isKnownCredentialType) { switch (server.authType) { case 'oauth2': return [{ name: getMcpRegistryCredentialTypeName(server), required: true }]; case 'extendsCredential': { const validated = getValidatedExtendsCredential(server, isKnownCredentialType); if (!validated) return []; return [{ name: getMcpRegistryCredentialTypeName(server), required: true }]; } default: return []; } } function pickRemote(server) { const streamable = server.remotes.find((r) => r.type === 'streamable-http'); if (streamable) return { transport: 'httpStreamable', endpointUrl: streamable.url }; const sse = server.remotes.find((r) => r.type === 'sse'); if (sse) return { transport: 'sse', endpointUrl: sse.url }; return null; } const ICON_MIME_PREFERENCE = [ 'image/svg+xml', 'image/webp', 'image/png', 'image/jpeg', 'image/jpg', ]; function preferredIcon(icons) { for (const mimeType of ICON_MIME_PREFERENCE) { const match = icons.find((icon) => icon.mimeType === mimeType); if (match) return match; } return icons[0]; } function pickIconUrl(icons) { const light = preferredIcon(icons.filter((icon) => icon.theme === 'light')); const dark = preferredIcon(icons.filter((icon) => icon.theme === 'dark')); if (light && dark) return { light: light.src, dark: dark.src }; return preferredIcon(icons)?.src; } function withRemoteDefaults(properties, transport, endpointUrl) { return properties.map((prop) => { if (prop.name === 'endpointUrl') return { ...prop, default: endpointUrl }; if (prop.name === 'serverTransport') return { ...prop, default: transport }; return prop; }); } function serverToCredentialDescription(server, isKnownCredentialType) { switch (server.authType) { case 'oauth2': return serverToOAuth2CredentialDescription(server); case 'extendsCredential': return serverToExtendedCredentialDescription(server, isKnownCredentialType); default: return null; } } function serverToNodeDescription(server, baseDescription, isKnownCredentialType) { if (server.authType !== 'oauth2' && server.authType !== 'extendsCredential') return null; const remote = pickRemote(server); if (!remote) return null; const displayName = `${server.title} MCP`; const description = structuredClone(baseDescription); if (server.status === 'deprecated') { description.hidden = true; } else { delete description.hidden; } description.displayName = displayName; description.name = (0, change_case_1.camelCase)(server.slug); description.iconUrl = pickIconUrl(server.icons); description.description = server.tagline; description.defaults = { name: displayName }; description.credentials = getNodeDescriptionCredentials(server, isKnownCredentialType); if (description.codex) { description.codex.alias?.push(server.title, displayName); if (server.websiteUrl) { description.codex.resources = { primaryDocumentation: [{ url: server.websiteUrl }] }; } } description.properties = withRemoteDefaults(description.properties, remote.transport, remote.endpointUrl); description.builderHint = { ...description.builderHint, searchHint: `Agent-optimised ${server.title} integration. When wiring an ai_tool to an AI Agent for ${server.title}, use THIS node, not the native action node — this variant exposes ${server.title}'s tools in the shape AI Agents expect and ships pre-configured connection details.`, }; return description; } //# sourceMappingURL=node-description-transform.js.map