Devbox MCP exposes a ChatGPT-compatible MCP server for controlled file, shell, Git, Docker, and host-tool operations.
It supports two runtime modes:
- Docker mode: the original reproducible Windows + Docker Desktop workflow.
- Host mode: direct execution on Termux, Linux, and macOS without Docker.
auto selects Docker on Windows and host mode on Termux/Linux/macOS.
For a minimal server, download devbox-core-TARGET from the release assets.
It contains one C++23 executable with native start/stop/supervision, verified
promotion and rollback commands. Normal operation needs no Node/npm/Git, compiler,
browser or desktop stack. Follow the core installation guide
for signed initialization and optional OS startup integration.
The full bundle remains available and ships three native programs from the same source revision:
devbox-tui— the guided C++17 interactive setup experience for new users.devbox-setup— the C++ CLI used by the TUI and intended for scripts, CI, and unattended installation.devbox-mcp— the C++23 MCP service and native management CLI, including process control, durable jobs, files, authentication, and capture.
The TUI retains the source-checkout installation workflow, including Node/npm/Git,
for existing development and legacy installations. The CLI defaults to native
management for new installations; --repo explicitly selects the source-checkout
workflow. Packaged installation needs no Rust or C++ compiler. Existing checkouts
and production services are not migrated by extracting a new bundle.
Prebuilt release binaries are produced for:
- Windows x86-64
- Linux x86-64 and ARM64
- Alpine/musl Linux x86-64
- macOS x86-64 and Apple Silicon
- Android/Termux arm64-v8a, armeabi-v7a, x86-64, and x86
curl --fail --location --output install-devbox.sh \
https://raw.githubusercontent.com/adybag14-cyber/devbox/main/scripts/install-devbox.sh
sh install-devbox.shThe script detects the OS, architecture, and Linux libc, downloads all three native binaries, verifies them against SHA256SUMS, and starts the TUI when a terminal is interactive. Pass CLI options to the script for automation.
Extract devbox-windows-x86_64.zip and keep these files together:
devbox-tui.exe
devbox-setup.exe
devbox-mcp.exe
The TUI and installer also recognize matching platform-named standalone assets. For direct CLI setup, launch:
.\devbox-setup.exe --native-root C:\Devbox `
--receipt .\qualification-receipt.json --provenance .\provenance.sigstore.json `
--source RELEASE_COMMIT_SHA --target windows-x86_64The release workflow tests the three binaries together and verifies each extracted archive. PowerShell 7 is preferred by the Windows runtime while Windows PowerShell 5.1 remains an automatic launch fallback.
Configure an existing checkout:
devbox-setup --repo . --guardianFor a new native installation, supply the matching release qualification files:
devbox-setup --native-root /absolute/path/devbox \
--receipt qualification-receipt.json --provenance provenance.sigstore.json \
--source RELEASE_COMMIT_SHA --target linux-x86_64Useful options:
--runtime auto|host|docker
--host 127.0.0.1
--port 8100
--workspace /path/to/workspace
--auth none|oauth|cloudflare
--public-base-url https://mcp.example.com
--cloudflare-team-domain https://team.cloudflareaccess.com
--cloudflare-aud <audience>
--cloudflare-jwks-url https://team.cloudflareaccess.com/cdn-cgi/access/certs
--guardian
--no-start
--no-link
--skip-system-packages
--skip-install
--dry-run
Version 0.5 can install missing runtime prerequisites using winget on Windows, Homebrew on macOS, pkg on Termux, and common Linux package managers (apt-get, dnf, yum, pacman, zypper, or apk). Existing .env files are preserved; only selected keys are updated.
Install the signed canonical Termux app from:
Then run inside Termux:
pkg install -y curl ca-certificates
curl --fail --location --output install-devbox.sh \
https://raw.githubusercontent.com/adybag14-cyber/devbox/main/scripts/install-termux.sh
sh install-devbox.shThe Termux installer downloads and SHA-256 verifies the C++ server, CLI, and TUI for the detected Android ABI. Interactive terminals enter the TUI; scripted invocations use the CLI directly.
Full Android instructions: docs/TERMUX.md
git clone https://github.com/microsoft/vcpkg.git .cpp-build/vcpkg
git -C .cpp-build/vcpkg checkout --detach 04a9d8e5212d01ee1dd9478eadd9caade4f8b0d4
sh .cpp-build/vcpkg/bootstrap-vcpkg.sh -disableMetrics
cmake -S . -B .cpp-build/native -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_TOOLCHAIN_FILE="$PWD/.cpp-build/vcpkg/scripts/buildsystems/vcpkg.cmake"
cmake --build .cpp-build/native --config Release --parallel 4
ctest --test-dir .cpp-build/native -C Release --output-on-failure
cmake --install .cpp-build/native --config Release --prefix .cpp-build/packageSee cpp-bootstrap/README.md for Windows and musl build details, and setup-tui/README.md for the frontend.
cpp-bootstrap/: cross-platform C++ setup CLI and testssetup-tui/: dependency-light C++17 interactive setup frontendbin/devbox.js: installabledevboxcommandcpp-mcp/: C++ MCP service, durable jobs, atomic checkpoints and native process controlbootstrap/andrust-mcp/: retained Rust reference sources; SDK regression scripts also validate the C++ binarysrc/server.js: retained legacy JavaScript compatibility implementationsrc/runtime.js: runtime selector for Docker versus host modesrc/docker-runtime.js: Docker-backed runtimesrc/host-runtime.js: host-backed runtime for Termux/Linux/macOSsrc/host-tools.js: host shell and allowed-program execution helperssrc/launcher.js: background service launcherruntime.Dockerfile: reproducible Linux runtime image for Docker modescripts/Start-ChatGptDevboxMcp.ps1: Windows/Docker startup flowscripts/Stop-ChatGptDevboxMcp.ps1: Windows/Docker shutdown flow
See runtime dependency profiles for the distinction between the native core bundle, native supervision, optional tools and the retained source-checkout workflow.
The setup binaries can provision common prerequisites automatically where a supported package manager is available. You can opt out with --skip-system-packages.
- A matching native release, supported OS/ABI, writable private state and TLS trust
- GitHub CLI only during signed installation/promotion verification
- No Node/npm/Git, compiler, browser or display packages for normal core operation
- Node.js 18 or newer for the launcher and Guardian; Node.js 24 is the certified/tested supervisor profile
- A matching native C++ release bundle, or CMake 3.24+, a C++23 compiler and the pinned vcpkg checkout for source builds
- npm
- Git for checkout and build provenance
- Android API 21+ through the canonical Termux app
- Windows, Termux, Linux, or macOS
- optional but useful:
gh,python3,ripgrep, andcurl
- Docker Desktop or a compatible Docker engine
- PowerShell 7 is preferred for Windows automation; Windows PowerShell 5.1 remains a compatibility fallback
- optional: GitHub CLI, Cloudflare Tunnel, and Cloudflare Access
git clone https://github.com/adybag14-cyber/devbox.git
cd devbox
cp .env.example .env
npm install
npm link
node bin/devbox.js startOn Windows PowerShell, copy the environment file with:
Copy-Item .env.example .envThe repository automatically loads <repo>/.env. Existing process environment variables take priority.
Host mode is the default on Termux, Linux, and macOS.
DEVBOX_RUNTIME_MODE=host devboxBehavior:
- file and shell operations run directly on the host
devbox_run_programis the preferred fast path for a single executable with structured arguments; it avoids shell startup and quoting overheaddevbox_exec_readonlyis best-effort and is not container-sandboxed; use it when shell syntax such as pipelines, variables, or redirection is actually needed- host-mode
devbox_search_filesprefers ripgrep when available and retains a native C++ walker with RE2 as a fallback; normal searches respect ignore files for speed, whileinclude_ignored=trueopts into exhaustive hidden/ignored content - synchronous process tools share a bounded execution pool; detached jobs cannot consume the reserved interactive slot, while
/healthz, status, file I/O, and Guardian remain outside the process queue; recursive scans/copies/archives/package installs are classified separately asio-heavyso storage pressure cannot masquerade as light interactive work - generic host tools are exposed through
host_* - legacy
windows_host_*names remain compatibility aliases host_capture_displaycaptures the native desktop;host_capture_windowcaptures the largest visible window for a PID or its child processes- Windows window capture detects black
PrintWindowresults and falls back to compositor-visible pixels; macOS uses CoreGraphics +screencapture; Linux window capture uses X11, while full-display capture can use Wayland'sgrim
Termux and Android instructions: docs/TERMUX.md
Canonical Termux app: https://github.com/adybag14-cyber/termux-app
Linux/macOS details: docs/HOST_COMPATIBILITY.md
Docker mode is the default on Windows and can be selected elsewhere:
DEVBOX_RUNTIME_MODE=docker devboxBehavior:
- Devbox shell and file tools run in the Docker runtime container
- read-only shell commands use disposable read-only containers
- host tools remain explicit and separate from the container runtime
Windows users can also use:
.\scripts\Start-ChatGptDevboxMcp.ps1The C++ service exposes 50 tools: the 37 compatible legacy tools, eight native agent APIs for durable submissions, job/task discovery, revisioned checkpoints, atomic files and capability inspection, two native Windows computer-use tools, and three native public-web research tools. Research targets 100 source documents in Standard mode or 50 in Fast mode, with explicit partial coverage and citation evidence. See the native agent runtime contract. Guardian supervises the selected native service. Ordinary Devbox shell commands honor HOST_SHELL and inherit the service token, while explicit host_exec retains the administrative PowerShell policy.
Important .env values:
DEVBOX_RUNTIME_MODE=auto|host|dockerHOSTandPORTHOST_WORKSPACE_PATHHOST_DEFAULT_WORKDIRPOWERSHELL_EXE(optional Windows primary override; defaults to installed PowerShell 7)POWERSHELL_FALLBACK_EXE(optional Windows fallback override; defaults to Windows PowerShell 5.1)HOST_SHELLHOST_PROGRAM_ALLOWLISTadds entries to the canonical host defaults; useHOST_PROGRAM_ALLOWLIST_EXTRAfor explicit local additions, and setHOST_PROGRAM_ALLOWLIST_REPLACE=trueonly when intentionally replacing the canonical defaults- Migration note: older deployments treated
HOST_PROGRAM_ALLOWLISTas a full replacement. If you intentionally narrowed the defaults, setHOST_PROGRAM_ALLOWLIST_REPLACE=true; otherwise the configured entries are now merged with the canonical safe defaults.
- Migration note: older deployments treated
DEVBOX_PROGRAM_ALLOWLISTcontrols the structureddevbox_run_programfast path; in host mode the executable must also be allowed byHOST_PROGRAM_ALLOWLISTHOST_SEARCH_BACKEND=auto|rg|jsselects host search acceleration;autoprefers ripgrepMCP_EXEC_MAX_CONCURRENT,MCP_EXEC_RESERVED_INTERACTIVE,MCP_EXEC_QUEUE_TIMEOUT_MS, andMCP_BACKGROUND_QUEUE_TIMEOUT_MStune the shared execution poolMCP_WATCH_MAX_CONCURRENTgives passive watchers such asgh run watcha separate pool;MCP_EXEC_HEAVY_WEIGHT/MCP_EXEC_HEAVY_CAPACITY(defaults2/4) control CPU-heavy build/browser work, whileMCP_EXEC_IO_HEAVY_WEIGHT/MCP_EXEC_IO_HEAVY_CAPACITY(defaults2/2) serialize recursive scans, large copies/archives, package installs, and similar storage-intensive workMCP_BACKGROUND_PRIORITY_AGE_MS(default30000) prevents sustained interactive traffic from starving background jobs indefinitely; normal interactive priority remains in effect before the aging thresholdMCP_JOB_LOG_MAX_BYTESandMCP_JOB_LOG_ROTATIONSbound detached-job stdout/stderr on disk;MCP_JOB_HEARTBEAT_MSandMCP_JOB_ORPHAN_STALE_MScontrol orphan detection;MCP_JOB_RETENTION_HOURSbounds persisted terminal-job history;MCP_JOB_STORE_MAX_BYTESandMCP_JOB_STORE_MAX_TERMINAL_JOBSapply global pressure limits that evict the oldest terminal jobs toward a low-water mark without deleting active jobs- incremental job maintenance reports cycle number, cursor, total jobs, progress percent, and cycle age; quota accounting remains independent so a large retained history does not require a full rescan every minute
MCP_WAIT_MAX_SECONDSbounds no-process waits; preferdevbox_wait,devbox_wait_for_file, ordevbox_job_status(wait_seconds=...)over shellsleep/Start-SleepSCREEN_CAPTURE_ATTEMPT_TIMEOUT_MS,SCREEN_CAPTURE_RETRIES, andSCREEN_CAPTURE_QUEUE_TIMEOUT_MScontrol serialized fail-fast screenshot captureGUARDIAN_HOST_PRESSURE_SAMPLE_MScontrols diagnostic Windows CPU/memory/commit/pagefile sampling; it does not trigger repair by itselfDEVBOX_VERSION_CACHE_MScontrols the toolchain-version cache; a supervised background loop refreshes it sodevbox_statusremains subprocess-free while normally returning fresh versionsdevbox_statusexposes cached scheduler/store health plusexecutionStore.diskPressure, a robust multi-sample free-space trend (freeBytesTrendPerHour, sample count, and window), andoperationalWarnings; low disk percentage warns before the hard readiness floor. Warning/critical pressure serializes weighted work, and critical pressure rejects new mutating heavy/I/O-heavy work while leaving read-only inspection and cleanup availablenpm run repo:freshnesscomparesHEAD, cachedorigin/main, and the actual remote head so a stale remote-tracking ref cannot masquerade as a current checkoutPUBLIC_BASE_URLfor public OAuth deploymentsENABLE_GATEWAY_BRIDGE=true|falseGATEWAY_BRIDGE_ORIGINS=https://chatgpt.com,https://chat.openai.comMAX_MCP_TRANSFER_CHARS,MAX_TEXT_OUTPUT_CHARS, andMCP_JSON_BODY_LIMITaccept numeric limits orunlimitedMAX_COMMAND_OUTPUT_CHARSdefaults to65536and is a non-bypassable per-stream safety ceiling for command results; use the large-file tools for larger transfersDOCKER_COMMAND_TIMEOUT_MScontrols bounded Docker subprocess execution
Do not commit .env, run/, workspace/, or live credentials.
devbox status
devbox restart
devbox stop
devbox runPlain devbox behaves like devbox start. devbox run keeps the server in the foreground.
Runtime telemetry is appended to run/tool-usage.jsonl and run/http-usage.jsonl. Log size is tracked in memory after the first stat so normal tool calls do not perform an extra filesystem metadata lookup per telemetry event. Tool telemetry also records execution-slot queue wait where applicable. Summarize it with npm run usage:summary, or run the live reliability probe with npm run soak:live.
Guardian v2 monitors the MCP process, local and public health endpoints, the selected runtime, and the optional tunnel without making host mode depend on Docker. Windows uses elevated scheduled tasks, Linux uses a systemd user service when available, macOS uses a per-user launchd LaunchAgent, and Termux uses Termux:Boot; all platforms run the same Node supervisor.
# Windows host mode: Docker is not probed or required
.\scripts\Install-ChatGptDevboxGuardian.ps1 -Runtime host -Public -OAuth# Linux systemd user service or Termux:Boot
./scripts/install-guardian.sh autoDocker mode includes stale-container start/replace repair plus exponential backoff and a persistent circuit breaker after repeated Docker Desktop failures. On Windows, the boot-critical AtStartup task launches the portable Node Guardian directly at Highest/S4U; logon and the 10-minute KeepAlive task retain the independent PowerShell Ensure recovery path. Windows/host startup also has single-owner lifecycle locking, a bounded startup deadline, immediate MCP PID ownership, cleanup-on-failure, and a machine-readable run/startup-state.json phase journal that Guardian uses to avoid racing an in-progress start. See docs/GUARDIAN.md for readiness fields, status commands, and service-manager setup.
After startup, inspect the root endpoint:
curl http://127.0.0.1:8100/Typical local connector settings:
- Name:
Devbox MCP - MCP Server URL:
http://127.0.0.1:8100/mcp - Authentication: server modes are
none,demo-oauth, orcloudflare-access; the setup TUI/CLI presents these asnone,oauth, andcloudflare.
Authentication and transport are separate. Selecting oauth or cloudflare configures MCP authentication and requires a public HTTPS base URL; it does not require Cloudflare Tunnel specifically. cloudflared is shown as an optional setup preflight tool when you want Cloudflare Tunnel transport. For platform-specific installation, persistence, and troubleshooting on Windows, Linux, macOS, and Termux, see Cloudflare Tunnel setup or run devbox-tui --cloudflare-help.
For commands likely to exceed the connector request lifetime, use the persistent async job tools instead of holding one MCP request open:
- Synchronous shell tools are intentionally capped at 90 seconds because upstream MCP/connector requests can be aborted around the two-minute mark. Do not use a long synchronous timeout for builds, exports, sleeps, or soak tests.
devbox_run_programshould be preferred for one executable such asgit,gh,node,python, orrg; it bypasses the shell. Long direct programs should usedevbox_run_program_start.devbox_exec_startstarts a detached shell job and returns a job ID immediately; useresource_class=watch|light|heavy|io-heavywhen auto-detection is not appropriate.- Passive watchers use their own bounded pool; CPU-heavy and I/O-heavy jobs consume weighted capacity. Under disk pressure, weighted and light interactive work use separate FIFO lanes and light work is kept outside the weighted slot corridor, avoiding head-of-line stalls while preserving per-class FIFO ordering.
devbox_job_status(wait_seconds=...)long-polls using a Node timer without occupying an execution slot.devbox_waitand host-modedevbox_wait_for_filelikewise avoid spawning a shell just to sleep/poll.- Detached job logs rotate at configured byte limits, and dead runners with stale heartbeats reconcile to terminal
interruptedstate. - Synchronous shell/direct-program tools support
output_mode=head|tail|summary,max_output_chars, andmax_output_linesfor bounded large-output inspection. devbox_job_logsreturns bounded log tails.devbox_job_cancelcancels the detached process tree.
When MCP_AUTH_MODE=none, local loopback requests can expose the browser bridge for configured ChatGPT origins. Disable it with ENABLE_GATEWAY_BRIDGE=false when it is not needed.
host_execprovides direct host shell access and should be enabled only in a trusted environment.host_run_programis constrained byHOST_PROGRAM_ALLOWLISTand is the preferred native-host fast path for a single executable.- Persistent OAuth state automatically prunes expired authorization codes and tokens during load/persistence and bounds dynamic client registration with
MCP_OAUTH_MAX_CLIENTS(default256), evicting only the oldest unreferenced clients. - OAuth advertises capability scopes
mcp:devbox:read,mcp:devbox:exec,mcp:host:read,mcp:host:exec, andmcp:admin. The legacymcp:toolsscope remains a full-access compatibility scope so existing connector sessions continue to work. - Host-mode read-only execution is cooperative rather than a hard sandbox.
- The built-in
oauth/demo-oauthmode is for connector/protocol testing and does not authenticate an external user identity. Public deployments requiring identity enforcement should usecloudflare-accessor another trusted authentication layer in front of Devbox.
JavaScript service tests:
npm testC++ runtime and installer tests:
ctest --test-dir .cpp-build/native -C Release --output-on-failureService smoke test:
node bin/devbox.js start
curl --fail http://127.0.0.1:8100/healthz
node bin/devbox.js stopThis helper sends continue immediately and every two minutes while this page remains visible. It requires exactly one visible, empty editable field inside a form and a unique Send button in that same form. It pauses while a response is running, leaves existing drafts alone, and stops on navigation. If the page structure is unsupported, it does nothing. This is a page-dependent convenience example; Devbox's persistent jobs are the supported way to keep commands running across requests.
Stop it with window.devboxContinue.stop(). Pasting the snippet again stops the previous instance, including any pending attempt.
(() => {
window.devboxContinue?.stop();
clearInterval(window.continueTimer);
const route = location.href;
let stopped = false;
let busy = false;
const sendSelector = 'button[type="submit"], button[aria-label="Send message" i], button[data-testid="send-button"]';
const stopSelector = 'button[data-testid="stop-button"], button[aria-label="Stop streaming" i], button[aria-label="Stop generating" i]';
const visible = (el) => {
if (!el?.isConnected || !el.getClientRects().length) return false;
for (let parent = el; parent; parent = parent.parentElement) {
const style = getComputedStyle(parent);
if (style.visibility !== 'visible' || Number(style.opacity) === 0 || style.display === 'none') return false;
}
const rect = el.getBoundingClientRect();
return rect.bottom > 0 && rect.right > 0 && rect.top < innerHeight && rect.left < innerWidth;
};
const generating = () => [...document.querySelectorAll(stopSelector)].some(visible);
const sendButtons = (form) => [...form.querySelectorAll(sendSelector)].filter(visible);
const active = () => !stopped && location.href === route && document.visibilityState === 'visible';
const stop = () => {
stopped = true;
clearInterval(window.continueTimer);
};
async function tick() {
if (location.href !== route) stop();
if (!active() || busy || generating()) return;
const boxes = [...document.querySelectorAll('[contenteditable]')]
.filter(el => el.isContentEditable && visible(el));
if (boxes.length !== 1) return;
const box = boxes[0];
const form = box.closest('form');
if (!form || box.textContent.trim() || sendButtons(form).length !== 1) return;
busy = true;
try {
box.focus();
const selection = window.getSelection();
if (!selection) return;
const range = document.createRange();
range.selectNodeContents(box);
range.collapse(false);
selection.removeAllRanges();
selection.addRange(range);
if (!document.execCommand('insertText', false, 'continue')) return;
const deadline = Date.now() + 5_000;
while (active() && Date.now() < deadline) {
if (!visible(box) || box.closest('form') !== form || box.textContent.trim() !== 'continue' || generating()) return;
const buttons = sendButtons(form);
if (buttons.length !== 1) return;
const button = buttons[0];
if (!button.disabled && button.getAttribute('aria-disabled') !== 'true') {
button.click();
return;
}
await new Promise(resolve => setTimeout(resolve, 100));
}
} catch (error) {
console.warn('Continue helper stopped this attempt:', error);
} finally {
busy = false;
}
}
window.devboxContinue = { stop, tick };
window.continueTimer = setInterval(tick, 2 * 60 * 1000);
void tick();
})();For Windows named Cloudflare Tunnel, CLOUDFLARED_EDGE_BIND_ADDRESS=auto selects the current IPv4 address on the active physical default-route adapter and records the interface/address in run/host-cloudflared.transport.json. If an explicitly configured DHCP address is no longer assigned, startup automatically resolves the replacement physical default-route IPv4 instead of leaving cloudflared bound to a stale lease.