switch_context
Switch between NATIVE_APP and WEBVIEW_* contexts in hybrid mobile apps. Use accessibility IDs in native context, CSS/XPath in webview. Changes persist for all subsequent commands.
Instructions
Switches between native and webview automation contexts in a hybrid mobile app. In NATIVE_APP context, use accessibility IDs; in WEBVIEW_* context, use CSS/XPath. Changes persist for all subsequent commands. Accepts context name or 1-based index. Use get_contexts to discover available targets. Mobile-only.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| context | Yes | Context name to switch to (e.g., "NATIVE_APP", "WEBVIEW_com.example.app", or use index from wdio://session/current/contexts resource) |
Implementation Reference
- src/tools/context.tool.ts:20-49 (handler)The actual handler function that receives the context argument (name or index) and calls browser.switchContext(). Supports index-based switching (1-based) or direct context name switching.
export const switchContextTool: ToolCallback = async (args: { context: string; }): Promise<CallToolResult> => { try { const browser = getBrowser(); const { context } = args; if (/^\d+$/.test(context)) { const contexts = await browser.getContexts(); const index = Number.parseInt(context, 10) - 1; if (index >= 0 && index < contexts.length) { const targetContext = contexts[index] as string; await browser.switchContext(targetContext); return { content: [{ type: 'text', text: `Switched to context: ${targetContext}` }] }; } throw new Error(`Error: Invalid context index ${context}. Available contexts: ${contexts.length}`); } await browser.switchContext(context); return { content: [{ type: 'text', text: `Switched to context: ${context}` }], }; } catch (e) { return { isError: true, content: [{ type: 'text', text: `Error switching context: ${e}` }], }; } }; - src/tools/context.tool.ts:7-18 (schema)Tool definition with name 'switch_context', description, annotations, and inputSchema defining a single 'context' string parameter.
export const switchContextToolDefinition: ToolDefinition = { name: 'switch_context', description: 'Switches between native and webview automation contexts in a hybrid mobile app. In NATIVE_APP context, use accessibility IDs; in WEBVIEW_* context, use CSS/XPath. Changes persist for all subsequent commands. Accepts context name or 1-based index. Use get_contexts to discover available targets. Mobile-only.', annotations: { title: 'Switch Context', destructiveHint: false, idempotentHint: true }, inputSchema: { context: z .string() .describe( 'Context name to switch to (e.g., "NATIVE_APP", "WEBVIEW_com.example.app", or use index from wdio://session/current/contexts resource)', ), }, }; - src/types/tool.ts:4-9 (schema)The ToolDefinition interface used to type the switch_context definition.
export interface ToolDefinition<T extends ZodRawShape = ZodRawShape> { name: string; description: string; inputSchema: T; annotations?: ToolAnnotations; } - src/server.ts:144-144 (registration)Registration of the switch_context tool via registerTool(switchContextToolDefinition, switchContextTool).
registerTool(switchContextToolDefinition, switchContextTool); - src/tools/get-contexts.tool.ts:6-26 (helper)The get_contexts tool, described as a companion to switch_context — 'Use before switch_context to discover NATIVE_APP and WEBVIEW_* targets.'
export const getContextsToolDefinition: ToolDefinition = { name: 'get_contexts', description: 'Returns available automation contexts and the currently active one. Use before switch_context to discover NATIVE_APP and WEBVIEW_* targets. Mobile-only.', annotations: { title: 'Get Automation Contexts', readOnlyHint: true, idempotentHint: true }, inputSchema: {}, }; export const getContextsTool: ToolCallback = async (): Promise<CallToolResult> => { const [contexts, current] = await Promise.all([readContexts(), readCurrentContext()]); if (contexts.mimeType === 'text/plain' && contexts.text.startsWith('Error')) { return { isError: true, content: [{ type: 'text', text: contexts.text }] }; } if (current.mimeType === 'text/plain' && current.text.startsWith('Error')) { return { isError: true, content: [{ type: 'text', text: current.text }] }; } const combined = { contexts: JSON.parse(contexts.text), currentContext: JSON.parse(current.text), }; return { content: [{ type: 'text', text: JSON.stringify(combined) }] }; };