hover_element
Hover over elements to reveal dropdown menus, tooltips, and hover-only buttons or trigger CSS :hover states without clicking.
Instructions
Move mouse over an element without clicking. Use this to reveal dropdown menus, tooltips, hover-only buttons, or to trigger CSS :hover states.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| target | Yes | Element or position to hover over | |
| tabId | No | Target tab ID (defaults to active tab) | |
| apiKey | No | API key for authentication if enabled |
Implementation Reference
- src/tools/hover.ts:25-37 (handler)The async handler function that sends the 'hover_element' command via the WebSocket bridge and returns the result.
async ({ target, tabId, apiKey }) => { const result = await bridge.sendCommand({ command: 'hover_element', params: { target }, tabId, apiKey, }); if (!result.success) { return { content: [{ type: 'text', text: `Error: ${result.error?.message}` }], isError: true }; } return { content: [{ type: 'text', text: `Hovering over ${target.type === 'coordinates' ? `(${(target.value as any).x}, ${(target.value as any).y})` : target.value}` }] }; } ); - src/tools/hover.ts:5-14 (schema)The 'targetSchema' Zod schema defining input validation for the target parameter (coordinates, css, or xpath).
const targetSchema = z.object({ type: z.enum(['coordinates', 'css', 'xpath']).describe('Method to locate: "css" (most reliable), "xpath", or "coordinates"'), value: z.union([ z.string().describe('CSS selector or XPath to element'), z.object({ x: z.number().describe('X coordinate in pixels'), y: z.number().describe('Y coordinate in pixels') }).describe('Exact pixel coordinates'), ]).describe('The selector string or {x, y} coordinates object'), }); - src/tools/hover.ts:16-38 (registration)The 'registerHoverTools' function that registers the 'hover_element' tool on the MCP server with its name, description, schema, and handler.
export function registerHoverTools(server: McpServer, bridge: WebSocketBridge) { server.tool( 'hover_element', 'Move mouse over an element without clicking. Use this to reveal dropdown menus, tooltips, hover-only buttons, or to trigger CSS :hover states.', { target: targetSchema.describe('Element or position to hover over'), tabId: z.number().optional().describe('Target tab ID (defaults to active tab)'), apiKey: z.string().optional().describe('API key for authentication if enabled'), }, async ({ target, tabId, apiKey }) => { const result = await bridge.sendCommand({ command: 'hover_element', params: { target }, tabId, apiKey, }); if (!result.success) { return { content: [{ type: 'text', text: `Error: ${result.error?.message}` }], isError: true }; } return { content: [{ type: 'text', text: `Hovering over ${target.type === 'coordinates' ? `(${(target.value as any).x}, ${(target.value as any).y})` : target.value}` }] }; } ); } - src/tools/index.ts:29-55 (registration)The 'registerAllTools' function that calls registerHoverTools (indirect registration via index).
export function registerAllTools(server: McpServer, bridge: WebSocketBridge) { registerNavigationTools(server, bridge); registerTabManagementTools(server, bridge); registerKeyboardTools(server, bridge); registerScreenshotTools(server, bridge); registerClickTools(server, bridge); registerInputTools(server, bridge); registerDragDropTools(server, bridge); registerHoverTools(server, bridge); registerDevtoolsSourcesTools(server, bridge); registerDevtoolsModifyTools(server, bridge); registerDevtoolsNetworkTools(server, bridge); registerDevtoolsStorageTools(server, bridge); registerDevtoolsConsoleTools(server, bridge); registerAccessibilityTools(server, bridge); registerEmulationTools(server, bridge); registerElementTools(server, bridge); registerAuditTools(server, bridge); registerInteractionTools(server, bridge); registerMonitoringTools(server, bridge); registerQaTools(server, bridge); registerGestureTools(server, bridge); registerMacroTools(server, bridge); registerVisualRegressionTools(server, bridge); } - src/websocket-bridge.ts:63-103 (helper)The WebSocketBridge.sendCommand helper method that sends commands (including 'hover_element') to the browser extension.
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)); }); }