safari_navigateLABSCO SUMMARY
You pay in macOS permissions, not in credentials.
This one automates the Safari session you already have, so anything behind a sign-in is reachable with no credential handoff and nothing to log into twice. Read that as the cost as well as the feature — every site that Safari is signed into is within reach of whatever is driving the tools, and the setup is a chain of local grants (Apple Events, Automation, Screen Recording, Accessibility) that each fail in their own quiet way. The failure modes are at least well marked: safari_doctor walks the chain, and when a session loses track of the tab it opened, the tools refuse rather than fall back onto the tab you are reading. Two things to size up before installing: it is macOS-only, and the extension-only capabilities need an Xcode build plus a Safari setting that resets on every restart.
What it is
A macOS-only MCP server that automates the Safari you already use, rather than launching a separate automation browser. Two engines sit underneath it: an optional Safari extension talking to a local bridge, and AppleScript driven through a persistent Swift helper, which is always available and takes over when the extension is not connected. It ships as the npm package safari-mcp (2.16.3) over stdio, runs npx safari-mcp with no arguments, and is MIT licensed. There is also an opt-in HTTP mode — SAFARI_MCP_HTTP=1 SAFARI_MCP_HTTP_PORT=9225 npx safari-mcp — so several clients share one process instead of one process each.
What you get
- Navigation and page reading —
safari_navigate,safari_navigate_and_read,safari_read_page,safari_get_source - Page state an agent can target by reference —
safari_snapshotreturns an accessibility tree with a ref id on every interactive element, andsafari_accessibility_snapshotgives roles and ARIA - Clicking and pointing —
safari_click,safari_click_and_read,safari_hover,safari_drag, addressable by CSS selector, visible text, coordinates, or a ref from a snapshot - Forms and editors —
safari_fill,safari_fill_form,safari_fill_and_submit,safari_select_option,safari_react_select_set, plussafari_replace_editorfor Monaco, CodeMirror, Ace and ProseMirror andsafari_verify_stateto read back framework-level state - Tabs —
safari_list_tabs,safari_new_tab,safari_switch_tab,safari_wait_for_new_tabfor popups such as an OAuth window - Capture —
safari_screenshot,safari_screenshot_element,safari_save_pdf - Network and console —
safari_start_network_capture,safari_network_details,safari_mock_route,safari_throttle_network,safari_start_console,safari_get_console - Cookies and storage —
safari_get_cookies,safari_set_cookie,safari_local_storage,safari_session_storage,safari_export_storage,safari_import_storage,safari_list_indexed_dbs,safari_get_indexed_db - OS-level input —
safari_native_click,safari_native_type,safari_native_keyboard,safari_native_hoversend CGEvent events to Safari without bringing it to the front - Page analysis and diagnostics —
safari_analyze_page,safari_performance_metrics,safari_css_coverage,safari_webkit_compat,safari_inspect_viewport,safari_safe_area_insets,safari_check_pwa, andsafari_doctorfor the permission chain - Batching —
safari_run_scriptruns several actions in one call
Requirements
No account and no API key: it holds no remote connections, communicating over stdio and localhost only. What it needs instead is macOS with Safari, Node.js 20+, and a chain of local grants. Two switches inside Safari: Settings → Advanced → "Show features for web developers", then Develop → "Allow JavaScript from Apple Events". Three in System Settings → Privacy & Security: Automation → Safari, which macOS attaches to the app that launches the server (Terminal, VS Code) rather than to safari-mcp itself; Screen Recording for safari_screenshot; and Accessibility for the bundled safari-helper binary, without which the safari_native_* tools and safari_save_pdf report success but nothing moves. An npm update changes the binary's cdhash and macOS drops the Automation grant silently — the README's one-line osascript call re-triggers the prompt. The Safari extension is optional and is not in the npm package: clone the repo and build the Xcode project, and note that Develop → "Allow Unsigned Extensions" has to be re-enabled after every Safari restart.
Setup effort
One command — npx safari-mcp
USE CASES
Testing a flow that only exists behind a login
The agent works in the Safari session you already have, so a page that requires you to be signed in loads the way it does for you — nothing to configure on a separate automation browser.
Filling a form that a framework owns
Values go in through React, Vue and Angular setters rather than as keystrokes, code editors get replaced wholesale, and the state the component actually holds can be read back before anything is submitted.
Watching what a page asks for while it runs
Capture fetch and XHR traffic with headers and timing, substitute your own response for a route, or throttle the connection down to slow-3g and see what the page does.
Running several agents against one Safari
Start the opt-in HTTP daemon and point every client at http://127.0.0.1:9225/mcp. Each MCP session keeps its own active-tab pointer, marked so it survives navigation and tab reordering; a session that cannot re-find its tab stops instead of steering the tab in front of you.
Working out why a tool call did nothing
One call walks the macOS permission and daemon chain — Apple Events, Accessibility, Screen Recording, code signing — and names the link that failed together with its fix.
97 tools
Listed in project docs. Your client may show a different list.
safari_go_backsafari_go_forwardsafari_reloadsafari_read_pagesafari_get_sourcesafari_navigate_and_readsafari_clicksafari_double_clicksafari_right_clicksafari_hoversafari_click_and_waitsafari_click_and_readsafari_fillsafari_clear_fieldsafari_select_optionsafari_fill_formsafari_fill_and_submitsafari_type_textsafari_press_keysafari_react_select_setsafari_react_select_list_optionssafari_replace_editorsafari_verify_statesafari_screenshotsafari_screenshot_elementsafari_save_pdfsafari_scrollsafari_scroll_tosafari_scroll_to_elementsafari_list_tabssafari_new_tabsafari_close_tabsafari_switch_tabsafari_wait_for_new_tabsafari_wait_forsafari_waitsafari_evaluatesafari_eval_filesafari_get_elementsafari_query_allsafari_get_computed_stylesafari_detect_formssafari_accessibility_snapshotsafari_snapshotsafari_dragsafari_upload_filesafari_paste_imagesafari_handle_dialogsafari_resizesafari_emulatesafari_reset_emulationsafari_get_cookiessafari_set_cookiesafari_delete_cookiessafari_local_storagesafari_set_local_storagesafari_delete_local_storagesafari_session_storagesafari_set_session_storagesafari_delete_session_storagesafari_export_storagesafari_import_storagesafari_clipboard_readsafari_clipboard_writesafari_networksafari_start_network_capturesafari_network_detailssafari_clear_networksafari_mock_routesafari_clear_mockssafari_start_consolesafari_get_consolesafari_clear_consolesafari_console_filtersafari_performance_metricssafari_throttle_networksafari_extract_tablessafari_extract_metasafari_extract_imagessafari_extract_linkssafari_override_geolocationsafari_list_indexed_dbssafari_get_indexed_dbsafari_css_coveragesafari_analyze_pagesafari_doctorsafari_reload_extensionsafari_run_scriptsafari_native_clicksafari_native_hoversafari_native_typesafari_native_keyboardsafari_inspect_viewportsafari_safe_area_insetssafari_check_pwasafari_webkit_compatBEFORE YOU INSTALL
What to know first
Tools you get
97 tools named in the project's documentation.
Requires
- npx on PATH
- Node.js 20+
Where it runs
All 4 documented clients run the server on your machine.
INSTALLATION
Connect your client
Server setup
npx safari-mcpMCP Clients
Claude Code
claude mcp add safari -- npx safari-mcpClaude Desktop, Cursor
{
"mcpServers": {
"safari": {
"command": "npx",
"args": [
"safari-mcp"
]
}
}
}VS Code
{
"servers": {
"safari": {
"command": "npx",
"args": [
"safari-mcp"
]
}
}
}