Skip to main content
Glama

get_flagged_tasks

Retrieve flagged tasks from OmniFocus with optional project filtering. Customize results by excluding completed tasks or limiting to specific projects for focused task management.

Instructions

Get flagged tasks from OmniFocus with optional project filtering

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
hideCompletedNoSet to false to show completed flagged tasks (default: true)
projectFilterNoFilter flagged tasks by project name (optional)

Implementation Reference

  • The MCP tool handler that wraps the primitive function, handles errors, and returns formatted MCP response.
    export async function handler(args: z.infer<typeof schema>, extra: RequestHandlerExtra) {
      try {
        const result = await getFlaggedTasks({
          hideCompleted: args.hideCompleted !== false, // Default to true
          projectFilter: args.projectFilter
        });
        
        return {
          content: [{
            type: "text" as const,
            text: result
          }]
        };
      } catch (err: unknown) {
        const errorMessage = err instanceof Error ? err.message : 'Unknown error occurred';
        return {
          content: [{
            type: "text" as const,
            text: `Error getting flagged tasks: ${errorMessage}`
          }],
          isError: true
        };
      }
    }
  • Zod schema defining the input parameters for the get_flagged_tasks tool.
    export const schema = z.object({
      hideCompleted: z.boolean().optional().describe("Set to false to show completed flagged tasks (default: true)"),
      projectFilter: z.string().optional().describe("Filter flagged tasks by project name (optional)")
    });
  • src/server.ts:106-111 (registration)
    Registers the 'get_flagged_tasks' tool on the MCP server using the schema and handler from definitions/getFlaggedTasks.
    server.tool(
      "get_flagged_tasks", 
      "Get flagged tasks from OmniFocus with optional project filtering",
      getFlaggedTasksTool.schema.shape,
      getFlaggedTasksTool.handler
    );
  • Core helper function that executes the OmniFocus '@flaggedTasks.js' script via executeOmniFocusScript and formats the output into a markdown list grouped by project.
    export async function getFlaggedTasks(options: GetFlaggedTasksOptions = {}): Promise<string> {
      const { hideCompleted = true, projectFilter } = options;
      
      try {
        // Execute the flagged tasks script
        const result = await executeOmniFocusScript('@flaggedTasks.js', { 
          hideCompleted: hideCompleted,
          projectFilter: projectFilter
        });
        
        if (typeof result === 'string') {
          return result;
        }
        
        // If result is an object, format it
        if (result && typeof result === 'object') {
          const data = result as any;
          
          if (data.error) {
            throw new Error(data.error);
          }
          
          // Format the flagged tasks
          let output = `# 🚩 FLAGGED TASKS\n\n`;
          
          if (projectFilter) {
            output = `# 🚩 FLAGGED TASKS - Project: ${projectFilter}\n\n`;
          }
          
          if (data.tasks && Array.isArray(data.tasks)) {
            if (data.tasks.length === 0) {
              output += projectFilter 
                ? `No flagged tasks found in project "${projectFilter}"\n`
                : "🎉 No flagged tasks - nice and clean!\n";
            } else {
              const taskCount = data.tasks.length;
              output += `Found ${taskCount} flagged task${taskCount === 1 ? '' : 's'}:\n\n`;
              
              // Group tasks by project for better organization
              const tasksByProject = new Map<string, any[]>();
              
              data.tasks.forEach((task: any) => {
                const projectName = task.projectName || '📥 Inbox';
                if (!tasksByProject.has(projectName)) {
                  tasksByProject.set(projectName, []);
                }
                tasksByProject.get(projectName)!.push(task);
              });
              
              // Display tasks grouped by project
              tasksByProject.forEach((tasks, projectName) => {
                if (tasksByProject.size > 1) {
                  output += `## 📁 ${projectName}\n`;
                }
                
                tasks.forEach((task: any, index: number) => {
                  const dueDateStr = task.dueDate ? ` [DUE: ${new Date(task.dueDate).toLocaleDateString()}]` : '';
                  const deferDateStr = task.deferDate ? ` [DEFER: ${new Date(task.deferDate).toLocaleDateString()}]` : '';
                  const statusStr = task.taskStatus !== 'Available' ? ` (${task.taskStatus})` : '';
                  const estimateStr = task.estimatedMinutes ? ` ⏱${task.estimatedMinutes}m` : '';
                  
                  output += `• 🚩 ${task.name}${dueDateStr}${deferDateStr}${statusStr}${estimateStr}\n`;
                  
                  if (task.note && task.note.trim()) {
                    output += `  📝 ${task.note.trim()}\n`;
                  }
                  
                  if (task.tags && task.tags.length > 0) {
                    const tagNames = task.tags.map((tag: any) => tag.name).join(', ');
                    output += `  🏷 ${tagNames}\n`;
                  }
                  
                  output += '\n';
                });
              });
            }
          } else {
            output += "No flagged tasks data available\n";
          }
          
          return output;
        }
        
        return "Unexpected result format from OmniFocus";
        
      } catch (error) {
        console.error("Error in getFlaggedTasks:", error);
        throw new Error(`Failed to get flagged tasks: ${error instanceof Error ? error.message : 'Unknown error'}`);
      }
    }
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It mentions 'optional project filtering' and implies retrieval of flagged tasks, but lacks details on permissions, rate limits, pagination, or what 'flagged' means in OmniFocus context. For a read operation tool with zero annotation coverage, this leaves significant gaps in understanding how it behaves.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence that front-loads the core purpose ('Get flagged tasks from OmniFocus') and adds a useful detail ('with optional project filtering'). There is no wasted language, and it's appropriately sized for a simple retrieval tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's low complexity (2 parameters, no output schema, no annotations), the description is adequate but not complete. It covers the basic purpose and hints at filtering, but lacks details on return format, error handling, or behavioral traits. For a read operation, this is minimally viable but could be more informative.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the input schema already documents both parameters thoroughly. The description adds minimal value by mentioning 'optional project filtering,' which aligns with the 'projectFilter' parameter, but doesn't provide additional context beyond what the schema states. This meets the baseline for high schema coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Get flagged tasks') and resource ('from OmniFocus'), making the purpose immediately understandable. It distinguishes this tool from siblings like 'get_inbox_tasks' or 'get_tasks_by_tag' by specifying 'flagged tasks' as the target. However, it doesn't specify whether this retrieves all flagged tasks or only active ones, which would make it a perfect 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage through 'optional project filtering,' suggesting this tool is for retrieving flagged tasks with possible project-based narrowing. However, it doesn't explicitly state when to use this versus alternatives like 'filter_tasks' or 'get_custom_perspective_tasks,' nor does it mention prerequisites or exclusions. The guidance is present but not comprehensive.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Related Tools

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/jqlts1/omnifocus-mcp-enhanced'

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