On 6 November 2026 Scott Hanselman shipped sandbox-mcp, an MIT-licensed CLI and MCP server that boots a disposable Windows 11 guest inside Windows Sandbox, deploys an app, drives it with native UI Automation, and throws the guest away. The README lists measured GUI samples in the 40–50 second range end-to-end. A portable ZIP with bundled Node means no host Node install is required. Requirements are Windows 11 Pro/Enterprise/Education 24H2+.
The pitch is clean: “Give your AI agent a brand-new Windows PC. Then throw it away.” For anyone shipping desktop tooling or testing agent-driven UI flows, that removes the “works on my machine” class of failures without leaving residual state or requiring a full VM farm.
Desktop agents that also need to listen to real calls, interviews, or system audio still run into a different wall. The sandbox isolates the guest process tree; the host audio engine and the capture path that feeds real-time STT do not move with it.
Why the capture path stays on the host
Windows Sandbox gives the guest its own desktop, its own process space, and its own audio endpoints. An agent running inside the sandbox sees a clean machine. An overlay or STT pipeline that must capture both the user’s microphone and the remote side of a Zoom/Teams/Meet call without injecting a bot still needs the host’s WASAPI loopback and the host’s default capture device.
The practical dual-track stack on the host looks like this:
- Capture device (mic) → shared or exclusive WASAPI input client.
- Render endpoint (speakers/headphones) → WASAPI loopback (input stream opened on a render device).
- Two independent lock-free rings (SPSC, power-of-two) so the audio callback never allocates or waits.
- Consumer thread that resamples to the STT native rate (usually 16 kHz mono int16), runs a lightweight VAD, and feeds separate streaming sessions.
- Optional cross-track gating so the mic does not re-transcribe the speakers.
Shared-mode periods on modern hardware are typically 10 ms. With IAudioClient3 you can request the engine’s minimum period (often 5 ms or lower on capable drivers). Exclusive mode drops the engine mixing and APO chain but takes exclusive ownership of the endpoint and kills system sounds.
Add the fixed costs:
| Stage | Typical cost |
|---|---|
| WASAPI shared period | 10 ms (or 5–8 ms if requested) |
| Callback → ring copy + format convert | 1–3 ms |
| Resample + VAD | 2–5 ms |
| Network RTT + model first partial | 35–100 ms depending on provider |
| Overlay paint | <16 ms |
A model that advertises 45 ms time-to-final still produces 80–150 ms end-to-end partials once the Windows path is included. Bluetooth headsets, communications enhancements, or a busy audio engine push the number higher. The sandbox does not change any of those numbers because the capture client never runs inside it.
Minimal loopback capture sketch
Using cpal (which activates WASAPI loopback when you open an input stream on a render endpoint) the essential shape is:
let device = find_output_device(name)?;
let default_cfg = device.default_output_config()?;
let config = StreamConfig {
channels: default_cfg.channels(),
sample_rate: default_cfg.sample_rate(),
buffer_size: BufferSize::Default, // or Fixed for tighter periods
};
// build_input_stream on the render device → loopback
let stream = device.build_input_stream(
&config,
move |data: &[f32], _: &InputCallbackInfo| {
// push to SPSC ring; never allocate, never block
ring.push_slice(data);
},
|err| eprintln!("stream error: {}", err),
None,
)?;
stream.play()?;
The same pattern works for the microphone on a capture device. Timestamp both rings from a shared monotonic clock so later alignment of the two transcripts is possible. Resample once, early, to the rate the STT session expects. Keep the audio callback under a few hundred microseconds; any heavier work (VAD, network send, UI update) lives on the consumer side.
If you drop to the wasapi crate directly you gain IAudioClient3 period control and process-loopback (ApplicationLoopback) for capturing a specific process tree. Process-loopback is useful when you want only the call app and not the rest of the desktop mix; it still runs on the host and still pays the engine’s period.
Tradeoffs that actually matter
- Shared mode + small period: lowest practical latency while keeping system audio and other apps alive. Fragile if a driver or APO stalls.
- Exclusive mode: tighter, but you lose mixing and many headsets refuse it or glitch.
- Process-loopback vs full loopback: process-loopback avoids capturing your own TTS or notification sounds; full loopback is simpler and works for any call app.
- Local model vs remote STT: local (Qwen3 ASR class) removes the network RTT but still sits behind the same capture budget. The Windows path is the floor either way.
- Sandbox for UI testing vs host capture for live audio: they solve orthogonal problems. You can have an agent that tests the installer inside a sandbox and a separate host pipeline that feeds the live call transcript.
The sandbox-mcp model is excellent for “does this desktop app still start and accept input after a clean install?” It does not move the real-time audio path. Any tool that must show translated captions or agent text while the other party is still speaking has to own the host WASAPI clients, the ring buffers, and the latency budget.
That is the part that still determines whether the overlay is useful or just late.
I'm building Talkaside, a Windows app for job interviews and calls in another language.
Drafted with AI assistance from this project's code and logs.

Top comments (0)