Una lista de tareas para dos personas, que se puede usar de dos maneras a la vez: desde la página web, o hablándole a Claude por chat. Las dos ven exactamente lo mismo.
La app son dos programas corriendo al mismo tiempo que leen y escriben en un solo archivo. Ese archivo es la lista de verdad; todo lo demás son formas distintas de mirarla.
La página web además se refresca sola cada 10 segundos, así que si la otra persona cambia algo, lo vas a ver aparecer sin tocar nada. Mientras tengas una ventana de edición abierta el refresco se frena, para no borrarte lo que estás escribiendo.
Cada tarea tiene una franja de color a la izquierda y un cartelito con su estado. No hace falta leer nada para saber cómo viene una tarea:
http://localhost:3000; en el servidor va a ser tu dominio.Cada persona tiene la suya, y el nombre que firma cada cambio sale de ahí: no se escribe a mano, así que nadie puede hacerse pasar por otro. Las cuentas se crean en el servidor, con un comando — no hay una pantalla para registrarse, y es a propósito.
npm run usuarios -- listar npm run usuarios -- crear nacho "Nacho" npm run usuarios -- clave nacho npm run usuarios -- borrar nacho
clave — eso además cierra las sesiones abiertas de esa persona.
| Pestaña | Qué muestra | Para qué sirve |
|---|---|---|
| Todas las tareas | Todo, hecho y sin hacer, ordenado por urgencia | El día a día: crear, editar, tildar |
| Pendientes | Solo lo que falta, con el detalle de qué falta de cada una | Ver de un saque el trabajo que queda |
| Personas | El apartado de cada uno: lo que tiene que hacer y lo que ya hizo | Que cada uno sepa qué le toca, sin preguntar |
| Proyectos | Las carpetas para agrupar tareas, con cuántas pendientes tiene cada una | Organizar y ver el avance por proyecto |
| Movimientos | El historial: quién hizo qué y cuándo, en la app y desde Claude | Enterarse de lo que pasó sin preguntar |
| Quiero… | Cómo |
|---|---|
| Crear una tarea | Botón + Nueva tarea. Lo único obligatorio es el título. |
| Marcarla hecha o deshacerla | Click en el cuadradito de la izquierda. Se guarda solo. |
| Editarla | Click en cualquier parte de la tarjeta (no en el cuadradito). |
| Anotar qué falta | Dentro de la tarea, campo ¿Qué falta por hacer? |
| Ponerle fecha límite | Campo Fecha límite. Si pasa, la tarea se pone roja sola. |
| Borrar una tarea | Abrila y usá Eliminar. Pide confirmación. |
| Crear un proyecto | Pestaña Proyectos → + Nuevo proyecto. |
| Borrar un proyecto | Ícono 🗑 en su tarjeta. Se llevan también todas sus tareas: el aviso te dice cuántas. |
| Cerrar una ventana sin guardar | Botón Cancelar, tecla Esc, o click afuera. |
| Cambiar de nombre | Botón 👤 arriba a la derecha. |
La app arranca con dos personas cargadas, Maxi y Alan. En la pestaña Personas hacés click en cualquiera y entrás a su apartado, que está partido en dos bloques: Tiene que hacer arriba y Ya realizadas abajo. Así cada uno abre lo suyo y sabe exactamente qué le toca, sin tener que preguntar.
Para asignar una tarea, arriba de todo del formulario está el desplegable ¿Quién la hace?. Se puede elegir al crearla o cambiarlo después: entrás a la tarea, elegís a la otra persona y guardás. La tarea le desaparece a uno y le aparece al otro al instante.
En la pestaña Proyectos, hacé click en cualquier proyecto y entrás a su apartado: solo sus tareas, sus contadores, y un botón para crear una tarea ya asignada a él. Es también donde caen solas las tareas que pedís desde Claude.
Dentro del apartado de cada proyecto hay un interruptor Compartido. Es lo que decide si ese proyecto forma parte del circuito con Claude.
| 🔗 Compartido | 🔒 Privado | |
|---|---|---|
| La app web | Lo ve y lo edita | Lo ve y lo edita |
| Claude | Lo lista, lee y escribe | No lo ve ni puede tocarlo |
Los proyectos nuevos nacen compartidos, así lo normal funciona sin configurar nada. Apagá el interruptor solo en los que quieras dejar fuera.
La pestaña Movimientos es el diario de la app: cada vez que alguien crea, cambia, completa o borra algo, queda una línea sola, sin que nadie tenga que acordarse de anotarla. Sirve para lo de todos los días: entrar y ver qué pasó desde la última vez que miraste, sin tener que preguntarle nada a la otra persona.
| Cada línea dice | Cómo se ve |
|---|---|
| Cuándo | Agrupado por día, con la hora al costado |
| De dónde vino | 💻 desde la app, 🤖 desde Claude (el chat), ⌨️ desde Claude Code, o ⚙️ desde el servidor (altas de cuentas, restauraciones) |
| Quién | La cuenta con la que se entró; en lo que viene de Claude, el nombre que Claude declare |
| Qué pasó | «Completó la tarea Escribir los textos», «Actualizó la tarea Diseñar la portada (cambió la fecha límite)» |
Todo lo que toca una tarea o un proyecto queda anotado solo, venga de donde venga: de la app o de pedírselo a Claude. Nadie tiene que acordarse de nada.
Lo que no queda solo es el trabajo con Claude que nunca toca una tarea: arreglar un repositorio, desplegar algo, tomar una decisión. Para eso hay dos caminos:
| Dónde | Cómo queda registrado |
|---|---|
| Claude Code (la terminal, los repos) |
Automático. Al cerrar cada sesión, un enganche avisa qué commits se hicieron y qué archivos se tocaron. Si no cambió nada, no anota nada. |
| Chat de claude.ai | Pidiéndoselo: «dejá anotado que desplegamos la app». Las instrucciones del Proyecto ya le dicen que lo haga al terminar cada trabajo. |
Además de lo que se anota solo, con el botón + Anotar algo podés dejar asentado un avance que no es una tarea: «desplegamos la app en el VPS», «el cliente pidió correr la entrega a octubre». Se ven resaltadas en el historial, porque son lo que alguien quiso dejar dicho a propósito. Claude también puede dejarlas, si se lo pedís.
Cada persona conecta la app a su propia cuenta de Claude, una sola vez. Después, desde cualquier chat, le pide cosas en castellano común.
localhost). Mientras la app esté solo en tu PC, el conector no se puede
agregar desde claude.ai.
https://mcp.tudominio.com/mcpAuthorization: Bearer <tu MCP_API_KEY>MCP_API_KEY es una contraseña. Está en el archivo .env del
servidor. Pasásela a la otra persona por un canal privado y no la pegues en ningún
chat grupal, documento compartido ni repositorio.
No hace falta saber los nombres de las herramientas ni los números de las tareas: si le decís «la del flyer», Claude busca la lista y la encuentra.
Si trabajás dentro de un Proyecto de claude.ai, podés dejarlo atado a un proyecto de la app. Después, cuando pidas una tarea desde ese chat, va sola al lugar que corresponde: no tenés que aclarar nunca a qué proyecto pertenece.
npm run vincular -- "Marketing"Listo. A partir de ahí, desde ese Proyecto:
Mismo comando, agregando la ruta. Escribe el bloque en el CLAUDE.md de esa carpeta:
npm run vincular -- "Marketing" --carpeta "C:/ruta/al/repo"
| Herramienta | Qué hace |
|---|---|
listar_proyectos | Lista los proyectos compartidos, con cuántas tareas y cuántas pendientes tiene cada uno |
crear_proyecto | Crea un proyecto |
vincular_proyecto | Busca un proyecto por nombre y lo devuelve; si no existe, lo crea |
eliminar_proyecto | Borra un proyecto y todas sus tareas |
listar_personas | Lista a quiénes se les pueden asignar tareas, y cómo viene cada uno |
listar_tareas | Lista tareas; con only_pending devuelve solo las que faltan, con su detalle. Filtra por persona con assignee y trae las huérfanas con sin_asignar |
obtener_tarea | Trae una tarea puntual por su número |
crear_tarea | Crea una tarea, con o sin proyecto, y ya asignada a alguien si se lo decís |
asignar_tarea | Le pasa una tarea a otra persona, o la deja sin asignar |
actualizar_tarea | Cambia cualquier campo: título, detalle, fecha, proyecto, persona, estado |
completar_tarea | La marca como concluida |
reabrir_tarea | La vuelve a pendiente y anota qué falta |
eliminar_tarea | Borra una tarea |
registrar_movimiento | Deja anotado en el historial un avance que no es una tarea |
ver_movimientos | Lee el historial: qué se hizo, quién, y si fue desde la app o desde Claude |
resumen | Totales, vencidas, cómo viene cada persona, cuántas quedaron sin asignar, y las 10 pendientes más próximas |
Es lo que usa la página por debajo cuando apretás un botón. Todo lo que empieza con
/api pide la clave en el encabezado x-api-key.
| Método | Dirección | Qué hace |
|---|---|---|
| GET | /health | Público. Confirma que el servidor está vivo |
| GET | /api/auth-status | Público. Dice si hace falta clave, sin revelarla |
| POST | /api/auth-check | Público. Valida una clave antes de guardarla |
| GET | /api/projects | Lista proyectos con sus contadores |
| POST | /api/projects | Crea un proyecto |
| PATCH | /api/projects/:id | Edita nombre o descripción |
| DELETE | /api/projects/:id | Borra el proyecto y sus tareas |
| GET | /api/people | Lista las personas con sus contadores |
| POST | /api/people | Suma una persona a la lista |
| PATCH | /api/people/:id | Le cambia el nombre |
| DELETE | /api/people/:id | La saca de la lista. Sus tareas quedan sin asignar, no se borran |
| GET | /api/people/:id/tasks | Su apartado: lo que tiene que hacer y lo que ya hizo, separado |
| GET | /api/tasks | Lista tareas. Admite ?project_id=, ?assignee_id=, ?unassigned=true y ?only_pending=true |
| GET | /api/tasks/:id | Trae una tarea |
| POST | /api/tasks | Crea una tarea |
| PATCH | /api/tasks/:id | Edita una tarea |
| DELETE | /api/tasks/:id | Borra una tarea |
| GET | /api/activity | El historial. Admite ?project_id=, ?source=claude y ?limit= |
| POST | /api/activity | Deja una nota escrita a mano |
| GET | /api/summary | Contadores generales |
| Campo | Qué es |
|---|---|
id | El número de la tarea. Es el que le decís a Claude |
project_id | A qué proyecto pertenece (puede estar vacío) |
assignee_id | Quién la tiene que hacer. Si está vacío, la tarea aparece en «Sin asignar» |
title | El título. Es lo único obligatorio |
description | Descripción libre |
pending_details | Qué falta por hacer — el recuadro ámbar |
done | Si está concluida o no |
due_date | Fecha límite. Si pasa, la tarea se pone roja |
updated_by | Quién la tocó último |
created_at / updated_at | Cuándo se creó y cuándo se modificó |
Requiere Node.js 18 o superior. Parada en la carpeta app-proyectos:
# una sola vez npm install node scripts/gen-env.js # cada vez que la quieras usar npm run dev
Después abrí http://localhost:3000. Para frenarla, Ctrl+C en esa ventana.
npm run smoke
Levanta los dos servidores contra una base descartable y corre 88 pruebas:
seguridad, protocolo de Claude, alta y baja de proyectos y tareas, el filtro de
pendientes, el borrado en cascada y que las dos puertas vean lo mismo.
Tiene que terminar en 0 fallidas.
Con los dos subdominios ya apuntando a la IP del servidor, un solo comando hace todo: instala Node, genera las claves, levanta los dos procesos con PM2, configura Nginx y emite los certificados HTTPS.
APP_DOMAIN="app.tudominio.com" \ MCP_DOMAIN="mcp.tudominio.com" \ LETSENCRYPT_EMAIL="vos@dominio.com" \ bash deploy.sh
Al terminar imprime la MCP_API_KEY, que es la que se usa para conectar Claude.
Después hay que crear las cuentas, porque sin usuarios nadie puede entrar:
npm run usuarios -- crear ana "Ana" npm run usuarios -- crear beto "Beto" npm run usuarios -- crear nacho "Nacho"
deploy.sh si falló a mitad de camino
(por ejemplo, si el DNS todavía no había propagado). No pisa el .env ya creado.
Hay una foto de los proyectos y tareas que se puede volver a poner:
npm run respaldo # saca la foto de como esta todo ahora npm run restaurar # vuelve a crear lo que falte
Restaurar solo agrega lo que no está: nunca pisa ni borra lo que existe. Si una tarea sigue ahí pero cambiada, se la deja como está — manda el trabajo del día, no el respaldo. Se puede correr las veces que haga falta sin duplicar nada.
La sesión dura 30 días. También se cierra si borraste los datos del navegador, si estás en modo incógnito, o si alguien cambió tu contraseña. Volvé a entrar con tu usuario.
No se puede recuperar: en la base solo queda un resumen cifrado, no el texto. Se genera
una nueva en el servidor con npm run usuarios -- clave <usuario>.
Eso también cierra las sesiones abiertas de esa persona.
Después de cinco contraseñas erradas seguidas con el mismo usuario hay que esperar un minuto. Es a propósito: sin esa espera, alguien podría probar contraseñas de a miles.
Los servidores no están corriendo. En tu PC: volvé a correr npm run dev.
En el VPS: pm2 status tiene que mostrar app-web y
app-mcp en online; si no, pm2 restart app-web app-mcp
y mirá el detalle con pm2 logs.
Revisá tres cosas, en este orden: que la URL termine en /mcp, que el
encabezado diga exactamente Authorization: Bearer seguido de la clave
(con el espacio), y que el certificado HTTPS del subdominio esté vigente.
Para descartar, entrá a https://mcp.tudominio.com/health: tiene que
responder algo, no dar error de certificado.
La página se refresca sola cada 10 segundos, pero se frena mientras tengas una ventana de edición abierta. Cerrala y esperá unos segundos. Si aun así no aparece, puede que estén apuntando a servidores distintos.
Es el comportamiento esperado y no tiene deshacer. La única vuelta atrás es un backup:
toda la información vive en el archivo data/app.db. Copialo cada tanto
(junto a app.db-wal si existe) y vas a poder restaurar.
Si tocaste la página (public/), recargá con Ctrl+F5.
Si tocaste el servidor (db.js, server.js,
mcp-server.js), hay que reiniciar los procesos:
pm2 restart app-web app-mcp en el VPS, o cortar y volver a correr
npm run dev en tu PC.
http://localhost:3000 · en el VPS, https://app.tudominio.comhttps://mcp.tudominio.com/mcp.env, en la carpeta de la appdata/app.db — copialo para hacer backupnpm run smoke → 88 pruebas, tiene que dar 0 fallidaspm2 restart app-web app-mcp