puppeteer-mcp-claude 0.0.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 jaenster
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,279 @@
1
+ # MCP Puppeteer Server
2
+
3
+ A Model Context Protocol (MCP) server that provides Claude Code with comprehensive browser automation capabilities through Puppeteer. This server allows Claude to interact with web pages, take screenshots, execute JavaScript, and perform various browser automation tasks.
4
+
5
+ ## Features
6
+
7
+ - **Browser Management**: Launch and close Chrome/Chromium browsers
8
+ - **Page Operations**: Create, navigate, and manage multiple browser tabs
9
+ - **Element Interaction**: Click, type, and extract text from web elements
10
+ - **JavaScript Execution**: Run custom JavaScript code in the browser context
11
+ - **Screenshot Capture**: Take full-page or viewport screenshots
12
+ - **Selector Waiting**: Wait for elements to appear with configurable timeouts
13
+ - **Multi-page Support**: Manage multiple browser tabs simultaneously
14
+
15
+ ## Available Tools
16
+
17
+ | Tool | Description |
18
+ |------|-------------|
19
+ | `puppeteer_launch` | Launch a new browser instance |
20
+ | `puppeteer_new_page` | Create a new browser tab |
21
+ | `puppeteer_navigate` | Navigate to a URL |
22
+ | `puppeteer_click` | Click on an element |
23
+ | `puppeteer_type` | Type text into an input field |
24
+ | `puppeteer_get_text` | Extract text from an element |
25
+ | `puppeteer_screenshot` | Take a screenshot |
26
+ | `puppeteer_evaluate` | Execute JavaScript code |
27
+ | `puppeteer_wait_for_selector` | Wait for an element to appear |
28
+ | `puppeteer_close_page` | Close a specific tab |
29
+ | `puppeteer_close_browser` | Close the entire browser |
30
+
31
+ ## Installation
32
+
33
+ ### Quick Install (Recommended)
34
+
35
+ Install and configure for Claude Code in one command:
36
+
37
+ ```bash
38
+ npx puppeteer-mcp-claude install
39
+ ```
40
+
41
+ That's it! The installer will:
42
+ - Download and install the package
43
+ - Automatically configure Claude Code
44
+ - Verify the installation
45
+ - Provide next steps
46
+
47
+ ### Manual Installation
48
+
49
+ If you prefer to install manually:
50
+
51
+ 1. **Install the package globally**:
52
+ ```bash
53
+ npm install -g puppeteer-mcp-claude
54
+ ```
55
+
56
+ 2. **Configure for Claude Code**:
57
+ ```bash
58
+ puppeteer-mcp-claude install
59
+ ```
60
+
61
+ ### Development Installation
62
+
63
+ For development or contribution:
64
+
65
+ 1. **Clone and install dependencies**:
66
+ ```bash
67
+ git clone https://github.com/jaenster/puppeteer-mcp-claude.git
68
+ cd puppeteer-mcp-claude
69
+ npm install
70
+ ```
71
+
72
+ 2. **Build the project**:
73
+ ```bash
74
+ npm run build
75
+ ```
76
+
77
+ 3. **Use local setup script**:
78
+ ```bash
79
+ npm run setup-mcp
80
+ ```
81
+
82
+ ## Management Commands
83
+
84
+ | Command | Description |
85
+ |---------|-------------|
86
+ | `npx puppeteer-mcp-claude install` | Install and configure for Claude Code |
87
+ | `npx puppeteer-mcp-claude uninstall` | Remove from Claude Code |
88
+ | `npx puppeteer-mcp-claude status` | Check installation status |
89
+ | `npx puppeteer-mcp-claude help` | Show help and available tools |
90
+
91
+ ## Alternative Installation Methods
92
+
93
+ ### Method 1: Using Claude Code MCP Command
94
+
95
+ You can also configure this server using Claude Code's built-in MCP management:
96
+
97
+ ```bash
98
+ claude mcp add puppeteer-mcp-claude
99
+ ```
100
+
101
+ ### Method 2: Manual Configuration
102
+
103
+ Create or edit `~/.claude/claude_desktop_config.json`:
104
+ ```json
105
+ {
106
+ "mcpServers": {
107
+ "puppeteer-mcp-claude": {
108
+ "command": "npx",
109
+ "args": ["puppeteer-mcp-claude", "serve"],
110
+ "env": {
111
+ "NODE_ENV": "production"
112
+ }
113
+ }
114
+ }
115
+ }
116
+ ```
117
+
118
+ ## Post-Installation Steps
119
+
120
+ 1. **Restart Claude Code** if it's currently running
121
+ 2. **Test the integration**:
122
+ ```bash
123
+ npm run test:integration
124
+ ```
125
+ 3. **Verify in Claude Code** by asking: "List all available tools"
126
+
127
+ You should see the Puppeteer tools listed among the available tools.
128
+
129
+ ## Usage Examples
130
+
131
+ ### Basic Web Automation
132
+ ```javascript
133
+ // Launch browser
134
+ await puppeteer_launch({ headless: false });
135
+
136
+ // Create a new page
137
+ await puppeteer_new_page({ pageId: "main" });
138
+
139
+ // Navigate to a website
140
+ await puppeteer_navigate({
141
+ pageId: "main",
142
+ url: "https://example.com"
143
+ });
144
+
145
+ // Take a screenshot
146
+ await puppeteer_screenshot({
147
+ pageId: "main",
148
+ path: "screenshot.png"
149
+ });
150
+ ```
151
+
152
+ ### Form Interaction
153
+ ```javascript
154
+ // Type into a search field
155
+ await puppeteer_type({
156
+ pageId: "main",
157
+ selector: "input[name='search']",
158
+ text: "Claude AI"
159
+ });
160
+
161
+ // Click a button
162
+ await puppeteer_click({
163
+ pageId: "main",
164
+ selector: "button[type='submit']"
165
+ });
166
+
167
+ // Wait for results to load
168
+ await puppeteer_wait_for_selector({
169
+ pageId: "main",
170
+ selector: ".search-results"
171
+ });
172
+ ```
173
+
174
+ ### Data Extraction
175
+ ```javascript
176
+ // Extract text from an element
177
+ await puppeteer_get_text({
178
+ pageId: "main",
179
+ selector: "h1"
180
+ });
181
+
182
+ // Execute custom JavaScript
183
+ await puppeteer_evaluate({
184
+ pageId: "main",
185
+ script: "document.querySelectorAll('a').length"
186
+ });
187
+ ```
188
+
189
+ ## Configuration Options
190
+
191
+ ### Browser Launch Options
192
+ - `headless`: Run browser in headless mode (default: true)
193
+ - `args`: Array of Chrome arguments (e.g., `["--disable-web-security"]`)
194
+
195
+ ### Navigation Options
196
+ - `waitUntil`: Wait condition for navigation
197
+ - `load`: Wait for load event
198
+ - `domcontentloaded`: Wait for DOM content loaded
199
+ - `networkidle0`: Wait for no network activity
200
+ - `networkidle2`: Wait for max 2 network connections
201
+
202
+ ### Screenshot Options
203
+ - `path`: File path to save screenshot
204
+ - `fullPage`: Capture full page scroll height (default: false)
205
+
206
+ ## Management Commands
207
+
208
+ | Command | Description |
209
+ |---------|-------------|
210
+ | `npm run setup-mcp` | Automatically configure MCP server |
211
+ | `npm run remove-mcp` | Remove MCP server configuration |
212
+ | `npm run status-mcp` | Check current configuration status |
213
+ | `npm run test:integration` | Test the MCP server integration |
214
+
215
+ ## Troubleshooting
216
+
217
+ ### Common Issues
218
+
219
+ 1. **Claude Code doesn't see the tools**:
220
+ - Ensure Claude Code is restarted after configuration
221
+ - Check that the path in `claude_desktop_config.json` is correct
222
+ - Verify the MCP server is configured properly with `npm run status-mcp`
223
+
224
+ 2. **"Browser not launched" errors**:
225
+ - Always call `puppeteer_launch` before using other tools
226
+ - Make sure the browser launch was successful
227
+
228
+ 3. **Element not found errors**:
229
+ - Use `puppeteer_wait_for_selector` before interacting with elements
230
+ - Verify selectors are correct using browser developer tools
231
+
232
+ 4. **Permission errors**:
233
+ - Make sure the project directory has proper permissions
234
+ - Check that `ts-node` is installed and accessible
235
+
236
+ ### Debug Mode
237
+
238
+ For debugging, you can run the server in development mode:
239
+ ```bash
240
+ npm run dev
241
+ ```
242
+
243
+ This will show detailed logs of all MCP operations.
244
+
245
+ ### Testing
246
+
247
+ Run the test suite to verify everything is working:
248
+ ```bash
249
+ npm test
250
+ ```
251
+
252
+ For integration testing with Claude Code:
253
+ ```bash
254
+ npm run test:integration
255
+ ```
256
+
257
+ ## Security Considerations
258
+
259
+ - The server runs with the same permissions as the user
260
+ - Browser instances are automatically cleaned up on exit
261
+ - All JavaScript execution happens in the browser context, not the Node.js process
262
+ - Network requests are subject to the same security policies as a regular Chrome browser
263
+
264
+ ## Requirements
265
+
266
+ - Node.js 16 or higher
267
+ - Chrome/Chromium browser (automatically downloaded by Puppeteer)
268
+ - Claude Code with MCP support
269
+ - TypeScript support (`ts-node`)
270
+
271
+ ## Support
272
+
273
+ If you encounter issues:
274
+ 1. Check the troubleshooting section above
275
+ 2. Verify your configuration with `npm run status-mcp`
276
+ 3. Run the integration tests with `npm run test:integration`
277
+ 4. Check Claude Code logs for MCP-related errors
278
+
279
+ For additional help, refer to the [Claude Code MCP documentation](https://docs.anthropic.com/en/docs/claude-code/mcp).
package/bin/cli.js ADDED
@@ -0,0 +1,326 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { execSync, spawn } = require('child_process');
4
+ const { readFileSync, writeFileSync, existsSync, mkdirSync } = require('fs');
5
+ const { join } = require('path');
6
+ const { homedir } = require('os');
7
+ const path = require('path');
8
+
9
+ class PuppeteerMCPInstaller {
10
+ constructor() {
11
+ this.packageDir = path.dirname(__dirname);
12
+ this.claudeConfigPath = join(homedir(), '.claude', 'claude_desktop_config.json');
13
+ this.serverName = 'puppeteer-mcp-claude';
14
+ }
15
+
16
+ async install() {
17
+ console.log('🚀 Installing Puppeteer MCP Claude...\n');
18
+
19
+ try {
20
+ await this.ensureClaudeDirectory();
21
+ await this.updateClaudeConfig();
22
+ await this.verifyInstallation();
23
+
24
+ console.log('\n✅ Puppeteer MCP Claude installed successfully!');
25
+ console.log('\n📋 Next steps:');
26
+ console.log(' 1. Restart Claude Code if it\'s running');
27
+ console.log(' 2. In Claude Code, ask: "List all available tools"');
28
+ console.log(' 3. You should see puppeteer tools listed');
29
+ console.log('\n🔧 Management commands:');
30
+ console.log(' npx puppeteer-mcp-claude uninstall # Remove from Claude Code');
31
+ console.log(' npx puppeteer-mcp-claude status # Check installation status');
32
+ console.log('\n📖 Documentation: https://github.com/jaenster/puppeteer-mcp-claude');
33
+
34
+ } catch (error) {
35
+ console.error('❌ Installation failed:', error.message);
36
+ process.exit(1);
37
+ }
38
+ }
39
+
40
+ async uninstall() {
41
+ console.log('🗑️ Uninstalling Puppeteer MCP Claude...\n');
42
+
43
+ if (!existsSync(this.claudeConfigPath)) {
44
+ console.log('⚠️ No Claude Code configuration found');
45
+ return;
46
+ }
47
+
48
+ try {
49
+ const configContent = readFileSync(this.claudeConfigPath, 'utf8');
50
+ const config = JSON.parse(configContent);
51
+
52
+ if (config.mcpServers?.[this.serverName]) {
53
+ delete config.mcpServers[this.serverName];
54
+ writeFileSync(this.claudeConfigPath, JSON.stringify(config, null, 2));
55
+ console.log('✅ Puppeteer MCP Claude removed from Claude Code configuration');
56
+ console.log(' Restart Claude Code to complete removal');
57
+ } else {
58
+ console.log('⚠️ Puppeteer MCP Claude was not found in configuration');
59
+ }
60
+ } catch (error) {
61
+ console.error('❌ Failed to remove configuration:', error.message);
62
+ }
63
+ }
64
+
65
+ async status() {
66
+ console.log('📊 Puppeteer MCP Claude Status\n');
67
+
68
+ if (!existsSync(this.claudeConfigPath)) {
69
+ console.log('❌ No Claude Code configuration found');
70
+ console.log(' Run: npx puppeteer-mcp-claude install');
71
+ return;
72
+ }
73
+
74
+ try {
75
+ const configContent = readFileSync(this.claudeConfigPath, 'utf8');
76
+ const config = JSON.parse(configContent);
77
+
78
+ if (config.mcpServers?.[this.serverName]) {
79
+ console.log('✅ Puppeteer MCP Claude is installed');
80
+ console.log('\n📋 Configuration:');
81
+ const serverConfig = config.mcpServers[this.serverName];
82
+ console.log(` Command: ${serverConfig.command}`);
83
+ console.log(` Args: ${serverConfig.args?.join(' ') || 'none'}`);
84
+ console.log(` Working Directory: ${serverConfig.cwd || 'not set'}`);
85
+ console.log(` Environment: ${JSON.stringify(serverConfig.env || {})}`);
86
+
87
+ // Check if the server executable exists
88
+ if (serverConfig.cwd && existsSync(join(serverConfig.cwd, 'dist', 'index.js'))) {
89
+ console.log('✅ Server executable found');
90
+ } else {
91
+ console.log('⚠️ Server executable not found - may need to rebuild');
92
+ }
93
+ } else {
94
+ console.log('❌ Puppeteer MCP Claude is not installed');
95
+ console.log(' Run: npx puppeteer-mcp-claude install');
96
+ }
97
+
98
+ // Show all MCP servers
99
+ if (config.mcpServers && Object.keys(config.mcpServers).length > 0) {
100
+ console.log('\n📋 All configured MCP servers:');
101
+ Object.keys(config.mcpServers).forEach(serverName => {
102
+ const isOurs = serverName === this.serverName ? ' ← (this package)' : '';
103
+ console.log(` • ${serverName}${isOurs}`);
104
+ });
105
+ }
106
+
107
+ } catch (error) {
108
+ console.error('❌ Failed to read configuration:', error.message);
109
+ }
110
+ }
111
+
112
+ async ensureClaudeDirectory() {
113
+ const claudeDir = join(homedir(), '.claude');
114
+
115
+ if (!existsSync(claudeDir)) {
116
+ console.log('📁 Creating .claude directory...');
117
+ mkdirSync(claudeDir, { recursive: true });
118
+ }
119
+
120
+ console.log('✅ Claude directory ready');
121
+ }
122
+
123
+ async updateClaudeConfig() {
124
+ console.log('📝 Updating Claude Code configuration...');
125
+
126
+ let config = {};
127
+ let hasExistingConfig = false;
128
+
129
+ // Read existing config if it exists
130
+ if (existsSync(this.claudeConfigPath)) {
131
+ try {
132
+ const configContent = readFileSync(this.claudeConfigPath, 'utf8');
133
+ config = JSON.parse(configContent);
134
+ hasExistingConfig = true;
135
+ console.log('📖 Found existing configuration');
136
+ } catch (error) {
137
+ console.log('⚠️ Could not parse existing config, creating new one');
138
+ config = {};
139
+ }
140
+ }
141
+
142
+ // Initialize mcpServers if it doesn't exist
143
+ if (!config.mcpServers) {
144
+ config.mcpServers = {};
145
+ }
146
+
147
+ // Check if server already exists
148
+ if (config.mcpServers[this.serverName]) {
149
+ console.log('⚠️ Puppeteer MCP Claude already configured');
150
+ console.log(' Updating existing configuration...');
151
+ }
152
+
153
+ // Get the globally installed package location
154
+ const globalPackageDir = this.getGlobalPackageDir();
155
+
156
+ // Add/update our MCP server configuration
157
+ config.mcpServers[this.serverName] = {
158
+ command: 'npx',
159
+ args: ['puppeteer-mcp-claude', 'serve'],
160
+ env: {
161
+ NODE_ENV: 'production'
162
+ }
163
+ };
164
+
165
+ // Write the updated configuration
166
+ writeFileSync(this.claudeConfigPath, JSON.stringify(config, null, 2));
167
+
168
+ if (hasExistingConfig) {
169
+ console.log('✅ Configuration updated');
170
+ } else {
171
+ console.log('✅ Configuration created');
172
+ }
173
+ }
174
+
175
+ getGlobalPackageDir() {
176
+ try {
177
+ // Try to get the package directory from npm
178
+ const npmRoot = execSync('npm root -g', { encoding: 'utf8' }).trim();
179
+ const packagePath = join(npmRoot, 'puppeteer-mcp-claude');
180
+
181
+ if (existsSync(packagePath)) {
182
+ return packagePath;
183
+ }
184
+ } catch (error) {
185
+ // Fallback: use the current package directory
186
+ console.log('⚠️ Using local package directory as fallback');
187
+ }
188
+
189
+ return this.packageDir;
190
+ }
191
+
192
+ async verifyInstallation() {
193
+ console.log('🔍 Verifying installation...');
194
+
195
+ // Check if config file exists and is valid
196
+ if (!existsSync(this.claudeConfigPath)) {
197
+ throw new Error('Configuration file was not created');
198
+ }
199
+
200
+ try {
201
+ const configContent = readFileSync(this.claudeConfigPath, 'utf8');
202
+ const config = JSON.parse(configContent);
203
+
204
+ if (!config.mcpServers?.[this.serverName]) {
205
+ throw new Error('Puppeteer MCP Claude not found in configuration');
206
+ }
207
+
208
+ const serverConfig = config.mcpServers[this.serverName];
209
+
210
+ // Verify configuration structure
211
+ if (!serverConfig.command || !serverConfig.args) {
212
+ throw new Error('Incomplete MCP server configuration');
213
+ }
214
+
215
+ // Verify server configuration (skip path check for npx commands)
216
+ let serverInfo = '';
217
+ if (serverConfig.command === 'npx' && serverConfig.args[0] === 'puppeteer-mcp-claude') {
218
+ // For npx commands, we just verify the structure is correct
219
+ console.log('✅ NPX configuration verified');
220
+ serverInfo = `${serverConfig.command} ${serverConfig.args.join(' ')}`;
221
+ } else {
222
+ // For direct paths, check if the file exists
223
+ const serverPath = serverConfig.args[0];
224
+ if (!existsSync(serverPath)) {
225
+ throw new Error(`Server executable not found at: ${serverPath}`);
226
+ }
227
+ console.log(`✅ Server executable found: ${serverPath}`);
228
+ serverInfo = serverPath;
229
+ }
230
+
231
+ console.log('✅ Installation verified');
232
+ console.log(` Server: ${serverInfo}`);
233
+
234
+ } catch (error) {
235
+ throw new Error(`Installation verification failed: ${error.message}`);
236
+ }
237
+ }
238
+
239
+ async serve() {
240
+ // Start the MCP server
241
+ const serverPath = join(this.packageDir, 'dist', 'index.js');
242
+ if (!existsSync(serverPath)) {
243
+ console.error('❌ Server executable not found. Please ensure the package is built properly.');
244
+ process.exit(1);
245
+ }
246
+
247
+ // Execute the server
248
+ const server = spawn('node', [serverPath], {
249
+ stdio: 'inherit',
250
+ cwd: this.packageDir
251
+ });
252
+
253
+ server.on('error', (error) => {
254
+ console.error('❌ Failed to start server:', error);
255
+ process.exit(1);
256
+ });
257
+
258
+ server.on('exit', (code) => {
259
+ process.exit(code);
260
+ });
261
+ }
262
+
263
+ showHelp() {
264
+ console.log('🤖 Puppeteer MCP Claude - Browser Automation for Claude Code\n');
265
+ console.log('Usage:');
266
+ console.log(' npx puppeteer-mcp-claude install # Install MCP server for Claude Code');
267
+ console.log(' npx puppeteer-mcp-claude uninstall # Remove MCP server from Claude Code');
268
+ console.log(' npx puppeteer-mcp-claude status # Check installation status');
269
+ console.log(' npx puppeteer-mcp-claude serve # Start the MCP server (used internally)');
270
+ console.log(' npx puppeteer-mcp-claude help # Show this help message');
271
+ console.log('\nAvailable Browser Tools:');
272
+ console.log(' • puppeteer_launch - Launch browser instance');
273
+ console.log(' • puppeteer_new_page - Create new browser tab');
274
+ console.log(' • puppeteer_navigate - Navigate to URL');
275
+ console.log(' • puppeteer_click - Click elements');
276
+ console.log(' • puppeteer_type - Type text into inputs');
277
+ console.log(' • puppeteer_get_text - Extract text from elements');
278
+ console.log(' • puppeteer_screenshot - Capture screenshots');
279
+ console.log(' • puppeteer_evaluate - Execute JavaScript');
280
+ console.log(' • puppeteer_wait_for_selector - Wait for elements');
281
+ console.log(' • puppeteer_close_page - Close browser tab');
282
+ console.log(' • puppeteer_close_browser - Close entire browser');
283
+ console.log('\nDocumentation: https://github.com/jaenster/puppeteer-mcp-claude');
284
+ console.log('Issues: https://github.com/jaenster/puppeteer-mcp-claude/issues');
285
+ }
286
+ }
287
+
288
+ // CLI interface
289
+ async function main() {
290
+ const command = process.argv[2];
291
+ const installer = new PuppeteerMCPInstaller();
292
+
293
+ switch (command) {
294
+ case 'install':
295
+ await installer.install();
296
+ break;
297
+ case 'uninstall':
298
+ await installer.uninstall();
299
+ break;
300
+ case 'status':
301
+ await installer.status();
302
+ break;
303
+ case 'serve':
304
+ await installer.serve();
305
+ break;
306
+ case 'help':
307
+ case '--help':
308
+ case '-h':
309
+ installer.showHelp();
310
+ break;
311
+ default:
312
+ if (!command) {
313
+ installer.showHelp();
314
+ } else {
315
+ console.error(`Unknown command: ${command}`);
316
+ console.log('Run "npx puppeteer-mcp-claude help" for usage information.');
317
+ process.exit(1);
318
+ }
319
+ break;
320
+ }
321
+ }
322
+
323
+ main().catch(error => {
324
+ console.error('❌ Error:', error.message);
325
+ process.exit(1);
326
+ });
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,411 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
8
+ const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
9
+ const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
10
+ const puppeteer_1 = __importDefault(require("puppeteer"));
11
+ class PuppeteerMCPServer {
12
+ server;
13
+ browser = null;
14
+ pages = new Map();
15
+ constructor() {
16
+ this.server = new index_js_1.Server({
17
+ name: 'mcp-puppeteer',
18
+ version: '1.0.0',
19
+ }, {
20
+ capabilities: {
21
+ tools: {},
22
+ },
23
+ });
24
+ this.setupToolHandlers();
25
+ this.setupErrorHandling();
26
+ }
27
+ setupErrorHandling() {
28
+ this.server.onerror = (error) => console.error('[MCP Error]', error);
29
+ process.on('SIGINT', async () => {
30
+ await this.cleanup();
31
+ process.exit(0);
32
+ });
33
+ }
34
+ async cleanup() {
35
+ if (this.browser) {
36
+ await this.browser.close();
37
+ }
38
+ }
39
+ setupToolHandlers() {
40
+ this.server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => {
41
+ return {
42
+ tools: [
43
+ {
44
+ name: 'puppeteer_launch',
45
+ description: 'Launch a new Puppeteer browser instance',
46
+ inputSchema: {
47
+ type: 'object',
48
+ properties: {
49
+ headless: { type: 'boolean', default: true },
50
+ args: { type: 'array', items: { type: 'string' } },
51
+ },
52
+ },
53
+ },
54
+ {
55
+ name: 'puppeteer_new_page',
56
+ description: 'Create a new page in the browser',
57
+ inputSchema: {
58
+ type: 'object',
59
+ properties: {
60
+ pageId: { type: 'string', description: 'Unique identifier for the page' },
61
+ },
62
+ required: ['pageId'],
63
+ },
64
+ },
65
+ {
66
+ name: 'puppeteer_navigate',
67
+ description: 'Navigate to a URL',
68
+ inputSchema: {
69
+ type: 'object',
70
+ properties: {
71
+ pageId: { type: 'string' },
72
+ url: { type: 'string' },
73
+ waitUntil: { type: 'string', enum: ['load', 'domcontentloaded', 'networkidle0', 'networkidle2'] },
74
+ },
75
+ required: ['pageId', 'url'],
76
+ },
77
+ },
78
+ {
79
+ name: 'puppeteer_click',
80
+ description: 'Click on an element',
81
+ inputSchema: {
82
+ type: 'object',
83
+ properties: {
84
+ pageId: { type: 'string' },
85
+ selector: { type: 'string' },
86
+ },
87
+ required: ['pageId', 'selector'],
88
+ },
89
+ },
90
+ {
91
+ name: 'puppeteer_type',
92
+ description: 'Type text into an element',
93
+ inputSchema: {
94
+ type: 'object',
95
+ properties: {
96
+ pageId: { type: 'string' },
97
+ selector: { type: 'string' },
98
+ text: { type: 'string' },
99
+ },
100
+ required: ['pageId', 'selector', 'text'],
101
+ },
102
+ },
103
+ {
104
+ name: 'puppeteer_get_text',
105
+ description: 'Get text content from an element',
106
+ inputSchema: {
107
+ type: 'object',
108
+ properties: {
109
+ pageId: { type: 'string' },
110
+ selector: { type: 'string' },
111
+ },
112
+ required: ['pageId', 'selector'],
113
+ },
114
+ },
115
+ {
116
+ name: 'puppeteer_screenshot',
117
+ description: 'Take a screenshot of the page',
118
+ inputSchema: {
119
+ type: 'object',
120
+ properties: {
121
+ pageId: { type: 'string' },
122
+ path: { type: 'string' },
123
+ fullPage: { type: 'boolean', default: false },
124
+ },
125
+ required: ['pageId'],
126
+ },
127
+ },
128
+ {
129
+ name: 'puppeteer_evaluate',
130
+ description: 'Execute JavaScript in the page context',
131
+ inputSchema: {
132
+ type: 'object',
133
+ properties: {
134
+ pageId: { type: 'string' },
135
+ script: { type: 'string' },
136
+ },
137
+ required: ['pageId', 'script'],
138
+ },
139
+ },
140
+ {
141
+ name: 'puppeteer_wait_for_selector',
142
+ description: 'Wait for a selector to appear',
143
+ inputSchema: {
144
+ type: 'object',
145
+ properties: {
146
+ pageId: { type: 'string' },
147
+ selector: { type: 'string' },
148
+ timeout: { type: 'number', default: 30000 },
149
+ },
150
+ required: ['pageId', 'selector'],
151
+ },
152
+ },
153
+ {
154
+ name: 'puppeteer_close_page',
155
+ description: 'Close a specific page',
156
+ inputSchema: {
157
+ type: 'object',
158
+ properties: {
159
+ pageId: { type: 'string' },
160
+ },
161
+ required: ['pageId'],
162
+ },
163
+ },
164
+ {
165
+ name: 'puppeteer_close_browser',
166
+ description: 'Close the browser and all pages',
167
+ inputSchema: {
168
+ type: 'object',
169
+ properties: {},
170
+ },
171
+ },
172
+ ],
173
+ };
174
+ });
175
+ this.server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
176
+ const { name, arguments: args } = request.params;
177
+ try {
178
+ switch (name) {
179
+ case 'puppeteer_launch':
180
+ return await this.handleLaunch(args);
181
+ case 'puppeteer_new_page':
182
+ return await this.handleNewPage(args);
183
+ case 'puppeteer_navigate':
184
+ return await this.handleNavigate(args);
185
+ case 'puppeteer_click':
186
+ return await this.handleClick(args);
187
+ case 'puppeteer_type':
188
+ return await this.handleType(args);
189
+ case 'puppeteer_get_text':
190
+ return await this.handleGetText(args);
191
+ case 'puppeteer_screenshot':
192
+ return await this.handleScreenshot(args);
193
+ case 'puppeteer_evaluate':
194
+ return await this.handleEvaluate(args);
195
+ case 'puppeteer_wait_for_selector':
196
+ return await this.handleWaitForSelector(args);
197
+ case 'puppeteer_close_page':
198
+ return await this.handleClosePage(args);
199
+ case 'puppeteer_close_browser':
200
+ return await this.handleCloseBrowser(args);
201
+ default:
202
+ throw new Error(`Unknown tool: ${name}`);
203
+ }
204
+ }
205
+ catch (error) {
206
+ return {
207
+ content: [
208
+ {
209
+ type: 'text',
210
+ text: `Error: ${error instanceof Error ? error.message : String(error)}`,
211
+ },
212
+ ],
213
+ };
214
+ }
215
+ });
216
+ }
217
+ async handleLaunch(args) {
218
+ const { headless = true, args: browserArgs = [] } = args;
219
+ if (this.browser) {
220
+ await this.browser.close();
221
+ }
222
+ this.browser = await puppeteer_1.default.launch({
223
+ headless,
224
+ args: [...browserArgs, '--no-sandbox', '--disable-setuid-sandbox'],
225
+ });
226
+ return {
227
+ content: [
228
+ {
229
+ type: 'text',
230
+ text: 'Browser launched successfully',
231
+ },
232
+ ],
233
+ };
234
+ }
235
+ async handleNewPage(args) {
236
+ const { pageId } = args;
237
+ if (!this.browser) {
238
+ throw new Error('Browser not launched. Call puppeteer_launch first.');
239
+ }
240
+ const page = await this.browser.newPage();
241
+ this.pages.set(pageId, page);
242
+ return {
243
+ content: [
244
+ {
245
+ type: 'text',
246
+ text: `Page ${pageId} created successfully`,
247
+ },
248
+ ],
249
+ };
250
+ }
251
+ async handleNavigate(args) {
252
+ const { pageId, url, waitUntil = 'load' } = args;
253
+ const page = this.pages.get(pageId);
254
+ if (!page) {
255
+ throw new Error(`Page ${pageId} not found`);
256
+ }
257
+ await page.goto(url, { waitUntil });
258
+ return {
259
+ content: [
260
+ {
261
+ type: 'text',
262
+ text: `Navigated to ${url}`,
263
+ },
264
+ ],
265
+ };
266
+ }
267
+ async handleClick(args) {
268
+ const { pageId, selector } = args;
269
+ const page = this.pages.get(pageId);
270
+ if (!page) {
271
+ throw new Error(`Page ${pageId} not found`);
272
+ }
273
+ await page.click(selector);
274
+ return {
275
+ content: [
276
+ {
277
+ type: 'text',
278
+ text: `Clicked on ${selector}`,
279
+ },
280
+ ],
281
+ };
282
+ }
283
+ async handleType(args) {
284
+ const { pageId, selector, text } = args;
285
+ const page = this.pages.get(pageId);
286
+ if (!page) {
287
+ throw new Error(`Page ${pageId} not found`);
288
+ }
289
+ await page.type(selector, text);
290
+ return {
291
+ content: [
292
+ {
293
+ type: 'text',
294
+ text: `Typed "${text}" into ${selector}`,
295
+ },
296
+ ],
297
+ };
298
+ }
299
+ async handleGetText(args) {
300
+ const { pageId, selector } = args;
301
+ const page = this.pages.get(pageId);
302
+ if (!page) {
303
+ throw new Error(`Page ${pageId} not found`);
304
+ }
305
+ const element = await page.$(selector);
306
+ if (!element) {
307
+ throw new Error(`Element ${selector} not found`);
308
+ }
309
+ const text = await page.evaluate((el) => el.textContent, element);
310
+ return {
311
+ content: [
312
+ {
313
+ type: 'text',
314
+ text: `Text from ${selector}: ${text}`,
315
+ },
316
+ ],
317
+ };
318
+ }
319
+ async handleScreenshot(args) {
320
+ const { pageId, path, fullPage = false } = args;
321
+ const page = this.pages.get(pageId);
322
+ if (!page) {
323
+ throw new Error(`Page ${pageId} not found`);
324
+ }
325
+ const screenshot = await page.screenshot({
326
+ path,
327
+ fullPage,
328
+ type: 'png'
329
+ });
330
+ return {
331
+ content: [
332
+ {
333
+ type: 'text',
334
+ text: path ? `Screenshot saved to ${path}` : 'Screenshot taken',
335
+ },
336
+ ],
337
+ };
338
+ }
339
+ async handleEvaluate(args) {
340
+ const { pageId, script } = args;
341
+ const page = this.pages.get(pageId);
342
+ if (!page) {
343
+ throw new Error(`Page ${pageId} not found`);
344
+ }
345
+ const result = await page.evaluate(script);
346
+ return {
347
+ content: [
348
+ {
349
+ type: 'text',
350
+ text: `Script result: ${JSON.stringify(result)}`,
351
+ },
352
+ ],
353
+ };
354
+ }
355
+ async handleWaitForSelector(args) {
356
+ const { pageId, selector, timeout = 30000 } = args;
357
+ const page = this.pages.get(pageId);
358
+ if (!page) {
359
+ throw new Error(`Page ${pageId} not found`);
360
+ }
361
+ await page.waitForSelector(selector, { timeout });
362
+ return {
363
+ content: [
364
+ {
365
+ type: 'text',
366
+ text: `Selector ${selector} appeared`,
367
+ },
368
+ ],
369
+ };
370
+ }
371
+ async handleClosePage(args) {
372
+ const { pageId } = args;
373
+ const page = this.pages.get(pageId);
374
+ if (!page) {
375
+ throw new Error(`Page ${pageId} not found`);
376
+ }
377
+ await page.close();
378
+ this.pages.delete(pageId);
379
+ return {
380
+ content: [
381
+ {
382
+ type: 'text',
383
+ text: `Page ${pageId} closed`,
384
+ },
385
+ ],
386
+ };
387
+ }
388
+ async handleCloseBrowser(args) {
389
+ if (this.browser) {
390
+ await this.browser.close();
391
+ this.browser = null;
392
+ this.pages.clear();
393
+ }
394
+ return {
395
+ content: [
396
+ {
397
+ type: 'text',
398
+ text: 'Browser closed',
399
+ },
400
+ ],
401
+ };
402
+ }
403
+ async run() {
404
+ const transport = new stdio_js_1.StdioServerTransport();
405
+ await this.server.connect(transport);
406
+ console.error('MCP Puppeteer server running on stdio');
407
+ }
408
+ }
409
+ const server = new PuppeteerMCPServer();
410
+ server.run().catch(console.error);
411
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "puppeteer-mcp-claude",
3
+ "version": "0.0.1",
4
+ "main": "dist/index.js",
5
+ "bin": {
6
+ "puppeteer-mcp-claude": "./bin/cli.js"
7
+ },
8
+ "files": [
9
+ "dist/",
10
+ "bin/",
11
+ "README.md",
12
+ "LICENSE"
13
+ ],
14
+ "scripts": {
15
+ "build": "tsc",
16
+ "start": "node dist/index.js",
17
+ "dev": "ts-node src/index.ts",
18
+ "test": "ts-node tests/e2e.ts",
19
+ "test:integration": "ts-node tests/claude-integration.ts",
20
+ "test:claude": "ts-node tests/claude-simple-test.ts",
21
+ "test:real": "ts-node tests/real-claude-test.ts",
22
+ "test:console": "ts-node tests/console-claude-test.ts",
23
+ "setup-mcp": "ts-node scripts/setup-mcp.ts setup",
24
+ "remove-mcp": "ts-node scripts/setup-mcp.ts remove",
25
+ "status-mcp": "ts-node scripts/setup-mcp.ts status",
26
+ "prepublishOnly": "npm run build",
27
+ "prepack": "npm run build"
28
+ },
29
+ "keywords": ["mcp", "puppeteer", "claude", "browser-automation", "model-context-protocol"],
30
+ "author": "jaenster",
31
+ "repository": {
32
+ "type": "git",
33
+ "url": "https://github.com/jaenster/puppeteer-mcp-claude.git"
34
+ },
35
+ "bugs": {
36
+ "url": "https://github.com/jaenster/puppeteer-mcp-claude/issues"
37
+ },
38
+ "homepage": "https://github.com/jaenster/puppeteer-mcp-claude#readme",
39
+ "license": "MIT",
40
+ "description": "A Model Context Protocol (MCP) server that provides Claude Code with comprehensive browser automation capabilities through Puppeteer",
41
+ "dependencies": {
42
+ "@modelcontextprotocol/sdk": "^1.15.0",
43
+ "@types/node": "^24.0.10",
44
+ "puppeteer": "^24.12.0",
45
+ "ts-node": "^10.9.2",
46
+ "typescript": "^5.8.3"
47
+ }
48
+ }