read_page_html
Retrieve the complete HTML source of the currently active browser tab to inspect page structure and content.
Instructions
Read the full HTML source of the current page
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| tabId | No | Target tab ID (defaults to active tab) | |
| apiKey | No | API key for authentication |
Implementation Reference
- src/tools/devtools-sources.ts:6-26 (registration)Registers the 'read_page_html' MCP tool with the server, defining its name, description, input schema (optional tabId and apiKey), and handler that sends a command via WebSocket bridge.
export function registerDevtoolsSourcesTools(server: McpServer, bridge: WebSocketBridge) { server.tool( 'read_page_html', 'Read the full HTML source of the current page', { tabId: z.number().optional().describe('Target tab ID (defaults to active tab)'), apiKey: z.string().optional().describe('API key for authentication'), }, async ({ tabId, apiKey }) => { const result = await bridge.sendCommand({ command: 'read_page_html', params: {}, tabId, apiKey, }); if (!result.success) { return { content: [{ type: 'text', text: `Error: ${result.error?.message}` }], isError: true }; } return { content: [{ type: 'text', text: result.data as string }] }; } ); - src/tools/devtools-sources.ts:14-25 (handler)The handler function that executes the tool: sends a 'read_page_html' command via WebSocketBridge.sendCommand and returns the HTML as text, or an error message if the command fails.
async ({ tabId, apiKey }) => { const result = await bridge.sendCommand({ command: 'read_page_html', params: {}, tabId, apiKey, }); if (!result.success) { return { content: [{ type: 'text', text: `Error: ${result.error?.message}` }], isError: true }; } return { content: [{ type: 'text', text: result.data as string }] }; } - src/tools/devtools-sources.ts:10-13 (schema)Input schema for the tool: tabId (optional number) and apiKey (optional string), validated with Zod.
{ tabId: z.number().optional().describe('Target tab ID (defaults to active tab)'), apiKey: z.string().optional().describe('API key for authentication'), }, - src/websocket-bridge.ts:63-103 (helper)The WebSocketBridge.sendCommand method that forwards the 'read_page_html' command to the Chrome extension via WebSocket and returns the response.
async sendCommand(cmd: BridgeCommand): Promise<BridgeResponse> { if (!this.isConnected()) { return { success: false, error: { code: 'NOT_CONNECTED', message: 'Chrome extension is not connected. Ensure the extension is installed, enabled, and the browser is running.', }, }; } const id = crypto.randomUUID(); const timeout = cmd.timeout ?? DEFAULT_TIMEOUT; return new Promise<BridgeResponse>((resolve, reject) => { const timer = setTimeout(() => { this.pending.delete(id); resolve({ success: false, error: { code: 'TIMEOUT', message: `Command '${cmd.command}' timed out after ${timeout}ms`, }, }); }, timeout); this.pending.set(id, { resolve, reject, timer }); const message = { id, type: 'request', command: cmd.command, params: cmd.params, tabId: cmd.tabId, apiKey: cmd.apiKey, timestamp: Date.now(), }; this.client!.send(JSON.stringify(message)); }); } - src/tools/index.ts:12-12 (helper)Import of registerDevtoolsSourcesTools from devtools-sources.ts, called at line 39 to register the tool.
import { registerDevtoolsSourcesTools } from './devtools-sources.js';