Skip to content
Agentmart
Submit a tool

Safari MCP

Native Safari browser automation for AI agents — 98 tools, zero Chrome overhead.

Connector by achiya-automation · GitHub account verified by the MCP Registry

IndexedMITLocal (stdio)★ 224
Write a review

Chalk Labs

Need help deploying Safari MCP?

Chalk Labs sets up agents like this inside real teams: connected to your tools, tested on your data, with a human in the loop where it matters.

Book a call

Install

Works with Claude Code, Codex, VS Code, Cursor, Windsurf, Claude Desktop. Read the repository before you give any tool access to your data.

npx agentmarket install connector/achiya-automation-safari-mcp

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Native Safari browser automation for AI agents — 98 tools, zero Chrome overhead.

Use cases: browser-automation, web-scraping

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this server can do and what it asks for, from its tool list and install config. Checked Oct 25, 2026.

Runs code on install

Its package runs an install script (such as npm postinstall or setup.py code) as soon as you install it, before any tool is called. Read the script first.

Tools
33 read · 38 write · 9 delete · 18 not yet classified
Secrets
None asked for
Install scripts
Runs code on install
Runs as
Node.js package

Tools by what they do 98

Read from the source code; the running server may list different tools.

Read 33 · Look things up without changing anything.

  • safari_accessibility_snapshot
  • safari_analyze_page
  • safari_check_pwa
  • safari_clipboard_read
  • safari_console_filter
  • safari_css_coverage
  • safari_detect_forms
  • safari_extract_images
  • safari_extract_links
  • safari_extract_meta
  • safari_extract_tables
  • safari_get_computed_style
Show 21 more tools
  • safari_get_console
  • safari_get_cookies
  • safari_get_element
  • safari_get_indexed_db
  • safari_get_source
  • safari_inspect_viewport
  • safari_list_frames
  • safari_list_indexed_dbs
  • safari_list_tabs
  • safari_local_storage
  • safari_network_details
  • safari_performance_metrics
  • safari_query_all
  • safari_read_page
  • safari_safe_area_insets
  • safari_screenshot
  • safari_screenshot_element
  • safari_session_storage
  • safari_snapshot
  • safari_verify_state
  • safari_webkit_compat

Write 38 · Create, change, send or run things.

  • safari_click
  • safari_click_and_read
  • safari_click_and_wait
  • safari_clipboard_write
  • safari_close_tab
  • safari_double_click
  • safari_drag
  • safari_eval_file
  • safari_fill
  • safari_fill_and_submit
  • safari_fill_form
  • safari_go_forward
Show 26 more tools
  • safari_handle_dialog
  • safari_hover
  • safari_import_storage
  • safari_native_click
  • safari_native_hover
  • safari_native_type
  • safari_navigate
  • safari_navigate_and_read
  • safari_press_key
  • safari_react_select_list_options
  • safari_react_select_set
  • safari_replace_editor
  • safari_resize
  • safari_right_click
  • safari_save_pdf
  • safari_scroll
  • safari_scroll_to
  • safari_scroll_to_element
  • safari_select_option
  • safari_set_cookie
  • safari_set_local_storage
  • safari_set_session_storage
  • safari_start_console
  • safari_start_network_capture
  • safari_type_text
  • safari_upload_file

Delete 9 · Delete, drop, revoke or wipe things.

  • safari_clear_console
  • safari_clear_field
  • safari_clear_mocks
  • safari_clear_network
  • safari_delete_cookies
  • safari_delete_local_storage
  • safari_delete_session_storage
  • safari_reset_emulation
  • safari_run_script

Not yet classified 18 · We could not tell from the name and description.

  • safari_doctor
  • safari_emulate
  • safari_evaluate
  • safari_export_storage
  • safari_go_back
  • safari_mock_route
  • safari_native_keyboard
  • safari_network
  • safari_new_tab
  • safari_override_geolocation
  • safari_paste_image
  • safari_reload
Show 6 more tools
  • safari_reload_extension
  • safari_switch_tab
  • safari_throttle_network
  • safari_wait
  • safari_wait_for
  • safari_wait_for_new_tab

Files it touches

  • Any path the agent passes to its tools

Tools (98)

Read from the source code; the running server may differ. Descriptions are the server’s own words; hidden characters are shown as [U+…].

  • safari_accessibility_snapshot

    Get the accessibility tree of the page (roles, ARIA labels, focusable elements, form states). Essential for a11y auditing.

  • safari_analyze_page

    Full page analysis in ONE call: title, URL, meta tags, OG, headings, link stats, image stats, forms, and text preview. Perfect for SEO/audit.

  • safari_check_pwa

    Audit the page for iOS 'Add to Home Screen' / PWA readiness: apple-mobile-web-app-capable, apple-touch-icon (incl. 180x180), theme-color, status-bar style, web app manifest, splash screens. Returns a pass/total checklist.

  • safari_clear_console

    Clear all captured console messages

  • safari_clear_field

    Clear an input field

  • safari_clear_mocks

    Remove all network route mocks (restore real network behavior)

  • safari_clear_network

    Clear all captured network requests

  • safari_click

    Click element. Use ref (from snapshot), selector, text, or x/y. Works on React/Airtable/virtual DOM apps via full PointerEvent+MouseEvent sequence + React Fiber fallback. Pure JS — never touches user's mouse. When using ref, always take a FRESH safari_snapshot first — refs expire after each new snapshot.

  • safari_click_and_read

    Click an element then return the updated page — saves 1 full round-trip vs separate click+read_page. Handles both React Router navigation and full page loads.

  • safari_click_and_wait

    Click an element AND wait for the result (page load or element). Use instead of click + wait_for separately.

  • safari_clipboard_read

    Read the current clipboard content (text)

  • safari_clipboard_write

    Write text to the system clipboard

  • safari_close_tab

    Close the current tab. After a daemon/session restart, pass the opaque receipt returned by safari_new_tab or safari_list_tabs.

  • safari_console_filter

    Get console messages filtered by level (must call safari_start_console first)

  • safari_css_coverage

    Analyze CSS coverage: find unused CSS rules across all stylesheets. Shows coverage percentage per stylesheet.

Show 83 more tools
  • safari_delete_cookies

    Delete a specific cookie or all cookies for the current page

  • safari_delete_local_storage

    Delete a localStorage key, or clear all localStorage (omit key to clear all)

  • safari_delete_session_storage

    Delete a sessionStorage key, or clear all sessionStorage (omit key to clear all)

  • safari_detect_forms

    Auto-detect all forms on the page with their fields, types, selectors, and submit buttons. Great for automated form filling.

  • safari_doctor

    Diagnose the macOS permission + daemon chain in one shot: Safari running, Apple Events/Automation, native helper daemon, Accessibility (native clicks), Screen Recording, and the helper's codesign identity. Returns a pass/fail checklist with the exact System Settings fix per failure, then the extension bridge: which worker holds the profile lease, every worker that tried and what the profile probe answered it, and what each Safari profile's extension storage holds. Run this FIRST when clicks/screenshots/startup 'don't work even with permissions granted' or when tools answer 'profile extension u…

  • safari_double_click

    Double-click an element by CSS selector or x/y coordinates (e.g. to select a word in text)

  • safari_drag

    Drag an element to another element or position. Use CSS selectors or x/y coordinates.

  • safari_emulate

    Description is built at runtime.

  • safari_eval_file

    Execute JavaScript read from a FILE path (avoids passing huge scripts inline / manual copy). Same engine as safari_evaluate: extension-first (no focus steal), AppleScript fallback. Use to upload binary via a generated .js containing base64.

  • safari_evaluate

    Execute JavaScript in the current page (a returned Promise is awaited — fetch/timers work in background tabs; requestAnimationFrame never fires there). Automatically falls back to AppleScript when CSP blocks execution (e.g. Google Search Console, LinkedIn). For reading data, prefer safari_read_page or safari_snapshot. For interactions, prefer safari_click/fill with refs.

  • safari_export_storage

    Export all storage state (cookies + localStorage + sessionStorage) as JSON — useful for saving and restoring login sessions

  • safari_extract_images

    Extract all images with src, alt, dimensions, loading strategy, viewport visibility

  • safari_extract_links

    Extract all links with href, text, rel, target, external/nofollow detection

  • safari_extract_meta

    Extract all meta tags: title, description, canonical, OG tags, Twitter cards, JSON-LD, alternate languages, RSS feeds

  • safari_extract_tables

    Extract HTML tables as structured JSON (headers + rows). Perfect for scraping data tables.

  • safari_fill

    Fill/replace value in an input, textarea, select, OR contenteditable (rich text). Handles React controlled inputs, ProseMirror, Draft.js, and Google Closure editors automatically. Use for SETTING a value (replaces existing). For code editors (Monaco/CodeMirror/Ace), use safari_replace_editor instead. For character-by-character typing in search boxes, use safari_type_text. IMPORTANT: When using ref, always take a FRESH safari_snapshot first — refs expire after each new snapshot (prefix changes: 5_xx → 6_xx).

  • safari_fill_and_submit

    Fill a form AND submit it in one operation. Finds submit button automatically if not specified.

  • safari_fill_form

    Fill multiple form fields at once

  • safari_get_computed_style

    Get computed CSS styles for an element. Optionally filter specific properties.

  • safari_get_console

    Get captured console messages (must call safari_start_console first)

  • safari_get_cookies

    Get cookies for the current page

  • safari_get_element

    Get detailed info about an element (tag, text, rect, attributes, visibility)

  • safari_get_indexed_db

    Read records from an IndexedDB database store

  • safari_get_source

    Get HTML source of current page

  • safari_go_back

    Go back in browser history

  • safari_go_forward

    Go forward in browser history

  • safari_handle_dialog

    Set up handler for the next alert/confirm/prompt dialog

  • safari_hover

    Hover over element. Use ref, selector, or x/y

  • safari_import_storage

    Import storage state from JSON (as exported by safari_export_storage) — restores cookies, localStorage, sessionStorage

  • safari_inspect_viewport

    Validate the page's <meta name=viewport> against iOS Safari best practices: width=device-width, initial-scale, disabled-zoom (WCAG 1.4.4), viewport-fit=cover. Returns parsed attributes + severity-tagged issues (error/warning/info).

  • safari_list_frames

    List every document in the tab — the main page plus each iframe — with its frameId, URL and text length. Use when a page's content lives in a cross-origin iframe (an embedded app, a micro-frontend shell, a payment field): safari_read_page and safari_evaluate see only the main document there and come back empty or with a loader. Pass the frameId or a URL substring as safari_evaluate's `frame` to run inside it.

  • safari_list_indexed_dbs

    List all IndexedDB databases on the current page

  • safari_list_tabs

    List every tab in this session's Safari window (titles + URLs, including the user's own tabs — verbose and rarely needed). Tabs this session owns carry a receipt. Prefer keeping the receipt from safari_new_tab over listing.

  • safari_local_storage

    Get localStorage data for the current page

  • safari_mock_route

    Intercept network requests matching a URL pattern and return a mock response. Works with both fetch and XHR. Useful for testing API error states, offline behavior, or replacing API responses.

  • safari_native_click

    OS-level mouse click via macOS CGEvent — produces isTrusted: true events that pass WAF/bot detection (G2, Cloudflare, etc.). Use when regular safari_click fails with 405/403 errors or form submissions are blocked. Trade-off: physically moves the mouse cursor and requires Safari window to be visible. Use ref (from snapshot), selector, text, or x/y. When using ref, always take a FRESH safari_snapshot first.

  • safari_native_hover

    OS-level mouse hover via macOS CGEvent — moves the real cursor to an element to trigger native :hover / mouseenter handlers. Use for obfuscated UIs where JS-dispatched mouseenter isn't enough, like Discord server sidebars (tooltips only appear on real hover) or portal-rendered tooltips. After hover, call safari_wait_for or safari_evaluate to read the tooltip. Dwells for dwellMs to let tooltips render, then restores the original cursor position by default. Requires Safari window to be visible.

  • safari_native_keyboard

    OS-level keyboard event via macOS CGEvent — sends a real keypress (with optional modifiers) to the Safari window WITHOUT activating Safari or stealing focus. Use when safari_press_key's JS path doesn't reach React trust-gated handlers (Discord ProseMirror Enter, Slack send, virtualized editors). Keys: enter, return, tab, escape, space, delete, backspace, up/down/left/right, home, end, pageup, pagedown, f1-f6, a-z, 0-9 and common punctuation. Modifiers: cmd, shift, alt, ctrl. Produces isTrusted:true events. Never activates Safari — runs entirely in the background.

  • safari_native_type

    Insert text into ANY editor via OS-level clipboard paste (CGEvent Cmd+V targeted to Safari window). Unlike safari_fill which manipulates DOM directly (breaking React/ProseMirror state), this goes through the real paste pipeline — ProseMirror/Slate/Draft.js process the paste event natively and update their internal model. After native_type, pressing Enter (via safari_native_keyboard) will actually submit the form because the framework state matches the DOM. Saves and restores the user's clipboard. No focus stealing. Use for Discord, Slack, and any editor where safari_fill works visually but the…

  • safari_navigate

    Navigate this session's tab to a URL (pass `receipt` to pin the tab). Waits for the page to load. Returns {title, url} — plus a fresh `receipt` when the origin changed; use that one from then on.

  • safari_navigate_and_read

    Navigate to a URL and return the page content in one step — saves 1 full round-trip vs navigate+read_page. Use instead of safari_navigate + safari_read_page. Like safari_navigate, returns a fresh `receipt` when the origin changed; use that one from then on.

  • safari_network

    Quick network overview via Performance API (no setup needed). Shows URLs and timing for resources loaded by the page. For detailed request/response info (headers, status codes, POST bodies), use safari_start_network_capture + safari_network_details instead.

  • safari_network_details

    Get captured network requests with full details (must call safari_start_network_capture first)

  • safari_new_tab

    Open a new background tab (never steals focus), optionally with a URL. Returns {tabIndex, safeUrl, receipt}. KEEP THE RECEIPT and pass it as `receipt` to every later call on this tab — it survives MCP reconnects, daemon restarts, parallel sessions and subagents, and makes safari_list_tabs / safari_switch_tab unnecessary.

  • safari_override_geolocation

    Override the browser's geolocation API to return custom coordinates

  • safari_paste_image

    Paste an image from a local file into the focused element via JS DataTransfer (no clipboard, no focus steal). Works on Medium, dev.to, HackerNoon, TOI, etc.

  • safari_performance_metrics

    Get detailed performance metrics: navigation timing, Web Vitals (FCP, LCP, CLS), resource breakdown, memory usage

  • safari_press_key

    Press a keyboard key (enter, tab, escape, arrows, etc). Supports modifiers (cmd, shift, alt, ctrl).

  • safari_query_all

    Find all elements matching a CSS selector (returns tag, text, href, value). x/y are relative to each element's own frame viewport — for matches inside an iframe, click by selector or snapshot ref, not by these coordinates

  • safari_react_select_list_options

    List available options of a react-select v5 dropdown without opening the menu. Returns JSON {ok, total, options:[{label,value}…]}. Useful when safari_react_select_set returns 'option not found' and you need to see exact labels (e.g. 'Email Routing Rules' vs 'Email Routing'). Either ref or selector required.

  • safari_react_select_set

    Set a value in a react-select v5 dropdown by walking React fiber to find the Select component and invoking onChange directly — bypasses the menu UI entirely. Use when safari_click on the chevron or option keeps failing (Cloudflare custom token forms after a few rows, portal-rendered selects that intercept synthetic events). Returns JSON {ok, selected} on success, or {ok:false, error, available:[…]} listing up to 30 option labels on miss. Match is by label, value, or case-insensitive label. Either ref or selector required. NOTE: For Permissions-levels combos that are disabled until a Permission…

  • safari_read_page

    Read page text content (title, URL, body text). Use for reading article text or page content. For interacting with elements, prefer safari_snapshot (gives ref IDs). Use selector to read specific element. Use maxLength to limit output.

  • safari_reload

    Reload the current page

  • safari_reload_extension

    Hot-reload the Safari MCP Bridge extension — forces it to reload its own code from disk without requiring manual Safari Preferences → Extensions → toggle. Use after editing extension/background.js or extension/content.js in the safari-mcp repo. The extension briefly disconnects during reload and auto-reconnects within ~2 seconds. NOTE: this tool itself requires the extension version already installed to support the `reload_extension` command (added in v2.9.1+). If your extension is older, trigger a manual reload once to pick up this feature.

  • safari_replace_editor

    Replace ALL content in a code editor (Monaco, CodeMirror, Ace, ProseMirror). Use ONLY for code editors — Airtable automations, GitHub gists, CodePen, n8n code nodes, etc. NOT for rich text editors like Medium/LinkedIn (use safari_fill for those). Detects ProseMirror/Draft.js/CodeMirror/Monaco/Ace and uses their native API.

  • safari_reset_emulation

    Reset device emulation: restores the window size from before safari_emulate and removes its navigator overrides (no reload)

  • safari_resize

    Resize the Safari window

  • safari_right_click

    Right-click (context menu) an element by CSS selector or x/y coordinates

  • safari_run_script

    Batch Safari actions in one MCP session. Named profiles use the verified extension and support: newTab, switchTab, getReceipt, listTabs, closeTab, navigate, navigateAndRead, readPage, snapshot, getElementInfo, querySelectorAll, waitFor, waitForTime, click, clickAndOpenPopup, fill, fillForm, clearField, typeText, selectOption, pressKey, scroll, scrollTo, scrollToElement, hover, evaluate, reload, goBack, goForward. switchTab accepts an index or an opaque receipt; a valid receipt recovers the exact owned tab across Safari windows without focusing one. clickAndOpenPopup takes exactly one selector …

  • safari_safe_area_insets

    Read the live CSS safe-area-inset values (top/right/bottom/left) as the page sees them, whether viewport-fit=cover is set, and whether env(safe-area-inset-*) is used in any stylesheet. For notch / Dynamic Island layout debugging.

  • safari_save_pdf

    Save the current page as a PDF file. Uses screencapture + PDF rendering (no Safari UI interaction needed).

  • safari_screenshot

    Take a visual screenshot (base64 JPEG). EXPENSIVE — use safari_snapshot instead for most tasks. Only use screenshot when you need to verify visual layout, styling, images, or colors that snapshot can't show. Pass maxWidth (e.g. 1024) for layout checks — far fewer tokens.

  • safari_screenshot_element

    Take a screenshot of a specific element (by CSS selector). Returns a base64 image.

  • safari_scroll

    Scroll the page up or down by a specified amount

  • safari_scroll_to

    Scroll to a specific position on the page

  • safari_scroll_to_element

    Scroll to element by CSS selector OR text. For virtual DOM (Airtable) use text — scrolls down until text appears in DOM.

  • safari_select_option

    Select an option in a native <select> dropdown. Sets .value and dispatches change event. Pass `ref` (from safari_snapshot) for a select inside an iframe or shadow DOM — a plain `selector` only reaches the top document. For custom dropdowns (React/LinkedIn), use safari_click on the dropdown trigger, then safari_click on the option instead.

  • safari_session_storage

    Get sessionStorage data for the current page

  • safari_set_cookie

    Set a cookie on the current page

  • safari_set_local_storage

    Set a value in localStorage

  • safari_set_session_storage

    Set a value in sessionStorage

  • safari_snapshot

    PREFERRED way to see page state. Returns accessibility tree with ref IDs for every interactive element. Use refs with click/fill/type instead of CSS selectors. Workflow: snapshot → see refs → click({ref:'0_5'}). PREFER THIS over safari_screenshot (cheaper, structured text vs heavy image) and over safari_read_page (includes interactive refs). Use safari_screenshot only when you need to see visual layout/styling.

  • safari_start_console

    Start capturing console messages (log, warn, error, info). Call once per page.

  • safari_start_network_capture

    Start capturing detailed network requests (fetch + XHR) with headers, status, timing. Call once per page. Intercepts fetch/XHR — captures requests AFTER this call only. For quick overview of already-loaded resources, use safari_network instead.

  • safari_switch_tab

    Switch the MCP session's logical target without focusing Safari. Pass an index for the current session window, or an opaque receipt to recover the exact owned tab across Safari windows; a valid receipt takes precedence over any supplied index. Rarely needed: passing `receipt` on each tool call already targets that tab.

  • safari_throttle_network

    Simulate slow network conditions. Profiles: slow-3g, fast-3g, 4g, offline. Or custom latency/speed. Call with no args to reset.

  • safari_type_text

    Type text character-by-character with realistic key events. Best for: search boxes (triggers autocomplete), chat inputs, and fields that react to each keystroke. For rich text editors (Medium, HackerNoon, LinkedIn), use safari_fill instead — it uses framework-native APIs. For code editors (Monaco/CodeMirror), use safari_replace_editor. When using ref, always take a FRESH safari_snapshot first — refs expire after each new snapshot.

  • safari_upload_file

    Upload a file to a <input type='file'> element via JavaScript DataTransfer — NO file dialog, NO UI interaction. IMPORTANT: Do NOT click the file input before calling this tool — just provide the selector and file path. If a file dialog is already open, this tool will close it first. NOTE: 'verified 0 files' may appear even on success if the site uses a custom upload handler — check visually with safari_snapshot. For an IMAGE going into a composer/editor that should show a thumbnail, pass verifyPreview:true — some sites (Google Business Profile) accept the file handle and flip their UI to 'atta…

  • safari_verify_state

    Verify the framework-level state of an editor/input matches the expected value. Returns JSON {match, mode, actual, expected, hint?}. Modern editors (ProseMirror, Lexical, Closure, React-controlled inputs) maintain state separately from the DOM — `.value` or `.textContent` may show new text while the internal store still holds old data, so a Submit click sends stale data. Call this AFTER safari_fill and BEFORE clicking Submit on critical forms (Featured.com, LinkedIn share, Medium, Reddit).

  • safari_wait

    Wait for a fixed time in milliseconds. Use only when you need a brief pause between actions. PREFER safari_wait_for (waits for element/text to appear) — it's smarter and doesn't waste time.

  • safari_wait_for

    Wait for an element or text to appear on the page

  • safari_wait_for_new_tab

    Wait for a new tab to appear (e.g. after OAuth login click opens popup). Automatically switches to the new tab.

  • safari_webkit_compat

    Check every CSS property used on the page against THIS Safari via CSS.supports() — reports unsupported properties, properties that need a -webkit- prefix, and known Safari rendering quirks (e.g. position:sticky inside overflow ancestors). Tested in the live engine, so no false positives.

Compare and alternatives

    Featured in

    Signals

    Stars
    224
    Forks
    33
    Open issues
    10
    Last commit
    Oct 19, 2026 (12 days ago)
    Last release
    Oct 26, 2026 (5 days ago)

    From GitHub (fetched Oct 24, 2026).

    Details

    Registry name
    io.github.achiya-automation/safari-mcp
    Version
    2.22.19
    Auth
    No auth
    Packages
    npm safari-mcp
    License
    MIT
    First seen
    Oct 24, 2026
    Last checked
    Oct 26, 2026

    Done for you

    Rather not set it up yourself?

    Chalk Labs scopes, builds and runs agents for your team: the task audit, the eval harness, the integrations and the weekly ops report. Fixed scope, priced before we start.

    See how we build AI agents →Read the case studies

    Chalk Labs is a two-founder AI and growth studio. We build AI agents, CRMs and MVPs for Web3 and AI companies, and have shipped 50+ product and token launches.

    launches shipped
    50+
    launches shipped
    media placements
    500+
    media placements
    founders on every account
    2
    founders on every account

    Press we've placed: Forbes · CoinDesk · Decrypt · Cointelegraph · The Block

    Rahil Jain, Co-founder, Chalk Labs. Ex-Goldman Sachs engineer. You talk to the person who builds it.

    Get Safari MCP running in your business

    Tell us what you want to automate. A founder replies within one working day with a plan, not a pitch deck.

    Goes to the Chalk Labs founders, not the newsletter. Privacy

    Need help deploying Safari MCP?

    CallGet help
    Cite this page

    Safari MCP. Agent Mart. https://agentmart.dev/connectors/achiya-automation-safari-mcp (last updated 2026-10-26)