navigate_to_url
Load any web page by navigating to a specified URL. Automatically waits for the page to finish loading.
Instructions
Load a web page in the browser. Use this whenever you need to go to a specific website or web address. Automatically waits for page to load.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Full URL including http:// or https:// (e.g., "https://google.com") | |
| tabId | No | Target tab ID (defaults to currently active tab) | |
| apiKey | No | API key for authentication if enabled |
Implementation Reference
- src/tools/navigation.ts:15-28 (handler)Handler function for the 'navigate_to_url' tool. Sends a 'navigate_to_url' command via WebSocket bridge, waits for response, and returns success/error text content.
async ({ url, tabId, apiKey }) => { const result = await bridge.sendCommand({ command: 'navigate_to_url', params: { url }, tabId, apiKey, timeout: LONG_TIMEOUT, }); if (!result.success) { return { content: [{ type: 'text', text: `Error: ${result.error?.message}` }], isError: true }; } return { content: [{ type: 'text', text: `Navigated to ${url}` }] }; } ); - src/tools/navigation.ts:10-14 (schema)Schema (Zod) definitions for navigate_to_url input: url (required string), tabId (optional number), apiKey (optional string).
{ url: z.string().describe('Full URL including http:// or https:// (e.g., "https://google.com")'), tabId: z.number().optional().describe('Target tab ID (defaults to currently active tab)'), apiKey: z.string().optional().describe('API key for authentication if enabled'), }, - src/tools/navigation.ts:6-28 (registration)Registration of navigate_to_url tool via server.tool() within the registerNavigationTools function, aggregated into registerAllTools in tools/index.ts.
export function registerNavigationTools(server: McpServer, bridge: WebSocketBridge) { server.tool( 'navigate_to_url', 'Load a web page in the browser. Use this whenever you need to go to a specific website or web address. Automatically waits for page to load.', { url: z.string().describe('Full URL including http:// or https:// (e.g., "https://google.com")'), tabId: z.number().optional().describe('Target tab ID (defaults to currently active tab)'), apiKey: z.string().optional().describe('API key for authentication if enabled'), }, async ({ url, tabId, apiKey }) => { const result = await bridge.sendCommand({ command: 'navigate_to_url', params: { url }, tabId, apiKey, timeout: LONG_TIMEOUT, }); if (!result.success) { return { content: [{ type: 'text', text: `Error: ${result.error?.message}` }], isError: true }; } return { content: [{ type: 'text', text: `Navigated to ${url}` }] }; } ); - src/websocket-bridge.ts:63-103 (helper)WebSocketBridge.sendCommand() helper used by the handler to send the command and await 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/types.ts:1-26 (helper)TypeScript interfaces (BridgeCommand, BridgeResponse) and LONG_TIMEOUT constant used by the navigate_to_url handler.
export interface BridgeCommand { command: string; params: Record<string, unknown>; tabId?: number; apiKey?: string; timeout?: number; } export interface BridgeResponse { success: boolean; data?: unknown; error?: { code: string; message: string; }; } export interface PendingRequest { resolve: (value: BridgeResponse) => void; reject: (error: Error) => void; timer: ReturnType<typeof setTimeout>; } export const DEFAULT_TIMEOUT = 30_000; export const LONG_TIMEOUT = 60_000; export const WEBSOCKET_PORT = parseInt(process.env.WEBSOCKET_PORT || '7890', 10);