Apple Silicon macOS Technical Preview
Current preview: 0.1.0-preview.3
Windows support is implemented in parts of the codebase but is not part of this public preview yet. Real-machine Windows validation is still pending.
Rootbound connects ChatGPT to real projects on your Mac while keeping Codex as the local trust, sandbox, permission, and execution authority.
ChatGPT reasons. Rootbound performs model-free local actions. Codex keeps control of local trust and permissions.
Rootbound is useful when you want ChatGPT to inspect, edit, test, commit, and continue work in the same local codebases you already use with Codex — without secretly delegating the reasoning to another Codex model.
0.1.0-preview.3 removes Rootbound's one-active-project limitation without introducing one daemon or tunnel per repository.
Connect each project once on the active Rootbound connection:
cd ~/Documents/Dev/project-a
rootbound connect .
cd ~/Documents/Dev/project-b
rootbound connect .The healthy supervised runtime is reused. Each saved connection keeps its own project allowlist, and ChatGPT can discover the allowed projects with codex.workspace_list.
The project that bootstraps the runtime becomes its anchor, but the anchor is infrastructure state only. It is never a hidden “current project”. If several projects are available and a project-facing request is not safely scoped, Rootbound returns PROJECT_SCOPE_REQUIRED instead of guessing.
The public MCP contract is now 33 tools on rootbound-public-preview-v6.
- project grants are isolated per saved connection;
- canonical path routing rejects cross-project and nested-project allowlist bypasses;
- commands, Git, edits, browser/context reads and continuity share the same central project-scope guard;
- long commands retain their durable
projectRef/cwdidentity; - the detached Windows command worker independently revalidates connection scope before execution;
- connection switching validates the current runtime anchor on the target connection and can roll back transactionally on failure;
rootbound stopandrootbound stop --forceterminate the complete detached runtime process tree — supervisor, tunnel and MCP child — so stale MCP servers cannot survive a normal restart or upgrade;- existing one-connection installs can migrate trusted registered projects to that single connection, but no implicit grant migration occurs once multiple saved connections exist.
See docs/multi-project-runtime.md for routing, errors, retries, concurrency and the real-Mac acceptance test.
Apple Silicon macOS can capability-probe a newly bundled, unknown Codex build before use instead of failing solely because its exact version string changed. Unknown builds are accepted for the current process only after the model-free App Server/permission probe succeeds; trust is never widened to a wildcard version range.
You can inspect that compatibility contract with:
npm run probe:codex -- --cwd /path/to/trusted/projectSee docs/multi-connection.md, docs/multi-project-runtime.md, and docs/continuity-runtime.md for the detailed runtime contracts.
ChatGPT
↓
Rootbound public MCP surface
↓
connection-scoped project routing
↓
model-free local primitives
↓
Codex App Server permissions / sandbox
↓
Your projects, Git repos and local commands
You can ask ChatGPT things like:
@Rootbound find where authentication is handled
@Rootbound fix the failing tests and run them again
@Rootbound show me what changed in Git
@Rootbound continue
Rootbound does not expose a public Codex model/agent lane. ChatGPT remains the reasoning model.
You do not need to understand MCP, JSON-RPC, SQLite, tunnel profiles, or Codex App Server internals.
The normal setup has five parts:
1. Install the prerequisites
2. Install Rootbound
3. Connect one or more local projects
4. Add the matching tunnel in ChatGPT
5. Test it
Rootbound currently requires:
- Git
- Node.js 22.13 or newer
- Codex installed locally
- OpenAI
tunnel-client - a ChatGPT account/workspace that can use the required custom MCP app/connector actions
Check Git and Node:
git --version
node --versionRootbound uses your local Codex installation as the trust and sandbox layer. It does not install or replace Codex for you.
git clone https://github.com/LeoMbm/Rootbound.git
cd Rootbound
sh ./bin/rootbound-install.shThe installer checks Node/Codex, stages the app under your user Library, installs production dependencies, and creates a rootbound CLI link under ~/.local/bin.
Verify:
rootbound versionWindows support is not part of this public Technical Preview yet. Windows-specific implementation remains in the repository for ongoing validation.
cd ~/Documents/Dev/my-app
rootbound connect .This is the Normal setup: one command. The guided one-command flow handles tunnel setup, exact-root Codex trust, Rootbound's runtime-only permission contract, project registration, validation, connection-scoped project access, and runtime startup.
Connect additional projects the same way:
cd ~/Documents/Dev/another-app
rootbound connect .On the same Rootbound connection, the existing healthy runtime is reused. The second project is granted to that connection; Rootbound does not stop the first runtime just to switch repositories.
You may see Node's SQLite is an experimental feature warning. That warning by itself does not mean Rootbound failed.
Normal Codex :workspace protects Git metadata such as .git/index.lock. Rootbound therefore uses a runtime-only named Codex profile called rootbound for complete Git workflows.
The profile extends :workspace, grants .git write access inside the authorized workspace, enables outbound network access, and keeps local binding disabled.
The profile is injected only into Codex App Server processes launched by Rootbound and is never written into ~/.codex/config.toml.
A successful first approval includes output similar to:
Permissions: approved runtime-only rootbound
Remote callers can request only the public Rootbound readOnly / inherit behavior; they cannot select an arbitrary stronger Codex profile.
Rootbound asks for explicit Codex trust for each exact project root. A backup of the Codex config is created before trust mutation.
Successful setup looks similar to:
Rootbound workspace ready.
Project: /Users/you/Documents/Dev/my-app
Trust: added exact-root trust
Permissions: approved runtime-only rootbound
Tunnel: configured
Connection access: 1 workspace(s)
Runtime: running
Open ChatGPT settings and create a custom MCP app/connector using Connection: Tunnel. Select the same tunnel ID Rootbound is currently using.
Inspect the active connection with:
rootbound connection currentRootbound can validate its local side, but it cannot reliably inspect which tunnel the ChatGPT UI currently selected.
After a public surface change, reconnect/refresh the custom MCP app so ChatGPT does not keep an older cached tool snapshot.
From ChatGPT:
@Rootbound list my workspaces, open the one I ask for, and show me its Git status
Local health checks:
rootbound status
rootbound self-test .
rootbound doctor "$PWD"Doctor and self-test do not intentionally start a Codex model turn.
Register/grant each project once on the active connection:
cd ~/Documents/Dev/project-a
rootbound connect .
cd ~/Documents/Dev/project-b
rootbound connect .Rootbound keeps one supervised runtime per active connection and exposes multiple allowed workspaces through it. The first project used to start that runtime becomes the runtime anchor for bootstrap/restart purposes only. It is not an implicit project choice for later tool calls.
In ChatGPT, codex.workspace_list discovers the projects allowed on the current connection. Project-facing operations are then scoped by projectRef, cwd, a continuity binding/rescue, or the only available project.
If several projects are available and an operation has no safe scope, Rootbound returns PROJECT_SCOPE_REQUIRED instead of guessing or falling back to the anchor.
rootbound start /path/to/project
rootbound status
rootbound stopBoth normal and forced stops operate on the complete detached runtime process tree. Use rootbound stop --force for a wedged runtime; Rootbound still terminates the tracked supervisor, tunnel and MCP child rather than intentionally leaving a stale connector process behind.
See docs/multi-project-runtime.md for routing, migration, retry, concurrency and smoke-test details.
rootbound connection list
rootbound connection current
rootbound connection add work
rootbound connection switch work
rootbound connection repair work
rootbound connection remove workEach scoped connection keeps its tunnel configuration, runtime key, and project allowlist isolated. A running connection switch is transactional: Rootbound validates the target, restarts the current runtime anchor on that connection only if the anchor is allowed there, requires /readyz, and restores the previous runtime if the target cannot become ready.
Rootbound calls these connections, not ChatGPT accounts. It does not store ChatGPT emails, ChatGPT OAuth tokens, or Codex OAuth credentials in the connection registry.
rootbound logs
rootbound logs --follow
rootbound logs --follow --new-only--new-only separates historical log tail from entries generated after follow mode begins.
The primary rescue entry point is:
@Rootbound continue
The flow is:
Codex work is interrupted / quota is exhausted
↓
Rootbound resolves an authorized project scope
↓
project + repo + thread + worktree are revalidated
↓
existing durable rescue is reattached, or a new rescue starts
↓
ChatGPT receives bounded recent context + real local state
↓
ChatGPT continues the work
↓
Rootbound creates a verified handoff manifest
↓
verified checkpoint is injected back into the original Codex thread
A later ChatGPT conversation can reattach to the same rescue if the saved rescue, original thread, and current worktree still agree.
Rootbound refuses ambiguous project/thread selection, conflicting drift, unsafe rollback, and tampered manifests. With multiple registered projects, the runtime anchor is not used as a hidden continuity fallback.
For supported Rootbound mutations, codex.continuity_rollback restores only safely snapshotted Rootbound-owned rescue mutations. Rootbound does not implement rescue rollback with git reset.
rootbound connect .
rootbound start /path/to/project
rootbound status
rootbound stop
rootbound stop --force
rootbound project list
rootbound project remove /path/to/project
rootbound project remove /path/to/project --remove-trust
rootbound trust remove /path/to/project
rootbound connection list
rootbound connection current
rootbound connection add work
rootbound connection switch work
rootbound connection repair work
rootbound connection remove work
rootbound logs
rootbound logs --follow
rootbound logs --follow --new-only
rootbound self-test .
rootbound diagnosticUpgrade from another release directory:
rootbound upgrade --from /path/to/rootbound-releaseRootbound keeps persistent state outside the installed app tree, so a staged upgrade does not replace project/continuity state.
The current surface exposes 33 public tools.
Current surface identifier: rootbound-public-preview-v6.
codex.workspace_listcodex.workspace_opencodex.project_contextcodex.skill_listcodex.skill_read
workspace_list returns only workspaces allowed for the current saved connection. workspace_open accepts projectRef or cwd, rechecks exact-root authority, and fails closed when scope is ambiguous.
codex.repo_searchcodex.read_manycodex.git_statuscodex.git_diff
codex.apply_patchcodex.precise_editcodex.edit_undocodex.edit_redo
codex.command_execcodex.command_startcodex.command_pollcodex.command_writecodex.command_terminate
Nested Codex CLI/model launches are refused on the model-free command lane.
codex.thread_listcodex.thread_readcodex.thread_itemscodex.continuity_bindcodex.continuity_statuscodex.continuity_checkpointcodex.continuity_unbind
codex.continuity_resumecodex.continuity_searchcodex.continuity_rollbackcodex.continuity_handoffcodex.quota_status
codex.continuity_resume is the preferred entry point for interruption/quota rescue. codex.continuity_handoff persists and injects the bounded verified handoff without starting a model turn. codex.continuity_rollback fails closed unless rollback coverage is provably safe.
codex.browser_statuscodex.browser_tabscodex.browser_read
Browser Reader is intentionally read-only in the public surface.
Rootbound is intentionally fail-closed.
- exact-root trust is explicit;
- each saved connection has an independent project allowlist;
- project-facing calls are centrally scoped and ambiguous multi-project calls fail with
PROJECT_SCOPE_REQUIREDrather than guessing; - nested registered projects cannot bypass a connection allowlist by being treated as files under an allowed parent;
- the runtime anchor is bootstrap state, never a hidden project selector;
- public callers cannot widen the local permission ceiling;
- the Rootbound permission profile is process-local;
- connection runtime keys stay outside registry metadata, normal logs, diagnostics, and public status output;
- new scoped tunnel connections require
/readyzbefore becoming active; - connection switches, repair, removal, start/stop, and tunnel mutation are serialized to avoid runtime races;
- runtime shutdown tracks the supervisor and tunnel and terminates the complete detached process tree, preventing an old MCP server from continuing to serve stale code after a restart or upgrade;
- common secret-bearing files are excluded from ordinary read/search flows unless explicitly requested;
- diagnostics redact credentials, home paths, and sensitive thread information;
- drift and rollback conflicts stop instead of guessing;
- continuity manifests are integrity checked;
- unknown Apple Silicon macOS Codex builds must pass the model-free capability probe before current-process use;
- no public Rootbound tool silently starts a Codex model turn.
See SECURITY.md and docs/multi-project-runtime.md for the complete boundaries.
On macOS, Rootbound keeps application and durable state separate:
~/Library/Application Support/Rootbound/
├── app/
├── state/
│ ├── rootbound.sqlite3
│ ├── connection-registry.json
│ ├── connection-projects-<connection-id>.json # legacy/default layout
│ └── connections/
│ └── <connection-id>/projects.json # scoped connection layout
├── runtime/
├── logs/
└── backups/
Existing pre-multi-connection tunnel files are preserved as the legacy/default connection rather than destructively migrated.
Multi-project project grants are connection-scoped files and do not bump the Rootbound SQLite schema.
The CLI normally lives at:
~/.local/bin/rootbound
If installation updated your shell profile, open a new Terminal window.
rootbound status
rootbound connection currentMake sure ChatGPT is using the same tunnel ID as the active Rootbound connection.
After changing rootbound-public-preview-*, reconnect the ChatGPT connector/app to refresh its cached MCP tool snapshot.
A healthy single Rootbound runtime should normally have one launch.mjs stdio MCP process behind its tunnel. On macOS you can inspect it with:
ps -axo pid=,ppid=,pgid=,command= | grep '[s]cripts/launch.mjs stdio'Current builds stop the complete runtime process tree, including forced stops. Older Technical Preview builds could leave a tunnel/MCP process alive after a forced supervisor kill; after upgrading, stop the runtime with the current rootbound stop --force before reconnecting ChatGPT. If an orphan from an older build is no longer represented in Rootbound runtime state, terminate that stale process group once or restart the user session before starting the new runtime.
Several workspaces are available and the request did not identify one safely. Call codex.workspace_list, then retry with the intended projectRef or an absolute cwd inside that project.
Rootbound deliberately does not remember a mutable global “active project” for ChatGPT conversations.
Run rootbound connect . from that project while the intended Rootbound connection is active. Rootbound does not copy project grants between saved connections automatically.
rootbound connection repair <name>Repair validates the replacement before committing it and restores the previous key/config if validation fails.
On Apple Silicon macOS, rootbound connect . automatically capability-probes an unknown bundled Codex build before use. A compatible build can proceed for the current process without modifying the built-in allowlist.
For an explicit diagnostic:
npm run probe:codex -- --cwd /path/to/trusted/projectIf the capability probe fails, Rootbound fails closed. Do not manually add wildcard version ranges to the production policy.
Run rootbound connect . from the new canonical root. Rootbound intentionally avoids treating stale paths as the same workspace without revalidation.
Most users should use:
rootbound connect .Manual configuration is an operator/debug escape hatch:
rootbound tunnel configure --argv-json '["tunnel-client","run","--profile","my-profile"]'
rootbound tunnel show
rootbound tunnel clearROOTBOUND_TUNNEL_ARGV_JSON remains available as an advanced/environment-only override. Explicit saved connections take precedence so a stale global environment override cannot silently redirect a connection switch. Because this mode has no durable saved-connection identity, project allowlisting is intentionally not connection-scoped there.
Persistent manual tunnel configuration rejects detectable literal credentials.
CONTROL_PLANE_TUNNEL_ID=tunnel_... \
CONTROL_PLANE_API_KEY=... \
rootbound connect . --yes--yes records consent for the current Rootbound runtime permission contract. Use it only where that authority has already been intentionally approved.
Register/trust/grant without starting the runtime:
rootbound connect . --yes --no-startnpm ci
npm run test:v5
npm test
npm run validate:releaseFor the multi-project release, also run the real-Mac smoke test in docs/multi-project-runtime.md before merge. The smoke must confirm workspace discovery, cross-project isolation, PROJECT_SCOPE_REQUIRED for unscoped calls, persistence across restart, and that a stop/restart leaves only the newly started runtime/tunnel/MCP process tree.
Probe the currently installed Codex build explicitly:
npm run probe:codex -- --cwd /path/to/trusted/projectThe canonical public tool list lives in src/surface-contracts.mjs.
The detailed V5 acceptance plan lives in docs/plans/rootbound-v5.md.
Apache-2.0.
Rootbound is an independent project. It is not an OpenAI product and does not imply OpenAI endorsement.
Shoutout to @liyana31811, creator of Codexless. Their work was an early source of inspiration while Rootbound was taking shape.
Keep working in ChatGPT. Use Codex when you explicitly need Codex.