コンテンツにスキップ

Windowsミニオンのセットアップ

Windows マシンは @geekbeer/minion パッケージを使ってセルフホストミニオンとして運用できます。NSSM ベースの Windows Service として登録され、HQ からの install / update / restart が確実に動作します。初回セットアップ時のみ管理者権限が必要で、以降の日常運用(start/stop/restart/status 等)は一般ユーザーで実行できます。

flowchart LR
subgraph Windows["Windows PC"]
CLI["minion-cli-win"]
Server["エージェント\n(Fastify :8080)"]
Terminal["terminal-server\n(:7681)"]
PTY["node-pty セッション"]
Claude["Claude Code CLI"]
VNC["TightVNC\n(:5900, localhost only)"]
WSockify["websockify\n(:6080)"]
Server --> PTY
Terminal --> PTY
PTY --> Claude
WSockify --> VNC
end
subgraph Cloud["Cloud"]
HQ["HQ Server"]
end
HQ <-->|HTTPS / Cloudflare Tunnel| Server
HQ -->|WebSocket proxy| Terminal
HQ -->|WebSocket proxy| WSockify

WindowsミニオンとLinuxミニオンの違い

Section titled “WindowsミニオンとLinuxミニオンの違い”
項目WindowsLinux
CLIminion-cli-win (Node.js → PowerShell)minion-cli (Bash)
サービスマネージャNSSM (Windows Service)systemd / supervisord
管理者権限setup / uninstall のみ必要必要 (root)
エージェント実行ユーザーLocalSystemminion(専用システムユーザー)
デスクトップログオンユーザー (VNC=ログオンタスク)ubuntu(Xvfb + VNC)
ターミナルセッションnode-ptytmux
データディレクトリ<target-user>\.minion\(setup時に選択)/opt/minion-agent/
自動再起動NSSM サービス (AppRestartDelay)systemd restart
  • Node.js 22 LTS (engines: ">=22.0.0")。セットアップ時に未インストールの場合は winget install OpenJS.NodeJS.LTS で自動インストールされます。手動インストールする場合は nodejs.org から 22 LTS を推奨。Node.js 24(Current版)でも動作しますがbetter-sqlite3 のプリビルドバイナリが未提供の場合があり、その場合は自動的に Node.js 組み込みの node:sqlite にフォールバックします(v3.5.31+)。
  • 管理者権限 (Administrator)。パッケージインストール(npm install -g)、初回セットアップ、アンインストール時に必要。以降の操作(configure/start/stop/restart/status等)は一般ユーザーで実行可能。
  • PowerShell 実行ポリシー: デフォルトの Restricted ポリシーでは npm.ps1 の実行がブロックされます。事前に以下のいずれかで解除してください。
    Terminal window
    # 方法1: 現在のユーザーに対して永続的に許可(推奨)
    Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
    # 方法2: 現在のセッションのみ一時的に許可
    Set-ExecutionPolicy -Scope Process -ExecutionPolicy RemoteSigned
    RemoteSigned はローカルスクリプトを許可し、インターネットからダウンロードしたスクリプトには署名を要求する安全なポリシーです。または、PowerShell の代わりに cmd.exe(コマンドプロンプト)から npm を実行すれば実行ポリシーの影響を受けません。

HQ ダッシュボードから「新規ミニオン」を作成し、プロバイダタイプを Self-hosted に設定します。発行される minion_idapi_token を控えておきます。

2. パッケージをインストール(管理者PowerShellで実行)

Section titled “2. パッケージをインストール(管理者PowerShellで実行)”
Terminal window
# 管理者PowerShellで実行
npm install -g @geekbeer/minion

Note: 管理者で npm install -g を実行すると、パッケージは C:\Program Files\nodejs\node_modules\ にインストールされます。LocalSystem で動作する NSSM サービスから直接参照可能です。

Note (v3.5.31+): postinstall が npm のグローバル bin ディレクトリ(npm prefix -g)をユーザー PATH に自動追加します。Node.js のインストール方法(exe / winget 等)によっては %APPDATA%\npm が PATH に含まれず minion-cli-win コマンドが見つからない場合があります。PATH 変更は永続的ですが、反映にはターミナルの再起動が必要です。uninstall 時に自動削除されます。

3. セットアップを実行(管理者PowerShellで実行)

Section titled “3. セットアップを実行(管理者PowerShellで実行)”
Terminal window
# 管理者PowerShellで実行(引数不要)
minion-cli-win setup

セットアッププロセス(インフラ構築のみ):

  1. ターゲットユーザー選択(マシン上のユーザープロファイル一覧から選択)
  2. Node.js 22 LTS の確認・インストール(winget install OpenJS.NodeJS.LTS
  3. Git のインストール(git-bash)
  4. Claude Code CLI のインストール
  5. <target-user>\.minion\ ディレクトリの作成
  6. node-pty のインストール(node-pty-prebuilt-multiarch を優先、失敗時は node-pty
  7. NSSM の検証(パッケージに同梱)
  8. Windows Service の登録(LocalSystem、SDDL でターゲットユーザーに制御権付与)
  9. TightVNC の MSI インストール + レジストリ設定 + ログオンタスク登録
  10. websockify のセットアップ(Python + pip)
  11. cloudflared のダウンロード + NSSM サービス登録
  12. ファイアウォールルール自動設定(TCP 8080, 7681, 6080)

4. HQ へ接続(一般ユーザーで実行)

Section titled “4. HQ へ接続(一般ユーザーで実行)”
Terminal window
# 一般ユーザーのPowerShellで実行
minion-cli-win configure `
--hq-url https://<your-hq-url> `
--minion-id <minion-id> `
--api-token <api-token>

Configure プロセス:

  1. .env に HQ 接続情報を書き込み
  2. バンドルされたスキル・ルールをデプロイ
  3. Cloudflare Tunnel の設定(--setup-tunnel 指定時)— 管理者権限で実行した場合は minion-cloudflared NSSM サービスの登録も自動実行。一般ユーザーの場合はサービス起動のみ(事前に管理者権限で登録済みである必要あり)
  4. サービス起動(sc.exe 経由、管理者不要)
  5. ヘルスチェック + HQ への接続完了通知

管理者権限は setup / uninstall のみ必要です。

コマンド権限仕組み
setup, uninstall管理者必須サービス登録、ユーザー作成、ファイアウォール設定
configure一般ユーザー(トンネルサービス登録時は管理者推奨).env 書き込み + スキルデプロイ + トンネル設定・サービス登録 + サービス起動 + HQ通知
start, stop, restart一般ユーザーsetup 時に SDDL でサービス制御権を付与
status, health, daemons, diagnose一般ユーザーsc.exe query(読み取りのみ)

SDDL(Security Descriptor Definition Language)により、setup を実行したユーザーの SID にサービス制御権(Start/Stop/Pause/Query)を付与します。SID は <target-user>\.minion\.setup-user-sid に保存され、ターゲットユーザーのプロファイルパスは <target-user>\.minion\.target-user-profile に保存されます(configure / uninstall / diagnose から自動参照)。

全 NSSM サービスは LocalSystem で実行されます。

サービス実行ユーザー備考
minion-agentLocalSystemUSERPROFILE/HOME 環境変数でターゲットユーザーのパスを参照
minion-websockifyLocalSystemVNC (5900) への WebSocket プロキシ (6080)
minion-cloudflaredLocalSystemCloudflare Tunnel
TightVNCログオンタスクユーザーセッションで -run モード起動(デスクトップキャプチャに必要)

LocalSystem は最高権限を持つため、権限分離が必要な場合は専用サービスアカウント(例: minion-svc)を別途作成して NSSM ObjectName に設定することを推奨します。

セットアップ時に以下のレジストリ値が HKLM:\Software\TightVNC\Server に自動設定されます。

レジストリ値説明
LoopbackOnly1localhost からの接続のみ許可
AllowLoopback1ループバック接続を有効化
UseVncAuthentication0VNC パスワード認証を無効化
UseControlAuthentication0Windows ログオン認証を無効化
RfbPort5900VNC ポート

VNC パスワードを無効化しても安全な理由:

  • LoopbackOnly=1 により外部からの直接 VNC 接続は不可
  • websockify のみが localhost 経由で接続
  • ブラウザ〜HQ 間は Supabase セッション認証で保護済み
  • Linux コンテナミニオンも同じ設計(VNC 認証なし + localhost 限定)

setup-complete 呼び出し時に、Windows の LAN IP が自動検出されて HQ に送信されます。手動設定は不要です。

ファイアウォール(自動設定)

Section titled “ファイアウォール(自動設定)”

セットアップ時に自動設定されます。手動で追加する必要はありません。

設定されるルール:

  • Minion Agent - TCP 8080 (Inbound, All Profiles)
  • Minion VNC - TCP 6080 (Inbound, All Profiles)
Terminal window
minion-cli-win status
Terminal window
curl http://<windows-ip>:8080/api/status \
-H "Authorization: Bearer <api-token>"

期待されるレスポンス:

{
"status": "online",
"uptime": 123.45,
"version": "2.28.0",
"llm_command_configured": true
}

Windows マシン上で:

Terminal window
Invoke-RestMethod -Uri "https://<your-hq-url>/api/health"

4. WebSocket(ターミナル)の動作確認

Section titled “4. WebSocket(ターミナル)の動作確認”

HQ ダッシュボードを開き、対象ミニオンの Terminal タブを開きます。HQ が ws://<windows-ip>:7681/ws/<session> への WebSocket 接続をプロキシします。

%USERPROFILE%\.minion\.env に配置されます:

AGENT_PORT=8080
HEARTBEAT_INTERVAL=30
MINION_USER=<username>
HQ_URL=https://<your-hq-url>
API_TOKEN=<token>
MINION_ID=<uuid>
Terminal window
minion-cli-win reconfigure `
--hq-url https://<new-hq-url> `
--minion-id <new-id> `
--api-token <new-token>
Terminal window
minion-cli-win status # エージェントサービスのステータス確認
minion-cli-win health # ヘルスチェック
minion-cli-win daemons # 全サービスステータス(agent, vnc, websockify, cloudflared)
minion-cli-win restart # エージェントサービスのみ再起動
minion-cli-win restart --all # 全サービス再起動(agent + websockify + cloudflared、管理者権限必須)
minion-cli-win stop # エージェントサービス停止
minion-cli-win stop --force # 全サービスとロック保持プロセスを強制停止(管理者権限必須)
minion-cli-win start # エージェントサービス起動
minion-cli-win diagnose # 詳細診断

stop --force を使う場面: アップデート失敗で .env が壊れた/エージェント API が応答しない/NSSM が node.exe を再起動し続けて node_modules\@geekbeer\minion\ が削除できない、などで通常の stop が機能しないとき。NSSM の AppExit を一時的に書き換えて自動再起動を止め、関連プロセスを taskkill するため、進行中タスクは強制中断されます(/api/shutdown による HQ への offline heartbeat 通知もスキップされます)。通常運用では stop(graceful)を使用してください。

restart --all を使う場面 (v3.59.5+, 管理者権限必須): Windows Update 後など、一部サービスのみ停止したまま戻ってこないとき。素の restartminion-agent のみ対象なので、minion-cloudflaredSERVICE_DEMAND_START で登録されているため OS 再起動時に自動起動しない)が落ちていると tunnel が回復しません。restart --all は全 NSSM サービスを順に再起動した後、MinionVNC / MinionWSL ログオンタスクも re-trigger します。MinionVNC schtask が /RL HIGHEST で登録されているため、schtasks の発火に管理者権限が必要です。

Terminal window
Get-Content $env:USERPROFILE\.minion\logs\service-stdout.log -Tail 50
Get-Content $env:USERPROFILE\.minion\logs\service-stderr.log -Tail 50

Windows ミニオンは tmux の代わりに node-pty でターミナルセッションを管理します。

const pty = require('node-pty-prebuilt-multiarch')
const proc = pty.spawn('cmd.exe', [], { name: 'xterm-256color' })

node-pty は PTY エミュレーションを行うため、CLI が出力する ANSI エスケープシーケンスがそのまま onData に渡されます。ログファイルへの書き込み時は ANSI をストリップしてクリーンなテキストとして記録されます。

LLM_COMMAND 環境変数でスキル実行方法を制御できます:

LLM_COMMAND=claude -p '{prompt}'

セッション命名規則: wf-{workflow_id_8char}-{exec_id_4char}(Linux と同じ)。

ヘッドレス運用(ディスプレイなし)

Section titled “ヘッドレス運用(ディスプレイなし)”

ミニPC などディスプレイを接続せずに運用する場合、TightVNC がミラーリングする物理ディスプレイが存在しないため、VNC 接続がブラックアウトします。

Linux VPS ミニオンでは Xvfb(仮想フレームバッファ)で仮想ディスプレイを作成するためこの問題は発生しません。Xvfb は X11 専用のため Windows / macOS では使用できません。

HDMI ダミープラグ(ヘッドレスディスプレイアダプタ)を HDMI ポートに挿すだけで解決します。OS がディスプレイ接続を認識し、TightVNC が正常に画面をキャプチャできるようになります。

  • Amazon 等で「HDMI ダミープラグ」で検索(数百円〜)
  • ソフトウェアの変更は不要。現在の TightVNC + websockify 構成がそのまま動作
  • Mac mini をミニオン化する場合も同様に HDMI ダミープラグで対応可能

HDMI ダミープラグ使用時の注意: DPI スケーリング

Section titled “HDMI ダミープラグ使用時の注意: DPI スケーリング”

HDMI ダミープラグを接続すると、VNC の画面が 1/4 程度に縮小表示 される場合があります。クリック座標はズレず元の位置に判定が残るのが特徴です。

原因: 安価なダミープラグの多くは EDID で 4K(3840x2160)等の高解像度を報告します。Windows がこれに応じて DPI スケーリングを 150〜200% に自動設定するため、TightVNC が物理ピクセルでキャプチャした画面と論理座標系にズレが生じます。

解像度変更では直らない場合がある: EDID 固定型のダミープラグでは、Windows のディスプレイ設定で解像度を 1920x1080 に変更しても、再接続時に EDID の値(4K 等)に戻されます。

対処法 1: DPI スケーリングを 100% にする(推奨)

Section titled “対処法 1: DPI スケーリングを 100% にする(推奨)”

ヘッドレスミニオンでは UI の可読性を気にする必要がないため、スケーリング 100% で問題ありません。

Terminal window
# 現在の DPI を確認(96=100%, 120=125%, 144=150%, 192=200%)
Get-ItemProperty 'HKCU:\Control Panel\Desktop\WindowMetrics' -Name AppliedDPI

設定 → ディスプレイ → 拡大縮小とレイアウト100% に変更後、サインアウト→再サインイン(または再起動)が必要です。

対処法 2: TightVNC を DPI 非対応モードで実行する

Section titled “対処法 2: TightVNC を DPI 非対応モードで実行する”

TightVNC の実行ファイルに対して Windows の DPI 互換性設定を適用します。

Terminal window
$tvnPath = "$env:USERPROFILE\.minion\tightvnc\PFiles\TightVNC\tvnserver.exe"
New-Item -Path "HKCU:\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers" -Force
Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers" `
-Name $tvnPath -Value "~ DPIUNAWARE"

設定後、TightVNC を再起動:

Terminal window
Stop-Process -Name tvnserver -Force -ErrorAction SilentlyContinue
Start-Sleep -Seconds 2
& $tvnPath -run

対処法 3: EDID 書き換え対応アダプタを使用する

Section titled “対処法 3: EDID 書き換え対応アダプタを使用する”

EDID 固定型ではなく、EDID 書き換え対応の仮想 HDMI アダプタ(「Headless Ghost」等)を使えば任意の解像度(1920x1080 等)を設定でき、DPI スケーリング問題を根本回避できます。やや高価(数千円〜)。

npm コマンドが「スクリプトの実行が無効」エラーで失敗する

Section titled “npm コマンドが「スクリプトの実行が無効」エラーで失敗する”
npm : このシステムではスクリプトの実行が無効になっているため、ファイル C:\Program Files\nodejs\npm.ps1 を
読み込むことができません。
+ CategoryInfo : セキュリティ エラー: (: ) []、PSSecurityException
+ FullyQualifiedErrorId : UnauthorizedAccess

PowerShell の実行ポリシーが Restricted(デフォルト)のため、npm.ps1 スクリプトがブロックされています。事前準備 を参照して実行ポリシーを変更するか、cmd.exe から実行してください。

npm install 後に minion-cli-win コマンドが見つからない

Section titled “npm install 後に minion-cli-win コマンドが見つからない”
minion-cli-win : 用語 'minion-cli-win' は、コマンドレット、関数、スクリプト ファイル、または
操作可能なプログラムの名前として認識されません。

v3.5.31+ の場合: postinstall が npm グローバル bin ディレクトリを自動で PATH に追加します。ターミナルを再起動すれば反映されます。

v3.5.30 以前の場合: 手動で PATH に追加してください:

Terminal window
[Environment]::SetEnvironmentVariable('PATH',
[Environment]::GetEnvironmentVariable('PATH', 'User') + ';' + (npm prefix -g), 'User')

設定後、ターミナルを再起動してください。

node-pty のインストールが失敗する

Section titled “node-pty のインストールが失敗する”

プリビルド版を先に試してください:

Terminal window
npm install -g node-pty-prebuilt-multiarch

失敗する場合は Visual Studio Build Tools をインストールしてから再試行:

Terminal window
npm install -g node-pty

better-sqlite3 のビルドが失敗する(npm install -g 時)

Section titled “better-sqlite3 のビルドが失敗する(npm install -g 時)”
npm error command failed
npm error command C:\WINDOWS\system32\cmd.exe /d /s /c prebuild-install || node-gyp rebuild --release
npm error prebuild-install warn install No prebuilt binaries found (target=24.x.x ...)
npm error gyp ERR! find Python ... Could not find any Python installation to use

原因: better-sqlite3 はネイティブモジュールで、Node.js バージョンごとにプリビルドバイナリが必要です。Node.js 24(Current版)など新しいバージョンではプリビルドが未提供の場合があり、フォールバックの node-gyp ビルドには Python と Visual Studio Build Tools が必要です。

v3.5.31+ の場合: better-sqlite3optionalDependencies のため、ビルド失敗でもインストール自体は成功します。実行時に Node.js 組み込みの node:sqlite に自動フォールバックするため、追加対応は不要です。

v3.5.30 以前の場合: 以下のいずれかで対処してください:

  1. Node.js 22 LTS にダウングレード(推奨): winget install OpenJS.NodeJS.LTS でプリビルドバイナリが利用可能
  2. Python + Build Tools をインストール: npm install -g windows-build-tools または Visual Studio Build Tools を手動インストール

CLI の診断コマンドで確認してください:

Terminal window
minion-cli-win diagnose
minion-cli-win daemons

update-agent 後に minion-agent が起動しない(依存ファイル欠落)

Section titled “update-agent 後に minion-agent が起動しない(依存ファイル欠落)”

以下のような依存ファイル欠落による起動失敗が発生することがあります:

Error: Cannot find module './refs/data.json'

原因: 何らかのプロセスが Fastify / ajv のファイルを握っている状態で npm install が走り、node_modules/ajv/dist/refs/* が欠落したまま @geekbeer/minion のバージョンだけが更新された状態。

自動復旧後も駄目なとき(管理者 PowerShell で):

Terminal window
# 1. 関連サービス / タスクを止める
& "$env:USERPROFILE\.minion\nssm.exe" stop minion-agent confirm
schtasks /End /TN "MinionWSL"
# 2. 残った node.exe を掃除
Get-CimInstance Win32_Process -Filter "Name='node.exe'" |
Where-Object { $_.CommandLine -match '@geekbeer.minion|wsl-session-entry' } |
ForEach-Object { Stop-Process -Id $_.ProcessId -Force }
# 3. パッケージディレクトリを強制削除してクリーン再インストール
$prefix = (npm config get prefix).Trim()
Remove-Item -Recurse -Force "$prefix\node_modules\@geekbeer\minion"
npm install -g @geekbeer/minion@latest
# 4. サービス再開
& "$env:USERPROFILE\.minion\nssm.exe" start minion-agent
schtasks /Run /TN "MinionWSL"

更新スクリプトのログは ~/.minion/logs/update-agent.log(dev は update-agent-dev.log)を参照してください。

“Server is not configured properly” エラー

TightVNC のレジストリ設定を確認してください。VNC は NSSM サービス(LocalSystem)として Session 0 で動作するため、レジストリは HKLM を参照します:

Terminal window
Get-ItemProperty "HKLM:\Software\TightVNC\Server" | Select-Object UseVncAuthentication, LoopbackOnly, AllowLoopback

期待値: UseVncAuthentication=0, LoopbackOnly=1, AllowLoopback=1

設定が正しくない場合は setup を再実行するか、手動で設定(管理者PowerShellで実行):

Terminal window
$regPath = "HKLM:\Software\TightVNC\Server"
Set-ItemProperty -Path $regPath -Name UseVncAuthentication -Value 0 -Type DWord
Set-ItemProperty -Path $regPath -Name UseControlAuthentication -Value 0 -Type DWord
Set-ItemProperty -Path $regPath -Name LoopbackOnly -Value 1 -Type DWord
Set-ItemProperty -Path $regPath -Name AllowLoopback -Value 1 -Type DWord

設定変更後は TightVNC を再起動:

Terminal window
Stop-Process -Name tvnserver -Force -ErrorAction SilentlyContinue
Start-Sleep -Seconds 2
& "$env:USERPROFILE\.minion\tightvnc\PFiles\TightVNC\tvnserver.exe" -run

websockify が起動しない

Python が Microsoft Store スタブの場合は pip が使えません。setup v2.31.0+ で自動インストールされますが、手動の場合:

Terminal window
winget install Python.Python.3.12
pip install websockify

ポートの確認

Terminal window
netstat -an | Select-String "5900" # TightVNC
netstat -an | Select-String "6080" # websockify

HQ からミニオンに到達できない

Section titled “HQ からミニオンに到達できない”
  1. ファイアウォールルールが有効か確認: Get-NetFirewallRule -DisplayName "Minion*"
  2. ポートが Listen しているか確認: Test-NetConnection -ComputerName localhost -Port 8080
  3. エージェントプロセスが動作しているか確認: Get-Process -Name node | Where-Object { $_.CommandLine -like '*server.js*' }

ファイアウォールルールが有効なのに LAN アクセスが通らない

Section titled “ファイアウォールルールが有効なのに LAN アクセスが通らない”

ファイアウォールルールを追加しても外部から到達できない場合、以下を順に確認してください。

1. -LocalPort-Profile Any を使用しているか

Terminal window
# ルールの詳細を確認
Get-NetFirewallRule -DisplayName "Minion Agent" | Format-List DisplayName, Enabled, Action, Profile
Get-NetFirewallRule -DisplayName "Minion Agent" | Get-NetFirewallPortFilter

ProfileAny でない場合、Wi-Fi ネットワーク(Public プロファイル)ではルールが無効です。ルールを削除して再作成してください:

Terminal window
Remove-NetFirewallRule -DisplayName "Minion Agent"
New-NetFirewallRule -DisplayName "Minion Agent" -Direction Inbound -LocalPort 8080 -Protocol TCP -Action Allow -Profile Any

2. Node.js のブロックルールが存在しないか

Node.js 初回起動時に Windows のネットワークアクセスダイアログで「ブロック」を選択すると、アプリケーション単位のブロックルールが自動作成されます。このルールはポート単位の許可ルールより優先されます。

Terminal window
# Node.js のブロックルールを検索
Get-NetFirewallRule -Direction Inbound -Action Block -Enabled True |
Get-NetFirewallApplicationFilter |
Where-Object { $_.Program -like '*node*' } |
ForEach-Object { Get-NetFirewallRule -AssociatedNetFirewallApplicationFilter $_ } |
Format-List DisplayName

見つかった場合は削除してください:

Terminal window
Remove-NetFirewallRule -DisplayName "<表示されたルール名>"

3. 切り分け: ファイアウォールを一時無効化

上記で解決しない場合、ファイアウォール自体が原因か切り分けてください:

Terminal window
# 一時的に無効化(管理者PowerShell)
Set-NetFirewallProfile -All -Enabled False
# 別のマシンからテスト
# curl http://<WindowsのIP>:8080/api/health
# 確認後すぐに再有効化
Set-NetFirewallProfile -All -Enabled True