Content
# Cordel
Kanban self-hosted para os TODOs dos seus projetos — pensado para ser
consultado e movimentado direto por agentes como o Claude Code via MCP, sem
depender de um `TODO.md` estático.
Todo/kanban em cima dos projetos em que você está trabalhando de fato. Você
registra um projeto local (via MCP), e ele ganha um board kanban próprio
(Todo/Doing/Done) — com atualização em tempo real (SSE), então se algo
(você, outra aba, um agente como o Claude Code via API) mover um card, todo
mundo vendo o board vê a mudança sem precisar recarregar a página.
Self-hosted: não existe uma instância pública compartilhada nem conta de
usuário — cada pessoa sobe a própria instância (local ou num servidor
próprio) e usa sozinha, sem login.
Cards são **todo local** — ficam num banco SQLite da própria instância.
## Stack
Next.js 16 (App Router, fullstack — sem backend separado) + Prisma 7 +
SQLite + Server-Sent Events pro realtime. Design system próprio em
[rough.js](https://roughjs.com/) pro estilo hand-drawn.
## Rodando localmente
Pré-requisitos: Node 22+, pnpm.
```bash
pnpm install
cp .env.example .env
```
```bash
npx prisma migrate deploy # cria o banco sqlite local (dev.db, na raiz do projeto)
pnpm dev
```
Abre em [http://localhost:3000](http://localhost:3000).
## Rodando com Docker (recomendado pra self-host)
```bash
cp .env.example .env
docker compose up -d --build
```
Isso builda a imagem, roda as migrations automaticamente contra um volume
persistente (`cordel-data`) e sobe a app na porta 3000. Os dados sobrevivem
a `docker compose restart`/`down` (sem `-v`) e a rebuilds da imagem.
Para atualizar depois de puxar código novo:
```bash
docker compose up -d --build
```
## Conectando o Claude Code (MCP)
A ideia original do projeto: em vez do Claude Code checar um `TODO.md` local,
ele consulta e movimenta os cards do Cordel direto — em qualquer board, de
qualquer projeto, sem você ter que copiar/colar nada.
Isso funciona por um servidor MCP incluído em `mcp-server/`, que expõe o
board como ferramentas (`list_repos`, `get_board`, `create_card`,
`update_card`, `move_card`, `delete_card`). Ele fala com a sua instância via
API usando um token.
Projetos entram no Cordel só quando você (ou o agente, a seu pedido) registra
um projeto local em que está trabalhando de fato — nada é puxado
automaticamente de lugar nenhum:
- `scan_local_projects` — dado um diretório raiz (ex: `~/Projects`), lista
as subpastas que têm `.git` (candidatas a projeto). Só lista, não registra
nada.
- `add_local_project` — registra um projeto local (nome + caminho absoluto),
cria o board dele.
- `delete_project` — remove um projeto (e o board junto), permanentemente.
O caminho do projeto local fica salvo só como referência no banco — a app
nunca abre ou lê o conteúdo do diretório, então não precisa configurar
volume nenhum no Docker pra isso funcionar.
O servidor MCP já vem com `instructions` e `annotations` marcando quais
ferramentas são reversíveis (board local, sem problema em agir direto) e
quais são permanentes (`delete_card`, `delete_project` — aí o agente deve
confirmar antes). Isso é automático pra qualquer pessoa que conectar, não
precisa configurar nada.
### 1. Gere um token de API
Com a app rodando, vai em **Tokens** (canto superior direito) ou direto em
`/settings/tokens`, dá um nome e clica em "Gerar token". Copia o valor
mostrado — só aparece essa vez, não tem como recuperar depois (só revogar e
gerar outro na mesma página).
### 2. Registra no Claude Code
```bash
./scripts/connect-claude.sh <token do passo 1>
```
Isso builda o `mcp-server/` e roda o `claude mcp add` sozinho. Se a instância
não estiver em `http://localhost:3000`, passa a URL como segundo argumento:
`./scripts/connect-claude.sh <token> https://cordel.seu-dominio.com`.
A partir daí, em qualquer sessão do Claude Code (nesse projeto ou em
qualquer outro), ele tem as ferramentas do Cordel disponíveis — pode pedir
"lista os repos do Cordel" ou "cria um card no board X" que ele já sabe
chamar a ferramenta certa.
## Variáveis de ambiente
Ver `.env.example` — todas comentadas. Resumo:
| Variável | Pra quê |
|---|---|
| `DATABASE_URL` | Caminho do SQLite. Resolve relativo à raiz do projeto (não `prisma/`). Em Docker é sobrescrito pra apontar pro volume. |
## Estado do projeto
Este projeto documenta seu próprio contexto e pendências em
`.claude/CONTEXT.md` e `.claude/TODO.md` — vale ler antes de contribuir.