Skip to main content
Glama

Slate

Una whiteboard sull'iPad che gli agenti AI possono leggere e scrivere via MCP.

Disegni e scrivi a mano con la Pencil, aggiungi note e riquadri. Dall'altra parte un agente (Claude Code o qualsiasi client MCP) legge la board come struttura — elementi, testo, posizioni, frecce — e come immagine, così capisce anche quello che è stato scritto a mano. E può rispondere scrivendo sulla board.

Tutto gira sul tuo Mac. Nessun servizio esterno, nessun dato che esce dalla rete.

Prima di adottarlo: il codice di Slate è MIT, ma il canvas è l'SDK di tldraw, che non è open source e limita l'uso gratuito agli ambienti di sviluppo. Per un deployment di produzione serve una licenza tldraw. Dettagli nella sezione Licenza — leggila prima di costruirci sopra.

Come è fatto

iPad Safari (PWA tldraw)  ─┐
                           ├─ WebSocket sync ─►  board-server (Node 22+)
Mac browser (stessa PWA)  ─┘                     • @tldraw/sync-core
                                                  • SQLite (un file per board)
                                                  • render PNG headless + OCR
                                                          ▲
Claude Code / altri agent ── stdio MCP ──►  slate-mcp ────┘

Lo stato vive sul server, non sull'iPad: la board resta leggibile anche a tablet spento.

Cartella

Cosa fa

apps/board-server

Sync tldraw, persistenza, API, render, OCR

apps/board-web

La PWA installabile sull'iPad

apps/slate-mcp

Il server MCP che parla agli agenti

tools/ocr

Binario Swift che usa Apple Vision per la scrittura a mano

Related MCP server: @kamiazya/whiteboard-mcp

Prerequisiti

  • Node ≥ 22.12 — richiesto da tldraw 5. Il .node-version punta a 26. Se la tua shell è su Node 20 (default per altri progetti), usa /opt/homebrew/bin/node o fnm use 26.

  • Google Chrome — usato in headless per il render. Nessun browser da scaricare.

  • Xcode command line tools — solo per compilare il binario OCR.

Setup

npm install
npm run build

# OCR della scrittura a mano (opzionale ma consigliato)
cd tools/ocr && swiftc -O -o slate-ocr main.swift && cd -

Avvio

npm run dev:server     # in sviluppo

Oppure come servizio, così parte da solo al login:

./scripts/install-service.sh

All'avvio il server stampa i link di pairing:

[slate] pair a device:  http://192.168.1.x:4501/?token=…      ← LAN
[slate] pair a device:  http://100.x.x.x:4501/?token=…        ← Tailscale

Collegare l'iPad

  1. Apri uno dei link di pairing su Safari. Il token viene salvato e tolto dall'URL.

  2. Condividi → Aggiungi a Home. Si apre a schermo intero, senza barre.

  3. Fuori casa serve Tailscale sull'iPad (usa il link 100.x). In LAN non serve.

Il firewall di macOS blocca tutto

Se l'iPad non si collega ma da Mac funziona, è quasi certamente il firewall: autorizza il binario node reale (non il symlink).

NODE_REAL=$(readlink -f /opt/homebrew/bin/node)
sudo /usr/libexec/ApplicationFirewall/socketfilterfw --add "$NODE_REAL"
sudo /usr/libexec/ApplicationFirewall/socketfilterfw --unblockapp "$NODE_REAL"

Va rifatto dopo ogni aggiornamento di Node: Homebrew installa in un path versionato (/opt/homebrew/Cellar/node/26.4.0/bin/node) e l'autorizzazione è legata a quel path esatto.

Collegare l'agente

claude mcp add slate -- /opt/homebrew/bin/node ~/GitHub/mcp/slate/apps/slate-mcp/dist/index.js

L'MCP parla al server via loopback, che è sempre autorizzato: nessun token da configurare finché server e agente stanno sulla stessa macchina. Se li separi, passa SLATE_SERVER e SLATE_TOKEN.

Tool disponibili

Tool

Cosa fa

list_boards

Elenca le board, dalla più recente

read_board

Struttura: elementi, testo, posizioni, gruppi, frecce, + OCR della scrittura

render_board

Restituisce la board come immagine PNG

search_board

Cerca testo, incluso quello scritto a mano

create_board

Crea una board vuota

add_note

Aggiunge una sticky note (posizionata da sola per non sovrapporsi)

add_image

Carica un'immagine da file e la posiziona sulla board (PNG, JPEG, GIF, WebP)

update_note

Cambia il testo di un elemento mantenendo stile e posizione

delete_shapes

Elimina elementi

Eliminare una board non è esposto come tool: si fa via DELETE /api/boards/:id. Un agente può cancellare elementi, non board intere.

Quanto è affidabile l'OCR

Poco, ed è per questo che render_board esiste. Su scrittura a mano reale Apple Vision prende circa 3 parole su 4: abbastanza per cercare ("in che board avevo scritto FLUSSO?"), non abbastanza per fidarsi del testo riconosciuto.

Per capire davvero cosa c'è su una board disegnata, l'agente deve guardare l'immagine. read_board lo dice esplicitamente nel proprio output.

Misurato su una board di prova (scripts/ocr-scale-test.mjs confronta le varianti):

Variante

Risultato

scale 1.5, corretto

CIAO QUESTO E ON / TEST / ALUSSO 1 / FLUSSO?

scale 2, corretto (default)

CIAO QUESTO E ON / TEST / FLUSSO 1 / Autor

scale 3, corretto

CIAO QUEDO E ON / TEST / FLUSSO 1 / {LUSSO?

qualsiasi scala, --raw

sempre uguale o peggio

Due cose controintuitive emerse dai dati:

  • Alzare la risoluzione non migliora linearmente. A scale 3 la scrittura viene letta peggio che a 2 in alcuni punti: i tratti spessi iniziano a fondersi. Regola con SLATE_OCR_SCALE, non dare per scontato che più alto sia meglio.

  • La correzione linguistica conviene tenerla accesa, anche se spinge verso parole di dizionario (è lei a trasformare FLUSSO2 in Autor). Disattivarla con --raw peggiora tutto il resto. Se la tua board è fatta solo di sigle, riprova la misura: il compromesso può ribaltarsi.

Sicurezza

Un solo modello di accesso per tutte le superfici remote — API, sync e upload. Loopback è sempre autorizzato (è così che entra l'MCP); tutto il resto richiede il token, che viene generato al primo avvio e salvato in ~/.slate/token (0600).

Non esiste una modalità "senza token": lasciare aperto il sync proteggendo solo l'API sarebbe inutile, perché chi raggiunge il socket di sync ha già accesso completo in lettura e scrittura a ogni board.

Le immagini sotto /media/ si leggono senza token: tldraw le carica con <img src>, che non può portare un header, e mettere il token nell'URL lo farebbe finire dentro i documenti esportati. I nomi contengono un UUID, quindi non sono indovinabili.

Per restringere l'ascolto alla sola tailnet:

SLATE_HOST=100.x.x.x npm run dev:server   # il tuo indirizzo Tailscale

Variabili d'ambiente

Variabile

Default

Note

SLATE_HOST

0.0.0.0

Metti l'IP Tailscale per non esporre in LAN

SLATE_PORT

4501

SLATE_DATA_DIR

~/.slate

Board, asset, token

SLATE_TOKEN

generato

Sovrascrive quello salvato

SLATE_CHROME_PATH

Chrome in /Applications

Per il render

SLATE_OCR_BIN

tools/ocr/slate-ocr

SLATE_OCR_SCALE

2

Risoluzione del render passato a Vision

SLATE_SERVER

http://127.0.0.1:4501

Lato MCP

Trappole già incontrate

Cose che costano un pomeriggio se le scopri da solo.

  • fontSizeAdjustment: 0 rende il testo invisibile. La nota si salva, si rilegge correttamente dai dati, e sull'iPad appare vuota. Il valore giusto è null ("ricalcola"). Se scrivi record a mano, non copiare uno 0 da un esempio vecchio.

  • /assets è di Vite. Le immagini delle board stanno sotto /media perché la build della PWA emette i suoi bundle in /assets: una rotta sovrapposta se li mangia e l'app resta senza JavaScript, fallendo in modo silenzioso.

  • Il testo è ProseMirror, non stringa. props.richText vuole un documento; una stringa viene rifiutata dallo schema.

  • I tratti sono path base64. tldraw 5 non espone un encoder, quindi non si può fabbricare un tratto a mano libera da script — solo disegnandolo. Per lo stesso motivo la dimensione di un tratto non è calcolabile dal record: la sanno solo il renderer e l'endpoint OCR, che la misurano in un editor vivo.

  • Non elencare i tratti uno per uno. Una pagina scritta a mano sono decine o centinaia di draw: elencarli produce un muro di righe identiche che seppellisce tutto il resto. read_board li conta e mostra il testo riconosciuto.

  • Le note non crescono da sole. Una sticky è un riquadro fisso 200×200 e il testo che eccede viene tagliato nel render, pur restando integro nei dati: l'API lo rilegge intero mentre sull'iPad la nota appare mozzata. add_note stima growY dalla lunghezza del testo; il client ricalcola l'altezza esatta alla prima modifica.

  • Il posizionamento automatico ha bisogno delle misure vere. Siccome i tratti dichiarano dimensione zero, su una board disegnata il calcolo del bordo destro cade dove inizia il primo tratto e la nota finisce sopra il disegno. Per questo add_note interroga /api/boards/:id/bounds quando trova inchiostro.

  • I record scritti vengono validati. Il server rifiuta con 400 quello che non passa lo schema tldraw, invece di far crashare il canvas sull'iPad più tardi.

  • La licenza tldraw non è open source. Vedi la sezione qui sotto: incide su cosa puoi farci, non solo sul watermark.

Licenza

Il codice di Slate è MIT (vedi LICENSE): usalo, modificalo, ridistribuiscilo come vuoi.

Ma il canvas no. Slate è costruito sull'SDK di tldraw, che non è open source e ha una licenza propria. Vale la pena leggerla prima di adottare Slate, perché è più restrittiva di quanto il watermark lasci intuire:

  • L'uso gratuito è limitato ai Development Environment. La licenza definisce Production come «any production deployment of the Software that operates on servers, cloud platforms, web applications, or where the software is used to provide functionality to end users».

  • Per un deployment di produzione serve una licenza commerciale o un trial.

  • La redistribuzione è ammessa solo come componente di un'altra applicazione, mai standalone, e con copia verbatim della licenza tldraw.

In pratica: un'istanza personale self-hosted sul proprio Mac sta in una zona grigia che solo tldraw può chiarire; qualsiasi cosa somigli a un servizio per altri utenti quasi certamente richiede una licenza. Se il vincolo non ti va bene, la strada è sostituire il canvas con un'alternativa realmente libera — Excalidraw è MIT — tenendo il resto di Slate, che dal canvas dipende solo attraverso il layer di sync e il renderer.

Questa è lettura del testo della licenza, non consulenza legale. Per un uso serio chiedi a tldraw (sales@tldraw.com) o a un avvocato. Il quadro completo delle dipendenze e delle loro licenze è in NOTICE.md.

Sviluppo

npm run dev:server                    # server con reload
npm run dev:web                       # PWA su :4500, proxy verso il server
node scripts/seed-demo.mjs demo       # riempie una board di prova
node scripts/test-mcp.mjs demo        # esercita l'MCP su stdio
node scripts/make-icons.mjs           # rigenera le icone della PWA
A
license - permissive license
-
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • Real-time collaborative whiteboard — AI agents and humans edit the same board live over MCP.

  • OCR, transcription, file extraction, and image generation for AI agents via MCP.

  • MCP-native collaborative markdown editor with real-time AI document editing

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/giveme11us/slate'

If you have feedback or need assistance with the MCP directory API, please join our Discord server