n8n-nodes-browser-smart-automation 0.1.5 → 0.1.8

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.
Files changed (36) hide show
  1. package/dist/{McpClient → McpClientEX}/McpClient.node.js +5 -5
  2. package/dist/McpClientEX/McpClient.node.js.map +1 -0
  3. package/dist/McpClientEX/listSearch.js.map +1 -0
  4. package/dist/McpClientEX/resourceMapping.js.map +1 -0
  5. package/dist/McpClientEX/utils.js.map +1 -0
  6. package/dist/{McpClientTool → McpClientToolEX}/McpClientTool.node.js +21 -9
  7. package/dist/McpClientToolEX/McpClientTool.node.js.map +1 -0
  8. package/dist/McpClientToolEX/loadOptions.js.map +1 -0
  9. package/dist/McpClientToolEX/types.js.map +1 -0
  10. package/dist/McpClientToolEX/utils.js.map +1 -0
  11. package/dist/McpTriggerEX/FlushingTransport.js.map +1 -0
  12. package/dist/McpTriggerEX/McpServer.js.map +1 -0
  13. package/dist/{McpTrigger → McpTriggerEX}/McpTrigger.node.js +7 -7
  14. package/dist/McpTriggerEX/McpTrigger.node.js.map +1 -0
  15. package/package.json +8 -6
  16. package/dist/McpClient/McpClient.node.js.map +0 -1
  17. package/dist/McpClient/listSearch.js.map +0 -1
  18. package/dist/McpClient/resourceMapping.js.map +0 -1
  19. package/dist/McpClient/utils.js.map +0 -1
  20. package/dist/McpClientTool/McpClientTool.node.js.map +0 -1
  21. package/dist/McpClientTool/loadOptions.js.map +0 -1
  22. package/dist/McpClientTool/types.js.map +0 -1
  23. package/dist/McpClientTool/utils.js.map +0 -1
  24. package/dist/McpTrigger/FlushingTransport.js.map +0 -1
  25. package/dist/McpTrigger/McpServer.js.map +0 -1
  26. package/dist/McpTrigger/McpTrigger.node.js.map +0 -1
  27. /package/dist/{McpClient → McpClientEX}/listSearch.js +0 -0
  28. /package/dist/{McpClient → McpClientEX}/resourceMapping.js +0 -0
  29. /package/dist/{McpClient → McpClientEX}/utils.js +0 -0
  30. /package/dist/{McpClientTool → McpClientToolEX}/loadOptions.js +0 -0
  31. /package/dist/{McpClientTool → McpClientToolEX}/types.js +0 -0
  32. /package/dist/{McpClientTool → McpClientToolEX}/utils.js +0 -0
  33. /package/dist/{McpTrigger → McpTriggerEX}/FlushingTransport.js +0 -0
  34. /package/dist/{McpTrigger → McpTriggerEX}/McpServer.js +0 -0
  35. /package/nodes/{mcp.dark.svg → assets/mcp.dark.svg} +0 -0
  36. /package/nodes/{mcp.svg → assets/mcp.svg} +0 -0
@@ -40,17 +40,17 @@ var import_descriptions = require("../shared/descriptions");
40
40
  var import_utils = require("../shared/utils");
41
41
  class McpClient {
42
42
  description = {
43
- displayName: "MCP Client",
44
- description: "Standalone MCP Client",
43
+ displayName: "MCP Browser Client",
44
+ description: "Standalone MCP Browser Client",
45
45
  name: "mcpClient",
46
46
  icon: {
47
- light: "file:../mcp.svg",
48
- dark: "file:../mcp.dark.svg"
47
+ light: "file:../assets/mcp.svg",
48
+ dark: "file:../assets/mcp.dark.svg"
49
49
  },
50
50
  group: ["transform"],
51
51
  version: 1,
52
52
  defaults: {
53
- name: "MCP Client"
53
+ name: "MCP Browser Client"
54
54
  },
55
55
  credentials: import_descriptions.credentials,
56
56
  inputs: [import_n8n_workflow.NodeConnectionTypes.Main],
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../nodes/McpClientEX/McpClient.node.ts"],"sourcesContent":["import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\nimport type {\n\tIBinaryKeyData,\n\tIDataObject,\n\tIExecuteFunctions,\n\tINodeExecutionData,\n\tINodeType,\n\tINodeTypeDescription,\n\tNodeExecutionWithMetadata,\n} from 'n8n-workflow';\nimport { jsonParse, NodeConnectionTypes, NodeOperationError } from 'n8n-workflow';\nimport { ZodError } from 'zod';\nimport { prettifyError } from 'zod/v4/core';\nimport * as listSearch from './listSearch';\nimport * as resourceMapping from './resourceMapping';\nimport { credentials, transportSelect } from '../shared/descriptions';\nimport type { McpAuthenticationOption, McpServerTransport } from '../shared/types';\nimport {\n\tgetAuthHeaders,\n\ttryRefreshOAuth2Token,\n\tconnectMcpClient,\n\tmapToNodeOperationError,\n} from '../shared/utils';\n\nexport class McpClient implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'MCP Browser Client',\n\t\tdescription: 'Standalone MCP Browser Client',\n\t\tname: 'mcpClient',\n\t\ticon: {\n\t\t\tlight: 'file:../assets/mcp.svg',\n\t\t\tdark: 'file:../assets/mcp.dark.svg',\n\t\t},\n\t\tgroup: ['transform'],\n\t\tversion: 1,\n\t\tdefaults: {\n\t\t\tname: 'MCP Browser Client',\n\t\t},\n\t\tcredentials,\n\t\tinputs: [NodeConnectionTypes.Main],\n\t\toutputs: [NodeConnectionTypes.Main],\n\t\tproperties: [\n\t\t\ttransportSelect({\n\t\t\t\tdefaultOption: 'httpStreamable',\n\t\t\t}),\n\t\t\t{\n\t\t\t\tdisplayName: 'MCP Endpoint URL',\n\t\t\t\tname: 'endpointUrl',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '',\n\t\t\t\tplaceholder: 'e.g. https://my-mcp-server.ai/mcp',\n\t\t\t\trequired: true,\n\t\t\t\tdescription: 'The URL of the MCP server to connect to',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Authentication',\n\t\t\t\tname: 'authentication',\n\t\t\t\ttype: 'options',\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Bearer Auth',\n\t\t\t\t\t\tvalue: 'bearerAuth',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Header Auth',\n\t\t\t\t\t\tvalue: 'headerAuth',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'MCP OAuth2',\n\t\t\t\t\t\tvalue: 'mcpOAuth2Api',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Multiple Headers Auth',\n\t\t\t\t\t\tvalue: 'multipleHeadersAuth',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'None',\n\t\t\t\t\t\tvalue: 'none',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tdefault: 'none',\n\t\t\t\tdescription: 'The way to authenticate with your endpoint',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Credentials',\n\t\t\t\tname: 'credentials',\n\t\t\t\ttype: 'credentials',\n\t\t\t\tdefault: '',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tauthentication: ['headerAuth', 'bearerAuth', 'mcpOAuth2Api', 'multipleHeadersAuth'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Tool',\n\t\t\t\tname: 'tool',\n\t\t\t\ttype: 'resourceLocator',\n\t\t\t\tdefault: { mode: 'list', value: '' },\n\t\t\t\trequired: true,\n\t\t\t\tdescription: 'The tool to use',\n\t\t\t\tmodes: [\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'From List',\n\t\t\t\t\t\tname: 'list',\n\t\t\t\t\t\ttype: 'list',\n\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\tsearchListMethod: 'getTools',\n\t\t\t\t\t\t\tsearchable: true,\n\t\t\t\t\t\t\tskipCredentialsCheckInRLC: true,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'ID',\n\t\t\t\t\t\tname: 'id',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Input Mode',\n\t\t\t\tname: 'inputMode',\n\t\t\t\ttype: 'options',\n\t\t\t\tdefault: 'manual',\n\t\t\t\tnoDataExpression: true,\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Manual',\n\t\t\t\t\t\tvalue: 'manual',\n\t\t\t\t\t\tdescription: 'Manually specify the input data for each tool parameter',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'JSON',\n\t\t\t\t\t\tvalue: 'json',\n\t\t\t\t\t\tdescription: 'Specify the input data as a JSON object',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Parameters',\n\t\t\t\tname: 'parameters',\n\t\t\t\ttype: 'resourceMapper',\n\t\t\t\tdefault: {\n\t\t\t\t\tmappingMode: 'defineBelow',\n\t\t\t\t\tvalue: null,\n\t\t\t\t},\n\t\t\t\tnoDataExpression: true,\n\t\t\t\trequired: true,\n\t\t\t\ttypeOptions: {\n\t\t\t\t\tloadOptionsDependsOn: ['tool.value'],\n\t\t\t\t\tresourceMapper: {\n\t\t\t\t\t\tresourceMapperMethod: 'getToolParameters',\n\t\t\t\t\t\thideNoDataError: true,\n\t\t\t\t\t\taddAllFields: false,\n\t\t\t\t\t\tsupportAutoMap: false,\n\t\t\t\t\t\tmode: 'add',\n\t\t\t\t\t\tfieldWords: {\n\t\t\t\t\t\t\tsingular: 'parameter',\n\t\t\t\t\t\t\tplural: 'parameters',\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tinputMode: ['manual'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'JSON',\n\t\t\t\tname: 'jsonInput',\n\t\t\t\ttype: 'json',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\trows: 5,\n\t\t\t\t},\n\t\t\t\tdefault: '{\\n \"my_field_1\": \"value\",\\n \"my_field_2\": 1\\n}\\n',\n\t\t\t\tvalidateType: 'object',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tinputMode: ['json'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Options',\n\t\t\t\tname: 'options',\n\t\t\t\tplaceholder: 'Add Option',\n\t\t\t\tdescription: 'Additional options to add',\n\t\t\t\ttype: 'collection',\n\t\t\t\tdefault: {},\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Convert to Binary',\n\t\t\t\t\t\tname: 'convertToBinary',\n\t\t\t\t\t\ttype: 'boolean',\n\t\t\t\t\t\tdefault: true,\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Whether to convert images and audio to binary data. If false, images and audio will be returned as base64 encoded strings.',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Timeout',\n\t\t\t\t\t\tname: 'timeout',\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\tminValue: 1,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdefault: 60000,\n\t\t\t\t\t\tdescription: 'Time in ms to wait for tool calls to finish',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t};\n\n\tmethods = {\n\t\tlistSearch,\n\t\tresourceMapping,\n\t};\n\n\tasync execute(\n\t\tthis: IExecuteFunctions,\n\t): Promise<INodeExecutionData[][] | NodeExecutionWithMetadata[][] | null> {\n\t\tconst authentication = this.getNodeParameter('authentication', 0) as McpAuthenticationOption;\n\t\tconst serverTransport = this.getNodeParameter('serverTransport', 0) as McpServerTransport;\n\t\tconst endpointUrl = this.getNodeParameter('endpointUrl', 0) as string;\n\t\tconst node = this.getNode();\n\t\tconst { headers } = await getAuthHeaders(this, authentication);\n\t\tconst client = await connectMcpClient({\n\t\t\tserverTransport,\n\t\t\tendpointUrl,\n\t\t\theaders,\n\t\t\tname: node.type,\n\t\t\tversion: node.typeVersion,\n\t\t\tonUnauthorized: async (headers) => await tryRefreshOAuth2Token(this, authentication, headers),\n\t\t});\n\t\tif (!client.ok) {\n\t\t\tthrow mapToNodeOperationError(node, client.error);\n\t\t}\n\n\t\tconst inputMode = this.getNodeParameter('inputMode', 0, 'manual') as 'manual' | 'json';\n\t\tconst items = this.getInputData();\n\t\tconst returnData: INodeExecutionData[] = [];\n\t\tfor (let itemIndex = 0; itemIndex < items.length; itemIndex++) {\n\t\t\ttry {\n\t\t\t\tconst tool = this.getNodeParameter('tool.value', itemIndex) as string;\n\t\t\t\tconst options = this.getNodeParameter('options', itemIndex);\n\t\t\t\tlet parameters: IDataObject = {};\n\t\t\t\tif (inputMode === 'manual') {\n\t\t\t\t\tparameters = this.getNodeParameter('parameters.value', itemIndex) as IDataObject;\n\t\t\t\t} else {\n\t\t\t\t\tparameters = this.getNodeParameter('jsonInput', itemIndex) as IDataObject;\n\t\t\t\t}\n\n\t\t\t\tconst result = (await client.result.callTool(\n\t\t\t\t\t{\n\t\t\t\t\t\tname: tool,\n\t\t\t\t\t\targuments: parameters,\n\t\t\t\t\t},\n\t\t\t\t\tundefined,\n\t\t\t\t\t{\n\t\t\t\t\t\ttimeout: options.timeout ? Number(options.timeout) : undefined,\n\t\t\t\t\t},\n\t\t\t\t)) as CallToolResult;\n\n\t\t\t\tlet binaryIndex = 0;\n\t\t\t\tconst binary: IBinaryKeyData = {};\n\t\t\t\tconst content: IDataObject[] = [];\n\t\t\t\tconst convertToBinary = options.convertToBinary ?? true;\n\t\t\t\tfor (const contentItem of result.content) {\n\t\t\t\t\tif (contentItem.type === 'text') {\n\t\t\t\t\t\tcontent.push({\n\t\t\t\t\t\t\t...contentItem,\n\t\t\t\t\t\t\ttext: jsonParse(contentItem.text, { fallbackValue: contentItem.text }),\n\t\t\t\t\t\t});\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (convertToBinary && (contentItem.type === 'image' || contentItem.type === 'audio')) {\n\t\t\t\t\t\tbinary[`data_${binaryIndex}`] = await this.helpers.prepareBinaryData(\n\t\t\t\t\t\t\tBuffer.from(contentItem.data, 'base64'),\n\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\tcontentItem.mimeType,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tbinaryIndex++;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tcontent.push(contentItem as IDataObject);\n\t\t\t\t}\n\n\t\t\t\treturnData.push({\n\t\t\t\t\tjson: {\n\t\t\t\t\t\tcontent: content.length > 0 ? content : undefined,\n\t\t\t\t\t},\n\t\t\t\t\tbinary: Object.keys(binary).length > 0 ? binary : undefined,\n\t\t\t\t\tpairedItem: {\n\t\t\t\t\t\titem: itemIndex,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t} catch (e) {\n\t\t\t\tconst errorMessage =\n\t\t\t\t\te instanceof ZodError ? prettifyError(e) : e instanceof Error ? e.message : String(e);\n\t\t\t\tif (this.continueOnFail()) {\n\t\t\t\t\treturnData.push({\n\t\t\t\t\t\tjson: {\n\t\t\t\t\t\t\terror: {\n\t\t\t\t\t\t\t\tmessage: errorMessage,\n\t\t\t\t\t\t\t\tissues: e instanceof ZodError ? e.issues : undefined,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tpairedItem: {\n\t\t\t\t\t\t\titem: itemIndex,\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tthrow new NodeOperationError(node, errorMessage, {\n\t\t\t\t\titemIndex,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn [returnData];\n\t}\n}\n"],"mappings":"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","names":["headers"]}
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../nodes/McpClientEX/listSearch.ts"],"sourcesContent":["import type { ILoadOptionsFunctions, INodeListSearchResult } from 'n8n-workflow';\n\nimport type { McpAuthenticationOption, McpServerTransport } from '../shared/types';\nimport {\n\tconnectMcpClient,\n\tgetAuthHeaders,\n\tmapToNodeOperationError,\n\ttryRefreshOAuth2Token,\n} from '../shared/utils';\n\nexport async function getTools(\n\tthis: ILoadOptionsFunctions,\n\tfilter?: string,\n\tpaginationToken?: string,\n): Promise<INodeListSearchResult> {\n\tconst authentication = this.getNodeParameter('authentication') as McpAuthenticationOption;\n\tconst serverTransport = this.getNodeParameter('serverTransport') as McpServerTransport;\n\tconst endpointUrl = this.getNodeParameter('endpointUrl') as string;\n\tconst node = this.getNode();\n\tconst { headers } = await getAuthHeaders(this, authentication);\n\tconst client = await connectMcpClient({\n\t\tserverTransport,\n\t\tendpointUrl,\n\t\theaders,\n\t\tname: node.type,\n\t\tversion: node.typeVersion,\n\t\tonUnauthorized: async (headers) => await tryRefreshOAuth2Token(this, authentication, headers),\n\t});\n\n\tif (!client.ok) {\n\t\tthrow mapToNodeOperationError(node, client.error);\n\t}\n\n\tconst result = await client.result.listTools({ cursor: paginationToken });\n\tconst tools = filter\n\t\t? result.tools.filter((tool) => tool.name.toLowerCase().includes(filter.toLowerCase()))\n\t\t: result.tools;\n\n\treturn {\n\t\tresults: tools.map((tool) => ({\n\t\t\tname: tool.name,\n\t\t\tvalue: tool.name,\n\t\t\tdescription: tool.description,\n\t\t\tinputSchema: tool.inputSchema,\n\t\t})),\n\t\tpaginationToken: result.nextCursor,\n\t};\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,mBAKO;AAEP,eAAsB,SAErB,QACA,iBACiC;AACjC,QAAM,iBAAiB,KAAK,iBAAiB,gBAAgB;AAC7D,QAAM,kBAAkB,KAAK,iBAAiB,iBAAiB;AAC/D,QAAM,cAAc,KAAK,iBAAiB,aAAa;AACvD,QAAM,OAAO,KAAK,QAAQ;AAC1B,QAAM,EAAE,QAAQ,IAAI,UAAM,6BAAe,MAAM,cAAc;AAC7D,QAAM,SAAS,UAAM,+BAAiB;AAAA,IACrC;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM,KAAK;AAAA,IACX,SAAS,KAAK;AAAA,IACd,gBAAgB,OAAOA,aAAY,UAAM,oCAAsB,MAAM,gBAAgBA,QAAO;AAAA,EAC7F,CAAC;AAED,MAAI,CAAC,OAAO,IAAI;AACf,cAAM,sCAAwB,MAAM,OAAO,KAAK;AAAA,EACjD;AAEA,QAAM,SAAS,MAAM,OAAO,OAAO,UAAU,EAAE,QAAQ,gBAAgB,CAAC;AACxE,QAAM,QAAQ,SACX,OAAO,MAAM,OAAO,CAAC,SAAS,KAAK,KAAK,YAAY,EAAE,SAAS,OAAO,YAAY,CAAC,CAAC,IACpF,OAAO;AAEV,SAAO;AAAA,IACN,SAAS,MAAM,IAAI,CAAC,UAAU;AAAA,MAC7B,MAAM,KAAK;AAAA,MACX,OAAO,KAAK;AAAA,MACZ,aAAa,KAAK;AAAA,MAClB,aAAa,KAAK;AAAA,IACnB,EAAE;AAAA,IACF,iBAAiB,OAAO;AAAA,EACzB;AACD;","names":["headers"]}
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../nodes/McpClientEX/resourceMapping.ts"],"sourcesContent":["import type { ILoadOptionsFunctions, ResourceMapperFields } from 'n8n-workflow';\nimport { NodeOperationError } from 'n8n-workflow';\n\nimport { convertJsonSchemaToResourceMapperFields } from './utils';\nimport type { McpAuthenticationOption, McpServerTransport } from '../shared/types';\nimport {\n\tgetAuthHeaders,\n\tconnectMcpClient,\n\tgetAllTools,\n\ttryRefreshOAuth2Token,\n\tmapToNodeOperationError,\n} from '../shared/utils';\n\nexport async function getToolParameters(\n\tthis: ILoadOptionsFunctions,\n): Promise<ResourceMapperFields> {\n\tconst toolId = this.getNodeParameter('tool', 0, {\n\t\textractValue: true,\n\t}) as string;\n\tconst authentication = this.getNodeParameter('authentication') as McpAuthenticationOption;\n\tconst serverTransport = this.getNodeParameter('serverTransport') as McpServerTransport;\n\tconst endpointUrl = this.getNodeParameter('endpointUrl') as string;\n\tconst node = this.getNode();\n\tconst { headers } = await getAuthHeaders(this, authentication);\n\tconst client = await connectMcpClient({\n\t\tserverTransport,\n\t\tendpointUrl,\n\t\theaders,\n\t\tname: node.type,\n\t\tversion: node.typeVersion,\n\t\tonUnauthorized: async (headers) => await tryRefreshOAuth2Token(this, authentication, headers),\n\t});\n\n\tif (!client.ok) {\n\t\tthrow mapToNodeOperationError(node, client.error);\n\t}\n\n\tconst result = await getAllTools(client.result);\n\tconst tool = result.find((tool) => tool.name === toolId);\n\tif (!tool) {\n\t\tthrow new NodeOperationError(this.getNode(), 'Tool not found');\n\t}\n\n\tconst fields = convertJsonSchemaToResourceMapperFields(tool.inputSchema);\n\treturn {\n\t\tfields,\n\t};\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,0BAAmC;AAEnC,mBAAwD;AAExD,IAAAA,gBAMO;AAEP,eAAsB,oBAEW;AAChC,QAAM,SAAS,KAAK,iBAAiB,QAAQ,GAAG;AAAA,IAC/C,cAAc;AAAA,EACf,CAAC;AACD,QAAM,iBAAiB,KAAK,iBAAiB,gBAAgB;AAC7D,QAAM,kBAAkB,KAAK,iBAAiB,iBAAiB;AAC/D,QAAM,cAAc,KAAK,iBAAiB,aAAa;AACvD,QAAM,OAAO,KAAK,QAAQ;AAC1B,QAAM,EAAE,QAAQ,IAAI,UAAM,8BAAe,MAAM,cAAc;AAC7D,QAAM,SAAS,UAAM,gCAAiB;AAAA,IACrC;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM,KAAK;AAAA,IACX,SAAS,KAAK;AAAA,IACd,gBAAgB,OAAOC,aAAY,UAAM,qCAAsB,MAAM,gBAAgBA,QAAO;AAAA,EAC7F,CAAC;AAED,MAAI,CAAC,OAAO,IAAI;AACf,cAAM,uCAAwB,MAAM,OAAO,KAAK;AAAA,EACjD;AAEA,QAAM,SAAS,UAAM,2BAAY,OAAO,MAAM;AAC9C,QAAM,OAAO,OAAO,KAAK,CAACC,UAASA,MAAK,SAAS,MAAM;AACvD,MAAI,CAAC,MAAM;AACV,UAAM,IAAI,uCAAmB,KAAK,QAAQ,GAAG,gBAAgB;AAAA,EAC9D;AAEA,QAAM,aAAS,sDAAwC,KAAK,WAAW;AACvE,SAAO;AAAA,IACN;AAAA,EACD;AACD;","names":["import_utils","headers","tool"]}
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../nodes/McpClientEX/utils.ts"],"sourcesContent":["import type { JSONSchema7, JSONSchema7Definition } from 'json-schema';\nimport type {\n\tResourceMapperField,\n\tFieldType,\n\tINodePropertyOptions,\n\tIDataObject,\n} from 'n8n-workflow';\n\nfunction pickFirstSchema(schema: JSONSchema7Definition): JSONSchema7Definition {\n\tif (typeof schema === 'object' && (schema?.anyOf || schema?.oneOf)) {\n\t\tif (Array.isArray(schema.anyOf) && schema.anyOf[0] !== undefined) {\n\t\t\treturn schema.anyOf[0];\n\t\t}\n\n\t\tif (Array.isArray(schema.oneOf) && schema.oneOf[0] !== undefined) {\n\t\t\treturn schema.oneOf[0];\n\t\t}\n\t}\n\n\treturn schema;\n}\n\nfunction mergeTwoSchemas(\n\ta?: JSONSchema7Definition,\n\tb?: JSONSchema7Definition,\n): JSONSchema7Definition | undefined {\n\tif (a === undefined) {\n\t\treturn b;\n\t}\n\n\tif (b === undefined) {\n\t\treturn a;\n\t}\n\n\ta = pickFirstSchema(a);\n\tb = pickFirstSchema(b);\n\tif (a === false || b === false) {\n\t\treturn false;\n\t}\n\n\tif (a === true || b === true) {\n\t\treturn true;\n\t}\n\n\tif (a.type === 'object' && b.type === 'object') {\n\t\tconst properties = { ...(a.properties ?? {}), ...(b.properties ?? {}) };\n\t\tconst required = [...(a.required ?? []), ...(b.required ?? [])];\n\t\tconst additionalProperties = mergeTwoSchemas(a.additionalProperties, b.additionalProperties);\n\t\treturn { ...a, ...b, properties, required, additionalProperties };\n\t}\n\n\tif (a.type === 'array' && b.type === 'array') {\n\t\tif (Array.isArray(a.items) && Array.isArray(b.items)) {\n\t\t\t// Two tuples -> pick the longer one\n\t\t\treturn a.items.length > b.items.length ? a : b;\n\t\t}\n\n\t\tif (Array.isArray(a.items) || Array.isArray(b.items)) {\n\t\t\t// One tuple -> pick the tuple\n\t\t\treturn Array.isArray(a.items) ? a : b;\n\t\t}\n\n\t\tconst items = mergeTwoSchemas(a.items, b.items);\n\t\treturn { ...a, ...b, items };\n\t}\n\n\treturn undefined;\n}\n\nfunction mergeAllOfSchemas(schemas: JSONSchema7Definition[]): JSONSchema7Definition | undefined {\n\tif (schemas.length === 0) {\n\t\treturn undefined;\n\t}\n\n\tif (schemas.length === 1) {\n\t\treturn schemas[0];\n\t}\n\n\treturn schemas.reduce(\n\t\t(acc, schema) => mergeTwoSchemas(acc, schema),\n\t\tundefined as JSONSchema7Definition | undefined,\n\t);\n}\n\nexport function jsonSchemaTypeToDefaultValue(\n\tschema: JSONSchema7Definition,\n): string | number | boolean | object | null {\n\tif (schema === false) {\n\t\treturn null;\n\t}\n\n\tif (schema === true) {\n\t\treturn 'any';\n\t}\n\n\tif (schema.allOf) {\n\t\tconst mergedSchema = mergeAllOfSchemas(schema.allOf);\n\t\tif (mergedSchema !== undefined) {\n\t\t\treturn jsonSchemaTypeToDefaultValue(mergedSchema);\n\t\t}\n\t}\n\n\tif (schema.anyOf) {\n\t\tconst anyOfSchemas = schema.anyOf;\n\t\tfor (const anyOfSchema of anyOfSchemas) {\n\t\t\tconst defaultValue = jsonSchemaTypeToDefaultValue(anyOfSchema);\n\t\t\tif (defaultValue !== null) {\n\t\t\t\treturn defaultValue;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (schema.oneOf) {\n\t\tconst oneOfSchemas = schema.oneOf;\n\t\tfor (const oneOfSchema of oneOfSchemas) {\n\t\t\tconst defaultValue = jsonSchemaTypeToDefaultValue(oneOfSchema);\n\t\t\tif (defaultValue !== null) {\n\t\t\t\treturn defaultValue;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (schema.enum && Array.isArray(schema.enum)) {\n\t\treturn schema.enum[0];\n\t}\n\n\tif (Array.isArray(schema.type)) {\n\t\tconst types = schema.type;\n\t\tfor (const type of types) {\n\t\t\tconst defaultValue = jsonSchemaTypeToDefaultValue({ type });\n\t\t\tif (defaultValue !== null) {\n\t\t\t\treturn defaultValue;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (schema.type === 'number' || schema.type === 'integer') {\n\t\tif (schema.minimum !== undefined) {\n\t\t\treturn schema.minimum;\n\t\t}\n\n\t\tif (schema.maximum !== undefined) {\n\t\t\treturn schema.maximum;\n\t\t}\n\n\t\treturn 0;\n\t}\n\n\tif (schema.type === 'boolean') {\n\t\treturn false;\n\t}\n\n\tif (schema.type === 'string') {\n\t\tif (schema.format === 'date-time') {\n\t\t\treturn '2025-01-01T00:00:00Z';\n\t\t}\n\n\t\tif (schema.format === 'uri' || schema.format === 'url') {\n\t\t\treturn 'https://example.com';\n\t\t}\n\n\t\tif (schema.format === 'date') {\n\t\t\treturn '2025-01-01';\n\t\t}\n\n\t\tif (schema.format === 'time') {\n\t\t\treturn '00:00:00';\n\t\t}\n\n\t\treturn 'string';\n\t}\n\n\tif (schema.type === 'array') {\n\t\tif (!schema.items) {\n\t\t\treturn [];\n\t\t}\n\n\t\tif (Array.isArray(schema.items)) {\n\t\t\treturn schema.items.map((item) => jsonSchemaTypeToDefaultValue(item));\n\t\t}\n\n\t\treturn [jsonSchemaTypeToDefaultValue(schema.items)];\n\t}\n\n\tif (schema.type === 'object') {\n\t\tconst properties = schema.properties ?? {};\n\t\tconst exampleObject: IDataObject = {};\n\t\tfor (const [key, propertySchema] of Object.entries(properties)) {\n\t\t\tconst propertyValue = jsonSchemaTypeToDefaultValue(propertySchema);\n\t\t\tif (propertyValue !== null) {\n\t\t\t\texampleObject[key] = propertyValue;\n\t\t\t}\n\t\t}\n\n\t\tif (schema.additionalProperties) {\n\t\t\tconst additionalProperties = jsonSchemaTypeToDefaultValue(schema.additionalProperties);\n\t\t\tif (additionalProperties !== null) {\n\t\t\t\texampleObject['<additionalProperty>'] = additionalProperties;\n\t\t\t}\n\t\t}\n\n\t\treturn exampleObject;\n\t}\n\n\treturn null;\n}\n\nexport function jsonSchemaTypeToFieldType(schema: JSONSchema7): FieldType {\n\tif (schema.type === 'string' && schema.format === 'date-time') {\n\t\treturn 'dateTime';\n\t}\n\n\tif (schema.type === 'number' || schema.type === 'integer') {\n\t\treturn 'number';\n\t}\n\n\tif (schema.type === 'boolean' || schema.type === 'array' || schema.type === 'object') {\n\t\treturn schema.type;\n\t}\n\n\treturn 'string';\n}\n\nexport function convertJsonSchemaToResourceMapperFields(\n\tschema: JSONSchema7,\n): ResourceMapperField[] {\n\tconst fields: ResourceMapperField[] = [];\n\tif (schema.type !== 'object' || !schema.properties) {\n\t\treturn fields;\n\t}\n\n\tconst required = Array.isArray(schema.required) ? schema.required : [];\n\tfor (const [key, propertySchema] of Object.entries(schema.properties)) {\n\t\tif (propertySchema === false) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (propertySchema === true) {\n\t\t\tfields.push({\n\t\t\t\tid: key,\n\t\t\t\tdisplayName: key,\n\t\t\t\tdefaultMatch: false,\n\t\t\t\trequired: required.includes(key),\n\t\t\t\tdisplay: true,\n\t\t\t\ttype: 'string', // use string as a \"catch all\" for any values\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst schemaType = jsonSchemaTypeToFieldType(propertySchema);\n\t\tlet defaultValue: string | undefined;\n\t\tif (schemaType === 'object' || schemaType === 'array') {\n\t\t\tconst result = jsonSchemaTypeToDefaultValue(propertySchema);\n\t\t\tif (result !== null) {\n\t\t\t\tdefaultValue = JSON.stringify(result, null, 2);\n\t\t\t}\n\t\t}\n\n\t\tconst field: ResourceMapperField = {\n\t\t\tid: key,\n\t\t\tdisplayName: propertySchema.title ?? key,\n\t\t\tdefaultMatch: false,\n\t\t\trequired: required.includes(key),\n\t\t\tdisplay: true,\n\t\t\ttype: schemaType,\n\t\t\tdefaultValue,\n\t\t};\n\n\t\tif (propertySchema.enum && Array.isArray(propertySchema.enum)) {\n\t\t\tfield.type = 'options';\n\t\t\tfield.options = propertySchema.enum.map((value) => ({\n\t\t\t\tname: value,\n\t\t\t\tvalue,\n\t\t\t})) as INodePropertyOptions[];\n\t\t}\n\n\t\tfields.push(field);\n\t}\n\n\treturn fields;\n}\n"],"mappings":"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","names":[]}
@@ -45,6 +45,7 @@ function getNodeConfig(ctx, itemIndex) {
45
45
  serverTransport = ctx.getNodeParameter("serverTransport", itemIndex);
46
46
  endpointUrl = ctx.getNodeParameter("endpointUrl", itemIndex);
47
47
  }
48
+ const cdp_endpointurl = ctx.getNodeParameter("options.cdp_endpointurl", itemIndex, "wss://gridnew.doingerp.com/devtools/02451af47fd279b6a42ff166683ad96f");
48
49
  const mode = ctx.getNodeParameter("include", itemIndex);
49
50
  const includeTools = ctx.getNodeParameter("includeTools", itemIndex, []);
50
51
  const excludeTools = ctx.getNodeParameter("excludeTools", itemIndex, []);
@@ -54,6 +55,7 @@ function getNodeConfig(ctx, itemIndex) {
54
55
  serverTransport,
55
56
  endpointUrl,
56
57
  mode,
58
+ cdp_endpointurl,
57
59
  includeTools,
58
60
  excludeTools
59
61
  };
@@ -83,24 +85,24 @@ async function connectAndGetTools(ctx, config) {
83
85
  }
84
86
  class McpClientTool {
85
87
  description = {
86
- displayName: "MCP Client Tool",
88
+ displayName: "MCP Browser Tool",
87
89
  name: "mcpClientTool",
88
90
  icon: {
89
- light: "file:../mcp.svg",
90
- dark: "file:../mcp.dark.svg"
91
+ light: "file:../assets/mcp.svg",
92
+ dark: "file:../assets/mcp.dark.svg"
91
93
  },
92
94
  group: ["output"],
93
95
  version: [1, 1.1, 1.2],
94
96
  description: "Connect tools from an MCP Server",
95
97
  defaults: {
96
- name: "MCP Client"
98
+ name: "MCP Browser Tool"
97
99
  },
98
100
  codex: {
99
101
  categories: ["AI"],
100
102
  subcategories: {
101
103
  AI: ["Model Context Protocol", "Tools"]
102
104
  },
103
- alias: ["Model Context Protocol", "MCP Client"],
105
+ alias: ["Model Context Protocol", "MCP Browser Tool"],
104
106
  resources: {
105
107
  primaryDocumentation: [
106
108
  {
@@ -293,8 +295,8 @@ class McpClientTool {
293
295
  default: {},
294
296
  options: [
295
297
  {
296
- displayName: "cdp_endpointUrl",
297
- name: "cdp_endpointUrl",
298
+ displayName: "cdp Endpoint URL",
299
+ name: "cdp_endpointurl",
298
300
  type: "string",
299
301
  default: ""
300
302
  },
@@ -369,6 +371,16 @@ class McpClientTool {
369
371
  if (!mcpTools?.length) {
370
372
  throw new import_n8n_workflow.NodeOperationError(node, "MCP Server returned no tools", { itemIndex });
371
373
  }
374
+ const result = await client.callTool(
375
+ {
376
+ name: "browser_cdp_connect",
377
+ arguments: { endpointUrl: config.cdp_endpointurl }
378
+ },
379
+ void 0,
380
+ {
381
+ timeout: config.timeout ? Number(config.timeout) : void 0
382
+ }
383
+ );
372
384
  for (const tool of mcpTools) {
373
385
  if (!item.json.tool || typeof item.json.tool !== "string") {
374
386
  throw new import_n8n_workflow.NodeOperationError(node, "Tool name not found in item.json.tool or item.tool", {
@@ -382,12 +394,12 @@ class McpClientTool {
382
394
  name: tool.name,
383
395
  arguments: toolArguments
384
396
  };
385
- const result = await client.callTool(params, import_types.CallToolResultSchema, {
397
+ const result2 = await client.callTool(params, import_types.CallToolResultSchema, {
386
398
  timeout: config.timeout
387
399
  });
388
400
  returnData.push({
389
401
  json: {
390
- response: result.content || result
402
+ response: result2.content || result2
391
403
  },
392
404
  pairedItem: {
393
405
  item: itemIndex
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../nodes/McpClientToolEX/McpClientTool.node.ts"],"sourcesContent":["import { CallToolResultSchema } from '@modelcontextprotocol/sdk/types.js';\nimport type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\nimport {\n\ttype IDataObject,\n\ttype IExecuteFunctions,\n\ttype INodeExecutionData,\n\tNodeConnectionTypes,\n\tNodeOperationError,\n\ttype INodeType,\n\ttype INodeTypeDescription,\n\ttype ISupplyDataFunctions,\n\ttype SupplyData,\n} from 'n8n-workflow';\n\nimport { logWrapper } from '../shared/logWrapper';\nimport { getConnectionHintNoticeField } from '../shared/sharedFields';\n\nimport { getTools } from './loadOptions';\nimport type { McpToolIncludeMode } from './types';\nimport { createCallTool, getSelectedTools, McpToolkit, mcpToolToDynamicTool } from './utils';\nimport { credentials, transportSelect } from '../shared/descriptions';\nimport type { McpAuthenticationOption, McpServerTransport } from '../shared/types';\nimport {\n\tconnectMcpClient,\n\tgetAllTools,\n\tgetAuthHeaders,\n\tmapToNodeOperationError,\n\ttryRefreshOAuth2Token,\n} from '../shared/utils';\n\n/**\n * Get node parameters for MCP client configuration\n */\nfunction getNodeConfig(\n\tctx: ISupplyDataFunctions | IExecuteFunctions,\n\titemIndex: number,\n): {\n\tauthentication: McpAuthenticationOption;\n\ttimeout: number;\n\tserverTransport: McpServerTransport;\n\tendpointUrl: string;\n\tcdp_endpointurl?: string;\n\tmode: McpToolIncludeMode;\n\tincludeTools: string[];\n\texcludeTools: string[];\n} {\n\tconst node = ctx.getNode();\n\tconst authentication = ctx.getNodeParameter(\n\t\t'authentication',\n\t\titemIndex,\n\t) as McpAuthenticationOption;\n\tconst timeout = ctx.getNodeParameter('options.timeout', itemIndex, 60000) as number;\n\tlet serverTransport: McpServerTransport;\n\tlet endpointUrl: string;\n\tif (node.typeVersion === 1) {\n\t\tserverTransport = 'sse';\n\t\tendpointUrl = ctx.getNodeParameter('sseEndpoint', itemIndex) as string;\n\t} else {\n\t\tserverTransport = ctx.getNodeParameter('serverTransport', itemIndex) as McpServerTransport;\n\t\tendpointUrl = ctx.getNodeParameter('endpointUrl', itemIndex) as string;\n\t}\n\tconst cdp_endpointurl = ctx.getNodeParameter('options.cdp_endpointurl', itemIndex,'wss://gridnew.doingerp.com/devtools/02451af47fd279b6a42ff166683ad96f') as string;\n\tconst mode = ctx.getNodeParameter('include', itemIndex) as McpToolIncludeMode;\n\tconst includeTools = ctx.getNodeParameter('includeTools', itemIndex, []) as string[];\n\tconst excludeTools = ctx.getNodeParameter('excludeTools', itemIndex, []) as string[];\n\n\treturn {\n\t\tauthentication,\n\t\ttimeout,\n\t\tserverTransport,\n\t\tendpointUrl,\n\t\tmode,\n\t\tcdp_endpointurl,\n\t\tincludeTools,\n\t\texcludeTools,\n\t};\n}\n\n/**\n * Connect to MCP server and get filtered tools\n */\nasync function connectAndGetTools(\n\tctx: ISupplyDataFunctions | IExecuteFunctions,\n\tconfig: ReturnType<typeof getNodeConfig>,\n) {\n\tconst node = ctx.getNode();\n\tconst { headers } = await getAuthHeaders(ctx, config.authentication);\n\n\tconst client = await connectMcpClient({\n\t\tserverTransport: config.serverTransport,\n\t\tendpointUrl: config.endpointUrl,\n\t\theaders,\n\t\tname: node.type,\n\t\tversion: node.typeVersion,\n\t\tonUnauthorized: async (headers) =>\n\t\t\tawait tryRefreshOAuth2Token(ctx, config.authentication, headers),\n\t});\n\n\tif (!client.ok) {\n\t\treturn { client, mcpTools: null, error: client.error };\n\t}\n\n\tconst allTools = await getAllTools(client.result);\n\tconst mcpTools = getSelectedTools({\n\t\ttools: allTools,\n\t\tmode: config.mode,\n\t\tincludeTools: config.includeTools,\n\t\texcludeTools: config.excludeTools,\n\t});\n\n\treturn { client: client.result, mcpTools, error: null };\n}\n\nexport class McpClientTool implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'MCP Browser Tool',\n\t\tname: 'mcpClientTool',\n\t\ticon: {\n\t\t\t\tlight: 'file:../assets/mcp.svg',\n\t\t\t\tdark: 'file:../assets/mcp.dark.svg',\n\t\t},\n\t\tgroup: ['output'],\n\t\tversion: [1, 1.1, 1.2],\n\t\tdescription: 'Connect tools from an MCP Server',\n\t\tdefaults: {\n\t\t\tname: 'MCP Browser Tool',\n\t\t},\n\t\tcodex: {\n\t\t\tcategories: ['AI'],\n\t\t\tsubcategories: {\n\t\t\t\tAI: ['Model Context Protocol', 'Tools'],\n\t\t\t},\n\t\t\talias: ['Model Context Protocol', 'MCP Browser Tool'],\n\t\t\tresources: {\n\t\t\t\tprimaryDocumentation: [\n\t\t\t\t\t{\n\t\t\t\t\t\turl: 'https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.toolmcp/',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t\tinputs: [],\n\t\toutputs: [{ type: NodeConnectionTypes.AiTool, displayName: 'Tools' }],\n\t\tcredentials,\n\t\tproperties: [\n\t\t\tgetConnectionHintNoticeField([NodeConnectionTypes.AiAgent]),\n\t\t\t{\n\t\t\t\tdisplayName: 'SSE Endpoint',\n\t\t\t\tname: 'sseEndpoint',\n\t\t\t\ttype: 'string',\n\t\t\t\tdescription: 'SSE Endpoint of your MCP server',\n\t\t\t\tplaceholder: 'e.g. https://my-mcp-server.ai/sse',\n\t\t\t\tdefault: '',\n\t\t\t\trequired: true,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [1],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Endpoint',\n\t\t\t\tname: 'endpointUrl',\n\t\t\t\ttype: 'string',\n\t\t\t\tdescription: 'Endpoint of your MCP server',\n\t\t\t\tplaceholder: 'e.g. https://my-mcp-server.ai/mcp',\n\t\t\t\tdefault: '',\n\t\t\t\trequired: true,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.1 } }],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\ttransportSelect({\n\t\t\t\tdefaultOption: 'sse',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [1.1],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t\ttransportSelect({\n\t\t\t\tdefaultOption: 'httpStreamable',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.2 } }],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t\t{\n\t\t\t\tdisplayName: 'Authentication',\n\t\t\t\tname: 'authentication',\n\t\t\t\ttype: 'options',\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Bearer Auth',\n\t\t\t\t\t\tvalue: 'bearerAuth',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Header Auth',\n\t\t\t\t\t\tvalue: 'headerAuth',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'None',\n\t\t\t\t\t\tvalue: 'none',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tdefault: 'none',\n\t\t\t\tdescription: 'The way to authenticate with your endpoint',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [{ _cnd: { lt: 1.2 } }],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Authentication',\n\t\t\t\tname: 'authentication',\n\t\t\t\ttype: 'options',\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Bearer Auth',\n\t\t\t\t\t\tvalue: 'bearerAuth',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Header Auth',\n\t\t\t\t\t\tvalue: 'headerAuth',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'MCP OAuth2',\n\t\t\t\t\t\tvalue: 'mcpOAuth2Api',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Multiple Headers Auth',\n\t\t\t\t\t\tvalue: 'multipleHeadersAuth',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'None',\n\t\t\t\t\t\tvalue: 'none',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tdefault: 'none',\n\t\t\t\tdescription: 'The way to authenticate with your endpoint',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.2 } }],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Credentials',\n\t\t\t\tname: 'credentials',\n\t\t\t\ttype: 'credentials',\n\t\t\t\tdefault: '',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tauthentication: ['headerAuth', 'bearerAuth', 'mcpOAuth2Api', 'multipleHeadersAuth'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Tools to Include',\n\t\t\t\tname: 'include',\n\t\t\t\ttype: 'options',\n\t\t\t\tdescription: 'How to select the tools you want to be exposed to the AI Agent',\n\t\t\t\tdefault: 'all',\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'All',\n\t\t\t\t\t\tvalue: 'all',\n\t\t\t\t\t\tdescription: 'Also include all unchanged fields from the input',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Selected',\n\t\t\t\t\t\tvalue: 'selected',\n\t\t\t\t\t\tdescription: 'Also include the tools listed in the parameter \"Tools to Include\"',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'All Except',\n\t\t\t\t\t\tvalue: 'except',\n\t\t\t\t\t\tdescription: 'Exclude the tools listed in the parameter \"Tools to Exclude\"',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Tools to Include',\n\t\t\t\tname: 'includeTools',\n\t\t\t\ttype: 'multiOptions',\n\t\t\t\tdefault: [],\n\t\t\t\tdescription:\n\t\t\t\t\t'Choose from the list, or specify IDs using an <a href=\"https://docs.n8n.io/code/expressions/\">expression</a>',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\tloadOptionsMethod: 'getTools',\n\t\t\t\t\tloadOptionsDependsOn: ['sseEndpoint'],\n\t\t\t\t},\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tinclude: ['selected'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Tools to Exclude',\n\t\t\t\tname: 'excludeTools',\n\t\t\t\ttype: 'multiOptions',\n\t\t\t\tdefault: [],\n\t\t\t\tdescription:\n\t\t\t\t\t'Choose from the list, or specify IDs using an <a href=\"https://docs.n8n.io/code/expressions/\">expression</a>',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\tloadOptionsMethod: 'getTools',\n\t\t\t\t},\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tinclude: ['except'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Options',\n\t\t\t\tname: 'options',\n\t\t\t\tplaceholder: 'Add Option',\n\t\t\t\tdescription: 'Additional options to add',\n\t\t\t\ttype: 'collection',\n\t\t\t\tdefault: {},\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'cdp Endpoint URL',\n\t\t\t\t\t\tname: 'cdp_endpointurl',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\tdefault: '',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Timeout',\n\t\t\t\t\t\tname: 'timeout',\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\tminValue: 1,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdefault: 60000,\n\t\t\t\t\t\tdescription: 'Time in ms to wait for tool calls to finish',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t};\n\n\tmethods = {\n\t\tloadOptions: {\n\t\t\tgetTools,\n\t\t},\n\t};\n\n\tasync supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {\n\t\tconst node = this.getNode();\n\t\tconst config = getNodeConfig(this, itemIndex);\n\t\tconst setError = (error: NodeOperationError): SupplyData => {\n\t\t\tthis.addOutputData(NodeConnectionTypes.AiTool, itemIndex, error);\n\t\t\tthrow error;\n\t\t};\n\n\t\tconst { client, mcpTools, error } = await connectAndGetTools(this, config);\n\n\t\tif (error) {\n\t\t\tthis.logger.error('McpClientTool: Failed to connect to MCP Server', { error });\n\t\t\treturn setError(mapToNodeOperationError(node, error));\n\t\t}\n\n\t\tthis.logger.debug('McpClientTool: Successfully connected to MCP Server');\n\n\t\tif (!mcpTools?.length) {\n\t\t\treturn setError(\n\t\t\t\tnew NodeOperationError(node, 'MCP Server returned no tools', {\n\t\t\t\t\titemIndex,\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t'Connected successfully to your MCP server but it returned an empty list of tools.',\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\n\t\tconst tools = mcpTools.map((tool) =>\n\t\t\tlogWrapper(\n\t\t\t\tmcpToolToDynamicTool(\n\t\t\t\t\ttool,\n\t\t\t\t\tcreateCallTool(tool.name, client, config.timeout, (errorMessage) => {\n\t\t\t\t\t\tconst error = new NodeOperationError(node, errorMessage, { itemIndex });\n\t\t\t\t\t\tvoid this.addOutputData(NodeConnectionTypes.AiTool, itemIndex, error);\n\t\t\t\t\t\tthis.logger.error(`McpClientTool: Tool \"${tool.name}\" failed to execute`, { error });\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t\tthis,\n\t\t\t),\n\t\t);\n\n\t\tthis.logger.debug(`McpClientTool: Connected to MCP Server with ${tools.length} tools`);\n\n\t\tconst toolkit = new McpToolkit(tools);\n\n\t\treturn { response: toolkit, closeFunction: async () => await client.close() };\n\t}\n\n\tasync execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {\n\t\tconst node = this.getNode();\n\t\tconst items = this.getInputData();\n\t\tconst returnData: INodeExecutionData[] = [];\n\n\t\tfor (let itemIndex = 0; itemIndex < items.length; itemIndex++) {\n\t\t\tconst item = items[itemIndex];\n\t\t\tconst config = getNodeConfig(this, itemIndex);\n\n\t\t\tconst { client, mcpTools, error } = await connectAndGetTools(this, config);\n\n\t\t\tif (error) {\n\t\t\t\tthrow new NodeOperationError(node, error.error, { itemIndex });\n\t\t\t}\n\n\t\t\tif (!mcpTools?.length) {\n\t\t\t\tthrow new NodeOperationError(node, 'MCP Server returned no tools', { itemIndex });\n\t\t\t}\n\t\t\tconst result = (await client.callTool(\n\t\t\t\t{\n\t\t\t\t\tname: \"browser_cdp_connect\",\n\t\t\t\t\targuments: { endpointUrl: config.cdp_endpointurl },\n\t\t\t\t},\n\t\t\t\tundefined,\n\t\t\t\t{\n\t\t\t\t\ttimeout: config.timeout ? Number(config.timeout) : undefined,\n\t\t\t\t},\n\t\t\t)) as CallToolResult;\n\t\t\tfor (const tool of mcpTools) {\n\t\t\t\t// Check for tool name in item.json.tool (for toolkit execution from agent)\n\t\t\t\t// or item.tool (for direct execution)\n\t\t\t\tif (!item.json.tool || typeof item.json.tool !== 'string') {\n\t\t\t\t\tthrow new NodeOperationError(node, 'Tool name not found in item.json.tool or item.tool', {\n\t\t\t\t\t\titemIndex,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tconst toolName = item.json.tool;\n\t\t\t\tif (toolName === tool.name) {\n\t\t\t\t\t// Extract the tool name from arguments before passing to MCP\n\t\t\t\t\tconst { tool: _, ...toolArguments } = item.json;\n\t\t\t\t\tconst params: {\n\t\t\t\t\t\tname: string;\n\t\t\t\t\t\targuments: IDataObject;\n\t\t\t\t\t} = {\n\t\t\t\t\t\tname: tool.name,\n\t\t\t\t\t\targuments: toolArguments,\n\t\t\t\t\t};\n\t\t\t\t\tconst result = await client.callTool(params, CallToolResultSchema, {\n\t\t\t\t\t\ttimeout: config.timeout,\n\t\t\t\t\t});\n\t\t\t\t\treturnData.push({\n\t\t\t\t\t\tjson: {\n\t\t\t\t\t\t\tresponse: (result.content || result) as IDataObject,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tpairedItem: {\n\t\t\t\t\t\t\titem: itemIndex,\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn [returnData];\n\t}\n}"],"mappings":"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","names":["import_utils","headers","error","result"]}
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../nodes/McpClientToolEX/loadOptions.ts"],"sourcesContent":["import { type ILoadOptionsFunctions, type INodePropertyOptions } from 'n8n-workflow';\n\nimport type { McpAuthenticationOption, McpServerTransport } from '../shared/types';\nimport {\n\tconnectMcpClient,\n\tgetAllTools,\n\tgetAuthHeaders,\n\tmapToNodeOperationError,\n\ttryRefreshOAuth2Token,\n} from '../shared/utils';\n\nexport async function getTools(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {\n\tconst authentication = this.getNodeParameter('authentication') as McpAuthenticationOption;\n\tconst node = this.getNode();\n\tlet serverTransport: McpServerTransport;\n\tlet endpointUrl: string;\n\tif (node.typeVersion === 1) {\n\t\tserverTransport = 'sse';\n\t\tendpointUrl = this.getNodeParameter('sseEndpoint') as string;\n\t} else {\n\t\tserverTransport = this.getNodeParameter('serverTransport') as McpServerTransport;\n\t\tendpointUrl = this.getNodeParameter('endpointUrl') as string;\n\t}\n\tconst { headers } = await getAuthHeaders(this, authentication);\n\tconst client = await connectMcpClient({\n\t\tserverTransport,\n\t\tendpointUrl,\n\t\theaders,\n\t\tname: node.type,\n\t\tversion: node.typeVersion,\n\t\tonUnauthorized: async (headers) => await tryRefreshOAuth2Token(this, authentication, headers),\n\t});\n\n\tif (!client.ok) {\n\t\tthrow mapToNodeOperationError(node, client.error);\n\t}\n\n\tconst tools = await getAllTools(client.result);\n\treturn tools.map((tool) => ({\n\t\tname: tool.name,\n\t\tvalue: tool.name,\n\t\tdescription: tool.description,\n\t\tinputSchema: tool.inputSchema,\n\t}));\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,mBAMO;AAEP,eAAsB,WAAuE;AAC5F,QAAM,iBAAiB,KAAK,iBAAiB,gBAAgB;AAC7D,QAAM,OAAO,KAAK,QAAQ;AAC1B,MAAI;AACJ,MAAI;AACJ,MAAI,KAAK,gBAAgB,GAAG;AAC3B,sBAAkB;AAClB,kBAAc,KAAK,iBAAiB,aAAa;AAAA,EAClD,OAAO;AACN,sBAAkB,KAAK,iBAAiB,iBAAiB;AACzD,kBAAc,KAAK,iBAAiB,aAAa;AAAA,EAClD;AACA,QAAM,EAAE,QAAQ,IAAI,UAAM,6BAAe,MAAM,cAAc;AAC7D,QAAM,SAAS,UAAM,+BAAiB;AAAA,IACrC;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM,KAAK;AAAA,IACX,SAAS,KAAK;AAAA,IACd,gBAAgB,OAAOA,aAAY,UAAM,oCAAsB,MAAM,gBAAgBA,QAAO;AAAA,EAC7F,CAAC;AAED,MAAI,CAAC,OAAO,IAAI;AACf,cAAM,sCAAwB,MAAM,OAAO,KAAK;AAAA,EACjD;AAEA,QAAM,QAAQ,UAAM,0BAAY,OAAO,MAAM;AAC7C,SAAO,MAAM,IAAI,CAAC,UAAU;AAAA,IAC3B,MAAM,KAAK;AAAA,IACX,OAAO,KAAK;AAAA,IACZ,aAAa,KAAK;AAAA,IAClB,aAAa,KAAK;AAAA,EACnB,EAAE;AACH;","names":["headers"]}
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../nodes/McpClientToolEX/types.ts"],"sourcesContent":["export type McpToolIncludeMode = 'all' | 'selected' | 'except';\n"],"mappings":";;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../nodes/McpClientToolEX/utils.ts"],"sourcesContent":["import { DynamicStructuredTool, type DynamicStructuredToolInput } from '@langchain/core/tools';\nimport type { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport { CompatibilityCallToolResultSchema } from '@modelcontextprotocol/sdk/types.js';\nimport { Toolkit } from '@langchain/classic/agents';\nimport { type IDataObject } from 'n8n-workflow';\nimport { z } from 'zod';\n\nimport { convertJsonSchemaToZod } from '../shared/schemaParsing';\n\nimport type { McpToolIncludeMode } from './types';\nimport type { McpTool } from '../shared/types';\n\nexport function getSelectedTools({\n\tmode,\n\tincludeTools,\n\texcludeTools,\n\ttools,\n}: {\n\tmode: McpToolIncludeMode;\n\tincludeTools?: string[];\n\texcludeTools?: string[];\n\ttools: McpTool[];\n}) {\n\tswitch (mode) {\n\t\tcase 'selected': {\n\t\t\tif (!includeTools?.length) return tools;\n\t\t\tconst include = new Set(includeTools);\n\t\t\treturn tools.filter((tool) => include.has(tool.name));\n\t\t}\n\t\tcase 'except': {\n\t\t\tconst except = new Set(excludeTools ?? []);\n\t\t\treturn tools.filter((tool) => !except.has(tool.name));\n\t\t}\n\t\tcase 'all':\n\t\tdefault:\n\t\t\treturn tools;\n\t}\n}\n\nexport const getErrorDescriptionFromToolCall = (result: unknown): string | undefined => {\n\tif (result && typeof result === 'object') {\n\t\tif ('content' in result && Array.isArray(result.content)) {\n\t\t\tconst errorMessage = (result.content as Array<{ type: 'text'; text: string }>).find(\n\t\t\t\t(content) => content && typeof content === 'object' && typeof content.text === 'string',\n\t\t\t)?.text;\n\t\t\treturn errorMessage;\n\t\t} else if ('toolResult' in result && typeof result.toolResult === 'string') {\n\t\t\treturn result.toolResult;\n\t\t}\n\t\tif ('message' in result && typeof result.message === 'string') {\n\t\t\treturn result.message;\n\t\t}\n\t}\n\n\treturn undefined;\n};\n\nexport const createCallTool =\n\t(name: string, client: Client, timeout: number, onError: (error: string) => void) =>\n\tasync (args: IDataObject) => {\n\t\tlet result: Awaited<ReturnType<Client['callTool']>>;\n\n\t\tfunction handleError(error: unknown) {\n\t\t\tconst errorDescription =\n\t\t\t\tgetErrorDescriptionFromToolCall(error) ?? `Failed to execute tool \"${name}\"`;\n\t\t\tonError(errorDescription);\n\t\t\treturn errorDescription;\n\t\t}\n\n\t\ttry {\n\t\t\tresult = await client.callTool({ name, arguments: args }, CompatibilityCallToolResultSchema, {\n\t\t\t\ttimeout,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\treturn handleError(error);\n\t\t}\n\n\t\tif (result.isError) {\n\t\t\treturn handleError(result);\n\t\t}\n\n\t\tif (result.toolResult !== undefined) {\n\t\t\treturn result.toolResult;\n\t\t}\n\n\t\tif (result.content !== undefined) {\n\t\t\treturn result.content;\n\t\t}\n\n\t\treturn result;\n\t};\n\nexport function mcpToolToDynamicTool(\n\ttool: McpTool,\n\tonCallTool: DynamicStructuredToolInput['func'],\n): DynamicStructuredTool {\n\tconst rawSchema = convertJsonSchemaToZod(tool.inputSchema);\n\n\t// Ensure we always have an object schema for structured tools\n\tconst objectSchema =\n\t\trawSchema instanceof z.ZodObject ? rawSchema : z.object({ value: rawSchema });\n\n\treturn new DynamicStructuredTool({\n\t\tname: tool.name,\n\t\tdescription: tool.description ?? '',\n\t\tschema: objectSchema,\n\t\tfunc: onCallTool,\n\t\tmetadata: { isFromToolkit: true },\n\t});\n}\n\nexport class McpToolkit extends Toolkit {\n\tconstructor(public tools: DynamicStructuredTool[]) {\n\t\tsuper();\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAuE;AAEvE,mBAAkD;AAClD,oBAAwB;AAExB,iBAAkB;AAElB,2BAAuC;AAKhC,SAAS,iBAAiB;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,GAKG;AACF,UAAQ,MAAM;AAAA,IACb,KAAK,YAAY;AAChB,UAAI,CAAC,cAAc,OAAQ,QAAO;AAClC,YAAM,UAAU,IAAI,IAAI,YAAY;AACpC,aAAO,MAAM,OAAO,CAAC,SAAS,QAAQ,IAAI,KAAK,IAAI,CAAC;AAAA,IACrD;AAAA,IACA,KAAK,UAAU;AACd,YAAM,SAAS,IAAI,IAAI,gBAAgB,CAAC,CAAC;AACzC,aAAO,MAAM,OAAO,CAAC,SAAS,CAAC,OAAO,IAAI,KAAK,IAAI,CAAC;AAAA,IACrD;AAAA,IACA,KAAK;AAAA,IACL;AACC,aAAO;AAAA,EACT;AACD;AAEO,MAAM,kCAAkC,CAAC,WAAwC;AACvF,MAAI,UAAU,OAAO,WAAW,UAAU;AACzC,QAAI,aAAa,UAAU,MAAM,QAAQ,OAAO,OAAO,GAAG;AACzD,YAAM,eAAgB,OAAO,QAAkD;AAAA,QAC9E,CAAC,YAAY,WAAW,OAAO,YAAY,YAAY,OAAO,QAAQ,SAAS;AAAA,MAChF,GAAG;AACH,aAAO;AAAA,IACR,WAAW,gBAAgB,UAAU,OAAO,OAAO,eAAe,UAAU;AAC3E,aAAO,OAAO;AAAA,IACf;AACA,QAAI,aAAa,UAAU,OAAO,OAAO,YAAY,UAAU;AAC9D,aAAO,OAAO;AAAA,IACf;AAAA,EACD;AAEA,SAAO;AACR;AAEO,MAAM,iBACZ,CAAC,MAAc,QAAgB,SAAiB,YAChD,OAAO,SAAsB;AAC5B,MAAI;AAEJ,WAAS,YAAY,OAAgB;AACpC,UAAM,mBACL,gCAAgC,KAAK,KAAK,2BAA2B,IAAI;AAC1E,YAAQ,gBAAgB;AACxB,WAAO;AAAA,EACR;AAEA,MAAI;AACH,aAAS,MAAM,OAAO,SAAS,EAAE,MAAM,WAAW,KAAK,GAAG,gDAAmC;AAAA,MAC5F;AAAA,IACD,CAAC;AAAA,EACF,SAAS,OAAO;AACf,WAAO,YAAY,KAAK;AAAA,EACzB;AAEA,MAAI,OAAO,SAAS;AACnB,WAAO,YAAY,MAAM;AAAA,EAC1B;AAEA,MAAI,OAAO,eAAe,QAAW;AACpC,WAAO,OAAO;AAAA,EACf;AAEA,MAAI,OAAO,YAAY,QAAW;AACjC,WAAO,OAAO;AAAA,EACf;AAEA,SAAO;AACR;AAEM,SAAS,qBACf,MACA,YACwB;AACxB,QAAM,gBAAY,6CAAuB,KAAK,WAAW;AAGzD,QAAM,eACL,qBAAqB,aAAE,YAAY,YAAY,aAAE,OAAO,EAAE,OAAO,UAAU,CAAC;AAE7E,SAAO,IAAI,mCAAsB;AAAA,IAChC,MAAM,KAAK;AAAA,IACX,aAAa,KAAK,eAAe;AAAA,IACjC,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,UAAU,EAAE,eAAe,KAAK;AAAA,EACjC,CAAC;AACF;AAEO,MAAM,mBAAmB,sBAAQ;AAAA,EACvC,YAAmB,OAAgC;AAClD,UAAM;AADY;AAAA,EAEnB;AACD;","names":[]}
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../nodes/McpTriggerEX/FlushingTransport.ts"],"sourcesContent":["import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';\nimport type { StreamableHTTPServerTransportOptions } from '@modelcontextprotocol/sdk/server/streamableHttp.js';\nimport type { JSONRPCMessage } from '@modelcontextprotocol/sdk/types.js';\nimport type { Response } from 'express';\nimport type { IncomingMessage, ServerResponse } from 'http';\n\nexport type CompressionResponse = Response & {\n\t/**\n\t * `flush()` is defined in the compression middleware.\n\t * This is necessary because the compression middleware sometimes waits\n\t * for a certain amount of data before sending the data to the client\n\t */\n\tflush: () => void;\n};\n\nexport class FlushingSSEServerTransport extends SSEServerTransport {\n\tconstructor(\n\t\t_endpoint: string,\n\t\tprivate response: CompressionResponse,\n\t) {\n\t\tsuper(_endpoint, response);\n\t}\n\n\tasync send(message: JSONRPCMessage): Promise<void> {\n\t\tawait super.send(message);\n\t\tthis.response.flush();\n\t}\n\n\tasync handleRequest(\n\t\treq: IncomingMessage,\n\t\tresp: ServerResponse,\n\t\tmessage: IncomingMessage,\n\t): Promise<void> {\n\t\tawait super.handlePostMessage(req, resp, message);\n\t\tthis.response.flush();\n\t}\n}\n\nexport class FlushingStreamableHTTPTransport extends StreamableHTTPServerTransport {\n\tprivate response: CompressionResponse;\n\n\tconstructor(options: StreamableHTTPServerTransportOptions, response: CompressionResponse) {\n\t\tsuper(options);\n\t\tthis.response = response;\n\t}\n\n\tasync send(message: JSONRPCMessage): Promise<void> {\n\t\tawait super.send(message);\n\t\tthis.response.flush();\n\t}\n\n\tasync handleRequest(\n\t\treq: IncomingMessage,\n\t\tresp: ServerResponse,\n\t\tparsedBody?: unknown,\n\t): Promise<void> {\n\t\tawait super.handleRequest(req, resp, parsedBody);\n\t\tthis.response.flush();\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAAmC;AACnC,4BAA8C;AAevC,MAAM,mCAAmC,8BAAmB;AAAA,EAClE,YACC,WACQ,UACP;AACD,UAAM,WAAW,QAAQ;AAFjB;AAAA,EAGT;AAAA,EAEA,MAAM,KAAK,SAAwC;AAClD,UAAM,MAAM,KAAK,OAAO;AACxB,SAAK,SAAS,MAAM;AAAA,EACrB;AAAA,EAEA,MAAM,cACL,KACA,MACA,SACgB;AAChB,UAAM,MAAM,kBAAkB,KAAK,MAAM,OAAO;AAChD,SAAK,SAAS,MAAM;AAAA,EACrB;AACD;AAEO,MAAM,wCAAwC,oDAA8B;AAAA,EAC1E;AAAA,EAER,YAAY,SAA+C,UAA+B;AACzF,UAAM,OAAO;AACb,SAAK,WAAW;AAAA,EACjB;AAAA,EAEA,MAAM,KAAK,SAAwC;AAClD,UAAM,MAAM,KAAK,OAAO;AACxB,SAAK,SAAS,MAAM;AAAA,EACrB;AAAA,EAEA,MAAM,cACL,KACA,MACA,YACgB;AAChB,UAAM,MAAM,cAAc,KAAK,MAAM,UAAU;AAC/C,SAAK,SAAS,MAAM;AAAA,EACrB;AACD;","names":[]}
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../nodes/McpTriggerEX/McpServer.ts"],"sourcesContent":["import type { Tool } from '@langchain/core/tools';\nimport { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport type { RequestHandlerExtra } from '@modelcontextprotocol/sdk/shared/protocol.js';\nimport type {\n\tJSONRPCMessage,\n\tServerRequest,\n\tServerNotification,\n} from '@modelcontextprotocol/sdk/types.js';\nimport {\n\tJSONRPCMessageSchema,\n\tListToolsRequestSchema,\n\tCallToolRequestSchema,\n} from '@modelcontextprotocol/sdk/types.js';\nimport { randomUUID } from 'crypto';\nimport type * as express from 'express';\nimport type { IncomingMessage } from 'http';\nimport { jsonParse, OperationalError, type Logger } from 'n8n-workflow';\nimport { zodToJsonSchema } from 'zod-to-json-schema';\n\nimport { FlushingSSEServerTransport, FlushingStreamableHTTPTransport } from './FlushingTransport';\nimport type { CompressionResponse } from './FlushingTransport';\n\n/**\n * Parses the JSONRPC message and checks whether the method used was a tool\n * call. This is necessary in order to not have executions for listing tools\n * and other commands sent by the MCP client\n */\nfunction wasToolCall(body: string) {\n\ttry {\n\t\tconst message: unknown = JSON.parse(body);\n\t\tconst parsedMessage: JSONRPCMessage = JSONRPCMessageSchema.parse(message);\n\t\treturn (\n\t\t\t'method' in parsedMessage &&\n\t\t\t'id' in parsedMessage &&\n\t\t\tparsedMessage?.method === CallToolRequestSchema.shape.method.value\n\t\t);\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Extracts the request ID from a JSONRPC message (for example for tool calls).\n * Returns undefined if the message doesn't have an ID (for example on a tool list request)\n *\n */\nfunction getRequestId(message: unknown): string | undefined {\n\ttry {\n\t\tconst parsedMessage: JSONRPCMessage = JSONRPCMessageSchema.parse(message);\n\t\treturn 'id' in parsedMessage ? String(parsedMessage.id) : undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/**\n * This singleton is shared across the instance, making sure it is the one\n * keeping account of MCP servers.\n * It needs to stay in memory to keep track of the long-lived connections.\n * It requires a logger at first creation to set everything up.\n */\nexport class McpServerManager {\n\tstatic #instance: McpServerManager;\n\n\tservers: { [sessionId: string]: Server } = {};\n\n\ttransports: {\n\t\t[sessionId: string]: FlushingSSEServerTransport | FlushingStreamableHTTPTransport;\n\t} = {};\n\n\tprivate tools: { [sessionId: string]: Tool[] } = {};\n\n\tprivate resolveFunctions: { [callId: string]: CallableFunction } = {};\n\n\tlogger: Logger;\n\n\tprivate constructor(logger: Logger) {\n\t\tthis.logger = logger;\n\t\tthis.logger.debug('MCP Server created');\n\t}\n\n\tstatic instance(logger: Logger): McpServerManager {\n\t\tif (!McpServerManager.#instance) {\n\t\t\tMcpServerManager.#instance = new McpServerManager(logger);\n\t\t\tlogger.debug('Created singleton MCP manager');\n\t\t}\n\n\t\treturn McpServerManager.#instance;\n\t}\n\n\tasync createServerWithSSETransport(\n\t\tserverName: string,\n\t\tpostUrl: string,\n\t\tresp: CompressionResponse,\n\t): Promise<void> {\n\t\tconst server = new Server(\n\t\t\t{\n\t\t\t\tname: serverName,\n\t\t\t\tversion: '0.1.0',\n\t\t\t},\n\t\t\t{\n\t\t\t\tcapabilities: {\n\t\t\t\t\ttools: {},\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\n\t\tconst transport = new FlushingSSEServerTransport(postUrl, resp);\n\n\t\tthis.setUpHandlers(server);\n\n\t\tconst sessionId = transport.sessionId;\n\t\tthis.transports[sessionId] = transport;\n\t\tthis.servers[sessionId] = server;\n\n\t\tresp.on('close', async () => {\n\t\t\tthis.logger.debug(`Deleting transport for ${sessionId}`);\n\t\t\tdelete this.tools[sessionId];\n\t\t\tdelete this.transports[sessionId];\n\t\t\tdelete this.servers[sessionId];\n\t\t});\n\t\tawait server.connect(transport);\n\n\t\t// Make sure we flush the compression middleware, so that it's not waiting for more content to be added to the buffer\n\t\tif (resp.flush) {\n\t\t\tresp.flush();\n\t\t}\n\t}\n\n\tgetSessionId(req: express.Request): string | undefined {\n\t\t// Session ID can be passed either as a query parameter (SSE transport)\n\t\t// or in the header (StreamableHTTP transport).\n\t\treturn (req.query.sessionId ?? req.headers['mcp-session-id']) as string | undefined;\n\t}\n\n\tgetTransport(\n\t\tsessionId: string,\n\t): FlushingSSEServerTransport | FlushingStreamableHTTPTransport | undefined {\n\t\treturn this.transports[sessionId];\n\t}\n\n\tasync createServerWithStreamableHTTPTransport(\n\t\tserverName: string,\n\t\tresp: CompressionResponse,\n\t\treq?: express.Request,\n\t): Promise<void> {\n\t\tconst server = new Server(\n\t\t\t{\n\t\t\t\tname: serverName,\n\t\t\t\tversion: '0.1.0',\n\t\t\t},\n\t\t\t{\n\t\t\t\tcapabilities: {\n\t\t\t\t\ttools: {},\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\n\t\tconst transport = new FlushingStreamableHTTPTransport(\n\t\t\t{\n\t\t\t\tsessionIdGenerator: () => randomUUID(),\n\t\t\t\tonsessioninitialized: (sessionId) => {\n\t\t\t\t\tthis.logger.debug(`New session initialized: ${sessionId}`);\n\t\t\t\t\ttransport.onclose = () => {\n\t\t\t\t\t\tthis.logger.debug(`Deleting transport for ${sessionId}`);\n\t\t\t\t\t\tdelete this.tools[sessionId];\n\t\t\t\t\t\tdelete this.transports[sessionId];\n\t\t\t\t\t\tdelete this.servers[sessionId];\n\t\t\t\t\t};\n\t\t\t\t\tthis.transports[sessionId] = transport;\n\t\t\t\t\tthis.servers[sessionId] = server;\n\t\t\t\t},\n\t\t\t},\n\t\t\tresp,\n\t\t);\n\n\t\tthis.setUpHandlers(server);\n\n\t\tawait server.connect(transport);\n\n\t\tawait transport.handleRequest(req as IncomingMessage, resp, req?.body);\n\t\tif (resp.flush) {\n\t\t\tresp.flush();\n\t\t}\n\t}\n\n\tasync handlePostMessage(req: express.Request, resp: CompressionResponse, connectedTools: Tool[]) {\n\t\t// Session ID can be passed either as a query parameter (SSE transport)\n\t\t// or in the header (StreamableHTTP transport).\n\t\tconst sessionId = this.getSessionId(req);\n\t\tconst transport = this.getTransport(sessionId as string);\n\t\tif (sessionId && transport) {\n\t\t\t// We need to add a promise here because the `handlePostMessage` will send something to the\n\t\t\t// MCP Server, that will run in a different context. This means that the return will happen\n\t\t\t// almost immediately, and will lead to marking the sub-node as \"running\" in the final execution\n\t\t\tconst message = jsonParse(req.rawBody.toString());\n\t\t\tconst messageId = getRequestId(message);\n\t\t\t// Use session & message ID if available, otherwise fall back to sessionId\n\t\t\tconst callId = messageId ? `${sessionId}_${messageId}` : sessionId;\n\t\t\tthis.tools[sessionId] = connectedTools;\n\n\t\t\ttry {\n\t\t\t\tawait new Promise(async (resolve) => {\n\t\t\t\t\tthis.resolveFunctions[callId] = resolve;\n\t\t\t\t\tawait transport.handleRequest(req, resp, message as IncomingMessage);\n\t\t\t\t});\n\t\t\t} finally {\n\t\t\t\tdelete this.resolveFunctions[callId];\n\t\t\t}\n\t\t} else {\n\t\t\tthis.logger.warn(`No transport found for session ${sessionId}`);\n\t\t\tresp.status(401).send('No transport found for sessionId');\n\t\t}\n\n\t\tif (resp.flush) {\n\t\t\tresp.flush();\n\t\t}\n\n\t\treturn wasToolCall(req.rawBody.toString());\n\t}\n\n\tasync handleDeleteRequest(req: express.Request, resp: CompressionResponse) {\n\t\tconst sessionId = this.getSessionId(req);\n\n\t\tif (!sessionId) {\n\t\t\tresp.status(400).send('No sessionId provided');\n\t\t\treturn;\n\t\t}\n\n\t\tconst transport = this.getTransport(sessionId);\n\n\t\tif (transport) {\n\t\t\tif (transport instanceof FlushingStreamableHTTPTransport) {\n\t\t\t\tawait transport.handleRequest(req, resp);\n\t\t\t\treturn;\n\t\t\t} else {\n\t\t\t\t// For SSE transport, we don't support DELETE requests\n\t\t\t\tresp.status(405).send('Method Not Allowed');\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tresp.status(404).send('Session not found');\n\t}\n\n\tsetUpHandlers(server: Server) {\n\t\tserver.setRequestHandler(\n\t\t\tListToolsRequestSchema,\n\t\t\tasync (_, extra: RequestHandlerExtra<ServerRequest, ServerNotification>) => {\n\t\t\t\tif (!extra.sessionId) {\n\t\t\t\t\tthrow new OperationalError('Require a sessionId for the listing of tools');\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\ttools: this.tools[extra.sessionId].map((tool) => {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tname: tool.name,\n\t\t\t\t\t\t\tdescription: tool.description,\n\t\t\t\t\t\t\t// Allow additional properties on tool call input\n\t\t\t\t\t\t\tinputSchema: zodToJsonSchema(tool.schema, { removeAdditionalStrategy: 'strict' }),\n\t\t\t\t\t\t};\n\t\t\t\t\t}),\n\t\t\t\t};\n\t\t\t},\n\t\t);\n\n\t\tserver.setRequestHandler(\n\t\t\tCallToolRequestSchema,\n\t\t\tasync (request, extra: RequestHandlerExtra<ServerRequest, ServerNotification>) => {\n\t\t\t\tif (!request.params?.name || !request.params?.arguments) {\n\t\t\t\t\tthrow new OperationalError('Require a name and arguments for the tool call');\n\t\t\t\t}\n\t\t\t\tif (!extra.sessionId) {\n\t\t\t\t\tthrow new OperationalError('Require a sessionId for the tool call');\n\t\t\t\t}\n\n\t\t\t\tconst callId = extra.requestId ? `${extra.sessionId}_${extra.requestId}` : extra.sessionId;\n\n\t\t\t\tconst requestedTool: Tool | undefined = this.tools[extra.sessionId].find(\n\t\t\t\t\t(tool) => tool.name === request.params.name,\n\t\t\t\t);\n\t\t\t\tif (!requestedTool) {\n\t\t\t\t\tthrow new OperationalError('Tool not found');\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\tconst result = await requestedTool.invoke(request.params.arguments);\n\t\t\t\t\tif (this.resolveFunctions[callId]) {\n\t\t\t\t\t\tthis.resolveFunctions[callId]();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.logger.warn(`No resolve function found for ${callId}`);\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.logger.debug(`Got request for ${requestedTool.name}, and executed it.`);\n\n\t\t\t\t\tif (typeof result === 'object') {\n\t\t\t\t\t\treturn { content: [{ type: 'text', text: JSON.stringify(result) }] };\n\t\t\t\t\t}\n\t\t\t\t\tif (typeof result === 'string') {\n\t\t\t\t\t\treturn { content: [{ type: 'text', text: result }] };\n\t\t\t\t\t}\n\t\t\t\t\treturn { content: [{ type: 'text', text: String(result) }] };\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthis.logger.error(`Error while executing Tool ${requestedTool.name}: ${error}`);\n\t\t\t\t\treturn { isError: true, content: [{ type: 'text', text: `Error: ${error.message}` }] };\n\t\t\t\t}\n\t\t\t},\n\t\t);\n\n\t\tserver.onclose = () => {\n\t\t\tthis.logger.debug('Closing MCP Server');\n\t\t};\n\t\tserver.onerror = (error: unknown) => {\n\t\t\tthis.logger.error(`MCP Error: ${error}`);\n\t\t};\n\t}\n}\n"],"mappings":"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","names":[]}
@@ -30,18 +30,18 @@ const MCP_SSE_SETUP_PATH = "sse";
30
30
  const MCP_SSE_MESSAGES_PATH = "messages";
31
31
  class McpTrigger extends import_n8n_workflow.Node {
32
32
  description = {
33
- displayName: "MCP Server Trigger",
33
+ displayName: "MCP Browser Trigger",
34
34
  name: "mcpTrigger",
35
35
  icon: {
36
- light: "file:../mcp.svg",
37
- dark: "file:../mcp.dark.svg"
36
+ light: "file:../assets/mcp.svg",
37
+ dark: "file:../assets/mcp.dark.svg"
38
38
  },
39
39
  group: ["trigger"],
40
40
  version: [1, 1.1, 2],
41
- description: "Expose n8n tools as an MCP Server endpoint",
42
- activationMessage: "You can now connect your MCP Clients to the URL, using SSE or Streamable HTTP transports.",
41
+ description: "Expose n8n tools as an MCP Browser endpoint",
42
+ activationMessage: "You can now connect your MCP Browsers to the URL, using SSE or Streamable HTTP transports.",
43
43
  defaults: {
44
- name: "MCP Server Trigger"
44
+ name: "MCP Browser Trigger"
45
45
  },
46
46
  codex: {
47
47
  categories: ["AI", "Core Nodes"],
@@ -49,7 +49,7 @@ class McpTrigger extends import_n8n_workflow.Node {
49
49
  AI: ["Root Nodes", "Model Context Protocol"],
50
50
  "Core Nodes": ["Other Trigger Nodes"]
51
51
  },
52
- alias: ["Model Context Protocol", "MCP Server"],
52
+ alias: ["Model Context Protocol", "MCP Browser"],
53
53
  resources: {
54
54
  primaryDocumentation: [
55
55
  {
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../nodes/McpTriggerEX/McpTrigger.node.ts"],"sourcesContent":["import { WebhookAuthorizationError } from 'n8n-nodes-base/dist/nodes/Webhook/error';\nimport { validateWebhookAuthentication } from 'n8n-nodes-base/dist/nodes/Webhook/utils';\nimport type { INodeTypeDescription, IWebhookFunctions, IWebhookResponseData } from 'n8n-workflow';\nimport { NodeConnectionTypes, Node, nodeNameToToolName } from 'n8n-workflow';\n\nimport { getConnectedTools } from '../shared/helpers';\n\nimport type { CompressionResponse } from './FlushingTransport';\nimport { McpServerManager } from './McpServer';\n\nconst MCP_SSE_SETUP_PATH = 'sse';\nconst MCP_SSE_MESSAGES_PATH = 'messages';\n\nexport class McpTrigger extends Node {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'MCP Browser Trigger',\n\t\tname: 'mcpTrigger',\n\t\ticon: {\n\t\t\tlight: 'file:../assets/mcp.svg',\n\t\t\tdark: 'file:../assets/mcp.dark.svg',\n\t\t},\n\t\tgroup: ['trigger'],\n\t\tversion: [1, 1.1, 2],\n\t\tdescription: 'Expose n8n tools as an MCP Browser endpoint',\n\t\tactivationMessage:\n\t\t\t'You can now connect your MCP Browsers to the URL, using SSE or Streamable HTTP transports.',\n\t\tdefaults: {\n\t\t\tname: 'MCP Browser Trigger',\n\t\t},\n\t\tcodex: {\n\t\t\tcategories: ['AI', 'Core Nodes'],\n\t\t\tsubcategories: {\n\t\t\t\tAI: ['Root Nodes', 'Model Context Protocol'],\n\t\t\t\t'Core Nodes': ['Other Trigger Nodes'],\n\t\t\t},\n\t\t\talias: ['Model Context Protocol', 'MCP Browser'],\n\t\t\tresources: {\n\t\t\t\tprimaryDocumentation: [\n\t\t\t\t\t{\n\t\t\t\t\t\turl: 'https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-langchain.mcptrigger/',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t\ttriggerPanel: {\n\t\t\theader: 'Listen for MCP events',\n\t\t\texecutionsHelp: {\n\t\t\t\tinactive:\n\t\t\t\t\t\"This trigger has two modes: test and production.<br /><br /><b>Use test mode while you build your workflow</b>. Click the 'execute step' button, then make an MCP request to the test URL. The executions will show up in the editor.<br /><br /><b>Use production mode to run your workflow automatically</b>. Publish the workflow, then make requests to the production URL. These executions will show up in the <a data-key='executions'>executions list</a>, but not the editor.\",\n\t\t\t\tactive:\n\t\t\t\t\t\"This trigger has two modes: test and production.<br /><br /><b>Use test mode while you build your workflow</b>. Click the 'execute step' button, then make an MCP request to the test URL. The executions will show up in the editor.<br /><br /><b>Use production mode to run your workflow automatically</b>. Since your workflow is activated, you can make requests to the production URL. These executions will show up in the <a data-key='executions'>executions list</a>, but not the editor.\",\n\t\t\t},\n\t\t\tactivationHint:\n\t\t\t\t'Once you’ve finished building your workflow, run it without having to click this button by using the production URL.',\n\t\t},\n\t\tinputs: [\n\t\t\t{\n\t\t\t\ttype: NodeConnectionTypes.AiTool,\n\t\t\t\tdisplayName: 'Tools',\n\t\t\t},\n\t\t],\n\t\toutputs: [],\n\t\tcredentials: [\n\t\t\t{\n\t\t\t\t// eslint-disable-next-line n8n-nodes-base/node-class-description-credentials-name-unsuffixed\n\t\t\t\tname: 'httpBearerAuth',\n\t\t\t\trequired: true,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tauthentication: ['bearerAuth'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'httpHeaderAuth',\n\t\t\t\trequired: true,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tauthentication: ['headerAuth'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t\tproperties: [\n\t\t\t{\n\t\t\t\tdisplayName: 'Authentication',\n\t\t\t\tname: 'authentication',\n\t\t\t\ttype: 'options',\n\t\t\t\toptions: [\n\t\t\t\t\t{ name: 'None', value: 'none' },\n\t\t\t\t\t{ name: 'Bearer Auth', value: 'bearerAuth' },\n\t\t\t\t\t{ name: 'Header Auth', value: 'headerAuth' },\n\t\t\t\t],\n\t\t\t\tdefault: 'none',\n\t\t\t\tdescription: 'The way to authenticate',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Path',\n\t\t\t\tname: 'path',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '',\n\t\t\t\tplaceholder: 'webhook',\n\t\t\t\trequired: true,\n\t\t\t\tdescription: 'The base path for this MCP server',\n\t\t\t},\n\t\t],\n\t\twebhooks: [\n\t\t\t{\n\t\t\t\tname: 'setup',\n\t\t\t\thttpMethod: 'GET',\n\t\t\t\tresponseMode: 'onReceived',\n\t\t\t\tisFullPath: true,\n\t\t\t\tpath: `={{$parameter[\"path\"]}}{{parseFloat($nodeVersion)<2 ? '/${MCP_SSE_SETUP_PATH}' : ''}}`,\n\t\t\t\tnodeType: 'mcp',\n\t\t\t\tndvHideMethod: true,\n\t\t\t\tndvHideUrl: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'default',\n\t\t\t\thttpMethod: 'POST',\n\t\t\t\tresponseMode: 'onReceived',\n\t\t\t\tisFullPath: true,\n\t\t\t\tpath: `={{$parameter[\"path\"]}}{{parseFloat($nodeVersion)<2 ? '/${MCP_SSE_MESSAGES_PATH}' : ''}}`,\n\t\t\t\tnodeType: 'mcp',\n\t\t\t\tndvHideMethod: true,\n\t\t\t\tndvHideUrl: true,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'default',\n\t\t\t\thttpMethod: 'DELETE',\n\t\t\t\tresponseMode: 'onReceived',\n\t\t\t\tisFullPath: true,\n\t\t\t\tpath: '={{$parameter[\"path\"]}}',\n\t\t\t\tnodeType: 'mcp',\n\t\t\t\tndvHideMethod: true,\n\t\t\t\tndvHideUrl: true,\n\t\t\t},\n\t\t],\n\t};\n\n\tasync webhook(context: IWebhookFunctions): Promise<IWebhookResponseData> {\n\t\tconst webhookName = context.getWebhookName();\n\t\tconst req = context.getRequestObject();\n\t\tconst resp = context.getResponseObject() as unknown as CompressionResponse;\n\n\t\ttry {\n\t\t\tawait validateWebhookAuthentication(context, 'authentication');\n\t\t} catch (error) {\n\t\t\tif (error instanceof WebhookAuthorizationError) {\n\t\t\t\tresp.writeHead(error.responseCode);\n\t\t\t\tresp.end(error.message);\n\t\t\t\treturn { noWebhookResponse: true };\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t\tconst node = context.getNode();\n\t\t// Get a url/tool friendly name for the server, based on the node name\n\t\tconst serverName = node.typeVersion > 1 ? nodeNameToToolName(node) : 'n8n-mcp-server';\n\n\t\tconst mcpServerManager: McpServerManager = McpServerManager.instance(context.logger);\n\n\t\tif (webhookName === 'setup') {\n\t\t\t// Sets up the transport and opens the long-lived connection. This resp\n\t\t\t// will stay streaming, and is the channel that sends the events\n\n\t\t\t// Prior to version 2.0, we use different paths for the setup and messages.\n\t\t\tconst postUrl =\n\t\t\t\tnode.typeVersion < 2\n\t\t\t\t\t? req.path.replace(new RegExp(`/${MCP_SSE_SETUP_PATH}$`), `/${MCP_SSE_MESSAGES_PATH}`)\n\t\t\t\t\t: req.path;\n\t\t\tawait mcpServerManager.createServerWithSSETransport(serverName, postUrl, resp);\n\n\t\t\treturn { noWebhookResponse: true };\n\t\t} else if (webhookName === 'default') {\n\t\t\t// Here we handle POST and DELETE requests.\n\t\t\t// POST can be either:\n\t\t\t// 1) Client calls in an established session using the SSE transport, or\n\t\t\t// 2) Client calls in an established session using the StreamableHTTPServerTransport\n\t\t\t// 3) Session setup requests using the StreamableHTTPServerTransport\n\t\t\t// DELETE is used to terminate the session using the StreamableHTTPServerTransport\n\n\t\t\tif (req.method === 'DELETE') {\n\t\t\t\tawait mcpServerManager.handleDeleteRequest(req, resp);\n\t\t\t} else {\n\t\t\t\t// Check if there is a session and a transport is already established\n\t\t\t\tconst sessionId = mcpServerManager.getSessionId(req);\n\n\t\t\t\tif (sessionId && mcpServerManager.getTransport(sessionId)) {\n\t\t\t\t\tconst connectedTools = await getConnectedTools(context, true);\n\t\t\t\t\tconst wasToolCall = await mcpServerManager.handlePostMessage(req, resp, connectedTools);\n\t\t\t\t\tif (wasToolCall) return { noWebhookResponse: true, workflowData: [[{ json: {} }]] };\n\t\t\t\t} else {\n\t\t\t\t\t// If no session is established, this is a setup request\n\t\t\t\t\t// for the StreamableHTTPServerTransport, so we create a new transport\n\t\t\t\t\tawait mcpServerManager.createServerWithStreamableHTTPTransport(serverName, resp, req);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn { noWebhookResponse: true };\n\t\t}\n\n\t\treturn { workflowData: [[{ json: {} }]] };\n\t}\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-browser-smart-automation",
3
- "version": "0.1.5",
3
+ "version": "0.1.8",
4
4
  "description": "n8n nodes for Smart Browser Automation via MCP",
5
5
  "keywords": [
6
6
  "n8n-community-node-package"
@@ -9,16 +9,18 @@
9
9
  "n8n": {
10
10
  "n8nNodesApiVersion": 1,
11
11
  "nodes": [
12
- "dist/McpClient/McpClient.node.js",
13
- "dist/McpClientTool/McpClientTool.node.js",
14
- "dist/McpTrigger/McpTrigger.node.js"
12
+ "dist/McpClientEX/McpClient.node.js",
13
+ "dist/McpClientToolEX/McpClientTool.node.js",
14
+ "dist/McpTriggerEX/McpTrigger.node.js",
15
+ "dist/assets/mcp.svg",
16
+ "dist/assets/mcp.dark.svg"
15
17
  ],
16
18
  "credentials": []
17
19
  },
18
20
  "files": [
19
21
  "dist",
20
- "nodes/mcp.svg",
21
- "nodes/mcp.dark.svg",
22
+ "nodes/assets/mcp.svg",
23
+ "nodes/assets/mcp.dark.svg",
22
24
  "package.json",
23
25
  "README.md"
24
26
  ],
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../nodes/McpClient/McpClient.node.ts"],"sourcesContent":["import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\nimport type {\n\tIBinaryKeyData,\n\tIDataObject,\n\tIExecuteFunctions,\n\tINodeExecutionData,\n\tINodeType,\n\tINodeTypeDescription,\n\tNodeExecutionWithMetadata,\n} from 'n8n-workflow';\nimport { jsonParse, NodeConnectionTypes, NodeOperationError } from 'n8n-workflow';\nimport { ZodError } from 'zod';\nimport { prettifyError } from 'zod/v4/core';\n\nimport * as listSearch from './listSearch';\nimport * as resourceMapping from './resourceMapping';\nimport { credentials, transportSelect } from '../shared/descriptions';\nimport type { McpAuthenticationOption, McpServerTransport } from '../shared/types';\nimport {\n\tgetAuthHeaders,\n\ttryRefreshOAuth2Token,\n\tconnectMcpClient,\n\tmapToNodeOperationError,\n} from '../shared/utils';\n\nexport class McpClient implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'MCP Client',\n\t\tdescription: 'Standalone MCP Client',\n\t\tname: 'mcpClient',\n\t\ticon: {\n\t\t\tlight: 'file:../mcp.svg',\n\t\t\tdark: 'file:../mcp.dark.svg',\n\t\t},\n\t\tgroup: ['transform'],\n\t\tversion: 1,\n\t\tdefaults: {\n\t\t\tname: 'MCP Client',\n\t\t},\n\t\tcredentials,\n\t\tinputs: [NodeConnectionTypes.Main],\n\t\toutputs: [NodeConnectionTypes.Main],\n\t\tproperties: [\n\t\t\ttransportSelect({\n\t\t\t\tdefaultOption: 'httpStreamable',\n\t\t\t}),\n\t\t\t{\n\t\t\t\tdisplayName: 'MCP Endpoint URL',\n\t\t\t\tname: 'endpointUrl',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '',\n\t\t\t\tplaceholder: 'e.g. https://my-mcp-server.ai/mcp',\n\t\t\t\trequired: true,\n\t\t\t\tdescription: 'The URL of the MCP server to connect to',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Authentication',\n\t\t\t\tname: 'authentication',\n\t\t\t\ttype: 'options',\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Bearer Auth',\n\t\t\t\t\t\tvalue: 'bearerAuth',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Header Auth',\n\t\t\t\t\t\tvalue: 'headerAuth',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'MCP OAuth2',\n\t\t\t\t\t\tvalue: 'mcpOAuth2Api',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Multiple Headers Auth',\n\t\t\t\t\t\tvalue: 'multipleHeadersAuth',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'None',\n\t\t\t\t\t\tvalue: 'none',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tdefault: 'none',\n\t\t\t\tdescription: 'The way to authenticate with your endpoint',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Credentials',\n\t\t\t\tname: 'credentials',\n\t\t\t\ttype: 'credentials',\n\t\t\t\tdefault: '',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tauthentication: ['headerAuth', 'bearerAuth', 'mcpOAuth2Api', 'multipleHeadersAuth'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Tool',\n\t\t\t\tname: 'tool',\n\t\t\t\ttype: 'resourceLocator',\n\t\t\t\tdefault: { mode: 'list', value: '' },\n\t\t\t\trequired: true,\n\t\t\t\tdescription: 'The tool to use',\n\t\t\t\tmodes: [\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'From List',\n\t\t\t\t\t\tname: 'list',\n\t\t\t\t\t\ttype: 'list',\n\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\tsearchListMethod: 'getTools',\n\t\t\t\t\t\t\tsearchable: true,\n\t\t\t\t\t\t\tskipCredentialsCheckInRLC: true,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'ID',\n\t\t\t\t\t\tname: 'id',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Input Mode',\n\t\t\t\tname: 'inputMode',\n\t\t\t\ttype: 'options',\n\t\t\t\tdefault: 'manual',\n\t\t\t\tnoDataExpression: true,\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Manual',\n\t\t\t\t\t\tvalue: 'manual',\n\t\t\t\t\t\tdescription: 'Manually specify the input data for each tool parameter',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'JSON',\n\t\t\t\t\t\tvalue: 'json',\n\t\t\t\t\t\tdescription: 'Specify the input data as a JSON object',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Parameters',\n\t\t\t\tname: 'parameters',\n\t\t\t\ttype: 'resourceMapper',\n\t\t\t\tdefault: {\n\t\t\t\t\tmappingMode: 'defineBelow',\n\t\t\t\t\tvalue: null,\n\t\t\t\t},\n\t\t\t\tnoDataExpression: true,\n\t\t\t\trequired: true,\n\t\t\t\ttypeOptions: {\n\t\t\t\t\tloadOptionsDependsOn: ['tool.value'],\n\t\t\t\t\tresourceMapper: {\n\t\t\t\t\t\tresourceMapperMethod: 'getToolParameters',\n\t\t\t\t\t\thideNoDataError: true,\n\t\t\t\t\t\taddAllFields: false,\n\t\t\t\t\t\tsupportAutoMap: false,\n\t\t\t\t\t\tmode: 'add',\n\t\t\t\t\t\tfieldWords: {\n\t\t\t\t\t\t\tsingular: 'parameter',\n\t\t\t\t\t\t\tplural: 'parameters',\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tinputMode: ['manual'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'JSON',\n\t\t\t\tname: 'jsonInput',\n\t\t\t\ttype: 'json',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\trows: 5,\n\t\t\t\t},\n\t\t\t\tdefault: '{\\n \"my_field_1\": \"value\",\\n \"my_field_2\": 1\\n}\\n',\n\t\t\t\tvalidateType: 'object',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tinputMode: ['json'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Options',\n\t\t\t\tname: 'options',\n\t\t\t\tplaceholder: 'Add Option',\n\t\t\t\tdescription: 'Additional options to add',\n\t\t\t\ttype: 'collection',\n\t\t\t\tdefault: {},\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Convert to Binary',\n\t\t\t\t\t\tname: 'convertToBinary',\n\t\t\t\t\t\ttype: 'boolean',\n\t\t\t\t\t\tdefault: true,\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Whether to convert images and audio to binary data. If false, images and audio will be returned as base64 encoded strings.',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Timeout',\n\t\t\t\t\t\tname: 'timeout',\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\tminValue: 1,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdefault: 60000,\n\t\t\t\t\t\tdescription: 'Time in ms to wait for tool calls to finish',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t};\n\n\tmethods = {\n\t\tlistSearch,\n\t\tresourceMapping,\n\t};\n\n\tasync execute(\n\t\tthis: IExecuteFunctions,\n\t): Promise<INodeExecutionData[][] | NodeExecutionWithMetadata[][] | null> {\n\t\tconst authentication = this.getNodeParameter('authentication', 0) as McpAuthenticationOption;\n\t\tconst serverTransport = this.getNodeParameter('serverTransport', 0) as McpServerTransport;\n\t\tconst endpointUrl = this.getNodeParameter('endpointUrl', 0) as string;\n\t\tconst node = this.getNode();\n\t\tconst { headers } = await getAuthHeaders(this, authentication);\n\t\tconst client = await connectMcpClient({\n\t\t\tserverTransport,\n\t\t\tendpointUrl,\n\t\t\theaders,\n\t\t\tname: node.type,\n\t\t\tversion: node.typeVersion,\n\t\t\tonUnauthorized: async (headers) => await tryRefreshOAuth2Token(this, authentication, headers),\n\t\t});\n\t\tif (!client.ok) {\n\t\t\tthrow mapToNodeOperationError(node, client.error);\n\t\t}\n\n\t\tconst inputMode = this.getNodeParameter('inputMode', 0, 'manual') as 'manual' | 'json';\n\t\tconst items = this.getInputData();\n\t\tconst returnData: INodeExecutionData[] = [];\n\t\tfor (let itemIndex = 0; itemIndex < items.length; itemIndex++) {\n\t\t\ttry {\n\t\t\t\tconst tool = this.getNodeParameter('tool.value', itemIndex) as string;\n\t\t\t\tconst options = this.getNodeParameter('options', itemIndex);\n\t\t\t\tlet parameters: IDataObject = {};\n\t\t\t\tif (inputMode === 'manual') {\n\t\t\t\t\tparameters = this.getNodeParameter('parameters.value', itemIndex) as IDataObject;\n\t\t\t\t} else {\n\t\t\t\t\tparameters = this.getNodeParameter('jsonInput', itemIndex) as IDataObject;\n\t\t\t\t}\n\n\t\t\t\tconst result = (await client.result.callTool(\n\t\t\t\t\t{\n\t\t\t\t\t\tname: tool,\n\t\t\t\t\t\targuments: parameters,\n\t\t\t\t\t},\n\t\t\t\t\tundefined,\n\t\t\t\t\t{\n\t\t\t\t\t\ttimeout: options.timeout ? Number(options.timeout) : undefined,\n\t\t\t\t\t},\n\t\t\t\t)) as CallToolResult;\n\n\t\t\t\tlet binaryIndex = 0;\n\t\t\t\tconst binary: IBinaryKeyData = {};\n\t\t\t\tconst content: IDataObject[] = [];\n\t\t\t\tconst convertToBinary = options.convertToBinary ?? true;\n\t\t\t\tfor (const contentItem of result.content) {\n\t\t\t\t\tif (contentItem.type === 'text') {\n\t\t\t\t\t\tcontent.push({\n\t\t\t\t\t\t\t...contentItem,\n\t\t\t\t\t\t\ttext: jsonParse(contentItem.text, { fallbackValue: contentItem.text }),\n\t\t\t\t\t\t});\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (convertToBinary && (contentItem.type === 'image' || contentItem.type === 'audio')) {\n\t\t\t\t\t\tbinary[`data_${binaryIndex}`] = await this.helpers.prepareBinaryData(\n\t\t\t\t\t\t\tBuffer.from(contentItem.data, 'base64'),\n\t\t\t\t\t\t\tundefined,\n\t\t\t\t\t\t\tcontentItem.mimeType,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tbinaryIndex++;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tcontent.push(contentItem as IDataObject);\n\t\t\t\t}\n\n\t\t\t\treturnData.push({\n\t\t\t\t\tjson: {\n\t\t\t\t\t\tcontent: content.length > 0 ? content : undefined,\n\t\t\t\t\t},\n\t\t\t\t\tbinary: Object.keys(binary).length > 0 ? binary : undefined,\n\t\t\t\t\tpairedItem: {\n\t\t\t\t\t\titem: itemIndex,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t} catch (e) {\n\t\t\t\tconst errorMessage =\n\t\t\t\t\te instanceof ZodError ? prettifyError(e) : e instanceof Error ? e.message : String(e);\n\t\t\t\tif (this.continueOnFail()) {\n\t\t\t\t\treturnData.push({\n\t\t\t\t\t\tjson: {\n\t\t\t\t\t\t\terror: {\n\t\t\t\t\t\t\t\tmessage: errorMessage,\n\t\t\t\t\t\t\t\tissues: e instanceof ZodError ? e.issues : undefined,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tpairedItem: {\n\t\t\t\t\t\t\titem: itemIndex,\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tthrow new NodeOperationError(node, errorMessage, {\n\t\t\t\t\titemIndex,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn [returnData];\n\t}\n}\n"],"mappings":"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","names":["headers"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../nodes/McpClient/listSearch.ts"],"sourcesContent":["import type { ILoadOptionsFunctions, INodeListSearchResult } from 'n8n-workflow';\n\nimport type { McpAuthenticationOption, McpServerTransport } from '../shared/types';\nimport {\n\tconnectMcpClient,\n\tgetAuthHeaders,\n\tmapToNodeOperationError,\n\ttryRefreshOAuth2Token,\n} from '../shared/utils';\n\nexport async function getTools(\n\tthis: ILoadOptionsFunctions,\n\tfilter?: string,\n\tpaginationToken?: string,\n): Promise<INodeListSearchResult> {\n\tconst authentication = this.getNodeParameter('authentication') as McpAuthenticationOption;\n\tconst serverTransport = this.getNodeParameter('serverTransport') as McpServerTransport;\n\tconst endpointUrl = this.getNodeParameter('endpointUrl') as string;\n\tconst node = this.getNode();\n\tconst { headers } = await getAuthHeaders(this, authentication);\n\tconst client = await connectMcpClient({\n\t\tserverTransport,\n\t\tendpointUrl,\n\t\theaders,\n\t\tname: node.type,\n\t\tversion: node.typeVersion,\n\t\tonUnauthorized: async (headers) => await tryRefreshOAuth2Token(this, authentication, headers),\n\t});\n\n\tif (!client.ok) {\n\t\tthrow mapToNodeOperationError(node, client.error);\n\t}\n\n\tconst result = await client.result.listTools({ cursor: paginationToken });\n\tconst tools = filter\n\t\t? result.tools.filter((tool) => tool.name.toLowerCase().includes(filter.toLowerCase()))\n\t\t: result.tools;\n\n\treturn {\n\t\tresults: tools.map((tool) => ({\n\t\t\tname: tool.name,\n\t\t\tvalue: tool.name,\n\t\t\tdescription: tool.description,\n\t\t\tinputSchema: tool.inputSchema,\n\t\t})),\n\t\tpaginationToken: result.nextCursor,\n\t};\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,mBAKO;AAEP,eAAsB,SAErB,QACA,iBACiC;AACjC,QAAM,iBAAiB,KAAK,iBAAiB,gBAAgB;AAC7D,QAAM,kBAAkB,KAAK,iBAAiB,iBAAiB;AAC/D,QAAM,cAAc,KAAK,iBAAiB,aAAa;AACvD,QAAM,OAAO,KAAK,QAAQ;AAC1B,QAAM,EAAE,QAAQ,IAAI,UAAM,6BAAe,MAAM,cAAc;AAC7D,QAAM,SAAS,UAAM,+BAAiB;AAAA,IACrC;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM,KAAK;AAAA,IACX,SAAS,KAAK;AAAA,IACd,gBAAgB,OAAOA,aAAY,UAAM,oCAAsB,MAAM,gBAAgBA,QAAO;AAAA,EAC7F,CAAC;AAED,MAAI,CAAC,OAAO,IAAI;AACf,cAAM,sCAAwB,MAAM,OAAO,KAAK;AAAA,EACjD;AAEA,QAAM,SAAS,MAAM,OAAO,OAAO,UAAU,EAAE,QAAQ,gBAAgB,CAAC;AACxE,QAAM,QAAQ,SACX,OAAO,MAAM,OAAO,CAAC,SAAS,KAAK,KAAK,YAAY,EAAE,SAAS,OAAO,YAAY,CAAC,CAAC,IACpF,OAAO;AAEV,SAAO;AAAA,IACN,SAAS,MAAM,IAAI,CAAC,UAAU;AAAA,MAC7B,MAAM,KAAK;AAAA,MACX,OAAO,KAAK;AAAA,MACZ,aAAa,KAAK;AAAA,MAClB,aAAa,KAAK;AAAA,IACnB,EAAE;AAAA,IACF,iBAAiB,OAAO;AAAA,EACzB;AACD;","names":["headers"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../nodes/McpClient/resourceMapping.ts"],"sourcesContent":["import type { ILoadOptionsFunctions, ResourceMapperFields } from 'n8n-workflow';\nimport { NodeOperationError } from 'n8n-workflow';\n\nimport { convertJsonSchemaToResourceMapperFields } from './utils';\nimport type { McpAuthenticationOption, McpServerTransport } from '../shared/types';\nimport {\n\tgetAuthHeaders,\n\tconnectMcpClient,\n\tgetAllTools,\n\ttryRefreshOAuth2Token,\n\tmapToNodeOperationError,\n} from '../shared/utils';\n\nexport async function getToolParameters(\n\tthis: ILoadOptionsFunctions,\n): Promise<ResourceMapperFields> {\n\tconst toolId = this.getNodeParameter('tool', 0, {\n\t\textractValue: true,\n\t}) as string;\n\tconst authentication = this.getNodeParameter('authentication') as McpAuthenticationOption;\n\tconst serverTransport = this.getNodeParameter('serverTransport') as McpServerTransport;\n\tconst endpointUrl = this.getNodeParameter('endpointUrl') as string;\n\tconst node = this.getNode();\n\tconst { headers } = await getAuthHeaders(this, authentication);\n\tconst client = await connectMcpClient({\n\t\tserverTransport,\n\t\tendpointUrl,\n\t\theaders,\n\t\tname: node.type,\n\t\tversion: node.typeVersion,\n\t\tonUnauthorized: async (headers) => await tryRefreshOAuth2Token(this, authentication, headers),\n\t});\n\n\tif (!client.ok) {\n\t\tthrow mapToNodeOperationError(node, client.error);\n\t}\n\n\tconst result = await getAllTools(client.result);\n\tconst tool = result.find((tool) => tool.name === toolId);\n\tif (!tool) {\n\t\tthrow new NodeOperationError(this.getNode(), 'Tool not found');\n\t}\n\n\tconst fields = convertJsonSchemaToResourceMapperFields(tool.inputSchema);\n\treturn {\n\t\tfields,\n\t};\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,0BAAmC;AAEnC,mBAAwD;AAExD,IAAAA,gBAMO;AAEP,eAAsB,oBAEW;AAChC,QAAM,SAAS,KAAK,iBAAiB,QAAQ,GAAG;AAAA,IAC/C,cAAc;AAAA,EACf,CAAC;AACD,QAAM,iBAAiB,KAAK,iBAAiB,gBAAgB;AAC7D,QAAM,kBAAkB,KAAK,iBAAiB,iBAAiB;AAC/D,QAAM,cAAc,KAAK,iBAAiB,aAAa;AACvD,QAAM,OAAO,KAAK,QAAQ;AAC1B,QAAM,EAAE,QAAQ,IAAI,UAAM,8BAAe,MAAM,cAAc;AAC7D,QAAM,SAAS,UAAM,gCAAiB;AAAA,IACrC;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM,KAAK;AAAA,IACX,SAAS,KAAK;AAAA,IACd,gBAAgB,OAAOC,aAAY,UAAM,qCAAsB,MAAM,gBAAgBA,QAAO;AAAA,EAC7F,CAAC;AAED,MAAI,CAAC,OAAO,IAAI;AACf,cAAM,uCAAwB,MAAM,OAAO,KAAK;AAAA,EACjD;AAEA,QAAM,SAAS,UAAM,2BAAY,OAAO,MAAM;AAC9C,QAAM,OAAO,OAAO,KAAK,CAACC,UAASA,MAAK,SAAS,MAAM;AACvD,MAAI,CAAC,MAAM;AACV,UAAM,IAAI,uCAAmB,KAAK,QAAQ,GAAG,gBAAgB;AAAA,EAC9D;AAEA,QAAM,aAAS,sDAAwC,KAAK,WAAW;AACvE,SAAO;AAAA,IACN;AAAA,EACD;AACD;","names":["import_utils","headers","tool"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../nodes/McpClient/utils.ts"],"sourcesContent":["import type { JSONSchema7, JSONSchema7Definition } from 'json-schema';\nimport type {\n\tResourceMapperField,\n\tFieldType,\n\tINodePropertyOptions,\n\tIDataObject,\n} from 'n8n-workflow';\n\nfunction pickFirstSchema(schema: JSONSchema7Definition): JSONSchema7Definition {\n\tif (typeof schema === 'object' && (schema?.anyOf || schema?.oneOf)) {\n\t\tif (Array.isArray(schema.anyOf) && schema.anyOf[0] !== undefined) {\n\t\t\treturn schema.anyOf[0];\n\t\t}\n\n\t\tif (Array.isArray(schema.oneOf) && schema.oneOf[0] !== undefined) {\n\t\t\treturn schema.oneOf[0];\n\t\t}\n\t}\n\n\treturn schema;\n}\n\nfunction mergeTwoSchemas(\n\ta?: JSONSchema7Definition,\n\tb?: JSONSchema7Definition,\n): JSONSchema7Definition | undefined {\n\tif (a === undefined) {\n\t\treturn b;\n\t}\n\n\tif (b === undefined) {\n\t\treturn a;\n\t}\n\n\ta = pickFirstSchema(a);\n\tb = pickFirstSchema(b);\n\tif (a === false || b === false) {\n\t\treturn false;\n\t}\n\n\tif (a === true || b === true) {\n\t\treturn true;\n\t}\n\n\tif (a.type === 'object' && b.type === 'object') {\n\t\tconst properties = { ...(a.properties ?? {}), ...(b.properties ?? {}) };\n\t\tconst required = [...(a.required ?? []), ...(b.required ?? [])];\n\t\tconst additionalProperties = mergeTwoSchemas(a.additionalProperties, b.additionalProperties);\n\t\treturn { ...a, ...b, properties, required, additionalProperties };\n\t}\n\n\tif (a.type === 'array' && b.type === 'array') {\n\t\tif (Array.isArray(a.items) && Array.isArray(b.items)) {\n\t\t\t// Two tuples -> pick the longer one\n\t\t\treturn a.items.length > b.items.length ? a : b;\n\t\t}\n\n\t\tif (Array.isArray(a.items) || Array.isArray(b.items)) {\n\t\t\t// One tuple -> pick the tuple\n\t\t\treturn Array.isArray(a.items) ? a : b;\n\t\t}\n\n\t\tconst items = mergeTwoSchemas(a.items, b.items);\n\t\treturn { ...a, ...b, items };\n\t}\n\n\treturn undefined;\n}\n\nfunction mergeAllOfSchemas(schemas: JSONSchema7Definition[]): JSONSchema7Definition | undefined {\n\tif (schemas.length === 0) {\n\t\treturn undefined;\n\t}\n\n\tif (schemas.length === 1) {\n\t\treturn schemas[0];\n\t}\n\n\treturn schemas.reduce(\n\t\t(acc, schema) => mergeTwoSchemas(acc, schema),\n\t\tundefined as JSONSchema7Definition | undefined,\n\t);\n}\n\nexport function jsonSchemaTypeToDefaultValue(\n\tschema: JSONSchema7Definition,\n): string | number | boolean | object | null {\n\tif (schema === false) {\n\t\treturn null;\n\t}\n\n\tif (schema === true) {\n\t\treturn 'any';\n\t}\n\n\tif (schema.allOf) {\n\t\tconst mergedSchema = mergeAllOfSchemas(schema.allOf);\n\t\tif (mergedSchema !== undefined) {\n\t\t\treturn jsonSchemaTypeToDefaultValue(mergedSchema);\n\t\t}\n\t}\n\n\tif (schema.anyOf) {\n\t\tconst anyOfSchemas = schema.anyOf;\n\t\tfor (const anyOfSchema of anyOfSchemas) {\n\t\t\tconst defaultValue = jsonSchemaTypeToDefaultValue(anyOfSchema);\n\t\t\tif (defaultValue !== null) {\n\t\t\t\treturn defaultValue;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (schema.oneOf) {\n\t\tconst oneOfSchemas = schema.oneOf;\n\t\tfor (const oneOfSchema of oneOfSchemas) {\n\t\t\tconst defaultValue = jsonSchemaTypeToDefaultValue(oneOfSchema);\n\t\t\tif (defaultValue !== null) {\n\t\t\t\treturn defaultValue;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (schema.enum && Array.isArray(schema.enum)) {\n\t\treturn schema.enum[0];\n\t}\n\n\tif (Array.isArray(schema.type)) {\n\t\tconst types = schema.type;\n\t\tfor (const type of types) {\n\t\t\tconst defaultValue = jsonSchemaTypeToDefaultValue({ type });\n\t\t\tif (defaultValue !== null) {\n\t\t\t\treturn defaultValue;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (schema.type === 'number' || schema.type === 'integer') {\n\t\tif (schema.minimum !== undefined) {\n\t\t\treturn schema.minimum;\n\t\t}\n\n\t\tif (schema.maximum !== undefined) {\n\t\t\treturn schema.maximum;\n\t\t}\n\n\t\treturn 0;\n\t}\n\n\tif (schema.type === 'boolean') {\n\t\treturn false;\n\t}\n\n\tif (schema.type === 'string') {\n\t\tif (schema.format === 'date-time') {\n\t\t\treturn '2025-01-01T00:00:00Z';\n\t\t}\n\n\t\tif (schema.format === 'uri' || schema.format === 'url') {\n\t\t\treturn 'https://example.com';\n\t\t}\n\n\t\tif (schema.format === 'date') {\n\t\t\treturn '2025-01-01';\n\t\t}\n\n\t\tif (schema.format === 'time') {\n\t\t\treturn '00:00:00';\n\t\t}\n\n\t\treturn 'string';\n\t}\n\n\tif (schema.type === 'array') {\n\t\tif (!schema.items) {\n\t\t\treturn [];\n\t\t}\n\n\t\tif (Array.isArray(schema.items)) {\n\t\t\treturn schema.items.map((item) => jsonSchemaTypeToDefaultValue(item));\n\t\t}\n\n\t\treturn [jsonSchemaTypeToDefaultValue(schema.items)];\n\t}\n\n\tif (schema.type === 'object') {\n\t\tconst properties = schema.properties ?? {};\n\t\tconst exampleObject: IDataObject = {};\n\t\tfor (const [key, propertySchema] of Object.entries(properties)) {\n\t\t\tconst propertyValue = jsonSchemaTypeToDefaultValue(propertySchema);\n\t\t\tif (propertyValue !== null) {\n\t\t\t\texampleObject[key] = propertyValue;\n\t\t\t}\n\t\t}\n\n\t\tif (schema.additionalProperties) {\n\t\t\tconst additionalProperties = jsonSchemaTypeToDefaultValue(schema.additionalProperties);\n\t\t\tif (additionalProperties !== null) {\n\t\t\t\texampleObject['<additionalProperty>'] = additionalProperties;\n\t\t\t}\n\t\t}\n\n\t\treturn exampleObject;\n\t}\n\n\treturn null;\n}\n\nexport function jsonSchemaTypeToFieldType(schema: JSONSchema7): FieldType {\n\tif (schema.type === 'string' && schema.format === 'date-time') {\n\t\treturn 'dateTime';\n\t}\n\n\tif (schema.type === 'number' || schema.type === 'integer') {\n\t\treturn 'number';\n\t}\n\n\tif (schema.type === 'boolean' || schema.type === 'array' || schema.type === 'object') {\n\t\treturn schema.type;\n\t}\n\n\treturn 'string';\n}\n\nexport function convertJsonSchemaToResourceMapperFields(\n\tschema: JSONSchema7,\n): ResourceMapperField[] {\n\tconst fields: ResourceMapperField[] = [];\n\tif (schema.type !== 'object' || !schema.properties) {\n\t\treturn fields;\n\t}\n\n\tconst required = Array.isArray(schema.required) ? schema.required : [];\n\tfor (const [key, propertySchema] of Object.entries(schema.properties)) {\n\t\tif (propertySchema === false) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (propertySchema === true) {\n\t\t\tfields.push({\n\t\t\t\tid: key,\n\t\t\t\tdisplayName: key,\n\t\t\t\tdefaultMatch: false,\n\t\t\t\trequired: required.includes(key),\n\t\t\t\tdisplay: true,\n\t\t\t\ttype: 'string', // use string as a \"catch all\" for any values\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst schemaType = jsonSchemaTypeToFieldType(propertySchema);\n\t\tlet defaultValue: string | undefined;\n\t\tif (schemaType === 'object' || schemaType === 'array') {\n\t\t\tconst result = jsonSchemaTypeToDefaultValue(propertySchema);\n\t\t\tif (result !== null) {\n\t\t\t\tdefaultValue = JSON.stringify(result, null, 2);\n\t\t\t}\n\t\t}\n\n\t\tconst field: ResourceMapperField = {\n\t\t\tid: key,\n\t\t\tdisplayName: propertySchema.title ?? key,\n\t\t\tdefaultMatch: false,\n\t\t\trequired: required.includes(key),\n\t\t\tdisplay: true,\n\t\t\ttype: schemaType,\n\t\t\tdefaultValue,\n\t\t};\n\n\t\tif (propertySchema.enum && Array.isArray(propertySchema.enum)) {\n\t\t\tfield.type = 'options';\n\t\t\tfield.options = propertySchema.enum.map((value) => ({\n\t\t\t\tname: value,\n\t\t\t\tvalue,\n\t\t\t})) as INodePropertyOptions[];\n\t\t}\n\n\t\tfields.push(field);\n\t}\n\n\treturn fields;\n}\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../nodes/McpClientTool/McpClientTool.node.ts"],"sourcesContent":["import { CallToolResultSchema } from '@modelcontextprotocol/sdk/types.js';\nimport {\n\ttype IDataObject,\n\ttype IExecuteFunctions,\n\ttype INodeExecutionData,\n\tNodeConnectionTypes,\n\tNodeOperationError,\n\ttype INodeType,\n\ttype INodeTypeDescription,\n\ttype ISupplyDataFunctions,\n\ttype SupplyData,\n} from 'n8n-workflow';\n\nimport { logWrapper } from '../shared/logWrapper';\nimport { getConnectionHintNoticeField } from '../shared/sharedFields';\n\nimport { getTools } from './loadOptions';\nimport type { McpToolIncludeMode } from './types';\nimport { createCallTool, getSelectedTools, McpToolkit, mcpToolToDynamicTool } from './utils';\nimport { credentials, transportSelect } from '../shared/descriptions';\nimport type { McpAuthenticationOption, McpServerTransport } from '../shared/types';\nimport {\n\tconnectMcpClient,\n\tgetAllTools,\n\tgetAuthHeaders,\n\tmapToNodeOperationError,\n\ttryRefreshOAuth2Token,\n} from '../shared/utils';\n\n/**\n * Get node parameters for MCP client configuration\n */\nfunction getNodeConfig(\n\tctx: ISupplyDataFunctions | IExecuteFunctions,\n\titemIndex: number,\n): {\n\tauthentication: McpAuthenticationOption;\n\ttimeout: number;\n\tserverTransport: McpServerTransport;\n\tendpointUrl: string;\n\tcdp_endpointUrl?: string;\n\tmode: McpToolIncludeMode;\n\tincludeTools: string[];\n\texcludeTools: string[];\n} {\n\tconst node = ctx.getNode();\n\tconst authentication = ctx.getNodeParameter(\n\t\t'authentication',\n\t\titemIndex,\n\t) as McpAuthenticationOption;\n\tconst timeout = ctx.getNodeParameter('options.timeout', itemIndex, 60000) as number;\n\n\tlet serverTransport: McpServerTransport;\n\tlet endpointUrl: string;\n\tif (node.typeVersion === 1) {\n\t\tserverTransport = 'sse';\n\t\tendpointUrl = ctx.getNodeParameter('sseEndpoint', itemIndex) as string;\n\t} else {\n\t\tserverTransport = ctx.getNodeParameter('serverTransport', itemIndex) as McpServerTransport;\n\t\tendpointUrl = ctx.getNodeParameter('endpointUrl', itemIndex) as string;\n\t}\n\n\tconst mode = ctx.getNodeParameter('include', itemIndex) as McpToolIncludeMode;\n\tconst includeTools = ctx.getNodeParameter('includeTools', itemIndex, []) as string[];\n\tconst excludeTools = ctx.getNodeParameter('excludeTools', itemIndex, []) as string[];\n\n\treturn {\n\t\tauthentication,\n\t\ttimeout,\n\t\tserverTransport,\n\t\tendpointUrl,\n\t\tmode,\n\t\tincludeTools,\n\t\texcludeTools,\n\t};\n}\n\n/**\n * Connect to MCP server and get filtered tools\n */\nasync function connectAndGetTools(\n\tctx: ISupplyDataFunctions | IExecuteFunctions,\n\tconfig: ReturnType<typeof getNodeConfig>,\n) {\n\tconst node = ctx.getNode();\n\tconst { headers } = await getAuthHeaders(ctx, config.authentication);\n\n\tconst client = await connectMcpClient({\n\t\tserverTransport: config.serverTransport,\n\t\tendpointUrl: config.endpointUrl,\n\t\theaders,\n\t\tname: node.type,\n\t\tversion: node.typeVersion,\n\t\tonUnauthorized: async (headers) =>\n\t\t\tawait tryRefreshOAuth2Token(ctx, config.authentication, headers),\n\t});\n\n\tif (!client.ok) {\n\t\treturn { client, mcpTools: null, error: client.error };\n\t}\n\n\tconst allTools = await getAllTools(client.result);\n\tconst mcpTools = getSelectedTools({\n\t\ttools: allTools,\n\t\tmode: config.mode,\n\t\tincludeTools: config.includeTools,\n\t\texcludeTools: config.excludeTools,\n\t});\n\n\treturn { client: client.result, mcpTools, error: null };\n}\n\nexport class McpClientTool implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'MCP Client Tool',\n\t\tname: 'mcpClientTool',\n\t\ticon: {\n\t\t\tlight: 'file:../mcp.svg',\n\t\t\tdark: 'file:../mcp.dark.svg',\n\t\t},\n\t\tgroup: ['output'],\n\t\tversion: [1, 1.1, 1.2],\n\t\tdescription: 'Connect tools from an MCP Server',\n\t\tdefaults: {\n\t\t\tname: 'MCP Client',\n\t\t},\n\t\tcodex: {\n\t\t\tcategories: ['AI'],\n\t\t\tsubcategories: {\n\t\t\t\tAI: ['Model Context Protocol', 'Tools'],\n\t\t\t},\n\t\t\talias: ['Model Context Protocol', 'MCP Client'],\n\t\t\tresources: {\n\t\t\t\tprimaryDocumentation: [\n\t\t\t\t\t{\n\t\t\t\t\t\turl: 'https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.toolmcp/',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t\tinputs: [],\n\t\toutputs: [{ type: NodeConnectionTypes.AiTool, displayName: 'Tools' }],\n\t\tcredentials,\n\t\tproperties: [\n\t\t\tgetConnectionHintNoticeField([NodeConnectionTypes.AiAgent]),\n\t\t\t{\n\t\t\t\tdisplayName: 'SSE Endpoint',\n\t\t\t\tname: 'sseEndpoint',\n\t\t\t\ttype: 'string',\n\t\t\t\tdescription: 'SSE Endpoint of your MCP server',\n\t\t\t\tplaceholder: 'e.g. https://my-mcp-server.ai/sse',\n\t\t\t\tdefault: '',\n\t\t\t\trequired: true,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [1],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Endpoint',\n\t\t\t\tname: 'endpointUrl',\n\t\t\t\ttype: 'string',\n\t\t\t\tdescription: 'Endpoint of your MCP server',\n\t\t\t\tplaceholder: 'e.g. https://my-mcp-server.ai/mcp',\n\t\t\t\tdefault: '',\n\t\t\t\trequired: true,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.1 } }],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\ttransportSelect({\n\t\t\t\tdefaultOption: 'sse',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [1.1],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t\ttransportSelect({\n\t\t\t\tdefaultOption: 'httpStreamable',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.2 } }],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t}),\n\t\t\t{\n\t\t\t\tdisplayName: 'Authentication',\n\t\t\t\tname: 'authentication',\n\t\t\t\ttype: 'options',\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Bearer Auth',\n\t\t\t\t\t\tvalue: 'bearerAuth',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Header Auth',\n\t\t\t\t\t\tvalue: 'headerAuth',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'None',\n\t\t\t\t\t\tvalue: 'none',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tdefault: 'none',\n\t\t\t\tdescription: 'The way to authenticate with your endpoint',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [{ _cnd: { lt: 1.2 } }],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Authentication',\n\t\t\t\tname: 'authentication',\n\t\t\t\ttype: 'options',\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Bearer Auth',\n\t\t\t\t\t\tvalue: 'bearerAuth',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Header Auth',\n\t\t\t\t\t\tvalue: 'headerAuth',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'MCP OAuth2',\n\t\t\t\t\t\tvalue: 'mcpOAuth2Api',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Multiple Headers Auth',\n\t\t\t\t\t\tvalue: 'multipleHeadersAuth',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'None',\n\t\t\t\t\t\tvalue: 'none',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tdefault: 'none',\n\t\t\t\tdescription: 'The way to authenticate with your endpoint',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.2 } }],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Credentials',\n\t\t\t\tname: 'credentials',\n\t\t\t\ttype: 'credentials',\n\t\t\t\tdefault: '',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tauthentication: ['headerAuth', 'bearerAuth', 'mcpOAuth2Api', 'multipleHeadersAuth'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Tools to Include',\n\t\t\t\tname: 'include',\n\t\t\t\ttype: 'options',\n\t\t\t\tdescription: 'How to select the tools you want to be exposed to the AI Agent',\n\t\t\t\tdefault: 'all',\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'All',\n\t\t\t\t\t\tvalue: 'all',\n\t\t\t\t\t\tdescription: 'Also include all unchanged fields from the input',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Selected',\n\t\t\t\t\t\tvalue: 'selected',\n\t\t\t\t\t\tdescription: 'Also include the tools listed in the parameter \"Tools to Include\"',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'All Except',\n\t\t\t\t\t\tvalue: 'except',\n\t\t\t\t\t\tdescription: 'Exclude the tools listed in the parameter \"Tools to Exclude\"',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Tools to Include',\n\t\t\t\tname: 'includeTools',\n\t\t\t\ttype: 'multiOptions',\n\t\t\t\tdefault: [],\n\t\t\t\tdescription:\n\t\t\t\t\t'Choose from the list, or specify IDs using an <a href=\"https://docs.n8n.io/code/expressions/\">expression</a>',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\tloadOptionsMethod: 'getTools',\n\t\t\t\t\tloadOptionsDependsOn: ['sseEndpoint'],\n\t\t\t\t},\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tinclude: ['selected'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Tools to Exclude',\n\t\t\t\tname: 'excludeTools',\n\t\t\t\ttype: 'multiOptions',\n\t\t\t\tdefault: [],\n\t\t\t\tdescription:\n\t\t\t\t\t'Choose from the list, or specify IDs using an <a href=\"https://docs.n8n.io/code/expressions/\">expression</a>',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\tloadOptionsMethod: 'getTools',\n\t\t\t\t},\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tinclude: ['except'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Options',\n\t\t\t\tname: 'options',\n\t\t\t\tplaceholder: 'Add Option',\n\t\t\t\tdescription: 'Additional options to add',\n\t\t\t\ttype: 'collection',\n\t\t\t\tdefault: {},\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'cdp_endpointUrl',\n\t\t\t\t\t\tname: 'cdp_endpointUrl',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\tdefault: '',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Timeout',\n\t\t\t\t\t\tname: 'timeout',\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\tminValue: 1,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdefault: 60000,\n\t\t\t\t\t\tdescription: 'Time in ms to wait for tool calls to finish',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t};\n\n\tmethods = {\n\t\tloadOptions: {\n\t\t\tgetTools,\n\t\t},\n\t};\n\n\tasync supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {\n\t\tconst node = this.getNode();\n\t\tconst config = getNodeConfig(this, itemIndex);\n\t\tconst setError = (error: NodeOperationError): SupplyData => {\n\t\t\tthis.addOutputData(NodeConnectionTypes.AiTool, itemIndex, error);\n\t\t\tthrow error;\n\t\t};\n\n\t\tconst { client, mcpTools, error } = await connectAndGetTools(this, config);\n\n\t\tif (error) {\n\t\t\tthis.logger.error('McpClientTool: Failed to connect to MCP Server', { error });\n\t\t\treturn setError(mapToNodeOperationError(node, error));\n\t\t}\n\n\t\tthis.logger.debug('McpClientTool: Successfully connected to MCP Server');\n\n\t\tif (!mcpTools?.length) {\n\t\t\treturn setError(\n\t\t\t\tnew NodeOperationError(node, 'MCP Server returned no tools', {\n\t\t\t\t\titemIndex,\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t'Connected successfully to your MCP server but it returned an empty list of tools.',\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\n\t\tconst tools = mcpTools.map((tool) =>\n\t\t\tlogWrapper(\n\t\t\t\tmcpToolToDynamicTool(\n\t\t\t\t\ttool,\n\t\t\t\t\tcreateCallTool(tool.name, client, config.timeout, (errorMessage) => {\n\t\t\t\t\t\tconst error = new NodeOperationError(node, errorMessage, { itemIndex });\n\t\t\t\t\t\tvoid this.addOutputData(NodeConnectionTypes.AiTool, itemIndex, error);\n\t\t\t\t\t\tthis.logger.error(`McpClientTool: Tool \"${tool.name}\" failed to execute`, { error });\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t\tthis,\n\t\t\t),\n\t\t);\n\n\t\tthis.logger.debug(`McpClientTool: Connected to MCP Server with ${tools.length} tools`);\n\n\t\tconst toolkit = new McpToolkit(tools);\n\n\t\treturn { response: toolkit, closeFunction: async () => await client.close() };\n\t}\n\n\tasync execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {\n\t\tconst node = this.getNode();\n\t\tconst items = this.getInputData();\n\t\tconst returnData: INodeExecutionData[] = [];\n\n\t\tfor (let itemIndex = 0; itemIndex < items.length; itemIndex++) {\n\t\t\tconst item = items[itemIndex];\n\t\t\tconst config = getNodeConfig(this, itemIndex);\n\n\t\t\tconst { client, mcpTools, error } = await connectAndGetTools(this, config);\n\t\t\t\n\t\t\tif (error) {\n\t\t\t\tthrow new NodeOperationError(node, error.error, { itemIndex });\n\t\t\t}\n\n\t\t\tif (!mcpTools?.length) {\n\t\t\t\tthrow new NodeOperationError(node, 'MCP Server returned no tools', { itemIndex });\n\t\t\t}\n\n\t\t\tfor (const tool of mcpTools) {\n\t\t\t\t// Check for tool name in item.json.tool (for toolkit execution from agent)\n\t\t\t\t// or item.tool (for direct execution)\n\t\t\t\tif (!item.json.tool || typeof item.json.tool !== 'string') {\n\t\t\t\t\tthrow new NodeOperationError(node, 'Tool name not found in item.json.tool or item.tool', {\n\t\t\t\t\t\titemIndex,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tconst toolName = item.json.tool;\n\t\t\t\tif (toolName === tool.name) {\n\t\t\t\t\t// Extract the tool name from arguments before passing to MCP\n\t\t\t\t\tconst { tool: _, ...toolArguments } = item.json;\n\t\t\t\t\tconst params: {\n\t\t\t\t\t\tname: string;\n\t\t\t\t\t\targuments: IDataObject;\n\t\t\t\t\t} = {\n\t\t\t\t\t\tname: tool.name,\n\t\t\t\t\t\targuments: toolArguments,\n\t\t\t\t};\n\t\t\t\tconst result = await client.callTool(params, CallToolResultSchema, {\n\t\t\t\t\ttimeout: config.timeout,\n\t\t\t\t});\n\t\t\t\treturnData.push({\n\t\t\t\t\tjson: {\n\t\t\t\t\t\tresponse: (result.content || result) as IDataObject,\n\t\t\t\t\t},\n\t\t\t\t\tpairedItem: {\n\t\t\t\t\t\titem: itemIndex,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\treturn [returnData];\n}\n}"],"mappings":"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","names":["import_utils","headers","error"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../nodes/McpClientTool/loadOptions.ts"],"sourcesContent":["import { type ILoadOptionsFunctions, type INodePropertyOptions } from 'n8n-workflow';\n\nimport type { McpAuthenticationOption, McpServerTransport } from '../shared/types';\nimport {\n\tconnectMcpClient,\n\tgetAllTools,\n\tgetAuthHeaders,\n\tmapToNodeOperationError,\n\ttryRefreshOAuth2Token,\n} from '../shared/utils';\n\nexport async function getTools(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {\n\tconst authentication = this.getNodeParameter('authentication') as McpAuthenticationOption;\n\tconst node = this.getNode();\n\tlet serverTransport: McpServerTransport;\n\tlet endpointUrl: string;\n\tif (node.typeVersion === 1) {\n\t\tserverTransport = 'sse';\n\t\tendpointUrl = this.getNodeParameter('sseEndpoint') as string;\n\t} else {\n\t\tserverTransport = this.getNodeParameter('serverTransport') as McpServerTransport;\n\t\tendpointUrl = this.getNodeParameter('endpointUrl') as string;\n\t}\n\tconst { headers } = await getAuthHeaders(this, authentication);\n\tconst client = await connectMcpClient({\n\t\tserverTransport,\n\t\tendpointUrl,\n\t\theaders,\n\t\tname: node.type,\n\t\tversion: node.typeVersion,\n\t\tonUnauthorized: async (headers) => await tryRefreshOAuth2Token(this, authentication, headers),\n\t});\n\n\tif (!client.ok) {\n\t\tthrow mapToNodeOperationError(node, client.error);\n\t}\n\n\tconst tools = await getAllTools(client.result);\n\treturn tools.map((tool) => ({\n\t\tname: tool.name,\n\t\tvalue: tool.name,\n\t\tdescription: tool.description,\n\t\tinputSchema: tool.inputSchema,\n\t}));\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,mBAMO;AAEP,eAAsB,WAAuE;AAC5F,QAAM,iBAAiB,KAAK,iBAAiB,gBAAgB;AAC7D,QAAM,OAAO,KAAK,QAAQ;AAC1B,MAAI;AACJ,MAAI;AACJ,MAAI,KAAK,gBAAgB,GAAG;AAC3B,sBAAkB;AAClB,kBAAc,KAAK,iBAAiB,aAAa;AAAA,EAClD,OAAO;AACN,sBAAkB,KAAK,iBAAiB,iBAAiB;AACzD,kBAAc,KAAK,iBAAiB,aAAa;AAAA,EAClD;AACA,QAAM,EAAE,QAAQ,IAAI,UAAM,6BAAe,MAAM,cAAc;AAC7D,QAAM,SAAS,UAAM,+BAAiB;AAAA,IACrC;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM,KAAK;AAAA,IACX,SAAS,KAAK;AAAA,IACd,gBAAgB,OAAOA,aAAY,UAAM,oCAAsB,MAAM,gBAAgBA,QAAO;AAAA,EAC7F,CAAC;AAED,MAAI,CAAC,OAAO,IAAI;AACf,cAAM,sCAAwB,MAAM,OAAO,KAAK;AAAA,EACjD;AAEA,QAAM,QAAQ,UAAM,0BAAY,OAAO,MAAM;AAC7C,SAAO,MAAM,IAAI,CAAC,UAAU;AAAA,IAC3B,MAAM,KAAK;AAAA,IACX,OAAO,KAAK;AAAA,IACZ,aAAa,KAAK;AAAA,IAClB,aAAa,KAAK;AAAA,EACnB,EAAE;AACH;","names":["headers"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../nodes/McpClientTool/types.ts"],"sourcesContent":["export type McpToolIncludeMode = 'all' | 'selected' | 'except';\n"],"mappings":";;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../nodes/McpClientTool/utils.ts"],"sourcesContent":["import { DynamicStructuredTool, type DynamicStructuredToolInput } from '@langchain/core/tools';\nimport type { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport { CompatibilityCallToolResultSchema } from '@modelcontextprotocol/sdk/types.js';\nimport { Toolkit } from '@langchain/classic/agents';\nimport { type IDataObject } from 'n8n-workflow';\nimport { z } from 'zod';\n\nimport { convertJsonSchemaToZod } from '../shared/schemaParsing';\n\nimport type { McpToolIncludeMode } from './types';\nimport type { McpTool } from '../shared/types';\n\nexport function getSelectedTools({\n\tmode,\n\tincludeTools,\n\texcludeTools,\n\ttools,\n}: {\n\tmode: McpToolIncludeMode;\n\tincludeTools?: string[];\n\texcludeTools?: string[];\n\ttools: McpTool[];\n}) {\n\tswitch (mode) {\n\t\tcase 'selected': {\n\t\t\tif (!includeTools?.length) return tools;\n\t\t\tconst include = new Set(includeTools);\n\t\t\treturn tools.filter((tool) => include.has(tool.name));\n\t\t}\n\t\tcase 'except': {\n\t\t\tconst except = new Set(excludeTools ?? []);\n\t\t\treturn tools.filter((tool) => !except.has(tool.name));\n\t\t}\n\t\tcase 'all':\n\t\tdefault:\n\t\t\treturn tools;\n\t}\n}\n\nexport const getErrorDescriptionFromToolCall = (result: unknown): string | undefined => {\n\tif (result && typeof result === 'object') {\n\t\tif ('content' in result && Array.isArray(result.content)) {\n\t\t\tconst errorMessage = (result.content as Array<{ type: 'text'; text: string }>).find(\n\t\t\t\t(content) => content && typeof content === 'object' && typeof content.text === 'string',\n\t\t\t)?.text;\n\t\t\treturn errorMessage;\n\t\t} else if ('toolResult' in result && typeof result.toolResult === 'string') {\n\t\t\treturn result.toolResult;\n\t\t}\n\t\tif ('message' in result && typeof result.message === 'string') {\n\t\t\treturn result.message;\n\t\t}\n\t}\n\n\treturn undefined;\n};\n\nexport const createCallTool =\n\t(name: string, client: Client, timeout: number, onError: (error: string) => void) =>\n\tasync (args: IDataObject) => {\n\t\tlet result: Awaited<ReturnType<Client['callTool']>>;\n\n\t\tfunction handleError(error: unknown) {\n\t\t\tconst errorDescription =\n\t\t\t\tgetErrorDescriptionFromToolCall(error) ?? `Failed to execute tool \"${name}\"`;\n\t\t\tonError(errorDescription);\n\t\t\treturn errorDescription;\n\t\t}\n\n\t\ttry {\n\t\t\tresult = await client.callTool({ name, arguments: args }, CompatibilityCallToolResultSchema, {\n\t\t\t\ttimeout,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\treturn handleError(error);\n\t\t}\n\n\t\tif (result.isError) {\n\t\t\treturn handleError(result);\n\t\t}\n\n\t\tif (result.toolResult !== undefined) {\n\t\t\treturn result.toolResult;\n\t\t}\n\n\t\tif (result.content !== undefined) {\n\t\t\treturn result.content;\n\t\t}\n\n\t\treturn result;\n\t};\n\nexport function mcpToolToDynamicTool(\n\ttool: McpTool,\n\tonCallTool: DynamicStructuredToolInput['func'],\n): DynamicStructuredTool {\n\tconst rawSchema = convertJsonSchemaToZod(tool.inputSchema);\n\n\t// Ensure we always have an object schema for structured tools\n\tconst objectSchema =\n\t\trawSchema instanceof z.ZodObject ? rawSchema : z.object({ value: rawSchema });\n\n\treturn new DynamicStructuredTool({\n\t\tname: tool.name,\n\t\tdescription: tool.description ?? '',\n\t\tschema: objectSchema,\n\t\tfunc: onCallTool,\n\t\tmetadata: { isFromToolkit: true },\n\t});\n}\n\nexport class McpToolkit extends Toolkit {\n\tconstructor(public tools: DynamicStructuredTool[]) {\n\t\tsuper();\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAuE;AAEvE,mBAAkD;AAClD,oBAAwB;AAExB,iBAAkB;AAElB,2BAAuC;AAKhC,SAAS,iBAAiB;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,GAKG;AACF,UAAQ,MAAM;AAAA,IACb,KAAK,YAAY;AAChB,UAAI,CAAC,cAAc,OAAQ,QAAO;AAClC,YAAM,UAAU,IAAI,IAAI,YAAY;AACpC,aAAO,MAAM,OAAO,CAAC,SAAS,QAAQ,IAAI,KAAK,IAAI,CAAC;AAAA,IACrD;AAAA,IACA,KAAK,UAAU;AACd,YAAM,SAAS,IAAI,IAAI,gBAAgB,CAAC,CAAC;AACzC,aAAO,MAAM,OAAO,CAAC,SAAS,CAAC,OAAO,IAAI,KAAK,IAAI,CAAC;AAAA,IACrD;AAAA,IACA,KAAK;AAAA,IACL;AACC,aAAO;AAAA,EACT;AACD;AAEO,MAAM,kCAAkC,CAAC,WAAwC;AACvF,MAAI,UAAU,OAAO,WAAW,UAAU;AACzC,QAAI,aAAa,UAAU,MAAM,QAAQ,OAAO,OAAO,GAAG;AACzD,YAAM,eAAgB,OAAO,QAAkD;AAAA,QAC9E,CAAC,YAAY,WAAW,OAAO,YAAY,YAAY,OAAO,QAAQ,SAAS;AAAA,MAChF,GAAG;AACH,aAAO;AAAA,IACR,WAAW,gBAAgB,UAAU,OAAO,OAAO,eAAe,UAAU;AAC3E,aAAO,OAAO;AAAA,IACf;AACA,QAAI,aAAa,UAAU,OAAO,OAAO,YAAY,UAAU;AAC9D,aAAO,OAAO;AAAA,IACf;AAAA,EACD;AAEA,SAAO;AACR;AAEO,MAAM,iBACZ,CAAC,MAAc,QAAgB,SAAiB,YAChD,OAAO,SAAsB;AAC5B,MAAI;AAEJ,WAAS,YAAY,OAAgB;AACpC,UAAM,mBACL,gCAAgC,KAAK,KAAK,2BAA2B,IAAI;AAC1E,YAAQ,gBAAgB;AACxB,WAAO;AAAA,EACR;AAEA,MAAI;AACH,aAAS,MAAM,OAAO,SAAS,EAAE,MAAM,WAAW,KAAK,GAAG,gDAAmC;AAAA,MAC5F;AAAA,IACD,CAAC;AAAA,EACF,SAAS,OAAO;AACf,WAAO,YAAY,KAAK;AAAA,EACzB;AAEA,MAAI,OAAO,SAAS;AACnB,WAAO,YAAY,MAAM;AAAA,EAC1B;AAEA,MAAI,OAAO,eAAe,QAAW;AACpC,WAAO,OAAO;AAAA,EACf;AAEA,MAAI,OAAO,YAAY,QAAW;AACjC,WAAO,OAAO;AAAA,EACf;AAEA,SAAO;AACR;AAEM,SAAS,qBACf,MACA,YACwB;AACxB,QAAM,gBAAY,6CAAuB,KAAK,WAAW;AAGzD,QAAM,eACL,qBAAqB,aAAE,YAAY,YAAY,aAAE,OAAO,EAAE,OAAO,UAAU,CAAC;AAE7E,SAAO,IAAI,mCAAsB;AAAA,IAChC,MAAM,KAAK;AAAA,IACX,aAAa,KAAK,eAAe;AAAA,IACjC,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,UAAU,EAAE,eAAe,KAAK;AAAA,EACjC,CAAC;AACF;AAEO,MAAM,mBAAmB,sBAAQ;AAAA,EACvC,YAAmB,OAAgC;AAClD,UAAM;AADY;AAAA,EAEnB;AACD;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../nodes/McpTrigger/FlushingTransport.ts"],"sourcesContent":["import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';\nimport type { StreamableHTTPServerTransportOptions } from '@modelcontextprotocol/sdk/server/streamableHttp.js';\nimport type { JSONRPCMessage } from '@modelcontextprotocol/sdk/types.js';\nimport type { Response } from 'express';\nimport type { IncomingMessage, ServerResponse } from 'http';\n\nexport type CompressionResponse = Response & {\n\t/**\n\t * `flush()` is defined in the compression middleware.\n\t * This is necessary because the compression middleware sometimes waits\n\t * for a certain amount of data before sending the data to the client\n\t */\n\tflush: () => void;\n};\n\nexport class FlushingSSEServerTransport extends SSEServerTransport {\n\tconstructor(\n\t\t_endpoint: string,\n\t\tprivate response: CompressionResponse,\n\t) {\n\t\tsuper(_endpoint, response);\n\t}\n\n\tasync send(message: JSONRPCMessage): Promise<void> {\n\t\tawait super.send(message);\n\t\tthis.response.flush();\n\t}\n\n\tasync handleRequest(\n\t\treq: IncomingMessage,\n\t\tresp: ServerResponse,\n\t\tmessage: IncomingMessage,\n\t): Promise<void> {\n\t\tawait super.handlePostMessage(req, resp, message);\n\t\tthis.response.flush();\n\t}\n}\n\nexport class FlushingStreamableHTTPTransport extends StreamableHTTPServerTransport {\n\tprivate response: CompressionResponse;\n\n\tconstructor(options: StreamableHTTPServerTransportOptions, response: CompressionResponse) {\n\t\tsuper(options);\n\t\tthis.response = response;\n\t}\n\n\tasync send(message: JSONRPCMessage): Promise<void> {\n\t\tawait super.send(message);\n\t\tthis.response.flush();\n\t}\n\n\tasync handleRequest(\n\t\treq: IncomingMessage,\n\t\tresp: ServerResponse,\n\t\tparsedBody?: unknown,\n\t): Promise<void> {\n\t\tawait super.handleRequest(req, resp, parsedBody);\n\t\tthis.response.flush();\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAAmC;AACnC,4BAA8C;AAevC,MAAM,mCAAmC,8BAAmB;AAAA,EAClE,YACC,WACQ,UACP;AACD,UAAM,WAAW,QAAQ;AAFjB;AAAA,EAGT;AAAA,EAEA,MAAM,KAAK,SAAwC;AAClD,UAAM,MAAM,KAAK,OAAO;AACxB,SAAK,SAAS,MAAM;AAAA,EACrB;AAAA,EAEA,MAAM,cACL,KACA,MACA,SACgB;AAChB,UAAM,MAAM,kBAAkB,KAAK,MAAM,OAAO;AAChD,SAAK,SAAS,MAAM;AAAA,EACrB;AACD;AAEO,MAAM,wCAAwC,oDAA8B;AAAA,EAC1E;AAAA,EAER,YAAY,SAA+C,UAA+B;AACzF,UAAM,OAAO;AACb,SAAK,WAAW;AAAA,EACjB;AAAA,EAEA,MAAM,KAAK,SAAwC;AAClD,UAAM,MAAM,KAAK,OAAO;AACxB,SAAK,SAAS,MAAM;AAAA,EACrB;AAAA,EAEA,MAAM,cACL,KACA,MACA,YACgB;AAChB,UAAM,MAAM,cAAc,KAAK,MAAM,UAAU;AAC/C,SAAK,SAAS,MAAM;AAAA,EACrB;AACD;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../nodes/McpTrigger/McpServer.ts"],"sourcesContent":["import type { Tool } from '@langchain/core/tools';\nimport { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport type { RequestHandlerExtra } from '@modelcontextprotocol/sdk/shared/protocol.js';\nimport type {\n\tJSONRPCMessage,\n\tServerRequest,\n\tServerNotification,\n} from '@modelcontextprotocol/sdk/types.js';\nimport {\n\tJSONRPCMessageSchema,\n\tListToolsRequestSchema,\n\tCallToolRequestSchema,\n} from '@modelcontextprotocol/sdk/types.js';\nimport { randomUUID } from 'crypto';\nimport type * as express from 'express';\nimport type { IncomingMessage } from 'http';\nimport { jsonParse, OperationalError, type Logger } from 'n8n-workflow';\nimport { zodToJsonSchema } from 'zod-to-json-schema';\n\nimport { FlushingSSEServerTransport, FlushingStreamableHTTPTransport } from './FlushingTransport';\nimport type { CompressionResponse } from './FlushingTransport';\n\n/**\n * Parses the JSONRPC message and checks whether the method used was a tool\n * call. This is necessary in order to not have executions for listing tools\n * and other commands sent by the MCP client\n */\nfunction wasToolCall(body: string) {\n\ttry {\n\t\tconst message: unknown = JSON.parse(body);\n\t\tconst parsedMessage: JSONRPCMessage = JSONRPCMessageSchema.parse(message);\n\t\treturn (\n\t\t\t'method' in parsedMessage &&\n\t\t\t'id' in parsedMessage &&\n\t\t\tparsedMessage?.method === CallToolRequestSchema.shape.method.value\n\t\t);\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Extracts the request ID from a JSONRPC message (for example for tool calls).\n * Returns undefined if the message doesn't have an ID (for example on a tool list request)\n *\n */\nfunction getRequestId(message: unknown): string | undefined {\n\ttry {\n\t\tconst parsedMessage: JSONRPCMessage = JSONRPCMessageSchema.parse(message);\n\t\treturn 'id' in parsedMessage ? String(parsedMessage.id) : undefined;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/**\n * This singleton is shared across the instance, making sure it is the one\n * keeping account of MCP servers.\n * It needs to stay in memory to keep track of the long-lived connections.\n * It requires a logger at first creation to set everything up.\n */\nexport class McpServerManager {\n\tstatic #instance: McpServerManager;\n\n\tservers: { [sessionId: string]: Server } = {};\n\n\ttransports: {\n\t\t[sessionId: string]: FlushingSSEServerTransport | FlushingStreamableHTTPTransport;\n\t} = {};\n\n\tprivate tools: { [sessionId: string]: Tool[] } = {};\n\n\tprivate resolveFunctions: { [callId: string]: CallableFunction } = {};\n\n\tlogger: Logger;\n\n\tprivate constructor(logger: Logger) {\n\t\tthis.logger = logger;\n\t\tthis.logger.debug('MCP Server created');\n\t}\n\n\tstatic instance(logger: Logger): McpServerManager {\n\t\tif (!McpServerManager.#instance) {\n\t\t\tMcpServerManager.#instance = new McpServerManager(logger);\n\t\t\tlogger.debug('Created singleton MCP manager');\n\t\t}\n\n\t\treturn McpServerManager.#instance;\n\t}\n\n\tasync createServerWithSSETransport(\n\t\tserverName: string,\n\t\tpostUrl: string,\n\t\tresp: CompressionResponse,\n\t): Promise<void> {\n\t\tconst server = new Server(\n\t\t\t{\n\t\t\t\tname: serverName,\n\t\t\t\tversion: '0.1.0',\n\t\t\t},\n\t\t\t{\n\t\t\t\tcapabilities: {\n\t\t\t\t\ttools: {},\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\n\t\tconst transport = new FlushingSSEServerTransport(postUrl, resp);\n\n\t\tthis.setUpHandlers(server);\n\n\t\tconst sessionId = transport.sessionId;\n\t\tthis.transports[sessionId] = transport;\n\t\tthis.servers[sessionId] = server;\n\n\t\tresp.on('close', async () => {\n\t\t\tthis.logger.debug(`Deleting transport for ${sessionId}`);\n\t\t\tdelete this.tools[sessionId];\n\t\t\tdelete this.transports[sessionId];\n\t\t\tdelete this.servers[sessionId];\n\t\t});\n\t\tawait server.connect(transport);\n\n\t\t// Make sure we flush the compression middleware, so that it's not waiting for more content to be added to the buffer\n\t\tif (resp.flush) {\n\t\t\tresp.flush();\n\t\t}\n\t}\n\n\tgetSessionId(req: express.Request): string | undefined {\n\t\t// Session ID can be passed either as a query parameter (SSE transport)\n\t\t// or in the header (StreamableHTTP transport).\n\t\treturn (req.query.sessionId ?? req.headers['mcp-session-id']) as string | undefined;\n\t}\n\n\tgetTransport(\n\t\tsessionId: string,\n\t): FlushingSSEServerTransport | FlushingStreamableHTTPTransport | undefined {\n\t\treturn this.transports[sessionId];\n\t}\n\n\tasync createServerWithStreamableHTTPTransport(\n\t\tserverName: string,\n\t\tresp: CompressionResponse,\n\t\treq?: express.Request,\n\t): Promise<void> {\n\t\tconst server = new Server(\n\t\t\t{\n\t\t\t\tname: serverName,\n\t\t\t\tversion: '0.1.0',\n\t\t\t},\n\t\t\t{\n\t\t\t\tcapabilities: {\n\t\t\t\t\ttools: {},\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\n\t\tconst transport = new FlushingStreamableHTTPTransport(\n\t\t\t{\n\t\t\t\tsessionIdGenerator: () => randomUUID(),\n\t\t\t\tonsessioninitialized: (sessionId) => {\n\t\t\t\t\tthis.logger.debug(`New session initialized: ${sessionId}`);\n\t\t\t\t\ttransport.onclose = () => {\n\t\t\t\t\t\tthis.logger.debug(`Deleting transport for ${sessionId}`);\n\t\t\t\t\t\tdelete this.tools[sessionId];\n\t\t\t\t\t\tdelete this.transports[sessionId];\n\t\t\t\t\t\tdelete this.servers[sessionId];\n\t\t\t\t\t};\n\t\t\t\t\tthis.transports[sessionId] = transport;\n\t\t\t\t\tthis.servers[sessionId] = server;\n\t\t\t\t},\n\t\t\t},\n\t\t\tresp,\n\t\t);\n\n\t\tthis.setUpHandlers(server);\n\n\t\tawait server.connect(transport);\n\n\t\tawait transport.handleRequest(req as IncomingMessage, resp, req?.body);\n\t\tif (resp.flush) {\n\t\t\tresp.flush();\n\t\t}\n\t}\n\n\tasync handlePostMessage(req: express.Request, resp: CompressionResponse, connectedTools: Tool[]) {\n\t\t// Session ID can be passed either as a query parameter (SSE transport)\n\t\t// or in the header (StreamableHTTP transport).\n\t\tconst sessionId = this.getSessionId(req);\n\t\tconst transport = this.getTransport(sessionId as string);\n\t\tif (sessionId && transport) {\n\t\t\t// We need to add a promise here because the `handlePostMessage` will send something to the\n\t\t\t// MCP Server, that will run in a different context. This means that the return will happen\n\t\t\t// almost immediately, and will lead to marking the sub-node as \"running\" in the final execution\n\t\t\tconst message = jsonParse(req.rawBody.toString());\n\t\t\tconst messageId = getRequestId(message);\n\t\t\t// Use session & message ID if available, otherwise fall back to sessionId\n\t\t\tconst callId = messageId ? `${sessionId}_${messageId}` : sessionId;\n\t\t\tthis.tools[sessionId] = connectedTools;\n\n\t\t\ttry {\n\t\t\t\tawait new Promise(async (resolve) => {\n\t\t\t\t\tthis.resolveFunctions[callId] = resolve;\n\t\t\t\t\tawait transport.handleRequest(req, resp, message as IncomingMessage);\n\t\t\t\t});\n\t\t\t} finally {\n\t\t\t\tdelete this.resolveFunctions[callId];\n\t\t\t}\n\t\t} else {\n\t\t\tthis.logger.warn(`No transport found for session ${sessionId}`);\n\t\t\tresp.status(401).send('No transport found for sessionId');\n\t\t}\n\n\t\tif (resp.flush) {\n\t\t\tresp.flush();\n\t\t}\n\n\t\treturn wasToolCall(req.rawBody.toString());\n\t}\n\n\tasync handleDeleteRequest(req: express.Request, resp: CompressionResponse) {\n\t\tconst sessionId = this.getSessionId(req);\n\n\t\tif (!sessionId) {\n\t\t\tresp.status(400).send('No sessionId provided');\n\t\t\treturn;\n\t\t}\n\n\t\tconst transport = this.getTransport(sessionId);\n\n\t\tif (transport) {\n\t\t\tif (transport instanceof FlushingStreamableHTTPTransport) {\n\t\t\t\tawait transport.handleRequest(req, resp);\n\t\t\t\treturn;\n\t\t\t} else {\n\t\t\t\t// For SSE transport, we don't support DELETE requests\n\t\t\t\tresp.status(405).send('Method Not Allowed');\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tresp.status(404).send('Session not found');\n\t}\n\n\tsetUpHandlers(server: Server) {\n\t\tserver.setRequestHandler(\n\t\t\tListToolsRequestSchema,\n\t\t\tasync (_, extra: RequestHandlerExtra<ServerRequest, ServerNotification>) => {\n\t\t\t\tif (!extra.sessionId) {\n\t\t\t\t\tthrow new OperationalError('Require a sessionId for the listing of tools');\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\ttools: this.tools[extra.sessionId].map((tool) => {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tname: tool.name,\n\t\t\t\t\t\t\tdescription: tool.description,\n\t\t\t\t\t\t\t// Allow additional properties on tool call input\n\t\t\t\t\t\t\tinputSchema: zodToJsonSchema(tool.schema, { removeAdditionalStrategy: 'strict' }),\n\t\t\t\t\t\t};\n\t\t\t\t\t}),\n\t\t\t\t};\n\t\t\t},\n\t\t);\n\n\t\tserver.setRequestHandler(\n\t\t\tCallToolRequestSchema,\n\t\t\tasync (request, extra: RequestHandlerExtra<ServerRequest, ServerNotification>) => {\n\t\t\t\tif (!request.params?.name || !request.params?.arguments) {\n\t\t\t\t\tthrow new OperationalError('Require a name and arguments for the tool call');\n\t\t\t\t}\n\t\t\t\tif (!extra.sessionId) {\n\t\t\t\t\tthrow new OperationalError('Require a sessionId for the tool call');\n\t\t\t\t}\n\n\t\t\t\tconst callId = extra.requestId ? `${extra.sessionId}_${extra.requestId}` : extra.sessionId;\n\n\t\t\t\tconst requestedTool: Tool | undefined = this.tools[extra.sessionId].find(\n\t\t\t\t\t(tool) => tool.name === request.params.name,\n\t\t\t\t);\n\t\t\t\tif (!requestedTool) {\n\t\t\t\t\tthrow new OperationalError('Tool not found');\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\tconst result = await requestedTool.invoke(request.params.arguments);\n\t\t\t\t\tif (this.resolveFunctions[callId]) {\n\t\t\t\t\t\tthis.resolveFunctions[callId]();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.logger.warn(`No resolve function found for ${callId}`);\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.logger.debug(`Got request for ${requestedTool.name}, and executed it.`);\n\n\t\t\t\t\tif (typeof result === 'object') {\n\t\t\t\t\t\treturn { content: [{ type: 'text', text: JSON.stringify(result) }] };\n\t\t\t\t\t}\n\t\t\t\t\tif (typeof result === 'string') {\n\t\t\t\t\t\treturn { content: [{ type: 'text', text: result }] };\n\t\t\t\t\t}\n\t\t\t\t\treturn { content: [{ type: 'text', text: String(result) }] };\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthis.logger.error(`Error while executing Tool ${requestedTool.name}: ${error}`);\n\t\t\t\t\treturn { isError: true, content: [{ type: 'text', text: `Error: ${error.message}` }] };\n\t\t\t\t}\n\t\t\t},\n\t\t);\n\n\t\tserver.onclose = () => {\n\t\t\tthis.logger.debug('Closing MCP Server');\n\t\t};\n\t\tserver.onerror = (error: unknown) => {\n\t\t\tthis.logger.error(`MCP Error: ${error}`);\n\t\t};\n\t}\n}\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../nodes/McpTrigger/McpTrigger.node.ts"],"sourcesContent":["import { WebhookAuthorizationError } from 'n8n-nodes-base/dist/nodes/Webhook/error';\nimport { validateWebhookAuthentication } from 'n8n-nodes-base/dist/nodes/Webhook/utils';\nimport type { INodeTypeDescription, IWebhookFunctions, IWebhookResponseData } from 'n8n-workflow';\nimport { NodeConnectionTypes, Node, nodeNameToToolName } from 'n8n-workflow';\n\nimport { getConnectedTools } from '../shared/helpers';\n\nimport type { CompressionResponse } from './FlushingTransport';\nimport { McpServerManager } from './McpServer';\n\nconst MCP_SSE_SETUP_PATH = 'sse';\nconst MCP_SSE_MESSAGES_PATH = 'messages';\n\nexport class McpTrigger extends Node {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'MCP Server Trigger',\n\t\tname: 'mcpTrigger',\n\t\ticon: {\n\t\t\tlight: 'file:../mcp.svg',\n\t\t\tdark: 'file:../mcp.dark.svg',\n\t\t},\n\t\tgroup: ['trigger'],\n\t\tversion: [1, 1.1, 2],\n\t\tdescription: 'Expose n8n tools as an MCP Server endpoint',\n\t\tactivationMessage:\n\t\t\t'You can now connect your MCP Clients to the URL, using SSE or Streamable HTTP transports.',\n\t\tdefaults: {\n\t\t\tname: 'MCP Server Trigger',\n\t\t},\n\t\tcodex: {\n\t\t\tcategories: ['AI', 'Core Nodes'],\n\t\t\tsubcategories: {\n\t\t\t\tAI: ['Root Nodes', 'Model Context Protocol'],\n\t\t\t\t'Core Nodes': ['Other Trigger Nodes'],\n\t\t\t},\n\t\t\talias: ['Model Context Protocol', 'MCP Server'],\n\t\t\tresources: {\n\t\t\t\tprimaryDocumentation: [\n\t\t\t\t\t{\n\t\t\t\t\t\turl: 'https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-langchain.mcptrigger/',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t\ttriggerPanel: {\n\t\t\theader: 'Listen for MCP events',\n\t\t\texecutionsHelp: {\n\t\t\t\tinactive:\n\t\t\t\t\t\"This trigger has two modes: test and production.<br /><br /><b>Use test mode while you build your workflow</b>. Click the 'execute step' button, then make an MCP request to the test URL. The executions will show up in the editor.<br /><br /><b>Use production mode to run your workflow automatically</b>. Publish the workflow, then make requests to the production URL. These executions will show up in the <a data-key='executions'>executions list</a>, but not the editor.\",\n\t\t\t\tactive:\n\t\t\t\t\t\"This trigger has two modes: test and production.<br /><br /><b>Use test mode while you build your workflow</b>. Click the 'execute step' button, then make an MCP request to the test URL. The executions will show up in the editor.<br /><br /><b>Use production mode to run your workflow automatically</b>. Since your workflow is activated, you can make requests to the production URL. These executions will show up in the <a data-key='executions'>executions list</a>, but not the editor.\",\n\t\t\t},\n\t\t\tactivationHint:\n\t\t\t\t'Once you’ve finished building your workflow, run it without having to click this button by using the production URL.',\n\t\t},\n\t\tinputs: [\n\t\t\t{\n\t\t\t\ttype: NodeConnectionTypes.AiTool,\n\t\t\t\tdisplayName: 'Tools',\n\t\t\t},\n\t\t],\n\t\toutputs: [],\n\t\tcredentials: [\n\t\t\t{\n\t\t\t\t// eslint-disable-next-line n8n-nodes-base/node-class-description-credentials-name-unsuffixed\n\t\t\t\tname: 'httpBearerAuth',\n\t\t\t\trequired: true,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tauthentication: ['bearerAuth'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'httpHeaderAuth',\n\t\t\t\trequired: true,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tauthentication: ['headerAuth'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t\tproperties: [\n\t\t\t{\n\t\t\t\tdisplayName: 'Authentication',\n\t\t\t\tname: 'authentication',\n\t\t\t\ttype: 'options',\n\t\t\t\toptions: [\n\t\t\t\t\t{ name: 'None', value: 'none' },\n\t\t\t\t\t{ name: 'Bearer Auth', value: 'bearerAuth' },\n\t\t\t\t\t{ name: 'Header Auth', value: 'headerAuth' },\n\t\t\t\t],\n\t\t\t\tdefault: 'none',\n\t\t\t\tdescription: 'The way to authenticate',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Path',\n\t\t\t\tname: 'path',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '',\n\t\t\t\tplaceholder: 'webhook',\n\t\t\t\trequired: true,\n\t\t\t\tdescription: 'The base path for this MCP server',\n\t\t\t},\n\t\t],\n\t\twebhooks: [\n\t\t\t{\n\t\t\t\tname: 'setup',\n\t\t\t\thttpMethod: 'GET',\n\t\t\t\tresponseMode: 'onReceived',\n\t\t\t\tisFullPath: true,\n\t\t\t\tpath: `={{$parameter[\"path\"]}}{{parseFloat($nodeVersion)<2 ? '/${MCP_SSE_SETUP_PATH}' : ''}}`,\n\t\t\t\tnodeType: 'mcp',\n\t\t\t\tndvHideMethod: true,\n\t\t\t\tndvHideUrl: false,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'default',\n\t\t\t\thttpMethod: 'POST',\n\t\t\t\tresponseMode: 'onReceived',\n\t\t\t\tisFullPath: true,\n\t\t\t\tpath: `={{$parameter[\"path\"]}}{{parseFloat($nodeVersion)<2 ? '/${MCP_SSE_MESSAGES_PATH}' : ''}}`,\n\t\t\t\tnodeType: 'mcp',\n\t\t\t\tndvHideMethod: true,\n\t\t\t\tndvHideUrl: true,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'default',\n\t\t\t\thttpMethod: 'DELETE',\n\t\t\t\tresponseMode: 'onReceived',\n\t\t\t\tisFullPath: true,\n\t\t\t\tpath: '={{$parameter[\"path\"]}}',\n\t\t\t\tnodeType: 'mcp',\n\t\t\t\tndvHideMethod: true,\n\t\t\t\tndvHideUrl: true,\n\t\t\t},\n\t\t],\n\t};\n\n\tasync webhook(context: IWebhookFunctions): Promise<IWebhookResponseData> {\n\t\tconst webhookName = context.getWebhookName();\n\t\tconst req = context.getRequestObject();\n\t\tconst resp = context.getResponseObject() as unknown as CompressionResponse;\n\n\t\ttry {\n\t\t\tawait validateWebhookAuthentication(context, 'authentication');\n\t\t} catch (error) {\n\t\t\tif (error instanceof WebhookAuthorizationError) {\n\t\t\t\tresp.writeHead(error.responseCode);\n\t\t\t\tresp.end(error.message);\n\t\t\t\treturn { noWebhookResponse: true };\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t\tconst node = context.getNode();\n\t\t// Get a url/tool friendly name for the server, based on the node name\n\t\tconst serverName = node.typeVersion > 1 ? nodeNameToToolName(node) : 'n8n-mcp-server';\n\n\t\tconst mcpServerManager: McpServerManager = McpServerManager.instance(context.logger);\n\n\t\tif (webhookName === 'setup') {\n\t\t\t// Sets up the transport and opens the long-lived connection. This resp\n\t\t\t// will stay streaming, and is the channel that sends the events\n\n\t\t\t// Prior to version 2.0, we use different paths for the setup and messages.\n\t\t\tconst postUrl =\n\t\t\t\tnode.typeVersion < 2\n\t\t\t\t\t? req.path.replace(new RegExp(`/${MCP_SSE_SETUP_PATH}$`), `/${MCP_SSE_MESSAGES_PATH}`)\n\t\t\t\t\t: req.path;\n\t\t\tawait mcpServerManager.createServerWithSSETransport(serverName, postUrl, resp);\n\n\t\t\treturn { noWebhookResponse: true };\n\t\t} else if (webhookName === 'default') {\n\t\t\t// Here we handle POST and DELETE requests.\n\t\t\t// POST can be either:\n\t\t\t// 1) Client calls in an established session using the SSE transport, or\n\t\t\t// 2) Client calls in an established session using the StreamableHTTPServerTransport\n\t\t\t// 3) Session setup requests using the StreamableHTTPServerTransport\n\t\t\t// DELETE is used to terminate the session using the StreamableHTTPServerTransport\n\n\t\t\tif (req.method === 'DELETE') {\n\t\t\t\tawait mcpServerManager.handleDeleteRequest(req, resp);\n\t\t\t} else {\n\t\t\t\t// Check if there is a session and a transport is already established\n\t\t\t\tconst sessionId = mcpServerManager.getSessionId(req);\n\n\t\t\t\tif (sessionId && mcpServerManager.getTransport(sessionId)) {\n\t\t\t\t\tconst connectedTools = await getConnectedTools(context, true);\n\t\t\t\t\tconst wasToolCall = await mcpServerManager.handlePostMessage(req, resp, connectedTools);\n\t\t\t\t\tif (wasToolCall) return { noWebhookResponse: true, workflowData: [[{ json: {} }]] };\n\t\t\t\t} else {\n\t\t\t\t\t// If no session is established, this is a setup request\n\t\t\t\t\t// for the StreamableHTTPServerTransport, so we create a new transport\n\t\t\t\t\tawait mcpServerManager.createServerWithStreamableHTTPTransport(serverName, resp, req);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn { noWebhookResponse: true };\n\t\t}\n\n\t\treturn { workflowData: [[{ json: {} }]] };\n\t}\n}\n"],"mappings":"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","names":[]}
File without changes
File without changes
File without changes
File without changes
File without changes