关于 JCAppleScript
JCAppleScript 是一个 Swift 包,用于在 macOS 应用中执行 AppleScript,并内置 jcas-mcp MCP 服务,让 AI 助手通过预置命令控制 Messages、Mail、Finder 等应用。项目强调对参数进行清理,并提供安全模式以限制任意代码执行。
主要功能
- 01执行原始 AppleScript 与 JXA 代码
- 02内置多个 macOS 应用的预置命令
- 03参数在生成脚本前进行转义与校验
- 04JCAS_SAFE_MODE 模式可禁用任意代码工具
- 05支持通过 JSON 清单加载社区应用定义
适用场景
- 01让 AI 助手通过预置命令发送信息或管理提醒事项
- 02在 Swift 应用中嵌入 AppleScript 执行与应用命令注册表
- 03在执行前使用 preview_app_command 检查将要运行的脚本
MCP 相关
jcas-mcp 是 MCP 服务,向 MCP 客户端暴露 execute_applescript、run_app_command、preview_app_command 等 10 个工具。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
JCAppleScript
一个用于从 macOS 应用执行 AppleScript 的 Swift 软件包,内置 MCP 服务,可让 AI 助手通过预构建的命令快捷方式控制 macOS 应用。
概览
JCAppleScript 包含三个组件:
- JCAppleScript(库)- 核心 AppleScript 执行引擎
- AppShortcuts(库)- 为常见 macOS 应用提供预构建 AppleScript 命令的注册表
- jcas-mcp(可执行程序)- 用于 AI 驱动应用自动化的 MCP(Model Context Protocol)服务
安装
Swift Package Manager
将 JCAppleScript 添加到你的 Package.swift:
dependencies: [
.package(url: "https://github.com/johnnyclem/JCAppleScript.git", from: "2.0.0")
]
然后添加你需要的目标:
.target(
name: "YourTarget",
dependencies: [
"JCAppleScript", // Core engine only
"AppShortcuts", // App command registry
]
)
快速入门
使用核心引擎
import JCAppleScript
let engine = AppleScriptEngine.shared
// Execute raw AppleScript
let result = try engine.execute("""
tell application "Finder"
display dialog "Hello from Swift!"
end tell
""")
// Send a command to an application
let output = try engine.tell(application: "Music", command: "play")
// Execute a script file with variable substitution
let fileResult = try engine.executeFile(at: "/path/to/script.scpt", variables: ["Alice", "Hello!"])
// Execute JavaScript for Automation (JXA)
let jxa = try engine.execute("Application('Music').play()", language: .javaScript)
// Check syntax without executing
try engine.checkSyntax("tell application \"Finder\" to activate")
// All execution APIs also have async variants
let asyncResult = try await engine.execute("return 40 + 2")
在脚本源码中嵌入不可信值时,请先对其进行转义:
let userInput = "…"
let script = "display dialog \(AppleScriptString.quoted(userInput))"
使用应用快捷方式
import AppShortcuts
let registry = AppRegistry.shared
// Execute a pre-built command
let result = try registry.executeCommand("messages.send_message", arguments: [
"recipient": "+15551234567",
"message": "Hello from JCAppleScript!"
])
// Discover available commands
let commands = registry.commands(forApp: "Reminders")
for cmd in commands {
print("\(cmd.id): \(cmd.name) - \(cmd.description)")
}
// Search across all apps
let results = registry.searchCommands("send")
使用 MCP 服务
jcas-mcp 可执行程序是一个 Model Context Protocol 服务,AI 助手(Claude、GPT 等)可使用它控制 macOS 应用。
它已发布到 官方 MCP 注册表,名称为 io.github.johnnyclem/jcas-mcp;每个 GitHub 版本都会提供预构建的 jcas-mcp.mcpb 软件包(通用 macOS 二进制文件),可通过“设置”→“扩展”直接安装到 Claude Desktop。
在 Claude Desktop 中设置
将以下内容添加到你的 Claude Desktop 配置文件(~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"applescript": {
"command": "/path/to/jcas-mcp"
}
}
}
构建服务:
swift build -c release
# Binary at: .build/release/jcas-mcp
可用的 MCP 工具
| 工具 | 描述 |
|---|---|
execute_applescript | 执行任意 AppleScript 代码 † |
execute_jxa | 执行 JavaScript for Automation(JXA)代码 † |
tell_application | 通过 tell 代码块向指定应用发送命令 † |
check_script_syntax | 编译脚本(AppleScript 或 JXA),但不执行 |
list_running_applications | 获取当前正在运行的应用 |
list_registered_apps | 浏览所有已注册的应用命令表 |
search_commands | 按关键字搜索命令 |
run_app_command | 按 ID 执行预构建命令 |
preview_app_command | 试运行:显示命令将执行的确切脚本 |
get_app_commands | 获取指定应用的详细命令信息 |
† 服务以安全模式运行时,这些工具会被隐藏并禁用(见下文)。
服务配置
| 环境变量 | 作用 |
|---|---|
JCAS_SAFE_MODE=1 | 禁用任意代码工具(execute_applescript、execute_jxa、tell_application)以及标记为 dangerous 的注册表命令(例如 terminal.run_command、safari.run_javascript)。只有预构建且经过清理的注册表命令仍可用。 |
JCAS_APP_MANIFESTS=a.json:b.json | 以冒号分隔的 JSON 清单文件,其中包含启动时加载的其他社区应用定义。 |
CLI 标志:jcas-mcp --manifest 以 JSON 格式打印完整注册表,--version 打印服务版本,--help 显示用法。
AI 交互示例
User: "Send a message to John saying I'll be late"
AI uses tool: run_app_command
command_id: "messages.send_message"
arguments: { "recipient": "John", "message": "I'll be late" }
支持的应用
JCAppleScript 内置了 12 款 macOS 应用的命令表:
| 应用 | 类别 | 命令数 | 示例 |
|---|---|---|---|
| Messages | 通信 | 6 | 发送消息、列出聊天、获取参与者 |
| 通信 | 7 | 撰写邮件、搜索、检查邮件、列出账户 | |
| Reminders | 效率 | 7 | 创建/完成/删除提醒事项、搜索、列出 |
| Calendar | 效率 | 6 | 创建事件、列出今天的事件、查看即将发生的事件 |
| Notes | 效率 | 8 | 创建/搜索/追加笔记、管理文件夹 |
| Finder | 系统 | 12 | 文件操作、文件夹内容、标签、废纸篓 |
| Safari | 互联网 | 10 | 打开 URL、管理标签页、运行 JavaScript、获取页面内容 |
| Music | 媒体 | 13 | 播放控制、播放列表、资料库搜索、评分 |
| Terminal | 开发 | 8 | 运行命令、管理窗口/标签页、配置文件 |
| System Settings | 系统 | 13 | 深色模式、音量、通知、对话框、系统信息 |
| Xcode | 开发 | 20+ | 打开/构建/运行/测试项目、方案、构建日志、调试 |
| Speech Recognition | 系统 | 3 | 通过系统语音引擎监听语音短语 |
添加自定义应用支持
实现 ScriptableApp 协议,即可添加对任何支持脚本控制的 macOS 应用的支持:
import AppShortcuts
struct MyApp: ScriptableApp {
static let bundleIdentifier = "com.example.myapp"
static let appName = "MyApp"
static let description = "My custom application"
static let category = AppCategory.productivity
static let commands: [AppCommand] = [
AppCommand(
id: "myapp.do_thing",
name: "Do Thing",
description: "Performs the thing",
parameters: [
CommandParameter(name: "input", description: "The input value"),
]
) { args in
let input = args["input", default: ""]
return """
tell application "MyApp"
do thing with "\(input)"
end tell
"""
},
]
}
// Register at runtime
AppRegistry.shared.register(MyApp.self)
社区应用注册表
JCAppleScript 致力于通过社区贡献不断发展。应用快捷方式系统使用标准协议(ScriptableApp),便于:
- 添加新应用 - 为任何支持脚本控制的 macOS 应用实现
ScriptableApp - 扩展现有应用 - 为已注册的应用提交新命令
- 共享命令表 - 通过 JSON 清单导出/导入应用定义
我们正在构建一个可浏览的注册表(类似于 npmjs.org),你可以在其中:
- 浏览应用及其支持的 AppleScript 命令
- 为现有应用提交新命令
- 向注册表添加全新应用
- 生成用于与其他工具集成的 JSON 清单
导出和导入注册表
// Export all registered apps as manifest JSON
let json = try AppRegistry.shared.exportManifestJSON()
// Import community app definitions from a JSON manifest.
// Manifest commands are declarative script templates with ${param}
// placeholders; argument values are sanitized before substitution.
try AppRegistry.shared.loadManifest(contentsOf: URL(fileURLWithPath: "community.json"))
清单示例:
[
{
"name": "CoolApp",
"bundleIdentifier": "com.example.coolapp",
"description": "A community-contributed app",
"category": "Productivity",
"commands": [
{
"id": "coolapp.greet",
"name": "Greet",
"description": "Show a greeting",
"script": "tell application \"CoolApp\"\n greet \"${who}\"\nend tell",
"parameters": [
{"name": "who", "description": "Who to greet", "required": true, "type": "string"}
]
}
]
}
]
MCP 服务会在启动时从 JCAS_APP_MANIFESTS 环境变量加载额外的清单。
安全模型
注册表命令参数会在生成脚本前进行清理:
- 字符串、文件路径和日期参数会进行转义(
\、"和控制字符),以防止其突破 AppleScript 字符串字面量。 - 整数和布尔参数会经过严格验证/规范化——格式错误的值会在验证时被拒绝,并在生成时回退到声明的默认值。
- 超出参数
allowedValues列表范围的值会被丢弃。 - 与已声明参数不对应的参数会被丢弃。
执行调用方提供代码的命令(Terminal shell 命令、Safari JavaScript)会标记为 dangerous,并可通过 JCAS_SAFE_MODE=1 一并禁用。执行命令前,请使用 preview_app_command 工具检查该命令将运行的确切脚本。
请注意,execute_applescript、execute_jxa 和 tell_application 本就会执行任意代码——仅向你信任的客户端开放这些工具,或在安全模式下运行服务。
架构
JCAppleScript/
├── Sources/
│ ├── JCAppleScript/ # Core engine
│ │ ├── AppleScriptEngine.swift
│ │ ├── AppleScriptSanitizer.swift
│ │ ├── ScriptResult.swift
│ │ └── ScriptError.swift
│ ├── AppShortcuts/ # App command registry
│ │ ├── AppProtocol.swift # ScriptableApp protocol
│ │ ├── AppCommand.swift # Command & parameter types + sanitization
│ │ ├── AppDefinition.swift # Instance-based app description
│ │ ├── AppManifest.swift # JSON import/export
│ │ ├── AppRegistry.swift # Central registry
│ │ └── Apps/ # Built-in app sheets
│ │ ├── MessagesApp.swift
│ │ ├── RemindersApp.swift
│ │ ├── FinderApp.swift
│ │ ├── SafariApp.swift
│ │ ├── MailApp.swift
│ │ ├── CalendarApp.swift
│ │ ├── NotesApp.swift
│ │ ├── MusicApp.swift
│ │ ├── TerminalApp.swift
│ │ └── SystemSettingsApp.swift
│ └── JCAppleScriptMCP/ # MCP server
│ ├── main.swift
│ ├── MCPServer.swift
│ ├── MCPTransport.swift
│ └── MCPTypes.swift
├── Tests/
├── Legacy/ # Original Obj-C implementation
├── Package.swift
└── LICENSE
要求
- macOS 13.0+
- Swift 5.9+
旧版实现
原始 Objective-C 实现(2013 年)保存在 Legacy/ 目录中,供参考。它提供了基于变量替换的基本 NSAppleScript 封装。新的 Swift 实现基于这些概念构建,并加入了 MCP 服务、应用注册表和现代 Swift 编程模式。
许可证
MIT 许可证 - 版权所有 (c) 2013 John Clem。详情请参阅 LICENSE。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。