todox

O log de onde sua próxima sessão retoma: decisões, becos sem saída, repasses e tarefas em aberto, compartilhados entre máquinas, agentes (Claude Code, Codex, Cursor, VS Code) e pessoas. Notas desatualizadas são sinalizadas, nunca falsificadas; relatórios vêm do log. Hospedado ou auto-hospedado, MIT.

Servidor MCP hospedado

npx add-mcp 'https://www.todox.dev/api/mcp'

Instala no Claude Code, Codex, Cursor e outros

Documentação

todox

Memória de trabalho para desenvolvedores e seus agentes. Não é uma lista de verificação — é um registro que sua próxima sessão pode realmente retomar.

ci licence: MIT live

Um rastreador de issues é escrito de humano para humano. O todox é escrito de agente para agente, com um humano lendo por cima do ombro. Cada tarefa carrega as decisões por trás dela, as abordagens que falharam, as perguntas ainda em aberto e a nota que a última sessão deixou para trás.

Um agente novo chama get_context, lê isso e começa de onde o último parou — sem esbarrar numa parede que alguém já bateu. O briefing é limitado em vez de ilimitado, em linhas e em bytes, e ele relata o que os limites deixaram de fora em vez de cortar em silêncio. Nada é cortado no meio de uma frase: cada registro volta nomeado e datado com sua primeira linha, e um body de null significa que o orçamento foi gasto, não que o registro está vazio.

O que vai num registro

tipoo que significa
decisiono que você escolheu, e por que as alternativas perderam
dead_enduma abordagem que não funcionou — a entrada de maior valor, porque impede a repetição
questionalgo que só um humano pode responder
handoffestado de fim de sessão, escrito para um estranho
notetodo o resto

Duas coisas decorrem de tratar o registro como o produto:

  • Contexto desatualizado é sinalizado, e nunca falsificado. Arquivos vinculados são hashados pelo lado que pode vê-los — o agente — e o servidor armazena os hashes e compara. Se o código avançar, get_context diz que a nota pode estar mentindo. Até que um agente tenha realmente olhado, a nota é marcada como nunca verificada em vez de ser declarada como fresca: contexto que mente é pior que nenhum, e isso inclui mentir sobre o quão certos estamos.
  • Relatórios vêm do registro, não de commits. Cada mudança de status é um evento, então o que eu terminei hoje, quanto tempo levou, qual modelo fez é uma consulta em vez de arqueologia. Uma tarefa definida como doing e abandonada conta como a manhã em que foi definida, não as semanas desde então — e o relatório diz quanto deixou de fora, em vez de dobrar isso no título.
  • Um arquivo pode ser perguntado sobre o que se sabe dele. Os mesmos links que carregam os hashes são legíveis do outro lado: get_file_context recebe um caminho e responde com as tarefas que o tocaram, seus becos sem saída e qualquer nota permanente anexada a ele. Caminhos são dobrados para sua forma relativa ao repositório, então um link feito numa máquina é encontrado de outra.

Por que não a memória que seu agente já tem?

O Claude Code escreve suas próprias notas agora (memória automática, ativada por padrão desde fevereiro de 2026), e o Cursor e o Codex têm as deles. Use-as: elas são boas em lembrar que você prefere pnpm. O que a documentação deles diz, nas próprias palavras, é que são por repositório, por máquina ("local à máquina … não compartilhado entre máquinas") e por ferramenta, e não compartilhado com ninguém ("só você"). O todox é para o que fica fora dessa linha:

  • Duas máquinas, um registro. Um repositório é identificado pelo seu remoto, então a nota deixada no laptop é lida no desktop.
  • Todo agente, um registro. Claude Code, Codex, Cursor e VS Code todos falam MCP; a passagem de bastão que um deixa é o que o próximo lê, seja qual for.
  • As pessoas também. Um projeto pode ser compartilhado, e o registro carrega quem escreveu o quê e qual modelo fez.
  • Uma forma que uma nota num arquivo não tem. Tarefas que abrem e fecham, becos sem saída como seu próprio tipo, um relatório lido do registro, uma nota desatualizada que diz isso — e um briefing que relata o que seus limites deixaram de fora.

Experimente

todox.dev — qualquer um pode se registrar. Pequena implantação pessoal, sem promessa de disponibilidade. Auto-hospede se o registro for importante para você.

Rode o seu próprio

pnpm install
cp .env.example .env.local     # any Postgres 15+; see below for a container
pnpm db:migrate                # idempotent
pnpm seed                      # optional demo account: demo / todox-demo
pnpm dev

Conecte um agente

O todox é um servidor MCP remoto. Não há nada para instalar e nenhum repositório para clonar: aponte qualquer cliente MCP para a URL com um token de agente.

Crie um token na página da Conta e ele lhe entrega texto que você pode colar direto no agente que você usa, além do trecho de configuração para os quatro comuns. A forma é sempre a mesma — uma URL, um cabeçalho:

O Claude Code tem um caminho mais curto. O plugin carrega o servidor, o protocolo de sessão como uma habilidade e um lembrete no início da sessão; ele pede o token uma vez e o mantém nas suas configurações do Claude Code:

claude plugin marketplace add beydemirfurkan/todox
claude plugin install todox@todox

Todo o resto abaixo ainda se aplica a ele — o plugin são as mesmas quatro linhas, instalado em vez de colado. Veja plugin/README.md para o que ele faz e não faz.

# Claude Code. --scope user, because the default is this directory only.
claude mcp add --scope user --transport http todox https://www.todox.dev/api/mcp \
  --header "Authorization: Bearer todox_…"
// OpenCode v1 — ~/.config/opencode/opencode.json.
// MCP key is `mcp` (server name is a direct key under it), NOT `mcpServers`.
// `type` is `"remote"`, NOT `"http"` — the Claude/Cursor/VS Code value is
// silently ignored on OpenCode.
{
  "mcp": {
    "todox": {
      "type": "remote",
      "url": "https://www.todox.dev/api/mcp",
      "headers": { "Authorization": "Bearer todox_…" }
    }
  }
}
// OpenCode v2 — same key, server now nested under `mcp.servers`.
{
  "mcp": {
    "servers": {
      "todox": {
        "type": "remote",
        "url": "https://www.todox.dev/api/mcp",
        "headers": { "Authorization": "Bearer todox_…" }
      }
    }
  }
}
# Codex — ~/.codex/config.toml
[mcp_servers.todox]
url = "https://www.todox.dev/api/mcp"
http_headers = { Authorization = "Bearer todox_…" }
// Cursor — ~/.cursor/mcp.json, the one in your home directory.
{
  "mcpServers": {
    "todox": {
      "type": "http",
      "url": "https://www.todox.dev/api/mcp",
      "headers": { "Authorization": "Bearer todox_…" }
    }
  }
}
// VS Code — the user-level mcp.json ("MCP: Open User Configuration").
// The root key is "servers", NOT "mcpServers". This is the one client
// that differs, and getting it wrong is silent.
{
  "servers": {
    "todox": {
      "type": "http",
      "url": "https://www.todox.dev/api/mcp",
      "headers": { "Authorization": "Bearer todox_…" }
    }
  }
}

A chave de configuração do MCP e o valor de type diferem por agente, e a combinação errada é silenciosamente ignorada — sem erro, sem aviso, a ferramenta simplesmente não aparece:

agentechavetype
Claude CodemcpServers.NAME"http"
OpenCode v1mcp.NAME"remote"
OpenCode v2mcp.servers.NAME"remote"
CursormcpServers.NAME"http"
VS Code (Copilot Chat)servers.NAME"http"
CodexTOML [mcp_servers.NAME]n/a

Onde esses arquivos ficam difere por plataforma, e o VS Code é o que não fica onde um hábito de Linux colocaria:

agentemacOSLinuxWindows
Claude Code~/.claude.jsonigualigual
Cursor~/.cursor/mcp.jsonigualigual
Codex~/.codex/config.tomligualigual
OpenCode~/.config/opencode/opencode.jsonigualigual
VS Code~/Library/Application Support/Code/User/mcp.json~/.config/Code/User/mcp.json%APPDATA%\Code\User\mcp.json

Instale globalmente, não por projeto. Cada uma dessas ferramentas usa por padrão o diretório onde você está — claude mcp add sem escopo, .cursor/mcp.json, .vscode/mcp.json — e uma memória que só existe em um repositório é o oposto do objetivo. Também falha silenciosamente: as ferramentas simplesmente não estão lá no próximo projeto, então o agente nunca as menciona.

Escreva "type": "http" por extenso. Um cliente que encontra um url sem um tende a assumir um comando local e falha com algo pouco útil.

Então diga ao seu agente para usá-lo

Conectar não é o mesmo que ser usado, e a lacuna é maior do que parece. Os instructions de um servidor MCP são leitura de fundo; uma habilidade ou uma regra de CLAUDE.md é uma instrução. Quando discordam, o servidor perde — medido, num projeto novo, com o todox conectado o tempo todo e nunca chamado uma vez.

Então coloque quatro linhas no arquivo de memória que seu agente realmente obedece:

todox MCP is installed here — persistent memory across projects.

- Call `get_context` before starting non-trivial work (cwd = your working
  directory). It registers a new repo by itself.
- `create_task` for anything that will not finish this session.
- Before stopping, `session_status` lists what you touched; leave a
  `log_entry(kind:'handoff')` on each, and `dead_end` for approaches that failed.
- Always pass your own model id.

Ou deixe o instalador fazer:

pnpm install:mcp claude-code --write-memory

Está desligado a menos que seja pedido, porque esse arquivo é seu em vez de nosso, e é idempotente — o bloco é cercado com um comentário HTML, então uma segunda execução o substitui em vez de deixar dois conjuntos de instruções onde o mais antigo vence. Adicione --dry-run para ver o bloco exato primeiro.

Quando as ferramentas não aparecem de jeito nenhum, a falha silenciosa geralmente é uma das duas tabelas acima, e há um comando que lê os arquivos do jeito que cada cliente faz e diz qual:

npx https://github.com/beydemirfurkan/todox/releases/latest/download/todox-mcp.tgz doctor

Por cliente: a entrada, seu type, sua chave raiz, um resquício num local que o cliente nunca lê, se o arquivo de memória carrega o hábito e se o servidor responde ao token que encontrou (mascarado na saída). Também nomeia uma entrada do todox sentada na configuração do checkout atual pelo que ela é. Nada é alterado; docs/mcp.md tem o detalhe.

Se você pular isso e a conta então conectar por dias sem chamar uma ferramenta, o servidor diz isso no topo das suas instruções na próxima sessão — "conectado por N dias e não chamou uma ferramenta" — e entrega ao agente as quatro linhas e o caminho do arquivo de memória do seu cliente, dizendo para anexá-las e para lhe contar que fez. Medido a partir de tool_usage, então é dito apenas enquanto é verdade e para no momento em que uma ferramenta é chamada. É assim que uma conta cujo cliente mudou, ou cujo arquivo de memória nunca foi escrito, volta sem ninguém precisar perguntar.

O arquivo de nível de usuário, não o do projeto. Esta é a mesma armadilha da configuração acima, um diretório adiante:

AgenteO arquivo que se aplica em todo lugar
Claude Code~/.claude/CLAUDE.md
Codex~/.codex/AGENTS.md
Cursor~/.cursor/rules/todox.md
VS Code~/.copilot/instructions/todox.md
OpenCode~/.config/opencode/AGENTS.md

Um AGENTS.md do próprio repositório, e os arquivos de regras por projeto que os editores também leem, aplicam-se apenas dentro daquele checkout. Uma memória entre projetos instalada num projeto é a coisa que esta seção inteira existe para evitar.

A versão mais longa, como uma habilidade. As quatro linhas são o hábito; o protocolo de sessão inteiro — o mesmo texto que o servidor envia em initialize — também pode ficar no diretório de habilidades de nível de usuário do cliente, onde cada um desses clientes carrega um SKILL.md pela sua descrição quando o momento corresponde, e não gasta nada com isso caso contrário:

pnpm install:mcp claude-code --write-skill
AgenteO arquivo de habilidade que ele carrega
Claude Code~/.claude/skills/todox/SKILL.md
Codex~/.agents/skills/todox/SKILL.md
Cursor~/.cursor/skills/todox/SKILL.md
VS Code~/.copilot/skills/todox/SKILL.md
OpenCode~/.config/opencode/skills/todox/SKILL.md

O arquivo é inteiramente do todox — um diretório próprio, nada seu dentro — então uma segunda execução após uma atualização o substitui. É gerado a partir do mesmo texto que as instruções do servidor em vez de escrito duas vezes, que é o que mantém os dois em concordância.

O token fica fora desse arquivo — ele vive na sua configuração MCP. Este é o hábito, não a credencial.

Opcional: modo local

O servidor hospedado não tem sistema de arquivos — mas seu agente tem, e isso é suficiente: ele envia o hash quando vincula um arquivo e chama report_file_hashes com o que encontra depois, então a desatualização funciona por HTTP como em qualquer outro lugar.

O servidor stdio faz essa parte sozinho em vez de pedir. Vale a pena rodar se você preferir não gastar a atenção de um agente nisso, ou quiser que o hash aconteça mesmo quando o agente esquece. Não há nada para clonar:

TODOX_TOKEN=todox_… TODOX_URL=https://www.todox.dev \
  npx https://github.com/beydemirfurkan/todox/releases/latest/download/todox-mcp.tgz

Ou como uma configuração MCP, que é a forma que um agente quer:

{
  "mcpServers": {
    "todox": {
      "command": "npx",
      "args": [
        "-y",
        "https://github.com/beydemirfurkan/todox/releases/latest/download/todox-mcp.tgz"
      ],
      "env": { "TODOX_TOKEN": "todox_…", "TODOX_URL": "https://www.todox.dev" }
    }
  }
}

Não há pacote npm, e isso é uma decisão em vez de uma tarefa pendente. Um Release do GitHub não precisa de conta nem token para publicar ou instalar, então o tarball é toda a distribuição e npx recebe sua URL diretamente. A URL acima sempre resolve para o release mais novo; todo release também carrega um todox-mcp-<version>.tgz se você preferir fixar e escolher quando mover.

Ele carrega apenas o que o servidor stdio realmente carrega — sem Next, sem React, sem driver Postgres, porque fala com a API por HTTP e nunca abre um banco de dados. pnpm pack:mcp o constrói, e falha a construção se qualquer coisa do lado do servidor algum dia encontrar seu caminho de volta para a superfície de ferramentas.

De um clone, pnpm -C /path/to/todox mcp ainda funciona e é o que usar quando você está mudando as próprias ferramentas.

Ferramentas

ferramentao que faz
get_contextChame isso primeiro. Regras permanentes, decisões de projeto e pegadinhas, cada tarefa aberta com suas decisões, becos sem saída, perguntas, arquivos e último handoff — além de avisos de arquivos desatualizados. Resolve um projeto a partir de um slug, um nome ou qualquer caminho dentro dele. Limitado em linhas e em bytes, nunca truncado: cada registro mantém seu id, tipo, data e primeira linha, e um body nulo significa que o orçamento foi gasto — get_task o lê. Tarefas abertas intocadas por 14+ dias voltam como uma linha cada em idle_tasks — título, status, dias ociosos, cabeçalho do último handoff — fora de qualquer orçamento. Passe focus — uma frase sobre para que serve a sessão — e ambos os orçamentos são gastos nos registros que respondem a ela em vez dos mais recentes, que é o que permite que sejam menores.
create_taskCapture o trabalho. Passe cwd ou um project explícito; o esquema da ferramenta exige um antes da chamada ser executada. Registrar um novo também precisa de repo_root ou repo_url. O recibo retorna o caminho da tarefa e o comprimento do corpo sem ecoar o corpo.
update_taskStatus, título, corpo, prioridade. Mover para doing/done é de onde vêm as durações.
log_entryAcrescente um dos cinco tipos. answers_entry_id fecha um question — a única coisa que faz isso.
delete_entryPara uma entrada que estava errada quando foi escrita. Uma ultrapassada por trabalho posterior é história, não um erro — acrescente em vez disso.
activity_reportHoje / esta semana / qualquer janela: durações, modelos, importância, decisões, becos sem saída, perguntas em aberto. format:"markdown" é escrito para ser colado em uma atualização de status.
link_filesAnexe caminhos com seus hashes a uma tarefa ou a uma nota de contexto — os arquivos que o trabalho toca, e o plano que ele segue, onde quer que viva: um caminho fora do repositório é hasheado como qualquer outro, uma URL (um artefato do claude.ai, por exemplo) é mantida como escrita e nunca hasheada. Seguro chamar novamente para o mesmo arquivo.
report_file_hashesSomente hospedado: como os arquivos vinculados se parecem no disco agora. O processo local faz isso por si mesmo.
accept_file_change · unlink_fileLimpe um aviso de desatualização depois de ler a mudança, ou remova um link que parou de significar algo. Nada mais pode limpá-lo — o servidor nunca vê o arquivo.
add_contextConhecimento que sobrevive a uma tarefa; omita o projeto para torná-lo em toda a conta.
get_context_noteUma nota completa, para aquelas cujo corpo o briefing limitou e para ler além de um trecho de busca. Uma entrada que o orçamento não alcançou é lida com get_task.
get_file_contextO que se sabe sobre um arquivo: as tarefas que o tocaram com seus becos sem saída, e as notas anexadas a ele. Absoluto ou relativo ao repositório; ambos encontram um link feito em outra máquina.
session_statusChame antes de terminar. As tarefas que você mudou ou escreveu neste projeto nas últimas 12 horas (qualquer status), cada uma com se um handoff foi escrito desde a última coisa que você fez lá — além de tarefas deixadas doing por 7+ dias sem nada registrado. Ids, títulos, datas e um booleano; o hint diz o que cada lista ainda precisa. A regra de encerramento pede um handoff em cada tarefa tocada, e esta é a lista que ela assumiu que o agente lembraria.
update_context · delete_contextCorrija uma nota que se revelou errada. Um log que só pode ser adicionado deixa de valer a pena ser lido.
searchEm todos os seus projetos, classificados por relevância. Faça a pergunta em palavras; cite uma frase para exigi-la. Faz stemming em inglês e turco, e ainda corresponde ao meio de um identificador. Palavras que apenas um dos dois idiomas trata como ruído são descartadas, então uma pergunta não corresponde a todo registro contendo a palavra "a". kinds restringe a becos sem saída ou decisões; project impede que procure em outro lugar. Pergunte no idioma em que o log está escrito — ele faz stemming, não traduz — e se uma frase não encontrar nada, tente novamente com os identificadores distintivos sozinhos (3+ caracteres; mais curtos correspondem apenas como palavras inteiras).
get_taskUma tarefa com seu log e arquivos vinculados.
list_tasks · list_projectsAs listas simples, quando get_context é mais do que você precisa. Projetos são primeiro os mais recentes por atividade e carregam activity_at.
create_project · update_projectRaramente necessário: create_task com um cwd registra um. Um resumo vale a pena adicionar.
delete_projectO caminho de volta de um cwd digitado errado. Leva o projeto e tudo sob ele; confirm deve ser o slug.
merge_projectsO caminho de volta de um repositório registrado duas vezes. Move tarefas, notas e caminhos para o projeto sobrevivente; confirm deve ser o slug daquele que está sendo mesclado para fora.

Toda ferramenta de escrita aceita um model, e as instruções do servidor dizem ao agente para sempre passá-lo. É isso que torna a divisão por modelo real em vez de adivinhada.

Prompts

Três, porque há três momentos para os quais isto serve. Eles aparecem no menu do seu próprio cliente, então você pode ver o que o servidor faz sem ler nada:

promptquando
start_sessionantes de planejar — leia o que sessões anteriores estabeleceram
wrap_upantes de terminar — deixe um handoff, e os becos sem saída especialmente
standupquando alguém pergunta o que foi feito

Implantação

Um contêiner e um Postgres ao lado. docker-compose.yml na raiz é isso, montado — o banco de dados não publica porta alguma e é alcançável apenas pela rede do compose:

cp .env.example .env       # set POSTGRES_PASSWORD and TODOX_PUBLIC_URL
docker compose up -d --build
docker compose exec app pnpm db:migrate

A migração é uma linha separada de propósito; veja a nota no final desta seção. todox.dev em si executa os mesmos dois contêineres em um único host.

variávelpor quê
DATABASE_URLPostgres. Quando o banco de dados é um vizinho na mesma rede, este é o nome do serviço, e nenhum certificado ou porta pública está envolvido.
DATABASE_POOL_MAXOpcional, padrão 10. Conexões que este processo pode manter. Aumente apenas depois de verificar o próprio max_connections do servidor, que toda réplica compartilha.
TODOX_PUBLIC_URLLinks de verificação, links de redefinição e o trecho de configuração do agente são construídos a partir dele — erre e as pessoas, e seus agentes, caem no host errado.
SMTP_HOST · SMTP_USER · SMTP_PASS · MAIL_FROMSMTP_PORT)Opcional, mas os primeiros quatro juntos. Sem eles, o e-mail é impresso no log do servidor em vez de enviado. A porta padrão é 587 (STARTTLS). O que MAIL_FROM pode ser depende do provedor: um provedor de caixa de correio geralmente quer o endereço que autenticou, enquanto um provedor de chave de API quer qualquer endereço em um domínio verificado com ele. Se um limite de envio for atingido, as mensagens são descartadas e a falha aparece apenas no log.

Execute pnpm db:migrate quando o esquema mudar. Ele deliberadamente não executa na inicialização: DDL competindo entre instâncias de uma implantação contínua é uma má maneira de descobrir contenção de bloqueio, e o esquema é idempotente precisamente para que a decisão possa ser tomada após uma implantação em vez de durante uma. Do host:

docker exec <container> pnpm db:migrate

É também por isso que a imagem mantém suas dependências de desenvolvimento em vez de usar a saída standalone do Next — podá-las remove tsx e tudo sob scripts/, e um banco de dados deliberadamente inalcançável da internet só pode ser migrado de algo já dentro da rede.

Sabendo que realmente foi implantado

Um merge não é uma implantação, e a lacuna entre eles é silenciosa: nada dá erro, o site continua no ar, e o único sintoma é que uma correção que você viu ficar verde não é a que as pessoas estão executando. Em 2026-09-05 esta instância serviu código com dois dias e cinquenta e seis commits de idade, e o que tornou isso visível foi olhar em vez de qualquer coisa relatando.

A tag da imagem é o sha do git e o nome do contêiner muda a cada implantação, então uma linha responde:

docker inspect <container> --format '{{.Config.Image}}'

Compare isso com git rev-parse origin/main. Se diferirem, o código que você está lendo não é o código que está em execução.

Implantações automáticas valem a pena configurar, e valem a pena verificar depois de fazê-lo. Uma plataforma que puxa em um webhook pode ter o interruptor ligado e ainda assim nunca disparar, porque o interruptor e o webhook são duas configurações em dois lugares: esta instância tinha auto-implantação habilitada por semanas enquanto o repositório não tinha webhook algum, então nada nunca foi instruído a olhar. Depois de configurar um, confirme do lado de envio — o log de entrega — em vez do interruptor, porque um webhook apontado para o caminho errado responde alegremente e não faz nada.

Levando seus dados com você

A página da Conta tem um botão Baixar meus dados, e /api/export responde ao mesmo arquivo para um token de portador — então um agente pode escrever o backup sem o resultado passar por um modelo. Ele carrega cada projeto que você possui com suas tarefas, log, notas de contexto e hashes de arquivos, e nada sobre mais ninguém: nenhuma credencial, nenhum colaborador, nenhum token de compartilhamento, e nenhum projeto que foi compartilhado com você, que pertencem a quem os criou.

Carregando um em uma instância que você executa:

pnpm db:import ./todox-export-2026-08-18.json your-username

Aditivo, nunca destrutivo: nada é excluído ou sobrescrito, e um projeto cujo slug está ocupado chega sob o próximo livre. Eventos de tarefa também vêm, então durações em um relatório na cópia restaurada dizem o que diziam no original.

Segurança

Senhas são scrypt; sessões, tokens de agente e links de e-mail são armazenados como hashes apenas. A propriedade é aplicada em um único módulo, e uma linha pertencente a outra pessoa responde 404 em vez de 403 para que ids não possam ser sondados. Limites de taxa vivem no banco de dados, então eles se mantêm entre instâncias.

Detalhes, e uma lista honesta do que não é coberto, em SECURITY.md.

Lacunas conhecidas

  • A metade de substring da busca é indexada apenas onde o banco de dados permite. As duas metades são consultadas separadamente e mescladas, o que é o que permite que qualquer uma use um índice — medido em 110 mil linhas, uma busca caiu de 5,7s para 0,16s apenas no braço de texto completo. O braço ILIKE que encontra identificadores em texto completo não pode precisar de pg_trgm; pnpm db:migrate cria a extensão e seus cinco índices onde o papel pode, e informa isso de qualquer forma. Onde não pode — um Postgres sem contrib, um serviço gerenciado que recusa extensões — esse braço permanece como uma varredura sequencial e pnpm smoke:search imprime SKIP para ele em vez de falhar. A imagem postgres:18 em docker-compose.yml tem isso.
  • A desatualização é por hash de arquivo; por símbolo seria a versão honesta. Hospedado, depende do agente realmente enviar hashes — as instruções pedem, e nada pode forçar isso.
  • A cobertura fica em torno de 39%, e a forma importa mais que o número: a superfície do agente, o limite de autenticação e os repositórios que respondem "isso é seu" estão cobertos, enquanto grande parte da UI não está.
  • As observações veem o que o git pode informar e qual tarefa uma sessão definiu para doing, então respondem "o que mudou" e "em quê" — e nunca "por quê". A metade que carrega o raciocínio é uma transcrição, e a única API de hook que expõe uma pertence a um único cliente.
  • O orçamento de bytes do briefing cobre corpos de logs, corpos de notas e corpos de tarefas. Um eixo ainda é limitado apenas por uma contagem de linhas: os cabeçalhos de entradas e tarefas carregadas, o equivalente a cinquenta tarefas. É muito menor do que o que os orçamentos fixaram — um projeto caiu de 143 KB para cerca de 55 KB apenas no log — mas não é limitado em bytes, e pnpm bench:memory imprime isso para que o próximo leitor não precise descobrir.
  • As observações são capturadas apenas pelo processo local. Observar o git significa executar na máquina que contém o checkout, e o endpoint hospedado não tem nenhum — então, conectado dessa forma, a seção observations de cada briefing permanece vazia e nada em lugar algum a preenche. O caminho "Try-it" neste README é o hospedado, então isso é a maioria das pessoas. npx todox-mcp é o transporte que captura. Todo o resto funciona de forma idêntica de qualquer maneira.
  • Sem 2FA, sem revogação por sessão, sem log de auditoria.
  • Links de compartilhamento são não listados, não controlados por acesso.
  • Sem navegação por teclado além de / para busca.

Lançando uma versão

git tag v0.1.4 && git push origin v0.1.4

Esse é o procedimento. O workflow verifica a tag contra package.json, executa as verificações, compila o pacote stdio e o anexa a um GitHub Release — sem conta e sem credencial envolvidas, então npx <that tarball url> funciona desde a primeira tag.

Dois nomes sobem: todox-mcp-<version>.tgz, e os mesmos bytes como todox-mcp.tgz para que /releases/latest/download/todox-mcp.tgz seja um endereço que vale a pena escrever em uma configuração uma vez. Nada é publicado no npm, de propósito — veja a seção de modo local acima.

server.json fixa a entrada do registro MCP na mesma versão e server-json.test.ts a mantém lá, então a tag, o pacote e o registro se movem juntos ou o lançamento para.

Contribuindo

As regras que o código-fonte realmente segue, e como executar as verificações: CONTRIBUTING.md.

MIT — veja LICENSE.