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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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();
@@ -109,14 +109,6 @@ class SmartBrowserAutomation {
109
109
  placeholder: 'Add Option',
110
110
  default: {},
111
111
  options: [
112
- {
113
- displayName: 'CDP Endpoint',
114
- name: 'cdpUrl',
115
- type: 'string',
116
- default: '',
117
- placeholder: 'wss://...',
118
- description: 'The CDP URL to connect to. Overrides the one in credentials if provided.',
119
- },
120
112
  {
121
113
  displayName: 'Enabled Tool Names or IDs',
122
114
  name: 'enabledTools',
@@ -146,16 +138,26 @@ class SmartBrowserAutomation {
146
138
  const credentials = await this.getCredentials('smartBrowserAutomationApi');
147
139
  const sessionManager = BrowserSessionManager_1.default.getInstance();
148
140
  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' }];
141
+ const nodeTools = [
142
+ {
143
+ name: 'Connect to Browser (CDP)',
144
+ value: 'browser_connect_cdp',
145
+ description: 'Connect to a browser via CDP URL',
146
+ },
147
+ ];
148
+ if (tools && tools.length > 0) {
149
+ nodeTools.push(...tools.map((tool) => ({
150
+ name: tool.name.split('_').map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join(' '),
151
+ value: tool.name,
152
+ })));
151
153
  }
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
- }));
154
+ return nodeTools;
156
155
  }
157
156
  catch (error) {
158
- return [{ name: `Error: ${error.message}`, value: 'error' }];
157
+ return [
158
+ { name: 'Connect to Browser (CDP)', value: 'browser_connect_cdp' },
159
+ { name: `Error loading MCP tools: ${error.message}`, value: 'error' }
160
+ ];
159
161
  }
160
162
  },
161
163
  },
@@ -172,7 +174,7 @@ class SmartBrowserAutomation {
172
174
  }
173
175
  // Add a custom tool for the AI to connect to a specific CDP URL
174
176
  const connectTool = {
175
- name: 'browser_cdp_connect',
177
+ name: 'browser_connect_cdp',
176
178
  displayName: 'Connect to Browser (CDP)',
177
179
  description: 'Connect to a specific browser instance using a CDP URL (wss://...)',
178
180
  properties: [
@@ -208,10 +210,6 @@ class SmartBrowserAutomation {
208
210
  // Manual mode: User selects tool and provides arguments
209
211
  const toolName = this.getNodeParameter('toolName', i);
210
212
  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);
214
- }
215
213
  let toolArgs;
216
214
  try {
217
215
  toolArgs = JSON.parse(toolArgsStr);
@@ -219,6 +217,23 @@ class SmartBrowserAutomation {
219
217
  catch (error) {
220
218
  throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid JSON in Tool Arguments: ${error.message}`);
221
219
  }
220
+ // Special case: Manual Browser Connection
221
+ if (toolName === 'browser_connect_cdp') {
222
+ const endpoint = toolArgs.endpoint;
223
+ if (!endpoint) {
224
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Endpoint URL is required for browser_connect_cdp');
225
+ }
226
+ await sessionManager.initialize(credentials.mcpEndpoint, true, endpoint);
227
+ returnData.push({
228
+ json: { success: true, message: `Connected to browser at ${endpoint}` },
229
+ pairedItem: i,
230
+ });
231
+ continue;
232
+ }
233
+ // Initialize session if not ready
234
+ if (!sessionManager.isReady()) {
235
+ await sessionManager.initialize(credentials.mcpEndpoint, credentials.browserMode === 'cdp', credentials.cdpEndpoint);
236
+ }
222
237
  if (verbose) {
223
238
  console.log(`Executing tool: ${toolName} with args:`, toolArgs);
224
239
  }
@@ -236,9 +251,9 @@ class SmartBrowserAutomation {
236
251
  // AI Agent mode: Just initialize or close
237
252
  const operation = this.getNodeParameter('operation', i);
238
253
  if (operation === 'initialize') {
239
- 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);
254
+ // In AI mode, we use the credentials or fallback to nothing
255
+ const cdpUrl = credentials.cdpEndpoint;
256
+ const tools = await sessionManager.initialize(credentials.mcpEndpoint, true, cdpUrl);
242
257
  returnData.push({
243
258
  json: {
244
259
  success: true,
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.0.8",
4
4
  "description": "n8n node for AI-driven browser automation using MCP",
5
5
  "keywords": [
6
6
  "n8n-community-node-package",