safari-mcp 2.7.4 → 2.7.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,22 +8,17 @@
8
8
 
9
9
  **The only MCP server for Safari — native browser automation for AI agents.**
10
10
 
11
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
12
- [![GitHub release](https://img.shields.io/github/v/release/achiya-automation/safari-mcp)](https://github.com/achiya-automation/safari-mcp/releases)
13
11
  [![npm version](https://img.shields.io/npm/v/safari-mcp)](https://www.npmjs.com/package/safari-mcp)
14
12
  [![npm downloads](https://img.shields.io/npm/dm/safari-mcp)](https://www.npmjs.com/package/safari-mcp)
15
- [![CI](https://github.com/achiya-automation/safari-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/achiya-automation/safari-mcp/actions/workflows/ci.yml)
16
- [![Node.js](https://img.shields.io/badge/Node.js-18%2B-green)](https://nodejs.org/)
13
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
17
14
  [![macOS](https://img.shields.io/badge/macOS-only-blue)](https://www.apple.com/macos/)
18
- [![MCP](https://img.shields.io/badge/MCP-compatible-purple)](https://modelcontextprotocol.io)
19
15
  [![GitHub stars](https://img.shields.io/github/stars/achiya-automation/safari-mcp?style=social)](https://github.com/achiya-automation/safari-mcp/stargazers)
20
- [![achiya-automation/safari-mcp MCP server](https://glama.ai/mcp/servers/achiya-automation/safari-mcp/badges/score.svg)](https://glama.ai/mcp/servers/achiya-automation/safari-mcp)
21
16
 
22
- <a href="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"><img src="https://img.shields.io/badge/VS_Code-Install_MCP_Server-0078d4?logo=visual-studio-code&logoColor=white" alt="Install in VS Code"></a>
23
- <a href="https://insiders.vscode.dev/redirect?url=vscode-insiders:mcp/install?%7B%22safari-mcp%22%3A%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22safari-mcp%22%5D%7D%7D"><img src="https://img.shields.io/badge/VS_Code_Insiders-Install_MCP_Server-24bfa5?logo=visual-studio-code&logoColor=white" alt="Install in VS Code Insiders"></a>
24
- <a href="https://paypal.me/achiyaC123"><img src="https://img.shields.io/badge/Sponsor-PayPal-blue?logo=paypal" alt="Sponsor"></a>
17
+ <a href="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"><img src="https://img.shields.io/badge/VS_Code-Install_Server-0078d4?logo=visual-studio-code&logoColor=white" alt="Install in VS Code"></a>
18
+ <a href="https://insiders.vscode.dev/redirect?url=vscode-insiders:mcp/install?%7B%22safari-mcp%22%3A%7B%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22safari-mcp%22%5D%7D%7D"><img src="https://img.shields.io/badge/VS_Code_Insiders-Install_Server-24bfa5?logo=visual-studio-code&logoColor=white" alt="Install in VS Code Insiders"></a>
19
+ <a href="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"><img src="https://img.shields.io/badge/Cursor-Install_Server-f97316?logo=cursor&logoColor=white" alt="Install in Cursor"></a>
25
20
 
26
- **80 tools** · **Zero dependencies** · **~5ms per command** · **60% less CPU than Chrome**
21
+ **80 tools** · **No Chrome/Puppeteer/Playwright needed** · **~5ms per command** · **60% less CPU than Chrome**
27
22
 
28
23
  [Quick Start](#quick-start) · [All 80 Tools](#tools-80) · [Examples](examples/) · [Why Safari MCP?](#safari-mcp-vs-alternatives) · [Architecture](#architecture) · [Changelog](CHANGELOG.md)
29
24
 
@@ -31,25 +26,18 @@
31
26
 
32
27
  </div>
33
28
 
34
- > **If Safari MCP saves you from running Chrome, consider giving it a star!** It helps others discover this project.
35
-
36
- ---
29
+ > **TL;DR:** Use your real Safari with all your logins, cookies, and sessions. No headless browsers, no Chrome, no Puppeteer. Just native AppleScript + JavaScript on macOS — 60% less CPU/heat on Apple Silicon.
37
30
 
38
- > **TL;DR:** Use your real Safari with all your logins, cookies, and sessions. No headless browsers, no Chrome, no Puppeteer. Just pure AppleScript + JavaScript running natively on macOS — 60% less CPU/heat on Apple Silicon.
39
-
40
- <details>
41
- <summary><b>🤔 Why not just use Playwright or Chrome DevTools MCP?</b></summary>
31
+ ### 🤔 Why not just use Playwright or Chrome DevTools MCP?
42
32
 
43
33
  | Problem | Safari MCP Solution |
44
34
  |---------|-------------------|
45
35
  | Chrome DevTools MCP heats up your Mac | Native WebKit — ~60% less CPU |
46
36
  | Playwright launches a new browser without your logins | Uses your **real Safari** with all sessions |
47
- | Puppeteer requires Chrome + debug port | Zero dependencies — just AppleScript |
37
+ | Puppeteer requires Chrome + debug port | Just AppleScript — no extra browser |
48
38
  | Headless browsers can't access your authenticated sessions | Gmail, GitHub, Slack — already logged in |
49
39
  | Browser automation steals window focus | Safari stays in background, never interrupts |
50
40
 
51
- </details>
52
-
53
41
  ---
54
42
 
55
43
  ## Highlights
@@ -58,7 +46,7 @@
58
46
  - **Zero heat** — native WebKit on Apple Silicon, ~60% less CPU than Chrome
59
47
  - **Your real browser** — keeps all logins, cookies, sessions (Gmail, GitHub, Ahrefs, etc.)
60
48
  - **Background operation** — Safari stays in the background, no window stealing
61
- - **No dependencies** — no Puppeteer, no Playwright, no WebDriver, no Chrome
49
+ - **No browser dependencies** — no Puppeteer, no Playwright, no WebDriver, no Chrome
62
50
  - **Persistent process** — reuses a single osascript process (~5ms per command vs ~80ms)
63
51
  - **Framework-compatible** — React, Vue, Angular, Svelte form filling via native setters
64
52
 
@@ -73,86 +61,60 @@
73
61
  - Safari → Settings → Advanced → **Show features for web developers** ✓
74
62
  - Safari → Develop → **Allow JavaScript from Apple Events** ✓
75
63
 
76
- ### Install
64
+ ### Install (one command)
77
65
 
78
- **Option A — npm (recommended):**
79
66
  ```bash
80
- npm install -g safari-mcp
67
+ npx safari-mcp
81
68
  ```
82
69
 
83
- **Option B — Homebrew:**
84
- ```bash
85
- brew install achiya-automation/tap/safari-mcp
86
- ```
70
+ That's it — no global install needed. Or install permanently:
87
71
 
88
- **Option C — from source:**
89
72
  ```bash
90
- git clone https://github.com/achiya-automation/safari-mcp.git
91
- cd safari-mcp
92
- npm install
73
+ npm install -g safari-mcp
93
74
  ```
94
75
 
95
- ### Configure
96
-
97
- Add to your MCP client config:
76
+ ### Configure your MCP client
98
77
 
99
- <details>
100
- <summary><b>Claude Code</b> (~/.mcp.json)</summary>
78
+ Add to your client's config file — all clients use the same JSON:
101
79
 
102
80
  ```json
103
81
  {
104
82
  "mcpServers": {
105
83
  "safari": {
106
- "command": "node",
107
- "args": ["/path/to/safari-mcp/index.js"]
84
+ "command": "npx",
85
+ "args": ["safari-mcp"]
108
86
  }
109
87
  }
110
88
  }
111
89
  ```
112
- </details>
113
90
 
114
91
  <details>
115
- <summary><b>Claude Desktop</b> (claude_desktop_config.json)</summary>
92
+ <summary><b>Where does each client store this?</b></summary>
93
+
94
+ | Client | Config file |
95
+ |--------|------------|
96
+ | **Claude Code** | `~/.mcp.json` |
97
+ | **Claude Desktop** | `~/Library/Application Support/Claude/claude_desktop_config.json` |
98
+ | **Cursor** | `.cursor/mcp.json` in your project |
99
+ | **Windsurf** | `.windsurf/mcp.json` in your project |
100
+ | **VS Code + Continue** | `.vscode/mcp.json` in your project |
116
101
 
117
- ```json
118
- {
119
- "mcpServers": {
120
- "safari": {
121
- "command": "node",
122
- "args": ["/path/to/safari-mcp/index.js"]
123
- }
124
- }
125
- }
126
- ```
127
102
  </details>
128
103
 
129
104
  <details>
130
- <summary><b>Cursor</b> (.cursor/mcp.json)</summary>
105
+ <summary><b>Alternative: Homebrew</b></summary>
131
106
 
132
- ```json
133
- {
134
- "mcpServers": {
135
- "safari": {
136
- "command": "node",
137
- "args": ["/path/to/safari-mcp/index.js"]
138
- }
139
- }
140
- }
107
+ ```bash
108
+ brew install achiya-automation/tap/safari-mcp
141
109
  ```
142
110
  </details>
143
111
 
144
112
  <details>
145
- <summary><b>Windsurf / VS Code + Continue</b></summary>
113
+ <summary><b>Alternative: from source</b></summary>
146
114
 
147
- ```json
148
- {
149
- "mcpServers": {
150
- "safari": {
151
- "command": "node",
152
- "args": ["/path/to/safari-mcp/index.js"]
153
- }
154
- }
155
- }
115
+ ```bash
116
+ git clone https://github.com/achiya-automation/safari-mcp.git
117
+ cd safari-mcp && npm install
156
118
  ```
157
119
  </details>
158
120
 
@@ -377,7 +339,7 @@ Safari MCP runs locally on your Mac with minimal attack surface:
377
339
  | CPU/Heat | 🟢 Minimal | 🔴 High | 🟡 Medium |
378
340
  | Your logins | ✅ Yes | ✅ Yes | ❌ No |
379
341
  | macOS native | ✅ WebKit | ❌ Chromium | ❌ Chromium/WebKit |
380
- | Dependencies | None | Chrome + debug port | Playwright runtime |
342
+ | Browser dependencies | None | Chrome + debug port | Playwright runtime |
381
343
  | Tools | 80 | ~30 | ~25 |
382
344
  | File upload | JS (no dialog) | CDP | Playwright API |
383
345
  | Image paste | JS (no clipboard) | CDP | Playwright API |
@@ -453,12 +415,16 @@ The Safari MCP Extension is **optional but recommended**. Without it, ~80% of fu
453
415
 
454
416
  ### Installing the Extension
455
417
 
456
- The extension requires a one-time build with Xcode (free, included with macOS):
418
+ The extension requires a one-time build with Xcode (free, included with macOS).
419
+
420
+ > **Note for npm users:** The `xcode/` directory is not included in the npm package.
421
+ > Clone the [GitHub repository](https://github.com/achiya-automation/safari-mcp) to build from source.
457
422
 
458
423
  **Prerequisites:** Xcode (install from App Store — free)
459
424
 
460
425
  ```bash
461
- # 1. Build the extension app
426
+ # 1. Clone the repo (the npm package does not include the Xcode project)
427
+ git clone https://github.com/achiya-automation/safari-mcp.git
462
428
  cd safari-mcp
463
429
  xcodebuild -project "xcode/Safari MCP/Safari MCP.xcodeproj" \
464
430
  -scheme "Safari MCP (macOS)" -configuration Release build
@@ -549,26 +515,29 @@ Your support funds:
549
515
 
550
516
  ## Community
551
517
 
552
- Safari MCP is used by developers building AI agents on macOS. [Share your use case in Discussions](https://github.com/achiya-automation/safari-mcp/discussions)
518
+ **2,000+ weekly npm downloads** — developers are using Safari MCP to build AI agents on macOS.
519
+
520
+ - [GitHub Discussions](https://github.com/achiya-automation/safari-mcp/discussions) — ask questions, share use cases
521
+ - [Issues](https://github.com/achiya-automation/safari-mcp/issues) — bug reports and feature requests
522
+ - [![Good First Issues](https://img.shields.io/github/issues/achiya-automation/safari-mcp/good%20first%20issue?color=7057ff&label=good%20first%20issues)](https://github.com/achiya-automation/safari-mcp/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) — start contributing
553
523
 
554
524
  ---
555
525
 
556
- ## Spread the Word
526
+ ## Like it? Give it a ⭐
557
527
 
558
- If you find Safari MCP useful, help others discover it:
528
+ If Safari MCP saves you from Chrome overhead, **a star helps others discover it:**
559
529
 
560
- - [Star this repo](https://github.com/achiya-automation/safari-mcp)
561
- - [Share on Twitter/X](https://twitter.com/intent/tweet?text=Safari%20MCP%20%E2%80%94%20Stop%20running%20Chrome%20just%20so%20your%20AI%20agent%20can%20browse.%2080%20tools%2C%20native%20Safari%2C%2060%25%20less%20CPU.&url=https%3A%2F%2Fgithub.com%2Fachiya-automation%2Fsafari-mcp)
562
- - [Share on LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fgithub.com%2Fachiya-automation%2Fsafari-mcp)
563
- - Write about it on dev.to or your blog
530
+ [![Star this repo](https://img.shields.io/github/stars/achiya-automation/safari-mcp?style=social)](https://github.com/achiya-automation/safari-mcp)
564
531
 
565
- ---
532
+ [Share on Twitter/X](https://twitter.com/intent/tweet?text=Safari%20MCP%20%E2%80%94%20Stop%20running%20Chrome%20just%20so%20your%20AI%20agent%20can%20browse.%2080%20tools%2C%20native%20Safari%2C%2060%25%20less%20CPU.&url=https%3A%2F%2Fgithub.com%2Fachiya-automation%2Fsafari-mcp) · [Share on LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fgithub.com%2Fachiya-automation%2Fsafari-mcp) · [Write about it](https://dev.to/)
533
+
534
+ [![Star History Chart](https://api.star-history.com/svg?repos=achiya-automation/safari-mcp&type=Date)](https://star-history.com/#achiya-automation/safari-mcp&Date)
566
535
 
567
- ## Star History
536
+ ---
568
537
 
569
- If Safari MCP saved you from Chrome overhead, consider giving it a star!
538
+ ## Listed On
570
539
 
571
- [![Star History Chart](https://api.star-history.com/svg?repos=achiya-automation/safari-mcp&type=Date)](https://star-history.com/#achiya-automation/safari-mcp&Date)
540
+ [![Glama](https://glama.ai/mcp/servers/achiya-automation/safari-mcp/badges/score.svg)](https://glama.ai/mcp/servers/achiya-automation/safari-mcp) [![MCP Registry](https://img.shields.io/badge/MCP-Registry-purple)](https://registry.modelcontextprotocol.io/) [![CI](https://github.com/achiya-automation/safari-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/achiya-automation/safari-mcp/actions/workflows/ci.yml)
572
541
 
573
542
  ---
574
543
 
@@ -24,7 +24,11 @@
24
24
  "*://*.linkedin.com/*",
25
25
  "*://*.x.com/*",
26
26
  "*://*.twitter.com/*",
27
- "*://*.producthunt.com/*"
27
+ "*://*.producthunt.com/*",
28
+ "*://mail.google.com/*",
29
+ "*://calendar.google.com/*",
30
+ "*://chat.google.com/*",
31
+ "*://meet.google.com/*"
28
32
  ],
29
33
  "js": ["content.js"],
30
34
  "run_at": "document_start",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "safari-mcp",
3
- "version": "2.7.4",
3
+ "version": "2.7.5",
4
4
  "mcpName": "io.github.achiya-automation/safari-mcp",
5
5
  "description": "Safari browser automation for AI agents — native macOS, zero Chrome overhead. 80 tools via AppleScript + JavaScript.",
6
6
  "type": "module",
package/safari-helper CHANGED
Binary file
@@ -314,15 +314,10 @@ while let line = readLine(strippingNewline: true) {
314
314
  continue
315
315
  }
316
316
 
317
- // ========== FOCUS PRESERVATION ==========
318
- // Save the frontmost app BEFORE executing AppleScript.
319
- // Safari AppleScript can steal focus — we re-activate the previous app immediately after.
320
- // Re-activating is better than hiding Safari because:
321
- // 1. No jarring hide animation on Safari windows
322
- // 2. User's Safari windows stay visible (just not in front)
323
- // 3. Almost instantaneous — previous app just comes back to foreground
324
- let savedBundleId = NSWorkspace.shared.frontmostApplication?.bundleIdentifier
325
- let wasSafari = savedBundleId == "com.apple.Safari"
317
+ // Focus preservation is handled by the Node.js layer (osascript() function
318
+ // and extensionOrFallback). The daemon must NOT manage focus — it runs every
319
+ // 3 seconds for background checks, and restoring focus here steals Safari
320
+ // from the user whenever they switch to it.
326
321
 
327
322
  guard let nsScript = NSAppleScript(source: script) else {
328
323
  respond(["error": "failed to compile AppleScript"])
@@ -332,15 +327,6 @@ while let line = readLine(strippingNewline: true) {
332
327
  var errorDict: NSDictionary?
333
328
  let result = nsScript.executeAndReturnError(&errorDict)
334
329
 
335
- // Restore focus to previous app if Safari stole it (only if caller wasn't already in Safari)
336
- if !wasSafari,
337
- NSWorkspace.shared.frontmostApplication?.bundleIdentifier == "com.apple.Safari" {
338
- if let savedId = savedBundleId,
339
- let previousApp = NSRunningApplication.runningApplications(withBundleIdentifier: savedId).first {
340
- previousApp.activate()
341
- }
342
- }
343
-
344
330
  if let error = errorDict {
345
331
  let msg = (error["NSAppleScriptErrorMessage"] as? String) ?? "AppleScript error"
346
332
  respond(["error": msg])