get_all_projects
Retrieve a comprehensive list of all OmniFocus projects, including completed and dropped ones, for enhanced task management and review. Ideal when users request 'all projects' explicitly.
Instructions
Call this tool to get a list of all projects from OmniFocus, including completed and dropped ones. Use it when the user explicitly asks for 'all projects'.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Implementation Reference
- src/omnifocus/client.ts:98-108 (handler)The main handler function implementing the get_all_projects tool logic by generating and executing a JXA script via osascript to fetch all projects from OmniFocus.async getAllProjects(): Promise<any[]> { console.error('[DEBUG] getAllProjects called'); const jxaScript = buildJxaScriptForProjects(false); const output = this.executeScript(jxaScript); try { const projects = JSON.parse(output); return projects; } 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:62-65 (registration)Registration of the get_all_projects tool in the MCP server's listTools handler, including name, description, and empty input schema.name: 'get_all_projects', description: "Call this tool to get a list of all projects from OmniFocus, including completed and dropped ones. Use it when the user explicitly asks for 'all projects'.", inputSchema: { type: 'object', properties: {} } },
- src/server.ts:86-88 (handler)Dispatch handler in the MCP callToolRequest that routes the tool call to the OmniFocusClient's getAllProjects method.case 'get_all_projects': result = await this.client.getAllProjects(); break;
- Helper function that builds the JavaScript for Automation (JXA) script used to query all projects from OmniFocus, including filtering logic.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); })(); `; }
- src/omnifocus/client.ts:24-54 (helper)Private helper method in OmniFocusClient that executes the generated JXA script using osascript via a temporary file.private executeScript(script: string): string { const tmpFile = join(tmpdir(), `omnifocus_${Date.now()}_${Math.random().toString(36).substr(2, 9)}.js`); try { console.error(`[DEBUG] Writing script to ${tmpFile}`); writeFileSync(tmpFile, script); console.error(`[DEBUG] Executing osascript...`); const result = execSync(`osascript -l JavaScript "${tmpFile}"`, { encoding: 'utf8', timeout: 90000, // Increased timeout to 90 seconds for large task lists stdio: ['ignore', 'pipe', 'pipe'] }); console.error(`[DEBUG] Script execution completed`); return result.trim(); } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); console.error(`[DEBUG] Script execution failed:`, errorMessage); if (error instanceof Error) { throw new Error(`OmniFocus automation failed: ${error.message}`); } throw new Error('Unknown error executing OmniFocus automation'); } finally { try { unlinkSync(tmpFile); console.error(`[DEBUG] Cleaned up temp file`); } catch (e) { // Ignore cleanup errors } }