n8n-nodes-smart-browser-automation 1.0.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Ejaz Ullah
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,203 @@
1
+ # n8n-nodes-smart-browser-automation
2
+
3
+ n8n community node for AI-driven browser automation using Model Context Protocol (MCP).
4
+
5
+ ## Features
6
+
7
+ - **Two Modes**:
8
+ - **AI Agent Mode**: Let AI decide which browser tools to use (works with any AI model in n8n)
9
+ - **Manual Mode**: Choose specific browser tools from a dropdown list
10
+
11
+ - **MCP Integration**: Connect to MCP server once, reuse for all operations
12
+ - **Browser Flexibility**: Auto-launch browser or connect via CDP (Chrome DevTools Protocol)
13
+ - **Dynamic Tool Loading**: All MCP tools automatically available to AI agents
14
+ - **Persistent Session**: Browser stays open across multiple operations
15
+
16
+ ## Installation
17
+
18
+ ### Community Node Installation
19
+
20
+ 1. In n8n, go to **Settings** > **Community Nodes**
21
+ 2. Click **Install** and enter: `n8n-nodes-smart-browser-automation`
22
+ 3. Install the node
23
+
24
+ ### Manual Installation (for development)
25
+
26
+ ```bash
27
+ cd ~/.n8n/custom
28
+ git clone https://github.com/Ejazullah42/n8n-nodes-smart-browser-automation.git
29
+ cd n8n-nodes-smart-browser-automation
30
+ npm install
31
+ npm run build
32
+ ```
33
+
34
+ Restart n8n to load the node.
35
+
36
+ ## Prerequisites
37
+
38
+ 1. **MCP Server**: You need a running MCP server (e.g., from `@ejazullah/smart-browser-automation`)
39
+ 2. **Node.js**: Version 18 or higher
40
+
41
+ ## Configuration
42
+
43
+ ### Credentials Setup
44
+
45
+ Add new credentials for **Smart Browser Automation API**:
46
+
47
+ 1. **MCP Endpoint**: URL of your MCP server (e.g., `http://localhost:3000`)
48
+ 2. **Browser Mode**:
49
+ - **Auto Launch**: Automatically start a new browser
50
+ - **CDP Connection**: Connect to existing browser
51
+ 3. **CDP Endpoint** (if using CDP mode): WebSocket URL (e.g., `ws://localhost:9222`)
52
+
53
+ ## Usage
54
+
55
+ ### Mode 1: AI Agent (Automatic)
56
+
57
+ Use with n8n's **AI Agent** node to let AI decide which browser tools to use:
58
+
59
+ 1. Add **Smart Browser Automation** node
60
+ 2. Select **Mode**: `AI Agent (Auto)`
61
+ 3. Operation: `Initialize Session`
62
+ 4. Connect to **AI Agent** node
63
+ 5. AI can now use all browser tools automatically
64
+
65
+ **Example AI Agent Workflow**:
66
+ ```
67
+ Trigger → AI Agent (with Smart Browser Automation tools)
68
+ ```
69
+
70
+ AI Agent prompt: "Go to google.com and search for 'n8n automation', then extract the top 3 results"
71
+
72
+ The AI will automatically:
73
+ - Call `browser_navigate` to go to google.com
74
+ - Call `browser_type` to enter search text
75
+ - Call `browser_click` to submit
76
+ - Call `browser_snapshot` to see results
77
+ - Extract the data
78
+
79
+ ### Mode 2: Manual
80
+
81
+ Choose specific tools yourself:
82
+
83
+ 1. Add **Smart Browser Automation** node
84
+ 2. Select **Mode**: `Manual`
85
+ 3. **Tool**: Select from dropdown (browser_navigate, browser_click, etc.)
86
+ 4. **Tool Arguments**: Provide JSON arguments
87
+
88
+ **Example Manual Workflow**:
89
+ ```json
90
+ {
91
+ "url": "https://google.com"
92
+ }
93
+ ```
94
+
95
+ ## Available Browser Tools
96
+
97
+ All MCP browser tools are dynamically loaded. Common tools include:
98
+
99
+ - `browser_navigate` - Navigate to URL
100
+ - `browser_click` - Click element
101
+ - `browser_type` - Type text into input
102
+ - `browser_snapshot` - Capture page accessibility tree
103
+ - `browser_take_screenshot` - Take screenshot
104
+ - `browser_evaluate` - Execute JavaScript
105
+ - `browser_fill_form` - Fill multiple form fields
106
+ - `browser_select_option` - Select dropdown option
107
+ - `browser_hover` - Hover over element
108
+ - And more...
109
+
110
+ ## Example Workflows
111
+
112
+ ### Example 1: AI-Driven Web Scraping
113
+
114
+ ```
115
+ Webhook Trigger
116
+ → Smart Browser (Initialize)
117
+ → AI Agent (GPT-4)
118
+ - Tools: Smart Browser Automation
119
+ - Prompt: "Scrape product prices from example.com"
120
+ → Database Node (Save results)
121
+ ```
122
+
123
+ ### Example 2: Manual Form Filling
124
+
125
+ ```
126
+ Trigger
127
+ → Smart Browser (Manual Mode)
128
+ - Tool: browser_navigate
129
+ - Args: {"url": "https://form.com"}
130
+ → Smart Browser (Manual Mode)
131
+ - Tool: browser_fill_form
132
+ - Args: {"fields": [...]}
133
+ → Smart Browser (Manual Mode)
134
+ - Tool: browser_click
135
+ - Args: {"element": "Submit button"}
136
+ ```
137
+
138
+ ### Example 3: Testing with Multiple AI Models
139
+
140
+ ```
141
+ Trigger
142
+ → Smart Browser (Initialize)
143
+ → Switch Node
144
+ - Route to OpenAI Agent
145
+ - Route to Claude Agent
146
+ - Route to Gemini Agent
147
+ (All can use the same browser session)
148
+ ```
149
+
150
+ ## Closing Browser Session
151
+
152
+ Always close the session when done:
153
+
154
+ 1. **AI Agent Mode**: Set Operation to `Close Session`
155
+ 2. **Manual Mode**: Switch to AI Agent mode and close
156
+
157
+ ## Troubleshooting
158
+
159
+ ### Browser Not Connecting
160
+ - Verify MCP server is running
161
+ - Check MCP endpoint URL
162
+ - For CDP mode, ensure browser is running with remote debugging
163
+
164
+ ### Tools Not Appearing
165
+ - Click "Refresh" in the tool dropdown
166
+ - Verify credentials are configured correctly
167
+ - Check MCP server logs
168
+
169
+ ### AI Not Using Tools
170
+ - Ensure AI Agent node has access to the tools
171
+ - Check AI model supports function calling
172
+ - Verify tool descriptions are clear
173
+
174
+ ## Development
175
+
176
+ ```bash
177
+ # Install dependencies
178
+ npm install
179
+
180
+ # Build
181
+ npm run build
182
+
183
+ # Watch mode
184
+ npm run dev
185
+
186
+ # Lint
187
+ npm run lint
188
+ ```
189
+
190
+ ## Links
191
+
192
+ - [GitHub Repository](https://github.com/Ejazullah42/n8n-nodes-smart-browser-automation)
193
+ - [Smart Browser Automation Library](https://github.com/Ejazullah42/smart-browser-automation)
194
+ - [n8n Community Nodes](https://docs.n8n.io/integrations/community-nodes/)
195
+ - [Model Context Protocol](https://modelcontextprotocol.io/)
196
+
197
+ ## License
198
+
199
+ MIT
200
+
201
+ ## Author
202
+
203
+ Ejaz Ullah - ejaz@doinger.com
@@ -0,0 +1,7 @@
1
+ import { ICredentialType, INodeProperties } from 'n8n-workflow';
2
+ export declare class SmartBrowserAutomationApi implements ICredentialType {
3
+ name: string;
4
+ displayName: string;
5
+ documentationUrl: string;
6
+ properties: INodeProperties[];
7
+ }
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SmartBrowserAutomationApi = void 0;
4
+ class SmartBrowserAutomationApi {
5
+ name = 'smartBrowserAutomationApi';
6
+ displayName = 'Smart Browser Automation API';
7
+ documentationUrl = 'https://github.com/Ejazullah42/smart-browser-automation';
8
+ properties = [
9
+ {
10
+ displayName: 'MCP Endpoint',
11
+ name: 'mcpEndpoint',
12
+ type: 'string',
13
+ default: 'http://localhost:3000',
14
+ required: true,
15
+ description: 'MCP server endpoint URL (set once, reused for all operations)',
16
+ },
17
+ {
18
+ displayName: 'Browser Mode',
19
+ name: 'browserMode',
20
+ type: 'options',
21
+ options: [
22
+ {
23
+ name: 'Auto Launch',
24
+ value: 'launch',
25
+ description: 'Automatically launch a new browser instance',
26
+ },
27
+ {
28
+ name: 'CDP Connection',
29
+ value: 'cdp',
30
+ description: 'Connect to existing browser via Chrome DevTools Protocol',
31
+ },
32
+ ],
33
+ default: 'launch',
34
+ description: 'How to connect to the browser',
35
+ },
36
+ {
37
+ displayName: 'CDP Endpoint',
38
+ name: 'cdpEndpoint',
39
+ type: 'string',
40
+ default: 'ws://localhost:9222',
41
+ displayOptions: {
42
+ show: {
43
+ browserMode: ['cdp'],
44
+ },
45
+ },
46
+ description: 'Chrome DevTools Protocol WebSocket URL (supports dynamic URLs)',
47
+ },
48
+ ];
49
+ }
50
+ exports.SmartBrowserAutomationApi = SmartBrowserAutomationApi;
@@ -0,0 +1,21 @@
1
+ interface MCPTool {
2
+ name: string;
3
+ description?: string;
4
+ inputSchema?: any;
5
+ }
6
+ declare class BrowserSessionManager {
7
+ private static instance;
8
+ private mcpClient;
9
+ private transport;
10
+ private isInitialized;
11
+ private config;
12
+ private tools;
13
+ private constructor();
14
+ static getInstance(): BrowserSessionManager;
15
+ initialize(mcpEndpoint: string, useCDP: boolean, cdpEndpoint?: string): Promise<MCPTool[]>;
16
+ callTool(toolName: string, toolArgs?: any): Promise<any>;
17
+ getTools(): MCPTool[];
18
+ close(): Promise<void>;
19
+ isReady(): boolean;
20
+ }
21
+ export default BrowserSessionManager;
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const index_js_1 = require("@modelcontextprotocol/sdk/client/index.js");
4
+ const stdio_js_1 = require("@modelcontextprotocol/sdk/client/stdio.js");
5
+ class BrowserSessionManager {
6
+ static instance;
7
+ mcpClient = null;
8
+ transport = null;
9
+ isInitialized = false;
10
+ config = {};
11
+ tools = [];
12
+ constructor() { }
13
+ static getInstance() {
14
+ if (!BrowserSessionManager.instance) {
15
+ BrowserSessionManager.instance = new BrowserSessionManager();
16
+ }
17
+ return BrowserSessionManager.instance;
18
+ }
19
+ async initialize(mcpEndpoint, useCDP, cdpEndpoint) {
20
+ // Only initialize if not already done or config changed
21
+ if (this.isInitialized &&
22
+ this.config.mcpEndpoint === mcpEndpoint &&
23
+ this.config.cdpEndpoint === cdpEndpoint) {
24
+ return this.tools;
25
+ }
26
+ // Close existing session if config changed
27
+ if (this.mcpClient) {
28
+ await this.close();
29
+ }
30
+ // Initialize MCP client
31
+ 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: useCDP && cdpEndpoint ? { CDP_URL: cdpEndpoint } : undefined
37
+ });
38
+ await this.mcpClient.connect(this.transport);
39
+ // Fetch available tools from MCP server
40
+ const toolsResponse = await this.mcpClient.listTools();
41
+ this.tools = toolsResponse.tools || [];
42
+ this.config = { mcpEndpoint, cdpEndpoint };
43
+ this.isInitialized = true;
44
+ return this.tools;
45
+ }
46
+ async callTool(toolName, toolArgs) {
47
+ if (!this.mcpClient || !this.isInitialized) {
48
+ throw new Error('MCP client not initialized. Please configure credentials first.');
49
+ }
50
+ const result = await this.mcpClient.callTool({
51
+ name: toolName,
52
+ arguments: toolArgs || {}
53
+ });
54
+ return result;
55
+ }
56
+ getTools() {
57
+ return this.tools;
58
+ }
59
+ async close() {
60
+ if (this.mcpClient && this.transport) {
61
+ await this.mcpClient.close();
62
+ this.mcpClient = null;
63
+ this.transport = null;
64
+ this.isInitialized = false;
65
+ this.tools = [];
66
+ }
67
+ }
68
+ isReady() {
69
+ return this.isInitialized && this.mcpClient !== null;
70
+ }
71
+ }
72
+ exports.default = BrowserSessionManager;
@@ -0,0 +1,11 @@
1
+ import { IExecuteFunctions, ILoadOptionsFunctions, INodeExecutionData, INodePropertyOptions, INodeType, INodeTypeDescription } from 'n8n-workflow';
2
+ export declare class SmartBrowserAutomation implements INodeType {
3
+ description: INodeTypeDescription;
4
+ methods: {
5
+ loadOptions: {
6
+ getAvailableTools(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
7
+ };
8
+ };
9
+ getTools?(this: IExecuteFunctions): Promise<any[]>;
10
+ execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
11
+ }
@@ -0,0 +1,216 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SmartBrowserAutomation = void 0;
7
+ const n8n_workflow_1 = require("n8n-workflow");
8
+ const DynamicBrowserTools_1 = require("./tools/DynamicBrowserTools");
9
+ const BrowserSessionManager_1 = __importDefault(require("./BrowserSessionManager"));
10
+ class SmartBrowserAutomation {
11
+ description = {
12
+ displayName: 'Smart Browser Automation',
13
+ name: 'smartBrowserAutomation',
14
+ group: ['transform'],
15
+ version: 1,
16
+ description: 'Browser automation with AI Agent mode (auto) or Manual mode (user choice)',
17
+ defaults: {
18
+ name: 'Browser Automation',
19
+ },
20
+ inputs: ['main'],
21
+ outputs: ['main'],
22
+ credentials: [
23
+ {
24
+ name: 'smartBrowserAutomationApi',
25
+ required: true,
26
+ },
27
+ ],
28
+ properties: [
29
+ {
30
+ displayName: 'Mode',
31
+ name: 'mode',
32
+ type: 'options',
33
+ noDataExpression: true,
34
+ options: [
35
+ {
36
+ name: 'AI Agent (Auto)',
37
+ value: 'aiAgent',
38
+ description: 'Let AI decide which tools to use - use this with AI Agent node',
39
+ },
40
+ {
41
+ name: 'Manual',
42
+ value: 'manual',
43
+ description: 'Manually select tool and provide arguments',
44
+ },
45
+ ],
46
+ default: 'aiAgent',
47
+ description: 'How to execute browser automation',
48
+ },
49
+ {
50
+ displayName: 'Tool Name or ID',
51
+ name: 'toolName',
52
+ type: 'options',
53
+ typeOptions: {
54
+ loadOptionsMethod: 'getAvailableTools',
55
+ },
56
+ displayOptions: {
57
+ show: {
58
+ mode: ['manual'],
59
+ },
60
+ },
61
+ default: '',
62
+ 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
+ required: true,
64
+ },
65
+ {
66
+ displayName: 'Tool Arguments',
67
+ name: 'toolArgs',
68
+ type: 'json',
69
+ displayOptions: {
70
+ show: {
71
+ mode: ['manual'],
72
+ },
73
+ },
74
+ default: '{}',
75
+ description: 'Arguments for the selected tool in JSON format',
76
+ },
77
+ {
78
+ displayName: 'Operation',
79
+ name: 'operation',
80
+ type: 'options',
81
+ noDataExpression: true,
82
+ displayOptions: {
83
+ show: {
84
+ mode: ['aiAgent'],
85
+ },
86
+ },
87
+ options: [
88
+ {
89
+ name: 'Initialize Session',
90
+ value: 'initialize',
91
+ description: 'Initialize browser session and load available tools',
92
+ action: 'Initialize browser session and load available tools',
93
+ },
94
+ {
95
+ name: 'Close Session',
96
+ value: 'close',
97
+ description: 'Close browser session and cleanup',
98
+ action: 'Close browser session and cleanup',
99
+ },
100
+ ],
101
+ default: 'initialize',
102
+ },
103
+ {
104
+ displayName: 'Verbose',
105
+ name: 'verbose',
106
+ type: 'boolean',
107
+ default: false,
108
+ description: 'Whether to enable detailed logging',
109
+ },
110
+ ],
111
+ };
112
+ methods = {
113
+ loadOptions: {
114
+ // Populate tool dropdown in manual mode
115
+ async getAvailableTools() {
116
+ const credentials = await this.getCredentials('smartBrowserAutomationApi');
117
+ const sessionManager = BrowserSessionManager_1.default.getInstance();
118
+ const tools = await sessionManager.initialize(credentials.mcpEndpoint, credentials.browserMode === 'cdp', credentials.cdpEndpoint);
119
+ return tools.map((tool) => ({
120
+ name: tool.name.split('_').map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join(' '),
121
+ value: tool.name,
122
+ }));
123
+ },
124
+ },
125
+ };
126
+ // Expose tools to AI Agent nodes
127
+ async getTools() {
128
+ const credentials = await this.getCredentials('smartBrowserAutomationApi');
129
+ return await (0, DynamicBrowserTools_1.createDynamicBrowserTools)(credentials);
130
+ }
131
+ async execute() {
132
+ const items = this.getInputData();
133
+ const returnData = [];
134
+ const credentials = await this.getCredentials('smartBrowserAutomationApi');
135
+ const sessionManager = BrowserSessionManager_1.default.getInstance();
136
+ const mode = this.getNodeParameter('mode', 0);
137
+ for (let i = 0; i < items.length; i++) {
138
+ try {
139
+ if (mode === 'manual') {
140
+ // Manual mode: User selects tool and provides arguments
141
+ const toolName = this.getNodeParameter('toolName', i);
142
+ const toolArgsStr = this.getNodeParameter('toolArgs', i);
143
+ const verbose = this.getNodeParameter('verbose', i, false);
144
+ // Initialize session if not ready
145
+ if (!sessionManager.isReady()) {
146
+ await sessionManager.initialize(credentials.mcpEndpoint, credentials.browserMode === 'cdp', credentials.cdpEndpoint);
147
+ }
148
+ let toolArgs;
149
+ try {
150
+ toolArgs = JSON.parse(toolArgsStr);
151
+ }
152
+ catch (error) {
153
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Invalid JSON in Tool Arguments: ${error.message} `);
154
+ }
155
+ if (verbose) {
156
+ console.log(`Executing tool: ${toolName} with args: `, toolArgs);
157
+ }
158
+ const result = await sessionManager.callTool(toolName, toolArgs);
159
+ returnData.push({
160
+ json: {
161
+ success: true,
162
+ tool: toolName,
163
+ result,
164
+ },
165
+ pairedItem: i,
166
+ });
167
+ }
168
+ else {
169
+ // AI Agent mode: Just initialize or close
170
+ const operation = this.getNodeParameter('operation', i);
171
+ if (operation === 'initialize') {
172
+ const tools = await sessionManager.initialize(credentials.mcpEndpoint, credentials.browserMode === 'cdp', credentials.cdpEndpoint);
173
+ returnData.push({
174
+ json: {
175
+ success: true,
176
+ message: 'Browser session initialized. Tools are now available to AI Agent.',
177
+ toolsCount: tools.length,
178
+ tools: tools.map((t) => ({
179
+ name: t.name,
180
+ description: t.description
181
+ })),
182
+ },
183
+ pairedItem: i,
184
+ });
185
+ }
186
+ else if (operation === 'close') {
187
+ await sessionManager.close();
188
+ returnData.push({
189
+ json: {
190
+ success: true,
191
+ message: 'Browser session closed',
192
+ },
193
+ pairedItem: i,
194
+ });
195
+ }
196
+ }
197
+ }
198
+ catch (error) {
199
+ if (this.continueOnFail()) {
200
+ returnData.push({
201
+ json: {
202
+ success: false,
203
+ error: error.message
204
+ },
205
+ pairedItem: i,
206
+ });
207
+ }
208
+ else {
209
+ throw error;
210
+ }
211
+ }
212
+ }
213
+ return [returnData];
214
+ }
215
+ }
216
+ exports.SmartBrowserAutomation = SmartBrowserAutomation;
@@ -0,0 +1 @@
1
+ export declare function createDynamicBrowserTools(credentials: any): Promise<any[]>;
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createDynamicBrowserTools = createDynamicBrowserTools;
7
+ const BrowserSessionManager_1 = __importDefault(require("../BrowserSessionManager"));
8
+ // Convert MCP tool schema to n8n properties
9
+ function mcpSchemaToN8nProperties(mcpSchema) {
10
+ const properties = [];
11
+ if (!mcpSchema || !mcpSchema.properties) {
12
+ return properties;
13
+ }
14
+ for (const [key, value] of Object.entries(mcpSchema.properties)) {
15
+ const prop = value;
16
+ const nodeProperty = {
17
+ displayName: key.charAt(0).toUpperCase() + key.slice(1).replace(/_/g, ' '),
18
+ name: key,
19
+ type: 'string',
20
+ default: '',
21
+ description: prop.description || '',
22
+ required: mcpSchema.required?.includes(key) || false,
23
+ };
24
+ // Map types from JSON Schema to n8n types
25
+ if (prop.type === 'boolean') {
26
+ nodeProperty.type = 'boolean';
27
+ nodeProperty.default = false;
28
+ }
29
+ else if (prop.type === 'number' || prop.type === 'integer') {
30
+ nodeProperty.type = 'number';
31
+ nodeProperty.default = 0;
32
+ }
33
+ else if (prop.type === 'object' || prop.type === 'array') {
34
+ nodeProperty.type = 'json';
35
+ nodeProperty.default = prop.type === 'array' ? '[]' : '{}';
36
+ }
37
+ // Handle enums
38
+ if (prop.enum && Array.isArray(prop.enum)) {
39
+ nodeProperty.type = 'options';
40
+ nodeProperty.options = prop.enum.map((val) => ({
41
+ name: String(val),
42
+ value: val,
43
+ }));
44
+ }
45
+ properties.push(nodeProperty);
46
+ }
47
+ return properties;
48
+ }
49
+ // Create n8n tool instances from MCP tools
50
+ async function createDynamicBrowserTools(credentials) {
51
+ const sessionManager = BrowserSessionManager_1.default.getInstance();
52
+ // Initialize and get MCP tools
53
+ const mcpTools = await sessionManager.initialize(credentials.mcpEndpoint, credentials.browserMode === 'cdp', credentials.cdpEndpoint);
54
+ // Create n8n tool for each MCP tool
55
+ const n8nTools = mcpTools.map((mcpTool) => {
56
+ const toolName = mcpTool.name;
57
+ const displayName = toolName
58
+ .split('_')
59
+ .map((s) => s.charAt(0).toUpperCase() + s.slice(1))
60
+ .join(' ');
61
+ return {
62
+ name: toolName,
63
+ displayName: displayName,
64
+ description: mcpTool.description || `Execute ${displayName} browser action`,
65
+ properties: mcpSchemaToN8nProperties(mcpTool.inputSchema),
66
+ async execute(toolInput) {
67
+ try {
68
+ const result = await sessionManager.callTool(toolName, toolInput);
69
+ return {
70
+ success: true,
71
+ result: JSON.stringify(result, null, 2),
72
+ };
73
+ }
74
+ catch (error) {
75
+ return {
76
+ success: false,
77
+ error: error.message || 'Unknown error occurred',
78
+ };
79
+ }
80
+ }
81
+ };
82
+ });
83
+ return n8nTools;
84
+ }
package/package.json ADDED
@@ -0,0 +1,59 @@
1
+ {
2
+ "name": "n8n-nodes-smart-browser-automation",
3
+ "version": "1.0.0",
4
+ "description": "n8n node for AI-driven browser automation using MCP",
5
+ "keywords": [
6
+ "n8n-community-node-package",
7
+ "browser-automation",
8
+ "ai",
9
+ "mcp",
10
+ "playwright"
11
+ ],
12
+ "license": "MIT",
13
+ "homepage": "https://github.com/Ejazullah42/n8n-nodes-smart-browser-automation",
14
+ "author": {
15
+ "name": "Ejaz Ullah",
16
+ "email": "ejaz@doinger.com"
17
+ },
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/Ejazullah42/n8n-nodes-smart-browser-automation.git"
21
+ },
22
+ "main": "index.js",
23
+ "scripts": {
24
+ "build": "tsc && gulp build:icons",
25
+ "dev": "tsc --watch",
26
+ "format": "prettier nodes credentials --write",
27
+ "lint": "eslint \"nodes/**/*.ts\" \"credentials/**/*.ts\"",
28
+ "lintfix": "eslint \"nodes/**/*.ts\" \"credentials/**/*.ts\" --fix",
29
+ "prepublishOnly": "npm run build && npm run lint"
30
+ },
31
+ "files": [
32
+ "dist"
33
+ ],
34
+ "n8n": {
35
+ "n8nNodesApiVersion": 1,
36
+ "credentials": [
37
+ "dist/credentials/SmartBrowserAutomationApi.credentials.js"
38
+ ],
39
+ "nodes": [
40
+ "dist/nodes/SmartBrowserAutomation/SmartBrowserAutomation.node.js"
41
+ ]
42
+ },
43
+ "devDependencies": {
44
+ "@types/node": "^20.10.0",
45
+ "@typescript-eslint/parser": "^6.13.0",
46
+ "eslint": "^8.55.0",
47
+ "eslint-plugin-n8n-nodes-base": "^1.16.1",
48
+ "gulp": "^4.0.2",
49
+ "n8n-workflow": "^1.0.0",
50
+ "prettier": "^3.1.0",
51
+ "typescript": "^5.3.0"
52
+ },
53
+ "peerDependencies": {
54
+ "n8n-workflow": "*"
55
+ },
56
+ "dependencies": {
57
+ "@modelcontextprotocol/sdk": "^1.17.0"
58
+ }
59
+ }