MCPSafari:用于AI代理的原生Safari MCP服务器
让Claude、Cursor或任何兼容MCP的AI在macOS上完全控制Safari。导航选项卡、点击/键入/填写表单(甚至是React)、阅读HTML/可访问性树、执行JS、捕获屏幕截图、检查控制台和网络——所有这些都有23个安全工具。零Chrome开销,Apple Silicon优化,令牌认证,并使用官方Swift+Manifest V3 Safari扩展程序构建。
为什么选择MCPSafari?
- 更智能的元素定位(UID+CSS+文本+坐标+交互式排名)
- 与复杂网站完美配合
- 本地和私人(在Mac上运行)
- 完美的Mac优先代理工作流程
macOS 14+ • Safari 17+ • Xcode 26+
与官方合作建造 swift sdk 以及Manifest V3 Safari Web扩展。
为什么选择Safari浏览器而不是Chrome浏览器?
- Apple Silicon上的CPU/热量减少40-60%
- 保留您现有的Safari登录名/Cookie
- 原生可访问性树(对于复杂的UI比Playwright更好)
运作原理
MCP Client (Claude, etc.)
│ stdio
┌───────▼──────────────┐
│ Swift MCP Server │
│ (MCPSafari binary) │
└───────┬──────────────┘
│ WebSocket (localhost:8089)
┌───────▼──────────────┐
│ Safari Extension │
│ (background.js) │
└───────┬──────────────┘
│ content scripts
┌───────▼──────────────┐
│ Safari Browser │
│ (macOS 14.0+) │
└──────────────────────┘MCP服务器通过以下方式与客户端通信 标准 并通过本地桥接工具调用到Safari扩展 WebSocket该扩展通过浏览器API和注入页面的内容脚本执行操作。
需求
- macOS 14.0(索诺玛)或更高版本
- Safari 17+
- Swift 6.3+(用于从源代码构建)
- Xcode 26+(用于构建Safari扩展)
安装
自制(推荐)
安装MCP服务器二进制文件 和 Safari扩展应用程序 /Applications 一步到位。自动清理任何以前的安装。
brew install --cask epistates/tap/mcp-safari升级:
brew upgrade --cask epistates/tap/mcp-safari安装后,在中启用扩展 Safari>设置>扩展>MCPSafari扩展.
从发布
如果您不使用Homebrew,请从以下网址下载CLI二进制文件和扩展应用程序 :
| 资产 | 描述 |
|---|---|
MCPSafari-Server-arm64-apple-darwin | 适用于Apple Silicon的MCP服务器二进制文件(M1、M2、M3、M4) |
MCPSafari-Server-x86_64-apple-darwin | 用于Intel Mac的MCP服务器二进制文件 |
MCPSafari-Server-universal-apple-darwin | MCP服务器二进制文件——通用,可在任何Mac上运行 |
MCPSafari-Extension-arm64.tar.gz | 苹果Silicon的Safari扩展应用程序(M1、M2、M3、M4) |
MCPSafari-Extension-x86_64.tar.gz | 适用于Intel Mac的Safari扩展应用程序 |
# Apple Silicon (M1/M2/M3/M4) — use x86_64 for Intel Macs
curl -L -o /usr/local/bin/mcp-safari https://github.com/Epistates/MCPSafari/releases/latest/download/MCPSafari-Server-arm64-apple-darwin
chmod +x /usr/local/bin/mcp-safari
# Safari extension (must be in /Applications for macOS 26+)
curl -L https://github.com/Epistates/MCPSafari/releases/latest/download/MCPSafari-Extension-arm64.tar.gz | tar xzf -
mv MCPSafari.app /Applications/
open /Applications/MCPSafari.app然后在中启用扩展 Safari>设置>扩展>MCPSafari扩展.
源自
git clone https://github.com/Epistates/MCPSafari.git
cd MCPSafari
# Build the MCP server
cd MCPServer
swift build -c release
# Binary is at .build/release/MCPSafari
# Build and open the Safari extension
cd ../MCPSafari
xcodebuild -project MCPSafari.xcodeproj -scheme MCPSafari build
open ~/Library/Developer/Xcode/DerivedData/MCPSafari-*/Build/Products/Debug/MCPSafari.app然后在中启用扩展 Safari>设置>扩展>MCPSafari扩展.
配置
克劳德代码
使用Claude Code CLI注册服务器(用户范围,在每个项目中都可用):
claude mcp add --scope user mcp-safari mcp-safari或者,要将其范围限定到单个仓库,请创建 .mcp.json 在项目根:
{
"mcpServers": {
"mcp-safari": {
"command": "mcp-safari"
}
}
}证实 claude mcp list --你应该看看 mcp-safari — ✓ Connected.
注: Claude Code的CLI无法读取mcpServers从~/.claude/settings.json--这是克劳德桌面格式。将上面的JSON片段粘贴到settings.json被默默忽略(没有错误,没有注册),Safari扩展程序将显示为“断开连接”,因为服务器从未生成。使用claude mcp add或.mcp.json如上所示。
克劳德桌面版
增添 ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"mcp-safari": {
"command": "mcp-safari"
}
}
}Cursor/Windsurf/其他MCP客户端
任何支持MCP stdio传输的客户端都可以连接。指向 mcp-safari (或完整路径,如果不在 $PATH).
多个Claude实例
多个MCP客户端自动工作。如果使用默认端口(8089),服务器会自动找到空闲端口,扩展会自动发现8089-8098范围内的所有服务器。无需配置——只需启动多个客户端,每个客户端都有自己的连接。
对于默认范围之外的端口,请在扩展弹出窗口中手动添加或明确指定:
{
"mcpServers": {
"mcp-safari": {
"command": "mcp-safari",
"args": ["--port", "9090"]
}
}
}CLI选项
| 标志 | 描述 |
|---|---|
--port / -p | WebSocket端口(默认: 8089) |
--verbose | 调试级别日志记录到stderr |
工具(23)
选项卡管理
| 工具 | 说明 |
|---|---|
tabs_context | 列出所有打开的带有ID、URL和标题的选项卡 |
tabs_create | 打开一个新选项卡,可选地使用URL |
close_tab | 按ID关闭选项卡 |
select_tab | 将选项卡固定为未来调用的默认上下文 |
导航
| 工具 | 说明 |
|---|---|
navigate | 转到URL,或使用 back / forward / reload 行动 |
页面阅读
| 工具 | 说明 |
|---|---|
read_page | 获取页面内容 text, html,或 snapshot |
snapshot | 带有元素UID的可访问性树,用于交互 |
find | 按CSS选择器、文本或ARIA角色查找元素 |
交互
| 工具 | 说明 |
|---|---|
click | 按UID、CSS选择器、文本或坐标单击 |
type_text | 在带有可选的元素中键入 clearFirst 和 submitKey |
form_input | 批量填充表单字段(CSS选择器→ 价值图) |
select_option | 按值或标签选择下拉选项 |
scroll | 向任何方向滚动页面或元素 |
press_key | 按下组合键(例如。, Enter, Meta+a, Control+c) |
hover | 悬停以触发工具提示、菜单或悬停状态 |
drag | 在元素之间拖放 |
对话
| 工具 | 说明 |
|---|---|
handle_dialog | 接受或取消警报、确认和提示 |
截图
| 工具 | 说明 |
|---|---|
screenshot | 将可见选项卡区域捕获为PNG图像 |
JavaScript
| 工具 | 说明 |
|---|---|
javascript_tool | 在页面上下文中执行任意JS并返回表达式结果 |
调试
| 工具 | 说明 |
|---|---|
read_console | 使用级别和正则表达式过滤读取控制台消息 |
read_network | 使用类型筛选读取捕获的XHR/fetch请求 |
窗口
| 工具 | 说明 |
|---|---|
resize_window | 将浏览器窗口调整为特定尺寸 |
效用
| 工具 | 说明 |
|---|---|
wait | 等待持续时间、CSS选择器或文本出现 |
用法
基本工作流程
- 从上下文开始 --呼叫
tabs_context看看有什么是开放的,或者navigate到URL。 - 拍快照 --呼叫
snapshot获取包含元素UID的可访问性树。 - 互动 --使用快照中的UID
click,type_text,hover等等。 - 验证 --通行证
includeSnapshot: true在交互工具上查看更新的状态,或采取screenshot.
元素定位
与元素交互的工具接受多种定位策略:
| 策略 | 示例 | 何时使用 |
|---|---|---|
| 用户标识 | uid: "e42" | 最精确的——来自a snapshot |
| CSS选择器 | selector: "#login-btn" | 当你知道DOM结构时 |
| 文本 | text: "Sign In" | 互动元素排名较高 |
| 坐标 | x: 100, y: 200 | 最后手段——点击精确位置 |
表格填写
使用 form_input 一次填写多个字段:
{
"fields": {
"#name": "Jane Doe",
"#email": "jane@example.com",
"textarea[name=message]": "Hello!"
}
}这使用与React兼容的值设置(nativeInputValueSetter)因此,它适用于React、Next.js和类似框架中的受控输入。
智能文本匹配
当瞄准时 text,交互元素(按钮、链接、输入)的排名高于通用容器。点击 text: "Submit" 会更喜欢a Submit 超过一个 Submit .
行动后快照
大多数交互工具支持 includeSnapshot: true,它在操作后返回更新的可访问性树,这对于验证结果非常有用,而无需单独的 snapshot 电话。
行动后等待
navigate 和交互工具支持 waitForSelector, waitForText,以及 waitTimeout 在成功操作后等待返回。当与 includeSnapshot: true,等待后捕获快照。
页面痕迹
交互工具支持 trace: true 和 traceDuration 在操作后返回一个简短的页面跟踪。跟踪包括URL/历史更改、控制台消息、获取/XHR请求和在操作窗口期间捕获的DOM突变。
建筑
MCP服务器(MCPServer/)
Swift可执行文件使用官方 modelcontextprotocol/swift-sdk.通过以下方式与MCP客户端通信 标准 通过Safari扩展程序 WebSocket 桥梁使用 Network.framework.
main.swift--入口点,解析CLI标志,启动服务器SafariMCPServer.swift--工具定义和处理程序(参与者)WebSocketBridge.swift--具有请求/响应相关性的WebSocket服务器(参与者)BridgeMessage.swift--有线协议类型和AnyCodable序列化
Safari扩展程序(MCPSafari/)
包含以下功能的Manifest V3 Safari Web扩展:
background.js--WebSocket客户端、请求路由器、标签/导航/屏幕截图处理程序content.js--DOM交互、可访问性快照、元素查找、点击/键入/滚动模拟trace-interceptor.js--捕获操作窗口URL、历史记录、控制台、网络和DOM突变事件dialog-interceptor.js--补丁window.alert/confirm/prompt在页面脚本运行之前console-interceptor.js--捕获控制台消息read_consolenetwork-interceptor.js--捕获XHR/fetch请求read_networkpopup.html/js/css--显示连接状态的扩展弹出窗口
macOS主机应用程序
最小的macOS应用程序(AppDelegate.swift, ViewController.swift)它注册Safari扩展并为身份验证令牌交换提供本机消息传递。
安全
WebSocket身份验证
服务器在启动时生成一个随机UUID令牌,并将其写入 ~/.config/mcp-safari/tokens/ (模式 0600),并要求在发送任何MCP工具流量之前将其作为第一个WebSocket消息。该扩展通过主机应用程序的本机消息读取每个端口的令牌映射,因此多个服务器实例可以独立进行身份验证。没有有效令牌的连接将被关闭。
输入验证
- URL方案仅限于
http,https,about,以及file - 针对同种异体进行导航操作验证
- 正则表达式模式限制为200个字符,并在转发前进行验证
- 等待时间上限为300秒
权限
扩展程序在中请求这些权限 manifest.json:
| 许可 | 目的 |
|---|---|
tabs | 列出和管理选项卡 |
activeTab | 访问活动选项卡 |
scripting | 注入内容脚本并执行JS |
webNavigation | 导航选项卡(后退/前进/重新加载) |
nativeMessaging | 与主机应用程序进行身份验证令牌交换 |
alarms | 服务人员活着 |
storage | 在悬挂系统中保留所选选项卡 |
故障排除
扩展显示“已断开连接”
- 确保MCP服务器正在运行(检查您的MCP客户端日志)
- 验证端口8089是否未使用:
lsof -i :8089 - 在扩展弹出窗口中单击“重新连接”
- 使用
--verbose服务器上用于调试日志的标记
“无法建立连接”错误
内容脚本可能尚未注入。扩展程序在第一次交互时自动注入,但您也可以重新加载页面。
Safari权限提示
Safari在扩展首次与域交互时提示输入每个站点的权限。在Safari>设置>扩展>MCPSafari扩展中单击“始终允许访问每个网站”,以避免重复提示。
端口已在使用中
使用 --port 选择其他端口:
{
"mcpServers": {
"mcp-safari": {
"command": "mcp-safari",
"args": ["--port", "9090"]
}
}
}发展
构建与测试
# Build the MCP server
cd MCPServer
swift build
# Build the Safari extension
cd MCPSafari
xcodebuild -project MCPSafari.xcodeproj -scheme MCPSafari build
# Run the server with verbose logging
.build/debug/MCPSafari --verboseCI
CI工作流在每次推送和PR时运行 main:
- 构建MCP服务器(
swift build) - 测试MCP握手(验证二进制响应
initialize) - 构建Safari扩展(
xcodebuild)
项目结构
MCPSafari/
├── MCPServer/ # Swift MCP server
│ ├── Package.swift
│ └── Sources/mcp-safari/
│ ├── main.swift
│ ├── SafariMCPServer.swift
│ ├── WebSocketBridge.swift
│ └── BridgeMessage.swift
├── MCPSafari/ # Xcode project
│ ├── MCPSafari/ # macOS host app
│ ├── MCPSafari Extension/ # Safari web extension
│ │ ├── Resources/
│ │ │ ├── background.js
│ │ │ ├── content.js
│ │ │ ├── dialog-interceptor.js
│ │ │ ├── console-interceptor.js
│ │ │ ├── network-interceptor.js
│ │ │ ├── manifest.json
│ │ │ └── popup.html/js/css
│ │ └── SafariWebExtensionHandler.swift
│ └── MCPSafari.xcodeproj
├── .github/workflows/
│ ├── ci.yml
│ └── release.yml
└── CHANGELOG.md许可证
麻省理工学院
