Skill Excalidraw
Passo 0: Escolha uma Interface
Três interfaces controlam o mesmo canvas ao vivo. Escolha a primeira que se aplicar:
- Ferramentas MCP — se as ferramentas
excalidraw/*(ex.:batch_create_elements) estiverem na sua lista de ferramentas, prefira-as: os resultados caem diretamente no seu contexto e as capturas de tela voltam como imagens sem tocar no disco. - CLI (padrão quando não há ferramentas MCP):
Sem necessidade de configuração — qualquer comando que toque no canvas inicia automaticamente o servidor do canvas emnpx -y mcp-excalidraw-server <comando>http://127.0.0.1:3000(a primeira execução donpxbaixa o pacote). Se a CLI estiver instalada globalmente (npm i -g mcp-excalidraw-server), o alias mais curtoexcalidraw-canvas <comando>também funciona. - API REST (último recurso, por exemplo, de código de aplicação): endpoints HTTP em
http://127.0.0.1:3000— consultereferences/cheatsheet.mdpara payloads. O servidor já deve estar em execução.
A URL do canvas vem de EXPRESS_SERVER_URL (padrão http://127.0.0.1:3000). Lembre o usuário de abrir essa URL em um navegador — capturas de tela, exportação de imagens, conversão de mermaid e controle de viewport precisam de uma aba aberta (a CLI sai com código 4 quando está faltando).
Referência Rápida da CLI
Os resultados são JSON no stdout — exceto describe (texto simples) e saída de conteúdo bruto quando --out é omitido (export cena JSON, screenshot --format svg). Diagnósticos no stderr. Códigos de saída: 0 ok, 1 erro, 2 uso, 3 canvas inacessível, 4 aba do navegador necessária.
| Tarefa | Comando |
|---|---|
| Iniciar / parar / inspecionar servidor | start, stop, status |
| Criar elementos (em lote) | add elements.json ou echo '[...]' | add ou add --one '{...}' |
| Patch multi-operação em uma chamada | apply patch.json — {"create":[...],"update":[{"id":"a","set":{...}}],"delete":[...]} |
| Ler um / consultar vários | get <id>, query [--type t] [--bbox x0,y0,x1,y1] [--filter k=v] [--filter-json '{...}'] |
| Atualizar / excluir | update <id> --set '{...}', delete <id> [...] |
| Entender a cena | describe (resumo em texto simples: ids, posições, rótulos, conexões) |
| Ver a cena | screenshot [--out f.png] (PNG sem --out → caminho de arquivo temporário em JSON; SVG sem --out → SVG bruto) |
| Operações de layout | `arrange align |
| Arquivos de cena | export [--out scene.excalidraw], `import [scene.excalidraw |
| Mermaid → canvas | `mermaid [diagram.mmd |
| Snapshots | `snapshot save |
| Link para compartilhar | share (upload criptografado → URL excalidraw.com) |
| Limpar canvas | clear --yes |
| Instalar / atualizar esta skill | install-skill --dir <raiz-das-skills> (o agente escolhe a raiz do projeto/global) |
Formato dos Elementos (CLI e MCP)
A CLI e as ferramentas MCP aceitam o mesmo formato amigável ao agente e o normalizam automaticamente:
- Rótulos: coloque
"text": "Meu Rótulo"em qualquer forma — convertido para o formato de rótulo vinculado do Excalidraw. - Vinculação de setas:
"startElementId": "a"/"endElementId": "b"— setas roteiam automaticamente para as bordas do elemento. - fontFamily: passe um nome de string (
"helvetica","cascadia","excalifont", ...) ou número de string"1"–"8". - points: tanto tuplas
[[x,y], ...]quanto objetos[{"x":..,"y":..}]são aceitos. - Atualizações de patch: em
apply, as entradas de atualização podem usar campos diretos ({"id":"a","x":120}) ou um objetoset({"id":"a","set":{"x":120}}). Não misture as duas formas em uma entrada de atualização.
REST bruto é mais rigoroso: rótulos devem ser "label": {"text": "..."}, vinculações devem ser "start": {"id": "..."} / "end": {"id": "..."}. Só se preocupe com isso ao fazer POST diretamente na API.
Sistema de Coordenadas
O canvas usa uma grade de coordenadas 2D: (0, 0) é a origem, x aumenta para a direita, y aumenta para baixo. Planeje seu layout antes de escrever qualquer JSON.
Diretrizes gerais de espaçamento:
- Espaçamento vertical entre camadas: 80–120px (suficiente para que as setas não apertem os rótulos)
- Espaçamento horizontal entre irmãos: mínimo de 40–60px; dê 120px+ para setas com rótulo
- Largura da forma:
max(160, quantidadeCaracteresRotulo * 12)para manter o rótulo em uma linha - Altura da forma: 60px para linha única, 80px para rótulos de duas linhas
- Preenchimento de fundo/zona: 50px em todos os lados ao redor dos elementos contidos
Estilização para uma aparência profissional:
"fillStyle": "solid"em formas dá preenchimentos planos nítidos — o padrão é um padrão hachure esboçado- Combine preenchimentos
backgroundColorpastéis com seusstrokeColormais escuros (paleta na cheatsheet) "strokeStyle": "dashed"em bordas de zona e setas assíncronas é lido como "limite / fundo"
Anti-Padrões de Layout (Crítico para Diagramas Complexos)
Estes são os erros mais comuns que produzem diagramas ilegíveis. Evite todos eles.
1. NÃO use label.text (ou text) em retângulos grandes de zona de fundo
Quando você coloca um rótulo em um retângulo de fundo, o Excalidraw cria um elemento de texto vinculado centralizado no meio dessa forma — bem onde suas caixas de serviço serão colocadas. O texto se sobrepõe a tudo dentro da zona e não pode ser reposicionado.
Errado:
{"id": "zona-vpc", "type": "rectangle", "x": 50, "y": 50, "width": 800, "height": 400, "text": "VPC (10.0.0.0/16)"}
Correto — use um elemento de texto independente ancorado no topo da zona:
{"id": "zona-vpc", "type": "rectangle", "x": 50, "y": 50, "width": 800, "height": 400, "backgroundColor": "#e3f2fd"},
{"id": "rotulo-vpc", "type": "text", "x": 70, "y": 60, "width": 300, "height": 30, "text": "VPC (10.0.0.0/16)", "fontSize": 18}
O elemento de texto independente fica no canto superior da zona e não interfere com os elementos colocados dentro.
2. Evite setas cruzando zonas em diagramas complexos
Uma seta de um elemento em uma zona de layout para um elemento em uma zona distante desenhará uma longa linha diagonal cruzando tudo no meio. Em um diagrama de infraestrutura multi-zona, isso produz um emaranhado ilegível de espaguete.
Regra de design: Mantenha as setas dentro da mesma zona ou camada. Para mostrar relações entre zonas, use texto de anotação ou separe as zonas para que suas bordas fiquem adjacentes (sem elementos entre elas) e roteie a seta ao longo da borda.
Se você precisar conectar entre zonas, use uma seta em cotovelo que viaje ao longo do perímetro — nunca pelo meio de outra zona.
3. Use rótulos de seta com moderação
Rótulos de seta são colocados no ponto médio da seta. Em setas curtas, eles se sobrepõem às formas em ambas as extremidades. Em diagramas lotados, eles colidem com elementos próximos.
- Só adicione um rótulo de seta quando o nome da relação for genuinamente essencial (ex.: protocolo, número de porta, direção dos dados).
- Se você estiver adicionando um rótulo a cada seta, repense — geralmente adiciona ruído visual, não clareza.
- Mantenha rótulos de seta com ≤ 12 caracteres. Prefira omiti-los completamente em diagramas densos.
Qualidade: Por Que Isso Importa (e Como Verificar)
Diagramas do Excalidraw são comunicação visual. Se o texto for cortado, elementos se sobrepuserem ou setas cruzarem formas não relacionadas, o diagrama se torna confuso e não profissional — derrota todo o propósito de desenhá-lo. Portanto, após cada lote de elementos, verifique antes de adicionar mais.
Lista de Verificação de Qualidade
Após cada add / apply / batch_create_elements, tire uma captura de tela e verifique:
- Truncamento de texto — Todo o texto do rótulo está totalmente visível? Texto truncado significa que a forma é muito pequena. Aumente
widthe/ouheight. - Sobreposição — Alguma forma compartilha o mesmo espaço? As zonas de fundo devem conter totalmente os filhos com preenchimento.
- Cruzamento de setas — As setas cortam elementos não relacionados? Se sim, roteie-as ao redor usando setas curvas ou em cotovelo (veja Roteamento de Setas abaixo).
- Sobreposição de rótulo de seta — Os rótulos de seta ficam no ponto médio. Se eles se sobrepuserem a uma forma, encurte o rótulo ou ajuste o caminho da seta.
- Espaçamento — Pelo menos 40px de intervalo entre os elementos. Layouts apertados são difíceis de ler.
- Legibilidade — Tamanho da fonte ≥ 16 para corpo do texto, ≥ 20 para títulos.
- Posicionamento do rótulo da zona — Se você usou
text/label.textem um retângulo de zona de fundo, o rótulo da zona será centralizado no meio da zona, sobrepondo tudo dentro. Correção: exclua o elemento de texto vinculado e adicione um elemento de texto independente no topo da zona (veja Anti-Padrões de Layout acima).
Se você encontrar qualquer problema: pare, corrija, tire outra captura de tela, depois continue. Diga "Eu vejo [problema], corrigindo" em vez de ignorar os problemas. Só prossiga depois que todas as verificações passarem.
Fluxo de Trabalho: Desenhando um Novo Diagrama
Mermaid vs. Criação Direta — Qual Usar?
Use mermaid / create_from_mermaid quando: o usuário já tem um diagrama Mermaid, ou a estrutura mapeia claramente para um fluxograma/diagrama de sequência/ER com sintaxe Mermaid padrão. É rápido e lida com a conversão automaticamente, embora você tenha menos controle sobre o layout exato.
Crie elementos diretamente quando: você precisa de controle preciso de layout, o tipo de diagrama não mapeia bem para Mermaid (ex.: arquitetura personalizada, diagramas de nuvem anotados), ou você quer elementos posicionados em uma grade de coordenadas específica.
Passos (CLI mostrada; MCP tools são 1:1 — veja cheatsheet)
- Planeje sua grade de coordenadas — mapeie camadas e posições x antes de escrever JSON. (Modo MCP: chame
read_diagram_guidepara cores/tamanhos; a mesma orientação está emreferences/cheatsheet.md.) - Opcional para começo limpo:
npx -y mcp-excalidraw-server clear --yes - Crie formas e setas em uma chamada. Campos
idpersonalizados (ex.:"id": "auth-svc") facilitam atualizações posteriores:(Onpx -y mcp-excalidraw-server add - <<'EOF' [ {"id": "lb", "type": "rectangle", "x": 300, "y": 50, "width": 180, "height": 60, "text": "Load Balancer"}, {"id": "svc-a", "type": "rectangle", "x": 100, "y": 200, "width": 160, "height": 60, "text": "Web Server 1"}, {"id": "svc-b", "type": "rectangle", "x": 450, "y": 200, "width": 160, "height": 60, "text": "Web Server 2"}, {"id": "db", "type": "rectangle", "x": 275, "y": 350, "width": 210, "height": 60, "text": "PostgreSQL"}, {"type": "arrow", "x": 0, "y": 0, "startElementId": "lb", "endElementId": "svc-a"}, {"type": "arrow", "x": 0, "y": 0, "startElementId": "lb", "endElementId": "svc-b"}, {"type": "arrow", "x": 0, "y": 0, "startElementId": "svc-a", "endElementId": "db"}, {"type": "arrow", "x": 0, "y": 0, "startElementId": "svc-b", "endElementId": "db"} ] EOF-posicional é opcional — sem argumento de arquivo,addlê do stdin.) - Defina larguras de forma usando
max(160, comprimentoRotulo * 12). screenshot→ veja o arquivo → execute a Lista de Verificação de Qualidade → corrija problemas antes do próximo lote.
Roteamento de Setas — Evite Sobreposições
Setas retas podem cruzar elementos em diagramas complexos. Use setas curvas ou em cotovelo quando necessário:
Setas curvas (arco suave sobre obstáculos):
{
"type": "arrow", "x": 100, "y": 100,
"points": [[0, 0], [50, -40], [200, 0]],
"roundness": {"type": 2}
}
O waypoint intermediário [50, -40] levanta a seta para cima. roundness: {type: 2} a torna suave.
Setas em cotovelo (roteamento em ângulo reto / L):
{
"type": "arrow", "x": 100, "y": 100,
"points": [[0, 0], [0, -50], [200, -50], [200, 0]],
"elbowed": true
}
Quando usar cada um:
- Fan-out (uma fonte → muitos destinos): setas curvas com waypoints espalhados para evitar sobreposição
- Atravessar faixas (conectar a painéis laterais): setas em cotovelo que sobem, atravessam e depois descem
- Conexões horizontais longas: setas curvas com um leve deslocamento vertical
Regra: Se uma seta passar por uma forma não relacionada, adicione um waypoint para contorná-la.
Fluxo de Trabalho: Refinamento Iterativo
Combinar describe com screenshot é o que torna esta skill poderosa.
describe(describe_sceneno MCP) → texto estruturado: IDs de elementos, tipos, posições, rótulos, conexões. Use-o para saber o que está no canvas antes de fazer atualizações programáticas (encontrar IDs, entender bounding boxes).screenshot(get_canvas_screenshotno MCP) → PNG do canvas renderizado real. Use-o para verificação visual de qualidade — mostra exatamente o que o usuário vê, incluindo truncamento, sobreposição e roteamento de setas. A CLI imprime o caminho do arquivo salvo como JSON; leia/veja esse arquivo.
Loop de feedback:
adicionar elementos
→ screenshot → visualizar → "texto truncado em auth-svc"
→ atualizar auth-svc --set '{"width": 220}' → screenshot → "sobreposição entre auth-svc e rate-limiter"
→ atualizar rate-limiter --set '{"x": 520}' → screenshot → "todas as verificações passam"
→ prosseguir
Fluxo de Trabalho: Refinar um Diagrama Existente
describepara entender o estado atual — observe os IDs dos elementos e posições.- Identifique elementos por
idou texto do rótulo (não por coordenadas x/y — elas mudam). update <id> --set '{...}'para redimensionar/recolorir/mover;delete <id>para remover; ou agrupe tudo em um único patchapply. Setas vinculadas roteiam automaticamente quando você move ou redimensiona seus pontos finais — não precisa excluí-las e recriá-las.screenshotpara confirmar que a mudança parece correta.- Se as atualizações falharem: verifique se o ID existe com
get <id>; desbloqueie comarrange unlock --ids <id>se estiver bloqueado.
Fluxo de Trabalho: Conversão de Mermaid
echo 'graph TD
A[Cliente] --> B[API]
B --> C[(BD)]' | npx -y mcp-excalidraw-server mermaid
Requer uma aba de navegador aberta (a conversão é executada no frontend; código de saída 4 indica que você precisa abrir a URL do canvas). Depois screenshot para verificar o layout. Se o layout automático for ruim (nós aglomerados, arestas cruzadas), encontre os elementos problemáticos com describe e reposicione-os com update.
Fluxo de Trabalho: I/O de Arquivos
- Exportar cena:
export --out diagram.excalidraw(sem--out→ JSON para stdout) - Importar cena:
import diagram.excalidraw(anexar) ouimport diagram.excalidraw --replace - Imagem:
screenshot --out diagram.png/screenshot --format svg --out diagram.svg(aba do navegador necessária) - Link para compartilhar:
share— criptografa a cena e retorna um URL compartilhável
…
[truncado para tradução]