n8n-nodes-smart-browser-automation 1.1.13 → 1.3.0

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.
@@ -75,14 +75,14 @@ class BrowserSessionManager {
75
75
  throw new Error('MCP client not initialized. Please configure credentials first.');
76
76
  }
77
77
  try {
78
- // Only log in development/debug mode
79
- if (process.env.NODE_ENV !== 'production' && process.env.DEBUG) {
80
- console.log(`[MCP] Calling tool "${toolName}" with args:`, JSON.stringify(toolArgs || {}));
81
- }
78
+ // Log tool call for debugging
79
+ console.log(`[MCP] Calling tool "${toolName}" with args:`, JSON.stringify(toolArgs || {}));
82
80
  const result = await this.mcpClient.callTool({
83
81
  name: toolName,
84
82
  arguments: toolArgs || {}
85
83
  });
84
+ // Log the response for debugging
85
+ console.log(`[MCP] Tool "${toolName}" response:`, JSON.stringify(result, null, 2));
86
86
  return result;
87
87
  }
88
88
  catch (error) {
@@ -4,8 +4,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.SmartBrowserAutomation = void 0;
7
- const n8n_workflow_1 = require("n8n-workflow");
8
7
  const BrowserSessionManager_1 = __importDefault(require("./BrowserSessionManager"));
8
+ const DynamicBrowserTools_1 = require("./tools/DynamicBrowserTools");
9
9
  class SmartBrowserAutomation {
10
10
  description = {
11
11
  displayName: 'Smart Browser Automation',
@@ -27,81 +27,11 @@ class SmartBrowserAutomation {
27
27
  ],
28
28
  usableAsTool: true,
29
29
  properties: [
30
- {
31
- displayName: 'Mode',
32
- name: 'mode',
33
- type: 'options',
34
- noDataExpression: true,
35
- options: [
36
- {
37
- name: 'AI Agent (Auto)',
38
- value: 'aiAgent',
39
- description: 'Let AI decide which tools to use - use this with AI Agent node',
40
- },
41
- {
42
- name: 'Manual',
43
- value: 'manual',
44
- description: 'Manually select tool and provide arguments',
45
- },
46
- ],
47
- default: 'aiAgent',
48
- description: 'How to execute browser automation',
49
- },
50
- {
51
- displayName: 'Tool Name or ID',
52
- name: 'toolName',
53
- type: 'options',
54
- typeOptions: {
55
- loadOptionsMethod: 'getAvailableTools',
56
- },
57
- displayOptions: {
58
- show: {
59
- mode: ['manual'],
60
- },
61
- },
62
- default: 'browser_connect_cdp',
63
- 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>.',
64
- required: true,
65
- },
66
- {
67
- displayName: 'CDP Endpoint',
68
- name: 'cdpUrl',
69
- type: 'string',
70
- displayOptions: {
71
- show: {
72
- mode: ['manual'],
73
- toolName: ['browser_connect_cdp'],
74
- },
75
- },
76
- default: '',
77
- placeholder: 'wss://gridnew.doingerp.com/devtools/...',
78
- description: 'The wss:// or http:// endpoint for the browser CDP connection',
79
- },
80
- {
81
- displayName: 'Tool Arguments',
82
- name: 'toolArgs',
83
- type: 'json',
84
- displayOptions: {
85
- show: {
86
- mode: ['manual'],
87
- },
88
- hide: {
89
- toolName: ['browser_connect_cdp'],
90
- },
91
- },
92
- default: '{}',
93
- description: 'Arguments for the selected tool in JSON format',
94
- },
95
30
  {
96
31
  displayName: 'Operation',
97
32
  name: 'operation',
98
33
  type: 'options',
99
34
  noDataExpression: true,
100
- displayOptions: {
101
- show: {
102
- mode: ['aiAgent'],
103
- },
104
- },
105
35
  options: [
106
36
  {
107
37
  name: 'Initialize Session',
@@ -124,11 +54,6 @@ class SmartBrowserAutomation {
124
54
  type: 'collection',
125
55
  placeholder: 'Add Option',
126
56
  default: {},
127
- displayOptions: {
128
- show: {
129
- mode: ['aiAgent'],
130
- },
131
- },
132
57
  options: [
133
58
  {
134
59
  displayName: 'CDP Endpoint',
@@ -136,20 +61,10 @@ class SmartBrowserAutomation {
136
61
  type: 'string',
137
62
  default: '',
138
63
  placeholder: 'wss://gridnew.doingerp.com/devtools/...',
139
- description: 'The wss:// or http:// endpoint for the browser CDP connection',
140
- },
141
- {
142
- displayName: 'Enabled Tool Names or IDs',
143
- name: 'enabledTools',
144
- type: 'multiOptions',
145
- typeOptions: {
146
- loadOptionsMethod: 'getAvailableTools',
147
- },
148
- default: [],
149
- description: 'Select which tools to expose to the AI Agent or Manual list. Leave empty for all. Choose from the list, or specify IDs using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
64
+ description: 'Browser CDP endpoint to connect to. If not provided, MCP server will launch a new browser.',
150
65
  },
151
66
  {
152
- displayName: 'Verbose',
67
+ displayName: 'Verbose Logging',
153
68
  name: 'verbose',
154
69
  type: 'boolean',
155
70
  default: false,
@@ -193,99 +108,14 @@ class SmartBrowserAutomation {
193
108
  };
194
109
  // Expose tools to AI Agent nodes
195
110
  async getTools() {
196
- // To save tokens and prevent context overflow, we expose a single "Router Tool"
197
- // instead of 54 individual tool definitions.
198
- const routerTool = {
199
- name: 'browser_tool',
200
- displayName: 'Browser Action',
201
- description: `Perform browser automation actions.
202
- USAGE EXAMPLES:
203
- - Navigate: action='navigate', params={ "url": "https://..." }
204
- - Click: action='click', params={ "selector": "button.submit" }
205
- - Type: action='type', params={ "selector": "#input", "text": "hello" }
206
- - Scroll: action='scroll_to', params={ "selector": "footer" }
207
- - Get Text: action='get_text', params={ "selector": ".content" }
208
- - Screenshot: action='take_screenshot', params={}
209
-
210
- Available actions: navigate, click, type, press_key, scroll_to, get_text, take_screenshot, evaluate, etc.
211
- Supported Params depend on the action.`,
212
- properties: [
213
- {
214
- displayName: 'Action Name',
215
- name: 'action',
216
- type: 'string',
217
- required: true,
218
- default: '',
219
- },
220
- {
221
- displayName: 'Parameters',
222
- name: 'params',
223
- type: 'json',
224
- default: '{}',
225
- description: 'JSON parameters for the action (e.g., { "URL": "..." })',
226
- },
227
- ],
228
- async execute(input) {
229
- const sessionManager = BrowserSessionManager_1.default.getInstance();
230
- const credentials = await this.getCredentials('smartBrowserAutomationApi');
231
- // Ensure session is initialized
232
- if (!sessionManager.isReady()) {
233
- // Check for connection tool usage specifically
234
- if (input.action === 'connect_cdp' || input.action === 'browser_connect_cdp') {
235
- const endpoint = input.params?.endpoint;
236
- if (endpoint) {
237
- await sessionManager.initialize(credentials.mcpEndpoint, true, endpoint);
238
- return {
239
- content: [{ type: 'text', text: `Connected to browser at ${endpoint}.` }],
240
- isError: false,
241
- toolName: 'browser_connect_cdp',
242
- requestedAction: input.action
243
- };
244
- }
245
- }
246
- // Auto-initialize if possible (blindly)
247
- await sessionManager.initialize(credentials.mcpEndpoint, credentials.browserMode === 'cdp', credentials.cdpEndpoint);
248
- }
249
- // Normalize action name
250
- let toolName = input.action;
251
- if (!toolName.startsWith('browser_') && toolName !== 'connect_cdp') {
252
- toolName = `browser_${toolName}`;
253
- }
254
- // Handle params
255
- let toolArgs = input.params || {};
256
- if (typeof toolArgs === 'string') {
257
- try {
258
- toolArgs = JSON.parse(toolArgs);
259
- }
260
- catch (e) {
261
- // ignore
262
- }
263
- }
264
- console.log(`[Router] Routing '${input.action}' to '${toolName}' with args:`, toolArgs);
265
- try {
266
- const result = await sessionManager.callTool(toolName, toolArgs);
267
- // Add tool name to result for visibility
268
- if (result && typeof result === 'object') {
269
- result.toolName = toolName;
270
- result.requestedAction = input.action;
271
- }
272
- return result;
273
- }
274
- catch (error) {
275
- return {
276
- content: [{ type: 'text', text: `Error executing ${toolName}: ${error.message}` }],
277
- isError: true,
278
- toolName: toolName,
279
- requestedAction: input.action
280
- };
281
- }
282
- }
283
- };
284
- // Add a custom tool for specific CDP connection (legacy support)
111
+ const credentials = await this.getCredentials('smartBrowserAutomationApi');
112
+ // Get all individual MCP tools
113
+ const mcpTools = await (0, DynamicBrowserTools_1.createDynamicBrowserTools)(credentials);
114
+ // Add custom CDP connection tool
285
115
  const connectTool = {
286
116
  name: 'browser_connect_cdp',
287
117
  displayName: 'Connect to Browser (CDP)',
288
- description: 'Connect to a specific browser instance using a CDP URL. Params: { "endpoint": "wss://..." }',
118
+ description: 'Connect to a specific browser instance using a CDP endpoint URL',
289
119
  properties: [
290
120
  {
291
121
  displayName: 'Endpoint URL',
@@ -293,7 +123,7 @@ class SmartBrowserAutomation {
293
123
  type: 'string',
294
124
  default: '',
295
125
  required: true,
296
- description: 'The wss:// or http:// endpoint',
126
+ description: 'The wss:// or http:// CDP endpoint',
297
127
  },
298
128
  ],
299
129
  async execute(input) {
@@ -307,113 +137,65 @@ class SmartBrowserAutomation {
307
137
  };
308
138
  }
309
139
  };
310
- return [routerTool, connectTool];
140
+ return [...mcpTools, connectTool];
311
141
  }
312
142
  async execute() {
313
143
  const items = this.getInputData();
314
144
  const returnData = [];
315
145
  const credentials = await this.getCredentials('smartBrowserAutomationApi');
316
146
  const sessionManager = BrowserSessionManager_1.default.getInstance();
317
- const mode = this.getNodeParameter('mode', 0);
318
147
  for (let i = 0; i < items.length; i++) {
319
148
  try {
320
149
  const options = this.getNodeParameter('options', i, {});
321
150
  const verbose = options.verbose || false;
322
- if (mode === 'manual') {
323
- // Manual mode: User selects tool and provides arguments
324
- const toolName = this.getNodeParameter('toolName', i);
325
- // Special case: Manual Browser Connection
326
- if (toolName === 'browser_connect_cdp') {
327
- const endpoint = this.getNodeParameter('cdpUrl', i);
328
- if (!endpoint) {
329
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'CDP Endpoint URL is required for browser_connect_cdp');
330
- }
151
+ const operation = this.getNodeParameter('operation', i);
152
+ if (operation === 'initialize') {
153
+ const cdpUrl = credentials.cdpEndpoint;
154
+ await sessionManager.initialize(credentials.mcpEndpoint, true, cdpUrl);
155
+ // New logic: Auto-call browser_connect_cdp tool if a URL is provided
156
+ if (options.cdpUrl) {
331
157
  if (verbose) {
332
- console.log(`Connecting to browser CDP: ${endpoint}`);
158
+ console.log(`Auto-calling 'browser_connect_cdp' with endpoint: ${options.cdpUrl}`);
333
159
  }
334
- await sessionManager.initialize(credentials.mcpEndpoint, true, endpoint);
335
- returnData.push({
336
- json: {
337
- success: true,
338
- message: `Connected to browser at ${endpoint}`,
339
- timestamp: new Date().toISOString()
340
- },
341
- pairedItem: i,
342
- });
343
- continue;
344
- }
345
- const toolArgsStr = this.getNodeParameter('toolArgs', i);
346
- let toolArgs;
347
- try {
348
- toolArgs = JSON.parse(toolArgsStr);
349
- }
350
- catch (error) {
351
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid JSON in Tool Arguments: ${error.message}`);
352
- }
353
- // Initialize session if not ready
354
- if (!sessionManager.isReady()) {
355
- await sessionManager.initialize(credentials.mcpEndpoint, credentials.browserMode === 'cdp', credentials.cdpEndpoint);
356
- }
357
- if (verbose) {
358
- console.log(`Executing tool: ${toolName} with args:`, toolArgs);
359
- }
360
- const result = await sessionManager.callTool(toolName, toolArgs);
361
- returnData.push({
362
- json: result,
363
- pairedItem: i,
364
- });
365
- }
366
- else {
367
- // AI Agent mode: Just initialize or close
368
- const operation = this.getNodeParameter('operation', i);
369
- if (operation === 'initialize') {
370
- const cdpUrl = credentials.cdpEndpoint;
371
- await sessionManager.initialize(credentials.mcpEndpoint, true, cdpUrl);
372
- // New logic: Auto-call browser_connect_cdp tool if a URL is provided
373
- if (options.cdpUrl) {
374
- if (verbose) {
375
- console.log(`Auto-calling 'browser_connect_cdp' with endpoint: ${options.cdpUrl}`);
376
- }
377
- try {
378
- const connectionResult = await sessionManager.callTool('browser_connect_cdp', { endpoint: options.cdpUrl });
379
- // Return only the connection result, no extra messages
380
- returnData.push({
381
- json: connectionResult,
382
- pairedItem: i,
383
- });
384
- }
385
- catch (error) {
386
- returnData.push({
387
- json: {
388
- success: false,
389
- error: `Failed to connect: ${error.message}`
390
- },
391
- pairedItem: i,
392
- });
393
- }
160
+ try {
161
+ const connectionResult = await sessionManager.callTool('browser_connect_cdp', { endpoint: options.cdpUrl });
162
+ // Return only the connection result, no extra messages
163
+ returnData.push({
164
+ json: connectionResult,
165
+ pairedItem: i,
166
+ });
394
167
  }
395
- else {
396
- // No CDP URL provided
168
+ catch (error) {
397
169
  returnData.push({
398
170
  json: {
399
- success: true,
400
- message: 'MCP session initialized (no browser connection)'
171
+ success: false,
172
+ error: `Failed to connect: ${error.message}`
401
173
  },
402
174
  pairedItem: i,
403
175
  });
404
176
  }
405
177
  }
406
- else if (operation === 'close') {
407
- await sessionManager.close();
178
+ else {
179
+ // No CDP URL provided
408
180
  returnData.push({
409
181
  json: {
410
182
  success: true,
411
- message: 'Browser session closed',
183
+ message: 'MCP session initialized (no browser connection)'
412
184
  },
413
185
  pairedItem: i,
414
186
  });
415
187
  }
416
188
  }
189
+ else if (operation === 'close') {
190
+ await sessionManager.close();
191
+ returnData.push({
192
+ json: {
193
+ success: true,
194
+ message: 'Browser session closed',
195
+ },
196
+ pairedItem: i,
197
+ });
198
+ }
417
199
  }
418
200
  catch (error) {
419
201
  if (this.continueOnFail()) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-smart-browser-automation",
3
- "version": "1.1.13",
3
+ "version": "1.3.0",
4
4
  "description": "n8n node for AI-driven browser automation using MCP",
5
5
  "keywords": [
6
6
  "n8n-community-node-package",