Skip to content

codex_sdk: route MCP servers into Codex.Thread #175

@WiggidyW

Description

@WiggidyW

Context

The codex_sdk upstream client plumbs MCP server config end-to-end on the Rust side — McpServerConfig { url, headers } is built from the per-agent objectiveai::mcp::Connection and shipped on every run line via RunParams.mcp_servers. The Python runner currently ignores this field; see the NOTE(MCP) comment in objectiveai-codex-sdk-runner-py/main.py::handle_run.

This issue tracks wiring params.mcp_servers into the actual codex Thread so codex agents can call MCP tools.

Why it's deferred

The codex Python SDK's Codex.start_thread / resume_thread and Thread.run_streamed don't expose an MCP-server knob — the SDK's ThreadOptions / TurnOptions types have no field for it. The codex CLI binary itself supports MCP via ~/.codex/config.toml, but that's process-wide config, not per-thread.

Options

  1. Per-call config.toml synthesis — write a temporary ~/.codex/config.toml (or --config <path>) snippet before each Thread.run_streamed, scoped to the request's tempdir. Concurrency-hostile: codex reads its config at process start, so this would force a fresh codex subprocess per turn (defeating part of the multiplex win).

  2. Wait for SDK support — file an upstream issue / PR on openai-codex-sdk adding an mcp_servers field to ThreadOptions that propagates to the spawned codex exec invocation. Cleanest path; outside our control.

  3. Bypass the SDK — invoke the codex binary directly with our own arguments. Loses the SDK's event-streaming wrapper and forces us to re-implement ThreadEvent parsing.

Recommend #2 (waiting / upstream PR) unless we hit a customer with hard MCP requirements; in that case fall back to #1 with a per-request subprocess.

Touchpoints when we do wire it up

  • objectiveai-codex-sdk-runner-py/main.py::handle_run — replace the NOTE(MCP) comment with the actual MCP plumbing.
  • Optionally relax the _validate_run_params check if mcp_servers becomes required.
  • No Rust-side changes expected — RunParams.mcp_servers already serializes the right shape.
  • Re-test that codex_sdk::McpServerConfig::from(&Connection) produces the correct headers (Mcp-Session-Id, Authorization, User-Agent, X-Title, Referer/HTTP-Referer) for whatever consumer ends up reading them.

Out of scope

  • MCP wiring for codex_sdk agents only. Claude / OpenRouter MCP routing is unchanged.
  • The agent-level mcp_servers field on objectiveai::agent::codex_sdk::AgentBase is already declared and validated; this issue is about runtime routing only.

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