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 --jsonGive your agent the installed reference instead of pasting commands into its prompt:
tapscope agent-context
tapscope skills get mobile-debuggingagent-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:
- the device of the page chosen with
tapscope targets use <id>, - otherwise the device whose page was last opened in Tapscope or through CDP,
- 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:9222Cursor, 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.

MCP tools on iOS
Tested with chrome-devtools-mcp 1.12.0 against the iOS Simulator and an iPhone: 22 of 33 tools work.
| Works | Not available on iOS |
|---|---|
list_pages, select_page, new_page, close_page, navigate_page, wait_for | get_css_styles |
evaluate_script, take_screenshot (also full page), take_snapshot | upload_file, resize_page, emulate |
click, hover, fill, fill_form, type_text, press_key, drag | performance_*, take_heapsnapshot |
list_console_messages, get_console_message, list_network_requests, get_network_request | handle_dialog, lighthouse_audit |
screencast_start, screencast_stop |
close_pagecloses only tabs that a script opened.screencast_startandscreencast_stopneed--experimental-screencastand ffmpeg.get_css_stylesopens 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(), neverbrowser.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}"
}