Skip to main content
Glama
itelo
by itelo

Get it

Chrome, Edge, Brave

Download the zip from releases and load it unpacked (details). Store listings are on the way.

Firefox, Zen

Load extension/manifest.json as a temporary add-on (details). Add-ons listing on the way.

Claude Code and other MCP clients

claude mcp add view-sim -- npx -y view-sim-mcp (details)

  • Real device sizes. iPhone 15 Pro, 15 Pro Max, 13 mini and SE; Pixel 8; Galaxy S23; iPad mini; iPad Pro 11"; MacBook Pro 14" and 16"; iMac 24"; Dell UltraSharp 40" ultrawide. Each device gets the page area left after its status bar and browser bars, so iPhone 15 Pro in Safari is 393 × 659, as on the phone.

  • The browser around the page. Safari, Chrome, Firefox or Zen per device, with that browser's bars, tabs and user agent.

  • Phone behaviour. Mobile user agents, touch events, drag-to-scroll, hidden scrollbars and a touch cursor, all inside your normal browser and your signed-in session.

  • Transparent screenshots. PNGs of the device with its frame, the screen, or only the page.

  • An MCP server. Agents such as Claude Code can open sites on devices, navigate and take screenshots through the extension, or render headlessly with Playwright and real device emulation, with no window at all.

extension/    the browser extension (Chrome, Zen, Firefox)
mcp-server/   the MCP server: bridge to the extension, plus the headless renderer
tools/        icon renderer, demo site, store images, packaging and test harness
store/        store listing text and images
docs/         images for this README

Install the extension

Chrome: open chrome://extensions, turn on Developer mode, click Load unpacked and pick extension/. Or download view-sim-extension-<version>.zip from the releases, unzip it and load that folder.

Zen or Firefox (128+): open about:debugging#/runtime/this-firefox, click Load Temporary Add-on… and pick extension/manifest.json. The add-on is removed when the browser quits.

Site access. view-sim asks for nothing at install. The first time you turn it on for a site, the popup asks for access to that site only. To take screenshots, also click Allow access to all websites in the extension's settings: browsers only let an extension capture a tab when it has that permission. If you click the camera without it, the settings page opens.

Related MCP server: webshot-mcp

Using it

Open a site, click the toolbar button and flip the switch. Every page of that site then opens in the simulator until you turn it off.

  • Devices: iPhone 15 Pro, 15 Pro Max, 13 mini and SE; Pixel 8; Galaxy S23; iPad mini; iPad Pro 11"; MacBook Pro 14" and 16"; iMac 24"; and Dell UltraSharp 40" (U4025QW, 2560×1080).

  • Browsers, per device: the browser picker next to the device name changes the interface drawn around the page, and it sets what the page gets on mobile devices: user agent, navigator.vendor and userAgentData.

    iPhone

    iPad

    Android

    Mac / display

    Safari

    status bar on top; address bar and toolbar at the bottom

    one bar on top

    —

    macOS menu bar and Safari toolbar

    Chrome

    address bar on top, toolbar at the bottom

    one bar on top

    address bar on top, gesture bar at the bottom

    tab strip and address bar

    Firefox

    address bar on top, toolbar at the bottom

    one bar on top

    address bar at the bottom

    tab strip and address bar

    Zen

    —

    —

    —

    vertical tabs in a sidebar, page in a rounded card

    The page area is what is left after the system and browser bars. For example, iPhone 15 Pro in Safari gets 393 × 659, the same as the real phone. Rotated phones show a compact bar on top.

  • Screenshots: click the camera button on a device. It saves a PNG with a transparent background: the device with its frame, or the screen with status bar and browser bars when Frame is off. ⌥-click saves only the web page. While it captures, the device is shown alone and as large as the window allows. Chrome saves at screen resolution; Firefox and Zen render the device at 2× its real size.

  • Desktops keep your browser's real user agent, mouse input and scrollbars. Only screen.* and devicePixelRatio are changed.

MCP server

The extension connects out to a local server on ws://127.0.0.1:47820. The server accepts only connections from extension pages and speaks MCP over stdio to your agent.

claude mcp add view-sim -- npx -y view-sim-mcp

Add --scope user to have it in every project. From a clone of this repo instead:

cd mcp-server && npm install
claude mcp add view-sim --scope user -- node "$(pwd)/index.mjs"

Only let view-sim connect. By default any browser extension may connect to the bridge, and the server says so on stderr when it starts. To allow only view-sim, set VIEW_SIM_EXTENSION_IDS to its extension id, comma-separated for several browsers: in Chrome the 32-letter id shown on chrome://extensions, in Firefox and Zen the add-on id view-sim@itelo. In Chrome the id is also checked against the connection's origin, which other extensions cannot fake.

claude mcp add view-sim -e VIEW_SIM_EXTENSION_IDS=abcdefghijklmnopabcdefghijklmnop,view-sim@itelo -- npx -y view-sim-mcp

Tools:

Tool

What it does

view_sim_status

Shows whether the extension is connected, plus every simulator tab with its devices, URLs and page sizes

view_sim_list_devices

Lists device ids, screen sizes and the browsers each device supports

view_sim_open

Opens a URL in a new tab on the given devices, e.g. [{"id":"iphone-15-pro","browser":"safari"},"pixel-8"], and waits for them to load

view_sim_set_devices

Replaces the devices in a tab

view_sim_navigate

Loads a URL or path on the devices and waits

view_sim_set_options

Sets zoom, frame and sync

view_sim_screenshot

Captures one device or all of them from the extension's tab, as device, screen or viewport; returns images and can also save PNGs with save_dir

view_sim_headless_screenshot

Renders a URL on devices with no browser window and no extension (see below)

view_sim_turn_off

Turns the simulator off for a hostname

Headless screenshots

view_sim_headless_screenshot doesn't need the extension or a browser window. It loads the page with Playwright using real device emulation: viewport, pixel ratio, touch, mobile mode and user agent, so CSS pointer: coarse and the viewport meta tag behave as they do on a phone. Then it draws the device around the result with the same simulator code and CSS the extension uses. Safari devices render in WebKit; the other browsers render in Chromium, with their own interface and user agent. It needs Playwright's browsers once:

npx -y playwright@1.64.1 install chromium webkit

(From a clone: cd mcp-server && npm run install-browsers.)

Headless pages start signed out. For pages behind a login, pass storage_state: a Playwright storage-state JSON file with the cookies and localStorage to use.

Transparent backgrounds

device and screen images are PNGs with a transparent background, from both tools. The headless renderer draws on a transparent page. The extension captures the device twice, on black and on white, and works out each pixel's transparency from the difference, so rounded corners and anti-aliased edges stay clean. viewport images are the page itself, so they have no transparent areas.

Notes:

  • The browser must be running with the extension loaded. After the server starts, the extension can take up to 30 seconds to connect; the first call waits for it. The connection status is on the extension's settings page, where the bridge can also be turned off.

  • Screenshots bring the simulator tab and its window to the front, because browsers only capture what is on screen. macOS can refuse to bring a background app forward; if a screenshot reports that the tab "has no size on screen", click into the browser window once and retry.

  • In Firefox and Zen, an idle background page is stopped after 30 seconds. An open simulator tab keeps it running, so the bridge stays connected while you work.

  • open needs the extension to already have access to the site: turn the site on once from the toolbar button, or allow access to all websites in the settings.

  • screenshot needs access to all websites, as above.

  • Only one server can hold the port. A second agent session's server keeps retrying, and its tools report that the port is taken.

How it works

Piece

What it does

extension/background.js

Keeps the list of enabled sites. It registers the content scripts and one declarativeNetRequest rule per site; the rule sets the first device's user agent on the simulator's frames and strips X-Frame-Options and CSP from their responses. It also crops screenshots and runs the MCP bridge.

extension/simulator/

Runs at document_start in the top frame. It stops the page, replaces it with the simulator UI, and loads the same URL in one iframe per device.

extension/frame/frame-main.js

Runs in the page's own JavaScript context inside those iframes. It overrides the user agent and screen properties, emulates touch input and hides scrollbars on mobile devices, and reports navigation back to the simulator.

mcp-server/index.mjs

The MCP server and the WebSocket bridge.

Limitations

  • CSS media queries such as (pointer: coarse) still see a desktop. Only JS matchMedia is changed. Width-based queries work, because each iframe really has the device's width.

  • The server sees the user agent of the first device in the list; each frame's JavaScript sees its own.

  • If a device frame navigates to another site, that frame loses the emulation, unless that site is turned on too.

  • Pages that need to be top-level, such as some OAuth or payment flows, may break inside the frame.

Support view-sim

view-sim is free and MIT licensed. If it saves you time, you can support it on GitHub Sponsors. There is also a small link in the popup and on the settings page; the extension never asks.

Privacy

view-sim collects no data. It only talks to 127.0.0.1:47820 when the MCP bridge is on. See PRIVACY.md.

Dev

  • node tools/make-icons.mjs renders extension/icons/logo.svg to the toolbar PNGs. It uses the MCP server's Playwright, so run npm install in mcp-server/ first.

  • tools/demo-site/ is a small page to try the extension on: serve the project root and open http://localhost:4580/tools/demo-site/.

  • tools/harness.html runs the simulator without the extension runtime, with chrome.* stubbed. Serve the project root with python3 -m http.server 4580, then open http://localhost:4580/tools/harness.html.

  • node tools/store-images.mjs renders the README images in docs/ and the store images in store/images/ from tools/demo-site/showcase.html.

  • node tools/smoke-test.mjs renders one device headlessly and checks the image; CI runs it with the extension lint on every push.

  • node tools/package-extension.mjs zips extension/ into dist/view-sim-extension-<version>.zip for the stores. Pushing a v<version> tag that matches extension/manifest.json runs .github/workflows/release.yml, which lints, zips and attaches the zip to a GitHub release.

  • npm pack in mcp-server/ copies the extension files the headless renderer needs into mcp-server/vendor/ first, so the npm package works on its own. In the repo the renderer reads extension/ directly.

License

MIT © itelo

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    C
    quality
    D
    maintenance
    Enables taking screenshots of web pages with support for multiple devices (desktop, mobile, tablet), custom dimensions, full-page capture, and various image formats. Built with Playwright for reliable web page rendering and screenshot generation.
    1
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables agents to take screenshots and extract text from web pages using a persistent Chrome browser via CDP, with built-in SSRF protection.
    5 npm
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    Enables agents to open websites, capture full-page screenshots in the background using a Chromium-based browser, and read saved screenshots back as images.
    5
    1
    MIT