chrome-devtools-mcp-for-extension 0.25.6 → 0.25.7
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/build/src/McpContext.js +1 -1
- package/build/src/McpResponse.js +2 -2
- package/build/src/browser.js +3 -3
- package/build/src/formatters/extensionsPageFormatter.js +1 -1
- package/build/src/main.js +3 -3
- package/build/src/profile-migration.js +5 -0
- package/build/src/profile-resolver.js +44 -21
- package/build/src/project-detector.js +6 -1
- package/build/src/project-root-state.js +5 -0
- package/build/src/stable-identity.js +7 -2
- package/build/src/tools/bookmarks.js +1 -1
- package/build/src/tools/chatgpt-web.js +2 -2
- package/build/src/tools/diagnose-ui.js +2 -2
- package/build/src/tools/extensions.js +1 -2
- package/build/src/tools/gemini-web.js +2 -2
- package/build/src/tools/iframe-popup-tools.js +5 -0
- package/package.json +1 -1
package/build/src/McpContext.js
CHANGED
|
@@ -6,11 +6,11 @@
|
|
|
6
6
|
import fs from 'node:fs/promises';
|
|
7
7
|
import os from 'node:os';
|
|
8
8
|
import path from 'node:path';
|
|
9
|
+
import { BrowserConnectionManager, } from './browser-connection-manager.js';
|
|
9
10
|
import { NetworkCollector, PageCollector } from './PageCollector.js';
|
|
10
11
|
import { pages } from './tools/pages.js';
|
|
11
12
|
import { CLOSE_PAGE_ERROR } from './tools/ToolDefinition.js';
|
|
12
13
|
import { WaitForHelper } from './WaitForHelper.js';
|
|
13
|
-
import { BrowserConnectionManager, } from './browser-connection-manager.js';
|
|
14
14
|
const DEFAULT_TIMEOUT = 5_000;
|
|
15
15
|
const NAVIGATION_TIMEOUT = 10_000;
|
|
16
16
|
function getNetworkMultiplierFromString(condition) {
|
package/build/src/McpResponse.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import { getDevelopmentExtensionPaths } from './browser.js';
|
|
1
2
|
import { formatConsoleEvent } from './formatters/consoleFormatter.js';
|
|
3
|
+
import { formatExtensionsPage } from './formatters/extensionsPageFormatter.js';
|
|
2
4
|
import { getFormattedHeaderValue, getShortDescriptionForRequest, getStatusFromRequest, } from './formatters/networkFormatter.js';
|
|
3
5
|
import { formatA11ySnapshot } from './formatters/snapshotFormatter.js';
|
|
4
|
-
import { formatExtensionsPage } from './formatters/extensionsPageFormatter.js';
|
|
5
|
-
import { getDevelopmentExtensionPaths } from './browser.js';
|
|
6
6
|
import { paginate } from './utils/pagination.js';
|
|
7
7
|
export class McpResponse {
|
|
8
8
|
#includePages = false;
|
package/build/src/browser.js
CHANGED
|
@@ -296,7 +296,7 @@ function getChromeExtensionsDirectory(channel) {
|
|
|
296
296
|
const homeDir = os.homedir();
|
|
297
297
|
const platform = os.platform();
|
|
298
298
|
let chromeDataPath;
|
|
299
|
-
|
|
299
|
+
const profileName = 'Default';
|
|
300
300
|
if (platform === 'darwin') {
|
|
301
301
|
// macOS
|
|
302
302
|
chromeDataPath = path.join(homeDir, 'Library', 'Application Support', 'Google', 'Chrome');
|
|
@@ -450,8 +450,8 @@ export async function launch(options) {
|
|
|
450
450
|
if (resolved.reason === 'AUTO') {
|
|
451
451
|
console.error(` Root: ${process.cwd()}`);
|
|
452
452
|
}
|
|
453
|
-
|
|
454
|
-
|
|
453
|
+
const usingSystemProfile = false;
|
|
454
|
+
const profileDirectory = 'Default';
|
|
455
455
|
const args = [
|
|
456
456
|
'--hide-crash-restore-bubble',
|
|
457
457
|
`--profile-directory=${profileDirectory}`,
|
|
@@ -87,7 +87,7 @@ function groupExtensions(root, developmentPaths) {
|
|
|
87
87
|
// Find sibling nodes that belong to this extension
|
|
88
88
|
const siblings = [];
|
|
89
89
|
let version = '';
|
|
90
|
-
|
|
90
|
+
const enabled = true;
|
|
91
91
|
let location = '';
|
|
92
92
|
const errors = [];
|
|
93
93
|
// Collect related nodes (buttons, switches, text)
|
package/build/src/main.js
CHANGED
|
@@ -39,13 +39,13 @@ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
|
|
|
39
39
|
import { SetLevelRequestSchema, RootsListChangedNotificationSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
40
40
|
import { resolveBrowser } from './browser.js';
|
|
41
41
|
import { parseArguments } from './cli.js';
|
|
42
|
+
import { setupGraceful } from './graceful.js';
|
|
42
43
|
import { logger, saveLogsToFile } from './logger.js';
|
|
43
44
|
import { McpContext } from './McpContext.js';
|
|
44
45
|
import { McpResponse } from './McpResponse.js';
|
|
45
46
|
import { Mutex } from './Mutex.js';
|
|
46
|
-
import { resolveRoots } from './roots-manager.js';
|
|
47
47
|
import { setProjectRoot } from './project-root-state.js';
|
|
48
|
-
import {
|
|
48
|
+
import { resolveRoots } from './roots-manager.js';
|
|
49
49
|
import * as chatgptWebTools from './tools/chatgpt-web.js';
|
|
50
50
|
import * as consoleTools from './tools/console.js';
|
|
51
51
|
import * as emulationTools from './tools/emulation.js';
|
|
@@ -92,7 +92,7 @@ server.server.setNotificationHandler(RootsListChangedNotificationSchema, async (
|
|
|
92
92
|
logger('[roots] Cached roots cleared - will re-fetch on next browser launch');
|
|
93
93
|
});
|
|
94
94
|
let context;
|
|
95
|
-
|
|
95
|
+
const uiHealthCheckRun = false; // Track if UI health check has been run
|
|
96
96
|
let cachedRootsInfo = null; // Cache roots info
|
|
97
97
|
let initializationComplete = false; // Track if MCP initialization is complete
|
|
98
98
|
// Setup graceful shutdown
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
1
6
|
// src/profile-resolver.ts
|
|
2
7
|
// Phase 1 (v0.15.0) + v0.15.1 (MCP_CLIENT_ID support) + v0.17.0 (Hierarchical profiles)
|
|
3
8
|
// - Hybrid priority (CLI > MCP_USER_DATA_DIR > MCP_PROJECT_ID > AUTO > DEFAULT)
|
|
@@ -9,12 +14,12 @@
|
|
|
9
14
|
// - Client ID isolation (MCP_CLIENT_ID environment variable)
|
|
10
15
|
// - Hierarchical structure: {project}/{client}/{channel} (v0.17.0)
|
|
11
16
|
// - Minimal console.error() logging of decision
|
|
17
|
+
import crypto from 'node:crypto';
|
|
12
18
|
import fs from 'node:fs';
|
|
13
19
|
import os from 'node:os';
|
|
14
20
|
import path from 'node:path';
|
|
15
|
-
import crypto from 'node:crypto';
|
|
16
|
-
import { detectProjectName, detectProjectRoot } from './project-detector.js';
|
|
17
21
|
import { detectClientType } from './client-detector.js';
|
|
22
|
+
import { detectProjectName, detectProjectRoot } from './project-detector.js';
|
|
18
23
|
import { getProjectRoot } from './project-root-state.js';
|
|
19
24
|
import { resolveStableIdentity, } from './stable-identity.js';
|
|
20
25
|
const CACHE_ROOT = path.join(os.homedir(), '.cache', 'chrome-devtools-mcp');
|
|
@@ -25,8 +30,8 @@ export function resolveUserDataDir(opts) {
|
|
|
25
30
|
if (opts.rootsInfo) {
|
|
26
31
|
const stableProfilePath = path.join(CACHE_ROOT, 'profiles', opts.rootsInfo.profileKey, opts.rootsInfo.clientName, channel);
|
|
27
32
|
const normalized = pathNormalize(stableProfilePath);
|
|
28
|
-
// v0.25.
|
|
29
|
-
//
|
|
33
|
+
// v0.25.6: Migration from legacy profile formats to stable identity profile
|
|
34
|
+
// Supports: (1) v0.25.4以前のURI+clientベースハッシュ, (2) ディレクトリパスベースハッシュ
|
|
30
35
|
if (!fs.existsSync(stableProfilePath) && opts.rootsInfo.rootsUris.length > 0) {
|
|
31
36
|
try {
|
|
32
37
|
const firstUri = opts.rootsInfo.rootsUris[0];
|
|
@@ -34,28 +39,46 @@ export function resolveUserDataDir(opts) {
|
|
|
34
39
|
if (url.protocol === 'file:') {
|
|
35
40
|
const rootPath = url.pathname;
|
|
36
41
|
const realRoot = realpathSafe(rootPath);
|
|
37
|
-
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
|
|
42
|
+
// Try multiple legacy hash formats
|
|
43
|
+
const legacyHashFormats = [
|
|
44
|
+
// Format 1: v0.25.4以前 roots-manager.ts (URI + client JSON hash)
|
|
45
|
+
{
|
|
46
|
+
name: 'uri+client',
|
|
47
|
+
hash: (() => {
|
|
48
|
+
const sortedUris = [firstUri].sort();
|
|
49
|
+
const keyMaterial = JSON.stringify({
|
|
50
|
+
roots: sortedUris,
|
|
51
|
+
client: opts.rootsInfo.clientName,
|
|
52
|
+
});
|
|
53
|
+
return crypto.createHash('sha256').update(keyMaterial).digest('hex').slice(0, 8);
|
|
54
|
+
})(),
|
|
55
|
+
},
|
|
56
|
+
// Format 2: Directory path hash (shortHash)
|
|
57
|
+
{
|
|
58
|
+
name: 'directory-path',
|
|
59
|
+
hash: shortHash(realRoot),
|
|
60
|
+
},
|
|
61
|
+
];
|
|
62
|
+
for (const format of legacyHashFormats) {
|
|
63
|
+
const legacyKey = `${opts.rootsInfo.projectName}_${format.hash}`;
|
|
64
|
+
const legacyPath = path.join(CACHE_ROOT, 'profiles', legacyKey, opts.rootsInfo.clientName, channel);
|
|
65
|
+
if (fs.existsSync(legacyPath)) {
|
|
66
|
+
console.error(`[profiles] Migration: Found legacy profile (${format.name}): ${legacyPath}`);
|
|
67
|
+
console.error(`[profiles] Migration: Creating symlink to stable profile: ${stableProfilePath}`);
|
|
68
|
+
try {
|
|
69
|
+
fs.mkdirSync(path.dirname(stableProfilePath), { recursive: true });
|
|
70
|
+
fs.symlinkSync(legacyPath, stableProfilePath, 'dir');
|
|
71
|
+
console.error(`[profiles] Migration: ✅ Symlink created successfully`);
|
|
72
|
+
break; // Stop after first successful migration
|
|
73
|
+
}
|
|
74
|
+
catch (e) {
|
|
75
|
+
console.error(`[profiles] Migration: ⚠️ Failed to create symlink: ${e}`);
|
|
76
|
+
}
|
|
53
77
|
}
|
|
54
78
|
}
|
|
55
79
|
}
|
|
56
80
|
}
|
|
57
81
|
catch (e) {
|
|
58
|
-
// Ignore migration errors, continue with normal flow
|
|
59
82
|
console.error(`[profiles] Migration check failed: ${e}`);
|
|
60
83
|
}
|
|
61
84
|
}
|
|
@@ -1,12 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
1
6
|
// src/project-detector.ts
|
|
2
7
|
// Phase 1 (v0.15.0)
|
|
3
8
|
// - detectProjectRoot: git root → nearest package.json → cwd
|
|
4
9
|
// - detectProjectName: package.json "name" → dirname
|
|
5
10
|
// - Use spawnSync with 500ms timeout to avoid blocking long
|
|
6
11
|
// - Realpath normalization
|
|
12
|
+
import { spawnSync } from 'node:child_process';
|
|
7
13
|
import fs from 'node:fs';
|
|
8
14
|
import path from 'node:path';
|
|
9
|
-
import { spawnSync } from 'node:child_process';
|
|
10
15
|
export function detectProjectRoot(cwd) {
|
|
11
16
|
const realCwd = realpathSafe(cwd);
|
|
12
17
|
// 1) Try 'git rev-parse --show-toplevel' with 500ms timeout
|
|
@@ -1,10 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
1
6
|
// src/stable-identity.ts
|
|
2
7
|
// Stable project identity detection for profile persistence across directory moves
|
|
3
8
|
// Priority: MCP_PROFILE_ID > git remote origin > git first commit > package.json name > directory fallback
|
|
9
|
+
import { spawnSync } from 'node:child_process';
|
|
10
|
+
import crypto from 'node:crypto';
|
|
4
11
|
import fs from 'node:fs';
|
|
5
12
|
import path from 'node:path';
|
|
6
|
-
import crypto from 'node:crypto';
|
|
7
|
-
import { spawnSync } from 'node:child_process';
|
|
8
13
|
/**
|
|
9
14
|
* Resolve stable project identity in priority order.
|
|
10
15
|
* This identity remains stable even when the project directory is moved.
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
import { z } from 'zod';
|
|
7
|
+
import { CHATGPT_CONFIG } from '../config.js';
|
|
7
8
|
import { ToolCategories } from './categories.js';
|
|
8
9
|
import { defineTool } from './ToolDefinition.js';
|
|
9
|
-
import { CHATGPT_CONFIG } from '../config.js';
|
|
10
10
|
// Default development bookmarks
|
|
11
11
|
function getDefaultBookmarks() {
|
|
12
12
|
return {
|
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
import fs from 'node:fs';
|
|
7
7
|
import path from 'node:path';
|
|
8
8
|
import z from 'zod';
|
|
9
|
-
import { ToolCategories } from './categories.js';
|
|
10
|
-
import { defineTool } from './ToolDefinition.js';
|
|
11
9
|
import { CHATGPT_CONFIG } from '../config.js';
|
|
12
10
|
import { getLoginStatus, waitForLoginStatus, LoginStatus } from '../login-helper.js';
|
|
11
|
+
import { ToolCategories } from './categories.js';
|
|
12
|
+
import { defineTool } from './ToolDefinition.js';
|
|
13
13
|
/**
|
|
14
14
|
* Navigate with retry logic for handling ERR_ABORTED and other network errors
|
|
15
15
|
*/
|
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
import fs from 'node:fs';
|
|
7
7
|
import path from 'node:path';
|
|
8
8
|
import z from 'zod';
|
|
9
|
-
import { ToolCategories } from './categories.js';
|
|
10
|
-
import { defineTool } from './ToolDefinition.js';
|
|
11
9
|
import { CHATGPT_CONFIG } from '../config.js';
|
|
12
10
|
import { isLoginRequired } from '../login-helper.js';
|
|
11
|
+
import { ToolCategories } from './categories.js';
|
|
12
|
+
import { defineTool } from './ToolDefinition.js';
|
|
13
13
|
/**
|
|
14
14
|
* Known important elements in ChatGPT UI
|
|
15
15
|
*/
|
|
@@ -3,11 +3,10 @@
|
|
|
3
3
|
* Copyright 2025 Google LLC
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
7
6
|
import z from 'zod';
|
|
8
7
|
import { ToolCategories } from './categories.js';
|
|
9
|
-
import { defineTool } from './ToolDefinition.js';
|
|
10
8
|
import * as iframePopupTools from './iframe-popup-tools.js';
|
|
9
|
+
import { defineTool } from './ToolDefinition.js';
|
|
11
10
|
/**
|
|
12
11
|
* Consolidated extension popup tool.
|
|
13
12
|
* Combines: open_extension_popup, close_extension_popup
|
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
import fs from 'node:fs';
|
|
7
7
|
import path from 'node:path';
|
|
8
8
|
import z from 'zod';
|
|
9
|
-
import { ToolCategories } from './categories.js';
|
|
10
|
-
import { defineTool } from './ToolDefinition.js';
|
|
11
9
|
import { GEMINI_CONFIG } from '../config.js';
|
|
12
10
|
import { getLoginStatus, waitForLoginStatus, LoginStatus } from '../login-helper.js';
|
|
11
|
+
import { ToolCategories } from './categories.js';
|
|
12
|
+
import { defineTool } from './ToolDefinition.js';
|
|
13
13
|
/**
|
|
14
14
|
* Navigate with retry logic for handling ERR_ABORTED and other network errors
|
|
15
15
|
*/
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
1
6
|
// src/tools/iframe-popup-tools.ts
|
|
2
7
|
// Tools for inspecting & editing in-page iframe popups via CDP.
|
|
3
8
|
// These tools enable direct access to iframe-embedded extension popups.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "chrome-devtools-mcp-for-extension",
|
|
3
|
-
"version": "0.25.
|
|
3
|
+
"version": "0.25.7",
|
|
4
4
|
"description": "MCP server for Chrome extension development with Web Store automation. Fork of chrome-devtools-mcp with extension-specific tools.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": "./scripts/cli.mjs",
|