Skip to main content
Glama
nhodges
by nhodges

mcp-vroid

Un servidor MCP que controla la interfaz gráfica de VRoid Studio. Ofrece a cualquier cliente MCP (Claude Code, o cualquier otra cosa que hable con el protocolo) un conjunto de herramientas para lanzar la aplicación, verla, localizar widgets en la imagen, hacer clic y escribir, ajustar parámetros y exportar un .vrm — en Arch + Hyprland (Wayland), con VRoid Studio ejecutándose bajo Steam/Proton.

No existe una API de scripting en VRoid Studio, así que esto funciona de la única manera que está disponible: capturar la ventana, localizar las cosas con OCR y coincidencia de color, e inyectar eventos reales de puntero y teclado.

   grim ──► PNG ──► tesseract / cv2 ──► (x, y) ──► virtual pointer / XTEST
    ▲                                                        │
    └────────────────────  screenshot again  ◄───────────────┘

Elmotor bajo el servidor es el espiga tools/vroid-driver de mi proyecto arrakis, incluido aquí como mcp_vroid.driver — el mismo código, reempaquetado para que un cliente MCP pueda instalarlo y ponerlo en marcha.


Requisitos

cosa

por qué

Hyprland (>= 0.55, API de despacho)

descubrimiento de ventanas, foco, disgnadores

VRoid Studio vía Steam/Proton (appid 1486350)

la app que se está controlando

grim

capturas de pantalla

tesseract + datos de entrenamiento eng

OCR

gcc, wayland-scanner, libwayland-client

compilar el asistente de puntero

Xwayland (DISPLAY)

el teclado y la rueda pasan por X11 XTEST

Python 3.11+, uv

el propio servidor

Dependencias Python (uv sync las instala): mcp, pillow, numpy, opencv-python-headless, pytesseract, python-xlib.

Related MCP server: blockout-mcp

Instalación

git clone https://github.com/nhodges/mcp-vroid
cd mcp-vroid
uv sync                 # virtualenv + dependencies
bash native/build.sh    # builds native/vpointer  <-- REQUIRED, not optional

native/build.sh compila un cliente C de ~150 líneas para zwlr_virtual_pointer_unstable_v1 (el XML de protocolo está vendido en native/protocols/). Sin él, todo tool de puntero falla con native/vpointer missing. vroid_status informa si está presente.

Por qué un asistente en C: ydotool no está instalado en la máquina de referencia y /dev/uinput es 0600 root:root, así que la inyección evdev requeriría sudo o una regla de udev. El protocolo de puntero virtual de Wayland no necesita ninguna de las dos, mueve el cursor real del compositor y funciona con cualquier ventana.

Cliente mcpServers JSON:

claude mcp add vroid -- uv run --directory /path/to/mcp-vroid mcp-vroid

Genérico mcpServers JSON:

{
  "mcpServers": {
    "vroid": {
      "command": "uv",
      "args": ["run", "--directory", "/path/to/mcp-vroid", "mcp-vroid"]
    }
  }
}

Los clientes suelen lanzar los servidores con un entorno saneado. Este servidor recupera XDG_RUNTIME_DIR, WAYLAND_DISPLAY, HYPRLAND_INSTANCE_SIGNATURE y DISPLAY del directorio de runtime al arrancar (tools/ndc_vdvoice) para que hyprctl/grim/XTEST funcionen igualmente; vroid_status muestra lo que tuvo que completar. Cualquier que ya esté en el entorno gana.

Variables de entorno opcionales:

var

valor predeterminado

significado / función

MCP_VROID_CAPTURES

$XDG_STATE_HOME/mcp-vroid/captures

señal importante: a capturar

MCP_VROID_OUT

$XDG_STATE_HOME/mcp-vroid/out

directorio por defecto para exportar/guardar

MCP_VROID_VPOINTER

<checkout>/native/vpointer

ruta al asistente de puntero

MCP_VROID_MAX_IMAGE_PX

1600

el lado más largo de las imágenes y colores (0 = nunca reducir)

Herramientas

Ciclo de vida

Herramienta

Cómo lo hace

vroid_launch(restart=false, timeout=240)

Lanza VRoid cuando haga falta, va al escritorio 9 de Hyprland, recuerda en el escritorio que estabas y lo enfoca, y lo maximiza. restart=true mata primero la instancia en ejecución — el trabajo no guardado se pierde.

vroid_status()

Ventana presente / enfocada / título / geometría, escritorio activo, carpetas de captura y si vpointer/grim/tesseract/hyprctl están disponibles. Solo lectura, sin OCR.

vroid_release()

Vuelva al escritorio en el que vivía el usuario. VR Studio sigue abierto en el escritorio 9.

Viendo

tool

qué hace lo que haces

vroid_screenshot(region?, tag?, whole_screen?, fullscreen?)

Captura la ventana (o toda la salida, esp. para el diálogo de guardado de Wine), la guarda en la carpeta de capturas y te la devuelve como contenido de imagen MCP para que el modelo del cliente pueda verla. Informa del tamaño nativo de la imagen y del factor de reducción aplicado para la transferencia.

vroid_find_text(query, region?, exact?, limit?)

Nueva captura + tesseract; devuelve las cajas y centros de las palabras coincidentes en px de imagen. Pasa región — el OCR del fotograma completo tarda ~10 s, el de un panel ~2 s.

vroid_find_button(color='primary'|'disabled', label?, region?)

Localiza los botones de color sólido de VRoid #0096FA por color, porque tesseract se pierde con las etiquetas blancas sobre azul. Una pastilla gris significa deshabilitado.

vroid_current_screen()

start / editor / export_vrm / hair_editor / unknown.

Contacto (entrada sin procesar)

Herramienta

Descripción

vroid_click(x, y, space='image', button='left', double=false)

Mueve el puntero deslizando en un pocos pasos (para que se activen los estados hover) y cliquea.

vroid_drag(x1, y1, x2, y2, space='image', button='left')

click deslizamiento en 24 pasos soltar. El arrastre con el botón derecho orbita la cámara; el del botón central pega.

vroid_scroll(dy, dx, x?, y?, space='image')

Rueda, como teclas X11 4/5 (6/7 para horizontal). Sitúa el puntero sobre el panel que quieras desplazar.

vroid_type(text, clear_first=false)

Escribe en el elemento enfocado mediante XTEST.

vroid_key(combo, repetitions=1)

Enter, Esc, ctrl+s, ctrl+shift+s, …

Acting (flujos completos)

Herramienta

Qué hace

vroid_new_character(base='Fem'|'Masc')

Pantalla de inicio → Create New → base → editor.

vroid_open_tab(name)

Face / Hairstyle / Body / Outfit / Accessories / Look.

vroid_set_slider(label, value)

Desplaza el panel de parámetros a la fila y escribe un valor exacto en su caja numérica.

vroid_set_color(label, hex)

Igual que el otro, pero para una casilla de color #RRGGBB.

vroid_export_vrm(path, avatar_name, formato, version='1.0')

El paseo completo por Export-as-VRM, incluido el modal de ajustes de VRM y el diálogo de guardado de Wine Wine. El parámetro vs elige VRM1.0 o VRM0.0.

vroid_save_project(name?)

Ctrl+Shift+S a una ruta .vroid explícita, o un guardado normal en el archivo no se ha pasado.

Todas las herramientas de acción enfocan primero la VR y se niegan a actuar if not focused if window focused is VR Studio.

Cómo usarlo

Resumen: cóđului → observar → localizar → actuar → capturar de nuevo.

  1. vroid_launch()

  2. vroid_screenshot() y observa la imagen

  3. vroid_find_text("Export") (o vroid_find_button()) para obtener las coordenadas

  4. vroid_click(x, y) — coordenadas de una captura fresca, siempre

  5. vroid_screenshot() para confirmar lo que realmente pasó

Trucos aprendidos a la fuerza en el prototipo original:

  • Hay que mirar el plano entero, no un recorte. Un modal de confirmación de “Cerrar Editor de Peinados” estaba en el centro de la pantalla y se quedó ahí durante seis clics fallidos porque la comprobación singular oreado.

  • No juzgues el cambio por el viewport 3D. VRoid entremezcla cada frame, así que la diferencia entre dos pantallas enteras lee ~0.98 aunque no haya pasado nada. Para saber si eso pasa, mira una banda de la UI.

  • Preferir las cajas numéricas a arrastrar el slider. vroid_set_slider escribe un valor exacto, mientras que arrastrar solo es para controles que no tienen caja.

  • Los botones primarios se buscan por color, no por texto. Un pastil gris donde esperas azul es la app indicándote que hay un campo obligatorio vacío.

  • El OCR de un fotograma completo de 2560×1440 tarda ~10s en. Pasa un region .

Esp ediciones de coordenadas

Hay tres espacios en juego, y todos son distintos:

espacio

tamaño en la máquina de referencia

quién lo usa

layout (lógico)

2048 × 1152

hyprctl, el puntero virtual

píxeles esde píxel de la imagen

2560×1440

tesseract, cv2, todo lo que ves

X11 (controlador Xwayland)

2560 × 1440

XTEST

Las herramientas aceptan y devuelven pxx (space='image') de imagen por defecto y convierten internamente, así que directamente pega lo que devuelve vroid_find_text en vroid_click. Si MCP_VROID_MAX_IMAGE_PX redujo la imagen que te mostraron y leíste las coordenadas, multiplica las coordenadas por el inverso del factor downscale reportado — o simplemente pide a f, que siempre devuelve px nativas.

Mapa de la interfaz (VRoid Studio 2.14.0, English)

Las coordenadas están en px de una captura de 2560×1440 de la ventana a pantalla completa. Son pistas—las herramientas reales primero hacen el OCR.

Pantalla de inicio — la tarjeta Create New + está en ≈ (118, 218) y su rótulo en (118, 328); New / Open arriba a la derecha en (2439, 99) / (2495, 100); debajo, la cuadrícula de Sample Models. Create New abre un modal "Select a base to start with" con los rótulos Fem (1199, 862) y Masc (1359, 862): haz clic en la miniatura ~100 px por encima del rótulo.

Editor — la barra de pestañas en y ≈ 23: Face 97 · Hairstyle 198 · Body 302 · Outfit 392 · Accessories 509 · Look 622. La hamburguesa en (29, 23) → Save (Ctrl+S), Save As… (Ctrl+Shift+S), importación/exportación masiva, deshacer/rehacer, volver a la selección de modelos — Escape no cierra este menú; haz clic en otro sitio. Barra de herramientas arriba a la derecha: cámara (2415, 23), compartir/exportar (2464, 23), menú kebab (2512, 23). La columna de iconos de la izquierda (x ≈ 24, primer icono en y ≈ 77 y luego cada ~48 px) es la subcategoría de la pestaña actual. El panel izquierdo es la cuadrícula de preajustes, con Presets/Custom en y ≈ 120. El panel derecho es Custom en primer lugar y Parameters después.

Controles del panel derecho

control

cómo se maneja

slider

la caja numérica en x ≈ 2505 (vroid_set_slider); la pista va de x ≈ 2278 a 2516 con el 0.0 centrado

color

la caja #RRGGBB en x ≈ 2450 (vroid_set_color)

checkbox / radio

haz clic en la casilla o en el círculo

acordeón

haz clic en el rótulo (p. ej. > Reduce Polygons)

menú desplegable

solo en los diálogos nativos de Wine; haz clic y luego con las flechas del teclado

Los parámetros de Body empiezan en Model's Height : 161.2 cm, y siguen Fem Height, Masc Height, Eye Size X/Y? No, en realidad la lista: Fem Height, Masc Height, Body Size, Head Size, Head Width, Head Tip (Y), Neck Length/Thickness/Width, Soften Collarbone, … Los de Face: Eye Size X/Y, Eyes Position (X/Y), Rotate Eye Socket, Inner/Outer Eye Slant, Iris Size X/Y, Gaze (Y), … (unos ~40 renglones; las herramientas hacen scroll por ti).

Editor de peinado — pestaña Hairstyle → icono de la columna izquierda → subpestaña Custom+ Profile New → panel derecho Edit Hairstyle. Dentro: Add Freehand Hair Guides / Add Procedural Hair Guides, una lista Hair Groups, una paleta de herramientas en (330 / 365 / 398 / 432, 83), deshacer/rehacer en (76, 23) / (133, 23). Al salir pregunta primero: la en (23, 23) abre el modal Close Hairstyle Editor con Save as new head / Overwrite / Close without saving.

Export as VRM — icono de compartir (2464, 23) → Export as VRM → página de exportación a pantalla completa con la píldora azul Export en ≈ (2412, 197) → modal VRM Settings (centrado, con x de ~1000 a 1560, desplazable): Export Format con los botones de opción VRM1.0/VRM0.0, Avatar Name obligatorio, Version, Creators obligatorio, copyright/contacto/referencias, casillas de uso; la píldora Export sigue gris y sin respuesta hasta que se rellenan esos dos campos obligatorios → cuadro de diálogo para guardar de Wine (su propia ventana, título Export); el campo File name: se abre enfocado y con el texto seleccionado, de modo que escribir una ruta de Windows lo reemplaza y Enter activa el botón predeterminado. El prefijo de Proton mapea Z:\ a /, así que /home/nuri/x es Z:\home\nuri\x. No hagas clic en un Save localizado con OCR: la etiqueta Save in: coincide con la misma aguja.

Qué es frágil

  • El OCR es todo el sistema de localización. Las etiquetas pequeñas, con separación amplia o claras sobre oscuro se dividen o se pierden (ExportE + xport). Los iconos no tienen texto; esos anclajes se basan en fracciones fijas de la ventana y se moverán si pixiv reorganiza la interfaz.

  • Los anclajes fijos son fefracciones calibradas para 2560×1440 con escala 1.25. Con otro monitor quizá haya que volver a medirlas.

  • Los modales aparecen fuera de tu región de búsqueda y se tragan los clics en silencio.

  • Tempo. La ventana 3D tarda unos 5 s en aparecer después de escoger una base; la exportación demora 5–30 s (más con modelos pesados).

  • El diálogo de Wine es una ventana aparte, con su propia clase y geometría: usa ahí vroid_screenshot(whole_screen=true).

  • Idioma. Estas agujas suponen la interfaz en inglés.labrasta. Si VRoid sale en japonés, esvíalo por el menú kebab → Settings → Language.

  • El protector de pantalla inactivo puede llevarse la sesión a mitad de ejecución. El guardián no escribe en esa ventana y cierra esa única ventana (y solo esa) antes de actuar.

Nota de seguridad

Este servidor inyecta eventos reales del mouse y teclado en tu sesión de escritorio activa y captura pantallas de la misma. Esa es toda la gracia, y también el riesgo:

  • Las capturas pueden mostrar cualquier cosa en la salida; whole_screen=true captura absolutamente todo, y las capturas se guardan en el disco sin cifrar.

  • Las pulsaciones van a donde tiene el foco. El controlador se niega a actuar a menos que la ventana de VRoid Studio tenga el foco, pero una instrucción comprometida o descuidada de igual forma puede hacer clic en cualquier lugar dentro de VRoid.

  • vroid_launch(restart=true) cierra VRoid Studio al instante y se pierden cambios sin guardar.

  • Ninguna de estas acciones va en un entorno aislado y no hay ningún paso de confirmación.

Ejecútalo vigilado, con sesión supervisionada, y no dejes un agente conduciéndolo en secreto; vroid_release() te devuelve el escritorio al terminar.

Desarrollo

uv run python scripts/smoke_test.py             # start the server, list tools, call vroid_status
uv run python scripts/smoke_test.py --screenshot # + one passive capture if VRoid is open
uv run vroid-driver shot                        # the original driver CLI, still here

vroid-driver (mcp_vroid.driver.cli) es la interfaz de la shellía del juguete — launch, shot, find, click, tab, slider, export, cam, apply-params, … — muy útil para depurar sin un cliente MCP en el bucle.

Crédicos y licencia

El driver (src/mcp_vroid/driver/, native/) nació como el spike tools/vroid-driver dentro de mi proyecto arrakis y se incluye aquí con el servidor MCP envuelto alrededor.

MIT — consulta LICENSE.

Install Server
A
license - permissive license
A
quality
C
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

  • F
    license
    B
    quality
    D
    maintenance
    Enables GUI automation for controlling PIX4Dmatic on Windows through MCP. Supports launching, focusing, capturing screenshots, sending hotkeys, clicking UI elements, opening projects, starting processing, and checking outputs.
    18
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI agents to control the Blockout previs desktop app for AI filmmaking, allowing staging of 3D worlds, character animation, camera framing, timeline control, and viewport screenshotting through MCP tools.
    6
    Apache 2.0
  • A
    license
    A
    quality
    A
    maintenance
    Wraps the Live2D Cubism Editor's external application integration API as MCP tools, enabling AI agents to control Cubism Editor for modeling operations via natural language.
    17
    12
    MIT

View all related MCP servers

Related MCP Connectors

  • Generate, edit, and deploy immersive 3D/WebGL web projects from any MCP assistant.

  • Hosted real Google Chrome MCP with per-user persistent state. Navigate, click, type, screenshot.

  • Create App Store screenshots, icons, ASO copy, localization, and revisions via hosted MCP.

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/nhodges/mcp-vroid'

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