Skip to main content
Glama
BrowserGenie

BrowserGenie MCP Server

by BrowserGenie

emulate_device

Emulate a specific device preset to test web pages with accurate viewport, DPR, user agent, and touch emulation.

Instructions

Emulate a specific device preset (iPhone 14, Pixel 7, iPad Pro, desktop). Automatically sets viewport, DPR, user agent, and touch emulation.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
deviceYesDevice preset name
tabIdNoTarget tab ID (defaults to currently active tab)
apiKeyNoAPI key for authentication if enabled

Implementation Reference

  • Handler function for the 'emulate_device' tool. It looks up the device preset from DEVICE_PRESETS, sends the 'emulate_device' command via WebSocket bridge with preset dimensions, DPR, mobile/touch flags, and user agent, then returns success/error response.
      async ({ device, tabId, apiKey }) => {
        const preset = DEVICE_PRESETS[device];
        if (!preset) {
          return { content: [{ type: 'text', text: `Unknown device: ${device}` }], isError: true };
        }
        const result = await bridge.sendCommand({
          command: 'emulate_device',
          params: {
            width: preset.width,
            height: preset.height,
            deviceScaleFactor: preset.dpr,
            mobile: preset.mobile,
            touch: preset.touch,
            userAgent: preset.ua,
          },
          tabId,
          apiKey,
        });
        if (!result.success) {
          return { content: [{ type: 'text', text: `Error: ${result.error?.message}` }], isError: true };
        }
        return { content: [{ type: 'text', text: `Emulating ${device}: ${preset.width}x${preset.height}` }] };
      }
    );
  • Input schema for 'emulate_device' tool: requires 'device' (enum of presets: iphone-14, pixel-7, ipad-pro, desktop-1080, desktop-1440), optional 'tabId' and 'apiKey'.
    {
      device: z.enum(['iphone-14', 'pixel-7', 'ipad-pro', 'desktop-1080', 'desktop-1440'] as [string, ...string[]]).describe('Device preset name'),
      tabId: z.number().optional().describe('Target tab ID (defaults to currently active tab)'),
      apiKey: z.string().optional().describe('API key for authentication if enabled'),
    },
  • DEVICE_PRESETS constant defining dimensions (width, height), DPR, mobile/touch flags, and user agent strings for each device preset used by emulate_device.
    const DEVICE_PRESETS: Record<string, { width: number; height: number; dpr: number; mobile: boolean; touch: boolean; ua: string }> = {
      'iphone-14': { width: 390, height: 844, dpr: 3, mobile: true, touch: true, ua: 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Mobile/15E148 Safari/604.1' },
      'pixel-7': { width: 412, height: 915, dpr: 2.625, mobile: true, touch: true, ua: 'Mozilla/5.0 (Linux; Android 13; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Mobile Safari/537.36' },
      'ipad-pro': { width: 1024, height: 1366, dpr: 2, mobile: true, touch: true, ua: 'Mozilla/5.0 (iPad; CPU OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Safari/604.1' },
      'desktop-1080': { width: 1920, height: 1080, dpr: 1, mobile: false, touch: false, ua: '' },
      'desktop-1440': { width: 2560, height: 1440, dpr: 1, mobile: false, touch: false, ua: '' },
    };
  • Registration of 'emulate_device' tool via server.tool() inside registerEmulationTools(). Includes description, schema, and handler.
    server.tool(
      'emulate_device',
      'Emulate a specific device preset (iPhone 14, Pixel 7, iPad Pro, desktop). Automatically sets viewport, DPR, user agent, and touch emulation.',
      {
        device: z.enum(['iphone-14', 'pixel-7', 'ipad-pro', 'desktop-1080', 'desktop-1440'] as [string, ...string[]]).describe('Device preset name'),
        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 ({ device, tabId, apiKey }) => {
        const preset = DEVICE_PRESETS[device];
        if (!preset) {
          return { content: [{ type: 'text', text: `Unknown device: ${device}` }], isError: true };
        }
        const result = await bridge.sendCommand({
          command: 'emulate_device',
          params: {
            width: preset.width,
            height: preset.height,
            deviceScaleFactor: preset.dpr,
            mobile: preset.mobile,
            touch: preset.touch,
            userAgent: preset.ua,
          },
          tabId,
          apiKey,
        });
        if (!result.success) {
          return { content: [{ type: 'text', text: `Error: ${result.error?.message}` }], isError: true };
        }
        return { content: [{ type: 'text', text: `Emulating ${device}: ${preset.width}x${preset.height}` }] };
      }
    );
  • Import of registerEmulationTools from emulation.ts module.
    import { registerEmulationTools } from './emulation.js';
  • Call to registerEmulationTools(server, bridge) to wire up the tool during server initialization.
    registerEmulationTools(server, bridge);
Behavior3/5

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

No annotations are provided, so the description must carry the behavioral burden. It discloses that viewport, DPR, user agent, and touch are set automatically, but does not mention persistence, reversal, or side effects across tabs.

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: first states the core action, second explains the effects. Every word is relevant and there is no redundancy. Highly efficient.

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

Completeness3/5

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

Given no annotations or output schema, the description adequately covers purpose and effects. However, it lacks details on how to reset emulation, whether it persists, and any limitations, leaving some gaps for a state-modifying tool.

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

Parameters3/5

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

Schema coverage is 100%, so baseline is 3. The description adds context by listing device presets and stating the effects of emulation, but does not elaborate on tabId or apiKey parameters beyond what the schema provides.

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?

Description clearly states it emulates device presets and lists examples (iPhone 14, etc.). It specifically mentions setting viewport, DPR, user agent, and touch emulation, distinguishing it from sibling tools like resize_viewport or emulate_network_conditions.

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

Usage Guidelines3/5

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

The description implies usage for responsive testing but lacks explicit guidance on when to use this tool versus alternatives like resize_viewport or reset_viewport. No when-not-to-use or alternative tool suggestions are provided.

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/BrowserGenie/mcp'

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