Safari CLI
/SKILLSafari browser automation CLI on macOS via safari-mcp. Controls a real Safari browser.
--- name: "cli-anything-safari" description: >- Safari browser automation CLI on macOS via safari-mcp. Controls real Safari (native, keeps logins) by wrapping the safari-mcp MCP server. Every one of the 84 MCP tools is exposed 1:1 with schema-accurate arguments : guaranteed parity, no manual drift. --- # cli-anything-safari A command-line interface for Safari browser automation on macOS. Wraps the [safari-mcp](https://github.com/achiya-automation/safari-mcp) Node.js MCP server in a Python Click CLI. Feature parity is guaranteed. Every Click command is generated automatically from safari-mcp's tool schema (bundled as resources/tools.json). All 84 tools are reachable with the exact argument names and types the MCP server expects. ## When to use this CLI Each CLI invocation spawns a fresh subprocess, so there is per-call overhead. If your agent speaks MCP natively (Claude Code, Cursor, Cline, etc.), using safari-mcp directly over MCP stdio will be faster. Use this CLI when: - Your agent framework does not speak MCP (Codex CLI, GitHub Copilot CLI, custom scripts, older agent frameworks). - You need to script browser automation from bash : cli-anything-safari --json tool snapshot | jq '...'. - You run in CI/CD and want cron-able, subprocess-friendly output. - You're debugging interactively from Terminal. ## Installation ### Prerequisites 1. macOS : Safari MCP is macOS-only. 2. Safari : already installed on macOS. 3. Node.js 18+ : brew install node or from https://nodejs.org/ 4. Python 3.10+ 5. Enable Apple Events for Safari: Safari → Develop → Allow JavaScript from Apple Events ### Install the CLI ``bash cd safari/agent-harness pip install -e . ` The first tool call will download the safari-mcp npm package (one-time, a few MB). ## Command Structure The CLI has 5 top-level commands: | Command | Purpose | |-----------|-------------------------------------------------------------------| | tool | Call any of safari-mcp's **84 tools** (dynamic, schema-driven) | | tools | Inspect the bundled tool registry (list, describe, count) | | raw | Escape hatch : call a tool by full name with raw JSON args | | session | In-memory session state (last URL, current tab) | | repl | Interactive REPL (default when no subcommand given) | ## Usage Examples ### Discover the tool surface `bash # Count of tools (sanity check : must match safari-mcp's registered tools) cli-anything-safari tools count # → 84 # List every tool cli-anything-safari tools list cli-anything-safari tools list --filter click # filter by substring # Full schema for one tool (JSON or human format) cli-anything-safari tools describe safari_scroll cli-anything-safari --json tools describe safari_click ` ### Call a tool (schema-driven) `bash # Navigate cli-anything-safari tool navigate --url https://example.com # Take a snapshot (preferred over screenshot : structured text with ref IDs) cli-anything-safari --json tool snapshot # Click by ref (refs come from snapshot; they expire on the next snapshot!) cli-anything-safari tool click --ref 0_5 # Click by selector or visible text cli-anything-safari tool click --selector "#submit" cli-anything-safari tool click --text "Log in" # Fill a field cli-anything-safari tool fill --selector "#email" --value "user@example.com" # Scroll by direction/amount (NOT x/y : note the schema!) cli-anything-safari tool scroll --direction down --amount 500 # Drag one element onto another cli-anything-safari tool drag \ --source-selector ".card" \ --target-selector ".trash" # Screenshot : returns base64 JPEG in stdout. Decode with: cli-anything-safari --json tool screenshot --full-page \ | python3 -c "import sys,json,base64; \ d=json.load(sys.stdin); \ open('/tmp/shot.jpg','wb').write(base64.b64decode(d['data']))" # Save as PDF (this one writes to disk directly) cli-anything-safari tool save-pdf --path /tmp/page.pdf # Evaluate JavaScript (note: parameter is --script, not --code) cli-anything-safari tool evaluate --script "document.title" ` ### Navigate and read in one round-trip `bash cli-anything-safari --json tool navigate-and-read --url https://example.com ` ### Form fill (bulk) safarifillform takes an **array** of {selector, value} objects. Pass it as a JSON string: `bash cli-anything-safari tool fill-form --fields '[ {"selector": "#email", "value": "user@example.com"}, {"selector": "#password", "value": "hunter2"} ]' ` Run cli-anything-safari tools describe safarifillform to see the exact schema, including any new fields safari-mcp adds upstream. ### Network monitoring ``bash cli-anything-safari tool start-network-capture cli-anything-safari tool navigate --url https://example.com cli-anything-safari --json tool network cli-anything-sa