Skip to main content
Glama
mdoel
by mdoel

get_all_projects

Retrieve a complete list of all projects from OmniFocus, including completed and dropped ones, for comprehensive task management and review.

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
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • Core handler function that executes the tool logic: builds JXA script for all projects, runs it via osascript, parses JSON output.
    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:61-65 (registration)
    MCP tool registration in listTools handler: defines name, description, and input schema (no parameters).
    {
      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: {} }
    },
  • Server-side dispatch handler for the tool call, delegates to OmniFocusClient.getAllProjects().
    case 'get_all_projects':
      result = await this.client.getAllProjects();
      break;
  • Helper function that generates the JXA (JavaScript for Automation) script executed in OmniFocus to retrieve all projects data as JSON.
    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);
        })();
      `;
    } 
  • 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;
      };
    }

Latest Blog Posts

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