Safari MCP
Let AI agents automate your signed-in Safari session quietly in the background.
- Source repo
- achiya-automation/safari-mcp
- Stars
- ★ 235
- Last updated
- 3d ago
- License
- MIT
- Primary language
- JavaScript
- FA score
- 78/100 · Good
At a glance
- How it runs
- Works with
- Platform-specificClaude Code · Claude.ai
- Cost
- Free, no paid service needed
- Setup effort
- Medium · a few setup steps
- You'll need
- Typical use
- A macOS developer using Claude Code, Cursor, or VS Code wants an agent to work inside an already authenticated GitHub, Gmail, Slack, or internal-dashboard session.
- Not a fit if
- Teams on Windows or Linux — macOS Safari only
- Teams needing Lighthouse or Chrome performance traces
- Anyone who must not touch real logged-in accounts or live data
- Source review
- 78/100 · Good
What does this agent do, and when should you use it?
Safari MCP is a macOS-only local MCP server that exposes 98 Safari browser operations to AI coding tools. Its Node.js server coordinates an optional Safari extension, AppleScript, and a persistent Swift helper to control the everyday Safari profile in which the user is already signed in, rather than launching an isolated headless browser. The toolset covers navigation, page reading, forms, screenshots, storage, network capture and mocking, console output, performance metrics, extraction, native input, and iOS/WebKit checks. It can run over stdio for one client or as a localhost HTTP daemon shared by multiple sessions, with session-scoped tab ownership designed to prevent one agent from steering another agent's tab. It is a strong fit when an automation workflow needs existing cookies, logins, extensions, and real WebKit behavior, but its deployment boundary is strictly a Mac running Safari.
An MCP client starts the server with npx safari-mcp. A typical agent calls safari_snapshot to receive an accessibility tree with element refs, acts through tools such as safari_click, safari_fill, and safari_navigate, and takes another snapshot to verify the result. safari_read_page and safari_get_source return text or HTML; safari_screenshot and safari_save_pdf produce PNG or PDF output; extraction tools return structured tables, links, images, and metadata. The server can also manipulate cookies, localStorage, sessionStorage, and IndexedDB; capture or mock fetch/XHR traffic; collect console messages and performance metrics; and batch actions through safari_run_script. By default, operations are limited to tabs opened by the current session. In shared HTTP mode, tab state and unique markers are keyed by MCP session id, and the server refuses to fall back to the user's active tab if ownership tracking is lost. The optional Safari MCP Bridge handles closed shadow DOM, strict CSP pages, and deeper framework state, while AppleScript and the Swift helper provide fallback execution, CGEvent input, dialog handling, and PDF-related capabilities.
- A macOS developer using Claude Code, Cursor, or VS Code wants an agent to work inside an already authenticated GitHub, Gmail, Slack, or internal-dashboard session.
- A test engineer needs to fill React, Vue, Angular, or Svelte forms, replace content in Monaco, CodeMirror, Ace, or ProseMirror, and verify framework-level state before submission.
- A frontend compatibility team wants to audit iOS viewport metadata, safe-area handling, PWA readiness, and CSS support in the installed Safari version.
- An automation engineer needs structured page extraction plus console, network, and Web Vitals evidence from a real WebKit page.
- A team running several agents wants a shared local HTTP daemon with session-isolated tab ownership and fewer duplicate Node.js processes.
- A Mac user needs network mocking, throttling, device emulation, or geolocation overrides without installing Chromium, Playwright, or Puppeteer.
How do you install or deploy this agent?
Requirements are macOS, Safari, and Node.js 20+. In Safari, enable Settings → Advanced → Show features for web developers, then Settings → Developer → Allow JavaScript from Apple Events. Grant Automation access to Safari for the terminal or IDE that launches the MCP server. Start it directly with:
npx safari-mcpFor a permanent global installation:
npm install -g safari-mcpClaude Code can register it with:
claude mcp add safari -- npx safari-mcpOther MCP clients use command npx with argument safari-mcp. Screenshots, PDF export, and safari_native_* operations additionally require the documented Screen Recording or Accessibility permissions. The optional extension must be built from a GitHub clone with Xcode because the npm package does not include the xcode/ directory.
How do you use this agent?
Begin with safari_snapshot to inspect page state and obtain element refs. Pass those refs to safari_click, safari_fill, or another interaction tool, then call safari_snapshot again to confirm the result. Open an owned background tab with safari_new_tab; the default safety policy will not automatically take control of a tab the user opened. To work in an existing tab, set SAFARI_MCP_ALLOW_USER_TABS=1 and explicitly adopt it with safari_switch_tab; safari_close_tab will still refuse to close an adopted user tab. For concurrent agents, run SAFARI_MCP_HTTP=1 SAFARI_MCP_HTTP_PORT=9225 npx safari-mcp and configure each client for http://127.0.0.1:9225/mcp. Run safari_doctor when diagnosing Apple Events, Accessibility, Screen Recording, code-signing, or daemon-chain failures.
What are this agent's strengths and limitations?
- Reuses the user's real Safari cookies, sessions, logins, and installed extensions instead of requiring authentication in a separate automation browser.
- Its 98-tool surface extends beyond navigation and forms to storage, network mocking, console capture, performance data, extraction, native input, and Safari-specific validation.
- A dual-engine design prefers the extension and falls back to AppleScript plus a persistent Swift helper; the documentation reports roughly 5 ms per persistent-process command.
- Owned-tab guards, fail-closed behavior when tracking is lost, and per-session HTTP isolation reduce the risk of acting on the user's or another agent's tab.
- Normal tab creation and operation run in the background without bringing Safari forward, and no Chrome, Puppeteer, Playwright, or WebDriver dependency is required.
- Both per-client stdio and shared localhost HTTP deployment are documented for a range of MCP-compatible clients.
- The core is tied to macOS and stable Safari; Windows, Linux, and Safari Technology Preview are not supported.
- Initial setup involves Safari developer settings and several macOS permission systems, including Automation, Screen Recording, and Accessibility for particular features.
- The full feature set depends on an optional extension that must be cloned and built with Xcode; allowing unsigned extensions must be re-enabled after each Safari restart.
- Automation runs with the user's real browser identity and authenticated accounts, so actions can affect live data; the project explicitly says this is not an anti-detection feature.
- Native click, hover, and keyboard tools send real OS events to Safari and can interfere if the user is simultaneously working in another Safari tab.
- Lighthouse and Chrome-specific performance traces are absent, leaving those workflows to Chrome DevTools MCP.
How does this agent compare with similar options?
Against Chrome DevTools MCP, Safari MCP emphasizes native WebKit, the user's existing Safari login state, and lower claimed CPU and heat, while offering 98 tools; it does not provide Lighthouse or performance tracing. Against Playwright MCP, it avoids a Playwright runtime and isolated browser session and can inherit the user's authenticated environment, but it is restricted to Safari on macOS. Apple's safaridriver --mcp provides an officially supported, isolated WebDriver session for standards-based debugging, whereas this project controls ordinary signed-in Safari tabs and adds background operation, storage manipulation, network mocking, and a broader tool set. Apple's server is the clearer choice for clean-room WebDriver compatibility testing on Safari 27 or later; this repository is aimed at everyday automation that must reuse the user's normal browser state.
Key facts side by side with the most closely related agents.
| Agent | Source review | Form / cost | Stars | Updated | Language | Full support on |
|---|---|---|---|---|---|---|
| Safari MCP This agent | 78 · Good | MCP serverFree | ★ 235 | 3d ago | JavaScript | Claude Code · Claude.ai |
| Nuphus Desktop Automation MCP | 72 · Some gaps | MCP serverFree + model costs | ★ 332 | 4d ago | Rust | Claude.ai · OpenAI API · Claude API |
| Eko Agentic Workflow | 43 · Major gaps | Library / SDKFree + model costs | ★ 5k | 8mo ago | TypeScript | OpenAI API · Claude API |
| SuperAgentX Workflow Framework | 37 · Major gaps | Library / SDKFree + model costs | ★ 206 | 4mo ago | Python | OpenAI API |
How does FollowAgents rate this agent?
Why each dimension lost points
The repository shows substantive safeguards: pre-existing user tabs are denied by default, sessions use tab markers, lost ownership fails closed, user-tab adoption requires an explicit environment flag and switch action, and adopted tabs cannot be closed. CI blocks high-or-worse production dependency findings and pins GitHub Actions to commits. Deductions apply because the capability surface is inherently broad, including arbitrary page JavaScript, cookies, browser storage, clipboard access, uploads, and native input. Beyond operating-system grants and the user-tab opt-in, there is no evidence of per-action confirmation for form submission, storage mutation, or similar consequential operations. Local data flow and lack of telemetry are documented, but the optional HTTP daemon in the README qualifies SECURITY.md's unconditional no-open-port statement. Sensitive browser data can be read or exported; although the project says credentials are not stored, transmitted, or logged, no output redaction, access tiering, or secret-handling policy is demonstrated. Some reset or restore operations exist, but there is no general rollback for submissions, cookie deletion, or external side effects. The author, organization, email, and repository ownership are stated, but the publisher remains independently unverified.
The package metadata, description of 98 tools, and smoke test that starts the server and enumerates every registered tool are reasonably consistent. CI covers Node 20, 22, and 24 and checks syntax, undefined references, and tests. Deductions reflect the inconsistency between SECURITY.md's stdio/no-port description and the README's optional localhost HTTP daemon, plus the absence of evidence here about real Safari interaction stability. Runtime versions and macOS/Safari prerequisites are explicit and production dependencies are few, but operation depends on Safari developer settings, system permissions, an extension, and a local helper; postinstall also suppresses failure with “|| true”. Failure messaging is thoroughly addressed through actionable tab-guard errors, a doctor tool advertised with per-failure remedies, and smoke-test propagation of server stderr.
The README thoroughly identifies coding agents, concurrent agents, user-owned tabs, demos or voice assistants, web testing, and extraction scenarios. It clearly defines macOS-only support, Node 20+, Safari settings, permission boundaries, session isolation, and a third-party multiplexing caveat. Numerous MCP-client configurations, stdio and HTTP modes, and documented environment controls provide strong environment fit. Trigger precision is only adequate: the snapshot-to-ref workflow and target-selection strategies are clear, but arbitrary JavaScript, coordinate operations, native input, and batch execution provide broad discretion without systematic evidence defining when agents should avoid the higher-risk tools.
The README has clear navigation across quick start, workflow, concurrency, user-tab safety, environment variables, and categorized tools. Prerequisites and installation paths for many clients, Homebrew, and source builds are detailed. Tool names use a stable safari_ prefix, with tests enforcing format and uniqueness. Platform limits, permissions, session conflicts, and security considerations are concrete. MIT metadata matches the complete license text. Package versioning, tag-to-version verification, npm provenance, registry publishing, and a CI-enforced changelog policy demonstrate a mature update path. SECURITY.md supplies supported-version policy, scope, contact, and a response target. The deduction is that the referenced examples directory and changelog contents were not supplied, and there is no comprehensive FAQ in the available material, so their depth cannot be assessed.
Outputs are designed for agent consumption through structured page data, accessibility references, table and link extraction, network details, state verification, and combined operations. The recommended post-action snapshot workflow further improves usability. Driving an already authenticated native Safari session, implementing tab ownership, and offering Safari/WebKit-specific checks provide clear marginal value over generic automation. Cost-benefit is deducted because easy npx installation, few production dependencies, and the shared-daemon design support low setup and process cost, but the prominent approximately 5 ms, 40–60% lower CPU or heat, and zero-heat claims have no supplied benchmark method, raw measurements, or reproducible performance test.
Tool count, naming, license, Node/macOS scope, CI controls, and release controls receive some cross-file support, while the smoke test traces the registered-tool count to source. However, the principal performance claims lack benchmark code or data, and cited articles, issue comments, and testimonials cannot be independently checked within the prompt-only evidence set. The README labels testimonial provenance and separates several limitations clearly, but marketing assertions often place implementation facts, testimonials, and performance conclusions together without consistently identifying inference, measurement conditions, or independently verified fact.
- The agent can read cookies, clipboard contents, and browser storage and can execute arbitrary page JavaScript. Grant it only to trusted MCP clients and avoid unnecessary access to a Safari profile containing sensitive accounts.
- Keep SAFARI_MCP_ALLOW_USER_TABS disabled unless existing-tab control is required. Even when enabled, manually verify the selected tab and consequential submissions, purchases, messages, or deletions.
- Enabling JavaScript from Apple Events, Accessibility, and Screen Recording broadens local automation authority; consider revoking permissions that are no longer needed.
- The shared HTTP daemon listens on a localhost port, qualifying SECURITY.md's no-port summary. Check its bind address, session isolation, and exposure to other local processes before use.
- Do not treat the approximately 5 ms, 40–60% CPU or heat reduction, or zero-heat claims as independently established; the supplied static evidence contains no benchmark data.
- The postinstall command suppresses script failure. Run safari_doctor after installation and verify that the helper, extension, and permission chain are actually available.
Recent releases
Latest entries from the project's GitHub Releases. Notes are quoted from upstream as written, not rewritten or tested by FollowAgents.
-
Release notes excerpt
Added - safari_snapshot({ diff: true }) returns only what changed since that tab's previous snapshot. After a click or a fill an agent usually needs the few lines that changed, not the whole page again. Lines compare without their refs, which every snapshot renumbers in page order, so an element inserted near the top changes one line instead of all the lines after it. + lines are new and carry fresh refs; - lines are gone and are shown without their dead refs, at most 50 of them. The first call for a tab returns the full snapshot. Every snapshot is remembered (the newest 50 tabs …View on GitHub ↗ -
Release notes excerpt
Security - body-parser 2.3.0 → 2.4.0 and zod 4.4.3 → 4.6.7, both through @modelcontextprotocol/sdk, close two high advisories that failed CI's production audit: a denial of service from trailing bytes after a compressed request body in HTTP mode (GHSA-27r3-jxmh-p828), and memory exhaustion while validating oversized constrained collections (GHSA-mrhx-c7xc-m3w5). The same update takes fast-uri 3.1.8 → 3.1.9 (four moderate advisories, via ajv), ip-address 10.7.2 → 10.7.5 (GHSA-rxp7-6hxx-x8q5, via express-rate-limit) and qs 6.16.0 → 6.16.1. Lockfile only; the declared rang …View on GitHub ↗ -
Release notes excerpt
Fixed - A client that navigates its tab to another origin keeps working in it, without SAFARI_PROFILE (#172). When the extension served safari_navigate or safari_navigate_and_read, safari.js kept the URL the tab had left as the session's current page, and the tool then released that URL from the session's ownership. Every later write of the same client (click, fill, evaluate) was refused with "current tab (<the URL it left>) was not opened by this MCP session", whichever receipt it passed. A same-origin navigation hid it, because an owned URL that differs only in its query still …View on GitHub ↗
FAQ
Is the Safari extension mandatory?
Can it accidentally control a tab I am using?
SAFARI_MCP_ALLOW_USER_TABS=1 plus an explicit safari_switch_tab, and adopted tabs still cannot be closed by safari_close_tab.