@iflow-mcp/omnifocus-mcp 1.2.3 → 1.2.4
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.
- package/QUERY_TOOL_EXAMPLES.md +25 -2
- package/README.md +2 -2
- package/dist/tools/definitions/queryOmnifocus.js +12 -2
- package/dist/tools/primitives/queryOmnifocus.js +7 -3
- package/package.json +2 -2
- package/src/tools/definitions/queryOmnifocus.ts +18 -4
- package/src/tools/primitives/queryOmnifocus.ts +6 -3
package/QUERY_TOOL_EXAMPLES.md
CHANGED
|
@@ -91,6 +91,29 @@ The `query_omnifocus` tool provides efficient, targeted queries against your Omn
|
|
|
91
91
|
}
|
|
92
92
|
```
|
|
93
93
|
|
|
94
|
+
### Get tasks with notes
|
|
95
|
+
```json
|
|
96
|
+
{
|
|
97
|
+
"entity": "tasks",
|
|
98
|
+
"filters": {
|
|
99
|
+
"hasNote": true
|
|
100
|
+
},
|
|
101
|
+
"fields": ["name", "note", "projectName"]
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Get tasks without notes (for review)
|
|
106
|
+
```json
|
|
107
|
+
{
|
|
108
|
+
"entity": "tasks",
|
|
109
|
+
"filters": {
|
|
110
|
+
"hasNote": false,
|
|
111
|
+
"status": ["Available", "Next"]
|
|
112
|
+
},
|
|
113
|
+
"sortBy": "modificationDate"
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
94
117
|
## Performance Optimization
|
|
95
118
|
|
|
96
119
|
### Get only specific fields (reduces response size)
|
|
@@ -100,7 +123,7 @@ The `query_omnifocus` tool provides efficient, targeted queries against your Omn
|
|
|
100
123
|
"filters": {
|
|
101
124
|
"flagged": true
|
|
102
125
|
},
|
|
103
|
-
"fields": ["name", "dueDate", "projectName"],
|
|
126
|
+
"fields": ["name", "note", "dueDate", "projectName"],
|
|
104
127
|
"limit": 10
|
|
105
128
|
}
|
|
106
129
|
```
|
|
@@ -279,7 +302,7 @@ See what's in your inbox:
|
|
|
279
302
|
"filters": {
|
|
280
303
|
"projectName": "inbox"
|
|
281
304
|
},
|
|
282
|
-
"fields": ["name", "flagged", "dueDate", "tagNames"]
|
|
305
|
+
"fields": ["name", "note", "flagged", "dueDate", "tagNames"]
|
|
283
306
|
}
|
|
284
307
|
```
|
|
285
308
|
|
package/README.md
CHANGED
|
@@ -99,7 +99,7 @@ The server currently provides these tools:
|
|
|
99
99
|
Efficiently query your OmniFocus database with powerful filters. Get specific tasks, projects, or folders without loading the entire database.
|
|
100
100
|
|
|
101
101
|
Key Features:
|
|
102
|
-
- **Filter by multiple criteria**: project, tags, status, due dates, flags, and more
|
|
102
|
+
- **Filter by multiple criteria**: project, tags, status, due dates, flags, notes, and more
|
|
103
103
|
- **Request specific fields**: Reduce response size by only getting the data you need
|
|
104
104
|
- **Sort and limit results**: Control the output format
|
|
105
105
|
- **Much faster than dump_database** for targeted queries
|
|
@@ -115,7 +115,7 @@ Common Uses:
|
|
|
115
115
|
Parameters:
|
|
116
116
|
- `entity`: Type to query ('tasks', 'projects', or 'folders')
|
|
117
117
|
- `filters`: (Optional) Narrow results by project, tags, status, dates, etc.
|
|
118
|
-
- `fields`: (Optional) Specific fields to return (id, name, dueDate, etc.)
|
|
118
|
+
- `fields`: (Optional) Specific fields to return (id, name, note, dueDate, etc.)
|
|
119
119
|
- `limit`: (Optional) Maximum items to return
|
|
120
120
|
- `sortBy`: (Optional) Field to sort by
|
|
121
121
|
- `includeCompleted`: (Optional) Include completed items (default: false)
|
|
@@ -164,7 +164,12 @@ function formatTasks(tasks) {
|
|
|
164
164
|
if (task.completionDate) {
|
|
165
165
|
parts.push(`[completed: ${formatDate(task.completionDate)}]`);
|
|
166
166
|
}
|
|
167
|
-
|
|
167
|
+
let result = parts.join(' ');
|
|
168
|
+
// Add note on a new line if present
|
|
169
|
+
if (task.note) {
|
|
170
|
+
result += `\n Note: ${task.note}`;
|
|
171
|
+
}
|
|
172
|
+
return result;
|
|
168
173
|
}).join('\n');
|
|
169
174
|
}
|
|
170
175
|
function formatProjects(projects) {
|
|
@@ -174,7 +179,12 @@ function formatProjects(projects) {
|
|
|
174
179
|
const taskCount = project.taskCount !== undefined && project.taskCount !== null ? ` (${project.taskCount} tasks)` : '';
|
|
175
180
|
const flagged = project.flagged ? '🚩 ' : '';
|
|
176
181
|
const due = project.dueDate ? ` [due: ${formatDate(project.dueDate)}]` : '';
|
|
177
|
-
|
|
182
|
+
let result = `P: ${flagged}${project.name}${status}${due}${folder}${taskCount}`;
|
|
183
|
+
// Add note on a new line if present
|
|
184
|
+
if (project.note) {
|
|
185
|
+
result += `\n Note: ${project.note}`;
|
|
186
|
+
}
|
|
187
|
+
return result;
|
|
178
188
|
}).join('\n');
|
|
179
189
|
}
|
|
180
190
|
function formatFolders(folders) {
|
|
@@ -238,9 +238,9 @@ function generateFieldMapping(entity, fields) {
|
|
|
238
238
|
deferDate: formatDate(item.deferDate),
|
|
239
239
|
tagNames: item.tags ? item.tags.map(t => t.name) : [],
|
|
240
240
|
projectName: item.containingProject ? item.containingProject.name : (item.inInbox ? "Inbox" : null),
|
|
241
|
-
estimatedMinutes: item.estimatedMinutes || null
|
|
241
|
+
estimatedMinutes: item.estimatedMinutes || null,
|
|
242
|
+
note: item.note || ""
|
|
242
243
|
};
|
|
243
|
-
if (item.note && item.note.trim()) obj.note = item.note;
|
|
244
244
|
return obj;
|
|
245
245
|
`;
|
|
246
246
|
}
|
|
@@ -255,7 +255,8 @@ function generateFieldMapping(entity, fields) {
|
|
|
255
255
|
taskCount: taskArray.length,
|
|
256
256
|
flagged: item.flagged || false,
|
|
257
257
|
dueDate: formatDate(item.dueDate),
|
|
258
|
-
deferDate: formatDate(item.deferDate)
|
|
258
|
+
deferDate: formatDate(item.deferDate),
|
|
259
|
+
note: item.note || ""
|
|
259
260
|
};
|
|
260
261
|
`;
|
|
261
262
|
}
|
|
@@ -352,6 +353,9 @@ function generateFieldMapping(entity, fields) {
|
|
|
352
353
|
else if (field === 'estimatedMinutes') {
|
|
353
354
|
return `estimatedMinutes: item.estimatedMinutes || null`;
|
|
354
355
|
}
|
|
356
|
+
else if (field === 'note') {
|
|
357
|
+
return `note: item.note || ""`;
|
|
358
|
+
}
|
|
355
359
|
else {
|
|
356
360
|
// Default: try to access the field directly
|
|
357
361
|
return `${field}: item.${field} !== undefined ? item.${field} : null`;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@iflow-mcp/omnifocus-mcp",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.2.
|
|
4
|
+
"version": "1.2.4",
|
|
5
5
|
"description": "Model Context Protocol (MCP) server that integrates with OmniFocus for AI assistant interaction",
|
|
6
6
|
"main": "dist/server.js",
|
|
7
7
|
"bin": {
|
|
@@ -34,4 +34,4 @@
|
|
|
34
34
|
"ai"
|
|
35
35
|
],
|
|
36
36
|
"license": "MIT"
|
|
37
|
-
}
|
|
37
|
+
}
|
|
@@ -180,8 +180,15 @@ function formatTasks(tasks: any[]): string {
|
|
|
180
180
|
if (task.completionDate) {
|
|
181
181
|
parts.push(`[completed: ${formatDate(task.completionDate)}]`);
|
|
182
182
|
}
|
|
183
|
-
|
|
184
|
-
|
|
183
|
+
|
|
184
|
+
let result = parts.join(' ');
|
|
185
|
+
|
|
186
|
+
// Add note on a new line if present
|
|
187
|
+
if (task.note) {
|
|
188
|
+
result += `\n Note: ${task.note}`;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
return result;
|
|
185
192
|
}).join('\n');
|
|
186
193
|
}
|
|
187
194
|
|
|
@@ -192,8 +199,15 @@ function formatProjects(projects: any[]): string {
|
|
|
192
199
|
const taskCount = project.taskCount !== undefined && project.taskCount !== null ? ` (${project.taskCount} tasks)` : '';
|
|
193
200
|
const flagged = project.flagged ? '🚩 ' : '';
|
|
194
201
|
const due = project.dueDate ? ` [due: ${formatDate(project.dueDate)}]` : '';
|
|
195
|
-
|
|
196
|
-
|
|
202
|
+
|
|
203
|
+
let result = `P: ${flagged}${project.name}${status}${due}${folder}${taskCount}`;
|
|
204
|
+
|
|
205
|
+
// Add note on a new line if present
|
|
206
|
+
if (project.note) {
|
|
207
|
+
result += `\n Note: ${project.note}`;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return result;
|
|
197
211
|
}).join('\n');
|
|
198
212
|
}
|
|
199
213
|
|
|
@@ -293,9 +293,9 @@ function generateFieldMapping(entity: string, fields?: string[]): string {
|
|
|
293
293
|
deferDate: formatDate(item.deferDate),
|
|
294
294
|
tagNames: item.tags ? item.tags.map(t => t.name) : [],
|
|
295
295
|
projectName: item.containingProject ? item.containingProject.name : (item.inInbox ? "Inbox" : null),
|
|
296
|
-
estimatedMinutes: item.estimatedMinutes || null
|
|
296
|
+
estimatedMinutes: item.estimatedMinutes || null,
|
|
297
|
+
note: item.note || ""
|
|
297
298
|
};
|
|
298
|
-
if (item.note && item.note.trim()) obj.note = item.note;
|
|
299
299
|
return obj;
|
|
300
300
|
`;
|
|
301
301
|
} else if (entity === 'projects') {
|
|
@@ -309,7 +309,8 @@ function generateFieldMapping(entity: string, fields?: string[]): string {
|
|
|
309
309
|
taskCount: taskArray.length,
|
|
310
310
|
flagged: item.flagged || false,
|
|
311
311
|
dueDate: formatDate(item.dueDate),
|
|
312
|
-
deferDate: formatDate(item.deferDate)
|
|
312
|
+
deferDate: formatDate(item.deferDate),
|
|
313
|
+
note: item.note || ""
|
|
313
314
|
};
|
|
314
315
|
`;
|
|
315
316
|
} else if (entity === 'folders') {
|
|
@@ -380,6 +381,8 @@ function generateFieldMapping(entity: string, fields?: string[]): string {
|
|
|
380
381
|
return `path: item.container ? item.container.name + "/" + item.name : item.name`;
|
|
381
382
|
} else if (field === 'estimatedMinutes') {
|
|
382
383
|
return `estimatedMinutes: item.estimatedMinutes || null`;
|
|
384
|
+
} else if (field === 'note') {
|
|
385
|
+
return `note: item.note || ""`;
|
|
383
386
|
} else {
|
|
384
387
|
// Default: try to access the field directly
|
|
385
388
|
return `${field}: item.${field} !== undefined ? item.${field} : null`;
|