@dynamicu/chromedebug-mcp 2.4.0 ā 2.4.2
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/README.md +37 -2
- package/chrome-extension/icon128.png +0 -0
- package/chrome-extension/icon16.png +0 -0
- package/chrome-extension/icon48.png +0 -0
- package/chrome-extension/manifest.free.json +3 -3
- package/chrome-extension/manifest.json +3 -3
- package/package.json +4 -2
- package/scripts/package-pro-extension.js +81 -0
- package/scripts/package-webstore-extension.js +118 -0
- package/src/services/process-manager.js +14 -2
package/README.md
CHANGED
|
@@ -30,12 +30,22 @@ npm install
|
|
|
30
30
|
|
|
31
31
|
### As MCP Server
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
#### macOS / Linux
|
|
34
34
|
|
|
35
35
|
```bash
|
|
36
36
|
claude mcp add chromedebug -s user -- chromedebug-mcp
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
+
#### Windows
|
|
40
|
+
|
|
41
|
+
On Windows, use `cmd /c` to properly execute the server:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
claude mcp add chromedebug -s user -- cmd /c chromedebug-mcp
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**Note for Windows Users:** Process cleanup is currently limited on Windows. The server will start successfully but won't clean up orphaned processes from previous sessions. A full cross-platform process management solution is planned for a future release.
|
|
48
|
+
|
|
39
49
|
### Embedded HTTP Server
|
|
40
50
|
|
|
41
51
|
Chrome Debug automatically starts an embedded HTTP server for Chrome extension communication. The server uses ports configured in `config/chrome-pilot-config.json` (default: 3001, 3000, 3002, 3028). The server provides these REST API endpoints:
|
|
@@ -102,10 +112,35 @@ Chrome Debug includes a Chrome extension that enables visual element selection f
|
|
|
102
112
|
|
|
103
113
|
### Installing the Extension
|
|
104
114
|
|
|
115
|
+
#### Option 1: Chrome Web Store (Recommended - FREE Version)
|
|
116
|
+
|
|
117
|
+
Install the FREE version directly from the Chrome Web Store:
|
|
118
|
+
|
|
119
|
+
š **[Install from Chrome Web Store](https://chromewebstore.google.com/detail/lemgbmdnephoaniipapgeciebfeakffn?utm_source=item-share-cb)**
|
|
120
|
+
|
|
121
|
+
- ā
5 recordings per day
|
|
122
|
+
- ā
Full MCP integration
|
|
123
|
+
- ā
Visual element selection
|
|
124
|
+
- ā
Automatic updates
|
|
125
|
+
- ā
No manual installation needed
|
|
126
|
+
|
|
127
|
+
#### Option 2: Manual Installation (Development)
|
|
128
|
+
|
|
105
129
|
1. Open Chrome and navigate to `chrome://extensions/`
|
|
106
|
-
2. Enable "Developer mode"
|
|
130
|
+
2. Enable "Developer mode"
|
|
107
131
|
3. Click "Load unpacked" and select the `chrome-extension` directory
|
|
108
132
|
|
|
133
|
+
#### Option 3: PRO Version (Unlimited)
|
|
134
|
+
|
|
135
|
+
For unlimited recordings and advanced features, purchase the PRO version:
|
|
136
|
+
|
|
137
|
+
š **[Get PRO Version](https://dynamicu.lemonsqueezy.com/buy/641143)**
|
|
138
|
+
|
|
139
|
+
- ā
Unlimited recordings
|
|
140
|
+
- ā
Advanced function tracing
|
|
141
|
+
- ā
Enhanced capture features
|
|
142
|
+
- ā
Priority support
|
|
143
|
+
|
|
109
144
|
### Using the Extension
|
|
110
145
|
|
|
111
146
|
1. **Element Selection**
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"manifest_version": 3,
|
|
3
|
-
"name": "ChromeDebug MCP Assistant FREE v2.
|
|
4
|
-
"version": "2.
|
|
5
|
-
"description": "ChromeDebug MCP visual element selector [FREE Edition] [Build: 2025-01-20-v2.
|
|
3
|
+
"name": "ChromeDebug MCP Assistant FREE v2.4.0",
|
|
4
|
+
"version": "2.4.0",
|
|
5
|
+
"description": "ChromeDebug MCP visual element selector [FREE Edition] [Build: 2025-01-20-v2.4.0]",
|
|
6
6
|
"permissions": [
|
|
7
7
|
"activeTab",
|
|
8
8
|
"scripting",
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"manifest_version": 3,
|
|
3
|
-
"name": "ChromeDebug MCP Assistant v2.1.
|
|
4
|
-
"version": "2.1.
|
|
5
|
-
"description": "ChromeDebug MCP visual element selector with function tracing [Build: 2025-10-
|
|
3
|
+
"name": "ChromeDebug MCP Assistant v2.1.3",
|
|
4
|
+
"version": "2.1.3",
|
|
5
|
+
"description": "ChromeDebug MCP visual element selector with function tracing [Build: 2025-10-16-v2.1.3]",
|
|
6
6
|
"permissions": [
|
|
7
7
|
"activeTab",
|
|
8
8
|
"scripting",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dynamicu/chromedebug-mcp",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.2",
|
|
4
4
|
"description": "ChromeDebug MCP - MCP server that provides full control over a Chrome browser instance for debugging and automation with AI assistants like Claude Code",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -56,7 +56,9 @@
|
|
|
56
56
|
"tbv:microtest": "cd chrome-extension && npm run tbv:microtest",
|
|
57
57
|
"build:free": "webpack --config scripts/webpack.config.free.cjs",
|
|
58
58
|
"build:pro": "webpack --config scripts/webpack.config.pro.cjs",
|
|
59
|
-
"build:both": "npm run build:free && npm run build:pro"
|
|
59
|
+
"build:both": "npm run build:free && npm run build:pro",
|
|
60
|
+
"package-pro": "node scripts/package-pro-extension.js",
|
|
61
|
+
"package-webstore": "node scripts/package-webstore-extension.js"
|
|
60
62
|
},
|
|
61
63
|
"keywords": [
|
|
62
64
|
"mcp",
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Package PRO Chrome extension for LemonSqueezy distribution
|
|
5
|
+
* Creates a .zip file with the PRO version including activation manager
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { createWriteStream, promises as fs } from 'fs';
|
|
9
|
+
import { join, dirname } from 'path';
|
|
10
|
+
import { fileURLToPath } from 'url';
|
|
11
|
+
import { execSync } from 'child_process';
|
|
12
|
+
import archiver from 'archiver';
|
|
13
|
+
|
|
14
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
15
|
+
const __dirname = dirname(__filename);
|
|
16
|
+
const rootDir = join(__dirname, '..');
|
|
17
|
+
const proExtensionDir = join(rootDir, 'scripts', 'dist', 'pro');
|
|
18
|
+
const outputDir = join(rootDir, 'dist');
|
|
19
|
+
const outputFile = join(outputDir, 'chromedebug-extension-pro.zip');
|
|
20
|
+
|
|
21
|
+
async function packageProExtension() {
|
|
22
|
+
console.log('š¦ Building and packaging PRO Chrome extension...');
|
|
23
|
+
|
|
24
|
+
// Step 1: Build the pro version
|
|
25
|
+
console.log('šØ Building PRO version...');
|
|
26
|
+
try {
|
|
27
|
+
execSync('npm run build:pro', {
|
|
28
|
+
cwd: rootDir,
|
|
29
|
+
stdio: 'inherit'
|
|
30
|
+
});
|
|
31
|
+
} catch (error) {
|
|
32
|
+
console.error('ā Failed to build PRO version');
|
|
33
|
+
throw error;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Step 2: Verify the build output exists
|
|
37
|
+
try {
|
|
38
|
+
await fs.access(proExtensionDir);
|
|
39
|
+
} catch {
|
|
40
|
+
throw new Error(`Build output not found at ${proExtensionDir}`);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Step 3: Ensure output directory exists
|
|
44
|
+
try {
|
|
45
|
+
await fs.mkdir(outputDir, { recursive: true });
|
|
46
|
+
} catch (error) {
|
|
47
|
+
// Directory might already exist, that's fine
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Step 4: Create zip file
|
|
51
|
+
console.log('š¦ Creating PRO zip package...');
|
|
52
|
+
|
|
53
|
+
const output = createWriteStream(outputFile);
|
|
54
|
+
const archive = archiver('zip', { zlib: { level: 9 } });
|
|
55
|
+
|
|
56
|
+
return new Promise((resolve, reject) => {
|
|
57
|
+
output.on('close', () => {
|
|
58
|
+
const sizeKB = (archive.pointer() / 1024).toFixed(2);
|
|
59
|
+
console.log(`ā
PRO extension packaged successfully!`);
|
|
60
|
+
console.log(` Size: ${sizeKB} KB`);
|
|
61
|
+
console.log(` Location: ${outputFile}`);
|
|
62
|
+
console.log(` š This is the PRO version with activation manager`);
|
|
63
|
+
console.log(` š For LemonSqueezy distribution only`);
|
|
64
|
+
resolve();
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
archive.on('error', reject);
|
|
68
|
+
|
|
69
|
+
archive.pipe(output);
|
|
70
|
+
|
|
71
|
+
// Add all files from the pro build directory
|
|
72
|
+
archive.directory(proExtensionDir, false);
|
|
73
|
+
|
|
74
|
+
archive.finalize();
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
packageProExtension().catch(err => {
|
|
79
|
+
console.error('ā Failed to package PRO extension:', err);
|
|
80
|
+
process.exit(1);
|
|
81
|
+
});
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import archiver from 'archiver';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import { fileURLToPath } from 'url';
|
|
6
|
+
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
+
const __dirname = path.dirname(__filename);
|
|
9
|
+
|
|
10
|
+
const projectRoot = path.join(__dirname, '..');
|
|
11
|
+
const extensionDir = path.join(projectRoot, 'chrome-extension');
|
|
12
|
+
const distDir = path.join(projectRoot, 'dist');
|
|
13
|
+
const outputFile = path.join(distDir, 'chromedebug-extension-webstore.zip');
|
|
14
|
+
|
|
15
|
+
// Ensure dist directory exists
|
|
16
|
+
if (!fs.existsSync(distDir)) {
|
|
17
|
+
fs.mkdirSync(distDir, { recursive: true });
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Create output stream
|
|
21
|
+
const output = fs.createWriteStream(outputFile);
|
|
22
|
+
const archive = archiver('zip', { zlib: { level: 9 } });
|
|
23
|
+
|
|
24
|
+
console.log('š¦ Packaging Chrome extension for Web Store...');
|
|
25
|
+
|
|
26
|
+
// Listen for archive events
|
|
27
|
+
output.on('close', () => {
|
|
28
|
+
const sizeKB = (archive.pointer() / 1024).toFixed(2);
|
|
29
|
+
console.log(`ā
Extension packaged successfully!`);
|
|
30
|
+
console.log(` File: ${outputFile}`);
|
|
31
|
+
console.log(` Size: ${sizeKB} KB`);
|
|
32
|
+
console.log(`\nš Ready to upload to Chrome Web Store!`);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
archive.on('error', (err) => {
|
|
36
|
+
throw err;
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// Pipe archive to output file
|
|
40
|
+
archive.pipe(output);
|
|
41
|
+
|
|
42
|
+
// Files to include in the extension (FREE version for Web Store)
|
|
43
|
+
const filesToInclude = [
|
|
44
|
+
// Manifest (use FREE version and rename to manifest.json)
|
|
45
|
+
{ source: 'manifest.free.json', target: 'manifest.json' },
|
|
46
|
+
|
|
47
|
+
// Background service worker
|
|
48
|
+
'background.js',
|
|
49
|
+
'chrome-session-manager.js',
|
|
50
|
+
'logger.js',
|
|
51
|
+
'extension-config.js',
|
|
52
|
+
'firebase-client.js',
|
|
53
|
+
'firebase-config.js',
|
|
54
|
+
'license-helper.js',
|
|
55
|
+
|
|
56
|
+
// Content scripts (from manifest)
|
|
57
|
+
'content.js',
|
|
58
|
+
'content.css',
|
|
59
|
+
'pako.min.js',
|
|
60
|
+
'web-vitals.iife.js',
|
|
61
|
+
'pii-redactor.js',
|
|
62
|
+
'data-buffer.js',
|
|
63
|
+
'performance-monitor.js',
|
|
64
|
+
'dom-tracker.js',
|
|
65
|
+
'network-tracker.js',
|
|
66
|
+
|
|
67
|
+
// Popup
|
|
68
|
+
'popup.html',
|
|
69
|
+
'popup.js',
|
|
70
|
+
|
|
71
|
+
// Options page
|
|
72
|
+
'options.html',
|
|
73
|
+
'options.js',
|
|
74
|
+
|
|
75
|
+
// Activation manager
|
|
76
|
+
'activation-manager.html',
|
|
77
|
+
'activation-manager.js',
|
|
78
|
+
|
|
79
|
+
// Offscreen
|
|
80
|
+
'offscreen.html',
|
|
81
|
+
'offscreen.js',
|
|
82
|
+
|
|
83
|
+
// Frame capture
|
|
84
|
+
'frame-capture.js',
|
|
85
|
+
|
|
86
|
+
// Icons
|
|
87
|
+
'icon16.png',
|
|
88
|
+
'icon48.png',
|
|
89
|
+
'icon128.png',
|
|
90
|
+
|
|
91
|
+
// Documentation
|
|
92
|
+
'README.md'
|
|
93
|
+
];
|
|
94
|
+
|
|
95
|
+
// Add each file to the archive
|
|
96
|
+
filesToInclude.forEach(file => {
|
|
97
|
+
let sourcePath, targetName;
|
|
98
|
+
|
|
99
|
+
if (typeof file === 'object') {
|
|
100
|
+
// Handle object format { source: 'file.json', target: 'renamed.json' }
|
|
101
|
+
sourcePath = path.join(extensionDir, file.source);
|
|
102
|
+
targetName = file.target;
|
|
103
|
+
} else {
|
|
104
|
+
// Handle simple string format
|
|
105
|
+
sourcePath = path.join(extensionDir, file);
|
|
106
|
+
targetName = file;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (fs.existsSync(sourcePath)) {
|
|
110
|
+
archive.file(sourcePath, { name: targetName });
|
|
111
|
+
console.log(` ā ${targetName}${typeof file === 'object' ? ` (from ${file.source})` : ''}`);
|
|
112
|
+
} else {
|
|
113
|
+
console.warn(` ā Skipping missing file: ${typeof file === 'object' ? file.source : file}`);
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
// Finalize the archive
|
|
118
|
+
archive.finalize();
|
|
@@ -57,18 +57,30 @@ async function safeKillProcess(pid, signal = 'SIGTERM') {
|
|
|
57
57
|
/**
|
|
58
58
|
* Find ChromeDebug MCP processes using Node.js process list instead of shell commands
|
|
59
59
|
* This prevents command injection while maintaining functionality
|
|
60
|
+
*
|
|
61
|
+
* NOTE: Windows support is intentionally limited - the ps command doesn't exist on Windows.
|
|
62
|
+
* Process cleanup is skipped on Windows to allow the server to start. A proper cross-platform
|
|
63
|
+
* solution will be implemented in a future update.
|
|
60
64
|
*/
|
|
61
65
|
async function findChromePilotProcesses() {
|
|
66
|
+
// Skip process cleanup on Windows - ps command doesn't exist
|
|
67
|
+
// This allows the server to start on Windows without crashing
|
|
68
|
+
// TODO: Implement proper Windows process management using tasklist or Node.js process handles
|
|
69
|
+
if (process.platform === 'win32') {
|
|
70
|
+
console.log('[ChromeDebug] Process cleanup skipped on Windows (not yet implemented)');
|
|
71
|
+
return { pidsToKill: [], processDescriptions: [] };
|
|
72
|
+
}
|
|
73
|
+
|
|
62
74
|
const currentPid = process.pid;
|
|
63
75
|
const pidsToKill = [];
|
|
64
76
|
const processDescriptions = [];
|
|
65
|
-
|
|
77
|
+
|
|
66
78
|
try {
|
|
67
79
|
// Security: Use Node.js process list instead of shell commands
|
|
68
80
|
// This approach uses the 'ps-list' module or similar safe approach
|
|
69
81
|
// For now, we'll use a safer implementation with spawn instead of exec
|
|
70
82
|
const { spawn } = await import('child_process');
|
|
71
|
-
|
|
83
|
+
|
|
72
84
|
return new Promise((resolve) => {
|
|
73
85
|
const ps = spawn('ps', ['aux'], { stdio: ['ignore', 'pipe', 'ignore'] });
|
|
74
86
|
let stdout = '';
|