Skip to content
Back to skills

Codex Cross Session

ASecurity

Use when reaching an existing Codex session — codex queue, codex agents, remote-control start/pair, --remote, or a queued message that never arrives.

  • 2 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 4, 2026
ai-agentsbashsql

Works with

  • claude code
  • cli
  • mcp

Security analysis

A100/100

Scanned October 4, 2026

npx -y skills add Getty/skills --skill codex-cross-session --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Codex Cross Session?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Codex Cross Session
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/getty-codex-cross-session/badge)](https://www.skillsdirectory.com/skills/getty-codex-cross-session)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: codex-cross-session
description: "Use when reaching an existing Codex session — codex queue, codex agents, remote-control start/pair, --remote, or a queued message that never arrives."
---

# Reaching Other Codex Sessions

Codex sessions do not talk to each other. They share a **daemon** — one local
app-server that owns the running threads — and a **queue** that holds messages
until a thread picks them up. Anything you send is a letter, never a
conversation: there is no reply channel back to the sender.

Facts below verified against codex-cli 0.153.0 driving a 0.148.0 on a second
host; the versions do not have to match.

## The queue is a letterbox

```bash
codex queue --thread <uuid|thread-name> --message "Mach erst die Tests grün"
# Queued message 01a06fe5-…-53c3bfdd324d for thread 01a06fe4-…-7423bb04ccc0.
```

The thread does **not** have to be running. A message for a finished thread is
accepted and parked in `~/.codex/queue_1.sqlite` (table `queued_items`), and the
next time that thread is picked up the message is played in **before** whatever
prompt you pass then. Measured: queue "merke dir 99" onto a stopped thread, then
`codex exec resume <id> "nenne alle Zahlen"` — the run answers the queued
message first, then the new prompt with both numbers, and the queue is empty
after.

That ordering is the whole design. Use the queue for an instruction that must
land before the next turn, never for a question you want answered now — nothing
comes back to you, and nothing tells you it was read except the emptied queue
and the thread's own transcript.

The thread id comes from `thread.started` in `codex exec --json`
(see `codex-headless`); a thread name works in its place.

## Seeing what runs

`codex agents` browses the sessions on the shared local app-server daemon. It is
an interactive browser — **there is no `--json`**, so it is for you to look at,
not for a script to parse. When a script needs the id, keep the `thread_id` from
the run that created it.

## The daemon, and what "remote" means here

```bash
codex remote-control start --json
# {"mode":"daemon","status":"connected","serverName":"reuben",
#  "environmentId":"env_e_…","daemon":{"remoteControlEnabled":true,
#  "socketPath":"~/.codex/app-server-control/app-server-control.sock",…}}
codex remote-control pair --json     # {"pairingCode":"…","expiresAt":1788584345}
codex remote-control stop
```

`start` brings up the daemon and connects it; `serverName` defaults to the
hostname. `pair` mints a **short-lived** pairing code — it expires, so mint it
when you are about to use it.

The client side is an address, not an account:

```
--remote ws://host:port | wss://host:port | unix://PATH
--remote-auth-token-env <ENV_VAR>     # bearer token, by env var name
```

This is the significant difference from Claude Code, where cross-machine reach
is keyed to the *account*, so a host you can ssh into gives you nothing by
itself (see `claude-cross-session`). Here the daemon is addressable, and ssh is
enough — including against a Codex that belongs to somebody else's login:

```bash
ssh host 'codex app-server daemon start'      # prints socketPath as JSON
ssh -f -N -L /tmp/cdx.sock:/home/<user>/.codex/app-server-control/app-server-control.sock host
codex queue --remote unix:///tmp/cdx.sock --thread <id> --message "…"
```

**Keep the local socket path short.** `sockaddr_un` holds 108 characters, and
ssh rejects anything longer with `Bad local forwarding specification` — which
names the path and not the reason. A scratch directory deep under `/tmp` will
already be too long.

No token is involved on this path: reaching the socket at all is the
authorisation, and the ssh account's file permissions decide that.
`--remote-auth-token-env` belongs to the `ws://`/`wss://` endpoints.

Measured end to end: a thread created on the second host under a different
account, a message queued into it from the first host through the tunnel, and a
`codex exec resume` over there answering with both numbers — the queued one and
the local one. Remember to stop the daemon (`codex app-server daemon stop`) and
drop the tunnel afterwards.

## Codex as a tool for another agent

`codex mcp-server` runs Codex as an MCP server over stdio, which is how another
agent uses Codex as one of its tools rather than as a peer. That is a different
relationship from everything above and belongs in the client's MCP config.

## Related

- `codex-headless` — creating threads with `codex exec`, the JSONL events, and
  where the `thread_id` comes from.
- `claude-cross-session` — the same problem in Claude Code, solved with a live
  socket mesh and real two-way messages instead of a queue.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…