n8n-nodes-smart-browser-automation 1.2.0 → 1.3.1

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.
@@ -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',
@@ -61,20 +61,10 @@ class SmartBrowserAutomation {
61
61
  type: 'string',
62
62
  default: '',
63
63
  placeholder: 'wss://gridnew.doingerp.com/devtools/...',
64
- description: 'The wss:// or http:// endpoint for the browser CDP connection',
64
+ description: 'Browser CDP endpoint to connect to. If not provided, MCP server will launch a new browser.',
65
65
  },
66
66
  {
67
- displayName: 'Enabled Tool Names or IDs',
68
- name: 'enabledTools',
69
- type: 'multiOptions',
70
- typeOptions: {
71
- loadOptionsMethod: 'getAvailableTools',
72
- },
73
- default: [],
74
- 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>.',
75
- },
76
- {
77
- displayName: 'Verbose',
67
+ displayName: 'Verbose Logging',
78
68
  name: 'verbose',
79
69
  type: 'boolean',
80
70
  default: false,
@@ -118,110 +108,14 @@ class SmartBrowserAutomation {
118
108
  };
119
109
  // Expose tools to AI Agent nodes
120
110
  async getTools() {
121
- // To save tokens and prevent context overflow, we expose a single "Router Tool"
122
- // instead of 54 individual tool definitions.
123
- const routerTool = {
124
- name: 'browser_tool',
125
- displayName: 'Browser Action',
126
- description: `Execute browser automation actions. ALWAYS use this tool for browser interactions.
127
-
128
- WHEN TO USE:
129
- ✓ User wants to visit/open/go to a website → action='navigate'
130
- ✓ User wants to click something → action='click'
131
- ✓ User wants to type/enter text → action='type'
132
- ✓ User wants to read/get text from page → action='snapshot' or action='get_text'
133
- ✓ User wants a screenshot → action='take_screenshot'
134
-
135
- REQUIRED PARAMETERS:
136
- • action: The action name (navigate, click, type, snapshot, take_screenshot, etc.)
137
- • params: JSON object with action-specific parameters
138
-
139
- EXAMPLES:
140
- 1. Navigate: { "action": "navigate", "params": { "url": "https://example.com" } }
141
- 2. Click: { "action": "click", "params": { "element": "button text", "ref": "..." } }
142
- 3. Type: { "action": "type", "params": { "element": "input field", "ref": "...", "text": "hello" } }
143
- 4. Snapshot: { "action": "snapshot", "params": {} }
144
- 5. Screenshot: { "action": "take_screenshot", "params": {} }
145
-
146
- IMPORTANT: For navigate action, params must include "url" key.`,
147
- properties: [
148
- {
149
- displayName: 'Action Name',
150
- name: 'action',
151
- type: 'string',
152
- required: true,
153
- default: '',
154
- },
155
- {
156
- displayName: 'Parameters',
157
- name: 'params',
158
- type: 'json',
159
- default: '{}',
160
- description: 'JSON parameters for the action (e.g., { "URL": "..." })',
161
- },
162
- ],
163
- async execute(input) {
164
- const sessionManager = BrowserSessionManager_1.default.getInstance();
165
- const credentials = await this.getCredentials('smartBrowserAutomationApi');
166
- // Ensure session is initialized
167
- if (!sessionManager.isReady()) {
168
- // Check for connection tool usage specifically
169
- if (input.action === 'connect_cdp' || input.action === 'browser_connect_cdp') {
170
- const endpoint = input.params?.endpoint;
171
- if (endpoint) {
172
- console.log(`[Router] Connecting to CDP: ${endpoint}`);
173
- await sessionManager.initialize(credentials.mcpEndpoint, true, endpoint);
174
- return {
175
- content: [{ type: 'text', text: `Connected to browser at ${endpoint}.` }],
176
- isError: false,
177
- toolName: 'browser_connect_cdp',
178
- requestedAction: input.action
179
- };
180
- }
181
- }
182
- // Session not ready and no explicit connection requested
183
- // This shouldn't happen - session should be initialized first
184
- throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Browser session not initialized. Please connect to browser first using Initialize Session or connect_cdp action.');
185
- } // Normalize action name
186
- let toolName = input.action;
187
- if (!toolName.startsWith('browser_') && toolName !== 'connect_cdp') {
188
- toolName = `browser_${toolName}`;
189
- }
190
- // Handle params
191
- let toolArgs = input.params || {};
192
- if (typeof toolArgs === 'string') {
193
- try {
194
- toolArgs = JSON.parse(toolArgs);
195
- }
196
- catch (e) {
197
- // ignore
198
- }
199
- }
200
- console.log(`[Router] Routing '${input.action}' to '${toolName}' with args:`, toolArgs);
201
- try {
202
- const result = await sessionManager.callTool(toolName, toolArgs);
203
- // Add tool name to result for visibility
204
- if (result && typeof result === 'object') {
205
- result.toolName = toolName;
206
- result.requestedAction = input.action;
207
- }
208
- return result;
209
- }
210
- catch (error) {
211
- return {
212
- content: [{ type: 'text', text: `Error executing ${toolName}: ${error.message}` }],
213
- isError: true,
214
- toolName: toolName,
215
- requestedAction: input.action
216
- };
217
- }
218
- }
219
- };
220
- // 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
221
115
  const connectTool = {
222
116
  name: 'browser_connect_cdp',
223
117
  displayName: 'Connect to Browser (CDP)',
224
- 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',
225
119
  properties: [
226
120
  {
227
121
  displayName: 'Endpoint URL',
@@ -229,7 +123,7 @@ IMPORTANT: For navigate action, params must include "url" key.`,
229
123
  type: 'string',
230
124
  default: '',
231
125
  required: true,
232
- description: 'The wss:// or http:// endpoint',
126
+ description: 'The wss:// or http:// CDP endpoint',
233
127
  },
234
128
  ],
235
129
  async execute(input) {
@@ -243,7 +137,7 @@ IMPORTANT: For navigate action, params must include "url" key.`,
243
137
  };
244
138
  }
245
139
  };
246
- return [routerTool, connectTool];
140
+ return [...mcpTools, connectTool];
247
141
  }
248
142
  async execute() {
249
143
  const items = this.getInputData();
@@ -51,6 +51,7 @@ async function createDynamicBrowserTools(credentials) {
51
51
  const sessionManager = BrowserSessionManager_1.default.getInstance();
52
52
  // Initialize and get MCP tools
53
53
  const mcpTools = await sessionManager.initialize(credentials.mcpEndpoint, credentials.browserMode === 'cdp', credentials.cdpEndpoint);
54
+ console.log(`[DynamicTools] Fetched ${mcpTools.length} tools from MCP server`);
54
55
  // Create n8n tool for each MCP tool
55
56
  const n8nTools = mcpTools.map((mcpTool) => {
56
57
  const toolName = mcpTool.name;
@@ -58,18 +59,26 @@ async function createDynamicBrowserTools(credentials) {
58
59
  .split('_')
59
60
  .map((s) => s.charAt(0).toUpperCase() + s.slice(1))
60
61
  .join(' ');
62
+ // Use MCP's description or create a better one
63
+ let description = mcpTool.description;
64
+ if (!description || description.trim() === '') {
65
+ description = `Execute ${displayName} action in the browser.`;
66
+ }
67
+ console.log(`[DynamicTools] Tool: ${toolName}, Description: ${description.substring(0, 100)}...`);
61
68
  return {
62
69
  name: toolName,
63
70
  displayName: displayName,
64
- description: mcpTool.description || `Execute ${displayName} action in the browser. Use this tool when you need to ${displayName.toLowerCase()}.`,
71
+ description: description,
65
72
  properties: mcpSchemaToN8nProperties(mcpTool.inputSchema),
66
73
  async execute(toolInput) {
67
74
  try {
68
- console.log(`[AI Agent] Executing tool: ${toolName}`);
75
+ console.log(`[AI Agent] Executing tool: ${toolName} with input:`, JSON.stringify(toolInput));
69
76
  const result = await sessionManager.callTool(toolName, toolInput);
77
+ console.log(`[AI Agent] Tool ${toolName} result:`, JSON.stringify(result).substring(0, 200));
70
78
  return result;
71
79
  }
72
80
  catch (error) {
81
+ console.error(`[AI Agent] Tool ${toolName} error:`, error.message);
73
82
  throw new Error(error.message || 'Unknown error occurred');
74
83
  }
75
84
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-smart-browser-automation",
3
- "version": "1.2.0",
3
+ "version": "1.3.1",
4
4
  "description": "n8n node for AI-driven browser automation using MCP",
5
5
  "keywords": [
6
6
  "n8n-community-node-package",