TL;DR: Use your real Safari with all your logins, cookies, and sessions. No headless browsers, no Chrome, no Puppeteer. Just pure AppleScript + JavaScript running natively on macOS — 60% less CPU/heat on Apple Silicon.
🤔 Why not just use Playwright or Chrome DevTools MCP?
Problem
Safari MCP Solution
Chrome DevTools MCP heats up your Mac
Native WebKit — ~60% less CPU
Playwright launches a new browser without your logins
Uses your real Safari with all sessions
Puppeteer requires Chrome + debug port
Zero dependencies — just AppleScript
Headless browsers can't access your authenticated sessions
Gmail, GitHub, Slack — already logged in
Browser automation steals window focus
Safari stays in background, never interrupts
Highlights
80 tools — navigation, clicks, forms, screenshots, network, storage, accessibility, and more
Zero heat — native WebKit on Apple Silicon, ~60% less CPU than Chrome
Your real browser — keeps all logins, cookies, sessions (Gmail, GitHub, Ahrefs, etc.)
Background operation — Safari stays in the background, no window stealing
No dependencies — no Puppeteer, no Playwright, no WebDriver, no Chrome
Persistent process — reuses a single osascript process (~5ms per command vs ~80ms)
Framework-compatible — React, Vue, Angular, Svelte form filling via native setters
Quick Start
Prerequisites
macOS (any version with Safari)
Node.js 18+
Safari → Settings → Advanced → Show features for web developers ✓
Safari → Develop → Allow JavaScript from Apple Events ✓
Install
Option A — npm (recommended):
npminstall-g safari-mcp
Option B — Homebrew:
brew install achiya-automation/tap/safari-mcp
Option C — from source:
git clone https://github.com/achiya-automation/safari-mcp.git
cd safari-mcp
npminstall
The recommended pattern for AI agents using Safari MCP:
1. safari_snapshot → Get page state (accessibility tree)
2. safari_click/fill/... → Interact with elements by ref
3. safari_snapshot → Verify the result
Element targeting — tools accept multiple targeting strategies:
Strategy
Example
Best for
CSS selector
#login-btn, .submit
Unique elements
Visible text
"Sign In", "Submit"
Buttons, links
Coordinates
x: 100, y: 200
Canvas, custom widgets
Ref from snapshot
ref: "e42"
Any element from accessibility tree
Tip: Start with safari_snapshot to get element refs, then use refs for precise targeting. This is faster and more reliable than CSS selectors.
Tools (80)
Navigation (4)
Tool
Description
safari_navigate
Navigate to URL (auto HTTPS, wait for load)
safari_go_back
Go back in history
safari_go_forward
Go forward in history
safari_reload
Reload page (optional hard reload)
Page Reading (3)
Tool
Description
safari_read_page
Get title, URL, and text content
safari_get_source
Get full HTML source
safari_navigate_and_read
Navigate + read in one call
Click & Interaction (5)
Tool
Description
safari_click
Click by CSS selector, visible text, or coordinates
safari_double_click
Double-click (select word, etc.)
safari_right_click
Right-click (context menu)
safari_hover
Hover over element
safari_click_and_wait
Click + wait for navigation
Form Input (7)
Tool
Description
safari_fill
Fill input (React/Vue/Angular compatible)
safari_clear_field
Clear input field
safari_select_option
Select dropdown option
safari_fill_form
Batch fill multiple fields
safari_fill_and_submit
Fill form + submit in one call
safari_type_text
Type real keystrokes (JS-based, no System Events)
safari_press_key
Press key with modifiers
Screenshots & PDF (3)
Tool
Description
safari_screenshot
Screenshot as PNG (viewport or full page)
safari_screenshot_element
Screenshot a specific element
safari_save_pdf
Export page as PDF
Scroll (3)
Tool
Description
safari_scroll
Scroll up/down by pixels
safari_scroll_to
Scroll to exact position
safari_scroll_to_element
Smooth scroll to element
Tab Management (4)
Tool
Description
safari_list_tabs
List all tabs (index, title, URL)
safari_new_tab
Open new tab (background, no focus steal)
safari_close_tab
Close tab
safari_switch_tab
Switch to tab by index
Wait (2)
Tool
Description
safari_wait_for
Wait for element, text, or URL change
safari_wait
Wait for specified milliseconds
JavaScript (1)
Tool
Description
safari_evaluate
Execute arbitrary JavaScript, return result
Element Inspection (4)
Tool
Description
safari_get_element
Element details (tag, rect, attrs, visibility)
safari_query_all
Find all matching elements
safari_get_computed_style
Computed CSS styles
safari_detect_forms
Auto-detect all forms with field selectors
Accessibility (1)
Tool
Description
safari_accessibility_snapshot
Full a11y tree: roles, ARIA, focusable elements
Drag & Drop (1)
Tool
Description
safari_drag
Drag between elements or coordinates
File Operations (2)
Tool
Description
safari_upload_file
Upload file via JS DataTransfer (no file dialog!)
safari_paste_image
Paste image into editor (no clipboard touch!)
Dialog & Window (2)
Tool
Description
safari_handle_dialog
Handle alert/confirm/prompt
safari_resize
Resize browser window
Device Emulation (2)
Tool
Description
safari_emulate
Emulate device (iPhone, iPad, Pixel, Galaxy)
safari_reset_emulation
Reset to desktop
Cookies & Storage (10)
Tool
Description
safari_get_cookies
Get all cookies
safari_set_cookie
Set cookie with all options
safari_delete_cookies
Delete one or all cookies
safari_local_storage
Read localStorage
safari_set_local_storage
Write localStorage
safari_delete_local_storage
Delete/clear localStorage
safari_session_storage
Read sessionStorage
safari_set_session_storage
Write sessionStorage
safari_delete_session_storage
Delete/clear sessionStorage
safari_export_storage
Export all storage as JSON (backup/restore sessions)
safari_import_storage
Import storage state from JSON
Clipboard (2)
Tool
Description
safari_clipboard_read
Read clipboard text
safari_clipboard_write
Write text to clipboard
Network (6)
Tool
Description
safari_network
Quick network requests via Performance API
safari_start_network_capture
Start detailed capture (fetch + XHR)
safari_network_details
Get captured requests with headers/timing
safari_clear_network
Clear captured requests
safari_mock_route
Mock network responses (intercept fetch/XHR)
safari_clear_mocks
Remove all network mocks
Console (4)
Tool
Description
safari_start_console
Start capturing console messages
safari_get_console
Get all captured messages
safari_clear_console
Clear captured messages
safari_console_filter
Filter by level (log/warn/error)
Performance (2)
Tool
Description
safari_performance_metrics
Navigation timing, Web Vitals, memory
safari_throttle_network
Simulate slow-3g/fast-3g/4g/offline
Data Extraction (4)
Tool
Description
safari_extract_tables
Tables as structured JSON
safari_extract_meta
All meta: OG, Twitter, JSON-LD, canonical
safari_extract_images
Images with dimensions and loading info
safari_extract_links
Links with rel, external/nofollow detection
Advanced (5)
Tool
Description
safari_override_geolocation
Override browser geolocation
safari_list_indexed_dbs
List IndexedDB databases
safari_get_indexed_db
Read IndexedDB records
safari_css_coverage
Find unused CSS rules
safari_analyze_page
Full page analysis in one call
Automation (1)
Tool
Description
safari_run_script
Run multiple actions in a single call (batch)
Security
Safari MCP runs locally on your Mac with minimal attack surface:
Aspect
Detail
Network
No remote connections — all communication is local (stdio + localhost)
Permissions
macOS system permissions required (Screen Recording for screenshots)
Data
No telemetry, no analytics, no data sent anywhere
Extension
Communicates only with localhost:9224, validated by Safari
Code
Fully open source (MIT) — audit every line
Safari MCP vs Alternatives
Feature
Safari MCP
Chrome DevTools MCP
Playwright MCP
CPU/Heat
🟢 Minimal
🔴 High
🟡 Medium
Your logins
✅ Yes
✅ Yes
❌ No
macOS native
✅ WebKit
❌ Chromium
❌ Chromium/WebKit
Dependencies
None
Chrome + debug port
Playwright runtime
Tools
80
~30
~25
File upload
JS (no dialog)
CDP
Playwright API
Image paste
JS (no clipboard)
CDP
Playwright API
Focus steal
❌ Background
❌ Background
❌ Headless
Network mocking
✅
❌
✅
Lighthouse
❌
✅
❌
Performance trace
❌
✅
❌
Tip: Use Safari MCP for daily browsing tasks (95% of work) and Chrome DevTools MCP only for Lighthouse/Performance audits.
Safari MCP Servers Comparison
Feature
safari-mcp
MCPSafari
safari-mcp-server
Tools
80
23
~10
License
MIT
None
MIT
Install
npm / Homebrew
Binary
npm
Storage (cookies, localStorage)
10 tools
None
None
Data extraction (tables, links)
5 tools
None
None
Network mocking
Yes
No
No
Device emulation
Yes
No
No
File upload (no dialog)
Yes
No
No
PDF export
Yes
No
No
Console capture
4 tools
1
No
Performance metrics
Yes
No
No
Fallback engine
Dual (Extension + AppleScript)
Extension only
WebDriver
Architecture
Safari MCP uses a dual-engine architecture — the Extension is preferred for speed and advanced capabilities, with AppleScript as an always-available fallback:
Claude/Cursor/AI Agent
↓ MCP Protocol (stdio)
Safari MCP Server (Node.js)
↓ ↓
Extension (HTTP) AppleScript + Swift daemon
(~5-20ms/cmd) (~5ms/cmd, always available)
↓ ↓
Content Script do JavaScript in tab N
↓ ↓
Page DOM ←←←←←←←←←← Page DOM
Key design decisions:
Dual engine with automatic fallback — Extension is preferred; if not connected, AppleScript handles everything seamlessly
Persistent Swift helper — one long-running process instead of spawning per command (16x faster)
Tab-indexed operations — all JS runs on a specific tab by index, never steals visual focus
JS-first approach — typing, clicking, file upload all use JavaScript events (no System Events keyboard conflicts)
No activate — Safari is never brought to foreground
Safari Extension (Optional)
The Safari MCP Extension is optional but recommended. Without it, ~80% of functionality works via AppleScript alone. The extension adds capabilities that AppleScript cannot provide:
What the Extension Adds
Capability
With Extension
AppleScript Only
Closed Shadow DOM (Reddit, Web Components)
✅ Full access
❌ Invisible
Strict CSP sites
✅ Bypasses via MAIN world
❌ Often blocked
React/Vue/Angular state manipulation
✅ Deep (Fiber, ProseMirror)
⚠️ Basic
Loading state detection (spinners, skeletons)
✅ Smart detection
❌ No
Dialog handling (alert/confirm)
❌
✅ Only AppleScript
Native OS-level click (CGEvent)
❌
✅ Only AppleScript
PDF export
❌
✅ Only AppleScript
When do you need the extension? If you're automating modern SPAs with closed shadow DOM (e.g., Reddit), sites with strict Content Security Policy, or framework-heavy editors (Draft.js, ProseMirror, Slate).
Installing the Extension
The extension requires a one-time build with Xcode (free, included with macOS):
Prerequisites: Xcode (install from App Store — free)
# 1. Build the extension appcd safari-mcp
xcodebuild -project"xcode/Safari MCP/Safari MCP.xcodeproj"\-scheme"Safari MCP (macOS)"-configuration Release build
# 2. Find and open the built appopen ~/Library/Developer/Xcode/DerivedData/Safari_MCP-*/Build/Products/Release/Safari\ MCP.app
Then in Safari:
Safari → Settings → Advanced → enable Show features for web developers
The extension connects automatically to the MCP server on port 9224.
Note: "Allow Unsigned Extensions" resets every time Safari restarts. You'll need to re-enable it in the Develop menu after each restart. The extension itself stays installed.
Toolbar icon status:
ON — connected to MCP server
OFF — manually disabled via popup
(no badge) — server not running, will auto-reconnect
macOS Permissions
Safari MCP needs these one-time permissions:
Permission
Where
Why
JavaScript from Apple Events
Safari → Develop menu
Required for do JavaScript
Screen Recording
System Settings → Privacy
Required for safari_screenshot
Accessibility
System Settings → Privacy
Required for safari_save_pdf only
Troubleshooting
Issue
Fix
"AppleScript error"
Enable "Allow JavaScript from Apple Events" in Safari → Develop
Screenshots empty
Grant Screen Recording permission to Terminal/VS Code
Tab not found
Call safari_list_tabs to refresh tab indices
Hebrew keyboard issues
All typing uses JS events — immune to keyboard layout
HTTPS blocked
safari_navigate auto-tries HTTPS first, falls back to HTTP
Safari steals focus
Ensure you're on latest version — newTab restores your active tab