Can the Codex CC Plugin Be Run Without Broker Mode? A Complete Guide to Direct Mode
Yes, the Codex CC plugin can run without broker mode by default, using direct mode to spawn a fresh Codex app-server process for each request.
The openai/codex-plugin-cc repository supports two transport architectures: a lightweight direct mode that spawns ephemeral app-server processes, and an optional broker mode that maintains persistent connections. By default, the plugin operates entirely without the broker infrastructure, making it ideal for environments where long-running background processes are undesirable or impossible.
How Direct Mode Works in the Codex CC Plugin
Direct mode is the default operational path in the Codex CC plugin. When no broker endpoint is specified, the system automatically instantiates a SpawnedCodexAppServerClient that manages the lifecycle of a child process running codex app-server.
The Client Factory Logic in app-server.mjs
The decision between direct and broker mode occurs in plugins/codex/scripts/lib/app-server.mjs. The code first attempts to resolve a broker endpoint through multiple fallback mechanisms:
const brokerEndpoint = options.brokerEndpoint ?? options.env?.[BROKER_ENDPOINT_ENV] ?? process.env[BROKER_ENDPOINT_ENV] ?? null;
if (!brokerEndpoint && options.reuseExistingBroker) {
brokerEndpoint = loadBrokerSession(cwd)?.endpoint ?? null;
}
if (!brokerEndpoint && !options.reuseExistingBroker) {
const brokerSession = await ensureBrokerSession(cwd, { env: options.env });
brokerEndpoint = brokerSession?.endpoint ?? null;
}
const client = brokerEndpoint ? new BrokerCodexAppServerClient(...) : new SpawnedCodexAppServerClient(...);
When brokerEndpoint remains null—which occurs when no environment variable is set and no existing session is requested—the factory returns a SpawnedCodexAppServerClient, activating direct mode.
The SpawnedCodexAppServerClient Implementation
The SpawnedCodexAppServerClient class, defined in the same file, explicitly sets its transport mode and manages process spawning:
class SpawnedCodexAppServerClient extends AppServerClientBase {
constructor(cwd, options = {}) {
super(cwd, options);
this.transport = "direct";
}
// ... spawns codex app-server as child process
}
This class handles the full lifecycle of the Codex app-server, from initialization to teardown, without requiring any socket files, PID tracking, or the broker.json state file used by the broker architecture.
When Does the Plugin Use Broker Mode?
Broker mode is opt-in. The plugin only consults the broker infrastructure when one of the following conditions is met:
- Environment variable: The
CODEX_COMPANION_APP_SERVER_ENDPOINTvariable is exported (referenced internally asBROKER_ENDPOINT_ENV) - Explicit transport: The caller passes
transport: "broker"in the options object - Session reuse: The
reuseExistingBrokerflag is set totrueand a valid broker session exists
If none of these conditions are satisfied, the plugin falls back to the SpawnedCodexAppServerClient, ensuring zero broker dependencies.
Practical Implementation: Running Without a Broker
Operating the Codex CC plugin without broker mode requires no special configuration. Simply omit the broker-specific environment variables and flags.
Command-Line Usage
To run the plugin directly without any broker infrastructure:
# No environment variables needed
codex-companion.mjs start --cwd /my/project
This command spawns a fresh Codex app-server process for the session, executes the requested operations, and automatically terminates the server when finished. No broker.json files or Unix sockets are created.
Programmatic Usage
When integrating the plugin into Node.js applications, instantiate the client without providing a brokerEndpoint:
import { CodexAppServerClient } from "./plugins/codex/scripts/lib/app-server.mjs";
// Direct mode is selected automatically when brokerEndpoint is omitted
const client = new CodexAppServerClient("/my/project", {
env: process.env,
reuseExistingBroker: false // Ensure no existing broker session is picked up
});
await client.initialize(); // Spawns a fresh Codex app-server process
This approach guarantees isolation between requests, as each instantiation creates a separate process tree.
Disabling Broker via Environment
If your environment happens to have CODEX_COMPANION_APP_SERVER_ENDPOINT set but you wish to force direct mode, unset the variable before execution:
unset CODEX_COMPANION_APP_SERVER_ENDPOINT
codex-companion.mjs start --cwd /my/project
With the variable cleared, the plugin cannot locate a broker endpoint and defaults to spawning its own server process.
Key Source Files and Architecture
Understanding the direct mode implementation requires familiarity with these specific files in the openai/codex-plugin-cc repository:
plugins/codex/scripts/lib/app-server.mjs– Contains the main client factory logic, theSpawnedCodexAppServerClientclass for direct mode, and theBrokerCodexAppServerClientclass for broker modeplugins/codex/scripts/lib/broker-lifecycle.mjs– Implements broker session creation, teardown, and theBROKER_STATE_FILE("broker.json") persistence logic; only invoked when a broker endpoint is presentplugins/codex/scripts/lib/broker-endpoint.mjs– Handles parsing and validation of broker endpoint strings (e.g.,unix:/path/to/broker.sock)plugins/codex/scripts/app-server-broker.mjs– The standalone entrypoint for the persistent broker process (run asnode ... app-server-broker.mjs serve ...); not required for direct modeplugins/codex/commands/setup.md– Documentation referencing theCODEX_COMPANION_APP_SERVER_ENDPOINTenvironment variable that enables broker mode
Summary
- Direct mode is the default: The Codex CC plugin automatically runs without a broker when no endpoint is specified
- No configuration required: Simply omit
CODEX_COMPANION_APP_SERVER_ENDPOINTand broker flags to use direct mode - Process isolation: Direct mode spawns a fresh
codex app-serverprocess viaSpawnedCodexAppServerClientfor each session - Zero broker files: Direct mode does not create
broker.jsonstate files or Unix sockets - Opt-in broker: Broker mode requires explicit environment variables, transport options, or session reuse flags
Frequently Asked Questions
How do I know if the plugin is running in direct mode or broker mode?
Check the transport property of the client instance. In plugins/codex/scripts/lib/app-server.mjs, the SpawnedCodexAppServerClient explicitly sets this.transport = "direct", while broker clients use a different transport identifier. You can also inspect process listings: direct mode shows ephemeral codex app-server child processes, whereas broker mode maintains a persistent process via app-server-broker.mjs.
Does running without broker mode affect performance?
Direct mode incurs a startup cost for spawning the codex app-server process per request, while broker mode maintains a persistent connection. However, direct mode eliminates the complexity of managing broker.json state files and socket cleanup, making it more reliable for short-lived tasks and CI/CD environments where process isolation is preferred.
Can I switch between modes without changing code?
Yes. The plugin respects the CODEX_COMPANION_APP_SERVER_ENDPOINT environment variable (exported as BROKER_ENDPOINT_ENV in the source). Setting this variable enables broker mode; unsetting it forces direct mode. This allows you to toggle transport strategies via environment configuration without modifying the underlying JavaScript implementation.
What happens to the broker.json file when running in direct mode?
The broker.json file (defined as BROKER_STATE_FILE in plugins/codex/scripts/lib/broker-lifecycle.mjs) is never created or consulted in direct mode. This file only tracks active broker sessions when using ensureBrokerSession() or loadBrokerSession(). Direct mode via SpawnedCodexAppServerClient manages process lifecycles internally without external state persistence.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →