
Safari Mcp
io.github.achiya-automation由 GitHub 帳號 achiya-automation 發布v2.23.0更新於 Oct 29, 2026
Native Safari browser automation for AI agents — 98 tools, zero Chrome overhead.
概覽
本機 MCP 伺服器,讓 AI 助理在 macOS 上操作使用者真正的 Safari:導覽、點擊、填表、讀取頁面、截圖並檢查網路與主控台。
- 可以做什麼
- 導覽分頁與瀏覽紀錄,讀取頁面文字、HTML 與帶元素參照的無障礙快照
- 點擊、懸停、拖曳、輸入、填寫並送出表單,包含 React 元件與程式碼編輯器
- 截圖與匯出 PDF、捲動、調整視窗、模擬裝置、處理對話框
- 讀寫 Cookie、本機/工作階段儲存、剪貼簿、IndexedDB 與地理位置
- 檢視網路請求、模擬介面回應、擷取主控台輸出、量測效能並限制網路速度
- 執行 JavaScript,擷取表格、連結、圖片與中繼資料,並一次批次執行多個動作
- 適用情境
- 適合需要讓代理在 Mac 上使用者已登入的 Safari 中操作網頁的情境,例如測試網頁應用、填寫表單、擷取頁面資料或檢查 iOS/WebKit 相容性,而不必另裝 Chrome 或無頭瀏覽器。
- 執行需求
- 需要 macOS 與 Safari,以及 Node.js 20 以上版本;透過 npx 或全域 npm 安裝在本機執行。Safari 需開啟開發者功能與「允許來自 Apple 事件的 JavaScript」。另需 macOS 權限:Safari 的自動化權限(授予啟動它的父應用程式,如 VS Code 或終端機)、截圖與 PDF 所需的螢幕錄製權限,以及原生輸入工具所用 safari-helper 的輔助使用權限。選用的 Safari 擴充功能需以 Xcode 建置。
安裝
在 SourceWeft 中
- 開啟 儀表板中的 Safari Mcp,將其新增到工作區。
- 為需要使用其工具的對話啟用該服務。
Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。
其他 MCP 客戶端
參照 儲存庫 中的啟動說明。
README
🦁 Safari MCP
The browser for your coding agent.
Your real Safari, logged in — no Chrome, no heat, no headless.
[npm version] [npm downloads] [License: MIT] [macOS] [OpenSSF Scorecard]
Install in VS Code · VS Code Insiders · Install in Cursor
98 tools · No Chrome/Puppeteer/Playwright needed · ~5ms per command · 60% less CPU than Chrome
Quick Start · All 98 Tools · Examples · Why Safari MCP? · Architecture · Changelog
❌ 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. 98 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 ships an official Safari MCP —
safaridriver --mcp, first in Safari Technology Preview 247 (July 2026) and in stable Safari since 27.0. It drives an isolated automation session for debugging. safari-mcp drives the real Safari you're already logged into — your cookies and sessions, in the background, with 98 tools. See the full comparison below.
Highlights
- 98 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
In users' own words
Not solicited testimonials — quotes lifted from the public issue tracker, each linked to the thread it came from.
"I run multiple Pi sessions/subagents against my normal Safari profile in parallel. Sharing its cookies and logins is intentional." — @maxim, on running concurrent agents against a real browser
"The server has a deliberate tab-ownership model … the code is careful about this, and for the default case that's the right safety posture." — @turner-moore, on why the guards refuse to touch your tabs
"Direct local validation from the package: Safari MCP doctor 6/6." — @jrepp, who found and fixed a queue-alignment bug in the focus helper
Quick Start
Prerequisites
- macOS (any version with Safari)
- Node.js 20+
- Safari → Settings → Advanced → Show features for web developers ✓
- Safari → Settings → Developer → Allow JavaScript from Apple Events ✓
Install (one command)
That's it — no global install needed. Or install permanently:
Configure your MCP client
All clients run Safari MCP the same way — npx safari-mcp. Pick your editor:
Claude Code
Or edit ~/.mcp.json:
Claude Desktop
Edit ~/Library/Application Support/Claude/claude_desktop_config.json:
Restart Claude Desktop after saving.
Cursor
One-click: Install in Cursor
Or edit .cursor/mcp.json in your project:
VS Code / VS Code Insiders
One-click: Install in VS Code
Or edit .vscode/mcp.json:
Windsurf
Edit .windsurf/mcp.json in your project (or ~/.codeium/windsurf/mcp_config.json globally):
Cline
Open Cline in VS Code → click the MCP icon → Edit MCP Settings → add:
Continue
Edit ~/.continue/config.yaml (or .continue/config.yaml in workspace):
Goose
Edit ~/.config/goose/config.yaml:
LM Studio
Open LM Studio → Settings → MCP Servers → Add Server:
- Name:
safari - Command:
npx - Args:
safari-mcp
Zed
Open Zed → Settings → search for "Context Servers" and add:
Alternative: Homebrew
Alternative: from source
Usage Workflow
The recommended pattern for AI agents using Safari MCP:
Element targeting — tools accept multiple targeting strategies:
Tip: Start with
safari_snapshotto get element refs, then use refs for precise targeting. This is faster and more reliable than CSS selectors.
After a click or a fill, safari_snapshot with diff: true returns only the lines that changed since that tab's previous snapshot: + lines are new and carry fresh refs, - lines are gone. The first call for a tab returns the full snapshot.
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:
Then point every client at it:
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:
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.
Acting on a tab you already have open
By default the server touches only tabs it opened itself. Point it at one of yours and it refuses:
That default exists because early versions did click into and close people's tabs. But "read the article I'm looking at" and "fill in the form on my screen" are real, and reopening the page loses the session state that made your tab worth using. Set SAFARI_MCP_ALLOW_USER_TABS=1 and an explicit safari_switch_tab adopts the tab instead of refusing it; from then on the session works in it like one of its own, and says so:
What the flag deliberately does not do:
- It unlocks adoption, not the guards. Only
safari_switch_tabadopts, and only the tab you named. An ordinary click or navigate still never lands on whatever tab happens to be in front — the server acts on the tab you pointed it at, not the one you wandered to. safari_close_tabstill refuses. Closing is the one action whose cost you cannot undo, so an adopted tab is writable, never disposable. Close it yourself.- Adoption is session-local. Nothing is written to the shared ownership file, so it ends with the session rather than leaking to the next process on the machine.
safari_doctor prints the flag's state, and every operation on an adopted tab logs (user tab, opted-in) — so "why did it touch my tab" has an answer instead of being a mystery. Default off; set it only for agents you want working inside your own browsing session. Designed in #92.
Environment variables
SAFARI_MCP_RAISE_ON_NAVIGATE=1 is for agents whose whole point is showing you a page — a voice assistant answering "open YouTube", a demo driver. Everything else should leave it off: by default Safari MCP works in the background and hands focus back to whatever app you were using, so an agent can drive a page while you keep typing somewhere else.
Tools (98)
Click to expand the full tool list — organized by category
Navigation (4)
Page Reading (3)
Click & Interaction (6)
Form Input (11)
Screenshots & PDF (3)
Scroll (3)
Tab Management (5)
Wait (2)
JavaScript (3)
Element Inspection (4)
Accessibility (2)
Drag & Drop (1)
File Operations (2)
Dialog & Window (2)
Device Emulation (2)
Cookies & Storage (11)
Clipboard (2)
Network (6)
Console (4)
Performance (2)
Data Extraction (4)
Advanced (7)
Automation (1)
Native Input — CGEvent (4)
iOS & WebKit Validation (4)
Security
Safari MCP runs locally on your Mac with minimal attack surface:
Safari MCP vs Alternatives
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 in stable Safari since 27.0. 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.
On macOS 27.0 with Safari 27.0, safaridriver --help lists --mcp and its tools/list answers with 17 entries (verified 2026-09-15); Safari 26.5.2 had no --mcp (verified 2026-07-23). Check your own machine with safaridriver --help | grep mcp.
Running both? Apple's setup guide registers its server under the name
safari-mcp(claude mcp add safari-mcp -- /usr/bin/safaridriver --mcp) — the same name as this package. Give one of them a different name, e.g.claude mcp add safari-webdriver -- /usr/bin/safaridriver --mcp, so your client doesn't overwrite one with the other or leave you guessing which server answered.
About that
navigator.webdriverrow: the WebDriver standard requires every remote-controlled session to reporttrue, so Apple's server does. safari-mcp evaluates JavaScript in an ordinary tab, so it readsfalse(checked on Safari 27.0, 2026-09-17). That is the difference if a site refuses WebDriver traffic. It is not an anti-detection feature — nothing else about the browser is disguised, and your real logins are in use, so treat every page as if it knows exactly who you are.
When Apple's server is the right pick: you specifically want a clean-room, WebDriver-standard session for compatibility debugging on Safari 27 or later. For everything else — daily automation on the browser you're already signed into, in the background — 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:
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:
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
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)
Do not ad-hoc re-sign
Safari MCP.appwithcodesign --deep --sign -. That replaces the Apple Development identity on the wrapper and embedded extension; current Safari can then silently disable or mark the extension as removed. If a previous build was ad-hoc signed, run theclean buildcommand above again.
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:
- Safari → Settings → Advanced → enable Show features for web developers
- Safari → Settings → Developer → Allow unsigned extensions (required each Safari restart)
- Safari → Settings → Extensions → enable Safari MCP Bridge
The extension connects automatically to the first local bridge whose declared Safari profile matches its own. The default bridge ports are 9224, 9228, 9232, and 9236; a single-profile setup normally uses 9224.
Note: "Allow unsigned extensions" resets every time Safari restarts. You'll need to re-enable it in Safari → Settings → Developer 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:
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.
- Open System Settings → Privacy & Security → Accessibility (on macOS 27 the pane is named Device Control and Data Access).
- Click
+(unlock with your password if needed). - 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
- npm global install:
- 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:
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
FAQ
Does it work with Safari Technology Preview?
No. Every AppleScript path targets application "Safari" and the native helper looks for the bundle id com.apple.Safari, so STP (com.apple.SafariTechnologyPreview) is a different application that safari-mcp never addresses. Run it against stable Safari.
Note that Apple's own safaridriver --mcp server is the one that needs STP 247+ (or Safari 27+) — see Safari MCP vs Alternatives. The two are unrelated.
Can it handle private/incognito tabs?
Not as a supported mode, and it is untested. No tool opens a private window, and Safari disables extensions in Private Browsing unless you turn each one on explicitly, so the extension bridge — and everything in the "With Extension" column of Safari Extension (Optional) — is off there by default.
If you want an isolated identity, use a separate Safari profile instead: profile windows are a first-class concept here (see Running several agents at once).
Does it work with multiple Safari windows?
Yes. Tab lookups walk every window rather than assuming window 1, and a tab is pinned by its window's (index, tabCount) pair, because an index on its own is ambiguous once two windows are open. Profile windows are recognised by Safari's ProfileName — Tab Title window naming.
The reliable handle is still the receipt that safari_new_tab returns: pass it to every later call and the tab is addressed directly, no matter how many windows move around it.
What macOS versions are supported?
Any macOS with Safari — the package declares "os": ["darwin"] and no minimum OS, and there is no version gate in the code. Node.js 20+ is the hard requirement ("engines": { "node": ">=20" }).
Two places where the OS does matter in practice:
- On macOS 27 the Accessibility pane is renamed Device Control and Data Access — same grant, new name (see macOS Permissions).
- Safari 26 and 27 changed several web-platform behaviours that specific tools account for; those are handled, not blocked.
Can I run multiple instances simultaneously?
Yes — that is what Running several agents at once covers. Each session owns its own tabs, and ownership is tracked per session rather than by tab index, so one agent cannot act on (or close) a tab another agent owns.
One process binds the extension bridge port; the others proxy through it and take the port over if that process exits.
Do I need to keep Safari in the foreground?
No. safari_new_tab opens a background tab and never steals focus, and the few commands macOS forces an implicit activate on restore your previous frontmost app afterwards — with a guard that leaves focus alone if you were typing in Safari yourself a moment earlier.
The two exceptions are the deliberately native tools — safari_native_click, safari_native_keyboard, safari_native_hover — which post real OS events and therefore land wherever the frontmost window is. Do not use those while you are working in another Safari tab.
How does it interact with Safari extensions?
Your existing extensions keep running normally; safari-mcp drives the same Safari you use, so content blockers and password managers behave exactly as they do for you.
safari-mcp also ships its own optional extension. Without it roughly 80% of the tools still work over AppleScript alone; with it you additionally get closed shadow DOM, strict-CSP sites, deep framework state and loading-state detection. Dialog handling, native clicks and PDF export go the other way — those are AppleScript-only. The full split is in Safari Extension (Optional).
What happens if "Allow JavaScript from Apple Events" is not enabled?
Anything that evaluates JavaScript fails — safari_evaluate, safari_read_page, form filling, extraction — while pure AppleScript actions such as opening or switching tabs still work. That is the usual cause of "it opens the tab but reads nothing".
Turn it on in Safari → Settings → Advanced → Show features for web developers, then Safari → Settings → Developer → Allow JavaScript from Apple Events. Both are listed under Prerequisites. safari_doctor walks the rest of the chain (Automation, native helper, Accessibility, Screen Recording) and names this setting in its fix hint — but its Apple Events check only counts windows, which Automation permission alone satisfies, so it will not fail on this one for you.
Works With
Safari MCP works with any MCP-compatible client:
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
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 filling —
safari_fill_and_submitcalls React/Vue/Angular setters natively, no guessing whetherinputevents fired - Background operation — the agent works in parallel while you keep using your Mac
- One MCP call per workflow —
safari_run_scriptbatches 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
- [Good First Issues] — start contributing
Ecosystem
Other macOS MCP servers that complement Safari MCP:
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.
Listed On
[Glama] [MCP Registry] [MCP Scoreboard] [CI]
License
MIT — use it however you want.
Built by Achiya Automation — automation & AI agents for business.
來源:README.md,提交 cc9a082
工具
0版本歷史
22- v2.23.0最新Oct 29, 2026
- v2.22.19Oct 26, 2026
- v2.22.18Oct 19, 2026
- v2.22.17Oct 14, 2026
- v2.22.16Oct 13, 2026
- v2.22.15Oct 10, 2026
- v2.22.14Oct 9, 2026
- v2.22.13Oct 7, 2026
- v2.22.11Oct 6, 2026
- v2.22.10Oct 4, 2026
- v2.22.9Oct 3, 2026
- v2.22.8Oct 2, 2026
- v2.22.7Oct 1, 2026
- v2.22.5Sep 30, 2026
- v2.22.4Sep 28, 2026
- v2.22.2Sep 28, 2026
- v2.21.14Sep 24, 2026
- v2.21.13Sep 22, 2026
- v2.21.12Sep 20, 2026
- v2.21.11Sep 18, 2026
- v2.21.10Sep 17, 2026
- v2.21.9Sep 16, 2026
評分
已滿足適用檢查項的 50%
該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。
- 近 30 天內可連通25 分
請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。
- 已宣告認證方式10 分
請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。
- 已列出工具15 分
請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。
- 描述必需15 分
- 圖示10 分
- 文件15 分
- 授權條款10 分