Timezone MCP

Matemática de fusos horários para agendamento entre fronteiras: converter, comparar, encontrar janelas de sobreposição, próximo horário comercial. Sem rede.

Documentação

mcp-timezone

Servidor MCP para conversão de fusos horários e planejamento de reuniões: agende uma reunião entre fusos horários. Encontre horários de reunião dentro do horário comercial de todos.

Funciona com Claude Desktop, Claude Code, Cursor e qualquer cliente Model Context Protocol. Roda na sua própria máquina, ou hospedado sem instalação.

Página do produto: https://mcp.zovo.one/s/timezone — o que faz, as ferramentas que expõe e um endpoint de token ao vivo.

Instalação

Hospedado, nada para instalar. Obtenha um token em https://mcp.zovo.one/mcp/connect (a página de conexão) ou https://mcp.zovo.one/mcp/token (o mesmo token como JSON); um token anônimo gratuito é emitido na hora e uma chave Pro funciona da mesma forma. Em seguida, aponte um cliente MCP para https://mcp.zovo.one/mcp/timezone via streamable-http e envie o token como Authorization: Bearer <token>.

Se o seu cliente não puder definir cabeçalhos, coloque o token no caminho: https://mcp.zovo.one/mcp/timezone/t/<token>. Ambas as formas funcionam. A URL simples sem token responde 401 em tools/call, então o token não é opcional.

Claude Desktop, um clique. Baixe timezone.mcpb do último lançamento e clique duas vezes nele.

A partir do código-fonte. O espelho é autossuficiente: cada dependência @theluckystrike/* é incluída, então um clone novo compila sem configuração extra.

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

Em seguida, aponte seu cliente para o ponto de entrada compilado:

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

@theluckystrike/mcp-timezone ainda não está publicado no npm, então um comando npx -y @theluckystrike/mcp-timezone falhará. Os três caminhos acima são os que funcionam e cada um é testado pelo CI.

timezone demo

Espelho somente leitura de mcp-servers/servers/timezone. Veja MIRROR.md.

Trabalhe com clientes em outros países sem fazer aritmética de fusos horários de cabeça. Pergunte "que horas são para a Maria em Lisboa", "converta 15h de Varsóvia para Nova York e Bangalore", ou "encontre uma hora na próxima semana que funcione para mim, meu cliente em Nova York e meu designer em Londres" e obtenha uma resposta acionável: horários de reunião classificados onde todos estão dentro do próprio horário comercial, a sobreposição diária exata, quando os relógios mudam, quantos dias úteis uma data de entrega tem, e um arquivo de calendário que você pode enviar. Contatos salvos, horários de trabalho e nada mais ficam como JSON simples na sua própria máquina.

Construído por theluckystrike.

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

Encontre um horário de reunião que funcione para todos no exterior, converta qualquer hora entre cidades e escreva o convite, sem configuração, tudo local.

Instalação em 60 segundos

A publicação no npm para @theluckystrike/mcp-timezone está pendente. Até lá, o pacote de um clique .mcpb ou um clone+compilação são os caminhos que funcionam, ambos verificados abaixo.

Um clique (.mcpb): baixe timezone.mcpb do último lançamento e clique duas vezes nele no 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"]
    }
  }
}

O formulário npx acima começa a funcionar no momento em que o pacote é publicado. Até lá, use o pacote .mcpb acima, ou compile a partir do código-fonte com exatamente estes três 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

Em seguida, aponte o command do seu cliente para node com um argumento: o caminho absoluto para servers/timezone/dist/index.js.

Para rodar no modo Pro, defina MCP_LICENSE_KEY no mesmo bloco de configuração, ou chame license_activate uma vez com sua chave.

Ferramentas

FerramentaO que faz
nowA hora atual em qualquer lista de lugares, com a abreviação do fuso e o deslocamento UTC. Sem argumentos: o fuso desta máquina e UTC.
convert_timeConverte uma hora de um lugar para qualquer número de outros. Lê "2026-09-10 15:00", um timestamp ISO, ou "3pm tomorrow" como hora de parede em from_zone; um Z final ou um deslocamento explícito vence sobre from_zone. Sinaliza um resultado no dia seguinte ou anterior, e indica qual ocorrência usou em uma dobra de horário de verão (gap, fold).
find_meeting_slotsHorários classificados onde cada participante está dentro do próprio horário comercial, em uma grade de 30 minutos, fins de semana ignorados. Classificados por justiça (veja abaixo).
overlapA janela diária quando cada lugar listado está no trabalho, em UTC e em cada relógio local, calculada em uma data real para que semanas de horário de verão sejam honestas.
dst_changesCada mudança de relógio em um lugar por um ano: o instante UTC exato, o deslocamento antes e depois, e a hora local de cada lado.
business_daysDias úteis entre duas datas em um lugar, excluindo fins de semana e quaisquer feriados que você passar. As datas são estritas: 2026-02-30 é recusado, nunca arredondado para frente.
ics_createEscreve um arquivo de calendário .ics para uma reunião e retorna o caminho. Participantes com e-mail são convidados; um nome sem e-mail é listado na descrição. organizer_email escreve a linha ORGANIZER.
contacts_setLembra o fuso e o horário de trabalho de um cliente ou colega.
contacts_listTodos que você salvou, a hora local deles agora e se estão dentro do horário comercial.
license_statusGratuito ou Pro, e onde atualizar.
license_activateAtiva uma chave Pro (verificada offline).

Também expostos: o recurso tz://contacts (contatos salvos e a hora local atual deles) e o prompt schedule_with (propõe horários com contatos salvos e depois oferece escrever o convite).

O que você pode dizer

Nenhum nome de ferramenta é necessário.

Você dizFerramenta
"Que horas são em Varsóvia, Nova York e Bangalore agora?"now
"Converta 15h de Varsóvia em 10 de setembro para Nova York e Índia."convert_time
"Encontre uma hora na próxima semana para mim em Varsóvia, meu cliente em Nova York e meu designer em Londres."find_meeting_slots
"Quando Varsóvia e Nova York estão ambas no trabalho?"overlap
"Os relógios mudam em Varsóvia antes da nossa chamada de março?"dst_changes
"Quantos dias úteis de 1 a 30 de setembro, excluindo o dia 15?"business_days
"Escreva o .ics para quinta-feira 15h de Varsóvia, 45 minutos, convide maria@acme.com."ics_create
"Lembre que a Maria está em Lisboa e trabalha das 10 às 18."contacts_set
"Quem está acordado agora?"contacts_list

Exemplo prático

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

Três horas de justiça não é uma falha na classificação, é a verdade sobre Varsóvia e Nova York: com dias de 09:00-17:00 em ambos os lados, a janela compartilhada é apenas 15:00-17:00 em Varsóvia, então a reunião de alguém está sempre longe do meio do dia. A pontuação diz isso em vez de esconder. Amplie as horas de uma pessoa e a pontuação melhora.

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)

Como a classificação funciona

find_meeting_slots pontua cada candidato pela distância do pior participante das 13:00 locais, em horas, e ordena de forma crescente. O pior, não a média, de propósito: um horário agradável para duas pessoas e 07:00 para a terceira nunca deve superar um que seja 10:00 para todos. Uma justiça de 0 significaria que a reunião está ao meio-dia para todos; qualquer coisa abaixo de cerca de 2 é confortável.

Um horário só é oferecido quando a reunião inteira, do início ao fim, está dentro da janela de trabalho de cada participante, no próprio dia do calendário local deles. Fins de semana no fuso do primeiro participante são ignorados. Nenhum horário começa antes de earliest_date, se você passar uma hora com isso, horários anteriores naquele dia não são propostos.

Quando nada se encaixa, o servidor diz isso, mostra as janelas e então lista os horários mais próximos que são o horário de alguém, classificados pelos minutos totais fora, com a hora local de cada pessoa e os horários de trabalho que fariam cada um se encaixar. No nível gratuito, uma busca maior que 5 dias é encurtada para 5 dias e a resposta diz isso; nunca é recusada de imediato.

Como os lugares são resolvidos

Nomes de cidades e países são resolvidos por uma tabela embutida de 490 entradas (300+ cidades, todos os países comumente usados e abreviações de estados dos EUA). Cada entrada é verificada contra Intl.supportedValuesOf("timeZone") na inicialização; uma entrada que esta compilação Node não consegue resolver é descartada com uma linha no stderr em vez de responder silenciosamente com o fuso errado.

  • Um país que abrange vários fusos mapeia para seu fuso comercial principal: Estados Unidos -> America/New_York, Austrália -> Australia/Sydney, Canadá -> America/Toronto, Brasil -> America/Sao_Paulo, Rússia -> Europe/Moscow, México -> America/Mexico_City, Indonésia -> Asia/Jakarta. Nomeie uma cidade quando precisar de uma diferente.
  • IDs IANA sempre funcionam e sempre vencem: passe America/Denver e você obtém exatamente isso.
  • Deslocamentos no estilo UTC+2 resolvem para o fuso fixo correspondente (Etc/GMT-2, os sinais Etc são invertidos pelo banco de dados IANA, não por este servidor).
  • Uma abreviação fixa é um deslocamento, não um lugar. EST é Etc/GMT+5 (UTC-05:00) o ano todo, PST é Etc/GMT+8, CET é Etc/GMT-1, JST é Etc/GMT-9. Mapeá-los para um fuso com horário de verão fez EST significar EDT (UTC-04:00) todo verão, uma hora errada por metade do ano. Cada resposta traz uma nota nomeando o lugar para passar em vez disso ("New York", "Los Angeles", "Paris"). As abreviações de região ET, CT, MT, PT ainda nomeiam lugares e mantêm suas mudanças de relógio. IST é lido como Índia (UTC+05:30, Asia/Kolkata, sem horário de verão) e a nota diz isso, porque IST também nomeia o horário da Irlanda e de Israel.
  • Um nome desconhecido nunca é adivinhado. Ele retorna como um erro com sugestões: unknown time zone or place: "Warsawa". Did you mean: warsaw (Europe/Warsaw)?

O horário de verão não é armazenado aqui de forma alguma. Cada deslocamento vem dos dados ICU dentro da sua compilação Node via Intl.DateTimeFormat, então as regras permanecem atuais conforme o Node atualiza em vez de ficarem desatualizadas em uma tabela embutida.

Gratuito vs Pro

GratuitoPro
now, convert_time, overlap, dst_changes, business_daysIlimitadoIlimitado
find_meeting_slots participantesAté 3Ilimitado
find_meeting_slots janela de buscaAté 5 dias (uma solicitação mais longa é encurtada, não recusada)Ilimitado
Busca de horários recorrentes (recurring: true)--Sim
Contatos salvos5Ilimitado
Arquivos .ics3 por mêsIlimitado

Pro custa $19 único, ou $39 para todos os servidores do pacote: Obter Pro. A ativação é offline: as chaves são assinaturas Ed25519 verificadas contra uma chave pública compilada no pacote.

Como os dados são armazenados

Contatos e o contador mensal de .ics ficam em um arquivo JSON: ${XDG_DATA_HOME:-~/.local/share}/mcp-servers/timezone/data.json.

Cada escrita acontece sob um bloqueio consultivo em .../timezone/.lock, mantido durante todo o ciclo carregar-modificar-salvar, então dois clientes compartilhando um diretório de dados não podem descartar os contatos um do outro. O salvamento escreve um arquivo temporário e o renomeia no lugar, então uma falha no meio da escrita deixa o arquivo antigo ou o novo.

Se data.json estiver ilegível ou não for JSON válido, o servidor não trata isso como "sem contatos ainda". Ele move o arquivo para o lado byte a byte como data.json.corrupt-<timestamp>, escreve um marcador data.json.corrupt, e toda chamada posterior falha com data file is corrupt; moved to ...; nothing was written até você restaurar uma cópia boa e excluir o marcador.

Datas, horários e ressalvas honestas

  • Um horário sem offset é o horário de parede em from_zone, não UTC. 2026-09-10 15:00 com from_zone: "Warsaw" é 15:00 em Varsóvia. Um Z final ou um +05:30 explícito é respeitado exatamente e from_zone é então usado apenas para exibição.
  • Uma data de calendário é validada, não normalizada. 2026-02-30 é recusado com o motivo (fevereiro de 2026 tem 28 dias) em todos os lugares onde uma data é lida: convert_time, overlap, business_days, ics_create e a lista de feriados. Nada é jamais adiantado para março.
  • Um horário de parede dentro de uma lacuna de salto para frente não existe e é recusado. 02:30 em 2026-03-29 em Varsóvia retorna como um erro nomeando ambos os vizinhos válidos (2026-03-29 01:30 e 2026-03-29 03:30). Passe gap:"forward" para usar o horário após o salto ou gap:"backward" para o anterior; a resposta então informa qual foi usado. Adivinhar silenciosamente é como uma reunião muda uma hora uma vez por ano.
  • Horários ambíguos na dobra do outono retornam a PRIMEIRA ocorrência e informam isso: 02:30 em 2026-10-25 em Varsóvia é 00:30Z, a leitura CEST. Passe fold:"second" para 01:30Z, a CET. Ambas as respostas nomeiam a abreviação e o offset que usaram.
  • Participantes de .ics são endereços de calendário. Um participante com um e-mail se torna ATTENDEE;CN="Name";RSVP=TRUE:mailto:addr, com CN escrito como um valor de parâmetro RFC 5545 entre aspas. Um nome sem e-mail é listado em DESCRIPTION em vez de ser escrito como um endereço não roteável. Qualquer CR, LF ou caractere de controle em qualquer campo é recusado, não escapado: é assim que uma injeção de linha de conteúdo se parece. organizer_email escreve a linha ORGANIZER; sem ela, nenhum ORGANIZER é escrito e a resposta informa isso, porque as respostas então não têm para onde ir.
  • Arquivos .ics carregam horários UTC (DTSTART:20260910T130000Z) e nenhum bloco VTIMEZONE. Isso é deliberado: um VTIMEZONE escrito à mão com regras de DST desatualizadas é a forma clássica de um convite chegar com uma hora de diferença.
  • Horário de trabalho é o único calendário que este servidor possui. Ele não conhece suas reuniões existentes, feriados públicos (passe-os para business_days você mesmo) ou o almoço de ninguém. business_days informa isso em sua própria resposta quando nenhuma lista de feriados é passada, para que um número de "22 dias úteis" nunca seja confundido com um ajustado por feriados públicos.
  • Os tamanhos dos argumentos são limitados, para que um chamador descontrolado não transforme uma chamada em um travamento ou uma resposta enorme: strings de local e data com 100 caracteres, títulos de eventos com 200, descrições com 5000, até 50 zonas, 100 participantes, 100 participantes de reunião, 400 feriados, days <= 366, duration_minutes <= 1440, e um intervalo de business_days de no máximo 3700 dias (intervalos mais longos são recusados, nunca truncados silenciosamente).
  • out_path é escrito onde você o nomeia. ics_create resolve um caminho relativo em relação ao diretório de trabalho do processo e não o confina ao diretório de dados; um caminho não gravável retorna um EACCES limpo e não consome nada da cota mensal gratuita.
  • A omissão de fins de semana usa o fuso do primeiro participante e a convenção de sábado/domingo. Um fim de semana de sexta a sábado não é modelado; defina work_start/work_end ou leia as datas.

Solução de problemas

  • npx trava ou não encontra o pacote: a publicação do npm está pendente. Use o pacote .mcpb ou o caminho de clonar e compilar acima.
  • Uma cidade não é reconhecida: o erro lista sugestões. Qualquer ID IANA sempre funciona, então America/Argentina/Cordoba está disponível mesmo quando o nome da cidade não está na tabela.
  • Versão do Node: requer Node >= 18. Verifique com node -v. Builds mais antigos trazem regras de DST mais antigas.
  • Nada aparece / falhas silenciosas: este servidor escreve apenas em stderr, nunca em stdout. No Claude Desktop verifique Configurações -> Desenvolvedor -> o log do servidor; no Claude Code execute com --mcp-debug.
  • Uma chave Pro não é reconhecida: execute license_status e confirme que MCP_LICENSE_KEY está definido no processo que o cliente inicia, não apenas no seu shell.

Privacidade

Todos os dados permanecem locais: contatos ficam em ${XDG_DATA_HOME:-~/.local/share}/mcp-servers/timezone/data.json. O servidor não faz requisições de rede, não tem telemetria e não precisa de conta. Os dados de fuso horário vêm do banco de dados ICU já presente no Node.

Combina com

  • mcp-time-tracker, acompanhe as horas que você gasta nesses clientes e reporte-as.
  • mcp-invoice, transforme as horas rastreadas em uma fatura PDF numerada para o cliente no exterior.
  • office-suite, vários servidores em uma única instalação, uma entrada de configuração.

FAQ

Sim, e ele não armazena nenhuma regra de DST própria. Cada offset é lido dos dados ICU na sua build do Node, então Varsóvia e Nova York estando 5 horas separadas (não 6) entre 8 e 29 de março de 2026 sai corretamente.

Porque uma sobreposição real pode ter duas horas de largura. A pontuação de justiça reporta a distância da pior pessoa do seu meio-dia para que você possa ver o custo e decidir quem absorve.

Sim. Índia (+05:30), Nepal (+05:45), Adelaide (+09:30) e Chatham são tratados como qualquer outra zona; a grade de slots é de 30 minutos, então uma zona de meia hora produz inícios locais :00 e :30.

Não. Ele conhece apenas as horas de trabalho que você fornece. Ele escreve arquivos .ics; nunca lê ou se conecta a um serviço de calendário.

Não. Não há chamadas de rede em nenhum lugar, incluindo ativação de licença.

Licença

MIT

Um perfil de negócios para toda a suíte

Sua identidade é armazenada uma vez, em ${XDG_DATA_HOME:-~/.local/share}/mcp-servers/profile/business.json, e cada servidor da suíte a lê: o emissor de faturas, o cabeçalho de carta docx, o emissor recorrente, a taxa de IVA padrão do expense-tracker, o fuso doméstico do time-tracker e do timezone, e os cabeçalhos de currículo e contrato. Defina uma vez com business_set (invoice ou docx) - você nunca repete em nenhum outro lugar. Um endereço de e-mail é sempre obtido apenas desse perfil ou de um argumento explícito; quando nenhum é armazenado, os documentos mostram [add: email] e a ferramenta informa isso em vez de deixar alguém improvisar um endereço.

Use estas documentações como um servidor MCP

Qualquer cliente MCP (Claude, Cursor, Windsurf, VS Code) pode ler a documentação deste repositório diretamente via GitMCP — sem instalação: