mcpField
O
OmniFocus

OmniFocus

本地服务
github.com/steveardis生产力29 周前更新

关于 OmniFocus

OmniFocus 是面向 macOS 用户的 MCP 服务,可让大模型管理 OmniFocus 数据。它通过 Omni Automation 提供任务、项目、文件夹和标签的读取及完整增删改操作,并以稳定 ID 定位实体。

主要功能

  1. 01读取任务、项目、文件夹和标签
  2. 02创建、编辑、完成及删除项目
  3. 03移动任务和项目
  4. 04管理日期、标签和重复规则
  5. 05将名称解析为稳定 ID 候选项

适用场景

  1. 01按项目、状态或截止日期查看任务
  2. 02创建并更新项目和任务
  3. 03用文件夹和标签整理任务
  4. 04修改数据前区分同名实体

MCP 相关

该服务向 MCP 客户端提供 OmniFocus 读取和写入工具。它通过 `osascript -l JavaScript` 在正在运行的 macOS OmniFocus 应用内执行 OmniJS 代码。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"steveardis-omnifocus": {
"command": "npx",
"args": [
"-y",
"@scardis/omnifocus-mcp"
]
}
}
}
启动命令npx -y @scardis/omnifocus-mcp

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npm@scardis/omnifocus-mcp0.2.1

工具

27

收录的工具列表 · 更新于 2 周前

参数类型必填说明
limitinteger否返回项目的最大数量。默认值为 100。
filterobject否可选筛选条件。所有字段按 AND 组合。未指定 status 时,默认排除已完成和已丢弃的项目。
filter.statusarray否
filter.flaggedboolean否
filter.folderIdstring否

详细介绍

omnifocus-mcp

一个面向 OmniFocus 的 MCP 服务,可向 LLM 调用方开放完整的 Omni Automation JavaScript API。

仅支持 macOS。 要求 OmniFocus 在同一台机器上运行。整个实现通过 osascript -l JavaScript 在 OmniFocus 内运行 OmniJS 片段——无需生成 AppleScript 字符串,也不受脚本字典限制。

先决条件

  • macOS(Omni Automation 仅支持 macOS;服务无法在其他平台上启动)
  • 已安装并且正在运行 OmniFocus
  • Node.js ≥ 20

安装

此软件包已发布到 npm,名称为 @scardis/omnifocus-mcp。

通过 npx(无需安装)

添加到 MCP 客户端配置中(例如 Claude Desktop 的 claude_desktop_config.json):

{
  "mcpServers": {
    "omnifocus": {
      "command": "npx",
      "args": ["-y", "@scardis/omnifocus-mcp"]
    }
  }
}
从源代码安装
git clone https://github.com/steveardis/omnifocus-mcp.git
cd omnifocus-mcp
npm install
npm run build

然后配置 MCP 客户端:

{
  "mcpServers": {
    "omnifocus": {
      "command": "node",
      "args": ["/absolute/path/to/omnifocus-mcp/dist/server.js"]
    }
  }
}

可用工具

读取
工具描述
list_projects列出项目,可按状态、folderId、是否标记进行筛选。默认不包含已完成或已放弃的项目。数量上限(默认 100)。
get_project根据稳定 ID 获取完整的项目详情
list_tasks列出任务,可按 projectId、folderId、inbox: true 或 all: true 指定范围,并可按状态、标签、到期时间、是否标记进行筛选。数量上限(默认 200)。
get_task根据稳定 ID 获取完整的任务详情,包括延后/计划/到期日期、标签、重复规则、parentTaskId
list_folders列出文件夹,可按状态筛选。数量上限(默认 200)。
get_folder根据稳定 ID 获取完整的文件夹详情,包括子文件夹和项目 ID
list_tags列出标签,可按状态筛选。数量上限(默认 200)。
get_tag根据稳定 ID 获取完整的标签详情,包括子标签 ID
resolve_name将名称解析为稳定 ID 候选项——绝不会静默消歧;返回所有匹配项
写入
工具描述
create_task在收件箱或项目中创建任务,或创建子任务。支持延后/计划/到期日期、标签、标记、预估分钟数和重复规则。
edit_task编辑任意任务字段。传入 null 可清除日期或重复规则。未提供的字段保持不变。
complete_task将任务标记为已完成
drop_task将任务标记为已放弃
delete_task永久删除任务及其所有子任务
create_project创建项目,可选择放入文件夹。支持类型、状态、复查间隔和标签。
edit_project编辑项目字段
complete_project将项目标记为已完成
drop_project将项目标记为已放弃
delete_project永久删除项目及其所有任务
create_folder创建文件夹,可选择嵌套放置
edit_folder重命名文件夹
delete_folder永久删除文件夹及其整个子树
create_tag创建标签,可选择嵌套放置
edit_tag编辑标签名称或状态
delete_tag永久删除标签及其子标签
move_task将任务移至某个项目,或设为另一任务的子任务
move_project将项目移至某个文件夹或顶层
寻址模型

此服务返回的每个实体都包含稳定的 id 字段(OmniFocus 的 id.primaryKey)。后续调用时请使用此 ID,而非名称。名称可能存在歧义;ID 不会。

如果知道名称但没有 ID,请使用 resolve_name。它会返回一个列表——如果返回多个候选项,请检查 path 字段,并在执行任何写入操作前让用户确认具体对象。

与其他 OmniFocus MCP 服务的比较

有两个值得关注的替代方案: themotionmachine/OmniFocus-MCP 和 jqlts1/omnifocus-mcp-enhanced(前者的一个分支,提供了额外的工具)。

脚本 API。 这些替代方案使用 JXA 脚本字典或 AppleScript 驱动 OmniFocus。本服务只进行一次 JXA 调用 — Application('OmniFocus').evaluateJavascript() — 并在 OmniFocus 内部以 OmniJS(Omni Automation)运行所有逻辑。这样即可使用完整的 Omni Automation API(重复规则、审核间隔、视图、预测、附件、URL 自动化等),而非功能更有限的脚本字典。

参数注入。 这些替代方案通过字符串插值构造 osascript 命令,名称中的撇号、引号、反斜杠和 Unicode 字符可能导致问题。本服务使用 JSON.stringify 将所有参数序列化为 JS 字面量。

实体寻址。 这些替代方案主要通过名称寻址实体。本服务会为每个实体返回稳定的 id(id.primaryKey),并提供 resolve_name 将名称映射为候选 ID — 返回包含完整路径的所有匹配项,而不会在名称有歧义时悄悄选取其中一个。

完整的 CRUD。 本服务支持创建、编辑、完成、放弃、删除和移动任务、项目、文件夹和标签 — 还支持重复规则以及 OmniFocus 4 的计划日期。

开发

# Type-check without building
npm run typecheck

# Run unit tests (no OmniFocus required)
npm test

# Build (compiles TypeScript and copies snippets into dist/)
npm run build

发布新版本的说明见 RELEASING.md。

测试

单元测试(无需 OmniFocus)
npm test
集成测试

⚠️ 集成测试会针对你的真实 OmniFocus 数据库运行。

每次测试运行都会创建一个名为 __MCP_TEST_<uuid>__ 的临时顶级文件夹,并在清理时将其删除。如果测试运行在清理前中断,请运行清理脚本:

npm run test:cleanup-fixtures

⚠️ 同步警告: 默认情况下,如果启用了 OmniFocus 同步,集成测试将拒绝运行,以防测试数据传播到你的其他设备。请先禁用 OmniFocus 同步,或设置 MCP_TEST_ALLOW_SYNC=1 选择加入(测试数据将会同步):

# Default (refuses if sync enabled)
npm run test:integration

# With sync enabled (use carefully)
MCP_TEST_ALLOW_SYNC=1 npm run test:integration
清理过期的测试数据
npm run test:cleanup-fixtures

此操作会从 OmniFocus 中移除所有 __MCP_TEST_*__ 文件夹,以及因测试运行中断而遗留的孤立 __mcp_*__ 项目/标签。

贡献

欢迎贡献!以下是开始的方法:

  1. 复刻并克隆仓库
  2. 安装依赖项: npm install
  3. 运行单元测试(无需 OmniFocus):npm test
  4. 运行集成测试(需要 macOS + OmniFocus):npm run test:integration
提交 PR 前
  • npm run typecheck — 必须通过,且无错误
  • npm test — 所有单元测试都必须通过
  • npm run test:integration — 所有集成测试都必须通过(仅限 macOS)
  • 修改范围应保持聚焦 — 每个 PR 只包含一项功能或修复
架构概览

服务通过 osascript -l JavaScript 在 OmniFocus 内部运行 OmniJS 代码片段。每个工具分为三层:

  • Schema(src/schemas/shapes.ts)— 用于输入验证和输出解析的 Zod schema
  • 代码片段(src/snippets/*.js)— 在 OmniFocus 内部运行的 OmniJS 代码。使用纯 ES5 JavaScript(无导入、无 TypeScript)。参数通过 __ARGS__ 占位符注入。
  • 工具处理器(src/tools/*.ts)— 验证输入、调用 runSnippet() 并解析结果

添加新工具时:

  1. 在 src/schemas/shapes.ts 中定义输入/输出 schema,并从 src/schemas/index.ts 导出
  2. 在 src/snippets/ 中创建 OmniJS 代码片段
  3. 将代码片段名称添加到 src/runtime/snippetLoader.ts 中的 ALLOWED_SNIPPETS
  4. 在 src/tools/ 中创建工具处理器,并在 src/tools/index.ts 中注册
  5. 为 schema 添加单元测试,并添加针对 OmniFocus 运行的集成测试
编写 OmniJS 代码片段

代码片段在 OmniFocus 的 JavaScript 运行时中运行,而非 Node.js。主要限制:

  • ES5 风格的 JavaScript — 使用 var、function(){};较旧版本的 OmniFocus 不支持箭头函数
  • 不使用导入 — 所有 OmniJS 全局变量(flattenedTasks、flattenedProjects、moveTasks 等)均可直接使用
  • 返回 JSON — 始终 return JSON.stringify({ ok: true, data: ... })
  • 错误模式 — 抛出命名错误(NotFoundError、ValidationError),由桥接程序捕获并封装

许可证

MIT

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。