Skip to main content
Commands, package names, and image names on this page come from the open-source project that Mibyan Desktop is built on, and can differ from the Mibyan Desktop installer. For the supported Mibyan install and update path, see Install and update.
Mibyan runs natively on Windows 10 and Windows 11 — no WSL, no Cygwin, no Docker. This page is the deep dive: what works natively, what’s WSL-only, what the installer actually does, and the Windows-specific knobs you might need to touch. If you just want to install, the one-liner on the landing page or Installation page is all you need. Come back here when something surprises you.
Want WSL instead?If you prefer a POSIX environment for fork semantics or Linux-style file watchers, see the Windows (WSL2) Guide. Both coexist cleanly: native data lives under %LOCALAPPDATA%\mibyan, WSL data lives under ~/.mibyan.

Quick install

Open PowerShell (or Windows Terminal) and run:
No admin rights required. The installer goes to %LOCALAPPDATA%\mibyan\ and adds mibyan to your User PATH — open a new terminal after it finishes. Installer options use a scriptblock:
Mibyan Desktop is installed from the Mibyan Desktop download, or launched from an existing Mibyan CLI with mibyan desktop. See Install and update.
The current script does not accept -NoVenv or -Tag. -SkipSetup is still accepted as a deprecated alias for -NonInteractive so older install wrappers keep binding. To diagnose an unexpected short Windows path, use -ShowResolvedPaths first.

MSIX / App Installer and Microsoft Store

The bundled desktop is separate from the source script. Its MSIX package requires Windows 11 22H2 or later. Windows 10 source-script support does not mean the MSIX package supports Windows 10. Open the downloaded .appinstaller file with Windows App Installer. It installs a signed universal bundle and records the update source. The package includes Python, Node, supported dependencies, and prebuilt interfaces. It does not clone a checkout or build the base runtime on first launch. The MSIX execution aliases expose mibyan, mibyan-agent, and mibyan-acp. If another installation shadows an alias, inspect Get-Command mibyan -All. Windows Settings → Apps → Advanced app settings → App execution aliases controls the aliases. Sideload updates use the app’s Update control and Windows App Installer. Mibyan downloads a local descriptor before teardown and registers automatic relaunch. It does not require the ms-appinstaller: URL protocol. An unknown update-check result is not a claim that the package is current. The Microsoft Store variant uses its Partner Center package identity and Store updates. It does not use the sideload feed. mibyan update inside either bundled runtime does not run Git against package files. Mibyan-Setup.exe is a different, bootstrap installer. It provisions a source checkout through the scripts. Do not confuse it with the self-contained MSIX package. See Updating & Uninstalling.

Dependency bootstrap

PM owns managed tools. Feature code asks PM for the package it needs (pm.ensure("<package>"), e.g. cua-driver for Computer Use) instead of re-running the installer. Already installed tools are reused from PM’s recorded state; a missing optional tool is fetched on demand only when security.allow_lazy_installs permits it. install.ps1 has no -Ensure mode.

What the source installer does

  1. Locate Git, or stage the verified Git for Windows pin when Git is absent.
  2. Clone the selected repository branch and apply an optional commit pin.
  3. Bootstrap uv and create the initial Python environment.
  4. Run PM to provision Python 3.14, required tools, and the all Python extra.
  5. Mint CLI launchers in the data home’s bin directory and add it to User PATH.
  6. Prepare configuration and invoke the interactive setup/gateway stages unless skipped.
  7. If requested, build the desktop and create Start Menu/Desktop shortcuts.
  8. Write the bootstrap-completion marker.
The runtime launcher executes PM’s store Python and selects the dependency environment before imports. PM can publish a new writable environment without replacing libraries already loaded by a running process. There is no tiered pip fallback to silently reduce the installed feature set.
Skip provider hunting on WindowsOn Windows, per-tool API key setup (Firecrawl, FAL, Browser Use, OpenAI TTS) is the highest-friction part of getting a useful agent. A Nous Portal subscription covers the model and all of those tools through one OAuth login. After the installer finishes, run mibyan setup --portal to wire everything up.

Feature matrix

Windows support is feature- and architecture-specific. The base interfaces run natively, but some optional SDKs are excluded from particular targets. The dashboard uses its pywinpty/ConPTY bridge on Windows and ptyprocess on POSIX. A missing or broken native dependency can make the terminal unavailable; WSL is an alternative, not a requirement of the current design.

Optional dependency limits

  • Matrix’s native encrypted adapter is Linux-only; use a supported proxy route or a Linux backend on Windows.
  • Native Windows ARM64 excludes the mem0 and google-chat SDK extras, and the openWakeWord engine. Sherpa supports native Windows ARM64 and is the automatic wake-word default on that target.
  • Local Faster-Whisper STT is excluded on native Windows ARM64. Use a cloud or command-based STT provider. Porcupine remains a wake-engine alternative.
The platform markers in pyproject.toml define the packaged dependency set. A general gateway or voice feature claim does not override those markers.

How Mibyan runs shell commands on Windows

Mibyan’s terminal tool runs commands through Git Bash, same strategy Claude Code uses. This sidesteps the POSIX-vs-Windows gap without rewriting every tool. pm.shell() owns Bash resolution. It first checks the Git package recorded in PM facts, then the provisioned PATH. If a PATH candidate belongs to a WindowsApps package, the resolver prefers a conventional Git for Windows installation when available. Packaged tools are not general-purpose host installations. An external Python process can fail to start a WindowsApps payload executable with WinError 5. Use the package’s own launcher, or use conventional tools for a source checkout. Do not disable Windows security controls to work around that boundary. The current installer does not set mibyan_GIT_BASH_PATH. MinGit is not a replacement for Git for Windows with Bash.

UTF-8 console on Windows

Python’s default stdio on Windows uses the console’s active code page (usually cp1252 or cp437). Mibyan’s banner, slash-command list, tool feed, Rich panels, and skill descriptions all contain Unicode. Without intervention, any of that crashes with UnicodeEncodeError: 'charmap' codec can't encode character…. The fix is in mibyan_cli/stdio.py::configure_windows_stdio(), called early in every entry point (cli.py::main, mibyan_cli/main.py::main, gateway/run.py::main). It:
  1. Flips the console code page to CP_UTF8 (65001) via kernel32.SetConsoleCP / SetConsoleOutputCP.
  2. Reconfigures sys.stdout / sys.stderr / sys.stdin to UTF-8 with errors='replace'.
  3. Sets PYTHONIOENCODING=utf-8 and PYTHONUTF8=1 (via setdefault, so explicit user values win) so child Python subprocesses inherit UTF-8.
  4. Sets EDITOR=notepad if neither EDITOR nor VISUAL is set (see the Editor section below).
Idempotent. No-op on non-Windows. Opt out: mibyan_DISABLE_WINDOWS_UTF8=1 in the environment falls back to the legacy cp1252 stdio path. Useful for bisecting an encoding bug; unlikely to be the right setting in normal operation.

The editor (Ctrl-X Ctrl-E, /edit)

Pre-#21561, pressing Ctrl-X Ctrl-E or typing /edit silently did nothing on Windows. prompt_toolkit has a hardcoded POSIX-absolute fallback list (/usr/bin/nano, /usr/bin/pico, /usr/bin/vi, …) that never resolves on Windows — even with full Git for Windows installed. Mibyan’s Windows stdio shim now sets EDITOR=notepad as a default. Notepad ships with every Windows install and works as a blocking editor — subprocess.call(["notepad", file]) blocks until the window closes. User overrides still win (they’re checked before the setdefault): The --wait flag on VS Code is critical — without it the editor returns immediately and Mibyan gets a blank buffer back. Set it permanently in your PowerShell profile:
Or as a User environment variable in System Settings so every new shell picks it up.

Ctrl+Enter for newline in the CLI

Windows Terminal passes Ctrl+Enter through as a dedicated key sequence. Mibyan binds it to “insert newline” so you can compose multi-line prompts in the CLI without falling back to Esc-then-Enter. Works in Windows Terminal, VS Code integrated terminal, and any modern Windows console host that honors VT escape sequences. On legacy cmd.exe consoles Ctrl+Enter collapses to plain Enter — use Esc Enter instead, or upgrade to Windows Terminal (it’s free and installed by default on Windows 11).

Running the gateway at Windows login

mibyan gateway install on Windows uses Scheduled Tasks with a Startup-folder fallback — no admin required.

Install

What happens under the hood:
  1. schtasks /Create /SC ONLOGON /RL LIMITED /TN Mibyan_Gateway — registers a task that runs at your login with standard (non-elevated) permissions. No UAC prompt.
  2. If schtasks is blocked by group policy, falls back to writing a small Mibyan_Gateway.vbs launcher (run hidden via wscript.exe) into %APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup. Same effect, slightly cruder. A VBScript is used rather than a cmd.exe shortcut because a console allocated at logon can receive a close event that kills the gateway before it finishes starting. Only one of the two is ever kept: a successful task install removes any Startup-folder entry (including a legacy Mibyan_Gateway.cmd), the fallback is skipped while a task is still registered, and mibyan update / mibyan doctor --fix clean up older installs that have both, since both would launch the gateway at logon.
  3. Spawns the gateway detached via pythonw.exe — not python.exe. pythonw.exe has no console attached, which immunizes it against CTRL_C_EVENT broadcasts from sibling processes (a real issue that used to kill the gateway when you Ctrl+C’d anything in the same process group).
Flags used when spawning: DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP | CREATE_NO_WINDOW | CREATE_BREAKAWAY_FROM_JOB.

Manage

mibyan gateway status is idempotent — call it a thousand times in a row and it will never accidentally kill the gateway. (Pre-PR #21561 it silently did, via os.kill(pid, 0) colliding with CTRL_C_EVENT at the C level — see “process management internals” below if you care about the story.) Login auto-start is only ever installed on an explicit answer: mibyan gateway install, a Y on a real terminal, or mibyan_GATEWAY_INSTALL_START_ON_LOGIN=1. A scripted or piped mibyan gateway start (no TTY, or mibyan_NONINTERACTIVE=1) starts the gateway without touching the Scheduled Task or the Startup folder; set mibyan_GATEWAY_INSTALL_START_ON_LOGIN=0 to skip the question on a terminal too.

Why not a Windows Service?

Services require admin rights to install and tie the gateway’s lifecycle to machine boot, not user login. The typical Mibyan user wants: log in → gateway available, log out → gateway gone. Scheduled Tasks do exactly that without elevation. If you genuinely want a service, use nssm or sc create manually — but you probably don’t. If you do, name it Mibyan* or point its binary path inside the Mibyan install (venv\Scripts\mibyan.exe, the checkout, or gateway-service\): mibyan update stops and restarts only services it can positively identify as Mibyan-owned through the Service Control Manager, and pauses a Scheduled-Task-launched gateway by PID (Task Scheduler itself is never touched).

Data layout

These are default paths. mibyan_HOME and installer path arguments can change them. A full deletion of %LOCALAPPDATA%\mibyan also deletes user data and can affect other installations that share it. Use the uninstall command or Windows package removal instead of deleting that root to repair an app.

Browser tool

Browser setup depends on the selected backend. PM supplies the pinned agent-browser and Chromium packages for the built-in backend. Browser Use has its own managed CLI installation through mibyan tools. A self-contained MSIX includes supported browser tools in its payload. On Windows ARM64, the pinned Chromium and agent-browser binaries can use Windows’ x64 emulation. This differs from the native ARM64 Python runtime. See Browser automation for backend selection.

Running Mibyan on Windows — practical notes

PATH after install

The installer adds %LOCALAPPDATA%\mibyan\bin to your User PATH via [Environment]::SetEnvironmentVariable. Existing terminals don’t pick this up — open a new PowerShell window (or Windows Terminal tab) after installation. Close-and-reopen, don’t $env:PATH += … by hand unless you know what you’re doing. Verify:

Environment variables

Mibyan honors both $env:X (process-scope) and User environment variables (permanent, set in System Properties → Environment Variables). Setting API keys in %LOCALAPPDATA%\mibyan\.env (your mibyan_HOME) is the normal path — same as Linux:
Don’t put secrets in User environment variables unless you specifically want every Windows process to see them (it isn’t what you want).

Windows-specific env vars

These only affect native Windows installs:

Uninstall

From PowerShell:
For source installs, the uninstaller removes owned launchers, service entries, and application files. Review mibyan uninstall --dry-run before removal. --full also removes data; --data removes data without removing packaged code. For MSIX or Store installations, remove the app through Windows Settings → Apps → Installed apps. The CLI refuses to delete package-owned code.
User-data deletionBefore deleting data, stop every Mibyan process that uses the selected mibyan_HOME and make a backup. Review mibyan uninstall --dry-run before choosing a data-removal mode. Do not recursively delete the default data root to repair one application or profile. A custom mibyan_HOME can be elsewhere, and package removal does not remove that data.
The mibyan uninstall CLI subcommand also handles the case where the schtasks entry was registered under a different task name (older installs) — it searches by install path rather than by hardcoded task name.

Process management internals

This is background material — skip unless you’re debugging an “it’s killing itself” weirdness. On Linux and macOS, the POSIX idiom os.kill(pid, 0) is a no-op permission check: “is this PID alive and can I signal it?” On Windows, Python’s os.kill maps sig=0 to CTRL_C_EVENT — they collide at integer value 0 — and routes it through GenerateConsoleCtrlEvent(0, pid), which broadcasts Ctrl+C to the entire console process group containing the target PID. That’s bpo-14484, open since 2012. It won’t be fixed because changing it would break scripts that depend on the current behavior. Consequence: any codepath that said “check if this PID is alive” via os.kill(pid, 0) on Windows was silently killing the target. Mibyan migrated every such site (14 across 11 files) to gateway.status._pid_exists(), which uses psutil.pid_exists() (which in turn uses OpenProcess + GetExitCodeProcess on Windows — no signals). If you’re writing a plugin or patch, use psutil.pid_exists() directly or gateway.status._pid_exists() — never os.kill(pid, 0). scripts/check-windows-footguns.py enforces this in CI: any new os.kill(pid, 0) call fails the Windows footguns (blocking) check unless the line carries a # windows-footgun: ok — <reason> marker.

Common pitfalls

mibyan: command not found right after install. Open a new PowerShell window. The installer added %LOCALAPPDATA%\mibyan\bin to User PATH, but existing shells need to be restarted to pick it up. In the meantime you can run & "$env:LOCALAPPDATA\mibyan\bin\mibyan.exe". WinError 193: %1 is not a valid Win32 application when running a tool. You hit a shebang-script invocation that bypassed the .cmd shim. Mibyan resolves commands through shutil.which(cmd, path=local_bin) so PATHEXT picks up .CMD — if you’re invoking the tool via a hardcoded path instead, switch to the .cmd variant (e.g., npx.cmd, not npx). [scriptblock]::Create(...) fails with The assignment expression is not valid. Your download of install.ps1 picked up a UTF-8 BOM. The irm | iex form strips BOMs automatically; [scriptblock]::Create((irm ...)) does not. Re-run with the simple irm | iex form, or download the script manually and save it without a BOM via [IO.File]::WriteAllText($path, $text, (New-Object Text.UTF8Encoding $false)). Gateway won’t stay running after restart. Check mibyan gateway status — it merges the schtasks entry, the Startup-folder shortcut (if used), and the live PID. If schtasks is registered but not running, group policy may be blocking ONLOGON triggers. Run schtasks /Query /TN Mibyan_Gateway /V /FO LIST (Mibyan_Gateway_<profile> for a named profile) to see the task’s failure reason. The Startup-folder fallback engages automatically only when schtasks itself fails to register the task; there is no environment variable or flag to force it. /edit still does nothing after setting $env:EDITOR. You set it in the current process only; close and reopen the shell, or set it at User scope in System Properties → Environment Variables. Verify with echo $env:EDITOR in a new PowerShell window. Browser tool launches but tools time out. Run mibyan doctor and mibyan pm doctor. Use mibyan tools to inspect the selected browser backend. Do not install an unrelated Playwright revision into a signed app payload. agent-browser reports a Node version error. Run mibyan pm doctor and inspect which Mibyan launcher started the process. PM supplies the managed Node version. Do not delete an unrelated system Node installation to repair Mibyan. Chinese / Japanese / Arabic characters show as ? in the CLI. The UTF-8 stdio shim didn’t activate. Check that mibyan_DISABLE_WINDOWS_UTF8 is NOT set (Get-ChildItem env:mibyan_DISABLE_WINDOWS_UTF8). If it’s empty and you still see ?, the console host (very old cmd.exe) may not support UTF-8 at all — switch to Windows Terminal. Gateway can’t send Telegram photos — “BadRequest: payload contains invalid characters”. This is unrelated to Windows but sometimes surfaces first there. Usually it means your file path contains unescaped backslashes in a JSON body. Telegram should be receiving paths Mibyan normalizes, not raw Windows paths — if you’re seeing this inside a custom plugin, make sure you’re passing the Mibyan-provided path, not str(Path(...)) from user input. “Works on my other machine” encoding weirdness after git pull. If you edited Mibyan config or a skill on Windows using a non-UTF-8 editor (Notepad on older Windows versions, some Chinese IMEs), the file may have been saved with a BOM. Mibyan tolerates utf-8-sig on most config reads, but a BOM inside a folded YAML scalar (description: >) silently breaks YAML parsing. Re-save the file as plain UTF-8 without BOM.

Where to go next