
Aujourd’hui, on va parler d’un sujet qui me tient à cœur : comment faire bosser une IA à sa place quand on a une tablette graphique, des idées, mais une flemme monumentale de tracer des flèches droites. On va transformer une simple interface de dessin en un outil agentique piloté par Ollama. Accrochez-vous, ça va être dense.
L’Intro : La Tablette, la Formation et la Grosse Flemme
Quand je donne des formations, j’adore utiliser Excalidraw. C’est souple, c’est propre, et avec ma tablette, j’ai l’impression d’être sur un vrai tableau blanc. C’est parfait pour gribouiller des concepts en direct. Mais on va être honnête deux minutes : parfois, je suis en manque total d’inspiration pour mes schémas.
Dessiner une architecture microservices avec 15 nœuds, trois bases de données et un bus de messages alors que j’ai déjà parlé pendant trois heures ? J’ai juste une grosse flemme. L’idée, c’était simple : je veux une IA, en local (parce que ma VRAM, je l’ai payée, alors je l’utilise), qui puisse « tenir le pinceau » pendant que j’explique le concept aux élèves. On ne parle pas juste de générer une image statique, mais d’avoir un vrai Agent qui manipule le canvas en temps réel sous mes yeux.
Étape 1 : Monter le Tableau Blanc (Installation d’Excalidraw)
Avant de parler IA, il nous faut le support. La façon la plus simple et la plus propre de faire tourner Excalidraw chez soi sans dépendre du cloud, c’est Docker.
Tu peux le lancer en une seule ligne de commande pour tester: docker run --rm -dit --name excalidraw -p 8000:80 excalidraw/excalidraw:latest.
Mais comme on est sur une AI Station sérieuse, on va l’intégrer proprement dans notre docker-compose.yml. Cela nous permet de gérer les ports et les redémarrages automatiques.
# --- TABLEAU BLANC EXCALIDRAW ---
excalidraw:
image: excalidraw/excalidraw:latest
container_name: excalidraw
ports:
- "8000:80" # Accessible sur http://localhost:8000
restart: unless-stopped
Une fois que c’est lancé, tu as ton Excalidraw perso sur le port 8000. C’est rapide, c’est léger, et ça ne demande aucune configuration complexe pour commencer à dessiner avec sa tablette ou sur son ordinateur et c’est gratuit :D.

Étape 2 : L’Intelligence de Dessin (Serveur MCP)
Maintenant, on veut que l’IA puisse interagir avec ce canvas. Pour ça, on utilise le protocole MCP (Model Context Protocol). J’ai choisi le projet mcp-excalidraw-local qui propose environ 32 outils pour manipuler le tableau blanc (créer des formes, du texte, des flèches, etc.).
Pour l’intégrer à l’infra, on ajoute un service dédié qui va compiler les sources GitHub.
Le Dockerfile du serveur MCP
On crée un fichier Dockerfile.mcp-excalidraw :
FROM node:20-slim
RUN apt-get update && apt-get install -y git python3 make g++ && rm -rf /var/lib/apt/lists/*
RUN npm install -g pnpm
WORKDIR /app
RUN git clone https://github.com/sanjibdevnathlabs/mcp-excalidraw-local.git .
RUN pnpm install && pnpm build
# Le serveur attend des commandes stdio par défaut
CMD ["node", "dist/index.js"]Le Bridge pour Open-WebUI
Le souci, c’est que mon interface préférée, Open-WebUI, ne parle pas nativement le « stdio » (le langage des terminaux) pour le MCP. Elle préfère le HTTP. On va donc utiliser un bridge appelé mcpo qui va faire la traduction.
On ajoute ces deux services à notre docker-compose.yml:
mcp-excalidraw:
build:
context: .
dockerfile: Dockerfile.mcp-excalidraw
container_name: mcp-excalidraw
ports:
- "3001:3000"
environment:
- CANVAS_PORT=3000
- EXCALIDRAW_DB_PATH=/app/data/excalidraw.db
volumes:
- /chemin/vers/votre/data:/app/data
restart: unless-stopped
mcpo:
image: ghcr.io/open-webui/mcpo:main
container_name: mcpo
ports:
- "8081:8080"
volumes:
- ./mcpo/config.json:/app/config.json:ro
depends_on:
- mcp-excalidraw
restart: unless-stoppedIl ne faut pas oublier de créer le fichier ./mcpo/config.json pour dire à mcpo d’aller chercher le serveur Excalidraw:
{
"mcpServers": {
"excalidraw": {
"type": "sse",
"url": "http://mcp-excalidraw:3000/sse"
}
}
}Étape 3 : Le Tool Python « Agentic » (La Touche Finale)
Après pas mal de tests, j’ai réalisé que pour avoir un contrôle total, rien ne vaut un Tool Python personnalisé dans Open-WebUI. Cela permet d’éviter les erreurs de protocole et de formater les requêtes exactement comme l’API du serveur MCP l’attend.
Pourquoi ce script ?
J’ai découvert deux bugs critiques en analysant les logs:
- L’API attend un objet pour le texte :
{"label": {"text": "votre texte"}}et non une simple string. - Pour le Mermaid, le champ doit s’appeler
mermaidDiagram.
Voici le script excalidraw_tool.py corrigé que j’utilise:
"""
title: Excalidraw Canvas Tool
author: tazmen
description: Contrôle le canvas Excalidraw local
version: 1.2.0
"""
import json
import requests
import time
EXCALIDRAW_API = "http://mcp-excalidraw:3000"
class Tools:
def add_element(self, type: str, label: str = "", x: int = 100, y: int = 100, width: int = 200, height: int = 100):
"""Ajoute un élément sur le canvas."""
try:
payload = {
"type": type,
"label": {"text": label}, # Formatage correct pour l'API
"x": x, "y": y,
"width": width, "height": height
}
r = requests.post(f"{EXCALIDRAW_API}/api/elements", json=payload, timeout=5)
return "Élément ajouté."
except Exception as e:
return f"Erreur: {e}"
def create_diagram_from_mermaid(self, mermaid_code: str) -> str:
"""Convertit un code Mermaid en schéma Excalidraw."""
try:
r = requests.post(
f"{EXCALIDRAW_API}/api/elements/from-mermaid",
json={"mermaidDiagram": mermaid_code}, # Champ corrigé
timeout=10
)
time.sleep(2) # On laisse le temps au rendu
return "Schéma généré."
except Exception as e:
return f"Erreur: {e}"
def clear_canvas(self):
"""Vide le tableau blanc."""
requests.delete(f"{EXCALIDRAW_API}/api/elements/clear", timeout=5)
return "Canvas nettoyé."Les Galères et le Troubleshooting (Le mode survie)
Si vous faites ça, vous allez forcément tomber sur des erreurs de permissions. C’est mathématique.
- Erreur SQLITE_CANTOPEN : Le conteneur
mcp-excalidrawessaie d’écrire la base de données sur votre disque mais il n’a pas les droits. Comme le process Node.js tourne souvent avec l’UID 1001 , il faut lui donner la propriété du dossier:sudo chown -R 1001:1001 ~/tazmen-ai-station/mcp-excalidraw/data. - L’IA qui refuse de dessiner : Si votre modèle (Mistral ou Qwen) vous dit qu’il « ne peut pas dessiner ici », c’est qu’il n’est pas assez directif. Il faut lui forcer la main dans le System Prompt.
Mon System Prompt de « Grosse Flemme »
Ajoutez ceci à votre modèle personnalisé dans Open-WebUI:
« Tu es un assistant spécialisé dans la création de schémas sur Excalidraw. RÈGLE ABSOLUE : Quand on te demande un schéma, utilise TOUJOURS
create_diagram_from_mermaid. Ne montre jamais le code, dessine direct. ».
La Démo Finale : Ça en jette !
Une fois que tout est vert, le résultat est magique. Pendant ma formation, je dis simplement : « Fais-moi un schéma d’une architecture active directory avec les rôles FSMO ». L’IA réfléchit, génère le Mermaid, et paf, les boîtes apparaissent sur mon Excalidraw sur localhost:8000 ou 3001.
Conclusion
Voilà comment on passe d’une tablette graphique sympa à une station de travail agentique complète. C’est du boulot à installer, mais quel plaisir de voir ses idées prendre forme sans avoir à se battre avec l’alignement des rectangles !
Si vous avez des questions sur les variables d’environnement ou les quantisations de modèles (j’utilise Qwen 3.5 9B pour que ça rentre dans mes 16 Go de VRAM ), posez-les en commentaire.
À plus pour de nouvelles aventures en local !