- Skill ID
- hkuds/cli-anything/cli-anything-safari
- Publisher
- hkuds
- Repository
- cli-anything
- Installs
- 0
- Files
- 1
- Synced
- Sep 23, 2026
Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.
hkuds/cli-anything/cli-anything-safariInstalls these files- SKILL.md
What this skill tells the agent
cli-anything-safari
A command-line interface for Safari browser automation on macOS. Wraps the `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
- macOS — Safari MCP is macOS-only.
- Safari — already installed on macOS.
- Node.js 18+ —
brew install nodeor from https://nodejs.org/ - Python 3.10+
- Enable Apple Events for Safari: Safari → Develop → Allow JavaScript from Apple Events
Install the CLI
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
# 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_clickCall a tool (schema-driven)
# 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
cli-anything-safari --json tool navigate-and-read --url https://example.comForm fill (bulk)
safari_fill_form takes an array of {selector, value} objects. Pass it as a JSON string:
cli-anything-safari tool fill-form --fields '[
{"selector": "#email", "value": "user@example.com"},
{"selector": "#password", "value": "hunter2"}
]'Run cli-anything-safari tools describe safari_fill_form to see the exact schema, including any new fields safari-mcp adds upstream.
Network monitoring
cli-anything-safari tool start-network-capture
cli-anything-safari tool navigate --url https://example.com
cli-anything-safari --json tool network
cli-anything-safari tool performance-metricsStorage
cli-anything-safari tool get-cookies
cli-anything-safari tool set-cookie --name session --value abc123 --domain example.com
cli-anything-safari tool local-storage --key theme
# export-storage returns JSON to stdout — no --path arg. Pipe to a file:
cli-anything-safari --json tool export-storage > /tmp/storage.jsonRaw JSON escape hatch
When you need to pass a complex nested object or want to drive the CLI from a pre-built JSON blob:
cli-anything-safari raw safari_evaluate \
--json-args '{"code":"[...document.querySelectorAll(\"a\")].map(a => a.href)"}'Interactive REPL
cli-anything-safariThe REPL banner prints the absolute path to this SKILL.md so agents can self-discover capabilities.
JSON Output
All commands support --json as a global flag:
cli-anything-safari --json tool snapshot
cli-anything-safari --json tool list-tabs
cli-anything-safari --json tools listState Management
The CLI maintains a small amount of in-memory state for REPL display only:
- `last_url` — last URL the CLI navigated to (updated after every successful
tool navigate,tool navigate-and-read, ortool new-tab) - `current_tab_index` — last known active tab index
There is no persistent session, no undo/redo, no document model. Every CLI invocation starts with fresh state. Safari MCP itself is stateless per-call: each tool command spawns a fresh npx safari-mcp subprocess, performs the action, and exits. This is a deliberate design choice; see HARNESS.md and TEST.md for the reasoning behind the deviation from the standard undo/redo pattern.
Output Formats
All commands support dual output modes:
- Human-readable (default): indented key-value text for
dictresults, bullet lists for arrays, plain text otherwise - Machine-readable (
--jsonflag): structured JSON for agent consumption
# Human output
cli-anything-safari tool snapshot
# JSON output for agents
cli-anything-safari --json tool snapshot
cli-anything-safari --json tools list
cli-anything-safari --json tools describe safari_clickFor AI Agents
When using this CLI programmatically:
- Always use `--json` flag for parseable output.
- Check return codes — 0 for success, non-zero for errors (URL validation failures, MCP call failures, invalid JSON args).
- Parse stderr for error messages; use stdout for data.
- File-handling tools have inconsistent path arg names — always check
tools describe <name>first:
tool save-pdf --path /tmp/x.pdftool upload-file --selector ... --file-path /tmp/x.txt(note:--file-path, not--path)tool export-storage— no path arg; pipe JSON output to a filetool import-storage --path /tmp/x.jsontool screenshot/screenshot-element— return base64 in the JSON response, no path arg (decode it yourself)
- Snapshot before click — refs from
tool snapshotexpire on the next snapshot. Always snapshot → find ref → click in close succession. - Discover tools via `tools list` — the bundled registry is the source of truth for what's available. Do not hard-code tool names that may change upstream.
More from hkuds
Use this skill in a project
Open any RiverX project, search the Skills panel for hkuds/cli-anything/cli-anything-safari, and install it in one click.
