Skip to main content

Visor

Cross-platform Quest developer toolkit — an open source alternative to Meta Quest Developer Hub (MQDH) that runs on Linux, macOS, and Windows (MQDH is Windows/Mac only, so Linux users had nothing), plus something MQDH doesn't have on any platform: an MCP server that lets AI coding agents — Claude Code and any other MCP-compatible client — see and control your headset.

Four layers, one library:

Layer Command What it does
Python library import visor.adb Quest-aware ADB wrapper: devices, apps, capture, logs, performance
MCP server visor-mcp 29 quest_* tools for any MCP client — screenshots the model can see, crash logs, perf monitoring
CLI visor MQDH-like functionality from the terminal
Web dashboard visor ui Live instrument panel: perf charts, viewport, logs, app/file management

Requirements

  • Python 3.10+ on Linux, macOS, or Windows
  • adb on your PATH:
    • Linux: sudo apt install android-sdk-platform-tools (or sudo pacman -S android-tools)
    • macOS: brew install android-platform-tools
    • Windows: winget install --id Google.PlatformTools (or download platform-tools)
  • A Quest with developer mode enabled, connected via USB (accept the debugging prompt in the headset) or wireless ADB
  • Optional: ffmpeg for the dashboard's live video view, scrcpy for casting (both available via the same package managers)

Install

pip install visor-dev    # provides the `visor` command; from source:
git clone https://github.com/chisomobanzi/visor && cd visor && pip install .

CLI quickstart

visor devices                     # list connected headsets
visor info                        # battery, storage, firmware, thermal
visor connect-wireless            # unplug the cable, stay connected

visor install ./my-game.apk       # sideload a build
visor launch com.my.game
visor apps                        # sideloaded apps

visor screenshot                  # auto-wakes a sleeping headset
visor record 30                   # 30s video
visor cast                        # scrcpy casting

visor logs --tag Unity --level D  # filtered logcat
visor logs --grep NullReference -f  # follow live
visor crash-logs com.my.game      # parsed crash/ANR reports

visor perf                        # CPU/memory/thermal/battery snapshot
visor perf --monitor 30           # timeseries
visor thermal                     # per-sensor temps with throttle warnings

# Profiling (see "Performance profiling" below)
visor perf record -t 60           # record a session while you play
visor perf report session.json    # summary + bottleneck diagnosis
visor perf diff before.json after.json
visor bench com.my.game           # cold-start benchmark
visor trace -t 10                 # perfetto trace -> ui.perfetto.dev

visor push ./file /sdcard/  ·  visor pull /sdcard/f ./  ·  visor ls /sdcard/

Multiple devices? Add --device <serial>.

AI assistant integration (MCP)

visor-mcp is a standard Model Context Protocol server over stdio, so it works with any MCP-compatible client — Claude Code, OpenAI's Codex CLI, Cline, Continue, Cursor, and agent frameworks built on the MCP SDKs (including ones driving open-source models). It's primarily developed and tested against Claude Code, but nothing in it is Claude-specific: it exposes plain MCP tools and standard content blocks.

The server is a single command, visor-mcp, that speaks MCP over stdio and takes no arguments — register it however your client expects.

Claude Code:

claude mcp add quest -- visor-mcp

Most other clients (Cursor, Cline, Continue, Claude Desktop, …) use a JSON config:

{
  "mcpServers": {
    "quest": {
      "command": "visor-mcp"
    }
  }
}

Codex and some others use their own config file, but the essentials are the same everywhere: run visor-mcp, no args, stdio transport.

Then ask your assistant things like:

  • "Take a screenshot of my headset — what's on screen?" — clients that support image tool results (like Claude Code) display the actual image; text-only clients still get every other tool
  • "Install this build, launch it, and watch the logs for exceptions while I test"
  • "Why did my app crash? Pull the crash log and explain the stack trace"
  • "Monitor performance for 60 seconds while I play, then tell me if I'm thermal throttling"

Tools exposed: quest_devices, quest_info, quest_screenshot, quest_install, quest_uninstall, quest_launch, quest_stop, quest_app_list, quest_app_info, quest_app_memory, quest_clear_data, quest_logs, quest_logs_stream, quest_crash_logs, quest_performance, quest_monitor, quest_thermal, quest_frame_timing, quest_perf_session, quest_perf_diff, quest_launch_benchmark, quest_trace, quest_screen_record, quest_push, quest_pull, quest_files, quest_connect_wireless, quest_set_refresh_rate, quest_tracking.

Web dashboard

visor ui        # opens http://127.0.0.1:7700

Overview (battery/thermal lens gauges, tracking status), viewport with real-time live video (H.264 off the device via screenrecord, transcoded to an MJPEG stream — requires ffmpeg), performance charts sampled every 2.5s, filterable log viewer with crash reports, app management (install APK by upload, launch/stop/clear/uninstall), and a device file browser. Localhost-only by design.

Library

from visor import adb

quest = adb.discover_devices()[0]
adb.install_apk("build.apk", quest.serial)
adb.launch_app("com.my.game", quest.serial)
for entry in adb.logcat_stream(quest.serial, level="E"):
    print(entry.tag, entry.message)

All functions raise typed errors (DeviceUnauthorizedError, DeviceNotFoundError, …) with actionable messages instead of raw ADB stderr.

Performance profiling

Visor is a full VR profiler built on the per-second VrApi metrics the Quest runtime logs for any rendering VR app: FPS vs target, stale frames, CPU/GPU dynamic levels + clocks + utilization (including worst core), app GPU time vs frame budget, and free memory — plus periodic memory anatomy (dumpsys meminfo, where graphics allocations dominate) and thermal snapshots.

Sessions are the core primitive: record one while you play (visor perf record, the dashboard's ● RECORD, or the quest_perf_session MCP tool), get a summary and an evidence-based bottleneck diagnosis — GPU-bound, CPU-bound (single-thread vs parallel), thermal throttling (including silent clock clamping), memory pressure (lmkd kills), hitching (bursts with headroom), or memory growth — each with concrete recommendations. Sessions are JSON files; diff two of them to verify an optimization (visor perf diff / quest_perf_diff).

The dashboard's Performance tab is a live workspace: FPS chart with target line and stale-frame dots, app GPU time vs budget, utilization, clock levels, memory series, skin temperature with throttle threshold, and event annotations (level changes, thermal transitions, lmkd kills).

For the "what exactly blocked this frame" tier: visor trace captures a perfetto system trace (scheduling/clocks/graphics; open at ui.perfetto.dev), and visor bench measures cold-start times.

Notes: VR frame metrics only flow while the app is rendering — a sleeping display pauses everything (visor auto-wakes it), and 2D panel apps fall back to gfxinfo. Battery current draw isn't readable on OS v14+, so drain is inferred from level over longer sessions.

Notes on Quest OS v14+

  • /sys/class/thermal and battery current_now are permission-denied over ADB; visor reads thermals from dumpsys thermalservice instead (45 sensors on Quest 3).
  • Screenshots of a sleeping headset return nothing; visor auto-wakes the display via the prox_close broadcast and restores the proximity sensor afterwards.
  • Screenshots are side-by-side stereo; the MCP/UI return the left eye for readability (full stereo PNG is kept on disk).

Development

python -m venv .venv && .venv/bin/pip install -e ".[dev]"
.venv/bin/pytest

Tests use captured real-device output as fixtures — no headset needed.

License

MIT

Metadata

Release files for visor-dev 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for visor-dev 0.1.0
File Size Uploaded Provenance Actions
visor_dev-0.1.0.tar.gz 90.4 kB With provenance Details for visor_dev-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for visor-dev 0.1.0
File Interpreter ABI Platform Actions
visor_dev-0.1.0-py3-none-any.whl Python 3 none any Details for visor_dev-0.1.0-py3-none-any.whl

Total release size: 166.7 kB

Release files / visor_dev-0.1.0.tar.gz

Download URL visor_dev-0.1.0.tar.gz
Size 90.4 kB
Tags Source
SHA-256 checksum
How to use checksums
ece306bb23377fb98385d4953ccde4ffdbe931b5f1478b07f7caf2403834d987
BLAKE2b-256 checksum
How to use checksums
f2c184ad4f2f85bb36a5fb2457e9265a4c88116871ceab7ea77ba96f4b97952d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 12, 2026.

Transparency log

Release files / visor_dev-0.1.0-py3-none-any.whl

Download URL visor_dev-0.1.0-py3-none-any.whl
Size 76.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
88d1ed0d386fe9c8b1c2a6bec57b616cba3c4669f6d11087cc000dc37c5da991
BLAKE2b-256 checksum
How to use checksums
f957d6eb8c27ae0f8d69864bd59781a733796c12a7aa17e84724caf393dcf214
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 12, 2026.

Transparency log

Security for visor-dev 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for visor_dev-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 12, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page