AA

achiya-automation/safari-mcp

开发工具
164 stars 0 forks 质量 55 趋势 55

Your real Safari, logged in — no Chrome, no heat, no headless.

概览

Your real Safari, logged in — no Chrome, no heat, no headless.

README

❌ Without Safari MCP

Your AI agent needs to browse. So it either:

  • Spins up Chromium via Playwright — with no logins, no cookies, no sessions
  • Uses Chrome DevTools MCP — and melts your fan running a second browser
  • Relies on headless scrapers — blocked by Cloudflare, reCAPTCHA, and bot detection

✅ With Safari MCP

Your AI drives the Safari you’re already logged into — Gmail, GitHub, Ahrefs, Slack, banking.

Native WebKit. ~60% less CPU. Background operation. 97 tools. One npx command. macOS only.

📰 Featured on freeCodeCamp: How to Connect Your AI Coding Agent to a Browser on macOS · HackerNoon: Reverse-Engineering React, Shadow DOM, and CSP

🍎 Apple shipped an official Safari MCP (July 2026 — Safari Technology Preview 247+ and the Safari 27 beta). It’s built on safaridriver for isolated debugging sessions. safari-mcp drives the real Safari you’re already logged into — on the stable Safari that ships with macOS today, with 97 tools. See the full comparison below.


Highlights

  • 97 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 browser 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 (one command)

npx safari-mcp

That’s it — no global install needed. Or install permanently:

npm install -g safari-mcp

Configure your MCP client

All clients run Safari MCP the same way — npx safari-mcp. Pick your editor:


Usage Workflow

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.


Running several agents at once

Multiple agents or subagents driving one Safari at the same time will fight over the active tab — unless you run them against a shared HTTP daemon instead of one process per client:

SAFARI_MCP_HTTP=1 SAFARI_MCP_HTTP_PORT=9225 npx safari-mcp

Then point every client at it:

{ "mcpServers": { "safari-mcp": { "type": "http", "url": "http://127.0.0.1:9225/mcp" } } }

One daemon, many sessions — and each session gets its own tab state. The server keys activeTabIndex, the ownership flag and a unique tab marker off the MCP session id, so session A physically cannot read or steer session B’s tab.

Two properties make this safe rather than merely tidy:

  • Tab identity is a marker, not an index. Each session stamps a unique id into the page it opens, so ownership survives navigation and survives the user reordering or closing other tabs. An index alone would silently drift onto the wrong tab.

  • It fails closed. If a session’s marked tab can’t be re-found, every tool refuses instead of falling back to whatever tab is in front — because that tab is usually yours:

    Tab tracking lost — refusing to fall back to "current tab of window"
    (would target the user's active tab). Call safari_new_tab to reopen.
    

This also drops process count sharply: ~17 node processes for 17 concurrent sessions becomes 1.

SAFARI_PROFILE stays optional — leave it unset and sessions bind to your ordinary Safari windows, cookies and logins intact. Details in docs/http-transport-design.md.

Prefer stdio (one process per agent) over a persistent daemon? That works too — isolation then comes from the process boundary itself. One caveat: if your client multiplexes agents through mcporter, mcporter caches a single MCP client for all of them — whichever transport you pick — so the server never sees distinct sessions and per-session isolation can’t engage. mcporter-lanes (a pi extension by @maxim, born out of #76) fixes this upstream: each agent session gets its own daemon dir — and therefore its own safari-mcp — with an idle timeout so processes don’t pile up.


Tools (97)


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
Browser dependencies None Chrome + debug port Playwright runtime
Tools 97 ~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.

vs Apple’s Official Safari MCP (safaridriver)

In July 2026 Apple shipped an official Safari MCP server built on safaridriver — first in Safari Technology Preview 247, and now also in the Safari 27 beta. That’s great validation for the category — and it’s built for a different job. Apple’s server drives an isolated WebDriver automation session for debugging; safari-mcp drives the real Safari you’re already logged into.

It has not reached a stable Safari release yet: on macOS 26.5.2 with Safari 26.5.2, safaridriver --help lists --port, --bidi, --enable and --diagnose, and no --mcp (verified 2026-07-23). Check your own machine with safaridriver --help | grep mcp before assuming either way.

🦁 safari-mcp (this repo) Apple safaridriver --mcp
Your real logins / cookies ✅ Your actual Safari ⚠️ Isolated automation session — no access to AutoFill or browsing activity
Runs on ✅ Stable Safari, every Mac ⚠️ Safari Technology Preview 247+ or the Safari 27 beta — not in stable Safari 26.5
Background (no focus steal) ✅ Yes ❌ Dedicated window with a “controlled by automation” banner
Tools 97 ~17
Storage (cookies, localStorage, IndexedDB) ✅ 10 tools
Network mocking + throttling ✅ Yes ❌ Read-only network inspection
Device emulation (iPhone, iPad) ✅ Yes ⚠️ Viewport + media type only
Setup npx safari-mcp Enable “remote automation and external agents”, then point your client at that build’s safaridriver --mcp
Official Apple support ❌ Community (MIT) ✅ Apple, WebDriver-standard

When Apple’s server is the right pick: you specifically want a clean-room, WebDriver-standard session for compatibility debugging and you already run a preview or beta build. For everything else — daily automation on the browser you’re already signed into, on the Safari that shipped with your Mac — safari-mcp is built for exactly that.

Why Safari MCP and Not the Other Safari MCP Projects?

There are several “safari-mcp” projects floating around. Here’s how they compare:

Feature 🦁 safari-mcp (this repo) lxman/safari-mcp-server Epistates/MCPSafari HayoDev/safari-devtools-mcp
Tools 97 ~10 23 ~15
Install npx safari-mcp Manual Binary npx
Engine Dual (Extension + AppleScript) WebDriver Extension only DevTools Protocol
Keeps your real Safari logins ✅ Yes ⚠️ Limited ✅ Yes ❌ Debug session
Background (no focus steal) ✅ Yes ❌ No ⚠️ Sometimes ✅ Yes
Storage tools (cookies, localStorage, IndexedDB) 10 0 0 2
Data extraction (tables, meta, images, links) 4 0 0 0
Network mocking ✅ Yes ❌ No ❌ No ❌ No
Device emulation (iPhone, iPad, Pixel) ✅ Yes ❌ No ❌ No ❌ No
File upload (no dialog) ✅ JS DataTransfer ❌ No ❌ No ❌ No
Image paste (no clipboard touch) ✅ Yes ❌ No ❌ No ❌ No
PDF export ✅ Yes ❌ No ❌ No ❌ No
Console capture 4 tools 0 1 1
Performance metrics + Web Vitals ✅ Yes ❌ No ❌ No ⚠️ Partial
Active maintenance ✅ Multiple releases/week 🟡 Sporadic 🟡 Slow 🟡 Slow
License MIT MIT None specified MIT
In MCP Registry
In Awesome MCP

TL;DR — if you want the most complete Safari MCP with the smoothest install, the most tools, and active maintenance, this is the one.


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).

Note for npm users: The xcode/ directory is not included in the npm package. Clone the GitHub repository to build from source.

Prerequisites: Xcode (install from App Store — free)

# 1. Clone the repo (the npm package does not include the Xcode project)
git clone https://github.com/achiya-automation/safari-mcp.git
cd safari-mcp

# 2. Build the extension
xcodebuild -project "xcode/Safari MCP/Safari MCP.xcodeproj" \
  -scheme "Safari MCP (macOS)" -configuration Release build

# 3. Ad-hoc sign the built app so Safari will load it
# (xcodebuild without a signing identity produces a bundle Safari silently rejects)
APP_PATH=$(find ~/Library/Developer/Xcode/DerivedData/Safari_MCP-*/Build/Products/Release -name "Safari MCP.app" -maxdepth 2 | head -1)
codesign --sign - --force --deep "$APP_PATH"

# 4. Re-sign safari-helper with the Apple Events entitlement
# (helps macOS surface the TCC Automation prompt reliably)
codesign --sign - --force --entitlements safari-helper.entitlements safari-helper

# 4. Open the app (needed once so Safari registers the extension)
open "$APP_PATH"

Alternatively, open xcode/Safari MCP/Safari MCP.xcodeproj directly in Xcode, select your Apple ID under Signing & Capabilities, and click Run. A free personal Apple Developer account is sufficient for local use.

Then in Safari:

  1. Safari → Settings → Advanced → enable Show features for web developers
  2. Safari → Develop → Allow Unsigned Extensions (required each Safari restart)
  3. Safari → Settings → Extensions → enable Safari MCP Bridge

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
Automation → Safari System Settings → Privacy & Security → Automation Required for all AppleScript-backed tools
Screen Recording System Settings → Privacy & Security → Screen Recording Required for safari_screenshot
Accessibility (safari-helper) System Settings → Privacy & Security → Accessibility Required for safari_native_click, safari_native_keyboard, safari_native_hover and safari_save_pdf

Granting Accessibility to safari-helper (required for safari_native_*)

The safari_native_click, safari_native_keyboard and safari_native_hover tools inject OS-level CGEvent events into Safari without stealing focus. macOS requires the underlying helper binary to be approved in Accessibility before those events can reach a non-frontmost window.

  1. Open System Settings → Privacy & Security → Accessibility.
  2. Click + (unlock with your password if needed).
  3. Navigate to the helper binary and add it:
    • npm global install: $(npm root -g)/safari-mcp/safari-helper
    • npx / project install: ./node_modules/safari-mcp/safari-helper
    • From source clone: /path/to/safari-mcp/safari-helper
  4. Make sure the toggle next to it is ON.

The postinstall script re-signs the helper with a stable identifier (com.achiya-automation.safari-mcp) so this permission survives future upgrades — without that step, every npm update would silently revoke approval because the binary’s adhoc-signed identifier changes per build.

If safari_native_click reports success but the page doesn’t react (no isTrusted: true click events fire), the helper is most likely missing this approval. The safari_* (non-native_) tools don’t need it.

Granting Automation → Safari (important for IDE users)

macOS TCC grants Automation permission to the parent process that spawns the MCP server, not to safari-mcp itself. So you need to grant Automation → Safari to the app that runs Claude Code / Cursor / Windsurf — typically Visual Studio Code or Terminal.

If the permission dialog never appears automatically, run this command once from a Terminal that already has Automation permission:

osascript -e 'tell application "Safari" to get URL of current tab of window 1'

That call registers the Terminal app in the Automation database and then triggers the prompt for Safari. After you approve it, subsequent MCP calls from any child process chain will work.


Troubleshooting

Issue Fix
“AppleScript error” Enable “Allow JavaScript from Apple Events” in Safari → Develop
“Not authorized to send Apple events to Safari” Grant Automation → Safari to your IDE (see above)
“Not authorized” after npm update Updating changes the binary’s cdhash — macOS silently revokes Automation permission. Re-run the osascript one-liner above to re-grant it
safari_native_click reports success but page doesn’t react Add safari-helper to System Settings → Privacy & Security → Accessibility (see Granting Accessibility above). Confirm by attaching a click listener with {capture:true} in the page console — without the grant, no isTrusted: true event fires
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

Works With

Safari MCP works with any MCP-compatible client:

Client Status
Claude Code ✅ Tested daily
Claude Desktop ✅ Tested
Cursor ✅ Tested
Windsurf ✅ Compatible
VS Code + Continue ✅ Compatible

Contributing

PRs welcome! See CONTRIBUTING.md for setup instructions.

The codebase is two files:

  • safari.js — Safari automation layer (AppleScript + JavaScript)
  • index.js — MCP server with tool definitions

Sponsors

Safari MCP is free and open source. If it saves you time or CPU cycles, consider supporting its development:

Your support funds:

  • 🧪 Testing across macOS versions and Safari releases
  • 🛠️ New tools and features
  • 📖 Documentation and examples

Become the first sponsor!


Commercial Support

Need Safari MCP integrated into your product or agent stack? Achiya Automation offers:

  • Priority bug fixes and custom tool development for your use case
  • Integration consulting — wiring Safari MCP into production agent systems (Claude, Cursor, n8n, custom)
  • Private deployment support — multi-user Safari MCP, non-standard macOS environments, CI/CD
  • Training workshops for engineering teams adopting MCP-based automation

Built by the author of Safari MCP. Start a conversation →


What agents unlock with Safari MCP

When an AI agent drives Safari MCP, it gets things a headless browser can’t:

  • Real authenticated sessions — Gmail, GitHub, Ahrefs, Slack, banking dashboards are all already logged in
  • Framework-aware form fillingsafari_fill_and_submit calls React/Vue/Angular setters natively, no guessing whether input events fired
  • Background operation — the agent works in parallel while you keep using your Mac
  • One MCP call per workflowsafari_run_script batches navigation + clicks + extraction into a single roundtrip

The pattern holds across models: drive the browser the human already trusts — you inherit logins, cookies, extensions, and the user’s exact environment in one step.


Community

6,000+ monthly npm downloads — developers are building AI agents on macOS with Safari MCP.

  • GitHub Discussions — ask questions, share use cases
  • Issues — bug reports and feature requests
  • — start contributing

Ecosystem

Other macOS MCP servers that complement Safari MCP:

Project What it does When to use
mcp-server-macos-use OS-level macOS automation (accessibility, screen control) System-wide interactions beyond Safari
chrome-devtools-mcp Chrome DevTools Protocol Lighthouse audits, Chrome-specific performance traces

Using Safari MCP alongside Chrome DevTools MCP? Safari handles 95% of daily browsing (zero overhead), Chrome handles the 5% that needs Lighthouse or Chrome-specific traces.


Like it? Give it a ⭐

If Safari MCP saves you from Chrome overhead, a star helps others discover it:

Share on Twitter/X · Share on LinkedIn · Write about it


Listed On


License

MIT — use it however you want.


Built by Achiya Automation — automation & AI agents for business.

View this README on GitHub

安装

npx safari-mcp

配置

{ "mcpServers": { "safari": { "command": "npx", "args": ["safari-mcp"] } } }