DarwinRelay
Manages a background Chrome workspace via a companion extension, enabling navigation, inspection, form filling, and clicking in background tabs without stealing focus.
Provides native macOS desktop control, including shell and filesystem access, PTYs, Accessibility-based UI automation, screen capture, OCR, and input simulation.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@DarwinRelaytake a screenshot of this window and summarize what is on screen"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
DarwinRelay
Turn ChatGPT into a local agent for your Mac.
DarwinRelay is a source-first macOS MCP runtime that gives ChatGPT and other MCP clients structured access to the Mac you already use: shell and files, real PTYs, long-running jobs, background Chrome, native desktop control, and persisted Codex history.
Use ChatGPT itself like a local coding agent: let it inspect a repository, reproduce a failure, change the code, run the tests, and verify the result on your machine — without inserting another coding model between the conversation and macOS.
DarwinRelay is intentionally powerful. It isnot a sandbox and does not implement a filesystem or shell-command allowlist. A connected client can act with the effective permissions of the macOS user running the bridge. Read SECURITY.md before connecting a client or exposing the runtime beyond localhost.
Use ChatGPT as a local agent
A typical developer task can start as simply as:
Use DarwinRelay and work on ~/Projects/myapp.
Find why authentication is failing. Reproduce the problem, fix the underlying
cause, run the relevant tests, and verify the result locally.When ChatGPT exposes DarwinRelay's full tool surface, the same conversation can carry the task through the whole local loop:
understand → inspect → reproduce → modify → execute → verify → iterateDarwinRelay does not require Codex for that workflow. ChatGPT is the reasoning client; DarwinRelay is the execution runtime on your Mac.
ChatGPT availability
ChatGPT's custom-MCP availability is controlled by OpenAI and can change independently of DarwinRelay. Plan, workspace, rollout, and UI behavior may differ from the current documentation, so treat the tool surface shown in your account as authoritative for what that ChatGPT session can use. See the current OpenAI developer-mode and MCP app documentation when setting up the connection.
DarwinRelay itself remains MCP-client-neutral and can also be used by other clients that support the required MCP tool surface.
Here, “local agent” describes the workflow, not ChatGPT's separate Agent mode product feature. OpenAI currently says Agent mode does not use custom apps; use DarwinRelay from a normal ChatGPT conversation with the custom app selected.
Related MCP server: mcp-server-macos-use
What can it do?
Shell and files — run commands, inspect or modify files, apply patches, and manage local processes.
Real PTYs — interactive shells, REPLs, SSH, sudo prompts, TUIs, and long-running terminal programs.
Jobs and process lifecycle — start work that outlives one tool call, inspect it later, and reclaim it on shutdown.
Native computer use — semantic Accessibility queries/actions, windows, dialogs, file panels, screenshots, OCR, keyboard/mouse fallback, and visual waits.
Background browser automation — a dedicated Chrome profile and extension-owned tab pool that can navigate, inspect, fill, and click without routinely stealing focus.
Codex history — read persisted Codex threads without resuming them or starting another model turn.
Authenticated MCP transport — stdio locally, or the included HTTP/OAuth front end behind a tunnel you control.
Fail-closed lifecycle controls — explicit full-access unlock, audit metadata, process reclamation, singleton menu ownership, and rollback-aware app updates.
Developer workflow
The first useful DarwinRelay workflow should not require browser automation, native UI permissions, or Codex history.
ChatGPT
↓
DarwinRelay
↓
local repository
↓
read files / run commands / edit code / run tests
↓
verify the result on the same MacOnce the core coding loop works, add capabilities only when the task needs them:
use a PTY for an interactive debugger, REPL, SSH session, or TUI;
use background Chrome for web workflows;
grant native desktop permissions when ChatGPT needs to operate a real macOS app;
use Codex history when you want ChatGPT to inspect or continue earlier Codex work.
See examples/README.md for copy-paste workflows.
Beyond coding
DarwinRelay can combine local code, processes, browser state, and native macOS UI in one execution loop. For example, a desktop-app debugging task can look like:
launch the app
→ reproduce the issue through the real UI
→ inspect logs and code
→ fix the implementation
→ restart the app
→ repeat the UI flow
→ verify the fixThe native desktop layer uses Accessibility first and falls back to ScreenCaptureKit/Vision and synthesized input where needed. The browser layer uses a dedicated local Chrome profile by default rather than silently taking over your everyday profile.
Already using Codex?
DarwinRelay can read persisted Codex history without starting another Codex model turn. That makes Codex a useful continuity source rather than a required intermediary:
Find the latest Codex thread for this project.
Summarize the objective, branch, changed files, current errors, and unfinished step.
Then inspect the live repository and continue the work from ChatGPT.Quick start
DarwinRelay is currently source-first / self-built. GitHub Releases do not ship a prebuilt .app or .dmg, and a paid Apple Developer Program membership is not required for the current product model.
1. Requirements
Core self-build:
macOS 13 or newer;
Node.js 18 or newer (Node.js 22 is used in CI);
Xcode Command Line Tools /
swiftcfor the menu app and native helper.
For ChatGPT through the menu app's HTTP/Server URL path, also install cloudflared and make sure it is available on your login-shell PATH.
Optional capabilities:
Accessibility, Screen Recording, and Input/Post Events permissions — only for native desktop control;
Full Disk Access — only when tasks need macOS-protected filesystem locations;
Google Chrome — only for the managed
chrome_*background workspace;Codex CLI/history — only for
codex_thread_*continuity tools.
2. Choose an install path
Option A — Install with a local coding agent
Already use Codex, Claude Code, or another local coding agent with shell/filesystem access? Let it perform the self-build for you:
Install DarwinRelay on this Mac from:
https://github.com/dcierra/darwinrelay
Read AGENTS.md and the installation documentation first.
Install or verify the required dependencies, then build and install DarwinRelay
using the documented source-first/self-build path. Configure everything that
can be configured without weakening the project's security model.
Do not bypass macOS security controls. Do not use my personal Chrome profile.
When macOS requires Accessibility, Screen Recording, Input/Post Events, Full
Disk Access, Keychain access, or another user-consent step, stop and tell me
exactly what I need to approve manually.
After installation, verify that DarwinRelay starts correctly and report what
remains to connect it to my MCP client.The agent should follow the repository rather than guess. If this path exposes an ambiguous dependency, build step, or permission handoff, that is an onboarding bug to fix in DarwinRelay's scripts/docs rather than something to paper over with a longer prompt.
Option B — Install manually
git clone https://github.com/dcierra/darwinrelay.git
cd darwinrelay
npm run check
./menubar/build.sh
open /Applications/DarwinRelay.appThe build script installs the locally built menu app into /Applications when possible (falling back to ~/Applications). Keep the DarwinRelay checkout in place: the self-built app intentionally resolves its runtime from that source package.
The build uses a persistent local code-signing identity when one is available and otherwise falls back to ad-hoc signing. Ad-hoc builds work without a paid Apple Developer membership, but macOS TCC grants can need to be re-granted after rebuilds because the designated requirement can change.
For a compile/sign smoke test with no installation side effect, use:
DARWINRELAY_APP_OUTPUT=/tmp/DarwinRelay.app ./menubar/build.sh --build-onlyUpdating DarwinRelay
./scripts/update.sh is included starting with DarwinRelay v0.6.5. If an existing installation is on v0.6.4 or older, perform one final source-first manual upgrade/reinstall to v0.6.5 using the installation steps above; from v0.6.5 onward, use the updater for release-to-release changes.
From DarwinRelay v0.6.9 onward, the menu bar also exposes Update DarwinRelay…. It asks for explicit confirmation, opens the same canonical updater in an independent Terminal window, and shows progress while the app restarts. There is no silent or automatic update path.
You can run the same updater directly from a normal local Terminal/iTerm session (or another independent local shell), not through the DarwinRelay MCP connection that is about to restart:
cd /path/to/darwinrelay
./scripts/update.shThat updates to the latest stable vMAJOR.MINOR.PATCH release. To select an exact published release instead:
./scripts/update.sh v0.6.5The updater treats the Git checkout and /Applications/DarwinRelay.app as one transaction. It verifies the canonical GitHub origin, requires a clean checkout pinned to an exact stable release tag, checks source integrity, refuses moved tags and downgrades, atomically installs the new app with the same signing identity, refreshes autostart, restarts fail-closed, and requires the real MCP doctor to return CORE VERDICT: READY. If activation fails, it attempts to restore both the previous checkout and the retained rollback app.
It deliberately does not use git pull, git reset --hard, or delete local work. A dirty/development checkout is rejected; keep development changes in another branch/worktree rather than using the production install as a coding checkout.
Because the background Chrome extension is loaded unpacked from this checkout, a release that changes its manifest/source may require one manual Reload from Chrome's Extensions page in the dedicated DarwinRelay profile. The updater reports this when the extension version changes; never substitute a personal profile.
For project maintainers, updater/lifecycle changes have an additional pre-release gate: the exact untagged candidate is exercised on a real Mac with scripts/test-update-candidate.sh before a public tag is created. This is deliberately separate from the user-facing updater so arbitrary commits never become a normal update target.
3. Connect ChatGPT
Open the DR menu-bar item and press Start. When the MCP transport is running, choose Copy ChatGPT Setup and follow docs/CHATGPT.md.
The first coding workflow does not require Chrome, Codex history, Accessibility, Screen Recording, or Input permission. Configure those later when a task actually needs them.
4. Verify before modifying anything
Start with a read-only check:
Use DarwinRelay. Call bridge_status first.
Then list ~/Projects/myapp and read its top-level README/package metadata.
Do not modify files or run shell commands yet.Then, if ChatGPT exposes DarwinRelay's write/execute tools in your account, try the real workflow:
Use DarwinRelay and work on ~/Projects/myapp.
Run the test suite, find one failing test, fix the underlying issue, rerun the
relevant tests, and verify the result. Do not deploy or force-push anything.For troubleshooting, run:
./scripts/doctor.shThe doctor now gives a blocking Core / MCP coding path verdict separately from optional native-desktop, protected-filesystem, background-Chrome, and Codex capabilities. It performs a real local initialize → bridge_status smoke check for the selected transport and prints the next action for blocking failures. Deeper lifecycle/browser diagnostics continue to evolve in the roadmap.
Source-only local MCP usage
For MCP clients that can connect to a local stdio server, the bridge can also run directly without the menu app. Full access must be explicitly acknowledged:
export DARWINRELAY_FULL_ACCESS_ACK=I_UNDERSTAND_THIS_GRANTS_FULL_ACCESS
node bridge.mjsDefault runtime state:
~/Library/Application Support/DarwinRelay
~/Library/Logs/DarwinRelayUse environment variables such as DARWINRELAY_DATA_DIR, DARWINRELAY_LOG_DIR, DARWINRELAY_SHELL, and DARWINRELAY_AUDIT_MODE to isolate development/test instances.
How it works
flowchart LR
A[MCP client] --> B[DarwinRelay bridge]
B --> C[Shell / filesystem / jobs]
B --> D[PTY helper]
B --> E[Codex persisted history]
B --> F[MacUIHelper]
F --> G[Accessibility / ScreenCaptureKit / Vision / CGEvent]
B --> H[Chrome native host]
H --> I[DarwinRelay Chrome extension]
I --> J[Background DR tab pool]The native desktop helper is deliberately short-lived rather than a privileged daemon. The menu app, MacUIHelper, and virtual cursor use stable code-signing identifiers so macOS TCC grants can survive normal rebuilds when a persistent signing identity is available.
See docs/ARCHITECTURE.md for components, data flow, and trust boundaries.
For AI and coding agents
This repository includes agent-oriented documentation on purpose. If you give the repository to Codex, Claude, ChatGPT, or another coding agent, point it at AGENTS.md first. It describes the repository map, invariants, development commands, testing expectations, signing/browser rules, and release constraints.
For an agent operating an already-installed DarwinRelay runtime rather than modifying source, use docs/AGENT_OPERATIONS.md. It contains the complete tool-family map, preferred decision order, common failure states, and safe runtime workflows.
Native desktop control
DarwinRelay prefers semantic Accessibility operations and uses visual/raw input as a fallback. Core capabilities include:
ui_observe,ui_tree,ui_ax_query,ui_ax_at;fingerprinted AX refs with stale-ref detection;
ui_action,ui_wait_for,ui_assert;ui_app_*,ui_window_*, dialogs, and file panels;ScreenCaptureKit screenshots and Vision OCR;
background PID-targeted input where macOS supports it, with semantic verification and bounded foreground fallback;
ui_sequencefor deterministic multi-step native bursts;a click-through virtual AI cursor that does not move the physical pointer.
See docs/DESKTOP_CONTROL.md for the control model and limitations.
Background Chrome workspace
DarwinRelay uses an unpacked Chrome extension plus Native Messaging. The public extension identity is stable; the expected extension id is:
pfhahlehpahegefejooendokpkklgmgdThe installer creates or reuses a signed-out local Chrome profile named DarwinRelay by default. This keeps agent browsing state separate from an everyday Google profile:
# Recommended/default: dedicated local profile named DarwinRelay
./scripts/install-background-chrome.sh
# Explicit alternatives only when you want them
./scripts/install-background-chrome.sh --profile 'Some Existing Profile'
./scripts/install-background-chrome.sh --use-current-profileIf the DarwinRelay profile does not exist yet, quit Chrome once before running the installer so Chrome cannot concurrently rewrite its Local State; after the profile exists, normal reinstalls can run while Chrome is open. Uninstalling DarwinRelay deliberately leaves that profile in place because browser profile contents are user data.
Then, in the selected profile only, open chrome://extensions, enable Developer mode, choose Load unpacked, and select this repository's chrome-extension/ directory. You can pass --open to the installer for this one-time setup step.
The extension owns a Chrome-native tab group named DR. Routine chrome_open calls lease pre-created idle tabs instead of creating arbitrary foreground tabs. chrome_close returns workspace tabs to the pool.
Browser security model
Relaxed approvals are the default. Normal HTTP/HTTPS work through the configured chrome_* workspace does not need a per-site terminal grant. Enabling Strict approvals in the menu app restores scoped URL grants and one-use app-scoped native mutation approvals.
Direct Chrome automation through shell/AppleScript/JXA remains blocked by the bridge so normal web work stays on the managed background path. The separate native ui_* surface can still interact with foreground Chrome UI when browser/OS security surfaces genuinely require it.
An optional raw Browser Harness/CDP adapter exists behind DARWINRELAY_ADVANCED_BROWSER=1. It is disabled by default and fails closed under Strict approvals because arbitrary CDP cannot be soundly reduced to URL scopes.
HTTP / OAuth transport
mcp-http.mjs binds to loopback and supports the MCP HTTP transport with a static bearer token plus OAuth 2.1 flows used by remote MCP clients. A tunnel such as Cloudflare can publish the loopback service over HTTPS.
The menu app is the preferred entry point for the normal ChatGPT Server URL path. DEPLOY.md documents manual/advanced transport setup, including the OpenAI Secure MCP Tunnel path retained from the upstream project.
Do not expose the HTTP endpoint without reading the remote-access threat model in SECURITY.md. A credential accepted by this front end ultimately gates local code execution as your desktop user.
Development
npm run check
npm run test:core
npm run test:desktop
npm run test:lifecycle
# or all groups
npm testThe public CI intentionally exposes separate checks instead of one opaque test job:
Static checks — syntax/native build validation and full-history gitleaks scan;
Core & protocol tests — MCP, HTTP/OAuth, PTY, federation, browser, and adversarial tests;
Desktop control tests — deterministic desktop protocol tests plus native fixture compilation;
Install & lifecycle tests — installers, autostart, singleton ownership, rollback, and uninstall behavior.
The real mutable AppKit E2E needs a logged-in Mac with TCC permissions and therefore is not treated as reliable on disposable GitHub-hosted GUI sessions. Maintainers can run it locally with:
DARWINRELAY_RUN_NATIVE_DESKTOP_E2E=1 node tests/desktop-control-native.mjsSee CONTRIBUTING.md before opening a pull request. Current development priorities are tracked in ROADMAP.md.
Security
The important boundary is simple: DarwinRelay has the authority of the macOS account that runs it. Security features such as the unlock file, Strict approvals, audit metadata, OAuth, background browser routing, and process reclamation reduce accidental or remote misuse; they do not turn arbitrary shell access into a sandbox.
Security reports should use GitHub's private vulnerability reporting rather than a public issue. See SECURITY.md.
Project lineage
DarwinRelay is independently maintained and substantially diverged from Mac Developer Bridge by Alexander Rådahl Benz. The inherited upstream history is intentionally preserved, and the original MIT copyright notice remains in LICENSE. See UPSTREAM.md for the exact lineage and attribution policy.
The public dcierra/darwinrelay repository is the canonical development source. See docs/DEVELOPMENT_MODEL.md for the development/release model.
DarwinRelay is not affiliated with or endorsed by OpenAI, Apple, Google, Cloudflare, or the upstream maintainer.
License
MIT. See LICENSE and UPSTREAM.md.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- FlicenseAqualityDmaintenanceProvides native macOS computer control tools including mouse and keyboard simulation, screenshot capture, and application management for MCP-compatible agents. It enables AI assistants to directly interact with the macOS operating system and installed apps through standard tool calls.248
- AlicenseNot gradedqualityCmaintenanceEnables controlling macOS applications via accessibility APIs, supporting actions like clicking, typing, and keyboard input through MCP commands.47348MIT
- AlicenseBqualityBmaintenanceEnables full local computer control from MCP clients, including terminal commands, file system operations, application management, screen capture, and input device automation across Windows, macOS, and Linux.27MIT
- AlicenseNot gradedqualityBmaintenanceEnables MCP clients to control macOS via accessibility and screen recording, providing tools to list apps, observe UI, click, type, press keys, and scroll.MIT
Related MCP Connectors
Operate Linux, macOS and Windows from your LLM. Every action runs through an auditable allowlist.
OCR, transcription, file extraction, and image generation for AI agents via MCP.
MCP connector that lets ChatGPT list, search, and run your Apple Shortcuts via a local Mac agent
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/dcierra/darwinrelay'
If you have feedback or need assistance with the MCP directory API, please join our Discord server