Documentation / Automation

Coding agents, MCP and Puppeteer

Let your coding agent look at the real page: read the DOM, click through a flow, check errors and requests, and confirm the fix on the device.

Two ways in

  • The tapscope CLI – for agents that run shell commands, such as Claude Code, Codex or Cursor. Every command answers in JSON, element references come from a readable snapshot, and console and network events can be read incrementally. See the CLI reference.
  • The CDP endpoint http://127.0.0.1:9222 – behaves like Chrome with a debug port. Chrome DevTools MCP, Puppeteer and VS Code attach to it.

Both see the same pages, and both work while the Tapscope app is closed.

Agent workflow

tapscope doctor --json
tapscope devices list --json
tapscope open https://example.com --json
tapscope snapshot --interactive --json
tapscope click @e3 --json
tapscope console list --types error,exception --json
tapscope network list --failed --json
tapscope reload --json
tapscope screenshot --json

Give your agent the installed reference instead of pasting commands into its prompt:

tapscope agent-context
tapscope skills get mobile-debugging

agent-context prints commands, error codes and exit codes for exactly this version. The skills mobile-debugging, vscode-debugging and puppeteer are step-by-step task guides. With several agents, give each its own --session.

Which pages the endpoint shows

The CDP endpoint shows the pages of one device at a time:

  1. the device of the page chosen with tapscope targets use <id>,
  2. otherwise the device whose page was last opened in Tapscope or through CDP,
  3. otherwise the first booted simulator, then an iPhone or iPad (cable before Wi-Fi).

Android devices are never chosen on their own. Open a page in Tapscope or use targets use to pick one.

Chrome DevTools MCP

Claude Code:

claude mcp add tapscope -- npx -y chrome-devtools-mcp@latest --browser-url http://127.0.0.1:9222

Cursor, Claude Desktop and other MCP clients:

{
  "mcpServers": {
    "tapscope": {
      "command": "npx",
      "args": ["-y", "chrome-devtools-mcp@latest", "--browser-url", "http://127.0.0.1:9222"]
    }
  }
}

Codex (~/.codex/config.toml):

[mcp_servers.tapscope]
command = "npx"
args = ["-y", "chrome-devtools-mcp@latest", "--browser-url", "http://127.0.0.1:9222"]

The same snippets are in Tapscope under Settings › Agents.

Tapscope Settings, Agents tab: the CDP endpoint http://127.0.0.1:9222 and ready-to-copy Chrome DevTools MCP setup for Claude Code, Cursor and Claude Desktop
Settings › Agents with the CDP endpoint and the MCP setup.

MCP tools on iOS

Tested with chrome-devtools-mcp 1.12.0 against the iOS Simulator and an iPhone: 22 of 33 tools work.

WorksNot available on iOS
list_pages, select_page, new_page, close_page, navigate_page, wait_forget_css_styles
evaluate_script, take_screenshot (also full page), take_snapshotupload_file, resize_page, emulate
click, hover, fill, fill_form, type_text, press_key, dragperformance_*, take_heapsnapshot
list_console_messages, get_console_message, list_network_requests, get_network_requesthandle_dialog, lighthouse_audit
screencast_start, screencast_stop
  • close_page closes only tabs that a script opened.
  • screencast_start and screencast_stop need --experimental-screencast and ffmpeg.
  • get_css_styles opens a second DOM connection; WebKit then renumbers the nodes and earlier snapshot uids are outdated.
  • The snapshot approximates Chrome’s accessibility tree from the DOM; clicks and input are synthetic DOM events.

Android and Chrome targets speak CDP themselves and are passed through.

Puppeteer

import puppeteer from 'puppeteer-core';
const browser = await puppeteer.connect({
  browserURL: 'http://127.0.0.1:9222',
  defaultViewport: null,
  targetFilter: t => t.url().includes('example.com'),
});
const page = (await browser.pages()).find(p => p.url().includes('example.com'));
console.log(await page.evaluate(() => document.title));
await page.screenshot({ path: 'page.png' });
await browser.disconnect();
  • Use targetFilter: on real devices Safari suspends background tabs, and attaching to them would wait.
  • Call browser.disconnect(), never browser.close() – it is your device.
  • browser.newPage() opens a Safari tab; page.close() closes tabs that a script opened.

VS Code

Attach the JavaScript debugger to a page; breakpoints in your sources bind through source maps as with desktop Chrome:

{
  "type": "chrome",
  "request": "attach",
  "name": "Tapscope page",
  "port": 9222,
  "urlFilter": "https://example.com/*",
  "webRoot": "${workspaceFolder}"
}

Limits on iOS

Chat with Tapscope

The chat loads only after you choose “Start chat”. Your IP address, browser data and messages are then sent to tawk.to. The service may set cookies and process data in the United States.

Privacy information from tawk.to ↗