Safari Web Inspector Bridge
Inspects, observes, and automates WKWebViews on connected iOS devices through the Safari Web Inspector protocol.
Provides developer tools capabilities for Safari Web Inspector, enabling AI agents to inspect DOM, capture network logs, console logs, screenshots, and automate interactions within WKWebViews.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Safari Web Inspector Bridge list my iOS devices"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Safari Web Inspector Bridge
Safari Web Inspector Bridge is an MCP server that gives AI agents the same capabilities a developer gets from Safari Web Inspector — inspect, observe, and automate WKWebViews running on connected iOS devices.
Architecture
graph TD
Agent["AI Agent<br/>Claude, Codex, etc."]
Bridge["MCP Server:<br /><code>safari-web-inspector-bridge</code>"]
Proxy["managed child process: <code>ios-webkit-debug-proxy</code>"]
Device["iOS Device<br/>WKWebView"]
Agent <-->|"MCP <code>stdio</code>"| Bridge
Bridge <-->|"WebSocket<br/>WebKit Inspector Protocol"| Proxy
Proxy <-->|"usbmuxd<br/>(USB / Wi-Fi)"| Device
style Agent fill:#f0f0f0
style Bridge fill:#f0f0f0
style Proxy fill:#f0f0f0
style Device fill:#f0f0f0The server spawns ios-webkit-debug-proxy as a child process, connects to the WebKit Inspector Protocol over WebSocket, and exposes everything as MCP tools. The proxy is managed for its full lifecycle -- started on init, health-checked, auto-restarted on crash, and killed on shutdown.
Proxy Lifecycle
stateDiagram-v2
[*] --> Checking: Server starts
Checking --> Spawning: Binary found
Checking --> Error: Binary missing
Spawning --> HealthCheck: Process started
HealthCheck --> Ready: localhost:9221 responds
HealthCheck --> Error: Timeout (10s)
Ready --> Crashed: Process exits
Crashed --> Spawning: Restart (once)
Crashed --> Error: Already retried
Ready --> Stopped: Graceful shutdown
Stopped --> [*]13 MCP Tools
Discovery: list_devices | list_inspectable_pages | connect
Observation: get_url | get_dom | get_network_log | get_console_log | screenshot
Automation: navigate | execute_javascript | click_element | type_text | wait_for
Related MCP server: Mobile Device MCP
Prerequisites
macOSrequired forusbmuxdand iOS device connectivityios-webkit-debug-proxy:brew install ios-webkit-debug-proxyiOS: Settings › Safari › Advanced › Web Inspector: enabledtarget app WKWebView must have
isInspectable = true
Installation
git clone https://github.com/andesco/safari-web-inspector-bridge.git
cd safari-web-inspector-bridge
npm install
npm run buildAdd to Claude Code
claude mcp add safari-web-inspector-bridge node /path/to/safari-web-inspector-bridge/dist/index.jsAdd to any MCP client
Add to your MCP configuration file:
{
"mcpServers": {
"safari-web-inspector-bridge": {
"command": "node",
"args": ["/path/to/safari-web-inspector-bridge/dist/index.js"],
"env": {
"SWIB_NETWORK_CAPTURE": "true",
"SWIB_CONSOLE_CAPTURE": "true"
}
}
}
}Tools
Device & Connection
Tool | Parameters | Returns |
| (none) |
|
|
|
|
|
|
|
Observation
Tool | Parameters | Returns |
| (none) |
|
|
|
|
|
|
|
|
|
|
| (none) | MCP image content (base64 PNG) |
Automation
Tool | Parameters | Returns |
|
|
|
|
|
|
|
|
|
|
|
|
| One of: |
|
Configuration
Env Var | Default | Description |
|
| Auto-connect to the first inspectable page on startup |
|
| Capture network requests on connect |
|
| Capture console messages on connect |
|
| Starting port for |
[!note]
SWIB_NETWORK_CAPTUREandSWIB_CONSOLE_CAPTUREdefault totrue— set tofalseto disable.SWIB_AUTO_CONNECTdefaults tofalse— set totrueto enable.
Example Workflow
sequenceDiagram
participant Agent as AI Agent
participant Bridge as MCP Server
participant Proxy as ios-webkit-debug-proxy
participant Device as iOS WKWebView
Agent->>Bridge: list_inspectable_pages()
Bridge->>Proxy: GET /json (devices + pages)
Proxy-->>Bridge: page_id: "1", title: "Banks"
Bridge-->>Agent: [{ page_id, title, url, app_bundle_id }]
Agent->>Bridge: connect({ page_id: "1" })
Bridge->>Proxy: WebSocket connect
Proxy->>Device: WebKit Inspector attach
Device-->>Proxy: Connected
Bridge-->>Agent: { connected: true }
Agent->>Bridge: get_network_log({ filter_url: "scotiabank" })
Bridge-->>Agent: [{ url, status: 302, redirected_to: "scotiabank://..." }]
Agent->>Bridge: execute_javascript("document.title")
Bridge->>Device: Runtime.evaluate
Device-->>Bridge: "Banks"
Bridge-->>Agent: { result: "Banks" }
Agent->>Bridge: click_element({ selector: "button.next" })
Bridge->>Device: Runtime.evaluate (querySelector + click)
Device-->>Bridge: clicked
Bridge-->>Agent: { clicked: true, tag_name: "button" }
Agent->>Bridge: wait_for({ url_contains: "/dashboard" })
loop Poll until match
Bridge->>Device: Runtime.evaluate (location.href)
Device-->>Bridge: current URL
end
Bridge-->>Agent: { matched: true, elapsed_ms: 1230 }
Agent->>Bridge: screenshot()
Bridge->>Device: Page.snapshotRect
Device-->>Bridge: base64 PNG
Bridge-->>Agent: image contentDevelopment
npm run build # Compile TypeScript to dist/
npm run dev # Watch mode (tsc --watch)
npm test # Run tests (vitest)
npm run test:watch # Watch mode tests
npm start # Run the MCP server (node dist/index.js)Project structure
src/
index.ts # Entry point, server setup, lifecycle
types.ts # Interfaces and config loader
proxy-manager.ts # Spawns and manages ios-webkit-debug-proxy
device-discovery.ts # Queries proxy for devices and pages
webkit-connection.ts # WebSocket connection to WebKit Inspector Protocol
network-buffer.ts # Ring buffer for network request entries (1000 max)
tools/
device-tools.ts # list_devices, list_inspectable_pages, connect
observation-tools.ts # get_url, get_dom, get_network_log, get_console_log, screenshot
automation-tools.ts # navigate, execute_javascript, click_element, type_text, wait_forAvailable Tools
14 toolsclick_elementA
Click a DOM element identified by CSS selector
Inputs: selector (required), index.
connectB
Attach to a specific inspectable page for observation and automation
Inputs: page_id (required).
debug_protocolA
Dump the raw WebKit Inspector Protocol messages exchanged (for debugging)
Inputs: clear.
execute_javascriptB
Evaluate a JavaScript expression in the page context
Inputs: expression (required), await_promise.
get_console_logA
Retrieve JavaScript console messages since connection or last clear
Inputs: clear, level.
get_domA
Read the page's DOM as HTML
Inputs: selector, outer_html.
get_network_logA
Retrieve captured network requests since connection or last clear
Inputs: clear, filter_url, filter_status.
get_urlA
Get the current URL of the connected page
Inputs: no named parameters.
list_devicesA
List connected iOS devices with Web Inspector enabled
Inputs: no named parameters.
list_inspectable_pagesA
Enumerate all inspectable WKWebViews across connected devices
Inputs: device_udid.
screenshotB
Capture a screenshot of the webview content
Inputs: no named parameters.
type_textA
Type text into the currently focused element or a specified element
Inputs: text (required), selector.
wait_forC
Wait for a condition before proceeding
Inputs: selector, timeout_ms, network_idle, url_contains.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 14 tools
Each tool has a clearly distinct role: enumeration (list_devices, list_inspectable_pages), connection, state retrieval (get_url, get_dom, get_network_log, get_console_log), actions (navigate, execute_javascript, click_element, type_text, wait_for), and debugging (screenshot, debug_protocol). No two tools target the same resource or action in an ambiguous way.
Most tools follow a consistent verb_noun pattern (list_devices, get_url, click_element). A few single-word verbs (connect, navigate, screenshot) deviate slightly but are still clear and fit the overall imperative style. No mixed naming conventions like camelCase or inconsistent prefixes.
14 tools is well within the ideal range for a comprehensive browser automation/inspection server. Each tool covers a necessary aspect of the workflow without redundancy or bloat.
The toolset covers the core lifecycle of inspecting and automating WKWebViews: discovery, connection, navigation, DOM access, interaction, waiting, and logging. A minor gap is lack of an explicit clear operation for network/console logs despite descriptions mentioning 'last clear', but this can be worked around with reconnection.
Maintenance
Related MCP Connectors
Web scraping, browser automation, screenshots and AI data extraction for AI agents via MCP.
Let your AI agent control real iPhones: screenshots, tap, swipe, type and open apps.
Give an AI agent an iPhone to see, tap and type on over MCP. Free early access (Simulator).
Web search API and MCP server for developers building AI agents.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceMCP server for iOS automation via rpcclient, enabling AI agents to connect to iOS RPC servers and perform actions like launching apps, clicking, typing, and gesture control.2MIT
- AlicenseNot gradedqualityCmaintenanceAn MCP server that lets AI agents control iOS and Android devices (tap, scroll, type, take screenshots, read UI trees, and run code). Works with multiple devices at the same time.94 npm54MIT
- AlicenseAqualityDmaintenanceAn MCP server that lets an AI agent drive the iOS Simulator in a loop, enabling tapping, typing, swiping, reading the screen via the accessibility tree, and verifying app state.14MIT
- AlicenseNot gradedqualityDmaintenanceA Model Context Protocol (MCP) server for iOS Simulator automation. Enables AI assistants to visually interact with iOS apps running in the simulator.40 npm1MIT