urc — плагин для Claude Code: управление Codex и Gemini с телефона
Связывает панель Codex или Gemini в tmux с Remote Control в приложении Claude на телефоне. Одна команда — и сообщения с телефона идут в другой CLI.
/plugin marketplace add anthropics/claude-plugins-community
/plugin install urc@claude-communityЧто делает urc
URC расширяет /remote-control на чужие CLI. Вы запускаете /urc codex или /urc gemini, плагин поднимает панель в tmux и мостом соединяет её с сессией Remote Control в приложении Claude на телефоне. Сообщение уходит целиком, ответ возвращается как есть. Мост работает через лёгкий Haiku-релей: он сам очищается после 25 отправок, переподключается, если цель умерла, и повторяет отправку до трёх раз. Наберите status — увидите остаток ёмкости и здоровье цели.
Есть режим без вызова модели: строка >codex: сообщение или >gemini: сообщение уходит через хук UserPromptSubmit. Для этого сначала нужно прописать цель: bash urc/core/relay-ctl.sh add codex %NNN && bash urc/core/relay-ctl.sh on. Мостить можно и с другой стороны — скиллом rc-bridge в Codex или командой /rc в Gemini.
Заранее понадобятся tmux, Python 3.10+, jq, Claude CLI и тариф Claude Max для управления с телефона. Gemini CLI требует ручной правки: если в ~/.gemini/settings.json есть белый список tools.allowed, блок "tools" надо убрать, иначе мост не заработает. Проверять список инструментов командой /tools бесполезно — она их намеренно скрывает, смотрите gemini mcp list или /mcp list. Внутри также MCP-сервер urc-coordination с 11 инструментами для обмена сообщениями между панелями через SQLite.
Какие задачи решает
- управлять панелью Codex с телефона, не открывая ноутбук
- подключить уже запущенную панель tmux по её ID
- пережить падение целевой панели без ручного перезапуска
- раздать сообщения между агентами в Claude, Codex и Gemini
- отправлять команды в другой CLI без вызова модели
Примеры запросов агенту
- Запусти Codex и подключи его к телефону:
/urc codex - Подключи уже открытую панель с ID 875:
/urc 875 - Покажи, какие панели ещё не подключены:
/urc
Как установить urc
Через маркетплейс плагинов
/plugin marketplace add anthropics/claude-plugins-community/plugin install urc@claude-communityПо шагам, с командами для каждой платформы: Плагины Claude Code: маркетплейсы, установка и как собрать свой
Вопросы о urc
Как установить urc в Claude Code?
Через маркетплейс: сначала /plugin marketplace add anthropics/claude-plugins-community, затем /plugin install urc@claude-community.
Что делает urc?
Соединяет панель Codex или Gemini в tmux с Remote Control в приложении Claude на телефоне. Сообщения и ответы идут через Haiku-релей без потерь.
Что нужно для работы urc?
tmux, Python 3.10+, jq, Claude CLI и тариф Claude Max для управления с телефона. Codex CLI или Gemini CLI ставятся отдельно — только те, что вы хотите мостить.
Исходный текст
SKILL.md · MIT
# URC — Universal Remote Control
Control Codex and Gemini from the Claude App on your phone.

You know `/remote-control` — the Claude Code feature that lets you control a session from the Claude App on your phone. URC makes it **universal**. One command, and your phone controls Codex. Another command, and it controls Gemini. Same app, same conversation, same interface. No extra API keys. No extra apps.
```bash
/urc codex # Your phone now controls Codex
/urc gemini # Your phone now controls Gemini
```
Behind the scenes, URC spawns a lightweight Haiku relay that acts as a pure passthrough — your messages go through unchanged, output comes back verbatim. The relay is self-managing: it auto-clears, auto-reconnects on target death, and runs indefinitely without intervention.
## Features
**Phone control for every CLI**
- Bridge any Codex or Gemini pane from your phone in one command
- Spawn new panes or bridge existing ones (`/urc 875`)
- Initiate bridges from the other side too (Codex skill or Gemini `/rc` command)
**Self-managing relay**
- Auto-clears at 25 sends — respawns itself, restores phone connection, resets counter
- Auto-reconnects on target death — spawns replacement, retries your message (3 attempts)
- Type **"status"** to check capacity, target health, and respawn count
- No manual maintenance, no `/clear`, no restarts
**Real-time visibility**
- Push attribution shows who dispatched each message and what was asked
- Instant "message received" confirmation when target gets your message
- Responses stream back to your phone as turns complete
**$0 relay mode**
- Type `>codex: message` or `>gemini: message` for hook-based passthrough
- Zero model invocation, zero cost — a `UserPromptSubmit` hook handles dispatch
- Setup: `bash urc/core/relay-ctl.sh add codex %NNN && bash urc/core/relay-ctl.sh on`
**Cross-CLI coordination**
- 11-tool MCP server for pane-level communication (dispatch, read, register, heartbeat, messaging)
- Agents across Claude Code, Codex, and Gemini can send messages, share work, and coordinate
- 5-layer inbox notification stack ensures no message is missed
**Tested and validated**
- 160 assertions across 10 test suites
- 23-check plugin validation
- Post-Enter stuck-input detection for TUI reliability
## Quick Start
### Prerequisites
- **tmux**: `brew install tmux` (macOS) or `sudo apt install tmux` (Linux)
- **Python 3.10+**, **jq**
- **Claude Code CLI**: `curl -fsSL https://claude.ai/install.sh | bash`
- **Claude Max plan** (for phone control — see [claude.com/pricing](https://claude.com/pricing))
- **Codex CLI** and/or **Gemini CLI** (optional — install whichever you want to bridge)
- Codex: `npm install -g @openai/codex`
- Gemini: see [github.com/google-gemini/gemini-cli](https://github.com/google-gemini/gemini-cli)
### Install
```bash
tmux new -s urc # Start a tmux session (required)
git clone https://github.com/siddharthkandan/universal-remote-control
cd universal-remote-control
./setup.sh # Detects your CLIs, generates configs
```
Or install as a Claude Code plugin:
```
/plugin marketplace add siddharthkandan/universal-remote-control
/plugin install urc
```
### Use It
From Claude Code (inside tmux):
```bash
/urc codex # Spawn Codex pane + bridge it to your phone
/urc gemini # Spawn Gemini pane + bridge it to your phone
/urc 875 # Bridge an existing pane by ID
/urc # List unbridged panes
```
Open the **Claude App on your phone** — the relay automatically activates Remote Control. Type a message and it goes straight to Codex or Gemini. Responses stream back as they complete.
Aliases: `/rc-bridge`, `/rc-any`, `/rc-relay` all work.
You can also bridge from the other side:
- **From Codex:** activate the `rc-bridge` skill
- **From Gemini:** type `/rc`
Your Claude plan covers the Haiku relay — no separate API key needed.
### Gemini Setup Note
Gemini CLI requires additional configuration beyond what `setup.sh` generates:
- `setup.sh` creates the project config and policy rules automatically
- If `~/.gemini/settings.json` has a `tools.allowed` whitelist, remove the `"tools"` block
- Verify: `gemini mcp list` (outside session) or `/mcp list` (in session)
- Note: Gemini's `/tools` command intentionally hides MCP tools — don't use it to check
## How It Works
```
Phone (Claude App)
| Remote Control
v
Haiku Relay (rc-bridge agent) ← self-managing, auto-clears at 25 sends
| send.sh push files
| (dispatch) ←———————— (response)
v |
Target pane (tmux) |
| hook.sh fires ———————————┘ ← captures response, writes push file
```
**The relay is a stateless passthrough.** State lives in tmux pane options (`@bridge_target`, `@bridge_cli`, `@bridge_relays`). Dispatch and response reading are handled through a `UserPromptSubmit` hook (`bridge-push-hook.sh`) — the relay's phone message triggers the hook, which dispatches via `send.sh` and reads any pending push files, all without consuming a model turn. When the target completes its turn, `hook.sh` captures the response and writes a push file. The relay picks it up on its next wake and displays it on your phone.
**The MCP server** (`urc-coordination`, 11 tools) provides the cross-pane infrastructure: dispatch messages, read pane output, register agents, track heartbeats, and send/receive async messages via SQLite. Any agent in any CLI can use these tools to coordinate with others.
> A second MCP server (`urc-teams`, 17 tools) provides structured team creation, typed messages, and task dependencies. Currently dormant — the coordination server handles all active messaging.
## Project Structure
> The root directory includes CLI-specific files (`CLAUDE.md`, `AGENTS.md`, `GEMINI.md`, symlinks) because each AI CLI has its own conventions for discovering instructions. All actual code lives in `urc/`.
### Core (`urc/`)
```
urc/
├── core/
│ ├── server.py Coordination MCP server (11 tools)
│ ├── db.py SQLite foundation
│ ├── teams_protocol.py Teams data layer (dormant)
│ ├── teams_server.py Teams MCP server (dormant)
│ ├── send.sh Pane dispatch (bracketed paste + post-Enter verify)
│ ├── hook.sh Turn completion + push attribution + respawn
│ ├── wait.sh Blocking wait with self-wake
│ ├── dispatch-and-wait.sh Atomic dispatch + wait + read
│ ├── cli-adapter.sh CLI detection + paste behavior
│ ├── urc-spawn.sh Fire-and-forget relay+target spawner
│ ├── urc-dispatch.sh ! mode CLI dispatcher
│ ├── urc-status.sh Fleet status display
│ ├── inbox-watcher.sh Background inbox notification
│ ├── circuit.sh Circuit breaker for dispatch failures
│ ├── relay-ctl.sh $0 relay configuration
│ └── test-*.sh 8 test suites (94 assertions)
├── lib/
│ └── state-write.sh Atomic JSON write helper
└── schemas/
└── response.md Response file schema
```
### CLI Integration
| File/Dir | Required by | Purpose |
|----------|-------------|---------|
| `CLAUDE.md` | Claude Code | Agent instructions |
| `AGENTS.md` | Codex | Agent instructions |
| `GEMINI.md` | Gemini | Agent instructions |
| `.claude/agents/` | Claude Code | RC Bridge agent definition |
| `.claude/skills/` | Claude Code | `/urc` command |
| `.claude/hooks/` | Claude Code | Session init + inbox hooks |
| `.agents/skills/` | Codex | Codex bridge skill |
### Plugin System
```
.claude-plugin/plugin.json Plugin manifest
hooks/hooks.json Plugin hooks (Stop + SessionStart)
hooks/scripts/bridge-push-hook.sh Hook-based dispatch + push reading (UserPromptSubmit)
hooks/scripts/plugin-setup.sh Auto-setup on first session
```
## Documentation
- [Getting Started](docs/getting-started.md) — Install, first bridge, tmux basics
- [Architecture Overview](docs/architecture-overview.md) — System design and message flows
- [Turn Completion System](docs/turn-completion-system.md) — Hook signal ordering and response capture
- [Design Decisions](docs/design-decisions.md) — Why things are built this way
- [Teams Protocol](docs/teams-protocol.md) — Structured cross-CLI messaging (dormant)
## Glossary
| Term | What it means |
|------|---------------|
| **Remote Control** | A Claude Code feature that lets you control a session from the Claude App on your phone |
| **MCP** | Model Context Protocol — how AI agents talk to external tools and services |
| **Haiku** | Claude's fastest model — used for the relay since it just passes messages through |
| **tmux** | Terminal multiplexer — runs multiple sessions in panes within one window |
| **Pane** | A terminal session inside tmux, identified by an ID like `%875` |
| **Push** | Response delivery from the target pane back to the relay when a turn completes |
## Troubleshooting
**MCP tools not showing in Gemini?**
Run `gemini mcp list`. If empty, verify `~/.gemini/policies/urc-mcp.toml` exists (created by `setup.sh`). Remove any `tools.allowed` whitelist from `~/.gemini/settings.json`.
**Relay shows "pane does not exist"?**
The target died. Type "status" to confirm, then "reconnect %NNN" with a new pane ID, or let auto-reconnect handle it.
**Text stuck in a pane's input field?**
A TUI timing edge case. `send.sh` retries automatically in most cases. If still stuck, press Enter manually.
**`setup.sh` fails on venv creation?**
Needs Python 3.10+. On some systems: `sudo apt install python3.12-venv`.
**Plugin validation fails?**
Run `bash scripts/validate-plugin.sh` for diagnostics. Most common fix: re-run `setup.sh`.
## Known Issues
### RC session idle timeout (~20 minutes) — [#32982](https://github.com/anthropics/claude-code/issues/32982)
Remote Control sessions are deregistered server-side after ~20 minutes of idle time, even when the local CLI process is alive. This affects ALL `/remote-control` sessions (not just URC relays) and is caused by a keepalive bug in Claude Code:
1. `CLAUDE_CODE_REMOTE` (set internally for all RC sessions) disables the 5-minute WebSocket keepalive
2. `CLAUDE_CODE_REMOTE_SEND_KEEPALIVES` (the replacement) is refcount-gated — only sends keepalives during active model processing, not during idle
3. Result: idle RC sessions have zero keepalive mechanism and the server deregisters them
**Impact on URC:** Relay sessions lose their phone connection after ~20 minutes of inactivity. The relay process stays alive but the phone shows "Disconnected" / "unknown network error."
**Status:** Bug report filed with full source analysis. Waiting for Anthropic's response before implementing workarounds. A watchdog (periodic activity to reset the server-side timer) is the known workaround but is deferred pending upstream clarity.
## Known Limitations
- **Gemini auto-reconnect race:** `send.sh` can report `delivered` for a dying pane. The next message triggers reconnect.
- **Prompt injection surface:** The relay passes phone messages in bash variables via `send.sh`. Low risk (phone user is machine owner), but content is not sanitized.
- **No automated tests for prompt-based features:** Push attribution, auto-reconnect, and the health dashboard are behavioral instructions in the agent prompt, not executable code.
## License
[MIT](LICENSE)
© sidkandan · MIT · sidkandan/universal-remote-control