CherryTree MCP Server
# CherryTree MCP Server
MCP server que expõe leitura e escrita de arquivos CherryTree `.ctd` (XML) como ferramentas nativas do Claude Code.
Suporta rich text, codeboxes, tabelas, imagens, âncoras e bookmarks. Todas as escritas passam por auditoria byte-a-byte automática comparando o backup com o arquivo resultante no disco.
## Tools disponíveis
### Leitura
- `list_nodes` — listar nodes da árvore (com profundidade e breadcrumb)
- `read_node` — ler conteúdo de um node (texto, formatação, widgets)
- `search_nodes` — busca full-text em todos os nodes
- `list_bookmarks` — listar nodes marcados como favoritos
### Escrita
- `create_node` — criar node (texto plano ou XML rico via `content_xml`)
- `create_node_with_codebox` — criar node com codebox (ou XML rico via `content_xml`)
- `update_node_content` — substituir ou append (texto plano ou XML rico via `content_xml`)
- `append_codebox_to_node` — adicionar codebox ou XML rico a node existente
- `update_node_properties` — alterar nome, tags, ícone, cor, readonly
- `delete_node` — deletar node e filhos
- `move_node` — mover node para outro pai
### Bookmarks
- `add_bookmark` — adicionar node aos favoritos
- `remove_bookmark` — remover node dos favoritos
## Rich Text (`content_xml`)
Os tools de escrita aceitam `content_xml` para formatação completa do CherryTree:
```xml
<rich_text scale="h1" foreground="#00000000ffff" weight="heavy">Título</rich_text>
<rich_text>
Texto normal com </rich_text>
<rich_text weight="heavy">negrito</rich_text>
<rich_text> e </rich_text>
<rich_text style="italic">itálico</rich_text>
<rich_text foreground="#e66100" weight="heavy"> e laranja bold</rich_text>
<rich_text link="node 42">link interno</rich_text>
```
### Atributos suportados em `<rich_text>`
| Atributo | Valores | Exemplo |
|----------|---------|---------|
| `weight` | `heavy` | bold |
| `foreground` | `#RRRRGGGGBBBB` (48-bit GTK) | `#00000000ffff` (azul) |
| `background` | `#RRRRGGGGBBBB` | highlight |
| `style` | `italic` | itálico |
| `underline` | `single` | sublinhado |
| `strikethrough` | `true` | riscado |
| `scale` | `h1`-`h6`, `small`, `sup`, `sub` | headings |
| `family` | `monospace` | monoespaçado |
| `justification` | `left`, `center`, `right`, `fill` | alinhamento |
| `link` | `webs URL`, `node UID`, `file BASE64`, `fold BASE64` | links |
| `indent` | `1`-`3` | indentação |
### Widgets (posicionados por `char_offset`)
Widgets são renderizados inline na posição `char_offset` (contagem de chars no texto concatenado dos `<rich_text>`). Cada widget ocupa exatamente 1 caractere no buffer.
```xml
<codebox char_offset="42" justification="left" frame_width="700"
frame_height="200" width_in_pixels="1"
syntax_highlighting="python3" highlight_brackets="1"
show_line_numbers="0">print("hello")</codebox>
<table char_offset="100" col_min="40" col_max="400"
col_widths="200,200" is_light="0">
<row><cell>valor1</cell><cell>valor2</cell></row>
<row><cell>header1</cell><cell>header2</cell></row>
</table>
<encoded_png char_offset="50" anchor="nome_ancora"/>
```
## Arquitetura
- **Leituras** usam `lxml` para parsing/queries XML (seguro, sem write-back)
- **Escritas** usam manipulação de string raw para evitar normalização de `\r` que corrompe `char_offset` em nodes não editados (bug do `lxml`/`ET` ao serializar)
- **Backup** com timestamp criado automaticamente antes de cada escrita em `.cherrytree-backups/` (mantém os últimos 10)
- **Auditoria** byte-a-byte após cada escrita: lê backup e arquivo novo do disco, compara prefixo/sufixo, identifica node alterado, conta total de nodes, valida XML
### Backups
Toda operação de escrita cria um backup **antes** de modificar o arquivo:
```
Documents/.cherrytree-backups/
Anotações_20260821_000345.ctd
Anotações_20260821_000639.ctd
Anotações_20260821_001800.ctd
...
```
- Formato: `{nome}_{YYYYMMDD_HHMMSS}.ctd`
- Retenção: últimos 10 backups (mais antigos são removidos automaticamente)
- Localização: subpasta `.cherrytree-backups/` no mesmo diretório do arquivo `.ctd`
Para restaurar manualmente:
```bash
cp "Documents/.cherrytree-backups/Anotações_20260821_000345.ctd" "Documents/Anotações.ctd"
```
### Formato de auditoria
Toda operação de escrita retorna um relatório como:
```
[AUDIT] readback 45,120,109 bytes: OK
delta: +252 bytes (45,119,857 -> 45,120,109)
change region: bak[45,119,844:45,119,844] -> disk[45,119,844:45,120,096]
prefix (45,119,844 bytes): OK
suffix (13 bytes): OK
nodes: 5304 (backup) -> 5305 (disco) [+1]
node adicionado: 6481 "Nome do Node" (alvo)
integridade: OK
XML parse: OK
```
Se qualquer byte fora da região alvo diferir entre backup e disco, o relatório exibe `CORRUPTED!` e `INTEGRITY FAILURE`.
Todas as write tools retornam o relatório de auditoria na resposta. Em caso de falha no XML parse, o backup é restaurado automaticamente:
```
XML parse: FAILED — <detalhes do erro>
ROLLBACK: backup restaurado automaticamente
```
## Instalação
### 1. Criar virtualenv e instalar dependências
```bash
cd ~/cherrytree-mcp
python3 -m venv .venv
.venv/bin/pip install -e .
```
### 2. Configurar o MCP no Claude Code
```bash
claude mcp add cherrytree -s user \
-e CHERRYTREE_FILE="/caminho/para/seu/arquivo.ctd" \
-- /caminho/para/cherrytree-mcp/.venv/bin/python \
/caminho/para/cherrytree-mcp/server.py
```
### 3. Reiniciar o Claude Code
As tools aparecem automaticamente como `mcp__cherrytree__<tool_name>`.
## Variáveis de ambiente
| Variável | Descrição |
|----------|-----------|
| `CHERRYTREE_FILE` | Caminho absoluto para o arquivo `.ctd` do CherryTree |
## Requisitos
- Python >= 3.11
- CherryTree v1.x (formato `.ctd` XML, não `.ctb` SQLite)
- Dependências: `mcp[cli]>=1.0.0`, `lxml>=5.0.0`
## Limitações
- Apenas formato `.ctd` (XML). Arquivos `.ctb` (SQLite) não são suportados.
- O CherryTree precisa ser recarregado (fechar/abrir ou trocar de node) após edições via MCP para refletir as mudanças na UI.
- Operações de escrita com `append=False` em `update_node_content` substituem todo o conteúdo do node (texto, codeboxes, imagens, tabelas).
TDQS
Scored across 13 tools
Most tools target distinct actions (list, read, search, create, update, delete, move, bookmark), so an agent can generally select correctly. The only mild overlap is create_node and create_node_with_codebox, since create_node can also embed codeboxes via content_xml, but the dedicated helper is clearly specialized.
Tool names uniformly follow a verb_noun pattern: list_nodes, read_node, create_node, update_node_content, delete_node, move_node, add_bookmark, remove_bookmark. Even the longer names like append_codebox_to_node and create_node_with_codebox still follow the same predictable convention.
13 tools is a well-scoped set for a CherryTree note-management server, covering reading, searching, writing, structure manipulation, and bookmarks without redundancy or bloat. Each tool earns its place and the count feels balanced for the domain.
The tool surface covers the full lifecycle of CherryTree nodes: list, read, search, create (regular and codebox), update content, update properties, append codebox, move, delete, plus complete bookmark management. There are no obvious dead ends for common note-editing workflows.