@dynamicu/chromedebug-mcp 2.5.7 → 2.5.9
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 +8 -0
- package/chrome-extension/background.js +94 -0
- package/chrome-extension/popup.js +24 -0
- package/package.json +1 -1
- package/src/commands/install-pro.js +18 -0
package/README.md
CHANGED
|
@@ -5,6 +5,14 @@
|
|
|
5
5
|
|
|
6
6
|
ChromeDebug MCP is a Model Context Protocol (MCP) server that gives AI assistants like Claude Code full control over a Chrome browser instance. It provides comprehensive browser automation, debugging, and screen recording capabilities optimized for AI-assisted development.
|
|
7
7
|
|
|
8
|
+
## 🎥 See It In Action
|
|
9
|
+
|
|
10
|
+
Watch the demo video to see how ChromeDebug MCP works:
|
|
11
|
+
|
|
12
|
+
[](https://youtu.be/2Y9nIsvEjks?si=x5XjN0ZPHYhjZAqd)
|
|
13
|
+
|
|
14
|
+
**[▶️ Watch Demo Video](https://youtu.be/2Y9nIsvEjks?si=x5XjN0ZPHYhjZAqd)**
|
|
15
|
+
|
|
8
16
|
## Quick Start
|
|
9
17
|
|
|
10
18
|
### Installation from npm
|
|
@@ -918,10 +918,96 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|
|
918
918
|
}
|
|
919
919
|
});
|
|
920
920
|
|
|
921
|
+
// Auto-activate PRO license on startup if activation file exists
|
|
922
|
+
async function checkAndActivateLicense() {
|
|
923
|
+
try {
|
|
924
|
+
console.log('[License Auto-Activation] Checking for activation file...');
|
|
925
|
+
|
|
926
|
+
// Try to fetch the activation file from the extension directory
|
|
927
|
+
const activationUrl = chrome.runtime.getURL('license-activation.json');
|
|
928
|
+
const response = await fetch(activationUrl);
|
|
929
|
+
|
|
930
|
+
if (!response.ok) {
|
|
931
|
+
console.log('[License Auto-Activation] No activation file found - using normal license flow');
|
|
932
|
+
return;
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
const activationData = await response.json();
|
|
936
|
+
console.log('[License Auto-Activation] Found activation file:', {
|
|
937
|
+
tier: activationData.tier,
|
|
938
|
+
activated_at: activationData.activated_at
|
|
939
|
+
});
|
|
940
|
+
|
|
941
|
+
// Check if license is already cached and valid
|
|
942
|
+
const cached = await chrome.storage.local.get('chromedebug_license_cache');
|
|
943
|
+
if (cached.chromedebug_license_cache?.valid && cached.chromedebug_license_cache?.tier === 'pro') {
|
|
944
|
+
console.log('[License Auto-Activation] License already activated and cached');
|
|
945
|
+
return;
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
// Activate the license
|
|
949
|
+
const licenseKey = activationData.license_key;
|
|
950
|
+
console.log('[License Auto-Activation] Activating license...');
|
|
951
|
+
|
|
952
|
+
// Call LemonSqueezy activation via Firebase Cloud Function
|
|
953
|
+
const instanceId = crypto.randomUUID();
|
|
954
|
+
await chrome.storage.local.set({
|
|
955
|
+
'chromedebug_instance_id': instanceId,
|
|
956
|
+
'ls_instance_id': instanceId,
|
|
957
|
+
'ls_license_key': licenseKey
|
|
958
|
+
});
|
|
959
|
+
|
|
960
|
+
const activationResponse = await fetch(`${FUNCTIONS_URL}/activateLicense`, {
|
|
961
|
+
method: 'POST',
|
|
962
|
+
headers: {'Content-Type': 'application/json'},
|
|
963
|
+
body: JSON.stringify({
|
|
964
|
+
licenseKey,
|
|
965
|
+
instanceId,
|
|
966
|
+
instanceName: `ChromeDebug-${navigator.userAgent.match(/Chrome\/(\d+)/)?.[1] || 'Unknown'}`
|
|
967
|
+
})
|
|
968
|
+
});
|
|
969
|
+
|
|
970
|
+
if (!activationResponse.ok) {
|
|
971
|
+
throw new Error(`Activation failed: HTTP ${activationResponse.status}`);
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
const activationResult = await activationResponse.json();
|
|
975
|
+
console.log('[License Auto-Activation] Activation result:', activationResult);
|
|
976
|
+
|
|
977
|
+
if (activationResult.activated || activationResult.valid) {
|
|
978
|
+
// Cache the license status
|
|
979
|
+
const licenseCache = {
|
|
980
|
+
valid: true,
|
|
981
|
+
tier: 'pro',
|
|
982
|
+
licenseKey: licenseKey.substring(0, 8) + '...',
|
|
983
|
+
cachedAt: Date.now(),
|
|
984
|
+
graceUntil: Date.now() + (30 * 24 * 60 * 60 * 1000) // 30 days
|
|
985
|
+
};
|
|
986
|
+
|
|
987
|
+
await chrome.storage.local.set({
|
|
988
|
+
'chromedebug_license_cache': licenseCache
|
|
989
|
+
});
|
|
990
|
+
|
|
991
|
+
console.log('[License Auto-Activation] ✓ PRO license activated successfully!');
|
|
992
|
+
console.log('[License Auto-Activation] Cached license status:', licenseCache);
|
|
993
|
+
} else {
|
|
994
|
+
console.error('[License Auto-Activation] Activation returned invalid status:', activationResult);
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
} catch (error) {
|
|
998
|
+
// Don't block extension startup on activation errors
|
|
999
|
+
console.error('[License Auto-Activation] Failed to auto-activate license:', error);
|
|
1000
|
+
console.log('[License Auto-Activation] Extension will continue with normal license flow');
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
|
|
921
1004
|
// Session recovery on startup - handle any stuck recordings from previous session
|
|
922
1005
|
chrome.runtime.onStartup.addListener(async () => {
|
|
923
1006
|
console.log('[Background] Extension startup detected - checking for stuck sessions');
|
|
924
1007
|
|
|
1008
|
+
// Check for PRO license auto-activation first
|
|
1009
|
+
await checkAndActivateLicense();
|
|
1010
|
+
|
|
925
1011
|
if (sessionManager) {
|
|
926
1012
|
try {
|
|
927
1013
|
// Use existing recovery method from session manager
|
|
@@ -935,6 +1021,14 @@ chrome.runtime.onStartup.addListener(async () => {
|
|
|
935
1021
|
}
|
|
936
1022
|
});
|
|
937
1023
|
|
|
1024
|
+
// Extension install/update - also check for license activation
|
|
1025
|
+
chrome.runtime.onInstalled.addListener(async (details) => {
|
|
1026
|
+
console.log('[Background] Extension installed/updated:', details.reason);
|
|
1027
|
+
|
|
1028
|
+
// Check for PRO license auto-activation on install/update
|
|
1029
|
+
await checkAndActivateLicense();
|
|
1030
|
+
});
|
|
1031
|
+
|
|
938
1032
|
// Listen for tab updates to handle restore points
|
|
939
1033
|
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
|
|
940
1034
|
// Inject console logging on navigation during recording
|
|
@@ -829,6 +829,25 @@ async function initializeLicenseUI() {
|
|
|
829
829
|
console.log('[License] Created new user ID:', currentUserId);
|
|
830
830
|
}
|
|
831
831
|
|
|
832
|
+
// Check for license activation file and pre-fill license key
|
|
833
|
+
try {
|
|
834
|
+
const activationFileUrl = chrome.runtime.getURL('license-activation.json');
|
|
835
|
+
const response = await fetch(activationFileUrl);
|
|
836
|
+
if (response.ok) {
|
|
837
|
+
const activationData = await response.json();
|
|
838
|
+
if (activationData.license_key) {
|
|
839
|
+
const licenseKeyInput = document.getElementById('license-key-input');
|
|
840
|
+
if (licenseKeyInput) {
|
|
841
|
+
licenseKeyInput.value = activationData.license_key;
|
|
842
|
+
console.log('[License UI] Pre-filled license key from activation file');
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
} catch (error) {
|
|
847
|
+
// Activation file doesn't exist or is inaccessible - this is normal for FREE version
|
|
848
|
+
console.log('[License UI] No activation file found - normal for FREE version');
|
|
849
|
+
}
|
|
850
|
+
|
|
832
851
|
// Check license status
|
|
833
852
|
const licenseStatus = await licenseClient.getCachedLicenseStatus();
|
|
834
853
|
console.log('[License] License status:', licenseStatus);
|
|
@@ -878,6 +897,11 @@ async function handleLicenseActivation() {
|
|
|
878
897
|
messageDiv.style.color = '#2196F3';
|
|
879
898
|
console.log('[License] Validating license key...');
|
|
880
899
|
|
|
900
|
+
// Clear any existing instance ID to force fresh activation
|
|
901
|
+
// This ensures we don't try to validate with stale/deleted instance IDs
|
|
902
|
+
await chrome.storage.local.remove(['ls_instance_id']);
|
|
903
|
+
console.log('[License] Cleared existing instance ID for fresh activation');
|
|
904
|
+
|
|
881
905
|
const result = await licenseClient.validateLicense(licenseKey);
|
|
882
906
|
console.log('[License] Validation result:', result);
|
|
883
907
|
console.log('[License] Error value:', result.error);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dynamicu/chromedebug-mcp",
|
|
3
|
-
"version": "2.5.
|
|
3
|
+
"version": "2.5.9",
|
|
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",
|
|
@@ -486,6 +486,24 @@ This will overwrite the existing installation.`;
|
|
|
486
486
|
// Set extension directory permissions
|
|
487
487
|
await fs.chmod(EXTENSION_DIR, 0o755);
|
|
488
488
|
|
|
489
|
+
// 5.5. Create license activation file for auto-activation
|
|
490
|
+
console.log('Creating license activation file...');
|
|
491
|
+
const activationFile = {
|
|
492
|
+
license_key: license,
|
|
493
|
+
activated_at: new Date().toISOString(),
|
|
494
|
+
auto_activate: true,
|
|
495
|
+
tier: 'pro'
|
|
496
|
+
};
|
|
497
|
+
|
|
498
|
+
const activationFilePath = path.join(EXTENSION_DIR, 'license-activation.json');
|
|
499
|
+
await fs.writeFile(
|
|
500
|
+
activationFilePath,
|
|
501
|
+
JSON.stringify(activationFile, null, 2),
|
|
502
|
+
'utf8'
|
|
503
|
+
);
|
|
504
|
+
await logInstall(`License activation file created: ${activationFilePath}`);
|
|
505
|
+
console.log(` Activation file created for auto-activation\n`);
|
|
506
|
+
|
|
489
507
|
// 6. Save license information
|
|
490
508
|
console.log('Saving license information...');
|
|
491
509
|
await saveLicenseInfo(license, extensionInfo.version);
|