todox

El registro desde el que se reanuda tu próxima sesión: decisiones, callejones sin salida, traspasos y tareas abiertas, compartidos entre máquinas, agentes (Claude Code, Codex, Cursor, VS Code) y personas. Las notas obsoletas se marcan, nunca se falsifican; los informes provienen del registro. Alojado o autoalojado, MIT.

Servidor MCP alojado

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

Se instala en Claude Code, Codex, Cursor y más

Documentación

todox

Memoria de trabajo para desarrolladores y sus agentes. No es una lista de verificación — es un registro del que tu próxima sesión realmente puede retomar.

ci licence: MIT live

Un rastreador de incidencias está escrito de humano a humano. todox está escrito de agente a agente, con un humano leyendo por encima del hombro. Cada tarea lleva las decisiones detrás de ella, los enfoques que fallaron, las preguntas aún abiertas y la nota que la última sesión dejó atrás.

Un agente nuevo llama a get_context, lee eso y comienza donde el anterior se detuvo — sin chocar con una pared que alguien ya golpeó. El informe está limitado en lugar de ser ilimitado, en filas y en bytes, y reporta lo que los límites omitieron en lugar de recortar en silencio. Nada se corta nunca a mitad de frase: cada registro vuelve nombrado y fechado con su primera línea, y un body de null significa que el presupuesto se gastó, no que el registro está vacío.

Qué va en un registro

tipoqué significa
decisionlo que elegiste y por qué las alternativas perdieron
dead_endun enfoque que no funcionó — la entrada de mayor valor, porque evita la repetición
questionalgo que solo un humano puede responder
handoffestado al final de la sesión, escrito para un desconocido
notetodo lo demás

Dos cosas se desprenden de tratar el registro como el producto:

  • El contexto obsoleto se marca, y nunca se falsifica. Los archivos vinculados se procesan con hash por el lado que puede verlos — el agente — y el servidor almacena los hashes y los compara. Si el código avanza, get_context dice que la nota puede estar mintiendo. Hasta que un agente haya mirado realmente, la nota se marca como nunca verificada en lugar de afirmarse que está fresca: el contexto que miente es peor que ninguno, y eso incluye mentir sobre qué tan seguros estamos.
  • Los informes provienen del registro, no de los commits. Cada cambio de estado es un evento, así que ¿qué terminé hoy, cuánto tardó, qué modelo lo hizo es una consulta en lugar de arqueología. Una tarea marcada como doing y abandonada cuenta como la mañana en que se marcó, no las semanas desde entonces — y el informe dice cuánto omitió, en lugar de plegarlo en el titular.
  • A un archivo se le puede preguntar qué se sabe sobre él. Los mismos enlaces que llevan los hashes son legibles desde el otro extremo: get_file_context toma una ruta y responde con las tareas que la tocaron, sus callejones sin salida y cualquier nota permanente adjunta. Las rutas se pliegan a su forma relativa al repositorio, así que un enlace hecho en una máquina se encuentra desde otra.

¿Por qué no la memoria que tu agente ya tiene?

Claude Code escribe sus propias notas ahora (memoria automática, activada por defecto desde febrero de 2026), y Cursor y Codex tienen las suyas. Úsalas: son buenas para recordar que prefieres pnpm. Lo que su documentación dice, en sus propias palabras, es que son por repositorio, por máquina ("local a la máquina … no compartido entre máquinas") y por herramienta, y no se comparten con nadie ("solo tú"). todox es para lo que queda fuera de esa línea:

  • Dos máquinas, un registro. Un repositorio se identifica por su remoto, así que la nota dejada en la laptop se lee en el escritorio.
  • Cada agente, un registro. Claude Code, Codex, Cursor y VS Code todos hablan MCP; el traspaso que uno deja es lo que el siguiente lee, sea cual sea.
  • Las personas también. Un proyecto se puede compartir, y el registro lleva quién escribió qué y qué modelo lo hizo.
  • Una forma que una nota en un archivo no tiene. Tareas que se abren y cierran, callejones sin salida como su propio tipo, un informe leído del registro, una nota obsoleta que lo dice — y un informe que reporta lo que sus límites omitieron.

Pruébalo

todox.dev — cualquiera puede registrarse. Pequeño despliegue personal, sin promesa de disponibilidad. Auto-aloja si el registro te importa.

Ejecuta el tuyo propio

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

Conecta un agente

todox es un servidor MCP remoto. No hay nada que instalar ni repositorio que clonar: apunta cualquier cliente MCP a la URL con un token de agente.

Crea un token en la página de Cuenta y te entrega texto que puedes pegar directamente en el agente que uses, más el fragmento de configuración para los cuatro comunes. La forma es siempre la misma — una URL, un encabezado:

Claude Code tiene un camino más corto. El plugin lleva el servidor, el protocolo de sesión como habilidad y un recordatorio al inicio de la sesión; pide el token una vez y lo guarda en tu configuración de Claude Code:

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

Todo lo demás abajo aún se aplica a él — el plugin son las mismas cuatro líneas, instalado en lugar de pegado. Ver plugin/README.md para qué hace y qué no hace.

# 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_…" }
    }
  }
}

La clave de configuración de MCP y el valor de type difieren por agente, y la combinación incorrecta se ignora silenciosamente — sin error, sin advertencia, la herramienta simplemente no aparece:

agenteclavetype
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

Dónde viven esos archivos difiere por plataforma, y VS Code es el que no está donde un hábito de Linux lo pondría:

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

Instálalo globalmente, no por proyecto. Cada una de estas herramientas por defecto apunta al directorio donde estás parado — claude mcp add sin un alcance, .cursor/mcp.json, .vscode/mcp.json — y una memoria que solo existe en un repositorio es lo opuesto al punto. También falla silenciosamente: las herramientas simplemente no están en el siguiente proyecto, así que el agente nunca las menciona.

Escribe "type": "http" explícitamente. Un cliente que encuentra un url sin uno tiende a asumir un comando local y falla con algo poco útil.

Luego dile a tu agente que lo use

Conectar no es lo mismo que ser usado, y la brecha es más grande de lo que parece. Los instructions de un servidor MCP son lectura de fondo; una habilidad o una regla de CLAUDE.md es una instrucción. Cuando están en desacuerdo, el servidor pierde — medido, en un proyecto nuevo, con todox conectado todo el tiempo y nunca llamado una vez.

Así que pon cuatro líneas en el archivo de memoria que tu 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.

O deja que el instalador lo haga:

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

Está apagado a menos que se pida, porque ese archivo es tuyo en lugar de nuestro, y es idempotente — el bloque está delimitado con un comentario HTML, así que una segunda ejecución lo reemplaza en lugar de dejar dos conjuntos de instrucciones donde el más antiguo gana. Agrega --dry-run para ver el bloque exacto primero.

Cuando las herramientas no aparecen en absoluto, el fallo silencioso suele ser una de las dos tablas de arriba, y hay un comando que lee los archivos como cada cliente lo hace y dice cuál:

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

Por cliente: la entrada, su type, su clave raíz, un resto en una ubicación que el cliente nunca lee, si el archivo de memoria lleva el hábito y si el servidor responde al token que encontró (enmascarado en la salida). También nombra una entrada de todox sentada en la configuración propia del checkout actual por lo que es. Nada se cambia; docs/mcp.md tiene el detalle.

Si omites esto y la cuenta luego se conecta durante días sin llamar a una herramienta, el servidor lo dice en la parte superior de sus instrucciones en la próxima sesión — "conectado durante N días y no ha llamado a una herramienta" — y le entrega al agente las cuatro líneas y la ruta del archivo de memoria de tu cliente, diciéndole que las agregue y que te diga que lo hizo. Medido desde tool_usage, así que se dice solo mientras es verdad y se detiene en el momento en que se llama a una herramienta. Así es como una cuenta cuyo cliente cambió, o cuyo archivo de memoria nunca se escribió, vuelve sin que nadie tenga que preguntar.

El archivo a nivel de usuario, no el del proyecto. Esta es la misma trampa que la configuración de arriba, un directorio más allá:

AgenteEl archivo que se aplica en todas partes
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

El AGENTS.md propio de un repositorio, y los archivos de reglas por proyecto que los editores también leen, se aplican solo dentro de ese checkout. Una memoria entre proyectos instalada en un proyecto es la cosa para la que existe toda esta sección.

La versión más larga, como habilidad. Las cuatro líneas son el hábito; el protocolo completo de sesión — el mismo texto que el servidor envía en initialize — también puede sentarse en el directorio de habilidades a nivel de usuario del cliente, donde cada uno de estos clientes carga un SKILL.md por su descripción cuando el momento coincide, y no gasta nada en ello de lo contrario:

pnpm install:mcp claude-code --write-skill
AgenteEl archivo de habilidad que carga
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

El archivo es enteramente de todox — un directorio propio, nada tuyo dentro — así que una segunda ejecución después de una actualización lo reemplaza. Se genera desde el mismo texto que las instrucciones del servidor en lugar de escribirse dos veces, que es lo que mantiene a los dos en desacuerdo.

El token se mantiene fuera de ese archivo — vive en tu configuración de MCP. Este es el hábito, no la credencial.

Opcional: modo local

El servidor alojado no tiene sistema de archivos — pero tu agente sí, y eso es suficiente: envía el hash cuando vincula un archivo y llama a report_file_hashes con lo que encuentra después, así que la obsolescencia funciona sobre HTTP como en cualquier otro lugar.

El servidor stdio hace esa parte él mismo en lugar de pedirla. Vale la pena ejecutarlo si prefieres no gastar la atención de un agente en ello, o quieres que el hash ocurra incluso cuando el agente lo olvida. No hay nada que clonar:

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

O como configuración de MCP, que es la forma que un agente quiere:

{
  "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" }
    }
  }
}

No hay paquete npm, y eso es una decisión en lugar de una tarea pendiente. Un Release de GitHub no necesita cuenta ni token para publicar o instalar desde él, así que el tarball es toda la distribución y npx toma su URL directamente. La URL de arriba siempre resuelve al release más nuevo; cada release también lleva un todox-mcp-<version>.tgz si prefieres fijar y elegir cuándo moverte.

Lleva solo lo que el servidor stdio realmente carga — sin Next, sin React, sin controlador de Postgres, porque habla con la API sobre HTTP y nunca abre una base de datos. pnpm pack:mcp lo construye, y falla la construcción si algo del lado del servidor alguna vez encuentra su camino en la superficie de la herramienta de nuevo.

Desde un clon, pnpm -C /path/to/todox mcp aún funciona y es lo que se usa cuando estás cambiando las herramientas mismas.

Herramientas

herramientaqué hace
get_contextLlama a esto primero. Reglas permanentes, decisiones del proyecto y errores conocidos, cada tarea abierta con sus decisiones, callejones sin salida, preguntas, archivos y último traspaso — además de advertencias de archivos obsoletos. Resuelve un proyecto desde un slug, un nombre o cualquier ruta dentro de él. Limitado en filas y en bytes, nunca truncado: cada registro conserva su id, tipo, fecha y primera línea, y un body de null significa que el presupuesto se agotó — get_task lo lee. Las tareas abiertas sin tocar durante 14+ días vuelven como una línea cada una en idle_tasks — título, estado, días inactivos, cabecera del último traspaso — fuera de todo presupuesto. Pasa focus — una frase sobre para qué sirve la sesión — y ambos presupuestos se gastan en los registros que la responden en lugar de los más recientes, que es lo que permite que sean más pequeños.
create_taskCaptura trabajo. Pasa cwd o un project explícito; el esquema de la herramienta exige uno antes de que se ejecute la llamada. Registrar uno nuevo también necesita repo_root o repo_url. El recibo devuelve la ruta de la tarea y la longitud del cuerpo sin repetir el cuerpo.
update_taskEstado, título, cuerpo, prioridad. Pasar a doing/done es de donde salen las duraciones.
log_entryAñade uno de los cinco tipos. answers_entry_id cierra un question — lo único que lo hace.
delete_entryPara una entrada que estaba mal cuando se escribió. Una superada por trabajo posterior es historia, no un error — añade en su lugar.
activity_reportHoy / esta semana / cualquier ventana: duraciones, modelos, importancia, decisiones, callejones sin salida, preguntas abiertas. format:"markdown" está escrito para pegarse en una actualización de estado.
link_filesAdjunta rutas con sus hashes a una tarea o a una nota de contexto — los archivos que toca el trabajo, y el plan que sigue, dondequiera que viva: una ruta fuera del repositorio se hashea como cualquier otra, una URL (un artefacto de claude.ai, por ejemplo) se conserva tal cual y nunca se hashea. Es seguro llamarla de nuevo para el mismo archivo.
report_file_hashesSolo alojado: cómo se ven los archivos enlazados en disco ahora. El proceso local lo hace por sí mismo.
accept_file_change · unlink_fileLimpia una advertencia obsoleta una vez que has leído el cambio, o elimina un enlace que ha dejado de significar algo. Nada más puede limpiarla — el servidor nunca ve el archivo.
add_contextConocimiento que sobrevive a una tarea; omite el proyecto para hacerlo de toda la cuenta.
get_context_noteUna nota completa, para aquellas cuyo cuerpo el resumen limitó y para leer más allá de un fragmento de búsqueda. Una entrada a la que el presupuesto no llegó se lee con get_task.
get_file_contextLo que se sabe de un archivo: las tareas que lo tocaron con sus callejones sin salida, y las notas adjuntas. Absoluta o relativa al repositorio; ambas encuentran un enlace hecho en otra máquina.
session_statusLlama antes de terminar. Las tareas que cambiaste o escribiste en este proyecto en las últimas 12 horas (cualquier estado), cada una con si se escribió un traspaso desde lo último que hiciste allí — además de tareas dejadas en doing durante 7+ días sin nada registrado. Ids, títulos, fechas y un booleano; el hint dice qué necesita aún cada lista. La regla de cierre pide un traspaso en cada tarea tocada, y esta es la lista que asumió que el agente recordaría.
update_context · delete_contextCorrige una nota que resultó equivocada. Un registro al que solo se puede añadir deja de valer la pena leerse.
searchEn todos tus proyectos, ordenados por relevancia. Haz la pregunta en palabras; cita una frase para exigirla. Reduce a raíces en inglés y turco, y aún así coincide con el medio de un identificador. Las palabras que solo uno de los dos idiomas trata como ruido se descartan, así una pregunta no coincide con cada registro que contenga la palabra "a". kinds limita a callejones sin salida o decisiones; project evita que busque en otro lugar. Pregunta en el idioma en que está escrito el registro — reduce a raíces, no traduce — y si una frase no encuentra nada, reintenta solo con los identificadores distintivos (3+ caracteres; los más cortos coinciden solo como palabras completas).
get_taskUna tarea con su registro y archivos enlazados.
list_tasks · list_projectsLas listas simples, cuando get_context es más de lo que necesitas. Los proyectos van primero por actividad más reciente y llevan activity_at.
create_project · update_projectRara vez necesarios: create_task con un cwd registra uno. Vale la pena añadir un resumen.
delete_projectEl camino de vuelta desde un cwd mal escrito. Toma el proyecto y todo lo que hay debajo; confirm debe ser el slug.
merge_projectsEl camino de vuelta desde un repositorio registrado dos veces. Mueve tareas, notas y rutas al proyecto superviviente; confirm debe ser el slug del que se fusiona.

Cada herramienta de escritura toma un model, y las instrucciones del servidor dicen al agente que siempre lo pase. Eso es lo que hace que el desglose por modelo sea real en lugar de adivinado.

Prompts

Tres, porque hay tres momentos para los que esto sirve. Aparecen en el menú propio de tu cliente, así que puedes ver lo que hace el servidor sin leer nada:

promptcuándo
start_sessionantes de planificar — lee lo que sesiones anteriores establecieron
wrap_upantes de terminar — deja un traspaso, y especialmente los callejones sin salida
standupcuando alguien pregunta qué se hizo

Despliegue

Un contenedor y un Postgres a su lado. docker-compose.yml en la raíz es eso, ensamblado — la base de datos no publica ningún puerto y solo es alcanzable a través de la red de compose:

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

La migración es una línea separada a propósito; ver la nota al final de esta sección. todox.dev mismo ejecuta los mismos dos contenedores en un solo host.

variablepor qué
DATABASE_URLPostgres. Cuando la base de datos es un vecino en la misma red, este es su nombre de servicio, y no hay certificado ni puerto público involucrado.
DATABASE_POOL_MAXOpcional, por defecto 10. Conexiones que este proceso puede mantener. Súbelo solo después de revisar el max_connections propio del servidor, que comparte cada réplica.
TODOX_PUBLIC_URLLos enlaces de verificación, los enlaces de restablecimiento y el fragmento de configuración del agente se construyen a partir de él — si lo pones mal, las personas, y sus agentes, aterrizan en el host equivocado.
SMTP_HOST · SMTP_USER · SMTP_PASS · MAIL_FROMSMTP_PORT)Opcionales, pero los primeros cuatro juntos. Sin ellos, el correo se imprime en el registro del servidor en lugar de enviarse. El puerto por defecto es 587 (STARTTLS). Lo que MAIL_FROM puede ser depende del proveedor: un proveedor de buzón suele querer la dirección que autenticó, mientras que un proveedor de clave API quiere cualquier dirección en un dominio verificado con ella. Si se alcanza un límite de envío, los mensajes se descartan y el fallo solo aparece en el registro.

Ejecuta pnpm db:migrate cuando el esquema cambie. Deliberadamente no se ejecuta al inicio: DDL compitiendo entre instancias de un despliegue continuo es una mala forma de descubrir contención de bloqueos, y el esquema es idempotente precisamente para que la decisión pueda tomarse después de un despliegue en lugar de durante uno. Desde el host:

docker exec <container> pnpm db:migrate

Eso también es por lo que la imagen conserva sus dependencias de desarrollo en lugar de usar la salida standalone de Next — podarlas elimina tsx y todo lo que hay bajo scripts/, y una base de datos deliberadamente inalcanzable desde internet solo puede migrarse desde algo ya dentro de la red.

Saber que realmente se desplegó

Una fusión no es un despliegue, y el hueco entre ambos es silencioso: nada da error, el sitio sigue arriba, y el único síntoma es que una corrección que viste pasar a verde no es la que la gente está ejecutando. El 2026-09-05 esta instancia sirvió código de dos días y cincuenta y seis commits de antigüedad, y lo que lo hizo visible fue mirar en lugar de que algo lo informara.

La etiqueta de la imagen es el sha de git y el nombre del contenedor cambia en cada despliegue, así que una línea lo responde:

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

Compáralo con git rev-parse origin/main. Si difieren, el código que estás leyendo no es el código que se está ejecutando.

Los despliegues automáticos valen la pena configurarlos, y vale la pena comprobarlos después de hacerlo. Una plataforma que tira de un webhook puede tener el interruptor activado y aun así nunca dispararse, porque el interruptor y el webhook son dos ajustes en dos lugares: esta instancia tenía el auto-despliegue habilitado durante semanas mientras el repositorio no tenía ningún webhook, así que nada fue avisado nunca para mirar. Después de configurar uno, confirma desde el lado emisor — el registro de entrega — en lugar de desde el interruptor, porque un webhook apuntado a la ruta equivocada responde alegremente y no hace nada.

Llevarte tus datos contigo

La página de Cuenta tiene un botón Descargar mis datos, y /api/export responde al mismo archivo a un token de portador — así un agente puede escribir la copia de seguridad sin que el resultado pase por un modelo. Lleva cada proyecto que posees con sus tareas, registro, notas de contexto y hashes de archivos, y nada sobre nadie más: ninguna credencial, ningún colaborador, ningún token de compartición, y ningún proyecto que se compartió contigo, que pertenecen a quien los hizo.

Cargar uno en una instancia que ejecutas:

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

Aditivo, nunca destructivo: nada se elimina ni se sobrescribe, y un proyecto cuyo slug está ocupado llega bajo el siguiente libre. Los eventos de tarea también pasan, así que las duraciones en un informe sobre la copia restaurada dicen lo que decían en el original.

Seguridad

Las contraseñas son scrypt; las sesiones, los tokens de agente y los enlaces de correo se almacenan solo como hashes. La propiedad se aplica en un solo módulo, y una fila que pertenece a otra persona responde 404 en lugar de 403 para que los ids no puedan sondearse. Los límites de tasa viven en la base de datos, así que se mantienen entre instancias.

Detalles, y una lista honesta de lo que no está cubierto, en SECURITY.md.

Huecos conocidos

  • La mitad de subcadena de búsqueda solo se indexa donde la base de datos lo permite. Las dos mitades se consultan por separado y se fusionan, lo que permite que cualquiera de ellas use un índice — medido en 110k filas, una búsqueda pasó de 5.7s a 0.16s solo en el brazo de texto completo. El brazo ILIKE que encuentra identificadores de texto completo no puede necesita pg_trgm; pnpm db:migrate crea la extensión y sus cinco índices donde el rol lo permite, y lo indica en cualquier caso. Donde no lo permite — un Postgres sin contrib, un servicio gestionado que rechaza extensiones — ese brazo permanece como un escaneo secuencial y pnpm smoke:search imprime SKIP para ello en lugar de fallar. La imagen postgres:18 en docker-compose.yml lo tiene.
  • La obsolescencia es por hash de archivo; por símbolo sería la versión honesta. Alojado, depende de que el agente realmente envíe hashes — las instrucciones lo piden, y nada puede obligarlo.
  • La cobertura ronda el 39%, y la forma importa más que el número: la superficie del agente, el límite de autenticación y los repositorios que responden "¿es esto tuyo?" están cubiertos, mientras que gran parte de la interfaz de usuario no lo está.
  • Las observaciones ven lo que git puede decirles y qué tarea una sesión estableció en doing, por lo que responden "qué cambió" y "en qué" — y nunca "por qué". La mitad que lleva el razonamiento es una transcripción, y la única API de enlace que expone una pertenece a un solo cliente.
  • El presupuesto de bytes del informe cubre cuerpos de registros, cuerpos de notas y cuerpos de tareas. Un eje sigue limitado solo por un recuento de filas: los encabezados de entradas y tareas transportadas, el equivalente a cincuenta tareas. Es mucho más pequeño que lo que los presupuestos fijaron — un proyecto pasó de 143 KB a aproximadamente 55 KB solo en el registro — pero no está limitado en bytes, y pnpm bench:memory lo imprime para que el siguiente lector no tenga que descubrirlo.
  • Las observaciones son capturadas solo por el proceso local. Observar git significa ejecutar en la máquina que tiene el checkout, y el endpoint alojado no tiene ninguno — así que conectado de esa manera, la sección observations de cada informe permanece vacía y nada en ningún lugar la llena. La ruta de prueba en este README es la alojada, por lo que es la mayoría de las personas. npx todox-mcp es el transporte que captura. Todo lo demás funciona de manera idéntica en ambos casos.
  • Sin 2FA, sin revocación por sesión, sin registro de auditoría.
  • Los enlaces compartidos no están listados, no tienen control de acceso.
  • Sin navegación por teclado más allá de / para búsqueda.

Publicar una versión

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

Ese es el procedimiento. El flujo de trabajo verifica la etiqueta contra package.json, ejecuta las comprobaciones, compila el paquete stdio y lo adjunta a una versión de GitHub — sin cuenta ni credencial involucradas, por lo que npx <that tarball url> funciona desde la primera etiqueta.

Dos nombres suben: todox-mcp-<version>.tgz, y los mismos bytes como todox-mcp.tgz para que /releases/latest/download/todox-mcp.tgz sea una dirección que valga la pena escribir en una configuración una vez. Nada se publica en npm, a propósito — consulta la sección de modo local anterior.

server.json fija la entrada del registro MCP a la misma versión y server-json.test.ts la mantiene allí, por lo que la etiqueta, el paquete y el registro se mueven juntos o la versión se detiene.

Contribuir

Las reglas que el código base realmente sigue, y cómo ejecutar las comprobaciones: CONTRIBUTING.md.

MIT — consulta LICENSE.