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 +21 -0
- package/README.md +279 -0
- package/bin/cli.js +326 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +411 -0
- package/dist/index.js.map +1 -0
- package/package.json +48 -0
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
|
+
});
|
package/dist/index.d.ts
ADDED
|
@@ -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
|
+
}
|