cli-anything-safari
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinesecli-anything-safari
cli-anything-safari
A command-line interface for Safari browser automation on macOS. Wraps the
Node.js MCP
server in a Python Click CLI.
safari-mcpFeature parity is guaranteed. Every Click command is generated
automatically from 's tool schema (bundled as
). All 84 tools are reachable with the exact
argument names and types the MCP server expects.
safari-mcpresources/tools.json一款用于macOS平台Safari浏览器自动化的命令行界面工具。基于Python Click CLI封装了
Node.js MCP
服务器。
safari-mcp保证功能完全一致。所有Click命令均从的工具模式自动生成(打包为)。全部84个工具均可通过MCP服务器要求的精确参数名称和类型调用。
safari-mcpresources/tools.jsonWhen to use this CLI
何时使用此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 directly over MCP stdio will be faster.
safari-mcpUse 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.
每次CLI调用都会启动一个全新的子进程,因此存在单次调用的开销。如果你的Agent原生支持MCP(如Claude Code、Cursor、Cline等),直接通过MCP标准输入输出使用会更快。
safari-mcp在以下场景使用此CLI:
- 你的Agent框架不支持MCP(如Codex CLI、GitHub Copilot CLI、自定义脚本、旧版Agent框架)。
- 你需要通过bash编写浏览器自动化脚本——例如 。
cli-anything-safari --json tool snapshot | jq '...' - 你在CI/CD环境中运行,需要支持定时任务、子进程友好的输出。
- 你在终端中交互式调试。
Installation
安装
Prerequisites
前置条件
- macOS — Safari MCP is macOS-only.
- Safari — already installed on macOS.
- Node.js 18+ — or from https://nodejs.org/
brew install node - Python 3.10+
- Enable Apple Events for Safari: Safari → Develop → Allow JavaScript from Apple Events
- macOS — Safari MCP仅支持macOS。
- Safari — macOS默认已安装。
- Node.js 18+ — 可通过安装,或从https://nodejs.org/下载。
brew install node - Python 3.10+
- 为Safari启用Apple事件:Safari → 开发 → 允许来自Apple事件的JavaScript
Install the CLI
安装CLI
bash
cd safari/agent-harness
pip install -e .The first call will download the npm package (one-time, a few MB).
toolsafari-mcpbash
cd safari/agent-harness
pip install -e .首次调用命令时会下载 npm包(仅一次,大小约数MB)。
toolsafari-mcpCommand Structure
命令结构
The CLI has 5 top-level commands:
| Command | Purpose |
|---|---|
| Call any of safari-mcp's 84 tools (dynamic, schema-driven) |
| Inspect the bundled tool registry ( |
| Escape hatch — call a tool by full name with raw JSON args |
| In-memory session state (last URL, current tab) |
| Interactive REPL (default when no subcommand given) |
CLI包含5个顶级命令:
| 命令 | 用途 |
|---|---|
| 调用safari-mcp的任意84个工具(动态生成,基于模式) |
| 查看已打包的工具注册表( |
| 应急入口——通过完整工具名和原始JSON参数调用工具 |
| 内存中的会话状态(最后访问的URL、当前标签页) |
| 交互式REPL(未指定子命令时默认启动) |
Usage Examples
使用示例
Discover the tool surface
探索工具范围
bash
undefinedbash
undefinedCount of tools (sanity check — must match safari-mcp's registered tools)
统计工具数量( sanity检查——必须与safari-mcp注册的工具数一致)
cli-anything-safari tools count
cli-anything-safari tools count
→ 84
→ 84
List every tool
列出所有工具
cli-anything-safari tools list
cli-anything-safari tools list --filter click # filter by substring
cli-anything-safari tools list
cli-anything-safari tools list --filter click # 通过子字符串过滤
Full schema for one tool (JSON or human format)
查看单个工具的完整模式(JSON或人类可读格式)
cli-anything-safari tools describe safari_scroll
cli-anything-safari --json tools describe safari_click
undefinedcli-anything-safari tools describe safari_scroll
cli-anything-safari --json tools describe safari_click
undefinedCall a tool (schema-driven)
调用工具(基于模式)
bash
undefinedbash
undefinedNavigate
导航
cli-anything-safari tool navigate --url https://example.com
cli-anything-safari tool navigate --url https://example.com
Take a snapshot (preferred over screenshot — structured text with ref IDs)
生成快照(优于截图——包含引用ID的结构化文本)
cli-anything-safari --json tool snapshot
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
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"
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"
cli-anything-safari tool fill --selector "#email" --value "user@example.com"
Scroll by direction/amount (NOT x/y — note the schema!)
按方向/数量滚动(注意:不是x/y——遵循模式!)
cli-anything-safari tool scroll --direction down --amount 500
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"
--source-selector ".card"
--target-selector ".trash"
cli-anything-safari tool drag
--source-selector ".card"
--target-selector ".trash"
--source-selector ".card"
--target-selector ".trash"
Screenshot — returns base64 JPEG in stdout. Decode with:
截图——在标准输出返回base64格式的JPEG。解码命令:
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']))"
| python3 -c "import sys,json,base64;
d=json.load(sys.stdin);
open('/tmp/shot.jpg','wb').write(base64.b64decode(d['data']))"
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']))"
| 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)
保存为PDF(此命令直接写入磁盘)
cli-anything-safari tool save-pdf --path /tmp/page.pdf
cli-anything-safari tool save-pdf --path /tmp/page.pdf
Evaluate JavaScript (note: parameter is --script, not --code)
执行JavaScript(注意:参数是--script,不是--code)
cli-anything-safari tool evaluate --script "document.title"
undefinedcli-anything-safari tool evaluate --script "document.title"
undefinedNavigate and read in one round-trip
一次往返完成导航与读取
bash
cli-anything-safari --json tool navigate-and-read --url https://example.combash
cli-anything-safari --json tool navigate-and-read --url https://example.comForm fill (bulk)
批量填充表单
safari_fill_form{selector, value}bash
cli-anything-safari tool fill-form --fields '[
{"selector": "#email", "value": "user@example.com"},
{"selector": "#password", "value": "hunter2"}
]'Run to see the
exact schema, including any new fields safari-mcp adds upstream.
cli-anything-safari tools describe safari_fill_formsafari_fill_form{selector, value}bash
cli-anything-safari tool fill-form --fields '[
{"selector": "#email", "value": "user@example.com"},
{"selector": "#password", "value": "hunter2"}
]'运行查看精确模式,包括safari-mcp上游新增的字段。
cli-anything-safari tools describe safari_fill_formNetwork 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-safari tool performance-metricsbash
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
存储操作
bash
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 themebash
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 themeexport-storage returns JSON to stdout — no --path arg. Pipe to a file:
export-storage将JSON返回至标准输出——无--path参数。可将输出管道到文件:
cli-anything-safari --json tool export-storage > /tmp/storage.json
undefinedcli-anything-safari --json tool export-storage > /tmp/storage.json
undefinedRaw JSON escape hatch
原始JSON应急入口
When you need to pass a complex nested object or want to drive the CLI from
a pre-built JSON blob:
bash
cli-anything-safari raw safari_evaluate \
--json-args '{"code":"[...document.querySelectorAll(\"a\")].map(a => a.href)"}'当你需要传递复杂嵌套对象,或希望通过预构建的JSON blob驱动CLI时:
bash
cli-anything-safari raw safari_evaluate \
--json-args '{"code":"[...document.querySelectorAll(\"a\")].map(a => a.href)"}'Interactive REPL
交互式REPL
bash
cli-anything-safariThe REPL banner prints the absolute path to this SKILL.md so agents can
self-discover capabilities.
bash
cli-anything-safariREPL横幅会打印SKILL.md的绝对路径,以便Agent自动发现功能。
JSON Output
JSON输出
All commands support as a global flag:
--jsonbash
cli-anything-safari --json tool snapshot
cli-anything-safari --json tool list-tabs
cli-anything-safari --json tools list所有命令均支持全局标志:
--jsonbash
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 the CLI navigated to (updated after every successful
last_url,tool navigate, ortool navigate-and-read)tool new-tab - — last known active tab index
current_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 command spawns a fresh
subprocess, performs the action, and exits. This is a
deliberate design choice; see and for the
reasoning behind the deviation from the standard undo/redo pattern.
toolnpx safari-mcpHARNESS.mdTEST.mdCLI仅为REPL显示维护少量内存状态:
- — CLI最后导航到的URL(每次成功执行
last_url、tool navigate或tool navigate-and-read后更新)tool new-tab - — 最后已知的活动标签页索引
current_tab_index
无持久会话,无撤销/重做功能,无文档模型。每次CLI调用均从全新状态开始。Safari MCP本身是单次调用无状态的:每个命令都会启动一个全新的子进程,执行操作后退出。这是一个刻意的设计选择;如需了解偏离标准撤销/重做模式的原因,请查看和。
toolnpx safari-mcpHARNESS.mdTEST.mdOutput Formats
输出格式
All commands support dual output modes:
- Human-readable (default): indented key-value text for results, bullet lists for arrays, plain text otherwise
dict - Machine-readable (flag): structured JSON for agent consumption
--json
bash
undefined所有命令支持两种输出模式:
- 人类可读格式(默认):字典结果为缩进的键值文本,数组为项目符号列表,其他为纯文本
- 机器可读格式(标志):结构化JSON,供Agent使用
--json
bash
undefinedHuman output
人类可读输出
cli-anything-safari tool snapshot
cli-anything-safari tool snapshot
JSON output for agents
供Agent使用的JSON输出
cli-anything-safari --json tool snapshot
cli-anything-safari --json tools list
cli-anything-safari --json tools describe safari_click
undefinedcli-anything-safari --json tool snapshot
cli-anything-safari --json tools list
cli-anything-safari --json tools describe safari_click
undefinedFor AI Agents
面向AI Agent的说明
When using this CLI programmatically:
- Always use flag for parseable output.
--json - 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 first:
tools describe <name>tool save-pdf --path /tmp/x.pdf- (note:
tool upload-file --selector ... --file-path /tmp/x.txt, not--file-path)--path - — no path arg; pipe JSON output to a file
tool export-storage tool import-storage --path /tmp/x.json- /
tool screenshot— return base64 in the JSON response, no path arg (decode it yourself)screenshot-element
- Snapshot before click — refs from expire on the next snapshot. Always snapshot → find ref → click in close succession.
tool snapshot - Discover tools via — the bundled registry is the source of truth for what's available. Do not hard-code tool names that may change upstream.
tools list - Use to learn the exact schema (required args, enum choices, JSON-typed args) before constructing a call. Never assume parameter names from the description — for example,
tools describe <name>takessafari_evaluate(not--script) even though the description says "JavaScript code to execute".--code
以编程方式使用此CLI时:
- 始终使用标志以获得可解析的输出。
--json - 检查返回码 — 0表示成功,非0表示错误(URL验证失败、MCP调用失败、无效JSON参数)。
- 解析标准错误流获取错误信息;标准输出流用于返回数据。
- 文件处理工具的路径参数名称不一致 — 调用前务必先执行:
tools describe <name>tool save-pdf --path /tmp/x.pdf- (注意:是
tool upload-file --selector ... --file-path /tmp/x.txt,不是--file-path)--path - — 无路径参数;将JSON输出管道到文件
tool export-storage tool import-storage --path /tmp/x.json- /
tool screenshot— 在JSON响应中返回base64,无路径参数(需自行解码)screenshot-element
- 点击前先快照 — 返回的引用在下次快照时会失效。务必按快照→查找引用→点击的顺序连续操作。
tool snapshot - 通过探索工具 — 已打包的注册表是可用工具的权威来源。不要硬编码可能随上游变更的工具名称。
tools list - **使用**了解精确模式(必填参数、枚举选项、JSON类型参数)后再构建调用。切勿根据描述假设参数名称——例如,
tools describe <name>接收safari_evaluate(而非--script),尽管描述中写的是“要执行的JavaScript代码”。--code
Agent-Specific Guidance
针对特定Agent的指南
Finding the right tool
查找合适的工具
Use the introspection commands. The CLI is guaranteed to reflect the
MCP server 1:1:
bash
undefined使用自省命令。CLI保证与MCP服务器1:1同步:
bash
undefinedFind all click-related tools
查找所有与点击相关的工具
cli-anything-safari tools list --filter click
cli-anything-safari tools list --filter click
Get the full schema (including every argument with type, description,
获取完整模式(包括每个参数的类型、描述、必填/可选、枚举选项、默认值)
required/optional, enum choices, defaults)
—
cli-anything-safari --json tools describe safari_click
undefinedcli-anything-safari --json tools describe safari_click
undefinedTool selection strategy
工具选择策略
- over
tool snapshot— structured text with ref IDs is orders of magnitude cheaper and carries the refs needed for clicks.tool screenshot - over
tool click --ref— refs are stable within a single snapshot, selectors may be brittle.tool click --selector - over
tool navigate-and-read+navigate— saves one round-trip.read-page - over
tool click-and-read+click— saves one round-trip.read-page - only when regular click fails with 405/403 (WAF blocks, G2, Cloudflare) — it physically moves the cursor.
tool native-click
- 优先使用而非
tool snapshot— 带有引用ID的结构化文本成本低得多,且包含点击所需的引用。tool screenshot - 优先使用而非
tool click --ref— 引用在单个快照内稳定,选择器可能不稳定。tool click --selector - 优先使用而非
tool navigate-and-read+navigate— 减少一次往返。read-page - 优先使用而非
tool click-and-read+click— 减少一次往返。read-page - 仅在常规点击返回405/403错误时使用(如WAF拦截、G2、Cloudflare)——它会物理移动光标。
tool native-click
Refs Expire
引用会失效
Refs from expire when you take a new snapshot:
tool snapshot- First snapshot: refs ,
0_1,0_2...0_3 - Second snapshot: refs ,
1_1,1_2...1_3
Always snapshot → click in close succession. If in doubt, snapshot again.
tool snapshot- 第一次快照:引用为,
0_1,0_2...0_3 - 第二次快照:引用为,
1_1,1_2...1_3
务必按快照→点击的顺序连续操作。如有疑问,重新快照。
Tab Ownership Safety
标签页所有权安全
Safari MCP tracks tab ownership per session. Tools that modify a tab
(navigate, click, fill) are blocked on tabs the session did not open.
To operate on a specific page, always start with .
tool new-tab --url ...Safari MCP按会话跟踪标签页所有权。修改标签页的工具(导航、点击、填充)无法操作会话未打开的标签页。如需操作特定页面,请始终从开始。
tool new-tab --url ...Error Handling
错误处理
Common errors:
- → install Node.js 18+
npx not found - → check network
safari-mcp package not found on npm registry - → harness is macOS-only
Not macOS - → enable "Allow JavaScript from Apple Events" in Safari → Develop
AppleScript denied - → URL validation rejected the input (by design)
Blocked URL scheme: file
常见错误:
- → 安装Node.js 18+
npx not found - → 检查网络
safari-mcp package not found on npm registry - → 此工具仅支持macOS
Not macOS - → 在Safari的“开发”菜单中启用“允许来自Apple事件的JavaScript”
AppleScript denied - → URL验证拒绝了输入(设计如此)
Blocked URL scheme: file
URL Validation
URL验证
The CLI validates URLs before passing them to ,
, and . Blocked schemes:
, , , , , , ,
, , and other browser-internal schemes. The
command also enforces this for navigation tools.
safari_navigatesafari_navigate_and_readsafari_new_tabfilejavascriptdatavbscriptaboutchromesafariwebkitx-applerawCLI会在将URL传递给、和前进行验证。被阻止的协议包括:、、、、、、、、及其他浏览器内部协议。命令同样会对导航工具执行此验证。
safari_navigatesafari_navigate_and_readsafari_new_tabfilejavascriptdatavbscriptaboutchromesafariwebkitx-applerawMulti-Session Warning
多会话警告
Safari MCP enforces a single active session by killing stale Node.js
processes older than 10 seconds. If you run two CLI instances at once,
one will kill the other's backend. There is currently no daemon
mode — for latency-sensitive workflows, drive the CLI from a
long-lived Python script that imports
directly to avoid
re-spawning the subprocess on every invocation.
cli_anything.safari.utils.safari_backend.call()Safari MCP通过终止超过10秒的陈旧Node.js进程来强制执行单个活动会话。如果同时运行两个CLI实例,其中一个会终止另一个的后端进程。目前无守护进程模式——对于对延迟敏感的工作流,可从长期运行的Python脚本直接导入,避免每次调用都重新启动子进程。
cli_anything.safari.utils.safari_backend.call()Links
链接
Security Considerations
安全注意事项
URL Validation
URL验证
All navigation tools (, , , and ) pass the argument through
which blocks dangerous schemes and optionally blocks
private networks (set ).
tool navigatetool navigate-and-readtool new-tabraw safari_navigate*urlutils/security.pyCLI_ANYTHING_SAFARI_BLOCK_PRIVATE=1所有导航工具(、、以及)都会将参数传入进行验证,该模块会阻止危险协议,并可选择阻止私有网络(设置)。
tool navigatetool navigate-and-readtool new-tabraw safari_navigate*urlutils/security.pyCLI_ANYTHING_SAFARI_BLOCK_PRIVATE=1Tab Isolation
标签页隔离
Safari MCP enforces per-session tab ownership upstream — tools cannot
operate on tabs the session did not open.
Safari MCP在上游强制执行按会话的标签页隔离——工具无法操作会话未打开的标签页。
Profile Isolation
配置文件隔离
Set env var to use a separate Safari profile for
automation:
SAFARI_PROFILEbash
export SAFARI_PROFILE="Automation"
cli-anything-safari tool navigate --url https://example.comThis keeps cookies/logins/history separate from the user's main browsing.
设置环境变量,为自动化操作使用单独的Safari配置文件:
SAFARI_PROFILEbash
export SAFARI_PROFILE="Automation"
cli-anything-safari tool navigate --url https://example.com这样可将Cookie、登录信息、浏览历史与用户的主浏览会话隔离开。
JavaScript Execution
JavaScript执行
tool evaluatetool run-scripttool evaluatetool run-scriptClipboard
剪贴板
tool clipboard-readtool clipboard-writetool clipboard-readtool clipboard-writeRegenerating the tool registry
重新生成工具注册表
If you upgrade , regenerate the bundled schema:
safari-mcpbash
python scripts/extract_tools.py \
"$(npm root -g)/safari-mcp/index.js" \
cli_anything/safari/resources/tools.jsonThe parity test () pins the expected tool count; update
it when the upstream tool list changes.
test_parity.py如果你升级了,请重新生成已打包的模式:
safari-mcpbash
python scripts/extract_tools.py \
"$(npm root -g)/safari-mcp/index.js" \
cli_anything/safari/resources/tools.json一致性测试()固定了预期的工具数量;上游工具列表变更时请更新此测试。
test_parity.pyMore Information
更多信息
- Full documentation: in the package
cli_anything/safari/README.md - Test coverage: in the package
cli_anything/safari/tests/TEST.md - Architecture analysis:
safari/agent-harness/SAFARI.md - Methodology:
cli-anything-plugin/HARNESS.md - MCP backend pattern:
cli-anything-plugin/guides/mcp-backend.md
- 完整文档:包内的
cli_anything/safari/README.md - 测试覆盖:包内的
cli_anything/safari/tests/TEST.md - 架构分析:
safari/agent-harness/SAFARI.md - 方法论:
cli-anything-plugin/HARNESS.md - MCP后端模式:
cli-anything-plugin/guides/mcp-backend.md
Version
版本
1.0.0 — targets safari-mcp 2.7.8 (84 tools). Bundled tool registry is
regenerated via when safari-mcp upgrades.
scripts/extract_tools.py1.0.0 — 适配safari-mcp 2.7.8(84个工具)。当safari-mcp升级时,会通过重新生成已打包的工具注册表。
scripts/extract_tools.py