# Safari Mcp

> Native Safari browser automation for AI agents. 80 tools via AppleScript — zero overhead, keeps logins, runs silently in background. Drop-in alternative to Chrome DevTools MCP with 40-60% less CPU/heat on Apple Silicon.

- **Type:** MCP server
- **Install:** `agentstack add mcp-achiya-automation-safari-mcp`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [achiya-automation](https://agentstack.voostack.com/s/achiya-automation)
- **Installs:** 0
- **Category:** [AI & ML](https://agentstack.voostack.com/c/ai-and-ml)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [achiya-automation](https://github.com/achiya-automation)
- **Source:** https://github.com/achiya-automation/safari-mcp
- **Website:** https://achiya-automation.com

## Install

```sh
agentstack add mcp-achiya-automation-safari-mcp
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# 🦁 Safari MCP

**The browser for your coding agent.**

*Your real Safari, logged in — no Chrome, no heat, no headless.*

[](https://www.npmjs.com/package/safari-mcp)
[](https://www.npmjs.com/package/safari-mcp)
[](https://opensource.org/licenses/MIT)
[](https://www.apple.com/macos/)

[](https://glama.ai/mcp/servers/@achiya-automation/safari-mcp)
[](https://registry.modelcontextprotocol.io/v0/servers?search=achiya-automation)
[](https://smithery.ai/server/@achiya-automation/safari-mcp)
[](https://mcpscoreboard.com/server/05977769-8762-4e89-aff3-a0c5776843bb/)

**96 tools** · **No Chrome/Puppeteer/Playwright needed** · **~5ms per command** · **60% less CPU than Chrome**

[Quick Start](#quick-start) · [All 96 Tools](#tools-96) · [Examples](examples/) · [Why Safari MCP?](#safari-mcp-vs-alternatives) · [Architecture](#architecture) · [Changelog](CHANGELOG.md)

## ❌ Without Safari MCP

Your AI agent needs to browse. So it either:

- **Spins up Chromium via Playwright** — with no logins, no cookies, no sessions
- **Uses Chrome DevTools MCP** — and melts your fan running a second browser
- **Relies on headless scrapers** — blocked by Cloudflare, reCAPTCHA, and bot detection

## ✅ With Safari MCP

Your AI drives the **Safari you're already logged into** — Gmail, GitHub, Ahrefs, Slack, banking.

Native WebKit. ~60% less CPU. Background operation. 96 tools. One `npx` command. macOS only.

> 📰 **Featured on freeCodeCamp:** [How to Connect Your AI Coding Agent to a Browser on macOS](https://www.freecodecamp.org/news/how-to-connect-your-ai-coding-agent-to-a-browser-on-macos/) · [HackerNoon: Reverse-Engineering React, Shadow DOM, and CSP](https://hackernoon.com/i-had-to-reverse-engineer-react-shadow-dom-and-csp-to-automate-safari-without-chrome)

---

## Highlights

- **96 tools** — navigation, clicks, forms, screenshots, network, storage, accessibility, and more
- **Zero heat** — native WebKit on Apple Silicon, ~60% less CPU than Chrome
- **Your real browser** — keeps all logins, cookies, sessions (Gmail, GitHub, Ahrefs, etc.)
- **Background operation** — Safari stays in the background, no window stealing
- **No browser dependencies** — no Puppeteer, no Playwright, no WebDriver, no Chrome
- **Persistent process** — reuses a single osascript process (~5ms per command vs ~80ms)
- **Framework-compatible** — React, Vue, Angular, Svelte form filling via native setters

---

## Quick Start

### Prerequisites

- macOS (any version with Safari)
- Node.js 18+
- Safari → Settings → Advanced → **Show features for web developers** ✓
- Safari → Develop → **Allow JavaScript from Apple Events** ✓

### Install (one command)

```bash
npx safari-mcp
```

That's it — no global install needed. Or install permanently:

```bash
npm install -g safari-mcp
```

### Configure your MCP client

All clients run Safari MCP the same way — `npx safari-mcp`. Pick your editor:

Claude Code

```bash
claude mcp add safari -- npx safari-mcp
```

Or edit `~/.mcp.json`:

```json
{
  "mcpServers": {
    "safari": {
      "command": "npx",
      "args": ["safari-mcp"]
    }
  }
}
```

Claude Desktop

Edit `~/Library/Application Support/Claude/claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "safari": {
      "command": "npx",
      "args": ["safari-mcp"]
    }
  }
}
```

Restart Claude Desktop after saving.

Cursor

One-click: [**Install in Cursor**](cursor://anysphere.cursor-deeplink/mcp/install?name=safari-mcp&config=%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22safari-mcp%22%5D%7D)

Or edit `.cursor/mcp.json` in your project:

```json
{
  "mcpServers": {
    "safari": {
      "command": "npx",
      "args": ["safari-mcp"]
    }
  }
}
```

VS Code / VS Code Insiders

One-click: [**Install in VS Code**](vscode:mcp/install?%7B%22safari-mcp%22%3A%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22safari-mcp%22%5D%7D%7D)

Or edit `.vscode/mcp.json`:

```json
{
  "servers": {
    "safari": {
      "type": "stdio",
      "command": "npx",
      "args": ["safari-mcp"]
    }
  }
}
```

Windsurf

Edit `.windsurf/mcp.json` in your project (or `~/.codeium/windsurf/mcp_config.json` globally):

```json
{
  "mcpServers": {
    "safari": {
      "command": "npx",
      "args": ["safari-mcp"]
    }
  }
}
```

Cline

Open Cline in VS Code → click the MCP icon → **Edit MCP Settings** → add:

```json
{
  "mcpServers": {
    "safari": {
      "command": "npx",
      "args": ["safari-mcp"]
    }
  }
}
```

Continue

Edit `~/.continue/config.yaml` (or `.continue/config.yaml` in workspace):

```yaml
mcpServers:
  - name: safari
    command: npx
    args:
      - safari-mcp
```

Goose

Edit `~/.config/goose/config.yaml`:

```yaml
extensions:
  safari:
    name: safari
    type: stdio
    cmd: npx
    args:
      - safari-mcp
    enabled: true
```

LM Studio

Open LM Studio → **Settings** → **MCP Servers** → **Add Server**:

- **Name:** `safari`
- **Command:** `npx`
- **Args:** `safari-mcp`

Zed

Open Zed → **Settings** → search for "Context Servers" and add:

```json
{
  "context_servers": {
    "safari": {
      "command": {
        "path": "npx",
        "args": ["safari-mcp"]
      }
    }
  }
}
```

Alternative: Homebrew

```bash
brew install achiya-automation/tap/safari-mcp
```

Alternative: from source

```bash
git clone https://github.com/achiya-automation/safari-mcp.git
cd safari-mcp && npm install
```

---

## Usage Workflow

The recommended pattern for AI agents using Safari MCP:

```
1. safari_snapshot        → Get page state (accessibility tree)
2. safari_click/fill/...  → Interact with elements by ref
3. safari_snapshot        → Verify the result
```

**Element targeting** — tools accept multiple targeting strategies:

| Strategy | Example | Best for |
|----------|---------|----------|
| CSS selector | `#login-btn`, `.submit` | Unique elements |
| Visible text | `"Sign In"`, `"Submit"` | Buttons, links |
| Coordinates | `x: 100, y: 200` | Canvas, custom widgets |
| Ref from snapshot | `ref: "e42"` | Any element from accessibility tree |

> **Tip:** Start with `safari_snapshot` to get element refs, then use refs for precise targeting. This is faster and more reliable than CSS selectors.

---

## Tools (96)

Click to expand the full tool list — organized by category

### Navigation (4)
| Tool | Description |
|------|-------------|
| `safari_navigate` | Navigate to URL (auto HTTPS, wait for load) |
| `safari_go_back` | Go back in history |
| `safari_go_forward` | Go forward in history |
| `safari_reload` | Reload page (optional hard reload) |

### Page Reading (3)
| Tool | Description |
|------|-------------|
| `safari_read_page` | Get title, URL, and text content |
| `safari_get_source` | Get full HTML source |
| `safari_navigate_and_read` | Navigate + read in one call |

### Click & Interaction (6)
| Tool | Description |
|------|-------------|
| `safari_click` | Click by CSS selector, visible text, or coordinates |
| `safari_double_click` | Double-click (select word, etc.) |
| `safari_right_click` | Right-click (context menu) |
| `safari_hover` | Hover over element |
| `safari_click_and_wait` | Click + wait for navigation |
| `safari_click_and_read` | Click then return the updated page — saves a round-trip (React Router + full loads) |

### Form Input (11)
| Tool | Description |
|------|-------------|
| `safari_fill` | Fill input (React/Vue/Angular compatible) |
| `safari_clear_field` | Clear input field |
| `safari_select_option` | Select dropdown option |
| `safari_fill_form` | Batch fill multiple fields |
| `safari_fill_and_submit` | Fill form + submit in one call |
| `safari_type_text` | Type real keystrokes (JS-based, no System Events) |
| `safari_press_key` | Press key with modifiers |
| `safari_react_select_set` | Set a react-select v5 value via React fiber — bypasses the menu UI |
| `safari_react_select_list_options` | List a react-select v5 dropdown's options without opening it |
| `safari_replace_editor` | Replace all content in a code editor (Monaco, CodeMirror, Ace, ProseMirror) |
| `safari_verify_state` | Verify an editor's framework-level state matches expected — catch stale DOM before Submit |

### Screenshots & PDF (3)
| Tool | Description |
|------|-------------|
| `safari_screenshot` | Screenshot as PNG (viewport or full page) |
| `safari_screenshot_element` | Screenshot a specific element |
| `safari_save_pdf` | Export page as PDF |

### Scroll (3)
| Tool | Description |
|------|-------------|
| `safari_scroll` | Scroll up/down by pixels |
| `safari_scroll_to` | Scroll to exact position |
| `safari_scroll_to_element` | Smooth scroll to element |

### Tab Management (5)
| Tool | Description |
|------|-------------|
| `safari_list_tabs` | List all tabs (index, title, URL) |
| `safari_new_tab` | Open new tab (background, no focus steal) |
| `safari_close_tab` | Close tab |
| `safari_switch_tab` | Switch to tab by index |
| `safari_wait_for_new_tab` | Wait for a new tab (e.g. OAuth popup) and auto-switch to it |

### Wait (2)
| Tool | Description |
|------|-------------|
| `safari_wait_for` | Wait for element, text, or URL change |
| `safari_wait` | Wait for specified milliseconds |

### JavaScript (1)
| Tool | Description |
|------|-------------|
| `safari_evaluate` | Execute arbitrary JavaScript, return result |

### Element Inspection (4)
| Tool | Description |
|------|-------------|
| `safari_get_element` | Element details (tag, rect, attrs, visibility) |
| `safari_query_all` | Find all matching elements |
| `safari_get_computed_style` | Computed CSS styles |
| `safari_detect_forms` | Auto-detect all forms with field selectors |

### Accessibility (2)
| Tool | Description |
|------|-------------|
| `safari_accessibility_snapshot` | Full a11y tree: roles, ARIA, focusable elements |
| `safari_snapshot` | Accessibility tree with ref IDs for every interactive element — preferred way to see page state |

### Drag & Drop (1)
| Tool | Description |
|------|-------------|
| `safari_drag` | Drag between elements or coordinates |

### File Operations (2)
| Tool | Description |
|------|-------------|
| `safari_upload_file` | Upload file via JS DataTransfer (no file dialog!) |
| `safari_paste_image` | Paste image into editor (no clipboard touch!) |

### Dialog & Window (2)
| Tool | Description |
|------|-------------|
| `safari_handle_dialog` | Handle alert/confirm/prompt |
| `safari_resize` | Resize browser window |

### Device Emulation (2)
| Tool | Description |
|------|-------------|
| `safari_emulate` | Emulate device (iPhone, iPad, Pixel, Galaxy) |
| `safari_reset_emulation` | Reset to desktop |

### Cookies & Storage (11)
| Tool | Description |
|------|-------------|
| `safari_get_cookies` | Get all cookies |
| `safari_set_cookie` | Set cookie with all options |
| `safari_delete_cookies` | Delete one or all cookies |
| `safari_local_storage` | Read localStorage |
| `safari_set_local_storage` | Write localStorage |
| `safari_delete_local_storage` | Delete/clear localStorage |
| `safari_session_storage` | Read sessionStorage |
| `safari_set_session_storage` | Write sessionStorage |
| `safari_delete_session_storage` | Delete/clear sessionStorage |
| `safari_export_storage` | Export all storage as JSON (backup/restore sessions) |
| `safari_import_storage` | Import storage state from JSON |

### Clipboard (2)
| Tool | Description |
|------|-------------|
| `safari_clipboard_read` | Read clipboard text |
| `safari_clipboard_write` | Write text to clipboard |

### Network (6)
| Tool | Description |
|------|-------------|
| `safari_network` | Quick network requests via Performance API |
| `safari_start_network_capture` | Start detailed capture (fetch + XHR) |
| `safari_network_details` | Get captured requests with headers/timing |
| `safari_clear_network` | Clear captured requests |
| `safari_mock_route` | Mock network responses (intercept fetch/XHR) |
| `safari_clear_mocks` | Remove all network mocks |

### Console (4)
| Tool | Description |
|------|-------------|
| `safari_start_console` | Start capturing console messages |
| `safari_get_console` | Get all captured messages |
| `safari_clear_console` | Clear captured messages |
| `safari_console_filter` | Filter by level (log/warn/error) |

### Performance (2)
| Tool | Description |
|------|-------------|
| `safari_performance_metrics` | Navigation timing, Web Vitals, memory |
| `safari_throttle_network` | Simulate slow-3g/fast-3g/4g/offline |

### Data Extraction (4)
| Tool | Description |
|------|-------------|
| `safari_extract_tables` | Tables as structured JSON |
| `safari_extract_meta` | All meta: OG, Twitter, JSON-LD, canonical |
| `safari_extract_images` | Images with dimensions and loading info |
| `safari_extract_links` | Links with rel, external/nofollow detection |

### Advanced (7)
| Tool | Description |
|------|-------------|
| `safari_override_geolocation` | Override browser geolocation |
| `safari_list_indexed_dbs` | List IndexedDB databases |
| `safari_get_indexed_db` | Read IndexedDB records |
| `safari_css_coverage` | Find unused CSS rules |
| `safari_analyze_page` | Full page analysis in one call |
| `safari_doctor` | Diagnose the macOS permission + daemon chain (Apple Events, Accessibility, Screen Recording, codesign) with per-failure fixes |
| `safari_reload_extension` | Hot-reload the Safari MCP Bridge extension without a manual toggle |

### Automation (1)
| Tool | Description |
|------|-------------|
| `safari_run_script` | Run multiple actions in a single call (batch) |

### Native Input — CGEvent (4)
| Tool | Description |
|------|-------------|
| `safari_native_click` | OS-level mouse click (CGEvent, `isTrusted: true`) — bypasses WAF/bot detection when `safari_click` is blocked (405/403) |
| `safari_native_hover` | OS-level cursor hover — triggers real `:hover`/`mouseenter` for tooltips and obfuscated UIs |
| `safari_native_type` | Insert text via the real paste pipeline — ProseMirror/Slate/Draft.js process it natively so Submit sends real data |
| `safari_native_keyboard` | OS-level keypress + modifiers to Safari, no focus steal — reaches React trust-gated handlers (Discord/Slack send) |

### iOS & WebKit Validation (4)
| Tool | Description |
|------|-------------|
| `safari_inspect_viewport` | Validate the `` tag for iOS Safari (device-width, zoom/WCAG, viewport-fit) |
| `safari_safe_area_insets` | Read live safe-area-inset values + viewport-fit / `env()` usage (notch / Dynamic Island) |
| `safari_check_pwa` | Audit iOS "Add to Home Screen" / PWA readiness (apple-touch-icon, manifest, theme-color, splash) |
| `safari_webkit_compat` | Check page CSS against this Safari via `CSS.supports()` — unsupported props, missing `-webkit-` prefixes, known quirks |

---

## Security

Safari MCP runs locally on your Mac with minimal attack surface:

| Aspect | Detail |
|--------|--------|
| Network | **No remote connections** — all communication is local (stdio + localhost) |
| Permissions | macOS system permissions required (Screen Recording for screenshots) |
| Data | No telemetry, no analytics, no data sent anywhere |
| Extension | Communicates only with `localhost:9224`, validated by Safari |
| Code | Fully open source (MIT) — audit every line |

---

## Safari MCP vs Alternatives

| Feature | Safari MCP | Chrome DevTools MCP | Playwright MCP |
|---------|:----------:|:-------------------:|:--------------:|
| CPU/Heat | 🟢 Minimal | 🔴 High | 🟡 Medium |
| Your logins | ✅ Yes | ✅ Yes | ❌ No |
| macOS native | ✅ WebKit | ❌ Chromium | ❌ Chromium/WebKit |
| Browser dependencies | None | Chrome + debug port | Playwright runtime |
| Tools | 96 | ~30 | ~25 |
| File upload | JS (no dialog) | CDP | Playwright API |
| Image paste | JS (no clipboard) | CDP | Playwright API |
| Focus steal | ❌ Background | ❌ Background | ❌ Headless |
| Network mocking | ✅ | ❌ | ✅ |
| Lighthouse | ❌ | ✅ | ❌ |
| Performance trace | ❌ | ✅ | ❌ |

> **Tip:** Use Safari MCP for daily browsing tasks (95% of work) and Chrome DevTools MCP only for Lighthouse/Performance audits.

### Why Safari MC

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [achiya-automation](https://github.com/achiya-automation)
- **Source:** [achiya-automation/safari-mcp](https://github.com/achiya-automation/safari-mcp)
- **License:** MIT
- **Homepage:** https://achiya-automation.com

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-achiya-automation-safari-mcp
- Seller: https://agentstack.voostack.com/s/achiya-automation
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
