OmniFocus MCP Server
OmniFocus MCP Server
Un servidor del Model Context Protocol (MCP) que permite a los asistentes de IA interactuar con OmniFocus en macOS mediante JXA (JavaScript for Automation).
Características
Este servidor MCP proporciona acceso a funcionalidad de OmniFocus:
Gestión de tareas
Listar tareas de la bandeja de entrada — Ver y filtrar tareas en tu bandeja de entrada (incluido el filtrado por varias etiquetas)
Crear tareas — Añadir nuevas tareas con soporte completo de propiedades (fechas de vencimiento, fechas planificadas, etiquetas, notas, subtareas, recurrencia)
Actualizar tareas — Cambiar el nombre, la nota, las fechas, el marcado, la estimación, la recurrencia o mover una tarea a otro proyecto
Completar/Descartar tareas — Marcar tareas como completadas o descartadas, individualmente o en lote
Eliminar tareas — Quitar una tarea de forma permanente
Actualizar notas de tarea — Reemplazar, vaciar o añadir texto a la nota de una tarea
Obtener tareas vencidas — Encontrar tareas cuyo vencimiento cae dentro de un período
Obtener tareas planificadas — Encontrar tareas planificadas dentro de un período
Obtener tareas marcadas — Listar todos los elementos marcados
Añadir/quitar etiquetas a tareas — Gestionar las etiquetas de una tarea, individualmente o en lote
Gestión de proyectos
Listar proyectos — Ver proyectos con filtrado por estado
Obtener tareas del proyecto — Listar todas las tareas pertenecientes a un proyecto
Crear proyectos — Nuevos proyectos con ubicación en carpeta, estado, fechas, modo secuencial, intervalo de revisión
Actualizar proyectos — Cambiar el nombre, la nota, el estado, el marcado, las fechas, el modo secuencial, el intervalo de revisión
Eliminar proyectos — Eliminar un proyecto y sus tareas
Actualizar notas del proyecto — Reemplazar, vaciar o actualizar el texto de la nota de un proyecto
Obtener proyectos para revisar — Encontrar proyectos que necesitan revisión, opcionalmente con sus tareas incompletas
Marcar proyecto revisado — Actualizar el estado de revisión de un proyecto y su próxima fecha de revisión
Marcar revisados en lote — Revisar eficientemente varios proyectos a la vez
Organización
Listar carpetas — Ver la jerarquía de carpetas
Crear/renombrar/eliminar carpetas — Gestionar el árbol de carpetas (incluidas las carpetas anidadas)
Listar etiquetas — Ver todas las etiquetas
Listar perspectivas — Ver perspectivas integradas y personalizadas
Obtener tareas de una perspectiva — Listar las tareas que muestra una perspectiva concreta
Búsqueda
Búsqueda universal — Buscar en tareas, proyectos, carpetas y etiquetas
Propiedades de seguridad
Sin ganador silencioso con nombres duplicados. OmniFocus permite que dos proyectos (o tareas) compartan nombre. Las búsquedas por nombre recopilan todas las coincidencias y fallan con los IDs coincidentes cuando hay más de una, de modo que un renombrado, una reubicación o un borrado nunca puede dar en el elemento equivocado y al mismo tiempo informar de un éxito.
Las mutaciones se verifican. Las operaciones en las que JXA puede fallar silenciosamente (en particular mover una tarea entre proyectos) releen el resultado dentro del mismo script, de forma que un movimiento fallido se notifica como error y no como éxito.
Related MCP server: OmniFocus MCP Server
Requisitos
macOS (OmniFocus solo está disponible para macOS/iOS, y este servidor usa JXA)
OmniFocus 3+ instalado
Node.js 18+
Permisos de automatización habilitados para tu terminal/aplicación cliente
Instalación
Clona o descarga este repositorio:
cd omnifocus-mcp-serverInstala las dependencias:
npm installCompila el TypeScript:
npm run buildConfigura tu cliente MCP para usar el servidor (consulta Configuración abajo)
Configuración
Claude Desktop
Añade al archivo de configuración de Claude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"omnifocus": {
"command": "/opt/homebrew/bin/node",
"args": ["/path/to/omnifocus-mcp-server/dist/index.js"]
}
}
}Usa una ruta absoluta al binario node. Un "node" a secas se resuelve usando el PATH de la sesión gráfica, que no incluye Homebrew ni los shims de un gestor de versiones, por lo que el servidor no arranca y aparece un error del estilo «server unreachable», aunque desde tu terminal funcione correctamente. Encuentra la tuya con which node.
Otros clientes MCP
El servidor usa transporte stdio por defecto, así que configura tu cliente para lanzar:
node /path/to/omnifocus-mcp-server/dist/index.jsAcceso remoto (transporte HTTP)
Para clientes remotos — los más importantes son los conectores personalizados de claude.ai, que es como la app de Claude para iOS llega a los servidores MCP — el servidor puede ejecutarse como un endpoint HTTP Streamable:
MCP_TRANSPORT=http \
MCP_AUTH_TOKEN="$(openssl rand -hex 32)" \
node /path/to/omnifocus-mcp-server/dist/index.jsVariables de entorno:
Variable | Default | Propósito |
|
| Ponlo a |
|
| Puerto de escucha |
|
| Dirección de enlace (mantén loopback; expónlo mediante un túnel) |
| — | Secreto compartido necesario; el servidor no arranca sin él |
| — | Origen público HTTPS en el que el servidor es accesible (p. ej. |
|
| Rompe un script JXA que se cuelgue (aplica a ambos transportes) |
El endpoint MCP es /mcp. La autenticación acepta una cabecera Authorization: Bearer <token>, o el token como segmento de ruta (/mcp/<token>) para clientes que no puedan enviar cabeceras personalizadas. GET /health no requiere autenticación.
Llegar a él desde claude.ai / la app de iOS. Los conectores personalizados se conectan desde la nube de Anthropic (no desde tu dispositivo), por lo que el endpoint debe ser accesible públicamente por HTTPS. Para esto sirven tanto un Clodeflare Tunnel como un Tailscale Funnel; en cualquier caso, un proceso local realiza una conexión saliente, así que no necesitas abrir puertos. (El Tailscale normal, sin Funnel, no: solo alcanza tu propia tailnet, en la que la nube de Anthropic no está.) Opcionalmente puedes restringir el acceso al rango de IP de salida de Anthropic (160.79.104.0/21) en una regla WAF de Cloudflare.
La interfaz de “Connectors” de claude.ai y de Claude Desktop (a diferencia de una configuración MCP en bruto o de un cliente API directo) siempre exige un handshake OAuth completo antes de llamar a un servidor remoto; no acepta el token estático por sí solo, ni siquiera incrustado en la URL. Ajusta MCP_PUBLIC_URL al origen público de tu túnel para activar una capa OAuth autoemitida que cumpla este requisito y que todas las características sigan estando protegidas con el mismo secreto estático (consulta oauth.ts / CLAUDE.md para más detalle). Con esto ajustado, añade el conector en Settings → Connectors mediante la URL con el token en la ruta (https://your-tunnel-host/mcp/<token>) — el paso “Connect” completará automáticamente el handshake OAuth. Si tu túnel también proxía / a otro servicio local, asegúrate de que /authorize, /token, /register y /.well-known/* estén también mapeados a este servidor; de lo contrario las peticiones OAuth nunca llegarán aquí.
El Mac debe permanecer despierto y con OmniFocus en ejecución (caffeinate -s o Amphetamine).
Semántica de sesión: solo un cliente. El transporte HTTP atiende una sola sesión por vez: una nueva initialize reemplaza la sesión anterior. Cada llamada a una herramienta es sin estado, y un cliente que cumple la especificación vuelve a inicializarse al recibir 404 para una sesión que ya no existe, por lo que un único cliente con llamadas secuenciales funciona bien. Esto también cubre el caso de que el servidor no tiene sesión en absoluto, que es lo que los pasa a todos los clientes después que el servidor se reinicia — se reinicializan en vez de tratar la punto como muerto.
Con dos clientes a la vez no. Se reproduce lanzando dos secuencias concurrentes initialize→tools/list hacia el endpoint público: una siempre recibe 404. El SDK de MCP subyacente vincula un único transporte a la instancia compartida del servidor, con lo cual la sesión perdedora es expulsada y su solicitud en curso recibe 404 o se queda colgada. Arreglar eso requiere una instancia de McpServer por sesión en lugar de patrón actual de registro sobre un singleton; no está planificado. Véanse los detalles en CLAUDE.md.
Solucionar problemas de un cliente que «no puede conectarse». Los clientes resumen cualquier fallo remoto en un único mensaje vago, así que lee el log de este servidor (StandardErrorPath de agente de tu inicio) en lugar de lo que dice el cliente: el código de estado indica cuál de tres cosas no relacionadas ha ocurrido:
Qué muestra el log | Significado | Solución |
| El token de la URL delquiero es incorrecto o llega truncado | Vuelve a copiar entero |
| La misma causa, vista desde el lado de OAuth. Un | Igual que arriba |
| Recuperación normal después de un reinicio o de una sesión secuestrada | Nada; el cliente se re-inicializa |
| Funcionando. El nombre del cliente identifica cuál cliente es. | — |
Si el log no muestra nada en absoluto, la petición nunca llegó a este servidor: comprueba los mapas de rutas del túnel y no este código.
Permisos
En el primer uso, macOS te pedirá que permitas el acceso de automatización:
Ve a Preferencias del Sistema → Seguridad y Privacidad → Privacidad → Automatización
Activa el permiso para que tu terminal o Claude Desktop controle OmniFocus
Reference de herramientas
Todas las 31 herramientas se listan abajo, agrupadas por área.
omnifocus_list_inbox
Lista las tareas de la bandeja de entrada, opcionalmente filtradas por etiquetas.
{
"includeCompleted": false,
"limit": 50,
"tags": ["Work", "Urgent"],
"tagMatchMode": "all"
}tagMatchMode es "all" (la tarea tiene todas las etiquetas listadas; por defecto), "any" (al menos una) o "none" (ninguna de ellas). Solo se aplica cuando se proporciona tags. Los mismos dos parámetros funcionan en omnifocus_get_due_tasks, omnifocus_get_flagged_tasks y omnifocus_get_planned_tasks.
omnifocus_list_projects
Lista proyectos con filtrado.
{
"status": "active",
"folderName": "Work",
"limit": 50
}omnifocus_get_project_tasks
Obtiene todas las tareas pertenecientes a un solo proyecto.
{
"projectId": "abc123",
"includeCompleted": false,
"limit": 100
}omnifocus_create_project
Crea un proyecto, opcionalmente dentro de una carpeta.
{
"name": "Website redesign",
"note": "Q1 initiative",
"folderName": "Work",
"dueDate": "2024-03-31T17:00:00",
"deferDate": "2024-01-15T09:00:00",
"flagged": false,
"sequential": false,
"status": "active",
"reviewIntervalDays": 7
}status es "active" (predeterminado), "on hold", "done" o "dropped". sequential: false (predeterminado) crea un proyecto paralelo.
omnifocus_update_project
Actualiza las propiedades de un proyecto. Identifícalo por projectId o projectName (el ID tiene prioridad).
{
"projectId": "abc123",
"name": "Website redesign v2",
"status": "on hold",
"flagged": true,
"dueDate": null,
"sequential": true,
"reviewIntervalDays": 14
}Pasa null para note, dueDate o deferDate para borrarlos. Un proyecto no puede moverse a otra carpeta (limitación de JXA).
omnifocus_delete_project
Elimina un proyecto y sus tareas. Identifícalo por projectId o projectName (el ID tiene prioridad).
{
"projectId": "abc123"
}omnifocus_list_folders
Lista todas las carpetas.
{
"status": "active",
"limit": 50
}omnifocus_create_folder
Crea una carpeta, de nivel superior o anidada.
{
"name": "Clients",
"parentFolderName": "Work"
}omnifocus_update_folder
Cambia el nombre de una carpeta. Identifícala por folderId o folderName (el ID tiene prioridad). Una carpeta no puede moverse dentro de otra carpeta (limitación de JXA).
{
"folderName": "Clients",
"name": "Key clients"
}omnifocus_delete_folder
Elimina una carpeta y todo su contenido. Identifícala por folderId o folderName (el ID tiene prioridad).
{
"folderId": "abc123"
}omnifocus_list_tags
Lista todas las etiquetas.
{
"status": "active",
"limit": 50
}omnifocus_list_perspectives
Lista las perspectivas (integradas y personalizadas).
{
"limit": 50
}omnifocus_get_perspective_tasks
Obtiene las tareas que se muestran en una perspectiva concreta.
{
"perspectiveName": "Next",
"limit": 50
}omnifocus_create_task
Crea una nueva tarea.
{
"name": "Review quarterly report",
"note": "Check all sections",
"projectName": "Work",
"dueDate": "2024-12-31T17:00:00",
"deferDate": "2024-12-01T09:00:00",
"plannedDate": "2024-12-15T09:00:00",
"flagged": true,
"estimatedMinutes": 60,
"tagNames": ["Review", "Important"],
"parentTaskId": "xyz789",
"recurrence": {
"frequency": "weekly",
"interval": 1,
"daysOfWeek": ["Monday", "Thursday"],
"repeatFrom": "due-date"
}
}Fecha planificada frente a fecha de vencimiento:
dueDate: cuándo debe completarse la tarea (fecha límite)plannedDate: cuándo tienes previsto trabajar en la tarea (planificación)Esta distinción es crucial para separar las fechas límite del tiempo de trabajo programado
Recurrencia: frequency es "daily", "weekly", "monthly" o "yearly". Usa daysOfWeek para semanal, dayOfMonth (1-31) para mensual, monthOfYear (1-12) para anual. repeatFrom es "due-date" (predeterminado) o "completion-date".
Subtareas: pasa parentTaskId para crear la tarea como hija de una tarea existente.
omnifocus_update_task
Actualiza una tarea existente. Identifícala por taskId o taskName (el ID tiene prioridad).
{
"taskId": "abc123",
"name": "Review quarterly report (final)",
"note": null,
"dueDate": "2024-12-20T17:00:00",
"flagged": true,
"estimatedMinutes": 45,
"projectName": "Work"
}Pasa
nullparanote,dueDate,deferDateoplannedDatepara borrarlos;estimatedMinutes: 0borra la estimación.projectId/projectNamemueve la tarea a ese proyecto (las subtareas van con ella). El movimiento se verifica después, por lo que un fallo se notifica como error en lugar de un falso éxito.recurrenceacepta el mismo objeto quecreate_task;recurrence: nulloclearRecurrence: truedesactiva la repetición.
omnifocus_delete_task
Elimina una tarea. Identifícala por taskId o taskName (el ID tiene prioridad).
{
"taskId": "abc123"
}omnifocus_update_task_note
Reemplaza, borra o añade contenido a la nota de una tarea. Identifícala por taskId o taskName (el ID tiene prioridad).
{
"taskId": "abc123",
"note": "Added after the call.",
"append": true
}Una cadena note vacía borra la nota.
omnifocus_complete_task
Marca una tarea como completada o descartada. Puedes identificar la tarea por ID o por nombre.
{
"taskId": "abc123",
"action": "complete"
}O usando el nombre de la tarea:
{
"taskName": "Write documentation",
"action": "complete"
}La acción puede ser "complete" (predeterminado) o "drop". Si se proporcionan tanto taskId como taskName, taskId tiene prioridad.
Descartar una tarea repetitiva borra primero su regla de repetición, de modo que la serie realmente se detiene en lugar de avanzar a la siguiente ocurrencia.
omnifocus_batch_complete_task
Completa o descarta hasta 100 tareas por ID en una sola llamada.
{
"taskIds": ["id1", "id2", "id3"],
"action": "complete"
}omnifocus_add_tag_to_task
Añade una etiqueta a una tarea. Puedes identificar la tarea por ID o por nombre.
{
"taskId": "abc123",
"tagName": "Urgent"
}O usando el nombre de la tarea:
{
"taskName": "Write report",
"tagName": "Urgent"
}Si se proporcionan tanto taskId como taskName, taskId tiene prioridad.
omnifocus_remove_tag_from_task
Elimina una etiqueta de una tarea. Puedes identificar la tarea por ID o por nombre.
{
"taskId": "abc123",
"tagName": "Urgent"
}O usando el nombre de la tarea:
{
"taskName": "Old task",
"tagName": "Done"
}Si se proporcionan tanto taskId como taskName, taskId tiene prioridad.
omnifocus_batch_add_tag
Añade una etiqueta existente a hasta 100 tareas por ID.
{
"taskIds": ["id1", "id2", "id3"],
"tagName": "Urgent"
}omnifocus_batch_remove_tag
Elimina una etiqueta de hasta 100 tareas por ID.
{
"taskIds": ["id1", "id2", "id3"],
"tagName": "Urgent"
}omnifocus_update_project_note
Reemplaza, borra o añade contenido a la nota de un proyecto. Identifícalo por projectId o projectName (el ID tiene prioridad).
{
"projectName": "Website redesign",
"note": "Kickoff moved to March.",
"append": false
}omnifocus_search
Busca en OmniFocus.
{
"query": "report",
"searchType": "all",
"limit": 20
}omnifocus_get_due_tasks
Obtiene las tareas que vencen dentro de un período de tiempo.
{
"daysAhead": 7,
"includeOverdue": true,
"limit": 50
}omnifocus_get_flagged_tasks
Obtiene las tareas marcadas con bandera.
{
"includeCompleted": false,
"limit": 50
}omnifocus_get_planned_tasks
Obtiene las tareas planificadas dentro de un período de tiempo.
{
"daysAhead": 7,
"includeOverdue": true,
"limit": 50
}omnifocus_get_projects_for_review
Obtiene los proyectos que necesitan revisión según su próxima fecha de revisión. Perfecto para practicantes de GTD que siguen el flujo de trabajo de revisión.
{
"daysAhead": 0,
"status": "active",
"limit": 50,
"includeTasks": true,
"taskLimit": 50
}Parámetros:
daysAhead: cuántos días hacia adelante mirar (0 = solo revisiones atrasadas)status: filtra por estado del proyecto ("active", "done", "dropped", "onHold", "all")limit: número máximo de proyectos a devolver (1-500)includeTasks: incluye las tareas incompletas de cada proyecto en el resultado (predeterminado false) — esto convierte una pasada de revisión en una sola llamada en lugar de una llamada de seguimiento por proyectotaskLimit: número máximo de tareas por proyecto cuandoincludeTaskses true (1-200, predeterminado 50)
Cada proyecto también devuelve reviewInterval y lastReviewDate.
omnifocus_mark_project_reviewed
Marca un proyecto como revisado y actualiza su próxima fecha de revisión. Puedes identificar el proyecto por ID o por nombre.
{
"projectId": "abc123"
}O usando el nombre del proyecto:
{
"projectName": "Weekly Review"
}Con intervalo de revisión personalizado:
{
"projectName": "Work Project",
"reviewIntervalDays": 14
}Parámetros:
projectIdoprojectName: identifica el proyecto (el ID tiene prioridad)reviewIntervalDays(opcional): intervalo de revisión personalizado en días. Si no se proporciona, usa el intervalo de revisión existente del proyecto.
omnifocus_batch_mark_reviewed
Marca varios proyectos como revisados en una sola operación eficiente.
{
"projectIds": ["id1", "id2", "id3"]
}Con intervalo de revisión personalizado para todos:
{
"projectIds": ["id1", "id2", "id3"],
"reviewIntervalDays": 7
}Parámetros:
projectIds: matriz de IDs de proyectos para marcar como revisados (1-100 proyectos)reviewIntervalDays(opcional): intervalo de revisión personalizado para aplicar a todos los proyectos
Devuelve un resumen con:
Número de revisiones correctas
Número de fallos
Datos completos de los proyectos con revisión correcta
Detalles del error para cualquier fallo
Formatos de fecha
Todas las fechas usan el formato ISO 8601: YYYY-MM-DDTHH:mm:ss
Ejemplos:
2024-12-31T17:00:00- 31 de diciembre de 2024 a las 17:002024-06-15T09:00:00- 15 de junio de 2024 a las 9:00
Gestión de errores
El servidor proporciona mensajes de error claros para problemas comunes:
OmniFocus no está en ejecución: inicia OmniFocus primero
Permiso denegado: activa los permisos de automatización en Preferencias del Sistema
Elemento no encontrado: el ID especificado no existe
Parámetros no válidos: comprueba el formato y los valores de los parámetros
Desarrollo
Compilación
npm run buildModo de vigilancia
npm run devPruebas
npm test # All unit tests
npm run test:watch # Watch mode
npm run test:coverage # Coverage report (thresholds enforced: 80% lines, 75% branches)Las pruebas de integración en src/__tests__/integration.test.ts están omitidas por defecto: requieren una instancia de OmniFocus en ejecución y modifican tu base de datos real.
Prueba manual
Después de compilar, puedes probar con:
echo '{"jsonrpc":"2.0","method":"tools/list","id":1}' | node dist/index.jsAplicar cambios a un servidor en ejecución (importante)
Los clientes MCP obtienen la lista de herramientas una vez cuando se conectan y la almacenan en caché durante la sesión. npm run build por sí solo no actualiza un cliente que ya está conectado — Node no recarga en caliente y el cliente no volverá a obtener el esquema. Después de cambiar herramientas/esquemas debes reiniciar el servidor y hacer que cada cliente se reconecte:
Recompilar:
npm run buildReiniciar el proceso del servidor para que cargue el nuevo
dist/:LaunchAgent (transporte HTTP):
launchctl kickstart -k gui/$(id -u)/com.sanderrobijns.omnifocus-mcpVerifica que sirve el nuevo esquema:
lsof -nP -iTCP:3000 -sTCP:LISTENdebería mostrar un PID recién iniciado.
Reconectar cada cliente para que vuelva a obtener
tools/list:Claude Code / Cowork: inicia una nueva sesión (una sesión en ejecución mantiene su esquema en caché durante toda su vida).
Claude Desktop: sal y vuelve a abrir la aplicación (o activa/desactiva el servidor).
claude.ai / conector personalizado de Claude iOS: vuelve a sincronizar el conector en Configuración → Conectores (almacena en caché la lista de herramientas a nivel del conector).
Hasta que el cliente se reconecte, seguirá mostrando el esquema antiguo, aunque el servidor ya sirva el nuevo.
Licencia
MIT
Créditos
Construido con:
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseAqualityAmaintenanceA Model Context Protocol (MCP) server that integrates with OmniFocus to enable Claude (or other MCP-compatible AI assistants) to interact with your tasks and projects.71,073236MIT
- AlicenseAqualityFmaintenanceAn MCP server that provides full read/write access to OmniFocus, enabling AI assistants to manage tasks, projects, folders, tags, and perspectives via 51 tools, resources, and prompts.513618MIT
- FlicenseNot gradedqualityBmaintenanceA production-grade MCP server that exposes OmniFocus as structured task infrastructure for AI agents, enabling read, write, and filter operations on tasks and projects via natural language.6
- AlicenseNot gradedqualityCmaintenanceMCP server that gives AI assistants full control over OmniFocus on macOS, including tasks, projects, tags, folders, perspectives, forecast, notifications, and review workflows.42MIT
Related MCP Connectors
A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yo…
Personal assistant MCP server with search, execute, packages, jobs, secrets, and integrations.
MCP connector that lets ChatGPT list, search, and run your Apple Shortcuts via a local Mac agent
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/estrenuo/omnifocus-mcp-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server