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.
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
| tipo | qué significa |
|---|---|
decision | lo que elegiste y por qué las alternativas perdieron |
dead_end | un enfoque que no funcionó — la entrada de mayor valor, porque evita la repetición |
question | algo que solo un humano puede responder |
handoff | estado al final de la sesión, escrito para un desconocido |
note | todo 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_contextdice 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
doingy 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_contexttoma 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
typedifieren por agente, y la combinación incorrecta se ignora silenciosamente — sin error, sin advertencia, la herramienta simplemente no aparece:
agente clave typeClaude Code mcpServers.NAME"http"OpenCode v1 mcp.NAME"remote"OpenCode v2 mcp.servers.NAME"remote"Cursor mcpServers.NAME"http"VS Code (Copilot Chat) servers.NAME"http"Codex TOML [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:
| agente | macOS | Linux | Windows |
|---|---|---|---|
| Claude Code | ~/.claude.json | igual | igual |
| Cursor | ~/.cursor/mcp.json | igual | igual |
| Codex | ~/.codex/config.toml | igual | igual |
| OpenCode | ~/.config/opencode/opencode.json | igual | igual |
| 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á:
| Agente | El 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
| Agente | El 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
| herramienta | qué hace |
|---|---|
get_context | Llama 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_task | Captura 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_task | Estado, título, cuerpo, prioridad. Pasar a doing/done es de donde salen las duraciones. |
log_entry | Añade uno de los cinco tipos. answers_entry_id cierra un question — lo único que lo hace. |
delete_entry | Para una entrada que estaba mal cuando se escribió. Una superada por trabajo posterior es historia, no un error — añade en su lugar. |
activity_report | Hoy / 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_files | Adjunta 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_hashes | Solo alojado: cómo se ven los archivos enlazados en disco ahora. El proceso local lo hace por sí mismo. |
accept_file_change · unlink_file | Limpia 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_context | Conocimiento que sobrevive a una tarea; omite el proyecto para hacerlo de toda la cuenta. |
get_context_note | Una 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_context | Lo 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_status | Llama 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_context | Corrige una nota que resultó equivocada. Un registro al que solo se puede añadir deja de valer la pena leerse. |
search | En 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_task | Una tarea con su registro y archivos enlazados. |
list_tasks · list_projects | Las 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_project | Rara vez necesarios: create_task con un cwd registra uno. Vale la pena añadir un resumen. |
delete_project | El camino de vuelta desde un cwd mal escrito. Toma el proyecto y todo lo que hay debajo; confirm debe ser el slug. |
merge_projects | El 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:
| prompt | cuándo |
|---|---|
start_session | antes de planificar — lee lo que sesiones anteriores establecieron |
wrap_up | antes de terminar — deja un traspaso, y especialmente los callejones sin salida |
standup | cuando 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.
| variable | por qué |
|---|---|
DATABASE_URL | Postgres. 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_MAX | Opcional, 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_URL | Los 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_FROM (· SMTP_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
ILIKEque encuentra identificadores de texto completo no puede necesitapg_trgm;pnpm db:migratecrea 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 ypnpm smoke:searchimprimeSKIPpara ello en lugar de fallar. La imagenpostgres:18endocker-compose.ymllo 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:memorylo 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
observationsde 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-mcpes 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.