Important
Unofficial project. Not affiliated with, endorsed by, or supported by OpenAI or Work Louder.
Use your phone to experience the Codex Micro feature with the Codex desktop app on Mac. This is an attempt to resemble the controls, lighting, and feel of the real OpenAI × Work Louder Codex Micro.
For the Codex desktop app—not Codex CLI. Everything runs between your Mac and phone over private Wi-Fi or Tailscale.
CodexMicroAppDemo.mp4 #
Warning
Tested with Codex desktop 26.715.52143 (build 5591) on macOS 26.5.1 (build 25F80) and one iPhone using Chrome. Other versions and setups are unverified. The built-in diagnostics are designed to give an AI coding agent enough information to fix small machine-specific issues.
After a Codex update: rerun make setup
. The adapters fail visibly if Codex changed an integration point; an AI coding agent can follow the short update repair playbook.
You need: macOS 13+, Codex desktop, Node 20+, Swift 6, and a phone browser.
make setup
That is the only project command you need. It explains both connection methods, checks prerequisites and permissions, builds the app, starts the Mac side, and opens a QR code. Scan it with your phone.
Keep the Terminal window open while using the controller. The first clean build can take about 45 seconds.
Tip
Prefer an AI agent? Give it this repository and say:
“Download https://github.com/maxxspotter/codex-micro-app, run the guided setup, explain both connection methods and every permission, then help me verify the phone controller. Keep everything local.”
The phone UI is the same either way. The difference is how the Mac delivers its inputs to Codex.
The Native Shim method adapts Marcel Pociot’s MIT-licensed Codex Micro Stream Deck emulator.
| Method | How it works | One-line tradeoff |
|---|---|---|
| Native Shim — recommended(detected inside Codex) | ||
| Codex itself shows a connected Codex Micro, as if the real device were attached. Phone inputs and lights use Codex’s native hardware channel. | Best feature parity, but Codex must launch through the shim. A Codex update may need a small compatibility fix that an AI coding agent can usually make from the built-in diagnostics. | |
| Standard Bridge(not detected as Micro hardware) | ||
| Codex does not show a connected Micro. A separate local Mac helper reads Codex state and operates supported controls for the phone. | Normal Codex launch, but some controls are more limited and UI changes can affect them. |
A phone webpage cannot present itself to a Mac as a USB/HID device. Without a device, Codex does not open its native Codex Micro input and lighting channel.
The Native Shim presents a local synthetic Codex Micro to the Codex process. That lets Codex handle task-key colors, the configurable knob, joystick, MIC, and command keys like real hardware. It does not patch the installed Codex application or task data on disk.
Its original license is preserved in apps/micro-shim/THIRD_PARTY_LICENSE.txt.
Note
If Codex is already open: Native Shim asks Codex to quit, waits, and
relaunches it once with the shim attached. Save or send unfinished composer
text first. Pressing Control-C
stops the shim-launched Codex; reopen Codex normally from the Dock to leave shim mode. Standard Bridge does not restart Codex.
You do not need these for first setup. They are shortcuts for repeat runs or AI agents:
| Command | Result |
|---|---|
make serve-shim |
|
| Start the recommended Native Shim | |
make serve |
|
| Start the Standard Bridge | |
make stop-shim |
|
| Stop only this repository’s shim processes | |
make stop |
|
| Stop only this repository’s standard bridge |
After the first Mac state arrives, the PWA header and OPTIONS screen say Native Shim, Standard Bridge, or Demo, so the active method is not implicit.
Easiest: Mac and phone on the same private Wi-Fi.Different networks: put both devices on the same private Tailscale tailnet. Never use Funnel or a public tunnel.- Keep the Mac awake, unlocked, and connected while controlling Codex.
Want to explore without touching Codex? Run make demo
and add ?demo=1
to the shown URL.
Note
Native Shim lets Codex own the mappings. The table shows the current native layout. Open Codex → Settings → Codex Micro to choose Agent keys and Knob behavior; the phone follows those settings automatically. The other phone keys mirror the native layout shown there. Standard Bridge performs the listed actions through the Mac helper.
Tip
Turn up the phone volume for the mechanical clicks. Browser haptics are used only when the phone exposes them.
| Off | White | Blue | Green | Amber | Red |
|---|---|---|---|---|---|
| Unassigned | Idle | Working | Finished, unread | Needs input | Failed |
The selected task pulses. The frame follows its color. Native Shim receives these colors from Codex’s hardware-lighting channel; Standard Bridge derives them from verified Codex task state.
| Prompt | Native Shim | Standard Bridge | Why |
|---|---|---|---|
| Mac incoming connections | |||
| ✓ | ✓ | Phone reaches the private local bridge on port 48321 |
|
| Chrome Local Network | |||
| ✓ | ✓ | Phone reaches the Mac | |
| Codex microphone | |||
| Optional | Optional | MIC uses Codex’s Mac microphone—not the phone webpage | |
| Mac Accessibility | |||
| — | ✓ | Standard Bridge uses named controls and verified key events—never screen coordinates | |
| Terminal Automation | |||
| Sometimes | — | macOS may ask before Terminal can quit and relaunch Codex for shim mode |
Native Shim injects into Codex’s local node-hid
layer, so Codex’s physical Input Monitoring indicator may remain “Not granted.” That permission is for a real USB/HID device and is not required by this shim path.
It should never ask for your OpenAI password, API key, Full Disk Access, screen recording, contacts, photos, or phone microphone.
For Standard Bridge, setup checks the exact Codex Micro Phone Bridge app before starting. If Accessibility is missing, it opens the correct macOS page and waits for you to enable it. A source-code rebuild can require one new grant; ordinary restarts of the same build reuse it.
Native Shim sends hardware events and follows Codex → Settings → Codex Micro. Standard Bridge expects these Codex defaults:
| Phone control | Codex shortcut |
|---|---|
| Dial tap | Control-Shift-M |
| Joystick ↓ | Command-B |
| Joystick ← / → | Command-[ / Command-] |
If you changed them, restore the defaults shown in Codex → Settings →
Keyboard shortcuts. make diagnose
reports incompatibilities.
On the tested setup, Native Shim connects as a Codex Micro and carries task lighting plus phone inputs through Codex’s hardware path. Standard Bridge remains available when users do not want process-level hardware emulation.
There is room to improve feature parity—for example, configurable buttons—and smooth out rough edges. Further work will depend on whether people find it useful.
- Mac only; Codex desktop updates can break either internal adapter.
- Update breakage is detected on a best-effort basis; compatibility code is never rewritten automatically or allowed to guess against a changed Codex UI.
- Native Shim depends on Codex’s current Electron/
node-hid
behavior. - Split and approval variants need broader real-world testing.
-
Browser PWA installation, haptics, and background reconnect vary.
-
Local traffic is authenticated HTTP, not TLS. Use trusted Wi-Fi or private Tailscale—never expose the port publicly.
-
No analytics, ads, hosted backend, or cloud relay.
-
Phone traffic stays between your phone and Mac.
-
The phone receives six generic slots and controller state—not task titles, prompts, responses, internal IDs, raw Codex events, or credentials.
-
Pairing sessions expire after 30 days.
-
Native Shim changes only the Codex process it launches; no Codex files are patched on disk.
Privacy details · Security model
flowchart LR
PHONE["Phone PWA"] <-->|"Private Wi-Fi or Tailscale<br/>paired local session"| MAC["Mac Swift companion"]
MAC --> SAFE["Small privacy-safe<br/>state projection"]
SAFE --> PHONE
MAC --> CHOICE{"Connection method"}
CHOICE -->|"Native Shim"| SOCKET["Private Unix sockets"]
SOCKET <--> HID["Synthetic Codex Micro<br/>node-hid shim"]
HID <--> CODEX["Codex desktop"]
CODEX -->|"Native task lighting"| HID
CHOICE -->|"Standard Bridge"| ADAPTER["Verified Codex adapter"]
ADAPTER <--> IPC["Codex local IPC<br/>live state + settings"]
ADAPTER <--> SERVER["Codex app-server<br/>supported task operations"]
ADAPTER --> META["Read-only local metadata<br/>pins + verification"]
ADAPTER --> AX["macOS Accessibility<br/>named controls only"]
IPC <--> CODEX
SERVER <--> CODEX
META --> CODEX
AX --> CODEX
The phone never talks directly to Codex. It sends only allowlisted actions to the Mac companion. Both methods return the same small, versioned phone state. Native Shim gets hardware input and lighting from Codex’s Micro channel; Standard Bridge performs one action and reports success only after observing the expected result.
flowchart LR
PRE["Read real state"] --> ACT["Perform one<br/>allowlisted action"]
ACT --> CHECK{"Expected result<br/>observed?"}
CHECK -->|Yes| OK["Verified success"]
CHECK -->|No| FAIL["Visible failure<br/>state stays honest"]
Technical details: Architecture · Protocol · AI-agent setup
| Command | Purpose |
|---|---|
make setup |
|
| Guided method choice, build, and start | |
make diagnose |
|
| Read-only Standard Bridge compatibility checks | |
make demo |
|
| Offline scripted controller | |
make shim-test |
|
| Hardware-free shim protocol test | |
make check |
|
| Lint, tests, browser checks, and release build |
Full credit for the original Codex Micro concept, hardware, software behavior, and product design goes to OpenAI and Work Louder: official OpenAI guide · official Work Louder product page.
Native hardware-emulation work is adapted from Marcel Pociot’s Codex Micro Stream Deck emulator under the MIT License.
Code is provided under the MIT License. Codex, Stream Deck, Work Louder, Codex Micro, OpenAI, ChatGPT, and related names and marks are trademarks of their respective owners. This license does not grant rights to third-party marks, product designs, trade dress, or official imagery.
See NOTICE.md.