Skip to main content
Glama

OmniFocus MCP Server

by mdoel
omnifocus-jxa.ts5.07 kB
// Utility for building JXA scripts and parsing results for OmniFocus automation export function buildJxaScriptForTasks(activeOnly: boolean): string { return ` (() => { const app = Application('OmniFocus'); app.includeStandardAdditions = true; const ofDoc = app.defaultDocument; function safe(obj, method) { try { return obj && typeof obj[method] === 'function' ? obj[method]() : null; } catch { return null; } } function getContext(task) { const ctx = safe(task, 'context'); return ctx ? { id: safe(ctx, 'id'), name: safe(ctx, 'name') } : null; } function getProject(task) { const proj = safe(task, 'containingProject'); return proj ? { id: safe(proj, 'id'), name: safe(proj, 'name') } : null; } function isInTemplatesFolder(project) { let folder = safe(project, 'folder'); while (folder) { if (safe(folder, 'name') === 'Templates') return true; folder = safe(folder, 'parentFolder'); } return false; } function isExcludedTask(task) { const name = safe(task, 'name') || ''; const note = safe(task, 'note') || ''; if (name.includes('«') || name.includes('»') || note.includes('«') || note.includes('»')) return true; if (name.includes('⚙️') || note.includes('⚙️')) return true; const proj = safe(task, 'containingProject'); if (!proj) return false; return isInTemplatesFolder(proj); } function getTaskData(task) { return { id: safe(task, 'id'), name: safe(task, 'name'), note: safe(task, 'note'), completed: safe(task, 'completed'), status: safe(task, 'status'), completionDate: safe(task, 'completionDate') ? safe(task, 'completionDate').toISOString() : null, creationDate: safe(task, 'creationDate') ? safe(task, 'creationDate').toISOString() : null, modificationDate: safe(task, 'modificationDate') ? safe(task, 'modificationDate').toISOString() : null, dueDate: safe(task, 'dueDate') ? safe(task, 'dueDate').toISOString() : null, deferDate: safe(task, 'deferDate') ? safe(task, 'deferDate').toISOString() : null, estimatedMinutes: safe(task, 'estimatedMinutes'), flagged: safe(task, 'flagged'), repetitionRule: safe(task, 'repetitionRule'), sequential: safe(task, 'sequential'), project: safe(task, 'project'), context: getContext(task), containingProject: getProject(task) }; } const allTasks = Array.from(ofDoc.flattenedTasks()); const filteredTasks = allTasks.filter(task => { if (isExcludedTask(task)) return false; const statusObj = safe(task, 'status') ? task.status() : null; const statusName = statusObj ? safe(statusObj, 'name') : ''; if (${activeOnly ? 'true' : 'false'}) { // Exclude completed or dropped tasks return !task.completed() && !/dropped/i.test(statusName); } return true; }); const result = filteredTasks.map(getTaskData); return JSON.stringify(result); })(); `; } export function buildJxaScriptForProjects(activeOnly: boolean): string { return ` (() => { const app = Application('OmniFocus'); app.includeStandardAdditions = true; const ofDoc = app.defaultDocument; function safe(obj, method) { try { return obj && typeof obj[method] === 'function' ? obj[method]() : null; } catch { return null; } } function isInTemplatesFolder(project) { let folder = safe(project, 'folder'); while (folder) { if (safe(folder, 'name') === 'Templates') return true; folder = safe(folder, 'parentFolder'); } return false; } function isExcludedProject(project) { const name = safe(project, 'name') || ''; if (name.includes('«') || name.includes('»')) return true; if (name.includes('⚙️')) return true; return isInTemplatesFolder(project); } function getProjectData(project) { return { id: safe(project, 'id'), name: safe(project, 'name'), note: safe(project, 'note'), completed: safe(project, 'completed'), status: safe(project, 'status'), flagged: safe(project, 'flagged'), folder: (function() { const folder = safe(project, 'folder'); return folder ? { id: safe(folder, 'id'), name: safe(folder, 'name') } : null; })(), }; } const allProjects = Array.from(ofDoc.flattenedProjects()); const filteredProjects = allProjects.filter(project => { if (isExcludedProject(project)) return false; // No activeOnly filtering here; always return all projects return true; }); const result = filteredProjects.map(getProjectData); return JSON.stringify(result); })(); `; }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/mdoel/omnifocus-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server