Skip to content

Commit cb092f8

Browse files
committed
Add extension-backed unique page tools
1 parent 86ffd58 commit cb092f8

8 files changed

Lines changed: 603 additions & 4 deletions

File tree

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -487,12 +487,14 @@ If you run into any issues, checkout our [troubleshooting guide](./docs/troubles
487487
- [`press_key`](docs/tool-reference.md#press_key)
488488
- [`type_text`](docs/tool-reference.md#type_text)
489489
- [`upload_file`](docs/tool-reference.md#upload_file)
490-
- **Navigation automation** (6 tools)
490+
- **Navigation automation** (8 tools)
491491
- [`close_page`](docs/tool-reference.md#close_page)
492492
- [`list_pages`](docs/tool-reference.md#list_pages)
493+
- [`list_unique_pages`](docs/tool-reference.md#list_unique_pages)
493494
- [`navigate_page`](docs/tool-reference.md#navigate_page)
494495
- [`new_page`](docs/tool-reference.md#new_page)
495496
- [`select_page`](docs/tool-reference.md#select_page)
497+
- [`select_unique_page`](docs/tool-reference.md#select_unique_page)
496498
- [`wait_for`](docs/tool-reference.md#wait_for)
497499
- **Emulation** (2 tools)
498500
- [`emulate`](docs/tool-reference.md#emulate)

docs/tool-reference.md

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<!-- AUTO GENERATED DO NOT EDIT - run 'npm run gen' to update-->
22

3-
# Chrome DevTools MCP Tool Reference (~7005 cl100k_base tokens)
3+
# Chrome DevTools MCP Tool Reference (~7304 cl100k_base tokens)
44

55
- **[Input automation](#input-automation)** (9 tools)
66
- [`click`](#click)
@@ -12,12 +12,14 @@
1212
- [`press_key`](#press_key)
1313
- [`type_text`](#type_text)
1414
- [`upload_file`](#upload_file)
15-
- **[Navigation automation](#navigation-automation)** (6 tools)
15+
- **[Navigation automation](#navigation-automation)** (8 tools)
1616
- [`close_page`](#close_page)
1717
- [`list_pages`](#list_pages)
18+
- [`list_unique_pages`](#list_unique_pages)
1819
- [`navigate_page`](#navigate_page)
1920
- [`new_page`](#new_page)
2021
- [`select_page`](#select_page)
22+
- [`select_unique_page`](#select_unique_page)
2123
- [`wait_for`](#wait_for)
2224
- **[Emulation](#emulation)** (2 tools)
2325
- [`emulate`](#emulate)
@@ -164,6 +166,14 @@
164166

165167
---
166168

169+
### `list_unique_pages`
170+
171+
**Description:** Get a list of pages open in the browser enriched with Chrome tabId identity from the tab-ID extension when available.
172+
173+
**Parameters:** None
174+
175+
---
176+
167177
### `navigate_page`
168178

169179
**Description:** Go to a URL, or back, forward, or reload. Use project URL if not specified otherwise.
@@ -203,6 +213,17 @@
203213

204214
---
205215

216+
### `select_unique_page`
217+
218+
**Description:** Select a page using its Chrome tabId as reported by the tab-ID extension.
219+
220+
**Parameters:**
221+
222+
- **tabId** (number) **(required)**: The Chrome tabId to select. Call [`list_unique_pages`](#list_unique_pages) to find available tab IDs.
223+
- **bringToFront** (boolean) _(optional)_: Whether to focus the page and bring it to the top.
224+
225+
---
226+
206227
### `wait_for`
207228

208229
**Description:** Wait for the specified text to appear on the selected page.

src/McpResponse.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import type {
3333
LighthouseData,
3434
Response,
3535
SnapshotParams,
36+
UniquePageData,
3637
} from './tools/ToolDefinition.js';
3738
import type {InsightName, TraceResult} from './trace-processing/parse.js';
3839
import {getInsightOutput, getTraceSummary} from './trace-processing/parse.js';
@@ -197,6 +198,7 @@ export class McpResponse implements Response {
197198
#listWebMcpTools?: boolean;
198199
#devToolsData?: DevToolsData;
199200
#tabId?: string;
201+
#uniquePages?: UniquePageData[];
200202
#args: ParsedArguments;
201203
#page?: McpPage;
202204
#redactNetworkHeaders = true;
@@ -221,6 +223,10 @@ export class McpResponse implements Response {
221223
this.#tabId = tabId;
222224
}
223225

226+
setUniquePages(uniquePages: UniquePageData[]): void {
227+
this.#uniquePages = uniquePages;
228+
}
229+
224230
setIncludePages(value: boolean): void {
225231
this.#includePages = value;
226232

@@ -698,6 +704,7 @@ export class McpResponse implements Response {
698704
defaultValue?: string;
699705
};
700706
pages?: object[];
707+
uniquePages?: object[];
701708
pagination?: object;
702709
heapSnapshot?: {
703710
stats?: object;
@@ -838,6 +845,30 @@ Call ${handleDialog.name} to handle it before continuing.`);
838845
structuredContent.tabId = this.#tabId;
839846
}
840847

848+
if (this.#uniquePages) {
849+
if (this.#uniquePages.length) {
850+
response.push('## Unique Pages');
851+
for (const page of this.#uniquePages) {
852+
const parts = [
853+
`${page.pageId}:`,
854+
`status=${page.identityStatus}`,
855+
`tabId=${page.tabId ?? 'null'}`,
856+
page.url,
857+
];
858+
if (page.selected) {
859+
parts.push('[selected]');
860+
}
861+
if (page.error) {
862+
parts.push(`error="${page.error}"`);
863+
}
864+
response.push(parts.join(' '));
865+
}
866+
} else {
867+
response.push('No pages found.');
868+
}
869+
structuredContent.uniquePages = this.#uniquePages;
870+
}
871+
841872
if (data.traceSummary) {
842873
const summary = getTraceSummary(data.traceSummary);
843874
response.push(summary);

src/bin/cliDefinitions.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,12 @@ export const commands: Commands = {
380380
category: 'Navigation automation',
381381
args: {},
382382
},
383+
list_unique_pages: {
384+
description:
385+
'Get a list of pages open in the browser enriched with Chrome tabId identity from the tab-ID extension when available.',
386+
category: 'Navigation automation',
387+
args: {},
388+
},
383389
navigate_page: {
384390
description:
385391
'Go to a URL, or back, forward, or reload. Use project URL if not specified otherwise.',
@@ -587,6 +593,26 @@ export const commands: Commands = {
587593
},
588594
},
589595
},
596+
select_unique_page: {
597+
description:
598+
'Select a page using its Chrome tabId as reported by the tab-ID extension.',
599+
category: 'Navigation automation',
600+
args: {
601+
tabId: {
602+
name: 'tabId',
603+
type: 'number',
604+
description:
605+
'The Chrome tabId to select. Call list_unique_pages to find available tab IDs.',
606+
required: true,
607+
},
608+
bringToFront: {
609+
name: 'bringToFront',
610+
type: 'boolean',
611+
description: 'Whether to focus the page and bring it to the top.',
612+
required: false,
613+
},
614+
},
615+
},
590616
take_memory_snapshot: {
591617
description:
592618
'Capture a heap snapshot of the currently selected page. Use to analyze the memory distribution of JavaScript objects and debug memory leaks.',

src/telemetry/tool_call_metrics.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,5 +586,22 @@
586586
"argType": "number"
587587
}
588588
]
589+
},
590+
{
591+
"name": "list_unique_pages",
592+
"args": []
593+
},
594+
{
595+
"name": "select_unique_page",
596+
"args": [
597+
{
598+
"name": "tab_id",
599+
"argType": "number"
600+
},
601+
{
602+
"name": "bring_to_front",
603+
"argType": "boolean"
604+
}
605+
]
589606
}
590607
]

src/tools/ToolDefinition.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,27 @@ export interface DevToolsData {
9999
cdpBackendNodeId?: number;
100100
}
101101

102+
export type UniquePageIdentityStatus =
103+
| 'resolved'
104+
| 'extension_unavailable'
105+
| 'unsupported_page'
106+
| 'script_failed'
107+
| 'no_tab_context';
108+
109+
export interface UniquePageData {
110+
pageId: number;
111+
tabId: number | null;
112+
selected: boolean;
113+
url: string;
114+
title: string;
115+
identityStatus: UniquePageIdentityStatus;
116+
uid?: string;
117+
windowId?: number;
118+
tabIndex?: number;
119+
tabNumber?: number;
120+
error?: string;
121+
}
122+
102123
export interface Response {
103124
appendResponseLine(value: string): void;
104125
setHeapSnapshotAggregates(
@@ -138,6 +159,7 @@ export interface Response {
138159
// Allows re-using DevTools data queried by some tools.
139160
attachDevToolsData(data: DevToolsData): void;
140161
setTabId(tabId: string): void;
162+
setUniquePages(uniquePages: UniquePageData[]): void;
141163
attachTraceSummary(trace: TraceResult): void;
142164
attachTraceInsight(
143165
trace: TraceResult,
@@ -222,6 +244,11 @@ export type Context = Readonly<{
222244
listExtensions(): Promise<Map<string, Extension>>;
223245
getExtension(id: string): Promise<Extension | undefined>;
224246
getSelectedMcpPage(): McpPage;
247+
createPagesSnapshot(): Promise<Page[]>;
248+
getPages(): Page[];
249+
getPageId(page: Page): number | undefined;
250+
isPageSelected(page: Page): boolean;
251+
getIsolatedContextName(page: Page): string | undefined;
225252
getExtensionServiceWorkers(): ExtensionServiceWorker[];
226253
getExtensionServiceWorkerId(
227254
extensionServiceWorker: ExtensionServiceWorker,

0 commit comments

Comments
 (0)