|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +chrome-devtools-mcp is an MCP (Model Context Protocol) server that enables AI coding agents to control and inspect a live Chrome browser. It acts as a bridge between MCP clients (like Claude, Cursor, Copilot) and Chrome DevTools, exposing 27 tools across categories: input automation, navigation, emulation, performance, network, and debugging. |
| 8 | + |
| 9 | +## Build & Development Commands |
| 10 | + |
| 11 | +```bash |
| 12 | +# Install dependencies |
| 13 | +npm ci |
| 14 | + |
| 15 | +# Build (clean, compile TypeScript, post-build processing, rollup) |
| 16 | +npm run build |
| 17 | + |
| 18 | +# Type checking without emitting files |
| 19 | +npm run typecheck |
| 20 | + |
| 21 | +# Format code (ESLint + Prettier) |
| 22 | +npm run format |
| 23 | + |
| 24 | +# Check formatting without fixing |
| 25 | +npm run check-format |
| 26 | + |
| 27 | +# Start the MCP server |
| 28 | +npm run start |
| 29 | + |
| 30 | +# Start with debug logging |
| 31 | +npm run start-debug |
| 32 | + |
| 33 | +# Run all tests |
| 34 | +npm test |
| 35 | + |
| 36 | +# Run only tests marked with test.only |
| 37 | +npm run test:only |
| 38 | + |
| 39 | +# Run only tests without rebuilding first |
| 40 | +npm run test:only:no-build |
| 41 | + |
| 42 | +# Update test snapshots |
| 43 | +npm run test:update-snapshots |
| 44 | + |
| 45 | +# Generate tool reference documentation |
| 46 | +npm run docs:generate |
| 47 | + |
| 48 | +# Full docs generation (build + generate + format) |
| 49 | +npm run docs |
| 50 | +``` |
| 51 | + |
| 52 | +## Testing |
| 53 | + |
| 54 | +The project uses Node.js built-in test runner. Test files are in `tests/` directory mirroring the `src/` structure. |
| 55 | + |
| 56 | +**Run a single test file:** |
| 57 | +```bash |
| 58 | +npm run build && node --require ./build/tests/setup.js --no-warnings=ExperimentalWarning --test-reporter spec --test-force-exit --test build/tests/path/to/file.test.js |
| 59 | +``` |
| 60 | + |
| 61 | +**Run specific test with test.only:** |
| 62 | +```bash |
| 63 | +npm run test:only |
| 64 | +``` |
| 65 | + |
| 66 | +## Architecture |
| 67 | + |
| 68 | +### Entry Point Flow |
| 69 | +1. `src/index.ts` - Node version validation, imports main |
| 70 | +2. `src/main.ts` - Server setup, tool registration, stdio transport |
| 71 | +3. `src/cli.ts` - CLI argument parsing (yargs) |
| 72 | +4. `src/browser.ts` - Browser launch/connection via Puppeteer |
| 73 | + |
| 74 | +### Core Components |
| 75 | + |
| 76 | +**McpContext** (`src/McpContext.ts`) |
| 77 | +- Central state management for browser sessions |
| 78 | +- Manages pages, snapshots, network/console collectors |
| 79 | +- Handles emulation states (CPU throttling, network conditions) |
| 80 | +- Provides methods for page selection, element lookup by UID, dialog handling |
| 81 | +- Implements timeout adjustments based on throttling multipliers |
| 82 | + |
| 83 | +**McpResponse** (`src/McpResponse.ts`) |
| 84 | +- Response builder for MCP tool handlers |
| 85 | +- Aggregates content (text, images, network requests, console messages) |
| 86 | +- Handles pagination and filtering |
| 87 | +- Converts internal data structures to MCP-compatible JSON |
| 88 | + |
| 89 | +**Tool Definition Pattern** (`src/tools/ToolDefinition.ts`) |
| 90 | +- All tools use `defineTool()` helper |
| 91 | +- Each tool exports a ToolDefinition object with: |
| 92 | + - `name`: snake_case tool name |
| 93 | + - `description`: Tool purpose |
| 94 | + - `annotations`: category, readOnlyHint |
| 95 | + - `schema`: Zod schema for parameters |
| 96 | + - `handler`: async (request, response, context) => Promise<void> |
| 97 | + |
| 98 | +**Tool Categories** (`src/tools/categories.ts`) |
| 99 | +- INPUT_AUTOMATION: click, drag, fill, press_key, hover, etc. |
| 100 | +- NAVIGATION: list_pages, new_page, navigate_page, select_page, close_page, wait_for |
| 101 | +- EMULATION: emulate_cpu, emulate_network, resize_page |
| 102 | +- PERFORMANCE: performance_start_trace, performance_stop_trace, performance_analyze_insight |
| 103 | +- NETWORK: list_network_requests, get_network_request |
| 104 | +- DEBUGGING: evaluate_script, take_screenshot, take_snapshot, list_console_messages, get_console_message |
| 105 | + |
| 106 | +### Tool Organization |
| 107 | + |
| 108 | +Each category has its own file in `src/tools/`: |
| 109 | +- `pages.ts` - Navigation tools |
| 110 | +- `input.ts` - Input automation |
| 111 | +- `emulation.ts` - Emulation controls |
| 112 | +- `performance.ts` - Performance tracing |
| 113 | +- `network.ts` - Network inspection |
| 114 | +- `console.ts` - Console message access |
| 115 | +- `screenshot.ts` - Screenshot capture |
| 116 | +- `script.ts` - JavaScript evaluation |
| 117 | +- `snapshot.ts` - Accessibility tree snapshots |
| 118 | + |
| 119 | +### Key Utilities |
| 120 | + |
| 121 | +**PageCollector** (`src/PageCollector.ts`) |
| 122 | +- Generic collector for page-scoped resources (network requests, console messages) |
| 123 | +- Maintains stable IDs for resources across tool calls |
| 124 | +- Supports preserved items (pinned for later access) |
| 125 | + |
| 126 | +**WaitForHelper** (`src/WaitForHelper.ts`) |
| 127 | +- Waits for page events after actions (network idle, DOM mutations, etc.) |
| 128 | +- Adjusts timeouts based on CPU/network throttling |
| 129 | + |
| 130 | +**DevTools Integration** (`src/DevtoolsUtils.ts`, `src/DevToolsConnectionAdapter.ts`) |
| 131 | +- Manages connection to Chrome DevTools frontend |
| 132 | +- Handles performance trace processing via bundled DevTools code |
| 133 | +- Extracts insights from performance recordings |
| 134 | + |
| 135 | +**Trace Processing** (`src/trace-processing/parse.ts`) |
| 136 | +- Processes Chrome DevTools Performance traces |
| 137 | +- Extracts metrics, insights, and timeline data |
| 138 | +- Uses bundled DevTools frontend code for analysis |
| 139 | + |
| 140 | +### Bundling & Third-Party Code |
| 141 | + |
| 142 | +**Rollup Configuration** (`rollup.config.mjs`) |
| 143 | +- Bundles Puppeteer and its dependencies |
| 144 | +- Creates standalone executable with all deps in `build/node_modules` |
| 145 | +- Uses cleanup plugin to remove unnecessary code |
| 146 | + |
| 147 | +**Third-Party Wrapper** (`src/third_party/index.ts`) |
| 148 | +- Re-exports Puppeteer, MCP SDK, and other dependencies |
| 149 | +- Single import point for external libraries |
| 150 | + |
| 151 | +**DevTools Frontend** (`chrome-devtools-frontend` npm package) |
| 152 | +- Bundled Chrome DevTools code for trace processing |
| 153 | +- See `src/devtools.d.ts` for type definitions |
| 154 | + |
| 155 | +## Adding a New Tool |
| 156 | + |
| 157 | +1. Choose appropriate file in `src/tools/` based on category |
| 158 | +2. Define tool using `defineTool()` helper |
| 159 | +3. Export the tool definition |
| 160 | +4. Tool automatically registered in `src/main.ts` via Object.values() import |
| 161 | +5. Run `npm run docs` to regenerate tool reference documentation |
| 162 | +6. Add tests in `tests/tools/` |
| 163 | + |
| 164 | +## Documentation Generation |
| 165 | + |
| 166 | +Tool reference docs are auto-generated from tool definitions: |
| 167 | +- `scripts/generate-docs.ts` - Extracts tool metadata and generates markdown |
| 168 | +- Updates `docs/tool-reference.md` and README.md tool list |
| 169 | +- Run `npm run docs` after tool changes |
| 170 | + |
| 171 | +## Browser Connection Modes |
| 172 | + |
| 173 | +**Launched Mode** (default) |
| 174 | +- Server starts Chrome with puppeteer.launch() |
| 175 | +- Uses persistent user data dir: `~/.cache/chrome-devtools-mcp/chrome-profile-$CHANNEL` |
| 176 | +- Can use `--isolated` flag for temporary profile |
| 177 | + |
| 178 | +**Connected Mode** (`--browserUrl` or `--wsEndpoint`) |
| 179 | +- Connects to existing Chrome instance |
| 180 | +- Requires Chrome started with `--remote-debugging-port` |
| 181 | +- Supports custom WebSocket headers for auth |
| 182 | + |
| 183 | +## Important Notes |
| 184 | + |
| 185 | +- All tool calls are serialized via Mutex to prevent race conditions |
| 186 | +- Tools must call `await getContext()` to lazily initialize browser connection |
| 187 | +- Response builder methods (`setIncludePages`, `setIncludeNetworkRequests`, etc.) control what data is included in tool responses |
| 188 | +- Snapshot UIDs format: `{snapshotId}_{nodeId}` - stale snapshots rejected |
| 189 | +- Network requests and console messages have stable IDs for cross-tool reference |
| 190 | +- Dialog handling is page-specific via event listeners in McpContext |
| 191 | +- Timeouts auto-adjust based on CPU throttling and network emulation |
| 192 | +- DevTools windows are hidden from page list unless `--experimentalDevtools` enabled |
0 commit comments