Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions src/McpPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import type {
Viewport,
WebMCPTool,
} from './third_party/index.js';
import type {ToolGroup, ToolDefinition} from './tools/inPage.js';
import {takeSnapshot} from './tools/snapshot.js';
import type {ToolGroup, ToolDefinition} from './tools/thirdPartyDeveloper.js';
import type {
ContextPage,
DevToolsData,
Expand Down Expand Up @@ -58,7 +58,7 @@ export class McpPage implements ContextPage {
#dialog?: Dialog;
#dialogHandler: (dialog: Dialog) => void;

inPageTools: ToolGroup<ToolDefinition> | undefined;
thirdPartyDeveloperTools: ToolGroup<ToolDefinition> | undefined;

constructor(page: Page, id: number) {
this.pptrPage = page;
Expand Down Expand Up @@ -89,8 +89,8 @@ export class McpPage implements ContextPage {
}
}

getInPageTools(): ToolGroup<ToolDefinition> | undefined {
return this.inPageTools;
getThirdPartyDeveloperTools(): ToolGroup<ToolDefinition> | undefined {
return this.thirdPartyDeveloperTools;
}

getWebMcpTools(): WebMCPTool[] {
Expand Down Expand Up @@ -144,7 +144,7 @@ export class McpPage implements ContextPage {
this.pptrPage.off('dialog', this.#dialogHandler);
}

async executeInPageTool(
async executeThirdPartyDeveloperTool(
toolName: string,
params: Record<string, unknown>,
response: Response,
Expand Down
40 changes: 22 additions & 18 deletions src/McpResponse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ import type {
JSONSchema7Definition,
Extension,
} from './third_party/index.js';
import type {ToolGroup, ToolDefinition} from './tools/inPage.js';
import {handleDialog} from './tools/pages.js';
import type {ToolGroup, ToolDefinition} from './tools/thirdPartyDeveloper.js';
import type {
DevToolsData,
ImageContentData,
Expand Down Expand Up @@ -196,7 +196,7 @@ export class McpResponse implements Response {
includePreservedMessages?: boolean;
};
#listExtensions?: boolean;
#listInPageTools?: boolean;
#listThirdPartyDeveloperTools?: boolean;
#listWebMcpTools?: boolean;
#devToolsData?: DevToolsData;
#tabId?: string;
Expand Down Expand Up @@ -244,9 +244,9 @@ export class McpResponse implements Response {
this.#listExtensions = true;
}

setListInPageTools(): void {
if (this.#args.categoryInPageTools) {
this.#listInPageTools = true;
setListThirdPartyDeveloperTools(): void {
if (this.#args.categoryThirdPartyDeveloperTools) {
this.#listThirdPartyDeveloperTools = true;
}
}

Expand Down Expand Up @@ -552,11 +552,11 @@ export class McpResponse implements Response {
extensions = await context.listExtensions();
}

let inPageTools: ToolGroup<ToolDefinition> | undefined;
if (this.#listInPageTools) {
let thirdPartyDeveloperTools: ToolGroup<ToolDefinition> | undefined;
if (this.#listThirdPartyDeveloperTools) {
const page = this.#page ?? context.getSelectedMcpPage();
inPageTools = await getToolGroup(page);
page.inPageTools = inPageTools;
thirdPartyDeveloperTools = await getToolGroup(page);
page.thirdPartyDeveloperTools = thirdPartyDeveloperTools;
}

let webmcpTools: WebMCPTool[] | undefined;
Expand Down Expand Up @@ -669,7 +669,7 @@ export class McpResponse implements Response {
traceSummary: this.#attachedTraceSummary,
extensions,
lighthouseResult: this.#attachedLighthouseResult,
inPageTools,
thirdPartyDeveloperTools,
webmcpTools,
errorMessage: this.#error?.message,
});
Expand All @@ -688,7 +688,7 @@ export class McpResponse implements Response {
traceInsight?: TraceInsightData;
extensions?: Map<string, Extension>;
lighthouseResult?: LighthouseData;
inPageTools?: ToolGroup<ToolDefinition>;
thirdPartyDeveloperTools?: ToolGroup<ToolDefinition>;
webmcpTools?: WebMCPTool[];
errorMessage?: string;
},
Expand All @@ -705,7 +705,7 @@ export class McpResponse implements Response {
traceInsights?: Array<{insightName: string; insightKey: string}>;
lighthouseResult?: object;
extensions?: object[];
inPageTools?: object;
thirdPartyDeveloperTools?: object;
webmcpTools?: object[];
message?: string;
networkConditions?: string;
Expand Down Expand Up @@ -1004,13 +1004,17 @@ Call ${handleDialog.name} to handle it before continuing.`);
}
}

if (this.#listInPageTools) {
structuredContent.inPageTools = data.inPageTools ?? undefined;
response.push('## In-page tools');
if (!data.inPageTools || !data.inPageTools.tools) {
response.push('No in-page tools available.');
if (this.#listThirdPartyDeveloperTools) {
structuredContent.thirdPartyDeveloperTools =
data.thirdPartyDeveloperTools ?? undefined;
response.push('## Third-party developer tools');
if (
!data.thirdPartyDeveloperTools ||
!data.thirdPartyDeveloperTools.tools
) {
response.push('No third-party developer tools available.');
} else {
const toolGroup = data.inPageTools;
const toolGroup = data.thirdPartyDeveloperTools;
response.push(`${toolGroup.name}: ${toolGroup.description}`);
response.push('Available tools:');
const toolDefinitionsMessage = toolGroup.tools
Expand Down
4 changes: 2 additions & 2 deletions src/TextSnapshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,8 @@ export class TextSnapshot {
}

// ExtraHandles represent DOM nodes which might not be part of the accessibility tree, e.g. DOM nodes
// returned by in-page tools. We insert them into the tree by finding the closest ancestor in the
// tree and inserting the node as a child. The ancestor's child nodes are re-parented if necessary.
// returned by third-party developer tools. We insert them into the tree by finding the closest ancestor
// in the tree and inserting the node as a child. The ancestor's child nodes are re-parented if necessary.
private static async insertExtraNodes(
page: McpPage,
idToNode: Map<string, TextSnapshotNode>,
Expand Down
4 changes: 2 additions & 2 deletions src/bin/chrome-devtools-mcp-cli-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,11 +237,11 @@ export const cliOptions = {
describe:
'Set to true to include tools related to extensions. Note: This feature is currently only supported with a pipe connection. autoConnect, browserUrl, and wsEndpoint are not supported with this feature until 149 will be released.',
},
categoryInPageTools: {
categoryThirdPartyDeveloperTools: {
type: 'boolean',
hidden: true,
describe:
'Set to true to enable tools exposed by the inspected page itself',
'Set to true to enable third-party developer tools exposed by the inspected page itself',
},
performanceCrux: {
type: 'boolean',
Expand Down
4 changes: 2 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,8 @@ export async function createMcpServer(
return;
}
if (
tool.annotations.category === ToolCategory.IN_PAGE &&
!serverArgs.categoryInPageTools
tool.annotations.category === ToolCategory['3P_DEVELOPER'] &&
!serverArgs.categoryThirdPartyDeveloperTools
) {
return;
}
Expand Down
4 changes: 2 additions & 2 deletions src/telemetry/flag_usage_metrics.json
Original file line number Diff line number Diff line change
Expand Up @@ -191,11 +191,11 @@
"flagType": "boolean"
},
{
"name": "category_in_page_tools",
"name": "category_third_party_developer_tools",
"flagType": "boolean"
},
{
"name": "category_in_page_tools_present",
"name": "category_third_party_developer_tools_present",
"flagType": "boolean"
},
{
Expand Down
4 changes: 2 additions & 2 deletions src/telemetry/tool_call_metrics.json
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@
]
},
{
"name": "execute_in_page_tool",
"name": "execute_3p_developer_tool",
"args": [
{
"name": "tool_name_length",
Expand Down Expand Up @@ -253,7 +253,7 @@
"args": []
},
{
"name": "list_in_page_tools",
"name": "list_3p_developer_tools",
"args": []
},
{
Expand Down
12 changes: 7 additions & 5 deletions src/tools/ToolDefinition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ import type {PaginationOptions} from '../utils/types.js';
import type {ToolCategory} from './categories.js';
import type {
ToolGroup,
ToolDefinition as InPageToolDefinition,
} from './inPage.js';
ToolDefinition as ThirdPartyDeveloperToolDefinition,
} from './thirdPartyDeveloper.js';

export interface BaseToolDefinition<
Schema extends zod.ZodRawShape = zod.ZodRawShape,
Expand Down Expand Up @@ -151,7 +151,7 @@ export interface Response {
): void;
setListExtensions(): void;
attachLighthouseResult(result: LighthouseData): void;
setListInPageTools(): void;
setListThirdPartyDeveloperTools(): void;
setListWebMcpTools(): void;
}

Expand Down Expand Up @@ -261,8 +261,10 @@ export type ContextPage = Readonly<{
action: () => Promise<unknown>,
options?: {timeout?: number; handleDialog?: 'accept' | 'dismiss' | string},
): Promise<void>;
getInPageTools(): ToolGroup<InPageToolDefinition> | undefined;
executeInPageTool(
getThirdPartyDeveloperTools():
| ToolGroup<ThirdPartyDeveloperToolDefinition>
| undefined;
executeThirdPartyDeveloperTool(
toolName: string,
params: Record<string, unknown>,
response: Response,
Expand Down
4 changes: 2 additions & 2 deletions src/tools/categories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export enum ToolCategory {
NETWORK = 'network',
DEBUGGING = 'debugging',
EXTENSIONS = 'extensions',
IN_PAGE = 'in-page',
'3P_DEVELOPER' = '3p-developer',
MEMORY = 'memory',
}

Expand All @@ -24,7 +24,7 @@ export const labels = {
[ToolCategory.NETWORK]: 'Network',
[ToolCategory.DEBUGGING]: 'Debugging',
[ToolCategory.EXTENSIONS]: 'Extensions',
[ToolCategory.IN_PAGE]: 'In-page tools',
[ToolCategory['3P_DEVELOPER']]: 'Third-party developer tools',
[ToolCategory.MEMORY]: 'Memory',
};

Expand Down
10 changes: 5 additions & 5 deletions src/tools/pages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export const listPages = defineTool(args => {
blockedByDialog: false,
handler: async (_request, response) => {
response.setIncludePages(true);
response.setListInPageTools();
response.setListThirdPartyDeveloperTools();
response.setListWebMcpTools();
},
};
Expand Down Expand Up @@ -116,7 +116,7 @@ export const selectPage = defineTool({
const page = context.getPageById(request.params.pageId);
context.selectPage(page);
response.setIncludePages(true);
response.setListInPageTools();
response.setListThirdPartyDeveloperTools();
response.setListWebMcpTools();
if (request.params.bringToFront) {
await page.pptrPage.bringToFront();
Expand Down Expand Up @@ -148,7 +148,7 @@ export const closePage = defineTool({
}
}
response.setIncludePages(true);
response.setListInPageTools();
response.setListThirdPartyDeveloperTools();
},
});

Expand Down Expand Up @@ -206,7 +206,7 @@ export const newPage = defineTool(args => {
);

response.setIncludePages(true);
response.setListInPageTools();
response.setListThirdPartyDeveloperTools();
},
};
});
Expand Down Expand Up @@ -373,7 +373,7 @@ export const navigatePage = definePageTool(args => {
}

response.setIncludePages(true);
response.setListInPageTools();
response.setListThirdPartyDeveloperTools();
response.setListWebMcpTools();
},
};
Expand Down
36 changes: 20 additions & 16 deletions src/tools/inPage.ts → src/tools/thirdPartyDeveloper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,34 +36,34 @@ declare global {
}
}

export const listInPageTools = definePageTool({
name: 'list_in_page_tools',
description: `Lists all in-page tools the page exposes for providing runtime information.
In-page tools can be called via the 'execute_in_page_tool()' MCP tool.
Alternatively, in-page tools can be executed by calling 'evaluate_script' and adding the
export const listThirdPartyDeveloperTools = definePageTool({
name: 'list_3p_developer_tools',
description: `Lists all third-party developer tools the page exposes for providing runtime information.
Third-party developer tools can be called via the 'execute_3p_developer_tool()' MCP tool.
Alternatively, third-party developer tools can be executed by calling 'evaluate_script' and adding the
following command to the script:
'window.__dtmcp.executeTool(toolName, params)'
This might be helpful when the in-page-tools return non-serializable values or when composing
the in-page-tools with additional functionality.`,
This might be helpful when the third-party developer tools return non-serializable values or when composing
third-party developer tools with additional functionality.`,
annotations: {
category: ToolCategory.IN_PAGE,
category: ToolCategory['3P_DEVELOPER'],
readOnlyHint: true,
conditions: ['inPageTools'],
conditions: ['thirdPartyDeveloperTools'],
},
schema: {},
blockedByDialog: false,
handler: async (_request, response, _context) => {
response.setListInPageTools();
response.setListThirdPartyDeveloperTools();
},
});

export const executeInPageTool = definePageTool({
name: 'execute_in_page_tool',
export const executeThirdPartyDeveloperTool = definePageTool({
name: 'execute_3p_developer_tool',
description: `Executes a tool exposed by the page.`,
annotations: {
category: ToolCategory.IN_PAGE,
category: ToolCategory['3P_DEVELOPER'],
readOnlyHint: false,
conditions: ['inPageTools'],
conditions: ['thirdPartyDeveloperTools'],
},
schema: {
toolName: zod.string().describe('The name of the tool to execute'),
Expand All @@ -90,7 +90,7 @@ export const executeInPageTool = definePageTool({
}
}

const toolGroup = request.page.getInPageTools();
const toolGroup = request.page.getThirdPartyDeveloperTools();
const tool = toolGroup?.tools.find(t => t.name === toolName);
if (!tool) {
throw new Error(`Tool ${toolName} not found`);
Expand All @@ -104,6 +104,10 @@ export const executeInPageTool = definePageTool({
);
}

await request.page.executeInPageTool(toolName, params, response);
await request.page.executeThirdPartyDeveloperTool(
toolName,
params,
response,
);
},
});
Loading
Loading