本项目提供了一个模型上下文协议(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 # 确保安装依赖
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,它将成为发布包的入口点。
package.json 中的 engines 字段)。docs/automation-permissions-example.png(占位图像)。以下是一些使用 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"
}
}
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。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,响应内容数组中将包含一条格式化的脚本执行时间的额外消息。execute_script 工具返回的响应格式如下:{
content: Array<{
type: 'text';
text: string;
}>;
isError?: boolean;
}
- `content`:包含脚本输出的文本内容项数组。
- `isError` (布尔值,可选):当脚本执行产生错误时设置为 `true`。当满足以下条件时设置此标志:
- 脚本输出(标准输出)以 "Error" 开头(不区分大小写)。
- 这有助于客户端在不解析输出文本的情况下轻松确定执行是否失败。
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):返回的最大结果数。{ "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" } }
osascript 错误将在 stderr 或错误消息中返回。请先使用脚本编辑器(对于 AppleScript)或 JXA 运行器在本地测试复杂脚本。timeout_seconds(默认 60 秒),它将被终止。对于长时间运行的脚本,请增加超时时间。script_path 是运行 MCP 服务器的用户可以访问的绝对 POSIX 路径。output_format_mode 设置为 'direct' 或 'auto'(默认)。对 JXA 使用 AppleScript 特定的格式化标志(如 human_readable)可能会导致错误。如果 AppleScript 输出解析不正确,请尝试 structured_output_and_error 或 structured_error。LOG_LEVEL:设置服务器的日志级别。
DEBUG、INFO、WARN、ERRORLOG_LEVEL=DEBUG npx @steipete/macos-automator-mcp@latestKB_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 匹配,你的本地版本将覆盖嵌入式版本。_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" } } }
{ "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" } } }
使用 get_scripting_tips 工具按类别探索所有可用的自动化功能。
本项目的知识库采用懒加载机制,在首次使用时进行解析,以实现服务器的快速启动。服务器使用 Node.js 运行,通过 osascript 命令执行 AppleScript 和 JXA 脚本。在处理脚本时,会根据不同的参数设置(如 output_format_mode)控制 osascript 的输出格式,以满足不同的需求。同时,服务器支持通过环境变量进行配置,如 LOG_LEVEL 和 KB_PARSING,以灵活控制日志级别和知识库解析时间。
本项目采用 MIT 许可证。详情请参阅 LICENSE 文件。