- Rust 97.9%
- Shell 1.9%
- Makefile 0.2%
|
Some checks failed
CI / Build (aarch64-apple-darwin) (push) Waiting to run
CI / Build (aarch64-unknown-linux-gnu) (push) Waiting to run
CI / Build (x86_64-pc-windows-gnu) (push) Waiting to run
Prerelease Test Build / publish (push) Blocked by required conditions
CI / conventional-commits (push) Has been skipped
CI / quality (push) Successful in 1m13s
Prerelease Test Build / prepare (push) Successful in 2s
Prerelease Test Build / Build (aarch64-apple-darwin) (push) Waiting to run
Prerelease Test Build / Build (aarch64-unknown-linux-gnu) (push) Waiting to run
Prerelease Test Build / Build (x86_64-pc-windows-gnu) (push) Waiting to run
Release-plz / Release-plz release (push) Failing after 36s
CI / Build (x86_64-unknown-linux-gnu) (push) Successful in 1m18s
Release-plz / Release-plz PR (push) Failing after 32s
Prerelease Test Build / Build (x86_64-unknown-linux-gnu) (push) Failing after 2m4s
Reviewed-on: #7 |
||
|---|---|---|
| .github/workflows | ||
| assets | ||
| crates/esper-relay | ||
| docs | ||
| scripts | ||
| vendor | ||
| .gitignore | ||
| .release-plz.toml | ||
| AGENTS.md | ||
| Cargo.lock | ||
| Cargo.toml | ||
| CHANGELOG.md | ||
| CONTRIBUTING.md | ||
| LICENSE | ||
| Makefile | ||
| README.md | ||
| renovate.json | ||
| rust-toolchain.toml | ||
esper-relay
Secure remote Codex control from your phone
esper-relay keeps
codex app-serverrunning on a machine you trust and gives you a mobile-friendly remote control surface over Tailscale. You get your Codex sessions on your phone, without exposing the host directly to the public internet.
📱 See It First
Thread view, prompt composer, and session controls on a phone-sized screen.
✨ Why It Exists
- Remote Codex access: resume threads, send prompts, and handle approvals from your phone.
- Private by default: keep remote access inside your tailnet instead of opening public ports.
- Host-side supervision: let
esper-relaykeepcodex app-serverrunning instead of managing it manually. - Mobile-first UI: use a touch-friendly web interface instead of remoting into a full desktop.
- Better file links: referenced host files open through the relay instead of dead local filesystem URLs.
📦 Install
crates.io
cargo install esper-relay
If you want a prebuilt archive instead, use GitHub Releases.
🚀 Quick Start
What You Need
- Codex CLI installed and authenticated so
codex app-serverworks on the host machine. - Tailscale installed on the host if you want remote access from your phone.
- Tailscale installed on your phone if you want to use the tailnet URL there.
- Rust and Cargo available for
cargo install.
Local-only setup
esper-relay --daemon
Then open http://127.0.0.1:3000.
Remote setup over Tailscale
Create ~/.config/esper-relay/config.toml:
bind_addr = "127.0.0.1:3500"
ready_timeout_ms = 60000
[tailnet]
enabled = true
hostname = "esper-relay"
listener_mode = "https"
listen_addr = ":443"
advertise_tags = ["tag:esper-relay"]
oauth_client_secret = "tskey-client-REPLACE_ME"
Then start the relay:
esper-relay --daemon
This gives you:
- local access on your configured
bind_addr - tailnet-only
https://<hostname>.<tailnet>.ts.net/access once MagicDNS and tailnet HTTPS are enabled
Stop cleanly
esper-relay --stop
When tailnet.oauth_ephemeral = true, a clean stop logs the ephemeral node out immediately instead of waiting for delayed tailnet cleanup.
🧭 How People Use It
- Run
esper-relayon the machine where Codex lives. - Open the web UI locally or through your tailnet.
- Resume a thread or start a new one from your phone.
- Send prompts, approve actions, and keep the session moving without sitting at the host machine.
⚙️ Configuration
Essentials
~/.config/esper-relay/config.tomlis loaded automatically when it exists.bind_addrcontrols the local web UI address.app_server_cmddefaults tocodex app-server.tailnet.listener_mode = "https"replaces the raw tailnet listener with tailnet-only HTTPS on:443.tailnet.advertise_tagsis required when you usetailnet.oauth_client_secret.tailnet.oauth_ephemeraldefaults totrue; set it tofalseif you want persistent OAuth-derived authkeys instead.
Environment Variables
Full environment variable reference
ESPER_RELAY_BIND(default:127.0.0.1:3000)ESPER_RELAY_APP_SERVER_CMD(default:codex app-server)ESPER_RELAY_READY_TIMEOUT_MS(default:8000)ESPER_RELAY_RESTART_BASE_DELAY_MS(default:500)ESPER_RELAY_RESTART_MAX_DELAY_MS(default:8000)ESPER_RELAY_EVENT_BUFFER(default:256)ESPER_RELAY_TRUSTED_LAN(default:true)ESPER_RELAY_TAILNET_LISTENER_MODE(default:tcp, valid values:tcp,https)ESPER_RELAY_TAILNET_OAUTH_EPHEMERAL(default:true, only applies totailnet.oauth_client_secret)
🛠️ Build Options
GitHub Releases
Stable and prerelease archives are published on GitHub Releases for:
x86_64-unknown-linux-gnuaarch64-unknown-linux-gnux86_64-pc-windows-gnuaarch64-apple-darwin
Build from source
git clone https://github.com/beisel-it/esper-relay.git
cd esper-relay
make run
🔌 Technical Reference
Core Commands
make runmake fmtmake fmt-checkmake clippymake testmake ci-localmake fetch-codex-sourcesmake fetch-themes
API Surface
POST /api/sessionsGET /api/themesGET /api/files/content?path=/absolute/path[&line=n][&column=n]GET /api/sessions/latestGET /api/sessions/{session_id}GET /api/sessions/{session_id}/timelineGET /api/sessions/{session_id}/events(WebSocket)POST /api/sessions/{session_id}/turnsPOST /api/sessions/{session_id}/interruptPOST /api/sessions/{session_id}/approvals/{approval_id}POST /api/sessions/{session_id}/server-requests/{request_id}/respondGET /api/threads?limit=50POST /api/threads/{thread_id}/resume
Approval and tool-input prompts surface the related turn/item context from the app-server payload, and explicit Codex file-reference links are rewritten through the relay so remote users can request host files safely through GET /api/files/content.
Operational Endpoints
GET /healthGET /readyGET /metrics
Repository Layout
.
├── .github/workflows/
├── crates/esper-relay/
├── docs/
├── scripts/
└── vendor/
Codex Source References
- Canonical captures:
docs/sources/codex/ - Latest snapshot metadata:
docs/sources/codex/manifest.json - Primary protocol reference:
docs/sources/codex/snapshots/.../remote/app-server.md
🔐 Maintainers
- Release and publishing details: docs/releasing.md
release-plzmanages release PRs, tagging, and crates.io publish.- Stable binaries are published from
v*tags, and prerelease binaries are published from pushes tomain.