Project status: This project is no longer needed. ChatGPT added mobile support. :party:
Codex Relay is a local command bridge for controlling Codex from a paired Android phone. It includes a Node.js app-server, a polished local web pairing screen, and a native Android client.
Security note: this project can start Codex and send commands on your Mac. Keep the server on localhost by default, pair only on trusted Wi-Fi, and use HTTPS for any remote access.
| Android connect | Android dashboard |
|---|---|
![]() |
![]() |
- Local web pairing screen with one-time 8-digit pairing codes.
- Native Android app, not a WebView shell.
- Paired-device token auth for future reconnects.
- Project picker, slash commands, file mentions, image attachment upload, and Codex result rendering.
- Browser live terminal for interactive Codex controls such as model switching, approvals, MCP inspection, compacting, and raw slash commands.
- Safe open-source defaults: localhost server binding, ignored
.env, HTTPS-required remote mode, and no auto-installed APK updates.
- macOS or Linux host with Node.js 20+.
- Codex CLI installed and available as
codex. - Android Studio, or JDK plus Gradle, to build the Android app locally.
- Phone and computer on the same trusted Wi-Fi for first pairing.
-
Install dependencies:
npm install
-
Generate a private local
.env:npm run setup
-
For browser-only local testing, start the server:
npm start
Open
http://localhost:8787.The browser app includes both the chat surface and a live Codex terminal. Use the terminal button after pairing to access the full interactive Codex CLI from the selected project.
-
To pair an Android phone on trusted Wi-Fi, edit
.envand set:HOST=0.0.0.0
Then restart:
npm start
-
Build and install the Android app:
cd android-native ./build-apk.shThe local debug APK is created at
android-native/app/build/outputs/apk/debug/app-debug.apk. -
Open the Android app and tap Continue.
-
Confirm the pairing request on the web screen on your Mac, then enter the 8-digit code shown there.
After pairing, the phone stores an encrypted paired-device token and reconnects automatically while the server is reachable.
Do not port-forward this server directly from your router.
For away-from-home use, pair once nearby first, then expose the server through a trusted HTTPS tunnel or reverse proxy:
cloudflared tunnel --url http://localhost:8787Set these values in .env:
TRUST_PROXY=true
PUBLIC_URL=https://your-secure-tunnel.exampleRemote HTTP URLs are rejected by the Android app. HTTPS is required outside private local-network addresses.
Copy .env.example or run npm run setup.
| Variable | Default | Purpose |
|---|---|---|
REMOTE_TOKEN |
generated | Private legacy token. Device tokens are preferred. |
PORT |
8787 |
App-server port. |
HOST |
127.0.0.1 |
Bind address. Use 0.0.0.0 only for trusted Wi-Fi pairing. |
CODEX_COMMAND |
/Applications/Codex.app/Contents/Resources/codex on macOS when installed, otherwise codex |
Codex app bundle command used for desktop-app-native sync. |
CODEX_WORKDIR |
current folder | Default workspace. |
CODEX_PROJECT_ROOTS |
parent folder | Folders exposed in the project picker. |
TRUST_PROXY |
false |
Trust X-Forwarded-Proto only behind your HTTPS proxy. |
PUBLIC_URL |
empty | Optional HTTPS tunnel URL for QR output. |
The Build Android APK workflow is manual. By default it uploads the APK artifact and publishes a GitHub release that the Android app can discover from Settings → Check updates.
For installable in-app updates, configure these GitHub Actions secrets so every release APK is signed with the same private key:
ANDROID_KEYSTORE_BASE64ANDROID_KEYSTORE_PASSWORDANDROID_KEYSTORE_TYPEANDROID_KEY_ALIASANDROID_KEY_PASSWORD
Keep signing keys out of the repo. If the signing secrets are missing, the workflow still builds an unsigned APK artifact, but Android will not install it as an update over an existing signed app.
.envis ignored and should never be committed.- Pairing codes are one-time, short-lived, and visible only from the Mac web UI.
- First pairing must start from the same local network.
- Android stores paired-device tokens with AndroidX encrypted preferences.
- Project chat history is project-scoped and redacts common token, private-key, bearer-token, and env-secret formats before sending transcript text to the phone.
- Remote access requires HTTPS.
- The Android app checks the latest GitHub release and opens the release page for updates; Android still handles APK installation approval.
Check the server syntax:
npm run checkAudit production dependencies:
npm audit --omit=devRegenerate icon PNGs after editing SVG assets:
npm run build:iconsMIT


