Safari MCP
Let AI agents automate your signed-in Safari session quietly in the background.
Per-dimension scores and reasoning
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.
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.
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 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.
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.
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.