omnifocus-mcp-enhanced 1.1.0

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.
@@ -0,0 +1,18 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "WebFetch(domain:github.com)",
5
+ "WebFetch(domain:discourse.omnigroup.com)",
6
+ "Bash(npm run build:*)",
7
+ "Bash(npx tsc:*)",
8
+ "Bash(npm install)",
9
+ "Bash(node:*)",
10
+ "Bash(osascript:*)",
11
+ "Bash(claude mcp:*)",
12
+ "Bash(chmod:*)",
13
+ "Bash(npm pack:*)",
14
+ "Bash(./publish.sh:*)"
15
+ ],
16
+ "deny": []
17
+ }
18
+ }
package/CLAUDE.md ADDED
@@ -0,0 +1,280 @@
1
+ # OmniFocus MCP Enhanced - Claude Code 使用指南
2
+
3
+ 这是一个增强版的 OmniFocus MCP 服务器,新增了完整的子任务功能支持。
4
+
5
+ ## 🚀 新功能特性
6
+
7
+ ### ✨ 子任务功能
8
+ - **通过父任务ID创建子任务**
9
+ - **通过父任务名称创建子任务**
10
+ - **专门的子任务创建工具**
11
+ - **批量子任务创建支持**
12
+ - **完整的任务层级管理**
13
+
14
+ ### 🛠 新增工具
15
+ 1. **`add_subtask`** - 专门的子任务创建工具
16
+ 2. **`get_task_by_id`** - 任务信息查询工具
17
+ 3. **增强的 `add_omnifocus_task`** - 支持父任务参数
18
+ 4. **增强的 `batch_add_items`** - 支持批量创建子任务
19
+
20
+ ## 📦 安装方式
21
+
22
+ ### 方式1:NPM 发布版本安装(推荐)
23
+
24
+ 如果已发布到 NPM:
25
+
26
+ ```bash
27
+ # 1. 移除原有的 OmniFocus MCP(如果有)
28
+ claude mcp remove omnifocus
29
+
30
+ # 2. 一键安装增强版
31
+ claude mcp add omnifocus-enhanced -- npx -y omnifocus-mcp-enhanced
32
+
33
+ # 3. 验证安装
34
+ claude mcp list
35
+ ```
36
+
37
+ **或者全局安装:**
38
+ ```bash
39
+ npm install -g omnifocus-mcp-enhanced
40
+ claude mcp add omnifocus-enhanced -- omnifocus-mcp-enhanced
41
+ ```
42
+
43
+ ### 方式2:本地项目安装
44
+
45
+ 如果你有项目源码:
46
+
47
+ ```bash
48
+ # 1. 移除原有的 OmniFocus MCP(如果有)
49
+ claude mcp remove omnifocus
50
+
51
+ # 2. 进入项目目录并构建
52
+ cd "/path/to/OmniFocus-MCP"
53
+ npm install
54
+ npm run build
55
+
56
+ # 3. 添加增强版 MCP
57
+ claude mcp add omnifocus-enhanced -- node "/path/to/OmniFocus-MCP/dist/server.js"
58
+
59
+ # 4. 验证安装
60
+ claude mcp list
61
+ ```
62
+
63
+ **实际安装命令示例:**
64
+ ```bash
65
+ claude mcp add omnifocus-enhanced -- node "/Users/zhangte/Library/Mobile Documents/iCloud~md~obsidian/Documents/obsidian-zhangte/1-当前项目/claude code-研究/MCPS/omnifocus_mcp/OmniFocus-MCP/dist/server.js"
66
+ ```
67
+
68
+ ### 方式3:多设备部署
69
+
70
+ 如果你要在其他 Mac 上使用:
71
+
72
+ ```bash
73
+ # 1. 打包项目(在原Mac上)
74
+ cd "/path/to/OmniFocus-MCP"
75
+ ./deploy.sh pack
76
+
77
+ # 2. 传输到新Mac并解压安装
78
+ # 将生成的 .tar.gz 文件传输到目标Mac
79
+ ./deploy.sh install omnifocus-mcp-enhanced-XXXXXXXX-XXXX.tar.gz
80
+ ```
81
+
82
+ ### 方式4:使用 CLI 脚本
83
+
84
+ ```bash
85
+ claude mcp add omnifocus-enhanced -- "/path/to/OmniFocus-MCP/cli.cjs"
86
+ ```
87
+
88
+ ## 🚀 发布到 NPM
89
+
90
+ 如果你想发布到 NPM 供其他人使用:
91
+
92
+ ### 发布步骤
93
+
94
+ ```bash
95
+ # 1. 检查发布准备状态
96
+ ./publish.sh check
97
+
98
+ # 2. 更新版本(可选)
99
+ ./publish.sh version patch # 或 minor, major
100
+
101
+ # 3. 发布到 NPM
102
+ ./publish.sh release
103
+ ```
104
+
105
+ ### 发布前准备
106
+
107
+ 1. **注册 NPM 账号** - https://www.npmjs.com/signup
108
+ 2. **登录 NPM**:
109
+ ```bash
110
+ npm login
111
+ ```
112
+ 3. **更新个人信息**:
113
+ - 修改 `package.json` 中的 `author` 信息
114
+ - 修改 `repository` URL 为你的 GitHub 仓库
115
+ 4. **确保包名唯一**:
116
+ - 检查 NPM 是否已有同名包
117
+ - 必要时修改 `package.json` 中的 `name`
118
+
119
+ ### 发布后使用
120
+
121
+ 发布成功后,用户可以通过以下命令安装:
122
+
123
+ ```bash
124
+ # 一键安装
125
+ claude mcp add omnifocus-enhanced -- npx -y your-package-name
126
+
127
+ # 或全局安装
128
+ npm install -g your-package-name
129
+ claude mcp add omnifocus-enhanced -- your-package-name
130
+ ```
131
+
132
+ ## 🎯 使用方法
133
+
134
+ ### 1. 创建子任务
135
+
136
+ #### 方法A:使用增强的 add_omnifocus_task
137
+ ```bash
138
+ # 通过父任务ID创建子任务
139
+ add_omnifocus_task {
140
+ "name": "分析竞争对手关键词",
141
+ "parentTaskId": "loK2xEAY4H1",
142
+ "note": "重点分析前10名竞争对手的关键词策略",
143
+ "dueDate": "2025-01-15",
144
+ "estimatedMinutes": 120,
145
+ "tags": ["SEO", "研究"]
146
+ }
147
+
148
+ # 通过父任务名称创建子任务
149
+ add_omnifocus_task {
150
+ "name": "制定内容发布计划",
151
+ "parentTaskName": "内容策略优化",
152
+ "flagged": true,
153
+ "estimatedMinutes": 60
154
+ }
155
+ ```
156
+
157
+ #### 方法B:使用专门的 add_subtask 工具
158
+ ```bash
159
+ add_subtask {
160
+ "name": "撰写SEO文章大纲",
161
+ "parentTaskName": "内容策略优化",
162
+ "note": "针对目标关键词撰写10篇文章大纲",
163
+ "dueDate": "2025-01-20",
164
+ "tags": ["内容", "写作"]
165
+ }
166
+ ```
167
+
168
+ ### 2. 批量创建任务和子任务
169
+
170
+ ```bash
171
+ batch_add_items {
172
+ "items": [
173
+ {
174
+ "type": "task",
175
+ "name": "网站技术优化",
176
+ "projectName": "谷歌SEO起量",
177
+ "note": "优化网站技术层面的SEO"
178
+ },
179
+ {
180
+ "type": "task",
181
+ "name": "页面速度优化",
182
+ "parentTaskName": "网站技术优化",
183
+ "estimatedMinutes": 180,
184
+ "flagged": true
185
+ },
186
+ {
187
+ "type": "task",
188
+ "name": "移动端适配检查",
189
+ "parentTaskName": "网站技术优化",
190
+ "estimatedMinutes": 90
191
+ },
192
+ {
193
+ "type": "task",
194
+ "name": "结构化数据添加",
195
+ "parentTaskName": "网站技术优化",
196
+ "estimatedMinutes": 120
197
+ }
198
+ ]
199
+ }
200
+ ```
201
+
202
+ ### 3. 查询任务信息
203
+
204
+ ```bash
205
+ # 通过任务ID查询
206
+ get_task_by_id {
207
+ "taskId": "loK2xEAY4H1"
208
+ }
209
+
210
+ # 通过任务名称查询
211
+ get_task_by_id {
212
+ "taskName": "内容策略优化"
213
+ }
214
+ ```
215
+
216
+ ### 4. 查看项目结构
217
+
218
+ ```bash
219
+ # 获取完整的OmniFocus数据库状态
220
+ dump_database {
221
+ "hideCompleted": false,
222
+ "hideRecurringDuplicates": true
223
+ }
224
+ ```
225
+
226
+ ## ⚠️ 重要提示
227
+
228
+ ### 参数限制
229
+ - **不能同时指定** `parentTaskId` 和 `parentTaskName`
230
+ - **不能同时指定** 父任务参数和 `projectName`(子任务自动继承父任务的项目)
231
+ - **子任务工具必须提供** `parentTaskId` 或 `parentTaskName` 其中之一
232
+
233
+ ### 错误处理
234
+ - 父任务不存在时会返回清晰的错误信息
235
+ - AppleScript 执行失败时会提供详细的错误描述
236
+ - 参数冲突时会在调用前进行验证
237
+
238
+ ## 🔧 开发和调试
239
+
240
+ ### 重新构建
241
+ ```bash
242
+ cd "/path/to/OmniFocus-MCP"
243
+ npm run build
244
+ # 重启 Claude Code 以使用最新版本
245
+ ```
246
+
247
+ ### 查看日志
248
+ AppleScript 执行日志会输出到 `console.error`,可以通过 Claude Code 的调试模式查看。
249
+
250
+ ### 测试 AppleScript
251
+ ```bash
252
+ # 测试查找项目
253
+ osascript -e 'tell application "OmniFocus" to tell front document to name of first flattened project where name contains "SEO"'
254
+
255
+ # 测试创建任务
256
+ osascript -e 'tell application "OmniFocus" to tell front document to set theProject to first flattened project where name = "谷歌SEO起量" ...'
257
+ ```
258
+
259
+ ## 📋 完整工具列表
260
+
261
+ 1. **dump_database** - 获取OmniFocus数据库状态
262
+ 2. **add_omnifocus_task** - 创建任务(增强版,支持父任务)
263
+ 3. **add_project** - 创建项目
264
+ 4. **remove_item** - 删除任务或项目
265
+ 5. **edit_item** - 编辑任务或项目
266
+ 6. **batch_add_items** - 批量添加(增强版,支持子任务)
267
+ 7. **batch_remove_items** - 批量删除
268
+ 8. **add_subtask** - 专门创建子任务(新增)
269
+ 9. **get_task_by_id** - 查询任务信息(新增)
270
+
271
+ ## 🎉 版本信息
272
+
273
+ - **基础版本**: 1.0.9
274
+ - **增强版本**: 1.1.0-enhanced
275
+ - **新增功能**: 完整子任务支持
276
+ - **兼容性**: 完全向后兼容原有功能
277
+
278
+ ---
279
+
280
+ **享受更强大的 OmniFocus 任务管理体验!** 🚀
package/README.md ADDED
@@ -0,0 +1,168 @@
1
+ # OmniFocus MCP Enhanced
2
+
3
+ An enhanced Model Context Protocol (MCP) server for OmniFocus with complete subtask support and advanced task management features.
4
+
5
+ ## 🚀 Features
6
+
7
+ - **Complete Subtask Support** - Create subtasks by parent task ID or name
8
+ - **Advanced Task Management** - Enhanced task creation with parent-child relationships
9
+ - **Batch Operations** - Bulk create tasks and subtasks efficiently
10
+ - **Task Information Query** - Get detailed task information and hierarchy
11
+ - **Full Backward Compatibility** - All original features preserved
12
+
13
+ ## 📦 Installation
14
+
15
+ ### Quick Install with Claude Code
16
+
17
+ ```bash
18
+ claude mcp add omnifocus-enhanced -- npx -y omnifocus-mcp-enhanced
19
+ ```
20
+
21
+ ### Manual Installation
22
+
23
+ ```bash
24
+ npm install -g omnifocus-mcp-enhanced
25
+ claude mcp add omnifocus-enhanced -- omnifocus-mcp-enhanced
26
+ ```
27
+
28
+ ## 🎯 New Features
29
+
30
+ ### Subtask Creation
31
+
32
+ Create subtasks using the enhanced `add_omnifocus_task` tool:
33
+
34
+ ```json
35
+ {
36
+ "name": "Research competitor keywords",
37
+ "parentTaskName": "SEO Strategy",
38
+ "note": "Analyze top 10 competitors",
39
+ "dueDate": "2025-01-15",
40
+ "estimatedMinutes": 120,
41
+ "tags": ["SEO", "Research"]
42
+ }
43
+ ```
44
+
45
+ Or use the dedicated `add_subtask` tool:
46
+
47
+ ```json
48
+ {
49
+ "name": "Write content outline",
50
+ "parentTaskId": "task-id-12345",
51
+ "flagged": true,
52
+ "estimatedMinutes": 60
53
+ }
54
+ ```
55
+
56
+ ### Batch Subtask Creation
57
+
58
+ Create multiple tasks and subtasks in one operation:
59
+
60
+ ```json
61
+ {
62
+ "items": [
63
+ {
64
+ "type": "task",
65
+ "name": "Website Optimization",
66
+ "projectName": "SEO Project"
67
+ },
68
+ {
69
+ "type": "task",
70
+ "name": "Page Speed Optimization",
71
+ "parentTaskName": "Website Optimization",
72
+ "estimatedMinutes": 180
73
+ },
74
+ {
75
+ "type": "task",
76
+ "name": "Mobile Responsiveness Check",
77
+ "parentTaskName": "Website Optimization",
78
+ "estimatedMinutes": 90
79
+ }
80
+ ]
81
+ }
82
+ ```
83
+
84
+ ### Task Information Query
85
+
86
+ Get detailed information about any task:
87
+
88
+ ```json
89
+ {
90
+ "taskId": "task-id-12345"
91
+ }
92
+ ```
93
+
94
+ ## 🛠 Available Tools
95
+
96
+ 1. **dump_database** - Get OmniFocus database state
97
+ 2. **add_omnifocus_task** - Create tasks (enhanced with subtask support)
98
+ 3. **add_project** - Create projects
99
+ 4. **remove_item** - Delete tasks or projects
100
+ 5. **edit_item** - Edit tasks or projects
101
+ 6. **batch_add_items** - Bulk add items (enhanced with subtask support)
102
+ 7. **batch_remove_items** - Bulk remove items
103
+ 8. **add_subtask** - Dedicated subtask creation (NEW)
104
+ 9. **get_task_by_id** - Query task information (NEW)
105
+
106
+ ## 📋 Requirements
107
+
108
+ - **macOS** - OmniFocus is macOS-only
109
+ - **OmniFocus 3+** - The application must be installed and running
110
+ - **Node.js 18+** - For running the MCP server
111
+ - **Claude Code** - For MCP integration
112
+
113
+ ## 🔧 Usage with Claude Code
114
+
115
+ After installation, you can use the enhanced features in Claude Code:
116
+
117
+ ```bash
118
+ # Create a subtask
119
+ add_subtask {
120
+ "name": "Design landing page mockup",
121
+ "parentTaskName": "Website Redesign",
122
+ "dueDate": "2025-01-20",
123
+ "tags": ["Design", "Web"]
124
+ }
125
+
126
+ # Get task details
127
+ get_task_by_id {
128
+ "taskName": "Website Redesign"
129
+ }
130
+
131
+ # Batch create with subtasks
132
+ batch_add_items {
133
+ "items": [
134
+ {
135
+ "type": "task",
136
+ "name": "Content Strategy",
137
+ "projectName": "Marketing Campaign"
138
+ },
139
+ {
140
+ "type": "task",
141
+ "name": "Keyword Research",
142
+ "parentTaskName": "Content Strategy"
143
+ }
144
+ ]
145
+ }
146
+ ```
147
+
148
+ ## 📖 Documentation
149
+
150
+ For detailed usage instructions, see [CLAUDE.md](./CLAUDE.md).
151
+
152
+ ## 🤝 Contributing
153
+
154
+ Contributions are welcome! Please feel free to submit a Pull Request.
155
+
156
+ ## 📄 License
157
+
158
+ MIT License - see LICENSE file for details.
159
+
160
+ ## 🔗 Links
161
+
162
+ - [OmniFocus](https://www.omnigroup.com/omnifocus/)
163
+ - [Model Context Protocol](https://modelcontextprotocol.io/)
164
+ - [Claude Code](https://docs.anthropic.com/en/docs/claude-code)
165
+
166
+ ## 🙏 Acknowledgments
167
+
168
+ Based on the original OmniFocus MCP server by [themotionmachine](https://github.com/themotionmachine/omnifocus-mcp-server).
Binary file
package/cli.cjs ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+ // cli.cjs
3
+ const path = require('path');
4
+ const childProcess = require('child_process');
5
+
6
+ const serverPath = path.join(__dirname, 'dist', 'server.js');
7
+ childProcess.spawn('node', ['--experimental-modules', serverPath], {
8
+ stdio: 'inherit'
9
+ });
@@ -0,0 +1,48 @@
1
+ // Core enums
2
+ export var Task;
3
+ (function (Task) {
4
+ let Status;
5
+ (function (Status) {
6
+ Status[Status["Available"] = 0] = "Available";
7
+ Status[Status["Blocked"] = 1] = "Blocked";
8
+ Status[Status["Completed"] = 2] = "Completed";
9
+ Status[Status["Dropped"] = 3] = "Dropped";
10
+ Status[Status["DueSoon"] = 4] = "DueSoon";
11
+ Status[Status["Next"] = 5] = "Next";
12
+ Status[Status["Overdue"] = 6] = "Overdue";
13
+ })(Status = Task.Status || (Task.Status = {}));
14
+ let RepetitionMethod;
15
+ (function (RepetitionMethod) {
16
+ RepetitionMethod[RepetitionMethod["DeferUntilDate"] = 0] = "DeferUntilDate";
17
+ RepetitionMethod[RepetitionMethod["DueDate"] = 1] = "DueDate";
18
+ RepetitionMethod[RepetitionMethod["Fixed"] = 2] = "Fixed";
19
+ RepetitionMethod[RepetitionMethod["None"] = 3] = "None";
20
+ })(RepetitionMethod = Task.RepetitionMethod || (Task.RepetitionMethod = {}));
21
+ })(Task || (Task = {}));
22
+ export var Project;
23
+ (function (Project) {
24
+ let Status;
25
+ (function (Status) {
26
+ Status[Status["Active"] = 0] = "Active";
27
+ Status[Status["Done"] = 1] = "Done";
28
+ Status[Status["Dropped"] = 2] = "Dropped";
29
+ Status[Status["OnHold"] = 3] = "OnHold";
30
+ })(Status = Project.Status || (Project.Status = {}));
31
+ })(Project || (Project = {}));
32
+ export var Folder;
33
+ (function (Folder) {
34
+ let Status;
35
+ (function (Status) {
36
+ Status[Status["Active"] = 0] = "Active";
37
+ Status[Status["Dropped"] = 1] = "Dropped";
38
+ })(Status = Folder.Status || (Folder.Status = {}));
39
+ })(Folder || (Folder = {}));
40
+ export var Tag;
41
+ (function (Tag) {
42
+ let Status;
43
+ (function (Status) {
44
+ Status[Status["Active"] = 0] = "Active";
45
+ Status[Status["Dropped"] = 1] = "Dropped";
46
+ Status[Status["OnHold"] = 2] = "OnHold";
47
+ })(Status = Tag.Status || (Tag.Status = {}));
48
+ })(Tag || (Tag = {}));
package/dist/server.js ADDED
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ // Import tool definitions
5
+ import * as dumpDatabaseTool from './tools/definitions/dumpDatabase.js';
6
+ import * as addOmniFocusTaskTool from './tools/definitions/addOmniFocusTask.js';
7
+ import * as addProjectTool from './tools/definitions/addProject.js';
8
+ import * as removeItemTool from './tools/definitions/removeItem.js';
9
+ import * as editItemTool from './tools/definitions/editItem.js';
10
+ import * as batchAddItemsTool from './tools/definitions/batchAddItems.js';
11
+ import * as batchRemoveItemsTool from './tools/definitions/batchRemoveItems.js';
12
+ import * as addSubtaskTool from './tools/definitions/addSubtask.js';
13
+ import * as getTaskByIdTool from './tools/definitions/getTaskById.js';
14
+ // Create an MCP server
15
+ const server = new McpServer({
16
+ name: "OmniFocus MCP",
17
+ version: "1.0.0"
18
+ });
19
+ // Register tools
20
+ server.tool("dump_database", "Gets the current state of your OmniFocus database", dumpDatabaseTool.schema.shape, dumpDatabaseTool.handler);
21
+ server.tool("add_omnifocus_task", "Add a new task to OmniFocus", addOmniFocusTaskTool.schema.shape, addOmniFocusTaskTool.handler);
22
+ server.tool("add_project", "Add a new project to OmniFocus", addProjectTool.schema.shape, addProjectTool.handler);
23
+ server.tool("remove_item", "Remove a task or project from OmniFocus", removeItemTool.schema.shape, removeItemTool.handler);
24
+ server.tool("edit_item", "Edit a task or project in OmniFocus", editItemTool.schema.shape, editItemTool.handler);
25
+ server.tool("batch_add_items", "Add multiple tasks or projects to OmniFocus in a single operation", batchAddItemsTool.schema.shape, batchAddItemsTool.handler);
26
+ server.tool("batch_remove_items", "Remove multiple tasks or projects from OmniFocus in a single operation", batchRemoveItemsTool.schema.shape, batchRemoveItemsTool.handler);
27
+ server.tool("add_subtask", "Add a new subtask to an existing task in OmniFocus", addSubtaskTool.schema.shape, addSubtaskTool.handler);
28
+ server.tool("get_task_by_id", "Get information about a specific task by ID or name", getTaskByIdTool.schema.shape, getTaskByIdTool.handler);
29
+ // Start the MCP server
30
+ const transport = new StdioServerTransport();
31
+ // Use await with server.connect to ensure proper connection
32
+ (async function () {
33
+ try {
34
+ console.error("Starting MCP server...");
35
+ await server.connect(transport);
36
+ console.error("MCP Server connected and ready to accept commands from Claude");
37
+ }
38
+ catch (err) {
39
+ console.error(`Failed to start MCP server: ${err}`);
40
+ }
41
+ })();
42
+ // For a cleaner shutdown if the process is terminated
@@ -0,0 +1,67 @@
1
+ import { z } from 'zod';
2
+ import { addOmniFocusTask } from '../primitives/addOmniFocusTask.js';
3
+ export const schema = z.object({
4
+ name: z.string().describe("The name of the task"),
5
+ note: z.string().optional().describe("Additional notes for the task"),
6
+ dueDate: z.string().optional().describe("The due date of the task in ISO format (YYYY-MM-DD or full ISO date)"),
7
+ deferDate: z.string().optional().describe("The defer date of the task in ISO format (YYYY-MM-DD or full ISO date)"),
8
+ flagged: z.boolean().optional().describe("Whether the task is flagged or not"),
9
+ estimatedMinutes: z.number().optional().describe("Estimated time to complete the task, in minutes"),
10
+ tags: z.array(z.string()).optional().describe("Tags to assign to the task"),
11
+ projectName: z.string().optional().describe("The name of the project to add the task to (will add to inbox if not specified)"),
12
+ parentTaskId: z.string().optional().describe("The ID of the parent task to create this task as a subtask"),
13
+ parentTaskName: z.string().optional().describe("The name of the parent task to create this task as a subtask (alternative to parentTaskId)")
14
+ });
15
+ export async function handler(args, extra) {
16
+ try {
17
+ // Call the addOmniFocusTask function
18
+ const result = await addOmniFocusTask(args);
19
+ if (result.success) {
20
+ // Task was added successfully
21
+ let locationText;
22
+ if (args.parentTaskId || args.parentTaskName) {
23
+ const parentRef = args.parentTaskId || args.parentTaskName;
24
+ locationText = `as a subtask of "${parentRef}"`;
25
+ }
26
+ else if (args.projectName) {
27
+ locationText = `in project "${args.projectName}"`;
28
+ }
29
+ else {
30
+ locationText = "in your inbox";
31
+ }
32
+ let tagText = args.tags && args.tags.length > 0
33
+ ? ` with tags: ${args.tags.join(', ')}`
34
+ : "";
35
+ let dueDateText = args.dueDate
36
+ ? ` due on ${new Date(args.dueDate).toLocaleDateString()}`
37
+ : "";
38
+ return {
39
+ content: [{
40
+ type: "text",
41
+ text: `✅ Task "${args.name}" created successfully ${locationText}${dueDateText}${tagText}.`
42
+ }]
43
+ };
44
+ }
45
+ else {
46
+ // Task creation failed
47
+ return {
48
+ content: [{
49
+ type: "text",
50
+ text: `Failed to create task: ${result.error}`
51
+ }],
52
+ isError: true
53
+ };
54
+ }
55
+ }
56
+ catch (err) {
57
+ const error = err;
58
+ console.error(`Tool execution error: ${error.message}`);
59
+ return {
60
+ content: [{
61
+ type: "text",
62
+ text: `Error creating task: ${error.message}`
63
+ }],
64
+ isError: true
65
+ };
66
+ }
67
+ }
@@ -0,0 +1,61 @@
1
+ import { z } from 'zod';
2
+ import { addProject } from '../primitives/addProject.js';
3
+ export const schema = z.object({
4
+ name: z.string().describe("The name of the project"),
5
+ note: z.string().optional().describe("Additional notes for the project"),
6
+ dueDate: z.string().optional().describe("The due date of the project in ISO format (YYYY-MM-DD or full ISO date)"),
7
+ deferDate: z.string().optional().describe("The defer date of the project in ISO format (YYYY-MM-DD or full ISO date)"),
8
+ flagged: z.boolean().optional().describe("Whether the project is flagged or not"),
9
+ estimatedMinutes: z.number().optional().describe("Estimated time to complete the project, in minutes"),
10
+ tags: z.array(z.string()).optional().describe("Tags to assign to the project"),
11
+ folderName: z.string().optional().describe("The name of the folder to add the project to (will add to root if not specified)"),
12
+ sequential: z.boolean().optional().describe("Whether tasks in the project should be sequential (default: false)")
13
+ });
14
+ export async function handler(args, extra) {
15
+ try {
16
+ // Call the addProject function
17
+ const result = await addProject(args);
18
+ if (result.success) {
19
+ // Project was added successfully
20
+ let locationText = args.folderName
21
+ ? `in folder "${args.folderName}"`
22
+ : "at the root level";
23
+ let tagText = args.tags && args.tags.length > 0
24
+ ? ` with tags: ${args.tags.join(', ')}`
25
+ : "";
26
+ let dueDateText = args.dueDate
27
+ ? ` due on ${new Date(args.dueDate).toLocaleDateString()}`
28
+ : "";
29
+ let sequentialText = args.sequential
30
+ ? " (sequential)"
31
+ : " (parallel)";
32
+ return {
33
+ content: [{
34
+ type: "text",
35
+ text: `✅ Project "${args.name}" created successfully ${locationText}${dueDateText}${tagText}${sequentialText}.`
36
+ }]
37
+ };
38
+ }
39
+ else {
40
+ // Project creation failed
41
+ return {
42
+ content: [{
43
+ type: "text",
44
+ text: `Failed to create project: ${result.error}`
45
+ }],
46
+ isError: true
47
+ };
48
+ }
49
+ }
50
+ catch (err) {
51
+ const error = err;
52
+ console.error(`Tool execution error: ${error.message}`);
53
+ return {
54
+ content: [{
55
+ type: "text",
56
+ text: `Error creating project: ${error.message}`
57
+ }],
58
+ isError: true
59
+ };
60
+ }
61
+ }