Skip to main content
Glama
nhodges
by nhodges

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 スパイクです。ここでは mcp_vroid.driver としてベンダリングしており、同じコードを MCP クライアントがインストールして起動できるように再パッケージしています。


必要条件

項目

理由

Hyprland(>= 0.55、Lua dispatch API)

ウィンドウの検出、フォーカス、ワークスペース

VRoid Studio を Steam/Proton(appid 1486350)から実行する

操作対象のアプリ

grim

スクリーンショット

tesseract + eng traineddata

OCR

gccwayland-scannerlibwayland-client

ポインターヘルパーのビルド

Xwayland(DISPLAY

キーボードとホイールは X11 XTEST を通る

Python 3.11+uv

サーバー本体

Python の依存関係(uv sync でインストール):mcppillownumpyopencv-python-headlesspytesseractpython-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 optional

native/build.shzwlr_virtual_pointer_unstable_v1(native/protocols/ に同梱)向けの約 150 行の C クライアントをコンパイルします。これが無いと、すべてのポインターツールは native/vpointer missing で失敗します。vroid_status はその有無を報告します。

なぜ C ヘルパーなのか:ydotool は基準のマシンにインストールされておらず、/dev/uinput0600 root:root なので、evdev による注入には sudo か udev ルールが必要です。Wayland の仮想ポインター・プロトコルはどちらも不要で、実際のコンポジタのカーソルを動かし、どのウィンドウでも機能します。

クライアントに登録する

Claude Code:

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

一般的な mcpServers JSON:

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

クライアントは多くの場合、 サニタイズされた環境 でサーバーを起動します。このサーバーは、起動時に XDG_RUNTIME_DIRWAYLAND_DISPLAYHYPRLAND_INSTANCE_SIGNATUREDISPLAY を実行時ディレクトリから復元します(src/mcp_vroid/session_env.py)。これにより、環境が変わっても hyprctl/grim/XTEST は動作します。vroid_status は何を補完したかを表示します。すでに環境にある値は優先されます。

任意の環境変数:

変数

デフォルト

説明

MCP_VROID_CAPTURES

$XDG_STATE_HOME/mcp-vroid/captures

スクリーンショットの保存先

MCP_VROID_OUT

$XDG_STATE_HOME/mcp-vroid/out

エクスポート・保存の既定ディレクトリ

MCP_VROID_VPOINTER

<checkout>/native/vpointer

ポインターヘルパーへのパス

MCP_VROID_MAX_IMAGE_PX

1600

クライアントへ送る画像の長辺(0 でダウンスケールしない)

ツール

ライフサイクル

ツール

説明

vroid_launch(restart=false, timeout=240)

必要なら Steam 経由で VRoid を起動し、Hyprland のワークスペース 9 に「駐車」させ、元いたワークスペースを記憶して、フォーカスと全画面を実行します。restart=true にする場合、稼働中のインスタンスを先に kill します。未保存の作業は失われます。

vroid_status()

ウィンドウの有無・フォーカス・タイトル・位置 、アクティブなワークスペース、キャプチャの保存場所、および vpointer/grim/tesseract/hyprctl が利用可能かどうかを報告。読み取り専用で、OCR は行いません。

vroid_release()

ユーザーが元いたワークスペースに戻します。VRoid はワークスペース 9 で起動したままですがいられるわけではありません。

表示

ツール

説明

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

ウィンドウ(Wine の保存画面ために出力画面全体)をキャプチャし、キャプチャディレクトリに保存して、クライアントのモデルに画像として返します。ネイティブ画像のサイズと転送時に適用されるダウンスケール係数も報告します。

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

新しいキャプチャ + tesseract を使い、一致した単語の四角形と中心点を画像ピクセルで返します。region を渡すこと。全フレームの OCR は約10秒、パネルは約2秒です。

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

白字の #0096FA をピンク色で見つけます。Tesseract は白文字の青ラベルを判定できないため。グレーピンは 無効 を示します。

vroid_current_screen()

start / editor / export_vrm / hair_editor / unknown のどれかを返します。

操作(生の入力)

ツール

説明

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

ポインターが少し多分数ステップで移動(ホバー状態を確実になくため)し、クリックします。

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

押下 → 24 ステップのすべらせ → 離す。右ドラックでカメラが周囲し、中ドラックでパンします。

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

X11 の 4/5 ボタン(および 6/7 で水平)のホイール操作。スクロールしたいパネル上面にポインターを置いておきます。

vroid_type(text, clear_first=false)

XTEST 経由でフォーカス中のウィジェットにタイプします。

vroid_key(combo, times=1)

ReturnEscapectrl+sctrl+shift+s など。

操作(フロー)

ツール

説明

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

スタート画面 → Create New → ベース → エディタ。

vroid_open_tab(name)

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

vroid_set_slider(label, value)

パラメータ パネルを指定の行までスクロールし、数値ボックスに確定した値を入力ます。

vroid_set_color(label, hex)

同じ手順を #RRGGBB カラーボックスに対して行います。

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

Export toVRM の全体手順(VRM Settings のメタデータ モーダルと Wine の保存ダイアログを含む)を実行します。version で VRM1.0 または VRM0.0 を指定します。

vroid_save_project(name?)

.vroid ファイルへの Ctrl+Shift+S で保存、または引数なしで通常の[保存]

操作系のツールは、まず最初に VRoid がフォーカスされていることを確認し、 フォーカスが VRoid Studio のウィンドウでなければ動作しません

操作方法

基本的なループは、 スクリーンショット → 確認 → 位置を探る → アクション → もう一度スクリーンショット

  1. vroid_launch()

  2. vroid_screenshot() をして 画像をを見る

  3. 座標を得るために vroid_find_text("Export") (または vroid_find_button()

  4. vroid_click(x, y) — 座標は常に「新しく取った」キャプチャから取得します

  5. vroid_screenshot() で実際に何が起きたかを確認

試行錯誤して得られた知恵:

  • 全体を読め。 「Close Hairstyle Editor」の確認モーダルが画面の中央にあったのに、上位 60 px だけを知らせていたため 6 回失敗しました。

  • 3D ビューポートの差分で判断しない。 VRoid は毎フレーム ディザリングされるため、何もしていないのに画像全体の差分は ~0.98 になる。UIが define 部分を見ること。

  • スライダードラッグより数値ボックスを使う。 vroid_set_slider は正確な値をタイプします。ドラッグはボックスの無いコントロール専用。

  • 主要ボタンはテキストでなく色で見つける。 青いところにピンクーの代わり灰色ピルがある場合、必須項目が空であることをアプリが示しています。

  • 2560×1440 の全フレームの OCR は約10 秒です。region を指定してください。

座標空間

ここに3つの異なる座標空間があります:

空間

基準マシン上のサイズ

使用するもの

Hyprland レイアウト(論理)

2048×1152

hyprctl、仮想ポインタ

キャプチャの 画像ピクセル

2560×1440

tesseract、cv2、見ているすべて

X11 ピクセル(Xwayland)

2560×1440

XTEST

ツールは既定では 画像ピクセル(空間 "space="image")で取得・戻納し、内部で変換します。vroid_find_text の出力/入力をvroid_click にそのまま渡せるという立地です。MCP_VROID_MAX_IMAGE_PX で送信された画像がダウンスケールされている場合、そこから読み取る座標は、報告された downscale 値の逆数で乗算してから使ってください。もしくは、常に native ピクセルを返す vroid_find_text を利用するば良い。

UI マップ(VRoid Studio 2.14.0、English)

座標のキャプチャ 2560×1440 (= fullscreen window) の image px。これら位置はあくまでヒントで、ツールはまず OCR で探索します。

起動画面Create New + カードは ≈ (118, 218)、キャプションは (118, 328)。右上の New / Open は (2439, 99) / (2495, 100)。その下にサンプルモデルのグリッド。Create New を押すと "Select a base to start with" というモーダルが開き、Fem (1199, 862) と Masc (1359, 862) のキャプションが並ぶ — キャプションの約 100 px 上のサムネイルをクリックする。

エディタ — タブ列は y ≈ 23:Face 97・Hairstyle 198・Body 302・Outfit 392・Accessories 509・Look 622。ハンバーガーメニュー (29, 23)→ 保存 (Ctrl+S)、名前を付けて保存… (Ctrl+Shift+S)、インポート/一括書き出し、元に戻す/やり直す、モデル選択へ戻る — Escape ではこのメニューは閉じない。他の場所をクリックする。右上のツールバー:カメラ (2415, 23)、共有/書き出し (2464, 23)、ケバブ (2512, 23)。左のアイコンレール(x ≈ 24、先頭アイコンは y ≈ 77、以降は約 48 px ごと)は、現在のタブのサブカテゴリ。左パネルは PresetsCustom があるプリセットグリッド(y ≈ 120)。右パネルはカスタマイズ、続いてパラメーター。

右パネルのコントロール

コントロール

操作方法

スライダー

x ≈ 2505 の数値ボックス (vroid_set_slider);トラックは x ≈ 2278 → 2516 で、0.0 が中心

カラー

x ≈ 2450 の #RRGGBB ボックス (vroid_set_color)

チェックボックス / ラジオ

四角/丸をクリック

アコーディオン

キャプションをクリック(例:> Reduce Polygons

ドロップダウン

ネイティブ Wine ダイアログの中のみ。クリック → 矢印キーで選択

Body のパラメーターは Model's Height : 161.2 cm から始まり、Fem HeightMasc HeightBody SizeHead SizeHead WidthHead Tip (Y)Neck Length/Thickness/WidthSoften Collarbone、…。Face のパラメーターは Eye Size X/YEyes Position (X/Y)Rotate Eye SocketInner/Outer Eye SlantIris Size X/YGaze (Y)、…(約 40 行;ツールが自動でスクロールしてくれる)。

ヘアエディター — Hairstyle タブ → 左のアイコン群から部品アイコン → Custom サブタブ → + Create New → 右パネル Edit Hairstyle。中には、Add Freehand Hair GuidesAdd Procedural Hair GuidesHair Groups リスト、ツールパレット(330 / 365 / 398 / 432, 83)、アンドゥー (76, 23) / (133, 23) がある。離れると確認が出る:(23, 23) の Close Hairstyle Editor モーダルが開き、Save as new itemOverwriteClose without saving を選ぶ。

VRM 書き出し — 共有アイコン (2464, 23) → Export as VRM → 全画面の書き出しページで、青い Export ピルバーは ≈ (2413, 197) → VRM Settings モーダル(中央、約 x 1000–1560、スクロール可能):Export Format のラジオ VRM1.0VRM0.0Avatar Name 必須VersionCreators 必須、著作権/連絡先/参考文献、利用条件のチェックボックス。Export ピルバーは、必須項目が両方埋まるまで グレーで無効のままWine の保存ダイアログ(独立ウィンドウ、タイトル Export):File name: フィールドはフォーカス&選択済みで開くので、Windows パスを打ち込めば上書きされ、Return で既定ボタンを 起動する。Proton のプレフィックスは Z:\/ にマップするため、/home/nuri/xZ:\home\nuri x になる。OCR で見つかった Save をクリックしてはダメ — Save in: ラベルが同じ needle に一致してしまうから。

壊れやすい点

  • OCR が位置特定の全部。 小さな、文字間隔が空いた、または明るい背景に薄い文字のラベルは分割・欠落する(ExportE + xport)。アイコンにはテキストが一切無いので、そのアンカーはウィンドウの割合で直書きされており、pixiv が UI を組み直すとずれる。

  • 固定アンカーは 2560×1440、スケール 1.25 で校正している比率。 別 のモニターでは fメモする必要がある。

  • モーダルは検索範囲の外に出て、クリックを静かに飲み込む。

  • タイミング。 ベースを選んでから 3D ビューポートが表示されるまで約 5 秒。書き出しは 5〜30 秒(重いモデルはより長い)。

  • Wine ダイアログは独立したウィンドウで、独自のクラスとジオメトリを持つ — そこで vroid_screenshot(whole_screen=true) を使う。

  • 言語。 この説明は英語UIを前提としている。VRoid が日本語で表示される場合は、ケバブ → Settings → Language で切り替える。

  • アイドル時のスクリーンセーバーが、実行途中にセッションを乗っ取ることがある。ガードは入力ように拒否し、操作前にそのウィンドウ一つ(それだけ)を閉じる。

セキュリティの注意

このサーバーは、実際のマウスとキーボードのイベントを、動作中のデスクトップセッションに挿入し、そのスクリーンショットを撮る。 それが目的であり、リスクでもある。

  • スクリーンショットは画面より何でも写し得る。whole_screen=true は全画面をキャプチャし、さらにそのまま暗号化されずにディスクへ書き出す。

  • キーストロークは、フォーカスを持つウィンドウに送られる。ドライバは、VRoid Studio がフォーカスされたウィンドウである限り動作を拒否する。言い換えれば、侵害された・不用意なプロンプト命令でも、VRoid の内部をクリックできてしまう。

  • vroid_launch(restart=true) は VRoid Studio を強制終了し、未保存の作業を失わせる。

  • ここにあるものはサンドボックス化されておらず、確認ステップもない。

有人監視で実行する — 見ているセッションで走らせ、エージェントを無監視で運転させないこと。終了時は 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 here

vroid-drivermcp_vroid.driver.cli)は、スパイクのシェル・インターフェイス — launchshotfindclicktabsliderexportcamapply-params、… — MCP クライアントを介さずにデバッグするのに便利。

クレジットとライセンス

ドライバー (src/mcp_vroid/driver/native/) は、私の arrakis プロジェクトの中の tools/vroid-driver スパイクに始まり、MCP サーバーで包んだ形でここに同梱している。

MIT — 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