zoho-projects-mcp
Provides tools for managing Zoho Projects, including listing projects and tasks, creating and updating tasks, adding comments, managing users, starting/stopping timers, and listing custom fields.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@zoho-projects-mcpList all projects"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
zoho-projects-mcp
Servidor MCP (Model Context Protocol) que conecta Zoho Projects con Claude AI. Permite gestionar proyectos y tareas, registrar tiempo, manejar comentarios y sincronizar horas directamente desde conversaciones con Claude.
Requisitos
Node.js 18+
Cuenta de Zoho Projects con acceso a la API
Claude Desktop (u otro cliente MCP compatible)
Related MCP server: Zoho Projects MCP Server
Instalación
git clone https://github.com/tu-org/zoho-projects-mcp.git
cd zoho-projects-mcp
npm installConfiguración
1. Variables de entorno
Crea un archivo .env en la raíz del proyecto:
ZOHO_CLIENT_ID=tu_client_id
ZOHO_CLIENT_SECRET=tu_client_secret
ZOHO_PORTAL_NAME=nombre_de_tu_portal
ZOHO_MY_USER_ID=tu_id_de_usuario_numerico
ZOHO_MY_NAME=Tu Nombre Completo
ZOHO_TEAM_EMAILS=usuario1@empresa.com,usuario2@empresa.com
ZOHO_TEAM_NAMES=nombre1,apellido1,nombre2,apellido2
ZOHO_AUTO_TIMER_PROJECT_ID=id_numerico_del_proyecto
ZOHO_AUTO_TIMER_TASK_ID=id_numerico_de_la_tarea
ZOHO_REFRESH_TOKEN=tu_refresh_tokenZOHO_PORTAL_NAME— nombre del portal en la URL de Zoho Projects (ej:sigobproyectos)ZOHO_MY_USER_ID— ID numérico del usuario que se asigna por defecto al crear tareas; obténlo conlist_usersen cualquier proyectoZOHO_MY_NAME— nombre completo del usuario (opcional); amplía la detección de menciones por nombre enmy-mentionsZOHO_TEAM_EMAILS— lista separada por comas de emails del equipo parateam-tasksZOHO_TEAM_NAMES— fragmentos de nombre separados por comas para detectar miembros del equipo por nombre (ej:"jose ramon,tejeda,kevin")ZOHO_AUTO_TIMER_PROJECT_ID— ID numérico del proyecto para el timer automático (ver sección Railway)ZOHO_AUTO_TIMER_TASK_ID— ID numérico de la tarea en la que se inicia/detiene el timer automáticoZOHO_REFRESH_TOKEN— refresh token OAuth; solo necesario en entornos sintokens.json(Railway, CI)
Para crear las credenciales OAuth, registra una aplicación en la Consola de Desarrolladores de Zoho con URI de redirección
http://localhost:8080/callback.
2. Autenticación OAuth2
Ejecuta el flujo de autenticación una sola vez. Abrirá el navegador para autorizar la app y guardará los tokens en tokens.json:
npm run setupLos tokens se renuevan automáticamente; no es necesario repetir este paso.
3. Integrar con Claude Desktop
Agrega el servidor al archivo de configuración de Claude Desktop (claude_desktop_config.json):
{
"mcpServers": {
"zoho-projects": {
"command": "node",
"args": ["/ruta/absoluta/al/proyecto/src/server.js"]
}
}
}Uso
Iniciar el servidor manualmente
npm startScripts de utilidad
Tareas abiertas del equipo
Muestra las tareas abiertas asignadas a los miembros del equipo en todos los proyectos. Requiere ZOHO_TEAM_EMAILS y/o ZOHO_TEAM_NAMES en .env:
npm run team-tasksMenciones en comentarios
Busca todos los comentarios donde te mencionan ([~ZOHO_MY_USER_ID]) en uno o todos los proyectos. Soporta filtro por rango de fechas:
npm run my-mentions # todos los proyectos
npm run my-mentions -- "nombre-proyecto" # un proyecto específico
npm run my-mentions -- --from=2026-05-01 --to=2026-06-09 # con rango de fechas
npm run my-mentions -- "nombre-proyecto" --from=2026-06-01Herramientas MCP disponibles
Proyectos y tareas
Herramienta | Descripción | Parámetros requeridos |
| Lista todos los proyectos del portal | — |
| Lista todas las tareas de un proyecto (paginación automática) |
|
| Detalle completo de una tarea |
|
| Crea una nueva tarea |
|
| Crea una subtarea bajo una tarea padre |
|
| Actualiza estado, prioridad, responsable, fechas, etc. |
|
| Elimina una tarea permanentemente (irreversible) |
|
| Lista los usuarios de un proyecto con su zpuid |
|
| Lista los campos personalizados disponibles |
|
Comentarios
Herramienta | Descripción | Parámetros requeridos |
| Lista todos los comentarios de una tarea |
|
| Agrega un comentario a una tarea |
|
| Edita un comentario existente |
|
| Elimina un comentario (irreversible) |
|
Archivos adjuntos
Herramienta | Descripción | Parámetros requeridos |
| Lista los archivos adjuntos de una tarea con URLs de descarga |
|
| Desvincula un adjunto de una tarea (no lo elimina de WorkDrive) |
|
Tiempo
Herramienta | Descripción | Parámetros requeridos |
| Inicia el timer de tiempo en una tarea |
|
| Detiene el timer activo |
|
| Lista los registros de tiempo de un proyecto por rango de fechas |
|
| Registra horas manualmente en una tarea |
|
| Para cada tarea cerrada con horas planeadas, crea un time log igual a |
|
Notas sobre create_task
project_idacepta nombre o ID numérico:"sigob-sir-lite"o"123456789"Si no se especifica
person_responsible, se asigna automáticamenteZOHO_MY_USER_IDprioritydebe ir en minúsculas:"high","medium","low","none"start_dateydue_dateusan formatoMM-DD-YYYY(se convierten a ISO internamente)Para campos personalizados usa
list_task_fieldspara obtener losapi_namey pásalos encustom_fields:{ "cf_area_tecnica": "Backend" }
Notas sobre update_task
Solo se envían los campos que se pasen; los demás quedan intactos.
Para cambiar el estado necesitas el ID numérico del estado (no el nombre). Patrón: busca con
list_tasksuna tarea que ya tenga ese estado → llama aget_task→ lee el ID en el campo Estado.Para mover la tarea a otra lista usa el parámetro
tasklist_id.
Notas sobre get_time_logs
Itera sobre las tareas del proyecto consultando los logs de cada una individualmente (limitación de la API de Zoho).
Si se pasa
user_zpuid, solo consulta las tareas asignadas a ese usuario.Si no se pasan fechas, devuelve el mes actual.
Notas sobre sync_task_hours
Opera sobre tareas cerradas con
owners_and_work.total_work > 0.factor(0.0–2.0, por defecto1.0): multiplica las horas planeadas antes de crear el log. Ej:0.95registra el 95% de las horas planeadas.La fecha del log usa
end_datede la tarea; si no tiene, usa la fecha de hoy.No reemplaza logs existentes — crea un entry adicional.
Procesa en lotes de 3 con pausa entre ellos para respetar el rate limit de Zoho.
Formato HTML de descripciones
El campo description en create_task y update_task se convierte automáticamente a HTML antes de enviarse a Zoho.
Si el texto ya contiene HTML, se envía tal cual.
Si es texto plano, se aplica la siguiente conversión:
Entrada | HTML generado |
Línea en MAYÚSCULAS (ej: |
|
Línea con | Agrupada en |
Cualquier otro texto |
|
Timer automático (cron)
El script scripts/auto-timer.js inicia o detiene el timer de una tarea de Zoho automáticamente. La tarea objetivo se configura vía variables de entorno — cada usuario apunta a su propia tarea sin tocar el código.
npm run timer:start # inicia el timer
npm run timer:stop # detiene el timerPaso 1 — obtener los IDs de tu tarea
Abre la tarea en Zoho Projects y copia los IDs del URL:
https://projects.zoho.com/portal/miportal#zp/projects/106599000032339072/tasks/.../106599000033129351
↑ project_id ↑ task_idPaso 2 — obtener el refresh token
Corre el flujo de autenticación local una vez (npm run setup) y luego copia el valor de refresh_token de tu tokens.json:
cat tokens.json | python3 -c "import sys,json; print(json.load(sys.stdin)['refresh_token'])"Paso 3 — elegir dónde desplegar
Opción A — Railway (recomendado, sin servidor propio)
Railway ejecuta cron services como contenedores que corren el comando y terminan. Se necesitan dos servicios dentro del mismo proyecto Railway.
Variables de entorno (configurar en cada servicio):
ZOHO_CLIENT_ID=tu_client_id
ZOHO_CLIENT_SECRET=tu_client_secret
ZOHO_PORTAL_NAME=tu_portal
ZOHO_REFRESH_TOKEN=tu_refresh_token
ZOHO_AUTO_TIMER_PROJECT_ID=id_numerico_del_proyecto
ZOHO_AUTO_TIMER_TASK_ID=id_numerico_de_la_tarea
TZ=America/Mexico_CityServicio 1 — iniciar timer
Campo | Valor |
Tipo | Cron Job |
Comando |
|
Schedule (UTC) |
|
Servicio 2 — detener timer
Campo | Valor |
Tipo | Cron Job |
Comando |
|
Schedule (UTC) |
|
Timezone: Railway siempre interpreta el schedule en UTC. Ajusta la hora según tu zona:
Zona
UTC offset
8am en UTC
5pm en UTC
CDMX verano (CDT)
UTC-5
0 13 * * 1-5
0 22 * * 1-5CDMX invierno (CST)
UTC-6
0 14 * * 1-5
0 23 * * 1-5Colombia / Perú
UTC-5
0 13 * * 1-5
0 22 * * 1-5Argentina
UTC-3
0 11 * * 1-5
0 20 * * 1-5España (verano)
UTC+2
0 6 * * 1-5
0 15 * * 1-5
Para verificar que funciona, usa el botón "Run Now" en cada servicio y revisa los logs. Deberías ver Timer iniciado o Timer detenido.
Opción B — VPS / servidor Linux (Ubuntu, Debian, etc.)
No necesitas tokens.json si defines ZOHO_REFRESH_TOKEN en el entorno. Clona el repo, instala dependencias y registra los crons:
git clone https://github.com/tu-org/zoho-projects-mcp.git /opt/zoho-mcp
cd /opt/zoho-mcp
npm install
cp .env.example .env # edita con tus valores, incluyendo ZOHO_AUTO_TIMER_* y ZOHO_REFRESH_TOKENEdita el crontab:
crontab -eAgrega las dos líneas (ajusta la hora a tu zona horaria del servidor):
0 8 * * 1-5 cd /opt/zoho-mcp && node scripts/auto-timer.js start >> /var/log/zoho-timer.log 2>&1
0 17 * * 1-5 cd /opt/zoho-mcp && node scripts/auto-timer.js stop >> /var/log/zoho-timer.log 2>&1Si el servidor corre en UTC, convierte las horas igual que en Railway. Verifica la zona del servidor con
timedatectly cámbiala si quieres usar hora local:sudo timedatectl set-timezone America/Mexico_City.
Opción C — Mac o Linux local (la máquina debe estar encendida a esas horas)
Requiere tokens.json generado por npm run setup. Registra los crons con crontab -e:
0 8 * * 1-5 cd /ruta/al/proyecto && node scripts/auto-timer.js start >> /tmp/zoho-timer.log 2>&1
0 17 * * 1-5 cd /ruta/al/proyecto && node scripts/auto-timer.js stop >> /tmp/zoho-timer.log 2>&1En Mac, si la máquina duerme exactamente a esa hora el cron puede no dispararse. Una alternativa más robusta en Mac es usar launchd en lugar de crontab.
Solución de problemas
Síntoma | Posible causa |
| Faltan esas variables de entorno |
| El timer no se inició antes (revisa logs del servicio start) |
| El refresh token expiró — corre |
Timer descartado (< 30 segundos) | Normal si se prueba con "Run Now" dos veces seguidas muy rápido |
Arquitectura
src/
├── server.js # Punto de entrada MCP — registra las 20 herramientas con esquemas Zod
├── zoho-client.js # Cliente HTTP singleton — refresco automático de tokens en 401
└── setup-auth.js # Flujo OAuth2 de una sola vez
scripts/
├── auto-timer.js # Cron — inicia/detiene timer automáticamente (Railway, VPS o local)
├── my-open-tasks.js # Utilidad CLI — tareas abiertas del equipo en todos los proyectos
└── my-mentions.js # Utilidad CLI — comentarios que te mencionan, con filtro de fechasEl cliente HTTP (zoho-client.js) intercepta respuestas 401, renueva el access token usando el refresh token y reintenta la solicitud original de forma transparente. Para endpoints que requieren application/x-www-form-urlencoded (como addbulktimelogs) expone postForm() en lugar del post() estándar que envía JSON.
Archivos sensibles
Los siguientes archivos contienen credenciales y están excluidos del repositorio (.gitignore):
.env— variables de entorno con credenciales OAuthtokens.json— tokens de acceso activos generados pornpm run setup
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- 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/falegria86/zoho-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server