🚀 macOS Automator MCP Server
本項目提供了一個模型上下文協議(MCP)服務器 macos_automator,它允許在 macOS 系統上執行 AppleScript 和 JavaScript for Automation (JXA) 腳本。該服務器具備一個預定義腳本知識庫,可通過 ID 訪問,同時支持內聯腳本、腳本文件和參數傳遞。知識庫會在首次使用時進行懶加載,以實現服務器的快速啟動。
🚀 快速開始
本項目提供的 macos_automator 服務器允許通過 MCP 協議遠程執行 AppleScript 和 JXA 腳本,實現對 macOS 系統的自動化控制。以下是使用該服務器的快速指南。
安裝與運行
運行此服務器的主要方式是通過 npx,這樣可以確保使用的是最新版本,而無需進行全局安裝。將以下配置添加到 MCP 客戶端的 mcp.json(或等效配置文件)中:
{
"mcpServers": {
"macos_automator": {
"command": "npx",
"args": [
"-y",
"@steipete/macos-automator-mcp@latest"
]
}
}
}
本地運行(開發或直接使用)
如果你想在本地開發或直接從克隆的倉庫運行服務器,可以使用提供的 start.sh 腳本。這在你需要進行本地修改或運行特定版本時非常有用。
- 克隆倉庫:
git clone https://github.com/steipete/macos-automator-mcp.git
cd macos-automator-mcp
npm install
- 配置 MCP 客戶端:
更新 MCP 客戶端的配置,使其指向克隆倉庫中
start.sh 腳本的絕對路徑。
示例 mcp.json 配置片段:
{
"mcpServers": {
"macos_automator_local": {
"command": "/absolute/path/to/your/cloned/macos-automator-mcp/start.sh",
"env": {
"LOG_LEVEL": "DEBUG"
}
}
}
}
重要提示:請將 /absolute/path/to/your/cloned/macos-automator-mcp/start.sh 替換為你係統上的正確絕對路徑。
start.sh 腳本會在未找到編譯版本時自動使用 tsx 直接運行 TypeScript 源代碼,或者在可用時從 dist/ 目錄運行編譯後的版本。它會遵循 LOG_LEVEL 環境變量。
開發者注意事項:如果修改 start.sh 腳本,在執行前刪除任何現有的編譯後的 dist/server.js(例如,添加 rm -f dist/server.js),則可以確保始終通過 tsx 運行 src/ 目錄中的最新 TypeScript 代碼。這在開發過程中非常有用,可以避免陳舊構建帶來的問題。對於生產部署(例如發佈到 npm),通常會有一個構建過程來創建最終的 dist/server.js,它將成為發佈包的入口點。
✨ 主要特性
- 通過 MCP 遠程執行 AppleScript/JXA 腳本。
- 利用豐富且可擴展的常見 macOS 自動化任務知識庫。
- 以編程方式控制 macOS 應用程序和系統功能。
- 將 macOS 自動化集成到更大的 AI 驅動工作流中。
📦 安裝指南
前提條件
- Node.js(建議版本 >=18.0.0,詳見
package.json 中的 engines 字段)。
- macOS 系統。
關鍵權限設置
- 運行此 MCP 服務器的應用程序(例如,終端、你的 Node.js 應用程序)需要在運行服務器的 macOS 機器上獲得用戶的明確權限。
- 自動化權限:用於控制其他應用程序(如 Finder、Safari、Mail 等)。
- 前往:系統設置 > 隱私與安全 > 自動化。
- 在列表中找到運行服務器的應用程序(例如,終端)。
- 確保為其需要控制的所有應用程序勾選複選框。
- 示例請參考:
docs/automation-permissions-example.png(佔位圖像)。
- 輔助功能權限:用於通過 “系統事件” 進行 UI 腳本編寫(例如,模擬點擊、按鍵)。
- 前往:系統設置 > 隱私與安全 > 輔助功能。
- 將運行服務器的應用程序(例如,終端)添加到列表中,並確保勾選其複選框。
- 首次嘗試控制新應用程序或使用輔助功能時,即使已預先授權,仍可能會觸發 macOS 確認提示。服務器本身無法授予這些權限。
💻 使用示例
基礎用法
以下是一些使用 execute_script 工具的示例:
{
"toolName": "execute_script",
"input": {
"kb_script_id": "safari_get_active_tab_url",
"timeout_seconds": 10
}
}
{
"toolName": "execute_script",
"input": {
"kb_script_id": "finder_create_folder_at_path",
"input_data": {
"folder_name": "New MCP Folder",
"parent_path": "~/Desktop"
}
}
}
高級用法
使用 get_scripting_tips 工具檢索知識庫中的腳本提示和示例:
{
"toolName": "get_scripting_tips",
"input": {
"list_categories": true
}
}
{
"toolName": "get_scripting_tips",
"input": {
"category": "safari"
}
}
{
"toolName": "get_scripting_tips",
"input": {
"search_term": "clipboard"
}
}
📚 詳細文檔
提供的工具
1. execute_script
在 macOS 上執行 AppleScript 或 JavaScript for Automation (JXA) 腳本。腳本可以作為內聯內容 (script_content)、絕對文件路徑 (script_path) 提供,或者通過使用其唯一的 kb_script_id 引用內置知識庫中的腳本。
- 腳本來源(互斥):
script_content (字符串):原始腳本代碼。
script_path (字符串):腳本文件的絕對 POSIX 路徑(例如,.applescript、.scpt、.js)。
kb_script_id (字符串):服務器知識庫中預定義腳本的 ID。使用 get_scripting_tips 工具發現可用的腳本 ID 及其功能。
- 語言指定:
language (枚舉: 'applescript' | 'javascript',可選):指定腳本語言。
- 如果使用
kb_script_id,語言將從知識庫腳本中推斷。
- 如果使用
script_content 或 script_path 且未指定 language,則默認為 'applescript'。
- 向腳本傳遞輸入:
arguments (字符串數組,可選):
- 對於
script_path:作為標準參數傳遞給腳本的 on run argv (AppleScript) 或 run(argv) (JXA) 處理程序。
- 對於
kb_script_id:如果預定義腳本設計為接受位置字符串參數(例如,替換佔位符 --MCP_ARG_1、--MCP_ARG_2),則使用此參數。請檢查 get_scripting_tips 中腳本的 argumentsPrompt。
input_data (JSON 對象,可選):
- 主要用於設計為接受命名、結構化輸入的
kb_script_id 腳本。
- 此對象中的值將替換腳本中的佔位符(例如,
--MCP_INPUT:yourKeyName)。請參閱 get_scripting_tips 中的 argumentsPrompt。
- 值(字符串、數字、布爾值、簡單數組/對象)將轉換為其 AppleScript 字面量等效形式。
- 其他選項:
timeout_seconds (整數,可選,默認值: 60):最大執行時間。
output_format_mode (枚舉,可選,默認值: 'auto'):控制 osascript 輸出格式化標誌。
'auto' (默認):AppleScript 使用人類可讀格式 (-s h),JXA 使用直接輸出(無 -s 標誌)。
'human_readable':強制使用 -s h(人類可讀輸出,主要用於 AppleScript)。
'structured_error':強制使用 -s s(結構化錯誤報告,主要用於 AppleScript)。
'structured_output_and_error':強制使用 -s ss(主要結果和錯誤的結構化輸出,主要用於 AppleScript)。
'direct':不使用 -s 標誌(建議用於 JXA,也是 auto 模式下 JXA 的行為)。
include_executed_script_in_output (布爾值,可選,默認值: false):如果為 true,輸出將包括完整的腳本內容(對於知識庫腳本,在進行任何佔位符替換後)或執行的腳本路徑。這將作為輸出內容數組中的額外文本部分添加。
include_substitution_logs (布爾值,可選,默認值: false):如果為 true,知識庫腳本上執行的佔位符替換的詳細日誌將包含在輸出中。這對於調試 input_data 和 arguments 如何處理和插入腳本非常有用。日誌在成功時會添加到腳本輸出之前,失敗時會添加到錯誤消息之後。
report_execution_time (布爾值,可選,默認值: false):如果為 true,響應內容數組中將包含一條格式化的腳本執行時間的額外消息。
- 安全警告與 macOS 權限:(與之前關於任意腳本執行和 macOS 自動化/輔助功能權限的關鍵警告相同)
- 響應格式:
execute_script 工具返回的響應格式如下:
{
content: Array<{
type: 'text';
text: string;
}>;
isError?: boolean;
}
- `content`:包含腳本輸出的文本內容項數組。
- `isError` (布爾值,可選):當腳本執行產生錯誤時設置為 `true`。當滿足以下條件時設置此標誌:
- 腳本輸出(標準輸出)以 "Error" 開頭(不區分大小寫)。
- 這有助於客戶端在不解析輸出文本的情況下輕鬆確定執行是否失敗。
2. get_scripting_tips
從服務器的知識庫中檢索 AppleScript/JXA 提示、示例和可運行腳本的詳細信息。對於發現可用腳本、其功能以及如何使用 execute_script(特別是 kb_script_id)非常有用。
- 參數:
list_categories (布爾值,可選,默認值: false):如果為 true,僅返回可用知識庫類別的列表及其描述。會覆蓋其他參數。
category (字符串,可選):按特定類別 ID(例如,"finder"、"safari")過濾提示。
search_term (字符串,可選):在提示標題、描述、腳本內容、關鍵字或 ID 中搜索關鍵字。
refresh_database (布爾值,可選,默認值: false):如果為 true,在處理請求之前強制從磁盤重新加載整個知識庫。這在開發過程中非常有用,如果你正在積極修改知識庫文件並希望確保使用的是最新版本,而無需重啟服務器。
limit (整數,可選,默認值: 10):返回的最大結果數。
- 輸出:
返回一個 Markdown 格式的字符串,包含請求的提示,包括其標題、描述、腳本內容、語言、可運行 ID(如果適用)、參數提示和註釋。
關鍵用例與示例
應用程序控制
{ "input": { "script_content": "tell application \"Safari\" to get URL of front document" } }
{ "input": { "script_content": "tell application \"Mail\" to get subject of messages of inbox whose read status is false" } }
文件系統操作
{ "input": { "script_content": "tell application \"Finder\" to get name of every item of desktop" } }
{ "input": { "script_content": "tell application \"Finder\" to make new folder at desktop with properties {name:\"My New Folder\"}" } }
系統交互
{ "input": { "script_content": "display notification \"Important Update!\" with title \"System Alert\"" } }
{ "input": { "script_content": "set volume output volume 50" } }
{ "input": { "script_content": "the clipboard" } }
故障排除
- 權限錯誤:如果腳本無法控制應用程序或執行 UI 操作,請在系統設置中仔細檢查運行 MCP 服務器的應用程序(例如,終端)的自動化和輔助功能權限。
- 腳本語法錯誤:
osascript 錯誤將在 stderr 或錯誤消息中返回。請先使用腳本編輯器(對於 AppleScript)或 JXA 運行器在本地測試複雜腳本。
- 超時問題:如果腳本執行時間超過
timeout_seconds(默認 60 秒),它將被終止。對於長時間運行的腳本,請增加超時時間。
- 文件未找到:確保
script_path 是運行 MCP 服務器的用戶可以訪問的絕對 POSIX 路徑。
- 輸出不正確/JXA 問題:對於 JXA 腳本,特別是那些使用 Objective-C 橋接的腳本,請確保
output_format_mode 設置為 'direct' 或 'auto'(默認)。對 JXA 使用 AppleScript 特定的格式化標誌(如 human_readable)可能會導致錯誤。如果 AppleScript 輸出解析不正確,請嘗試 structured_output_and_error 或 structured_error。
通過環境變量進行配置
LOG_LEVEL:設置服務器的日誌級別。
- 值:
DEBUG、INFO、WARN、ERROR
- 示例:
LOG_LEVEL=DEBUG npx @steipete/macos-automator-mcp@latest
KB_PARSING:控制知識庫(腳本提示)的解析時間。
- 值:
lazy(默認):在首次請求 get_scripting_tips 或在 execute_script 中使用 kb_script_id 時解析知識庫。這允許服務器更快啟動。
eager:在服務器啟動時解析知識庫。這可能會略微增加啟動時間,但確保知識庫立即可用,並能儘早捕獲任何解析錯誤。
- 示例(通過
start.sh 或類似方式運行時):
KB_PARSING=eager ./start.sh
- 示例(通過支持 `env` 的 MCP 運行器配置時,如 `mcp-agentify`):
{
"env": {
"LOG_LEVEL": "INFO",
"KB_PARSING": "eager"
}
}
本地知識庫
你可以使用自己的本地提示和共享處理程序來補充內置知識庫。創建一個與本倉庫中的 knowledge_base 相同的目錄結構(或其子集)。
默認情況下,應用程序將在 ~/.macos-automator/knowledge_base 中查找此本地知識庫。你可以通過設置 LOCAL_KB_PATH 環境變量來自定義此路徑。
示例
假設你在 /Users/yourname/my-custom-kb 有一個本地知識庫。設置環境變量:
export LOCAL_KB_PATH=/Users/yourname/my-custom-kb
或者,如果你正在運行驗證腳本,可以使用 --local-kb-path 參數:
npm run validate:kb -- --local-kb-path /Users/yourname/my-custom-kb
結構和覆蓋規則
- 你的本地知識庫應與主
knowledge_base 的類別結構一致(例如,01_applescript_core、05_web_browsers/safari 等)。
- 你可以添加新的
.md 提示文件或 _shared_handlers(例如,.applescript 或 .js 文件)。
- 如果本地知識庫中的提示 ID(無論是來自前元數據
id: 還是從文件名/路徑生成)與嵌入式知識庫中的 ID 匹配,你的本地版本將覆蓋嵌入式版本。
- 類似地,本地
_shared_handlers 目錄中具有相同名稱和語言的共享處理程序(例如,my_utility.applescript)將覆蓋同一類別中(或如果你將它們放在本地知識庫的 _shared_handlers 根目錄中,則全局覆蓋)具有相同名稱和語言的任何嵌入式處理程序。
- 本地知識庫中
_category_info.md 的類別描述也可以覆蓋嵌入式知識庫中同一類別的描述。
這允許你在不修改核心應用程序文件的情況下個性化和擴展可用的自動化腳本和提示。
自動化能力
此服務器通過 AppleScript 和 JavaScript for Automation (JXA) 提供強大的 macOS 自動化功能。以下是一些最有用的示例:
終端自動化
{ "input": { "kb_script_id": "terminal_app_run_command_new_tab", "input_data": { "command": "ls -la" } } }
- 使用 sudo 執行命令並安全提供密碼
- 捕獲命令輸出以進行處理
瀏覽器控制
{ "input": { "kb_script_id": "chrome_open_url_new_tab_profile", "input_data": { "url": "https://example.com", "profile_name": "Default" } } }
{ "input": { "kb_script_id": "safari_get_front_tab_url" } }
{ "input": { "kb_script_id": "chrome_execute_javascript", "input_data": { "javascript_code": "document.title" } } }
- 提取頁面內容、操作表單和自動化工作流
- 截取網頁截圖
系統交互
{ "input": { "kb_script_id": "systemsettings_toggle_dark_mode_ui" } }
{ "input": { "kb_script_id": "system_clipboard_get_file_paths" } }
文件操作
{ "input": { "kb_script_id": "finder_create_new_folder_desktop", "input_data": { "folder_name": "My Project" } } }
{ "input": { "kb_script_id": "fileops_read_text_file", "input_data": { "file_path": "~/Documents/notes.txt" } } }
應用程序集成
{ "input": { "kb_script_id": "calendar_create_event", "input_data": { "title": "Meeting", "start_date": "2023-06-01 10:00", "end_date": "2023-06-01 11:00" } } }
{ "input": { "kb_script_id": "mail_send_email_direct", "input_data": { "recipient": "user@example.com", "subject": "Hello", "body_content": "Message content" } } }
{ "input": { "kb_script_id": "music_playback_controls", "input_data": { "action": "play" } } }
- 與創意應用程序(Keynote、Pages、Numbers)協作
使用 get_scripting_tips 工具按類別探索所有可用的自動化功能。
🔧 技術細節
本項目的知識庫採用懶加載機制,在首次使用時進行解析,以實現服務器的快速啟動。服務器使用 Node.js 運行,通過 osascript 命令執行 AppleScript 和 JXA 腳本。在處理腳本時,會根據不同的參數設置(如 output_format_mode)控制 osascript 的輸出格式,以滿足不同的需求。同時,服務器支持通過環境變量進行配置,如 LOG_LEVEL 和 KB_PARSING,以靈活控制日誌級別和知識庫解析時間。
📄 許可證
本項目採用 MIT 許可證。詳情請參閱 LICENSE 文件。