Skip to content
Merged
2 changes: 1 addition & 1 deletion docs/tool-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ in the DevTools Elements panel (if any).

## Extensions

> NOTE: Extensions are not active by default. Use the '--category-extensions' flag
> NOTE: Extensions are not active by default. Use the '--categoryExtensions' flag
### `install_extension`

Expand Down
64 changes: 49 additions & 15 deletions scripts/generate-cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@ import {Client} from '@modelcontextprotocol/sdk/client/index.js';
import {StdioClientTransport} from '@modelcontextprotocol/sdk/client/stdio.js';

import {parseArguments} from '../build/src/bin/chrome-devtools-mcp-cli-options.js';
import {labels} from '../build/src/tools/categories.js';
import {buildFlag} from '../build/src/index.js';
import {
labels,
ToolCategory,
OFF_BY_DEFAULT_CATEGORIES,
} from '../build/src/tools/categories.js';
import {createTools} from '../build/src/tools/tools.js';

const OUTPUT_PATH = path.join(
Expand All @@ -29,7 +34,7 @@ async function fetchTools() {

const transport = new StdioClientTransport({
command: 'node',
args: [serverPath],
args: [serverPath, '--viaCli'],
env: {...process.env, CHROME_DEVTOOLS_MCP_NO_USAGE_STATISTICS: 'true'},
});

Expand Down Expand Up @@ -103,6 +108,15 @@ function schemaToCLIOptions(schema: JsonSchema): CliOption[] {
async function generateCli() {
const tools = await fetchTools();

const staticTools = createTools(parseArguments());
const toolNameToCategoryEnum = new Map<string, string>();
const toolNameToConditions = new Map<string, string[]>();

for (const tool of staticTools) {
toolNameToCategoryEnum.set(tool.name, tool.annotations.category);
toolNameToConditions.set(tool.name, tool.annotations.conditions || []);
}

// Sort tools by name
const sortedTools = tools
.sort((a, b) => a.name.localeCompare(b.name))
Expand All @@ -117,18 +131,17 @@ async function generateCli() {
if (tool.name === 'wait_for') {
return false;
}
// Skipping get_tab_id as it is for internal integrations
if (tool.name === 'get_tab_id') {
Comment thread
OrKoN marked this conversation as resolved.
return false;
}
// Skipping in_page tools as they are not launched yet
if (toolNameToCategoryEnum.get(tool.name) === ToolCategory.IN_PAGE) {
Comment thread
OrKoN marked this conversation as resolved.
return false;
}
return true;
});

const staticTools = createTools(parseArguments());
const toolNameToCategory = new Map<string, string>();
for (const tool of staticTools) {
toolNameToCategory.set(
tool.name,
labels[tool.annotations.category as keyof typeof labels],
);
}

const commands: Record<
string,
{description: string; category: string; args: Record<string, CliOption>}
Expand All @@ -140,15 +153,36 @@ async function generateCli() {
for (const opt of options) {
args[opt.name] = opt;
}
const category = toolNameToCategory.get(tool.name);
if (!category) {

const categoryEnum = toolNameToCategoryEnum.get(tool.name);
if (!categoryEnum) {
throw new Error(`Tool ${tool.name} has no category.`);
}
const category = labels[categoryEnum as unknown as keyof typeof labels];
if (!tool.description) {
throw new Error(`Tool ${tool.name} is missing descripttion`);
throw new Error(`Tool ${tool.name} is missing description`);
}

let description = tool.description;
const requiredFlags: string[] = [];

const isOffByDefault = OFF_BY_DEFAULT_CATEGORIES.includes(categoryEnum);
if (isOffByDefault) {
const categoryFlag = buildFlag(categoryEnum);
requiredFlags.push(`--${categoryFlag}=true`);
}

const conditions = toolNameToConditions.get(tool.name) || [];
for (const condition of conditions) {
requiredFlags.push(`--${condition}=true`);
}

if (requiredFlags.length > 0) {
description += ` (requires flag: ${requiredFlags.join(', ')})`;
}

commands[tool.name] = {
description: tool.description,
description,
category,
args,
};
Expand Down
8 changes: 7 additions & 1 deletion scripts/generate-docs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {get_encoding} from 'tiktoken';

import {cliOptions} from '../build/src/bin/chrome-devtools-mcp-cli-options.js';
import type {ParsedArguments} from '../build/src/bin/chrome-devtools-mcp-cli-options.js';
import {buildFlag} from '../build/src/index.js';
import {
ToolCategory,
OFF_BY_DEFAULT_CATEGORIES,
Expand Down Expand Up @@ -356,7 +357,7 @@ async function generateReference(
markdown += `## ${categoryName}\n\n`;

if (OFF_BY_DEFAULT_CATEGORIES.includes(category)) {
const flagName = `--category-${category}`;
const flagName = `--${buildFlag(category)}`;

markdown += `> NOTE: ${categoryName} are not active by default. Use the '${flagName}' flag\n\n`;
}
Expand Down Expand Up @@ -446,6 +447,11 @@ function getToolsAndCategories(tools: any) {
// Convert ToolDefinitions to ToolWithAnnotations
const toolsWithAnnotations: ToolWithAnnotations[] = tools
.filter(tool => {
// Skipping in_page tools as they are not launched yet
if (tool.annotations.category.includes('experimental')) {
return false;
}

if (!tool.annotations.conditions) {
return true;
}
Expand Down
21 changes: 21 additions & 0 deletions skills/chrome-devtools-cli/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,27 @@ chrome-devtools take_snapshot # Take a text snapshot of the page from the a11y t
chrome-devtools take_snapshot --verbose true --filePath "s.txt" # Take a verbose snapshot and save to file
```

## Extensions

```bash
chrome-devtools list_extensions # Lists all the Chrome extensions installed in the browser
chrome-devtools install_extension "/path/to/extension" # Installs a Chrome extension from the given path
chrome-devtools uninstall_extension "extension_id" # Uninstalls a Chrome extension by its ID
chrome-devtools reload_extension "extension_id" # Reloads an unpacked Chrome extension by its ID
chrome-devtools trigger_extension_action "extension_id" # Triggers the default action of an extension by its ID
```

## Experimental Features

Experimental tools are disabled by default. Enable them with the corresponding flag during `start`.

```bash
chrome-devtools click_at 100 200 # Clicks at the provided coordinates (requires --experimentalVision=true)
chrome-devtools screencast_start # Starts a screencast recording (requires --experimentalScreencast=true and ffmpeg)
chrome-devtools screencast_stop # Stops the active screencast
chrome-devtools list_webmcp_tools # List all WebMCP tools (requires --experimentalWebmcp=true)
```

## Service Management

```bash
Expand Down
2 changes: 1 addition & 1 deletion src/McpResponse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ export class McpResponse implements Response {
}

setListInPageTools(): void {
if (this.#args.categoryInPageTools) {
if (this.#args.categoryExperimentalInPage) {
this.#listInPageTools = true;
}
}
Expand Down
Loading
Loading