Timezone MCP

Matemáticas de zonas horarias para programar entre fronteras: convertir, comparar, encontrar ventanas de superposición, próxima hora laboral. Sin red.

Documentación

mcp-timezone

Servidor MCP para conversión de zonas horarias y planificación de reuniones: programa una reunión entre zonas horarias. Encuentra espacios para reuniones dentro del horario laboral de todos.

Funciona con Claude Desktop, Claude Code, Cursor y cualquier cliente del Model Context Protocol. Se ejecuta en tu propia máquina, o alojado sin instalación.

Página del producto: https://mcp.zovo.one/s/timezone — qué hace, las herramientas que expone y un endpoint de token en vivo.

Instalación

Alojado, nada que instalar. Obtén un token de https://mcp.zovo.one/mcp/connect (la página de conexión) o https://mcp.zovo.one/mcp/token (el mismo token como JSON); se emite uno anónimo gratuito al instante y una clave Pro funciona igual. Luego apunta un cliente MCP a https://mcp.zovo.one/mcp/timezone mediante streamable-http y envía el token como Authorization: Bearer <token>.

Si tu cliente no puede configurar cabeceras, pon el token en la ruta: https://mcp.zovo.one/mcp/timezone/t/<token>. Ambas formas funcionan. La URL desnuda sin token responde 401 en tools/call, así que el token no es opcional.

Claude Desktop, un clic. Descarga timezone.mcpb desde la última versión y haz doble clic.

Desde el código fuente. El espejo es autocontenido: cada dependencia de @theluckystrike/* está incluida, así que un clon nuevo compila sin configuración adicional.

git clone https://github.com/theluckystrike/mcp-timezone.git
cd mcp-timezone
npm install && npm run build

Luego apunta tu cliente al punto de entrada compilado:

{
  "mcpServers": {
    "timezone": {
      "command": "node",
      "args": ["/absolute/path/to/mcp-timezone/dist/index.js"]
    }
  }
}

@theluckystrike/mcp-timezone aún no está publicado en npm, así que un comando npx -y @theluckystrike/mcp-timezone fallará. Las tres rutas anteriores son las que funcionan y cada una es verificada por CI.

timezone demo

Espejo de solo lectura de mcp-servers/servers/timezone. Ver MIRROR.md.

Trabaja con clientes en otros países sin hacer aritmética de zonas horarias mentalmente. Pregunta "¿qué hora es para María en Lisboa", "convierte las 3pm de Varsovia a Nueva York y Bangalore", o "encuentra una hora la próxima semana que funcione para mí, mi cliente en Nueva York y mi diseñador en Londres" y obtén una respuesta accionable: espacios de reunión clasificados donde todos están dentro de su propio horario laboral, el solapamiento diario exacto, cuándo cambian los relojes, cuántos días hábiles son una fecha de entrega, y un archivo de calendario que puedes enviar. Contactos guardados, horarios laborales y nada más viven como JSON plano en tu propia máquina.

Creado por theluckystrike.

En el Registro MCP oficial (io.github.theluckystrike/timezone-world-clock-meeting-slots-overlap-ics).

Encuentra una hora de reunión que funcione para todos en el extranjero, convierte cualquier hora entre ciudades y escribe la invitación, sin configuración, todo local.

Instalación en 60 segundos

La publicación en npm para @theluckystrike/mcp-timezone está pendiente. Hasta entonces, el paquete de un clic .mcpb o un clon+compilación son la ruta que funciona, ambas verificadas abajo.

Un clic (.mcpb): descarga timezone.mcpb desde la última versión y haz doble clic en Claude Desktop: https://github.com/theluckystrike/mcp-servers/releases/latest

(claude_desktop_config.json):

{
  "mcpServers": {
    "timezone": {
      "command": "npx",
      "args": ["-y", "@theluckystrike/mcp-timezone"]
    }
  }
}

Claude Code:

claude mcp add timezone -- npx -y @theluckystrike/mcp-timezone

(.cursor/mcp.json):

{
  "mcpServers": {
    "timezone": {
      "command": "npx",
      "args": ["-y", "@theluckystrike/mcp-timezone"]
    }
  }
}

La forma npx anterior empieza a funcionar en cuanto el paquete se publique. Hasta entonces, usa el paquete .mcpb anterior, o compila desde el código fuente con exactamente estos tres comandos:

git clone https://github.com/theluckystrike/mcp-servers.git && cd mcp-servers
npm install
npm run build -w packages/mcp-license -w servers/timezone

Luego apunta el command de tu cliente a node con un argumento: la ruta absoluta a servers/timezone/dist/index.js.

Para ejecutar en modo Pro, configura MCP_LICENSE_KEY en el mismo bloque de configuración, o llama a license_activate una vez con tu clave.

Herramientas

HerramientaQué hace
nowLa hora actual en cualquier lista de lugares, con la abreviatura de zona y el desplazamiento UTC. Sin argumentos: la zona de esta máquina y UTC.
convert_timeConvierte una hora de un lugar a cualquier número de otros. Lee "2026-09-10 15:00", una marca de tiempo ISO, o "3pm tomorrow" como hora de pared en from_zone; un Z final o un desplazamiento explícito tiene prioridad sobre from_zone. Señala un resultado del día siguiente o anterior, y indica qué ocurrencia usó en un pliegue de DST (gap, fold).
find_meeting_slotsHoras clasificadas donde cada participante está dentro de su propio horario laboral, en una cuadrícula de 30 minutos, omitiendo fines de semana. Clasificadas por equidad (ver abajo).
overlapLa ventana diaria cuando cada lugar listado está trabajando, en UTC y en cada reloj local, calculada en una fecha real para que las semanas de DST sean honestas.
dst_changesCada cambio de reloj en un lugar durante un año: el instante UTC exacto, el desplazamiento antes y después, y la hora local a cada lado.
business_daysDías hábiles entre dos fechas en un lugar, excluyendo fines de semana y cualquier festivo que pases. Las fechas son estrictas: 2026-02-30 se rechaza, nunca se redondea hacia adelante.
ics_createEscribe un archivo de calendario .ics para una reunión y devuelve la ruta. Los asistentes con correo electrónico son invitados; un nombre sin correo se lista en la descripción. organizer_email escribe la línea ORGANIZER.
contacts_setRecuerda la zona y el horario laboral de un cliente o compañero.
contacts_listTodos los que has guardado, su hora local ahora y si están dentro del horario laboral.
license_statusGratis o Pro, y dónde actualizar.
license_activateActiva una clave Pro (verificada sin conexión).

También se exponen: el recurso tz://contacts (contactos guardados y su hora local actual) y el prompt schedule_with (propone horas con contactos guardados, luego ofrece escribir la invitación).

Lo que puedes decir

No se requieren nombres de herramientas.

Tú dicesHerramienta
"¿Qué hora es ahora en Varsovia, Nueva York y Bangalore?"now
"Convierte las 3pm de Varsovia del 10 de septiembre a Nueva York e India."convert_time
"Encuentra una hora la próxima semana para mí en Varsovia, mi cliente en Nueva York y mi diseñador en Londres."find_meeting_slots
"¿Cuándo están trabajando a la vez Varsovia y Nueva York?"overlap
"¿Cambian los relojes en Varsovia antes de nuestra llamada de marzo?"dst_changes
"¿Cuántos días hábiles hay del 1 al 30 de septiembre, excluyendo el 15?"business_days
"Escríbeme el .ics para el jueves a las 3pm de Varsovia, 45 minutos, invita a maria@acme.com."ics_create
"Recuerda que María está en Lisboa y trabaja de 10 a 6."contacts_set
"¿Quién está despierto ahora mismo?"contacts_list

Ejemplo práctico

You: Find an hour next week for me in Warsaw, my client in New York and my designer in London.

  find_meeting_slots { participants: [{name:"Me",zone:"Warsaw"},{name:"Client",zone:"New York"},
                                     {name:"Designer",zone:"London"}], duration_minutes: 60, days: 5 }

Assistant: 15 slots fit all 3 participants. Best first:
  1. 2026-09-07T13:30:00.000Z  fairness 3.00h
     Me 15:30-16:30 | Client 09:30-10:30 | Designer 14:30-15:30

Tres horas de equidad no es un defecto en la clasificación, es la verdad sobre Varsovia y Nueva York: con días de 09:00-17:00 en ambos lados, la ventana compartida es solo 15:00-17:00 en Varsovia, así que la reunión de alguien siempre está lejos del medio de su día. La puntuación lo dice en lugar de ocultarlo. Amplía las horas de una persona y la puntuación mejora.

You: Write the invite for that one, 45 minutes, and send it to maria@acme.com.

  ics_create { title:"Kickoff with Acme", start:"2026-09-10 15:00", zone:"Warsaw",
               duration_minutes:45, attendees:[{name:"Maria Nowak", email:"maria@acme.com"}],
               organizer_email:"you@yourdomain.com" }

Assistant: Wrote /Users/you/.local/share/mcp-servers/timezone/meeting.ics
Kickoff with Acme: 2026-09-10 15:00 Thu (CEST, UTC+02:00) for 45 min
DTSTART 2026-09-10T13:00:00.000Z (UTC)

Cómo funciona la clasificación

find_meeting_slots puntúa cada candidato por la distancia del peor participante desde las 13:00 local, en horas, y ordena ascendente. El peor, no el promedio, a propósito: un espacio agradable para dos personas y a las 07:00 para la tercera nunca debe superar a uno que sea a las 10:00 para todos. Una equidad de 0 significaría que la reunión está al mediodía para todos; cualquier valor por debajo de aproximadamente 2 es cómodo.

Un espacio solo se ofrece cuando toda la reunión, de principio a fin, está dentro de la ventana laboral de cada participante, en su propio día calendario local. Se omiten los fines de semana en la zona del primer participante. Ningún espacio comienza antes de earliest_date; si pasas una hora con eso, no se proponen espacios más temprano ese día.

Cuando nada encaja, el servidor lo dice, muestra las ventanas y luego lista las horas más cercanas que son el horario de alguien, clasificadas por los minutos totales fuera, con la hora local de cada persona y los horarios laborales que harían que cada uno encajara. En el nivel gratuito, una búsqueda de más de 5 días se acorta a 5 días y la respuesta lo dice; nunca se rechaza rotundamente.

Cómo se resuelven los lugares

Los nombres de ciudades y países se resuelven mediante una tabla integrada de 490 entradas (más de 300 ciudades, cada país de uso común y abreviaturas de estados de EE. UU.). Cada entrada se verifica contra Intl.supportedValuesOf("timeZone") al inicio; una entrada que esta compilación de Node no puede resolver se descarta con una línea en stderr en lugar de responder silenciosamente con la zona incorrecta.

  • Un país que abarca varias zonas se asigna a su zona comercial principal: Estados Unidos -> America/New_York, Australia -> Australia/Sydney, Canadá -> America/Toronto, Brasil -> America/Sao_Paulo, Rusia -> Europe/Moscow, México -> America/Mexico_City, Indonesia -> Asia/Jakarta. Nombra una ciudad cuando necesites una diferente.
  • Los IDs de IANA siempre funcionan y siempre ganan: pasa America/Denver y obtienes exactamente eso.
  • Los desplazamientos estilo UTC+2 se resuelven a la zona fija correspondiente (Etc/GMT-2, los signos de Etc están invertidos por la base de datos de IANA, no por este servidor).
  • Una abreviatura fija es un desplazamiento, no un lugar. EST es Etc/GMT+5 (UTC-05:00) todo el año, PST es Etc/GMT+8, CET es Etc/GMT-1, JST es Etc/GMT-9. Mapearlos a una zona con DST hizo que EST significara EDT (UTC-04:00) cada verano, una hora equivocada durante medio año. Cada respuesta lleva una nota nombrando el lugar a pasar en su lugar ("New York", "Los Angeles", "Paris"). Las abreviaturas regionales ET, CT, MT, PT aún nombran lugares y mantienen sus cambios de reloj. IST se lee como India (UTC+05:30, Asia/Kolkata, sin horario de verano) y la nota lo dice, porque IST también nombra la hora irlandesa e israelí.
  • Un nombre desconocido nunca se adivina. Vuelve como un error con sugerencias: unknown time zone or place: "Warsawa". Did you mean: warsaw (Europe/Warsaw)?

El DST no se almacena aquí en absoluto. Cada desplazamiento proviene de los datos de ICU dentro de tu compilación de Node mediante Intl.DateTimeFormat, así que las reglas se mantienen actualizadas a medida que Node se actualiza en lugar de quedar obsoletas en una tabla incluida.

Gratis vs Pro

GratisPro
now, convert_time, overlap, dst_changes, business_daysIlimitadoIlimitado
Participantes de find_meeting_slotsHasta 3Ilimitado
Ventana de búsqueda de find_meeting_slotsHasta 5 días (una solicitud más larga se acorta, no se rechaza)Ilimitado
Búsqueda de espacios recurrentes (recurring: true)--Sí
Contactos guardados5Ilimitado
Archivos .ics3 por mesIlimitado

Pro cuesta $19 de una sola vez, o $39 por cada servidor en el paquete: Obtener Pro. La activación es sin conexión: las claves son firmas Ed25519 verificadas contra una clave pública compilada en el paquete.

Cómo almacena datos

Los contactos y el contador mensual de .ics viven en un archivo JSON: ${XDG_DATA_HOME:-~/.local/share}/mcp-servers/timezone/data.json.

Cada escritura ocurre bajo un bloqueo de asesoramiento en .../timezone/.lock, mantenido durante todo el ciclo de cargar-modificar-guardar, para que dos clientes que comparten un directorio de datos no puedan descartar los contactos del otro. El guardado escribe un archivo temporal y lo renombra en su lugar, así que un bloqueo a mitad de escritura deja el archivo antiguo o el nuevo.

Si data.json alguna vez es ilegible o no es JSON válido, el servidor no lo trata como "sin contactos aún". Mueve el archivo a un lado byte por byte como data.json.corrupt-<timestamp>, escribe un marcador data.json.corrupt, y cada llamada posterior falla con data file is corrupt; moved to ...; nothing was written hasta que restaures una copia buena y elimines el marcador.

Fechas, horas y advertencias honestas

  • Una hora sin offset es hora de pared en from_zone, no UTC. 2026-09-10 15:00 con from_zone: "Warsaw" son las 15:00 en Varsovia. Un Z final o un +05:30 explícito se respeta exactamente y from_zone se usa solo para la visualización.
  • Una fecha de calendario se valida, no se normaliza. 2026-02-30 se rechaza con el motivo (febrero de 2026 tiene 28 días) en todos los lugares donde se lee una fecha: convert_time, overlap, business_days, ics_create y la lista de festivos. Nada se adelanta a marzo.
  • Una hora de pared dentro de un salto hacia adelante no existe y se rechaza. 02:30 el 2026-03-29 en Varsovia devuelve un error que nombra ambos vecinos válidos (2026-03-29 01:30 y 2026-03-29 03:30). Pasa gap:"forward" para tomar la hora después del salto o gap:"backward" para la anterior; la respuesta entonces indica cuál usó. Adivinar en silencio es cómo una reunión se mueve una hora una vez al año.
  • Las horas ambiguas en el pliegue de otoño devuelven la PRIMERA ocurrencia y lo indican: 02:30 el 2026-10-25 en Varsovia es 00:30Z, la lectura CEST. Pasa fold:"second" para 01:30Z, la CET. Ambas respuestas nombran la abreviatura y el offset que usaron.
  • Los asistentes de .ics son direcciones de calendario. Un asistente con un correo electrónico se convierte en ATTENDEE;CN="Name";RSVP=TRUE:mailto:addr, con CN escrito como un valor de parámetro RFC 5545 entre comillas. Un nombre sin correo electrónico se lista en DESCRIPTION en lugar de escribirse como una dirección no enrutable. Cualquier CR, LF o carácter de control en cualquier campo se rechaza, no se escapa: es lo que parece una inyección de línea de contenido. organizer_email escribe la línea ORGANIZER; sin ella no se escribe ORGANIZER y la respuesta lo indica, porque las respuestas no tendrían a dónde ir.
  • Los archivos .ics llevan horas UTC (DTSTART:20260910T130000Z) y sin bloque VTIMEZONE. Esto es deliberado: un VTIMEZONE escrito a mano con reglas de DST obsoletas es la forma clásica de que una invitación llegue con una hora de diferencia.
  • El horario laboral es el único calendario que tiene este servidor. No conoce tus reuniones existentes, festivos públicos (pásalos a business_days tú mismo) ni el almuerzo de nadie. business_days lo indica en su propia respuesta cuando no se pasa una lista de festivos, para que una cifra de "22 días hábiles" nunca se confunda con una ajustada por festivos públicos.
  • Los tamaños de argumentos están limitados, para que un llamador descontrolado no convierta una llamada en un cuelgue o una respuesta enorme: cadenas de lugar y fecha de 100 caracteres, títulos de eventos de 200, descripciones de 5000, hasta 50 zonas, 100 participantes, 100 asistentes, 400 festivos, days <= 366, duration_minutes <= 1440, y un rango de business_days de como máximo 3700 días (los rangos más largos se rechazan, nunca se truncan en silencio).
  • out_path se escribe donde lo nombres. ics_create resuelve una ruta relativa contra el directorio de trabajo del proceso y no la confina al directorio de datos; una ruta no escribible devuelve un EACCES limpio y no consume nada de la cuota mensual gratuita.
  • El salto de fin de semana usa la zona del primer participante y la convención de sábado/domingo. Un fin de semana de viernes a sábado no está modelado; establece work_start/work_end o lee las fechas.

Solución de problemas

  • npx se cuelga o no encuentra el paquete: la publicación de npm está pendiente. Usa el paquete .mcpb o la ruta de clonar y compilar anterior.
  • Una ciudad no se reconoce: el error lista sugerencias. Cualquier ID de IANA siempre funciona, así que America/Argentina/Cordoba está disponible incluso cuando el nombre de la ciudad no está en la tabla.
  • Versión de Node: requiere Node >= 18. Verifica con node -v. Las compilaciones más antiguas traen reglas de DST más antiguas.
  • No aparece nada / fallos silenciosos: este servidor escribe solo en stderr, nunca en stdout. En Claude Desktop revisa Configuración -> Desarrollador -> el registro del servidor; en Claude Code ejecuta con --mcp-debug.
  • Una clave Pro no se reconoce: ejecuta license_status y confirma que MCP_LICENSE_KEY está establecido en el proceso que lanza el cliente, no solo en tu shell.

Privacidad

Todos los datos permanecen locales: los contactos viven en ${XDG_DATA_HOME:-~/.local/share}/mcp-servers/timezone/data.json. El servidor no hace solicitudes de red, no tiene telemetría y no necesita cuenta. Los datos de zona horaria provienen de la base de datos ICU ya incluida en Node.

Se combina con

  • mcp-time-tracker, registra las horas que dedicas a esos clientes y repórtalas.
  • mcp-invoice, convierte las horas registradas en una factura PDF numerada para el cliente en el extranjero.
  • office-suite, varios servidores detrás de una sola instalación, una entrada de configuración.

Preguntas frecuentes

Sí, y no almacena reglas de DST propias. Cada offset se lee de los datos ICU en tu compilación de Node, por lo que Varsovia y Nueva York estando a 5 horas de diferencia (no 6) entre el 8 y el 29 de marzo de 2026 se calcula correctamente.

Porque una superposición real puede tener dos horas de ancho. La puntuación de equidad informa la peor distancia de una persona a su mediodía para que veas el costo y decidas quién lo absorbe.

Sí. India (+05:30), Nepal (+05:45), Adelaida (+09:30) y Chatham se manejan como cualquier otra zona; la cuadrícula de espacios es de 30 minutos, por lo que una zona de media hora produce inicios locales :00 y :30.

No. Solo conoce las horas laborales que le das. Escribe archivos .ics; nunca lee ni se conecta a un servicio de calendario.

No. No hay llamadas de red en ningún lugar, incluida la activación de licencia.

Licencia

MIT

Un perfil de negocio para toda la suite

Tu identidad se almacena una vez, en ${XDG_DATA_HOME:-~/.local/share}/mcp-servers/profile/business.json, y cada servidor de la suite la lee: el emisor de facturas, el membrete de docx, el emisor recurrente, la tasa de IVA predeterminada de expense-tracker, la zona principal de time-tracker y timezone, y los membretes de currículum y contrato. Establécelo una vez con business_set (invoice o docx): nunca lo repites en ningún otro lugar. Una dirección de correo electrónico solo se toma de ese perfil o de un argumento explícito; cuando no hay ninguna almacenada, los documentos muestran [add: email] y la herramienta lo indica en lugar de dejar que alguien improvise una dirección.

Usa estos documentos como servidor MCP

Cualquier cliente MCP (Claude, Cursor, Windsurf, VS Code) puede leer la documentación de este repositorio directamente a través de GitMCP, sin instalación: