豆豆友情提示:这是一个非官方 GitHub 代理镜像,主要用于网络测试或访问加速。请勿在此进行登录、注册或处理任何敏感信息。进行这些操作请务必访问官方网站 github.com。 Raw 内容也通过此代理提供。
Skip to content

Commit 68a6ea0

Browse files
committed
Merge branch 'main' into orkon/release-cli
2 parents 3ac5cd9 + c2d8009 commit 68a6ea0

39 files changed

+1497
-439
lines changed

.release-please-manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
".": "0.18.1"
2+
".": "0.19.0"
33
}

CHANGELOG.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,45 @@
11
# Changelog
22

3+
## [0.19.0](https://github.com/ChromeDevTools/chrome-devtools-mcp/compare/chrome-devtools-mcp-v0.18.1...chrome-devtools-mcp-v0.19.0) (2026-03-05)
4+
5+
6+
### 🎉 Features
7+
8+
* add pageId routing for parallel multi-agent workflows ([#1022](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1022)) ([caf601a](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/caf601a32832bb87cfac801a6bbeacb87508412f)), closes [#1019](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1019)
9+
* Add skill which helps with onboarding of the mcp server ([#1083](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1083)) ([7273f16](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/7273f16ec08f6d5b46a2693b0ad4d559086ded89))
10+
* integrate Lighthouse audits ([#831](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/831)) ([dfdac26](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/dfdac2648e560d756a8711ad3bb1fa470be8e7c9))
11+
12+
13+
### 🛠️ Fixes
14+
15+
* improve error messages around --auto-connect ([#1075](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1075)) ([bcb852d](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/bcb852dd2e440b0005f4a9ad270a1a7998767907))
16+
* improve tool descriptions ([#965](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/965)) ([bdbbc84](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/bdbbc84c125bdd48f4be48aa476bec0323de611c))
17+
* repair broken markdown and extract snippets in a11y-debugging skill ([#1096](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1096)) ([adac7c5](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/adac7c537ee304f324c5e7284fb363396d1773f5))
18+
* simplify emulation and script tools ([#1073](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1073)) ([e51ba47](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/e51ba4720338951e621585b77efc6a0e07678d99))
19+
* simplify focus state management ([#1063](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1063)) ([f763da2](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/f763da24a10e27605c0a5069853ce7c92974eec2))
20+
* tweak lighthouse description ([#1112](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1112)) ([5538180](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/55381804ae7ffa8a1e5933b621a9b8390b3000ff))
21+
22+
23+
### 📄 Documentation
24+
25+
* Adapt a11y skill to utilize Lighthouse ([#1054](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1054)) ([21634e6](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/21634e660c346e469ae62116b1824538f51567dd))
26+
* add feature release checklist to CONTRIBUTING.md ([#1118](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1118)) ([0378457](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/03784577ffb6e238bcb2d637bff9ad759723ea7b))
27+
* fix typo in README regarding slim mode ([#1093](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1093)) ([92f2c7b](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/92f2c7b48b56a6b1d6ac7c9e2f2e92beb26bcf62))
28+
29+
30+
### 🏗️ Refactor
31+
32+
* clean up more of the context getters ([#1062](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1062)) ([9628dab](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/9628dabcb4d39f0b94d152a0fc419e049246a29d))
33+
* consistently use McpPage in tools ([#1057](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1057)) ([302e5a0](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/302e5a04191ba0558e3c79f1486d01d5eb0f6896))
34+
* improve type safety for page scoped tools ([#1051](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1051)) ([5f694c6](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/5f694c60ffd21f8b022554c92b2ad4cbdb457375))
35+
* make cdp resolvers use McpPage ([#1060](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1060)) ([d6c06c5](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/d6c06c56a7b8e4968318adc9fc7c820ace9f5bd9))
36+
* move dialog handling to McpPage ([#1059](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1059)) ([40c241b](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/40c241bbfc80d6282953ab325b30a597d3d85ade))
37+
* move server to a separate file ([#1043](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1043)) ([a8bf3e5](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/a8bf3e585682c3126dfd378e9f98b5dc7ab6045d))
38+
* remove page passing via context ([#1061](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1061)) ([4cb5a17](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/4cb5a17b57f57d8a367cd423c960ba122b9952e3))
39+
* set defaults to performance trace tool ([#1090](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1090)) ([dfa9b79](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/dfa9b79a4ecc9e67f5b043f2dd97f6889d1fee0b))
40+
* simplify the response texts ([#1095](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1095)) ([cb0079e](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/cb0079efbbd41874f6913772fe3f2a037e9f5f8f))
41+
* type-cast as internal CdpPage interface ([#1064](https://github.com/ChromeDevTools/chrome-devtools-mcp/issues/1064)) ([2d5e4fa](https://github.com/ChromeDevTools/chrome-devtools-mcp/commit/2d5e4fa3579650a384ff21c88c2e6b9cda031e1a))
42+
343
## [0.18.1](https://github.com/ChromeDevTools/chrome-devtools-mcp/compare/chrome-devtools-mcp-v0.18.0...chrome-devtools-mcp-v0.18.1) (2026-02-25)
444

545

docs/troubleshooting.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,32 @@ Possible workarounds include:
100100

101101
- **Use Powershell or Git Bash** instead of WSL.
102102

103+
### Windows 10: Error during discovery for MCP server 'chrome-devtools': MCP error -32000: Connection closed
104+
105+
- **Solution 1** Call using `cmd` (For more info https://github.com/modelcontextprotocol/servers/issues/1082#issuecomment-2791786310)
106+
107+
```json
108+
"mcpServers": {
109+
"chrome-devtools": {
110+
"command": "cmd",
111+
"args": ["/c", "npx", "-y", "chrome-devtools-mcp@latest"]
112+
}
113+
}
114+
```
115+
116+
> **The Key Change:** On Windows, running a Node.js package via `npx` often requires the `cmd /c` prefix to be executed correctly from within another process like VSCode's extension host. Therefore, `"command": "npx"` was replaced with `"command": "cmd"`, and the actual `npx` command was moved into the `"args"` array, preceded by `"/c"`. This fix allows Windows to interpret the command correctly and launch the server.
117+
118+
- **Solution 2** Instead of another layer of shell you can write the absolute path to `npx`:
119+
> Note: The path below is an example. You must adjust it to match the actual location of `npx` on your machine. Depending on your setup, the file extension might be `.cmd`, `.bat`, or `.exe` rather than `.ps1`. Also, ensure you use double backslashes (`\\`) as path delimiters, as required by the JSON format.
120+
```json
121+
"mcpServers": {
122+
"chrome-devtools": {
123+
"command": "C:\\nvm4w\\nodejs\\npx.ps1",
124+
"args": ["-y", "chrome-devtools-mcp@latest"]
125+
}
126+
}
127+
```
128+
103129
### Connection timeouts with `--autoConnect`
104130

105131
If you are using the `--autoConnect` flag and tools like `list_pages`, `new_page`, or `navigate_page` fail with a timeout (e.g., `ProtocolError: Network.enable timed out` or `The socket connection was closed unexpectedly`), this usually means the MCP server cannot handshake with the running Chrome instance correctly. Ensure:

package-lock.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
{
22
"name": "chrome-devtools-mcp",
3-
"version": "0.18.1",
3+
"version": "0.19.0",
44
"description": "MCP server for Chrome DevTools",
55
"type": "module",
66
"bin": {
7-
"chrome-devtools-mcp": "./build/src/index.js",
7+
"chrome-devtools-mcp": "./build/src/bin/chrome-devtools-mcp.js",
88
"chrome-devtools": "./build/src/bin/chrome-devtools.js"
99
},
10-
"main": "./build/src/server.js",
10+
"main": "./build/src/index.js",
1111
"scripts": {
1212
"cli:generate": "node --experimental-strip-types scripts/generate-cli.ts",
1313
"clean": "node -e \"require('fs').rmSync('build', {recursive: true, force: true})\"",

scripts/generate-cli.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import path from 'node:path';
1010
import {Client} from '@modelcontextprotocol/sdk/client/index.js';
1111
import {StdioClientTransport} from '@modelcontextprotocol/sdk/client/stdio.js';
1212

13-
import {parseArguments} from '../build/src/cli.js';
13+
import {parseArguments} from '../build/src/bin/chrome-devtools-mcp-cli-options.js';
1414
import {labels} from '../build/src/tools/categories.js';
1515
import {createTools} from '../build/src/tools/tools.js';
1616

@@ -22,7 +22,10 @@ const OUTPUT_PATH = path.join(
2222
async function fetchTools() {
2323
console.log('Connecting to chrome-devtools-mcp to fetch tools...');
2424
// Use the local build of the server
25-
const serverPath = path.join(import.meta.dirname, '../build/src/index.js');
25+
const serverPath = path.join(
26+
import.meta.dirname,
27+
'../build/src/bin/chrome-devtools-mcp.js',
28+
);
2629

2730
const transport = new StdioClientTransport({
2831
command: 'node',

scripts/generate-docs.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ import {StdioClientTransport} from '@modelcontextprotocol/sdk/client/stdio.js';
1111
import type {Tool} from '@modelcontextprotocol/sdk/types.js';
1212
import {get_encoding} from 'tiktoken';
1313

14-
import {cliOptions} from '../build/src/cli.js';
15-
import type {ParsedArguments} from '../build/src/cli.js';
14+
import {cliOptions} from '../build/src/bin/chrome-devtools-mcp-cli-options.js';
15+
import type {ParsedArguments} from '../build/src/bin/chrome-devtools-mcp-cli-options.js';
1616
import {ToolCategory, labels} from '../build/src/tools/categories.js';
1717
import {createTools} from '../build/src/tools/tools.js';
1818

@@ -24,7 +24,7 @@ async function measureServer(args: string[]) {
2424
// 1. Connect to your actual MCP server
2525
const transport = new StdioClientTransport({
2626
command: 'node',
27-
args: ['./build/src/index.js', ...args], // Point to your built MCP server
27+
args: ['./build/src/bin/chrome-devtools-mcp.js', ...args], // Point to your built MCP server
2828
});
2929

3030
const client = new Client(

server.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@
77
"url": "https://github.com/ChromeDevTools/chrome-devtools-mcp",
88
"source": "github"
99
},
10-
"version": "0.18.1",
10+
"version": "0.19.0",
1111
"packages": [
1212
{
1313
"registryType": "npm",
1414
"registryBaseUrl": "https://registry.npmjs.org",
1515
"identifier": "chrome-devtools-mcp",
16-
"version": "0.18.1",
16+
"version": "0.19.0",
1717
"transport": {
1818
"type": "stdio"
1919
},

src/McpContext.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ export class McpContext implements Context {
109109
null;
110110

111111
#nextPageId = 1;
112+
#extensionPages = new WeakMap<Target, Page>();
112113

113114
#extensionServiceWorkerMap = new WeakMap<Target, string>();
114115
#nextExtensionServiceWorkerId = 1;
@@ -589,6 +590,36 @@ export class McpContext implements Context {
589590
this.#options.experimentalIncludeAllPages,
590591
);
591592

593+
const allTargets = this.browser.targets();
594+
const extensionTargets = allTargets.filter(target => {
595+
return (
596+
target.url().startsWith('chrome-extension://') &&
597+
target.type() === 'page'
598+
);
599+
});
600+
601+
for (const target of extensionTargets) {
602+
// Right now target.page() returns null for popup and side panel pages.
603+
let page = await target.page();
604+
if (!page) {
605+
// We need to cache pages instances for targets because target.asPage()
606+
// returns a new page instance every time.
607+
page = this.#extensionPages.get(target) ?? null;
608+
if (!page) {
609+
try {
610+
page = await target.asPage();
611+
this.#extensionPages.set(target, page);
612+
} catch (e) {
613+
this.logger('Failed to get page for extension target', e);
614+
}
615+
}
616+
}
617+
618+
if (page && !allPages.includes(page)) {
619+
allPages.push(page);
620+
}
621+
}
622+
592623
// Build a reverse lookup from BrowserContext instance → name.
593624
const contextToName = new Map<BrowserContext, string>();
594625
for (const [name, ctx] of this.#isolatedContexts) {

src/McpResponse.ts

Lines changed: 68 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

7-
import type {ParsedArguments} from './cli.js';
7+
import type {ParsedArguments} from './bin/chrome-devtools-mcp-cli-options.js';
88
import {ConsoleFormatter} from './formatters/ConsoleFormatter.js';
99
import {IssueFormatter} from './formatters/IssueFormatter.js';
1010
import {NetworkFormatter} from './formatters/NetworkFormatter.js';
@@ -16,6 +16,7 @@ import {DevTools} from './third_party/index.js';
1616
import type {
1717
ConsoleMessage,
1818
ImageContent,
19+
Page,
1920
ResourceType,
2021
TextContent,
2122
} from './third_party/index.js';
@@ -42,6 +43,7 @@ interface TraceInsightData {
4243
export class McpResponse implements Response {
4344
#includePages = false;
4445
#includeExtensionServiceWorkers = false;
46+
#includeExtensionPages = false;
4547
#snapshotParams?: SnapshotParams;
4648
#attachedNetworkRequestId?: number;
4749
#attachedNetworkRequestOptions?: {
@@ -94,6 +96,7 @@ export class McpResponse implements Response {
9496

9597
if (this.#args.categoryExtensions) {
9698
this.#includeExtensionServiceWorkers = value;
99+
this.#includeExtensionPages = value;
97100
}
98101
}
99102

@@ -501,6 +504,7 @@ export class McpResponse implements Response {
501504
pages?: object[];
502505
pagination?: object;
503506
extensionServiceWorkers?: object[];
507+
extensionPages?: object[];
504508
} = {};
505509

506510
const response = [];
@@ -559,34 +563,54 @@ Call ${handleDialog.name} to handle it before continuing.`);
559563
}
560564

561565
if (this.#includePages) {
562-
const parts = [`## Pages`];
563-
for (const page of context.getPages()) {
564-
const isolatedContextName = context.getIsolatedContextName(page);
565-
const contextLabel = isolatedContextName
566-
? ` isolatedContext=${isolatedContextName}`
567-
: '';
568-
parts.push(
569-
`${context.getPageId(page)}: ${page.url()}${context.isPageSelected(page) ? ' [selected]' : ''}${contextLabel}`,
570-
);
566+
const allPages = context.getPages();
567+
568+
const {regularPages, extensionPages} = allPages.reduce(
569+
(acc: {regularPages: Page[]; extensionPages: Page[]}, page: Page) => {
570+
if (page.url().startsWith('chrome-extension://')) {
571+
acc.extensionPages.push(page);
572+
} else {
573+
acc.regularPages.push(page);
574+
}
575+
return acc;
576+
},
577+
{regularPages: [], extensionPages: []},
578+
);
579+
580+
if (regularPages.length) {
581+
const parts = [`## Pages`];
582+
const structuredPages = [];
583+
for (const page of regularPages) {
584+
const isolatedContextName = context.getIsolatedContextName(page);
585+
const contextLabel = isolatedContextName
586+
? ` isolatedContext=${isolatedContextName}`
587+
: '';
588+
parts.push(
589+
`${context.getPageId(page)}: ${page.url()}${context.isPageSelected(page) ? ' [selected]' : ''}${contextLabel}`,
590+
);
591+
structuredPages.push(createStructuredPage(page, context));
592+
}
593+
response.push(...parts);
594+
structuredContent.pages = structuredPages;
571595
}
572-
response.push(...parts);
573-
structuredContent.pages = context.getPages().map(page => {
574-
const isolatedContextName = context.getIsolatedContextName(page);
575-
const entry: {
576-
id: number | undefined;
577-
url: string;
578-
selected: boolean;
579-
isolatedContext?: string;
580-
} = {
581-
id: context.getPageId(page),
582-
url: page.url(),
583-
selected: context.isPageSelected(page),
584-
};
585-
if (isolatedContextName) {
586-
entry.isolatedContext = isolatedContextName;
596+
597+
if (this.#includeExtensionPages) {
598+
if (extensionPages.length) {
599+
response.push(`## Extension Pages`);
600+
const structuredExtensionPages = [];
601+
for (const page of extensionPages) {
602+
const isolatedContextName = context.getIsolatedContextName(page);
603+
const contextLabel = isolatedContextName
604+
? ` isolatedContext=${isolatedContextName}`
605+
: '';
606+
response.push(
607+
`${context.getPageId(page)}: ${page.url()}${context.isPageSelected(page) ? ' [selected]' : ''}${contextLabel}`,
608+
);
609+
structuredExtensionPages.push(createStructuredPage(page, context));
610+
}
611+
structuredContent.extensionPages = structuredExtensionPages;
587612
}
588-
return entry;
589-
});
613+
}
590614
}
591615

592616
if (this.#includeExtensionServiceWorkers) {
@@ -803,3 +827,20 @@ Call ${handleDialog.name} to handle it before continuing.`);
803827
this.#textResponseLines = [];
804828
}
805829
}
830+
function createStructuredPage(page: Page, context: McpContext) {
831+
const isolatedContextName = context.getIsolatedContextName(page);
832+
const entry: {
833+
id: number | undefined;
834+
url: string;
835+
selected: boolean;
836+
isolatedContext?: string;
837+
} = {
838+
id: context.getPageId(page),
839+
url: page.url(),
840+
selected: context.isPageSelected(page),
841+
};
842+
if (isolatedContextName) {
843+
entry.isolatedContext = isolatedContextName;
844+
}
845+
return entry;
846+
}

0 commit comments

Comments
 (0)