Skip to main content
Glama
webdriverio

WebDriverIO MCP Server

Official

switch_tab

Idempotent

Switch active browser tab using a window handle or 0-based index. Subsequent commands execute on the selected tab.

Instructions

Focuses a browser tab by window handle or 0-based index. All subsequent tool calls operate on the active tab. Provide handle OR index — use get_tabs to find them. Browser-only; use switch_context for mobile webviews.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
handleNoWindow handle to switch to
indexNo0-based tab index to switch to

Implementation Reference

  • The switchTabTool callback: the main handler that executes the switch_tab logic. Accepts handle or index, uses getBrowser() to call switchToWindow or resolves index via getWindowHandles.
    export const switchTabTool: ToolCallback = async ({ handle, index }: { handle?: string; index?: number }): Promise<CallToolResult> => {
      try {
        const browser = getBrowser();
        if (handle) {
          await browser.switchToWindow(handle);
          return { content: [{ type: 'text', text: `Switched to tab: ${handle}` }] };
        } else if (index !== undefined) {
          const handles = await browser.getWindowHandles();
          if (index >= handles.length) {
            return { isError: true, content: [{ type: 'text', text: `Error: index ${index} out of range (${handles.length} tabs)` }] };
          }
          await browser.switchToWindow(handles[index]);
          return { content: [{ type: 'text', text: `Switched to tab ${index}: ${handles[index]}` }] };
        }
        return { isError: true, content: [{ type: 'text', text: 'Error: Must provide either handle or index' }] };
      } catch (e) {
        return { isError: true, content: [{ type: 'text', text: `Error switching tab: ${e}` }] };
      }
    };
  • The switchTabToolDefinition: defines the 'switch_tab' tool name, description, annotations, and inputSchema (optional handle string and optional index number).
    export const switchTabToolDefinition: ToolDefinition = {
      name: 'switch_tab',
      description: 'Focuses a browser tab by window handle or 0-based index. All subsequent tool calls operate on the active tab. Provide handle OR index — use get_tabs to find them. Browser-only; use switch_context for mobile webviews.',
      annotations: { title: 'Switch Browser Tab', destructiveHint: false, idempotentHint: true },
      inputSchema: {
        handle: z.string().optional().describe('Window handle to switch to'),
        index: z.number().int().min(0).optional().describe('0-based tab index to switch to'),
      },
    };
  • src/server.ts:129-129 (registration)
    Registration of switch_tab tool via registerTool(switchTabToolDefinition, switchTabTool) at line 129.
    registerTool(switchTabToolDefinition, switchTabTool);
  • src/server.ts:68-68 (registration)
    Import of switchTabTool and switchTabToolDefinition from tools/tabs.tool.ts into the server entry point.
    import { switchTabTool, switchTabToolDefinition } from './tools/tabs.tool';
  • Import of getBrowser() helper from session/state which retrieves the current browser instance used by the handler.
    import { getBrowser } from '../session/state';
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already provide idempotentHint=true. Description adds valuable context: 'All subsequent tool calls operate on the active tab,' explaining persistence. No contradictions. Could mention behavior if both handle and index provided, but still strong.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, no redundancy, front-loaded with the core action. Every sentence adds value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple switch tool with good annotations and full schema coverage, the description is complete. It covers exclusivity, side effect on subsequent calls, and domain restriction.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, but description adds the crucial exclusivity constraint (handle OR index) not in schema. References get_tabs for discovery, adding practical meaning.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action (focuses), resource (browser tab), and method (window handle or index). It also distinguishes from sibling switch_context for mobile webviews.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly tells when to use (browser-only) and when not (mobile webviews use switch_context). Advises using get_tabs to find handles/indices. Provides clear OR condition.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/webdriverio/mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server