Ekyte MCP

Recurso Em desenvolvimento

Ekyte MCP / Ekyte MCP

Servidor MCP + CLI que responde quem lançou e quem não lançou horas no Ekyte, e quanto do pacote mensal de manutenção cada projeto já consumiu. Código canônico: mukutu-mono/apps/ekyte-mcp (privado). Duas superfícies, uma mesma lógica de negócio (src/hours.ts). Fonte: mukutu-mono.

Números deste documento são ilustrativos

Consumo por projeto e nome de cliente são dado comercial e não entram no brain (este site é público). Os exemplos abaixo usam projetos fictícios; o dado real sai da ferramenta, na hora.

Esta página tinha sido apagada — restaurada em 24/09

Arquivado em 28/08, apagado do monorepo e do wiki em 03/09 (3ceb2461) com a justificativa de que o MCP oficial do Ekyte tornava um MCP próprio redundante. A justificativa estava certa sobre a ponte (acesso à API) e errada sobre a política (regras de negócio da Mukutu) — as duas saíram juntas. O que o arquivamento não previu: três rotinas agendadas e um workflow do mkt_central (apontamento-em-massa, coleta-horas-manutencao, verificacao-apontamento-delta, Z99_alerta_franquia_manutencao) dependiam destas ferramentas, sem substituto no oficial — e continuaram rodando de um clone órfão na máquina da Ana (manager-genesis/, já listado como candidato a limpeza de disco). O app foi restaurado ao monorepo em 23/09/2026 (PR #241 política + PR #242 deploy), a partir do commit anterior ao apagamento — que já trazia a correção de cálculo do PR #184 (ver abaixo). Esta nota do vault só foi refeita em 24/09, ao notar o link quebrado durante outra ingestão.

O que faz / What it does

Deriva o time automaticamente (quem tem apontamento nos últimos 30 dias — EKYTE_MCP_ROSTER_WINDOW_DAYS), aplica a meta de horas por pessoa e um calendário de dias úteis, e devolve o semáforo 🔴🟡🟢. / Answers who logged hours and who didn’t.

O semáforo: soma as horas de apontamentos Concluídos (status 20) cujo dia de trabalho é a data avaliada, dentro do escopo. Então:

  • 🔴 vermelho — horas = 0, não lançou nada.
  • 🟡 amarelo — 0 < horas < meta, lançou abaixo da meta.
  • 🟢 verde — horas ≥ meta.

Meta: por pessoa, em config/thresholds.json — hoje 6h para todo o time, sem overrides cadastrados. Ajustar alguém para meio-período é editar esse arquivo, sem tocar no código.

Anti-falso-alarme: janela de atraso de ~4 dias (lançamento tardio ainda conta no dia trabalhado); só dias úteis contam como “faltou” (src/workday.ts + config/holidays.json); fuso America/São_Paulo.

Não é a ponte — é a política / Not the bridge — the policy on top

O MCP oficial do Ekyte (api.ekyte.com/mcp) tem 105 ferramentas de CRUD cru (medido em 23/09/2026) — é para onde vai quem precisa escrever (criar tarefa, apontar hora, mover etapa). Este app não compete com ele; sabe o que o oficial não sabe:

MCP oficial do Ekyteekyte-mcp (este)
Papelacesso à APIpolítica da casa sobre os mesmos dados
Escreve?sim, em produçãonunca — a REST por trás é GET-only
Sabe o que é “meta de 6h/dia”?nãosim
Sabe o que é pacote de manutenção?nãosim

As duas superfícies / The two surfaces

CLI muk-ekyte — saída em tabela colorida no terminal, JSON quando redirecionada (para jq, scripts):

muk-ekyte hours                                    # time todo, hoje — 🔴🟡🟢
muk-ekyte hours --status red,yellow                # só quem está devendo horas
muk-ekyte hours --workspace muk --status red,yellow  # escopo Mukutu
muk-ekyte hours --date 2026-07-15 --format json | jq '.people'
muk-ekyte person "Nome" --period 14                # histórico de 14 dias

MCP ekyte-mcp no Claude Code — registrado no escopo user (vale em todos os projetos). Pergunta em linguagem natural: “quem não lançou horas hoje?”, “status de horas do time em 15/07/2026”, “quem está vermelho ou amarelo no escopo mukutu?”, “status das manutenções deste mês”.

As 6 ferramentas / The 6 tools

FerramentaPergunta que responde
ekyte_hours_status(date?)Time inteiro num dia: horas lançadas vs. meta, com semáforo.
ekyte_missing(date?)Só quem ficou abaixo da meta naquele dia (🔴 + 🟡).
ekyte_person(name, period_days?)Histórico dia a dia de uma pessoa numa janela recente.
ekyte_maintenance_status(month?, workspace?, match?)Por projeto de manutenção: horas do mês vs. o pacote mensal lido do nome do projeto.
ekyte_person_projects(name, month?)De uma pessoa: horas por projeto no mês, em 3 baldes transparentes (cliente / interno Mukutu / não-mapeado).
ekyte_fill_hours_plan(entries)Caminho de escrita (preencher horas) — inerte por design: devolve um plano, nunca escreve. ⚠️ dívida conhecida: o oficial já escreve de verdade com create_time_tracking; esta ferramenta é candidata a sair, mantida por ora para não fragmentar a restauração.

Escopo Mukutu / Mukutu scope

Use --workspace muk. O substring muk casa os ~35 workspaces Mukutu* (incluindo os “Mukutu - Cliente”) e um workspace com erro de digitação no nome — e nenhum outro workspace contém “muk”, então não há falso positivo. Verificado em 17/07/2026: 15 pessoas no escopo. Manutenção semanal: revarrer /workspaces da API e conferir se surgiu workspace Mukutu fora do padrão.

Manutenção: horas do mês vs. pacote / Maintenance packages

Pergunta diferente do semáforo diário: o semáforo é pessoa × dia, este é projeto × mês. Feito para relatório de cliente e diretoria.

  • Pacote — lido do nome do projeto (… - 8h → 8h/mês, regex /(\d+)\s*h\b/). Projeto sem Nh no nome vem como no_package.
  • Consumido — a soma bruta dos apontamentos do mês, o mesmo número que a tela “Estatísticas de Apontamento” do próprio Ekyte mostra. ⚠️ Isto mudou desde a versão anterior desta nota: até o PR #184 (18/08), o cálculo passava pelo join apontamento → tarefa → projeto, que subcontava horas de tarefa já arquivada (caso validado: um projeto leu 18,8h pelo join contra 20h47 reais). O join foi abandonado — hoje, em workspace “puro” de manutenção todo apontamento conta; em workspace “misto” (tem também projeto de site ativo), só conta o que a tarefa nomeia como manutenção.
  • Status — over (estourou o pacote) · ok (dentro) · unused (0h no mês) · no_package.

Exemplo de formato do retorno (projetos fictícios):

ProjetoPacote/mêsConsumido%Status
Cliente A · Manutenção8h5,0h63%ok
Cliente B · Manutenção12h4,8h40%ok
Cliente C · Manutenção20h24,2h121%over
Cliente D · Manutenção8h0h0%unused

O retorno completo traz ainda remaining_hours, end_date, expired, summary (contagem por status) e coverage.

Flag expired: vários projetos de manutenção têm data de término no passado e continuam recebendo horas — renovação não atualizada no Ekyte. O campo marca o caso sem somar nada silenciosamente: o pacote continua válido (a comparação de consumo vale), mas o registro precisa ser corrigido no Ekyte.

ekyte_person_projects nunca devolve um número só: o split cliente × interno é heurística sobre o título da tarefa e pode errar, então vem como balde sinalizado e jamais é somado ao total de cliente. ⚠️ Comportamento conhecido e aceito (24/09): o workspace interno Mukutu cai inteiro no balde de manutenção quando a linha não tem pacote contratado — não é bug, é a regra de hoje.

O frescor viaja dentro da resposta

Toda ferramenta de leitura retorna meta { generated_at, timezone, scope, up_to_date, alert }. Quando up_to_date = false (hoje ainda aberto, mês em andamento, data futura ou janela de lançamento tardio), o alert explica por que o número é provisório — e o aviso é sempre repassado a quem perguntou. O sinal não depende de memória nem de reinício: é a correção durável para “estou olhando dado parcial?”. Lógica em src/format.ts.

Datas: as ferramentas MCP aceitam dd/mm/aaaa ou ISO AAAA-MM-DD (mês mm/aaaa ou AAAA-MM) e sempre retornam dd/mm/aaaa. A CLI ainda usa ISO na flag --date e na saída JSON até ser recompilada.

Escrita de horas: inerte por design / Write path

ekyte_fill_hours_plan é a costura para preencher horas — a API REST do Ekyte é GET-only, então escrever de verdade significa dirigir a UI web via browser (pydoll). A v1 entrega a ferramenta deliberadamente inerte: valida e devolve {status: "plan_only", items, note}, sem abrir browser nem escrever, mesmo se pedirem. O MCP oficial já escreve de verdade (create_time_tracking) — é por isso que esta ferramenta é dívida conhecida, candidata a sair numa limpeza futura.

O serviço hospedado / The hosted service

ekyte-mcp.mukutu.cloud segue no ar (respondeu 400 em /mcp e 200 em /gestores.html em 23/09/2026) — o container nunca foi desligado, mesmo com o app apagado do git por três semanas. Dockerfile, deploy/docker-compose.yml, deploy/traefik-ekyte-mcp.yml.example e scripts/deploy.sh foram recuperados junto (PR #242) — quem hospeda o app consegue reconstruir o container a partir do próprio monorepo de novo. O workflow do GitHub que disparava deploy automático não voltou — de propósito, para o serviço não ganhar vida própria de novo sem decisão humana. O roteiro de encerramento formal (5 passos, GO humano em cada) nunca passou do passo 1.

Fontes de dados / Data sources

Duas camadas, em ordem de prioridade: (1) SurrealDB Mukutu ek_mart_daily — ainda não implantada em produção; (2) API REST do Ekyte /v1.0/time-trackings — o caminho que roda hoje. src/surreal.ts degrada para [] em qualquer erro (nunca lança), então o MCP funciona pela API hoje e passa a usar o mart sozinho quando ele subir.

Segurança da chave / Key handling

EKYTE_API_KEY (credencial da REST, escopo empresa) fica como variável de ambiente do usuário — fora de arquivo versionável, nunca commitada. É diferente do EKYTE_MCP_TOKEN do MCP oficial (de usuário); confundir as duas custa tempo. O servidor MCP herda a chave no momento em que o Claude Code inicia.

Por que importa para a Nova Mukutu / Why it matters

  • Substitui a checagem manual na UI do Ekyte por uma pergunta em linguagem natural — caso de uso direto de Automacoes de IA com dado interno real.
  • O relatório de pacote de manutenção é insumo de cobrança e diretoria: mostra estouro de escopo mês a mês, ligando a Modelo de Orçamento de Produto.
  • Episódio didático de governança: um app pode ser apagado com boa justificativa parcial e continuar vivo, sem registro, sustentado por um clone órfão numa máquina pessoal — o risco que Governança Mukutu e o AI SDLC tentam fechar.

Perguntas a responder / Questions to answer

  • ekyte_fill_hours_plan sai de vez, ou fica como fallback quando o oficial não cobrir algum caso?
  • Quando o ek_mart_daily sobe no SurrealDB (tira a dependência da API REST)?
  • O roteiro de encerramento do serviço hospedado — os 4 passos que faltam — ainda é a decisão certa, ou a restauração de 23/09 muda o plano?

Fontes / Sources

  • mukutu-mono/apps/ekyte-mcp/README.md + src/ (origin/main, lido em 24/09/2026) — 6 tools registradas, comparação com o oficial (105 tools).
  • Commits 3ceb2461 (apagamento, 03/09), c8eecd8/PR #241 (política volta, 23/09), 236122a/PR #242 (deploy volta, 23/09) — mktvirtual/mukutu-mono.
  • docs/mukutu-atividades/levantamento-iniciativas-mukutu.md (mukutu-mono) — item 7.1, revisão de 23/09.