n8n-nodes-browser-smart-automation 0.1.6 → 0.1.9

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.
@@ -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:../assets/mcp.light.svg",
47
+ light: "file:../assets/mcp.svg",
48
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],
@@ -1 +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 Client',\n\t\tdescription: 'Standalone MCP Client',\n\t\tname: 'mcpClient',\n\t\ticon: {\n\t\t\tlight: 'file:../assets/mcp.light.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 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
+ {"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"]}
@@ -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
  {
@@ -369,7 +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
  }
372
- await client.callTool({ name: "browser_connect_cdp", arguments: { endpoint: config.cdp_endpointurl } }, import_types.CallToolResultSchema, { timeout: config.timeout });
374
+ const result = await client.callTool(
375
+ {
376
+ name: "browser_cdp_connect",
377
+ arguments: { "endpoint": config.cdp_endpointurl }
378
+ },
379
+ void 0,
380
+ {
381
+ timeout: config.timeout ? Number(config.timeout) : void 0
382
+ }
383
+ );
373
384
  for (const tool of mcpTools) {
374
385
  if (!item.json.tool || typeof item.json.tool !== "string") {
375
386
  throw new import_n8n_workflow.NodeOperationError(node, "Tool name not found in item.json.tool or item.tool", {
@@ -383,12 +394,12 @@ class McpClientTool {
383
394
  name: tool.name,
384
395
  arguments: toolArguments
385
396
  };
386
- const result = await client.callTool(params, import_types.CallToolResultSchema, {
397
+ const result2 = await client.callTool(params, import_types.CallToolResultSchema, {
387
398
  timeout: config.timeout
388
399
  });
389
400
  returnData.push({
390
401
  json: {
391
- response: result.content || result
402
+ response: result2.content || result2
392
403
  },
393
404
  pairedItem: {
394
405
  item: itemIndex
@@ -1 +1 @@
1
- {"version":3,"sources":["../../nodes/McpClientToolEX/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 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\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\t\t\tawait client.callTool({name:\"browser_connect_cdp\",arguments:{endpoint:config.cdp_endpointurl}},CallToolResultSchema,{timeout:config.timeout});\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
+ {"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: { \"endpoint\": 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"]}
@@ -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
  {
@@ -1 +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 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":[]}
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":[]}
@@ -0,0 +1,7 @@
1
+ <svg width="180" height="180" viewBox="0 0 195 195" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <g stroke="#000" stroke-width="12" stroke-linecap="round">
3
+ <path d="M25 97.8528L92.8823 29.9706C102.255 20.598 117.451 20.598 126.823 29.9706V29.9706C136.196 39.3431 136.196 54.5391 126.823 63.9117L75.5581 115.177"/>
4
+ <path d="M76.2653 114.47L126.823 63.9117C136.196 54.5391 151.392 54.5391 160.765 63.9117L161.118 64.2652C170.491 73.6378 170.491 88.8338 161.118 98.2063L99.7248 159.6C96.6006 162.724 96.6006 167.789 99.7248 170.913L112.331 183.52"/>
5
+ <path d="M109.853 46.9411L59.6482 97.1457C50.2757 106.518 50.2757 121.714 59.6482 131.087V131.087C69.0208 140.459 84.2168 140.459 93.5894 131.087L143.794 80.8822"/>
6
+ </g>
7
+ </svg>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-browser-smart-automation",
3
- "version": "0.1.6",
3
+ "version": "0.1.9",
4
4
  "description": "n8n nodes for Smart Browser Automation via MCP",
5
5
  "keywords": [
6
6
  "n8n-community-node-package"
@@ -17,7 +17,7 @@
17
17
  },
18
18
  "files": [
19
19
  "dist",
20
- "nodes/assets/mcp.light.svg",
20
+ "nodes/assets/mcp.svg",
21
21
  "nodes/assets/mcp.dark.svg",
22
22
  "package.json",
23
23
  "README.md"