Paint MCP — controla Paint de Windows desde Claude
Servidor MCP local que le permite a Claude (vía Claude Code) abrir Paint deWindows 11 y dibujar en el lienzo. Paint no tiene API, así que se controla porautomatización de GUI (pyautogui mueve el mouse en coordenadas de pantalla).
Requisitos
- Windows 10/11 con Paint (
mspaint.exe) - Python 3.10+ (probado en 3.14)
Instalación
python -m pip install -r requirements.txt
Dependencias: mcp[cli], pyautogui, pillow, opencv-python, numpy (pygetwindow ypywin32 entran como dependencias en Windows). opencv-python y numpy se usan para laauto-calibración (detección del lienzo y del ícono del lápiz por imagen).
Cómo funciona
Las coordenadas de las tools son relativas al lienzo: (0,0) es la esquina superiorizquierda del área dibujable. El servidor las traduce a pantalla usando la posición de laventana de Paint + unos márgenes de calibración que descuentan el panel de herramientasizquierdo, el ribbon superior, los bordes y la barra de estado.
Detalles que hicieron falta para que el dibujo funcione en el Paint de Windows 11 (WinUI):
- Match por proceso, no por título. La ventana de Paint se ubica buscando el proceso
mspaint.exe. Buscar por título ("paint") fallaba porque VS Code abierto en la carpetaMCP-TEST-Painttambién contiene "paint" en su título. - Selección del lápiz. Antes de dibujar se clickea el ícono del Lápiz en el ribbon.Esto además descarta cualquier selección activa (p. ej. la que deja
Ctrl+Aal limpiar),que si no haría que los arrastres muevan la selección en vez de dibujar. - Priming. El primer arrastre después de tocar un botón del ribbon no pinta, así quese hace un arrastre corto sacrificable antes del trazo real.
dragTopor segmento. Arrastrar conmouseDown()+moveTo()solía dejar solo unpunto; cada segmento se traza condragTo()(presiona-arrastra-suelta). Los segmentoscomparten extremos, así que se ven continuos.
Auto-calibración
Para no depender de coordenadas fijas (que se rompen al cambiar de monitor, resolución oescala), el servidor se auto-calibra en cada uso:
- Lienzo: se detecta la región dibujable buscando la banda blanca dominante dentrode la ventana (numpy). El resultado se cachea por geometría de ventana.
- Lápiz: se ubica el ícono por reconocimiento de imagen (
cv2.matchTemplatesobreassets/pencil.png), tomando la mejor coincidencia en pantalla.
Si la detección falla (p. ej. sin opencv/numpy), cae automáticamente a los márgenes ycoordenadas fijas configurables por entorno (ver más abajo). get_canvas_info() informa siestá usando detected o fallback.
Nota: la plantilla
assets/pencil.pngy la detección asumen 100 % de escala depantalla. Con otra escala (125 %, 150 %…) el ícono cambia de tamaño y puede no matchear;en ese caso se usa el fallback de coordenadas.
Tools disponibles
| Tool | Descripción |
|---|---|
open_paint() |
Abre mspaint, lo maximiza y lo enfoca (si ya está abierto, solo lo enfoca). |
get_canvas_info() |
Devuelve bounds de la ventana y región del lienzo (para depurar/calibrar). |
draw_line(x1,y1,x2,y2) |
Línea recta. |
draw_rectangle(x,y,width,height) |
Rectángulo (4 líneas conectadas). |
draw_polyline(points) |
Trazo libre por una lista [[x,y],...]. |
clear_canvas() |
Limpia el lienzo (Ctrl+A + Delete). |
save_canvas(path) |
Guarda la región del lienzo como PNG (screenshot, sin usar el diálogo de Paint). |
Probar sin Claude
python test_local.py
Abre Paint, dibuja un rectángulo, una línea y un trazo libre, y guarda salida.png.
⚠️ Durante la ejecución el script toma control del mouse. No uses la PC mientrascorre. Para abortar de emergencia, mueve el mouse a una esquina de la pantalla(FAILSAFE de pyautogui).
Calibración (fallback)
Normalmente no hace falta calibrar: la auto-detección de arriba se encarga. Estos valoresson el fallback que se usa solo si la detección por imagen falla (sin opencv/numpy, oescala ≠ 100 %). Se ajustan por variables de entorno (no hace falta tocar el código):
| Variable | Default | Qué controla |
|---|---|---|
PAINT_MARGIN_TOP |
218 | Barra de título + ribbon superior |
PAINT_MARGIN_LEFT |
277 | Borde + panel de herramientas izquierdo |
PAINT_MARGIN_RIGHT |
285 | Borde/panel derecho |
PAINT_MARGIN_BOTTOM |
135 | Barra de estado inferior |
PAINT_PENCIL_X |
262 | X del ícono Lápiz (relativa a la ventana) |
PAINT_PENCIL_Y |
87 | Y del ícono Lápiz (relativa a la ventana) |
PAINT_DRAW_DURATION |
0.4 | Segundos por segmento (subir si Paint no registra el trazo) |
Cómo recalibrar: llamá get_canvas_info() para ver la región del lienzo y la posicióncalculada del lápiz, o sacá un screenshot de pantalla completa y medí: la esquina superiorizquierda del lienzo blanco te da MARGIN_LEFT/MARGIN_TOP, y el ícono del Lápiz en elribbon te da PAINT_PENCIL_X/PAINT_PENCIL_Y.
Usar desde Claude Code
El archivo .mcp.json ya registra el servidor (scope de proyecto). Para activarlo:
- Reinicia Claude Code en este directorio para que cargue
.mcp.json. - Verifica con
/mcpque aparece el servidor paint (aprueba el servidor si te lo pide). - Pídele a Claude algo como: "abre Paint y dibuja un cuadrado".
Límites del POC
- Dibuja siempre con el Lápiz y color negro. Cambiar color / grosor / pincel / textono está incluido (requiere clickear más botones del ribbon). Sería una v2.
- La calibración (márgenes y posición del lápiz) depende de la resolución y escala depantalla. Los defaults son para 2560×1080 al 100%; en otra config hay que ajustar lasvariables de entorno de arriba.