Safari MCP Server
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Capabilities
Features and capabilities supported by this server
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| safari_navigateB | Navigate to a URL in Safari. Waits for page to fully load. |
| safari_go_backB | Go back in browser history |
| safari_go_forwardA | Go forward in browser history |
| safari_reloadC | Reload the current page |
| safari_read_pageA | 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_get_sourceC | Get HTML source of current page |
| safari_snapshotA | 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_navigate_and_readA | 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. |
| safari_clickA | 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_readA | 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_double_clickA | Double-click an element by CSS selector or x/y coordinates (e.g. to select a word in text) |
| safari_right_clickA | Right-click (context menu) an element by CSS selector or x/y coordinates |
| safari_native_clickA | 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_fillA | 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_clear_fieldC | Clear an input field |
| safari_select_optionA | Select an option in a native dropdown. Sets .value and dispatches change event. For custom dropdowns (React/LinkedIn), use safari_click on the dropdown trigger, then safari_click on the option instead. |
| safari_fill_formB | Fill multiple form fields at once |
| safari_press_keyB | Press a keyboard key (enter, tab, escape, arrows, etc). Supports modifiers (cmd, shift, alt, ctrl). |
| safari_type_textA | 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_replace_editorA | 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_screenshotA | 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. |
| safari_screenshot_elementB | Take a screenshot of a specific element (by CSS selector). Returns base64 PNG image. |
| safari_scrollC | Scroll the page up or down by a specified amount |
| safari_scroll_toC | Scroll to a specific position on the page |
| safari_list_tabsB | List all open tabs in Safari with their titles and URLs |
| safari_new_tabB | Open a new tab, optionally with a URL |
| safari_close_tabB | Close the current tab |
| safari_switch_tabA | Switch to a specific tab by index (use safari_list_tabs to see indices). All subsequent commands (click, fill, evaluate, screenshot, scroll) will target this tab. If commands seem to run on the wrong tab, call switch_tab again to re-anchor. |
| safari_wait_forB | Wait for an element or text to appear on the page |
| safari_wait_for_new_tabA | Wait for a new tab to appear (e.g. after OAuth login click opens popup). Automatically switches to the new tab. |
| safari_evaluateA | Execute JavaScript in the current page. 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_get_elementB | Get detailed info about an element (tag, text, rect, attributes, visibility) |
| safari_query_allB | Find all elements matching a CSS selector (returns tag, text, href, value) |
| safari_hoverB | Hover over element. Use ref, selector, or x/y |
| safari_handle_dialogB | Set up handler for the next alert/confirm/prompt dialog |
| safari_resizeC | Resize the Safari window |
| safari_dragB | Drag an element to another element or position. Use CSS selectors or x/y coordinates. |
| safari_upload_fileA | Upload a file to a 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. |
| safari_paste_imageA | 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_emulateB | Emulate a mobile device by resizing window and setting user agent. Devices: iphone-14, iphone-14-pro-max, ipad, ipad-pro, pixel-7, galaxy-s24. Or use custom width/height. |
| safari_reset_emulationA | Reset device emulation back to desktop mode |
| safari_get_cookiesB | Get cookies for the current page |
| safari_local_storageB | Get localStorage data for the current page |
| safari_networkA | 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_run_scriptA | Batch multiple Safari actions in ONE call. Steps: [{action, args}]. Actions match other safari_* tool names without prefix (e.g. 'navigate', 'click', 'fill', 'evaluate', 'readPage'). |
| safari_start_consoleA | Start capturing console messages (log, warn, error, info). Call once per page. |
| safari_get_consoleA | Get captured console messages (must call safari_start_console first) |
| safari_clear_consoleA | Clear all captured console messages |
| safari_save_pdfA | Save the current page as a PDF file. Uses screencapture + PDF rendering (no Safari UI interaction needed). |
| safari_accessibility_snapshotA | Get the accessibility tree of the page (roles, ARIA labels, focusable elements, form states). Essential for a11y auditing. |
| safari_set_cookieB | Set a cookie on the current page |
| safari_delete_cookiesA | Delete a specific cookie or all cookies for the current page |
| safari_session_storageB | Get sessionStorage data for the current page |
| safari_set_session_storageC | Set a value in sessionStorage |
| safari_set_local_storageC | Set a value in localStorage |
| safari_delete_local_storageA | Delete a localStorage key, or clear all localStorage (omit key to clear all) |
| safari_delete_session_storageA | Delete a sessionStorage key, or clear all sessionStorage (omit key to clear all) |
| safari_export_storageA | Export all storage state (cookies + localStorage + sessionStorage) as JSON — useful for saving and restoring login sessions |
| safari_import_storageA | Import storage state from JSON (as exported by safari_export_storage) — restores cookies, localStorage, sessionStorage |
| safari_clipboard_readA | Read the current clipboard content (text) |
| safari_clipboard_writeC | Write text to the system clipboard |
| safari_mock_routeA | 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_clear_mocksA | Remove all network route mocks (restore real network behavior) |
| safari_waitA | 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_start_network_captureA | 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_network_detailsA | Get captured network requests with full details (must call safari_start_network_capture first) |
| safari_clear_networkB | Clear all captured network requests |
| safari_performance_metricsB | Get detailed performance metrics: navigation timing, Web Vitals (FCP, LCP, CLS), resource breakdown, memory usage |
| safari_throttle_networkA | Simulate slow network conditions. Profiles: slow-3g, fast-3g, 4g, offline. Or custom latency/speed. Call with no args to reset. |
| safari_console_filterA | Get console messages filtered by level (must call safari_start_console first) |
| safari_extract_tablesA | Extract HTML tables as structured JSON (headers + rows). Perfect for scraping data tables. |
| safari_extract_metaA | Extract all meta tags: title, description, canonical, OG tags, Twitter cards, JSON-LD, alternate languages, RSS feeds |
| safari_extract_imagesA | Extract all images with src, alt, dimensions, loading strategy, viewport visibility |
| safari_extract_linksB | Extract all links with href, text, rel, target, external/nofollow detection |
| safari_override_geolocationC | Override the browser's geolocation API to return custom coordinates |
| safari_get_computed_styleC | Get computed CSS styles for an element. Optionally filter specific properties. |
| safari_list_indexed_dbsB | List all IndexedDB databases on the current page |
| safari_get_indexed_dbC | Read records from an IndexedDB database store |
| safari_css_coverageA | Analyze CSS coverage: find unused CSS rules across all stylesheets. Shows coverage percentage per stylesheet. |
| safari_detect_formsA | Auto-detect all forms on the page with their fields, types, selectors, and submit buttons. Great for automated form filling. |
| safari_scroll_to_elementA | Scroll to element by CSS selector OR text. For virtual DOM (Airtable) use text — scrolls down until text appears in DOM. |
| safari_click_and_waitA | Click an element AND wait for the result (page load or element). Use instead of click + wait_for separately. |
| safari_fill_and_submitA | Fill a form AND submit it in one operation. Finds submit button automatically if not specified. |
| safari_analyze_pageA | Full page analysis in ONE call: title, URL, meta tags, OG, headings, link stats, image stats, forms, and text preview. Perfect for SEO/audit. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/achiya-automation/safari-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server