Skip to content

feat: Codex App Server engine — JSON-RPC 2.0 persistent subprocess #49

@dmora

Description

@dmora

Context

Codex CLI ships a proprietary "App Server" protocol — a bidirectional JSON-RPC layer streamed as JSONL over stdio. It powers all Codex surfaces (CLI, VS Code, web, macOS desktop) through a single stable API. This is analogous to what ACP is for OpenCode.

Our current engine/cli/codex uses codex exec --json (spawn-per-turn via Resumer). The App Server protocol would enable persistent multi-turn sessions without cold-starting a new subprocess per turn — same benefit our engine/acp provides for OpenCode.

Protocol details

  • Transport: bidirectional stdio (stdin/stdout) for local clients
  • Format: JSON-RPC streamed as JSONL (newline-delimited JSON)
  • Documentation: OpenAI provides protocol docs + schema generation tools for TypeScript and JSON Schema
  • Source: Available in the open-source Codex CLI repo

Why not ACP?

OpenAI closed the ACP feature request as "not planned". They found MCP semantics inadequate for richer session interactions and built their own protocol instead. Community ACP bridges exist (cola-io/codex-acp) but are wrappers, not native.

Proposal

New engine package: engine/appserver/codex (or engine/codex if it becomes the primary Codex engine).

Architecture

agentrun (interfaces)
├── engine/cli/codex/      ← existing spawn-per-turn (Resumer)
└── engine/appserver/codex/ ← new persistent JSON-RPC subprocess

This would follow the same pattern as engine/acp:

  • Persistent subprocess lifecycle (spawn once, send many)
  • JSON-RPC request/response over stdin/stdout
  • Process.Send() sends user messages as JSON-RPC calls
  • Process.Output() streams responses as they arrive
  • Session state maintained by the subprocess

Benefits over current CLI engine

engine/cli/codex (current) App Server engine (proposed)
Subprocess lifecycle New process per turn Single persistent process
Cold start Every turn Once
MCP servers Cold boot each turn Persistent connections
Multi-turn context Via --resume (disk-based) In-memory session state
Token efficiency Re-reads context each turn Maintains conversation

Research needed

Before implementation:

  1. Protocol spec: Extract the JSON-RPC method names, request/response schemas from the Codex source
  2. Availability: Verify the App Server is available as a standalone mode (not just embedded in IDE extensions)
  3. Stability: Assess whether the protocol is stable enough for a library to depend on (vs. internal/unstable)
  4. Auth: How authentication works in App Server mode vs. CLI exec mode

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions