n8n-nodes-smart-browser-automation 1.0.6 → 1.1.2

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.
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const index_js_1 = require("@modelcontextprotocol/sdk/client/index.js");
4
4
  const stdio_js_1 = require("@modelcontextprotocol/sdk/client/stdio.js");
5
+ const sse_js_1 = require("@modelcontextprotocol/sdk/client/sse.js");
5
6
  class BrowserSessionManager {
6
7
  static instance;
7
8
  mcpClient = null;
@@ -29,21 +30,30 @@ class BrowserSessionManager {
29
30
  }
30
31
  // Initialize MCP client
31
32
  this.mcpClient = new index_js_1.Client({ name: 'n8n-browser-automation', version: '1.0.0' }, { capabilities: {} });
32
- // Connect to MCP server
33
- this.transport = new stdio_js_1.StdioClientTransport({
34
- command: 'node',
35
- args: [mcpEndpoint],
36
- env: {
37
- ...process.env,
38
- ...(useCDP && cdpEndpoint ? { CDP_URL: cdpEndpoint } : {})
39
- }
40
- });
33
+ // Determine transport based on endpoint type
34
+ const isUrl = mcpEndpoint.startsWith('http://') || mcpEndpoint.startsWith('https://');
35
+ if (isUrl) {
36
+ // Connect via SSE
37
+ this.transport = new sse_js_1.SSEClientTransport(new URL(mcpEndpoint));
38
+ }
39
+ else {
40
+ // Connect via Stdio
41
+ this.transport = new stdio_js_1.StdioClientTransport({
42
+ command: 'node',
43
+ args: [mcpEndpoint],
44
+ env: {
45
+ ...process.env,
46
+ ...(useCDP && cdpEndpoint ? { CDP_URL: cdpEndpoint } : {})
47
+ }
48
+ });
49
+ }
41
50
  try {
42
51
  await this.mcpClient.connect(this.transport);
43
52
  }
44
53
  catch (error) {
45
54
  this.isInitialized = false;
46
- throw new Error(`Failed to connect to MCP server at ${mcpEndpoint}. Ensure the path is correct and accessible within your n8n environment. Error: ${error.message}`);
55
+ const transportType = isUrl ? 'SSE' : 'Stdio';
56
+ throw new Error(`Failed to connect to MCP server via ${transportType} at ${mcpEndpoint}. Error: ${error.message}`);
47
57
  }
48
58
  // Fetch available tools from MCP server
49
59
  const toolsResponse = await this.mcpClient.listTools();
@@ -56,11 +66,20 @@ class BrowserSessionManager {
56
66
  if (!this.mcpClient || !this.isInitialized) {
57
67
  throw new Error('MCP client not initialized. Please configure credentials first.');
58
68
  }
59
- const result = await this.mcpClient.callTool({
60
- name: toolName,
61
- arguments: toolArgs || {}
62
- });
63
- return result;
69
+ try {
70
+ if (this.config.mcpEndpoint?.includes('http')) {
71
+ console.log(`Calling remote tool: ${toolName} on ${this.config.mcpEndpoint}`);
72
+ }
73
+ const result = await this.mcpClient.callTool({
74
+ name: toolName,
75
+ arguments: toolArgs || {}
76
+ });
77
+ return result;
78
+ }
79
+ catch (error) {
80
+ console.error(`MCP Tool Call Error (${toolName}):`, error);
81
+ throw new Error(`MCP Tool Error: ${error.message}${error.data ? ' - ' + JSON.stringify(error.data) : ''}`);
82
+ }
64
83
  }
65
84
  getTools() {
66
85
  return this.tools;
@@ -60,10 +60,24 @@ class SmartBrowserAutomation {
60
60
  mode: ['manual'],
61
61
  },
62
62
  },
63
- default: '',
64
- description: 'Select the browser automation tool to execute. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
63
+ default: 'browser_connect_cdp',
64
+ description: 'Select the browser automation tool to execute. Choose "Connect to Browser (CDP)" to initialize/switch browser sessions. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
65
65
  required: true,
66
66
  },
67
+ {
68
+ displayName: 'CDP Endpoint',
69
+ name: 'cdpUrl',
70
+ type: 'string',
71
+ displayOptions: {
72
+ show: {
73
+ mode: ['manual'],
74
+ toolName: ['browser_connect_cdp'],
75
+ },
76
+ },
77
+ default: '',
78
+ placeholder: 'wss://gridnew.doingerp.com/devtools/...',
79
+ description: 'The wss:// or http:// endpoint for the browser CDP connection',
80
+ },
67
81
  {
68
82
  displayName: 'Tool Arguments',
69
83
  name: 'toolArgs',
@@ -72,6 +86,9 @@ class SmartBrowserAutomation {
72
86
  show: {
73
87
  mode: ['manual'],
74
88
  },
89
+ hide: {
90
+ toolName: ['browser_connect_cdp'],
91
+ },
75
92
  },
76
93
  default: '{}',
77
94
  description: 'Arguments for the selected tool in JSON format',
@@ -108,14 +125,19 @@ class SmartBrowserAutomation {
108
125
  type: 'collection',
109
126
  placeholder: 'Add Option',
110
127
  default: {},
128
+ displayOptions: {
129
+ show: {
130
+ mode: ['aiAgent'],
131
+ },
132
+ },
111
133
  options: [
112
134
  {
113
135
  displayName: 'CDP Endpoint',
114
136
  name: 'cdpUrl',
115
137
  type: 'string',
116
138
  default: '',
117
- placeholder: 'wss://...',
118
- description: 'The CDP URL to connect to. Overrides the one in credentials if provided.',
139
+ placeholder: 'wss://gridnew.doingerp.com/devtools/...',
140
+ description: 'The wss:// or http:// endpoint for the browser CDP connection',
119
141
  },
120
142
  {
121
143
  displayName: 'Enabled Tool Names or IDs',
@@ -146,16 +168,26 @@ class SmartBrowserAutomation {
146
168
  const credentials = await this.getCredentials('smartBrowserAutomationApi');
147
169
  const sessionManager = BrowserSessionManager_1.default.getInstance();
148
170
  const tools = await sessionManager.initialize(credentials.mcpEndpoint, credentials.browserMode === 'cdp', credentials.cdpEndpoint);
149
- if (!tools || tools.length === 0) {
150
- return [{ name: 'No Tools Found - Check MCP Server', value: 'none' }];
171
+ const nodeTools = [
172
+ {
173
+ name: 'Connect to Browser (CDP)',
174
+ value: 'browser_connect_cdp',
175
+ description: 'Connect to a browser via CDP URL',
176
+ },
177
+ ];
178
+ if (tools && tools.length > 0) {
179
+ nodeTools.push(...tools.map((tool) => ({
180
+ name: tool.name.split('_').map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join(' '),
181
+ value: tool.name,
182
+ })));
151
183
  }
152
- return tools.map((tool) => ({
153
- name: tool.name.split('_').map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join(' '),
154
- value: tool.name,
155
- }));
184
+ return nodeTools;
156
185
  }
157
186
  catch (error) {
158
- return [{ name: `Error: ${error.message}`, value: 'error' }];
187
+ return [
188
+ { name: 'Connect to Browser (CDP)', value: 'browser_connect_cdp' },
189
+ { name: `Error loading MCP tools: ${error.message}`, value: 'error' }
190
+ ];
159
191
  }
160
192
  },
161
193
  },
@@ -172,7 +204,7 @@ class SmartBrowserAutomation {
172
204
  }
173
205
  // Add a custom tool for the AI to connect to a specific CDP URL
174
206
  const connectTool = {
175
- name: 'browser_cdp_connect',
207
+ name: 'browser_connect_cdp',
176
208
  displayName: 'Connect to Browser (CDP)',
177
209
  description: 'Connect to a specific browser instance using a CDP URL (wss://...)',
178
210
  properties: [
@@ -207,11 +239,27 @@ class SmartBrowserAutomation {
207
239
  if (mode === 'manual') {
208
240
  // Manual mode: User selects tool and provides arguments
209
241
  const toolName = this.getNodeParameter('toolName', i);
210
- const toolArgsStr = this.getNodeParameter('toolArgs', i);
211
- // Initialize session if not ready
212
- if (!sessionManager.isReady()) {
213
- await sessionManager.initialize(credentials.mcpEndpoint, credentials.browserMode === 'cdp', credentials.cdpEndpoint);
242
+ // Special case: Manual Browser Connection
243
+ if (toolName === 'browser_connect_cdp') {
244
+ const endpoint = this.getNodeParameter('cdpUrl', i);
245
+ if (!endpoint) {
246
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'CDP Endpoint URL is required for browser_connect_cdp');
247
+ }
248
+ if (verbose) {
249
+ console.log(`Connecting to browser CDP: ${endpoint}`);
250
+ }
251
+ await sessionManager.initialize(credentials.mcpEndpoint, true, endpoint);
252
+ returnData.push({
253
+ json: {
254
+ success: true,
255
+ message: `Connected to browser at ${endpoint}`,
256
+ timestamp: new Date().toISOString()
257
+ },
258
+ pairedItem: i,
259
+ });
260
+ continue;
214
261
  }
262
+ const toolArgsStr = this.getNodeParameter('toolArgs', i);
215
263
  let toolArgs;
216
264
  try {
217
265
  toolArgs = JSON.parse(toolArgsStr);
@@ -219,6 +267,10 @@ class SmartBrowserAutomation {
219
267
  catch (error) {
220
268
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid JSON in Tool Arguments: ${error.message}`);
221
269
  }
270
+ // Initialize session if not ready
271
+ if (!sessionManager.isReady()) {
272
+ await sessionManager.initialize(credentials.mcpEndpoint, credentials.browserMode === 'cdp', credentials.cdpEndpoint);
273
+ }
222
274
  if (verbose) {
223
275
  console.log(`Executing tool: ${toolName} with args:`, toolArgs);
224
276
  }
@@ -236,13 +288,29 @@ class SmartBrowserAutomation {
236
288
  // AI Agent mode: Just initialize or close
237
289
  const operation = this.getNodeParameter('operation', i);
238
290
  if (operation === 'initialize') {
291
+ // Pull CDP URL from options if available, fallback to credentials
239
292
  const cdpUrl = options.cdpUrl || credentials.cdpEndpoint;
240
- const tools = await sessionManager.initialize(credentials.mcpEndpoint, true, // Force CDP if using initialize in AI mode
241
- cdpUrl);
293
+ if (verbose) {
294
+ console.log(`Initializing AI session with CDP: ${cdpUrl}`);
295
+ }
296
+ const tools = await sessionManager.initialize(credentials.mcpEndpoint, true, cdpUrl);
297
+ // New logic: Auto-call browser_connect tool if a URL is provided
298
+ if (options.cdpUrl) {
299
+ if (verbose) {
300
+ console.log(`Auto-calling 'browser_connect' with endpoint: ${options.cdpUrl}`);
301
+ }
302
+ try {
303
+ await sessionManager.callTool('browser_connect', { endpoint: options.cdpUrl });
304
+ }
305
+ catch (error) {
306
+ console.warn(`Failed to auto-connect browser via tool: ${error.message}`);
307
+ // We don't throw here to allow the AI to potentially fix it or show the error
308
+ }
309
+ }
242
310
  returnData.push({
243
311
  json: {
244
312
  success: true,
245
- message: 'Browser session initialized. Tools are now available to AI Agent.',
313
+ message: `MCP session initialized. Browser connect tool called for ${cdpUrl}.`,
246
314
  toolsCount: tools.length,
247
315
  tools: tools.map((t) => ({
248
316
  name: t.name,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-smart-browser-automation",
3
- "version": "1.0.6",
3
+ "version": "1.1.2",
4
4
  "description": "n8n node for AI-driven browser automation using MCP",
5
5
  "keywords": [
6
6
  "n8n-community-node-package",