Skip to main content
Glama

OmniFocus-MCP

getPerspectiveView.ts4.43 kB
import { z } from 'zod'; import { getPerspectiveView } from '../primitives/getPerspectiveView.js'; import { RequestHandlerExtra } from '@modelcontextprotocol/sdk/shared/protocol.js'; export const schema = z.object({ perspectiveName: z.string().describe("Name of the perspective to view (e.g., 'Inbox', 'Projects', 'Flagged', or custom perspective name)"), limit: z.number().optional().describe("Maximum number of items to return. Default: 100"), includeMetadata: z.boolean().optional().describe("Include additional metadata like project names, tags, dates. Default: true"), fields: z.array(z.string()).optional().describe("Specific fields to include in the response. Reduces response size. Available fields: id, name, note, flagged, dueDate, deferDate, completionDate, taskStatus, projectName, tagNames, estimatedMinutes") }); export async function handler(args: z.infer<typeof schema>, extra: RequestHandlerExtra) { try { const result = await getPerspectiveView({ perspectiveName: args.perspectiveName, limit: args.limit ?? 100, includeMetadata: args.includeMetadata ?? true, fields: args.fields }); if (result.success) { const items = result.items || []; // Format the output let output = `## ${args.perspectiveName} Perspective (${items.length} items)\n\n`; if (items.length === 0) { output += "No items visible in this perspective."; } else { // Format each item items.forEach(item => { const parts = []; // Core display const flag = item.flagged ? '🚩 ' : ''; const checkbox = item.completed ? '☑' : '☐'; parts.push(`${checkbox} ${flag}${item.name || 'Unnamed'}`); // Project context if (item.projectName) { parts.push(`(${item.projectName})`); } // Due date if (item.dueDate) { const date = new Date(item.dueDate); const dateStr = `${date.getMonth() + 1}/${date.getDate()}`; parts.push(`[due: ${dateStr}]`); } // Defer date if (item.deferDate) { const date = new Date(item.deferDate); const dateStr = `${date.getMonth() + 1}/${date.getDate()}`; parts.push(`[defer: ${dateStr}]`); } // Time estimate if (item.estimatedMinutes) { const hours = item.estimatedMinutes >= 60 ? `${Math.floor(item.estimatedMinutes / 60)}h${item.estimatedMinutes % 60 > 0 ? (item.estimatedMinutes % 60) + 'm' : ''}` : `${item.estimatedMinutes}m`; parts.push(`(${hours})`); } // Tags if (item.tagNames && item.tagNames.length > 0) { parts.push(`<${item.tagNames.join(',')}>`); } // Status if (item.taskStatus && item.taskStatus !== 'Available') { parts.push(`#${item.taskStatus.toLowerCase()}`); } // ID for reference if (item.id) { parts.push(`[${item.id}]`); } output += `• ${parts.join(' ')}\n`; // Add note preview if present and not too long if (item.note && item.note.trim()) { const notePreview = item.note.trim().split('\n')[0].substring(0, 80); const ellipsis = item.note.length > 80 || item.note.includes('\n') ? '...' : ''; output += ` └─ ${notePreview}${ellipsis}\n`; } }); } if (items.length === args.limit) { output += `\n⚠️ Results limited to ${args.limit} items. More may be available in this perspective.`; } return { content: [{ type: "text" as const, text: output }] }; } else { return { content: [{ type: "text" as const, text: `Failed to get perspective view: ${result.error}` }], isError: true }; } } catch (err: unknown) { const error = err as Error; console.error(`Error getting perspective view: ${error.message}`); return { content: [{ type: "text" as const, text: `Error getting perspective view: ${error.message}` }], isError: true }; } }

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/themotionmachine/OmniFocus-MCP'

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