get_active_projects
Retrieve a list of all active projects from OmniFocus. Use this tool to access current, non-completed projects for task management and organization purposes.
Instructions
Call this tool to get a list of all active (not completed or dropped) projects from OmniFocus. Use it when the user asks for their 'active projects' or 'current projects'.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Implementation Reference
- src/omnifocus/client.ts:111-122 (handler)Core handler function that implements the tool logic: builds JXA script for projects, executes via osascript, parses JSON output, and filters to active projects (not completed or dropped).async getActiveProjects(): Promise<any[]> { console.error('[DEBUG] getActiveProjects called'); const jxaScript = buildJxaScriptForProjects(false); const output = this.executeScript(jxaScript); try { const projects = JSON.parse(output); return projects.filter((p: any) => !p.completed && !(p.status && typeof p.status === 'string' && p.status.toLowerCase().includes('dropped'))); } catch (e) { console.error('[DEBUG] Failed to parse OmniFocus JXA output:', output); throw new Error('Failed to parse OmniFocus output as JSON'); } }
- src/server.ts:56-60 (registration)Tool registration in the MCP ListTools handler, defining name, description, and empty input schema.{ name: 'get_active_projects', description: "Call this tool to get a list of all active (not completed or dropped) projects from OmniFocus. Use it when the user asks for their 'active projects' or 'current projects'.", inputSchema: { type: 'object', properties: {} } },
- src/server.ts:83-85 (handler)MCP server dispatch handler that routes tool calls to the client implementation.case 'get_active_projects': result = await this.client.getActiveProjects(); break;
- src/types/omnifocus.ts:34-50 (schema)TypeScript interface defining the structure of OmniFocusProject objects returned by the tool.export interface OmniFocusProject { id: string; name: string; note: string; status: 'active' | 'on-hold' | 'completed' | 'dropped'; completionDate?: string; creationDate: string; modificationDate: string; dueDate?: string; deferDate?: string; sequential: boolean; singleton: boolean; containingFolder?: { id: string; name: string; }; }
- Helper function that generates the JXA (JavaScript for Automation) script executed by the handler to query OmniFocus projects.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); })(); `; }