wait_for_condition
Polls a JavaScript expression at a set interval until it returns true or a timeout expires, then reports whether the condition was met and the time taken.
Instructions
Wait until a JavaScript condition evaluates to true. Polls the expression at the specified interval until the timeout. Returns whether the condition was met and how long it took.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| expression | Yes | JavaScript expression that returns truthy when condition is met | |
| timeout | No | Max wait time in ms | |
| interval | No | Polling interval in ms | |
| tabId | No | Target tab ID (defaults to currently active tab) | |
| apiKey | No | API key for authentication if enabled |
Implementation Reference
- src/tools/qa.ts:219-242 (handler)The tool handler for 'wait_for_condition'. It registers an MCP tool that accepts expression, timeout, interval, tabId, and apiKey, then bridges the command to the Chrome extension via WebSocketBridge.sendCommand.
server.tool( 'wait_for_condition', 'Wait until a JavaScript condition evaluates to true. Polls the expression at the specified interval until the timeout. Returns whether the condition was met and how long it took.', { expression: z.string().describe('JavaScript expression that returns truthy when condition is met'), timeout: z.number().optional().default(10000).describe('Max wait time in ms'), interval: z.number().optional().default(500).describe('Polling interval in ms'), 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 ({ expression, timeout, interval, tabId, apiKey }) => { const result = await bridge.sendCommand({ command: 'wait_for_condition', params: { expression, timeout, interval }, tabId, apiKey, timeout: timeout + 5000, }); if (!result.success) { return { content: [{ type: 'text', text: `Error: ${result.error?.message}` }], isError: true }; } return { content: [{ type: 'text', text: JSON.stringify(result.data, null, 2) }] }; } ); - src/tools/qa.ts:219-242 (schema)The Zod schema defines inputs: expression (string, required), timeout (number, default 10000ms), interval (number, default 500ms), tabId (number, optional), and apiKey (string, optional).
server.tool( 'wait_for_condition', 'Wait until a JavaScript condition evaluates to true. Polls the expression at the specified interval until the timeout. Returns whether the condition was met and how long it took.', { expression: z.string().describe('JavaScript expression that returns truthy when condition is met'), timeout: z.number().optional().default(10000).describe('Max wait time in ms'), interval: z.number().optional().default(500).describe('Polling interval in ms'), 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 ({ expression, timeout, interval, tabId, apiKey }) => { const result = await bridge.sendCommand({ command: 'wait_for_condition', params: { expression, timeout, interval }, tabId, apiKey, timeout: timeout + 5000, }); if (!result.success) { return { content: [{ type: 'text', text: `Error: ${result.error?.message}` }], isError: true }; } return { content: [{ type: 'text', text: JSON.stringify(result.data, null, 2) }] }; } ); - src/tools/qa.ts:6-6 (registration)The tool is registered via registerQaTools() which calls server.tool('wait_for_condition', ...). This function is invoked from src/tools/index.ts line 51.
export function registerQaTools(server: McpServer, bridge: WebSocketBridge) { - src/websocket-bridge.ts:63-100 (helper)The WebSocketBridge.sendCommand method is the helper that sends the 'wait_for_condition' command to the Chrome extension via WebSocket, with timeout handling.
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(), };