App Server: peer-client co-presence with the live TUI thread (RFC)

Resolved 💬 5 comments Opened May 7, 2026 by parkertoddbrooks Closed May 7, 2026
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

Summary

We are building a remote rich client for a local Codex TUI session. The goal is not to run a second Codex agent and not to scrape terminal pixels. The goal is for a second local client to attach to the same live Codex thread as the TUI, hydrate history, receive streamed thread events, start or steer turns when appropriate, and surface approvals or Stop state through the same App Server protocol.

The public App Server docs describe codex app-server as the interface for rich clients that need conversation history, approvals, and streamed agent events. That sounds like the right layer, but we want to confirm the intended architecture before preparing a formal PR.

Docs reference:
https://developers.openai.com/codex/app-server

We are not asking about exposing the experimental App Server WebSocket transport to the public internet. The question here is the local App Server peer-client semantics for a live TUI thread.

Related public issues:

Architecture

flowchart TD
    subgraph Local["User machine: local Codex runtime"]
        TUI["Codex TUI\nCodex-owned\nLocal interactive client"]
        AppServer["Codex App Server\nCodex-owned\nProposed peer-client surface"]
        Peer["External peer client\nIntegration-owned\nLocal App Server client"]

        TUI <--> AppServer
        AppServer <--> Peer
    end

    subgraph Transport["Optional external transport"]
        Relay["Encrypted frame transport\nNot runtime authority"]
    end

    subgraph Remote["Remote UI"]
        UI["Browser or mobile client\nThread mirror, not terminal pixels"]
    end

    Peer <--> Relay
    Relay <--> UI

In our proof, Codex still runs locally. The external client is a peer client of App Server, not a second Codex runner. Any hosted transport outside the machine only carries encrypted client frames and is not authoritative over Codex runtime state.

What we observed

With stock App Server, a separate client can initialize, resume a stored thread, hydrate persisted history, and start a turn.

With stock App Server, full co-presence was not observed in our tested build: an additional observer did not reliably receive a normal TUI-originated turn stream, and an App Server-started turn was not live-rendered back through the active TUI/browser path as one shared event bus.

With a narrow local Codex patch that adds multi-subscriber live thread event fanout, we observed full co-presence across three surfaces: TUI, desktop web, and phone web. The demo video shows three originating turns, one from each surface, each appearing live on the other two. Three originations, two observers each, no handoff, no terminal mirror.

That suggests the missing primitive may be multi-subscriber live thread events, not a product-specific remote-control feature.

Demo artifacts:

Demo video (MP4): TUI, desktop web, and phone web on the same thread, three originating turns

!Static still from the WIP Remote Control Coherence demo

Static still note: captured at the end of the recording after one client had disconnected; the live three-way flow is in the video.

Codex-only patch shape

We have a narrow local branch based on upstream main that only changes Codex-side event fanout:

  • add an event fanout in CodexThread;
  • let legacy callers keep using next_event();
  • let App Server listener tasks subscribe independently;
  • add a websocket App Server test where two clients resume the same thread, one starts a turn, and both receive matching turn notifications.

Touched files:

codex-rs/core/src/codex_thread.rs
codex-rs/app-server/src/request_processors/thread_lifecycle.rs
codex-rs/app-server/tests/suite/v2/connection_handling_websocket.rs

This branch does not include any hosted relay code, browser UI, mobile UI, install flow, or product-specific protocol.

Patch branch: https://github.com/wipcomputer/codex/tree/cc-mini/app-server-multi-listener-rfc
Compare: https://github.com/openai/codex/compare/main...wipcomputer:codex:cc-mini/app-server-multi-listener-rfc

Question

Is App Server intended to support this kind of live peer-client co-presence with the Codex TUI?

If yes, is multi-subscriber live thread event fanout the right direction for an upstream PR, or is there a different App Server surface OpenAI wants external rich clients to use for attaching to the active TUI thread?

Happy to iterate on patch shape, prepare a formal upstream PR under Apache-2.0, or redirect to a different App Server surface if maintainers indicate the intended direction.

View original on GitHub ↗

5 Comments

github-actions[bot] contributor · 3 months ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #19887
  • #20344
  • #20757
  • #21177

Powered by Codex Action

parkertoddbrooks · 3 months ago

Thanks bot. Flagging the distinction so a triager can decide quickly:

I do not think this is a duplicate of #9224 / #19887 / #20344 / #20757. Those are user feature requests aggregating demand for "Remote Control / mobile companion."

This RFC is a different artifact class: a working patch, a public branch, a 30-second demo of three-way co-presence, and a specific question about which App Server surface is the intended one for trusted local peer clients.

The body cites #9224 as the demand signal; this issue is the implementer-side question on top of that.

Of the flagged issues, #21177 is the closest adjacent issue. It is open, it is about the same app-server thread refresh surface, and it suggests Codex Desktop may be hitting a related multi-subscriber refresh edge. Not a duplicate of this RFC, but a useful pointer for whoever picks this up.

Happy to close if maintainers point us at the right venue: a discussion, an existing internal RFC thread, or #9224 itself if that is where they want this kind of patch-shaped contribution to land. Otherwise the question stands: is App Server the intended surface for live TUI peer-client co-presence?

etraut-openai contributor · 3 months ago

There is a current assumption that only one client will interact with a thread at a time. For example, if you start a thread in the TUI and then start the desktop app, it is assumed that you'll close the thread in the TUI before interacting with it (sending it a new prompt) in the desktop app. This is because each client starts a new instance of the app server, and these instances currently don't talk to each other. I don't know if that affects your use case.

In any case, I'm going to close this issue since it's a question rather than a feature request. Feel free to post additional questions to the discussion forum.

parkertoddbrooks · 3 months ago

@etraut-openai Thanks, that does answer the core architecture question.

Yes, the current "one active client per thread" assumption directly affects this use case. The goal here is explicit live co-presence: a TUI-owned local thread with a trusted peer client attached at the same time, so phone/browser and TUI can observe and send through the same live thread rather than handing ownership between clients.

Our patched fork takes the smallest delta from the per-instance model: it makes a single App Server instance multi-listener, broadcasting events to N peer clients on one underlying CodexThread. That is why the 3-way demo works without a second runner or terminal mirroring.

Given the "currently don't talk to each other" framing, the real product question seems to be whether OpenAI's direction is:

  1. keep per-instance App Server ownership and add an inter-instance sync layer, or
  2. move toward a shared App Server instance with multi-listener semantics.

Our patch is one shape of option 2. Either path could resolve co-presence, but they have different security and lifecycle implications.

I’ll move follow-up questions to the discussion forum as suggested. Thanks again for the substantive read.

parkertoddbrooks · 3 months ago

Moved the follow-up architecture question to Discussions as suggested:

https://github.com/openai/codex/discussions/21558

Thanks again for clarifying the current App Server model in this issue.