MCP

Automate the Safari you are already signed into (macOS only)

For people who want to drive an already signed-in Safari on macOS for page reads and click/fill by ref; you need Node.js 20+ and Safari developer features plus Apple Events turned on.

Official source · safari-mcp

Install

npx safari-mcp

Who it's for

If you want an assistant to first see a page clearly in the Safari you already have open and signed into, then click or fill by reference, this path matches. It drives the stable Safari that ships with macOS, not a clean isolated browser started separately. Hard prerequisites: the machine must be macOS, and Node.js 20+ must already be installed here. Windows or Linux have no usable steps in the existing docs.

The repository places itself on the line of "keep using the Gmail, GitHub, Ahrefs, Slack, and online-banking sessions you are already signed into", and mentions native WebKit and background running. That means the assistant will meet a real login state, not an empty demo session. Whoever calls it is treated as allowed to see what is already on those tabs.

It does not fit people who only want to tap a page in an isolated environment, or who do not want the assistant to see real accounts. Non-Apple systems also have no second install path. If your goal is a "fresh, signed-out, throwaway session", the existing docs do not describe that path.

First try in 3 minutes

The official main path is only one: on a Mac that already meets the prerequisites, run

npx safari-mcp

The repository says a global install is not required first. The optional permanent install is npm install -g safari-mcp; do not take it on the first try.

Before start, check these four things: the system is any macOS with Safari; Node.js is 20 or newer; Safari has Settings → Advanced → Show features for web developers on; then Develop → Allow JavaScript from Apple Events is on. Missing one item means later calls have no basis.

The configuration location is this start command itself. Hand it to your MCP host to launch the service. Existing docs do not give JSON field names for a specific client, so this text does not add a config template and does not invent extra start flags.

The first time, only observe: call safari_snapshot and read the current page's accessibility tree. Success signal is page state returned, not an error or an empty tree. This read sees the real page structure you are looking at, including visible controls on signed-in sites. It is not zero risk, and it must not be read as "no local reads, no network".

If several assistants on the same machine will use Safari at once, the shared form in the docs is:

SAFARI_MCP_HTTP=1 SAFARI_MCP_HTTP_PORT=9225 npx safari-mcp

A single-person first try does not need this.

Use cases

Case 1: See the current tab before deciding the next step. Call safari_snapshot on the already-open Safari page to get the accessibility tree and page state. The docs list this as step one of the recommended workflow, with the goal Get page state. It fits confirming which page you are on and which controls can be referenced. The full return-field structure is not expanded; what can be confirmed is that you can get page state and an accessibility tree. Do not treat this step as navigation or a page change; existing docs give no navigation-class commands.

Case 2: Interact once by reference and read back. Step two is safari_click/fill/..., click or fill by ref; step three runs safari_snapshot again to check the result. This requires a ref from case 1; do not click coordinates from thin air. Clicks and fills change the page and have side effects; before acting, set a confirmation point — whether the matching control or copy changed as expected in the second snapshot. The tool name is written safari_click/fill/...; other interaction names are not listed one by one, so do not invent undocumented commands.

Limits

macOS only. Node.js 20+ is required, and Safari developer features plus JavaScript from Apple Events must be on. The service opens the stable Safari you are already signed into; mail, code hosting, analytics backends, chat, and banking sessions may all enter the assistant's view. Do not assume network isolation or a local read-only sandbox.

For concurrency, share a daemon with SAFARI_MCP_HTTP=1; the docs also say that when tab tracking fails it closes, instead of hitting the active tab you are using. Failure codes, undo steps, and tool parameters beyond safari_snapshot and safari_click/fill are not in the existing docs. Background running and lower CPU are the repository's own comparison claims, not a guarantee for this machine. If the first try is only a snapshot, it still reads a real page; first avoid banking tabs or any tab you do not intend to expose.