Send a prompt from TeamX Messages and your real Claude Code or Codex session on your laptop runs it. Replies stream back into the chat bubble live. The agent runs with --dangerously-skip-permissions and --yolo so there's nothing to confirm — work just happens.
You send a DM in TeamX → an edge function HMAC-signs the payload and POSTs it to your laptop's loopback listener → the listener pipes the prompt straight into your running claude or codex process. Streaming output flows back the same path into the chat bubble.
The listener long-polls TeamX from your laptop — no inbound ports, no webhook URL, no ngrok tunnel. Works through every firewall because it uses the same outbound HTTPS your browser uses.
Prompts land in a server-side queue scoped to your member id + agent type. Your laptop claims them via SELECT … FOR UPDATE SKIP LOCKED so two pollers never pick up the same prompt.
You can only DM your own agents. The relay enforces this in SQL: target bot owner_member_id must equal sender_member_id. Cross-member remote control is impossible.
Remote control rides on the same connection as the regular agent watcher. If you haven't connected yet, follow the Connect Agent guide first.
The listener long-polls TeamX for prompts. No loopback server, no NAT traversal, works from any network — behind a corporate proxy, on coffee-shop Wi-Fi, wherever. One command per agent type.
# Claude Code
npx @teamx-sh/agent listen --agent=claude-code
# Codex
npx @teamx-sh/agent listen --agent=codexIn the dashboard, open Messages. Your local agents appear as DM peers — Echo for Claude Code, Bolt for Codex. Send a message and it hits your CLI within a second or two.
As Claude Code or Codex produces tokens, they append into the same reply message live. No refresh — Supabase Realtime keeps the bubble in sync.
Click "+ New chat" in the DM header to start a fresh conversation with the same agent. Each DM channel gets its own session so Claude Code and Codex can keep separate contexts — "refactor session", "debug session", "demo prep" — without them bleeding into one another.
Yes. The whole point of remote control is zero friction — if every prompt asked you to confirm, the round-trip would be slower than just opening the terminal yourself. The safety net is that the agent only accepts prompts from you, signed with a secret only your laptop knows. If you want a per-prompt gate, pass --require-consent to the listener.
No. The relay edge function checks that the bot you’re messaging is owned by you (metadata.owner_member_id == your member_id). Other people see the bot in the team but cannot send to it through the remote-control path.
TeamX considers you online when the listener has polled within the last two minutes. If it hasn’t, the DM gets a system reply telling you to run the listener — your prompt isn’t silently dropped. Start the listener and DM again.
Each DM channel carries its own session_id in its metadata. When you click "+ New chat", a fresh channel + fresh session is spawned. The listener maintains one --resume context per session, so two DMs can be live at the same time without their replies mixing.
No. The prompt text goes from TeamX to your laptop. Whatever the agent does — file edits, git commits, npm installs — happens entirely on your machine. Only the agent’s reply text streams back into the chat bubble.
Ctrl+C in the terminal running the listener. The webhook URL is cleared from agent_connections immediately so the bot shows offline in TeamX.
Yes: --port=N. Default tries 5555, falls back through 5599.
Open the dashboard, copy the listener command from the Connect Agent page, and paste it on your laptop.