mcp-vroid
mcp-vroid
一个 驱动 VRoid Studio GUI 的 MCP 服务器。它为任何 MCP 客户端(Claude Code,或任何支持该协议的其他工具)提供一组工具:启动应用、查看应用、在画面中查找控件并点击和输入、设置参数,以及导出 .vrm —— 运行在 Arch + Hyprland (Wayland) 上,VRoid Studio 通过 Steam/Proton 运行。
VRoid Studio 没有脚本 API,所以只能用现在唯一可行的方式:对窗口截图,用 OCR 和颜色匹配定位目标,并注入真实的指针和键盘事件。
grim ──► PNG ──► tesseract / cv2 ──► (x, y) ──► virtual pointer / XTEST
▲ │
└──────────────────── screenshot again ◄───────────────┘服务器底层的引擎来自 arrakis 项目中的 tools/vroid-driver spike,这里以 mcp_vroid.driver 的名义随包带进来 —— 代码相同,只是重新打包,让 MCP 客户端能够安装并启动它。
环境要求
组件 | 用途 |
Hyprland(>= 0.55,Lua dispatch API) | 窗口发现、聚焦、工作区 |
VRoid Studio(通过 Steam/Proton,appid | 被驱动的应用 |
| 截屏 |
| OCR |
| 构建指针辅助工具 |
Xwayland( | 键盘和滚轮讲通过 X11 XTEST 注入 |
Python 3.11+、 | 服务器本体 |
Python 依赖(由 uv sync 安装):mcp、pillow、numpy、opencv-python-headless、pytesseract、python-xlib。
Related MCP server: blockout-mcp
安装
git clone https://github.com/nhodges/mcp-vroid
cd mcp-vroid
uv sync # virtualenv + dependencies
bash native/build.sh # builds native/vpointer <-- REQUIRED, not optionalnative/build.sh 编译出一个约 150 行的 C 客户端,用于 zwlr_virtual_pointer_unstable_v1(协议 XML 已随附在 native/protocols/ 下)。没有它,所有指针工具都会报 native/vpointer missing。vroid_status 会报告它是否存在。
为什么C 用一个C helper:ydotool 没有安装在参考机器上,且 /dev/uinput 是 0600 root:root,所以 evdev 注入需要 sudo 或 udev 规则。Wayland 虚拟指针协议不需要这两者,它移动的是合成器真实指针,并且能在任何窗口下工作。
向某个客户端注册
Claude Code:
claude mcp add vroid -- uv run --directory /path/to/mcp-vroid mcp-vroid通用 mcpServersJSON:
G4
通用 mcpServers JSON:
{
"mcpServers": {
"vroid": {
"command": "uv",
"args": ["run", "--directory", "/path/to/mcp-vroid", "mcp-vroid"]
}
}
}客户端通常会在一个净化过的环境中启动服务器。这台服务器会在启动时从运行时目录恢复 XDG_RUNTIME_DIR、WAYLAND_DISPLAY、HYPRLAND_INSTANCE_SIGNATURE 与 DISPLAY(src/mcp_vroid/session_env.py),所以 hyprctl/grim/XTEST 仍然能用;vroid_status 会显示它补了哪些。环境里已有的变量优先。
可选环境变量:
变量 | 默认值 | 含义 |
|
| 写入截图的位置 |
|
| 导出/保存的默认目录 |
|
| 指针辅助程序路径 |
|
| 发送给客户端的图片(单边最大长度,0=不缩放) |
工具
生命周期
tool | what it does |
| 需要时通过 Steam 启动 VRoid,把它停到 Hyprland workspace 9 上,记住你所在的工作区,再聚焦并全屏它。 |
| 窗口是否存在/聚焦/标题/几何、当前工作区、截图目录,以及 |
| 切回用户原来所在的工作区。VRoid(设在 ws 9)继续运行。 |
查看
tool | what it does | |
| 捕获窗口(或整个输出,对 Wine 的保存窗口按作用),保存到 captures 目录,并作为 MCP 图像内容返回,容纳客户端模型查看。报告原生图像尺寸以及传输时应用的降采样 factor。 | |
| 新截图 + tesseract;返回匹配单词的框与中心点,单位为图像 px。请传 | |
`vroid_find_button(color='primary' | 'disabled', label?, region?)` | 根据颜色找到 VRoid 的:由 solid 单色 |
|
|
执行(原始输入)
tool | what it does |
| 把指针分几步滑过去(其次能触发 hover 状态),再点击。 |
| 按下 → 24 步滑动 → 松开。右键拖动旋转相机,中键拖动平移。 |
| 滚轮( X11 buttons 4/5,6/7 为横向)。先把指针放在要滚的那块面板上。 |
| 通过 XTEST 向聚焦的控件键入内容。 |
| 如 |
执行(流程)
tool | what it does |
| 起始屏 → Create New → 基体 → 编辑器。 |
| Face / Hairstyle / Body / Outfit / Accessories / Look。 |
| 将 Parameters 面板滚动到对应行,然后在参数框输入精确值。 |
| 同上,针对 |
| 完整的 Export-as-VRM 流程,包括 VRM Settings 元数据模态框和 Wine 保存对话框。 |
| 带名字的用 Ctrl+Shift+S 存到显式 |
每个 acting 工具都会先在那之前聚焦 VRoid,若当前聚焦窗口不是 VRoid Studio 时拒绝被执行。
如何使用
大多数是:截图 → 查看 → 定位 → 点击/输入 → 再截图。
vroid_launch()vroid_screenshot(),并等待图片vroid_find_text("Export")(或vroid_find_button())获取坐标vroid_click(x, y)—— 始终从新的截图里获取坐标vroid_screenshot()确认实际发生
从最初的 spike 得来的重要规则:
读整个画面,而不是局部裁剪。 一个“Close Hairstyle Editor”的确认型弹窗正戳在屏幕中央,却导致六次点击失败,因为当时只对顶部 60 px 做了 OCR 检查。
不要通过 3D 视图判断变化。 VRoid 每帧都会做抖动(dithering),因此即使无事发生,全窗口 diff 也是 0.98 左右。要看一段 UI 条。
优先选择数值框,而不是拖敲滑块。
vroid_set_slider会输入精确值,拖拽留给我们没有数值框的控件。主导按钮是按颜色而不是文字查找。 如果你预期是蓝色胶囊却看到灰色胶囊,那是应用在告诉你某必填字段为空。
一个完整 2560×1440 帧先用 OCR 大约需要 10 秒。合并起来传
region。
坐标空间
实行有三个空间,参数各不相同:
空间 | 参考机型上的尺寸 | 由谁使用 |
Hyprland layout(逻辑层) | 2048 × 1152 |
|
截图的 image pixels | 2560 × 1440 | tesseract、cv2、你见到的所有内容 |
X11 像素(Xwayland) | 2560 × 1440 | XTEST |
工具默认接收并返回 image px(space="image"),并在内部自动换算坐标,所以你可以把 vroid_find_text 直接输出给 vroid_click。如果 MCP_VROID_MAX_IMAGE_PX 降采样了你看到的图片,请将你读到的坐标乘以给出的 downscale 因子的倒数——或者直接调用 vroid_find_text,它始终返回原生 px。
UI 地图(VRoid Studio 2.14.0,英文版)
坐标都是2560×1440 全屏窗口截图的 image px。把它们当作提示即可,工具会优先用 OCR 定位。
开始屏幕 — Create New + 卡片位于约 (118, 218),说明文字位于 (118, 328);右上角 New / Open 位于 (2439, 99) / (2495, 100);下方为 Sample Models 网格。点击 Create New 会打开一个模态框,文字为 "Select a base to start with",其中 Fem (1199, 862) 与 Masc (1359, 862) 是说明标签——应点击说明文字上方约 100 像素处的缩略图。
编辑器 — 标签栏位于 y ≈ 23:Face 97 · Hairstyle 198 · Body 302 ·
Outfit 392 · Accessories 509 · Look 622。汉堡菜单 ☰ 位于 (29, 23) →
Save (Ctrl+S)、Save As… (Ctrl+Shift+S)、导入/批量导出、撤销/重做、返回
模型选择界面——Escape 不会关闭此菜单,需点击其他位置。右上角工具栏:相机 (2415, 23),分享/导出 (2464, 23),竖向菜单 ⋮
(2512, 23)。左侧图标条(x ≈ 24,第一个图标 y ≈ 77,之后每个间隔约 48 像素)=
当前标签页的子分类。左侧面板 = 预设网格,Presets/Custom 位于 y ≈ 120。右侧面板 = Customize,然后是 Parameters。
右侧面板控件
控件 | 驱动方式 |
滑块 | 使用 x ≈ 2505 处的数字输入框(对应 |
颜色 | 使用 x ≈ 2450 处的 |
复选框 / 单选按钮 | 直接点击小方块/圆圈 |
折叠面板 (accordion) | 点击标题(例如 |
下拉框 | 仅在原生 Wine 对话框中出现;先点击,再用方向键操作 |
Body 参数从 Model's Height : 161.2 cm 开始,然后是 Fem Height、
Masc Height、Body Size、Head Size、Head Width、Head Tip (Y)、
Neck Length/Thickness/Width、Soften Collarbone,……Face 参数包括:
Eye 大小 X/Y,Eye Position (X/Y)、Rotate Eye Socket、Inner/Outer Eye Slant、Iris Size X/Y、Gaze (Y),……(共约 40行;工具会为你自动滚动。)
发型编辑 — Hairstyle 标签页 → 左侧图标栏的发型图标 → Custom 子标签页 →
+ Create New → 右侧出现 Edit Hairstyle。其中有:Add Freehand Hair Guides / Add Procedural Hair Guides、Hair Groups 列表,以及位于上方的
(330 / 365 / 398 / 432, 83) 的工具面板,撤销/重做在 (76, 23) / (133, 23)。退出前会提示:点击 ✕(23, 23)会弹出 Close Hairstyle Editor
对话框,其中有 Save as new item / Overwrite / Close without saving 三个选项。
导出为 VRM — 点击分享图标 (2462, 23) → 选择 Export as VRM → 进入全屏导出页面,可见蓝色 Export 胶囊按钮(约 (2412, 197)),然后再打开VRM Settings** 模态框(居中、可滚动,约 x 1000–1560 范围):其中包含 Export Format 的单选项 VRM 0.0/VRM 0.0,Avatar Name 字段为必填项,Version,以及 Creators 必填,版权/联系方式/参考资料,以及使用方式勾选框;Export 胶囊按钮在必填项填好前都会是灰色不可点击状态。接下来是 Wine 保存对话框(独立窗口,标题为 Export):其 File name: 输入框会自动获得焦点且文本已全选,所以直接输入 Windows 路径并回车触发默认按钮即可。Proton 前缀会把 Z:\ 映射为 /,因此 /home/nuri/x 对应 Z:\home\nuri\x。**不要把 OCR 识别到的 Save 当作唯一线索**:Save in: 标签也会匹配同一个关键词。
脆弱之处
整个定位都完全依赖 OCR。 字号较小、字距较大或浅底深字的标签容易被拆开或漏识别(例如
Export→E+xport)。图标完全无文字——这些 anchor 是按窗口尺寸硬编码的位置比例,pixiv 重新调整 UI 后就可能移动。固定锚点是按 2560×1440 分辨率、125% 缩放标定的。 如果换了别的显示器,可能需要重新量一次。
模态框可能出现在你搜索区域之外,并会悄悄吞掉点击。
时序问题。 选定基座后约 5 秒 3D 视口才出现;导出需要 5–30 秒(模型越重越久)。
Wine 对话框是一个独立的窗口,有完整的填充和几何设置,请对
vroid_screenshot(whole_screen=true)下手。语言。 这些前提都假设 UI 是英文。如果 VRoid 显示为日文,向上角骨、通过
⋮→ Settings → Language 改成英文。闲置屏保 可能在运行中随时抢占会话。保护逻辑拒绝在屏保窗口呼吸输入,并且在动手前只会关闭那一个窗口(只关那一个)。
安全注意
这个服务端会向真实桌面会话注入真实鼠标/键盘事件,并截取整个桌面的截图。 这就是它的核心目标,同时也正是风险所在:
截图可能包含屏幕上的任意可见内容——
whole_screen=true会全屏捕获,而且截图会明文(不加密)写到磁盘。按键会发往当前有焦点的窗口。驱动会跳过 VRoid Studio 以外的任何窗口,但即使被攻破或依赖提示不善,仍然可能点到 VRoid 内部任何位置。
vroid_launch(restart=true)会杀掉 VRoid Studio,未保存的工作会丢失。此处没有任何沙箱,也没有确认确认步骤。
请在有人的陪同下运行,在该会话中一直监视,不要让无人看管的 agent 长时间驱动它。完成后调用 vroid_release() 把桌面交还给你。
开发
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 herevroid-driver(mcp_vroid.driver.cli)是原型阶段的命令行界面——其中包含 launch、shot、find、click、tab、slider、export、cam、apply-params 等命令,非常适合在没有 MCP 客户端参与的情况下做调试。
致谢与许可证
驱动代码(src/mcp_vroid/driver/、native/)起初是来自我自己的 arrakis 项目,后来打成 tools/vroid-driver 的独立 spike,在这里与 MCP server 包装后一并提供。
MIT —— 见 LICENSE。
Maintenance
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
- FlicenseBqualityDmaintenanceEnables 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
- AlicenseNot gradedqualityCmaintenanceEnables 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.6Apache 2.0
- AlicenseAqualityAmaintenanceWraps 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.1712MIT
- FlicenseNot gradedqualityBmaintenanceEnables AI assistants to show, animate, and control a VRM character on the desktop, including posing and motion installation via MCP tools.1
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.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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