Expose native /goal lifecycle over the Codex MCP server
Summary
Please expose the native /goal lifecycle through the Codex MCP server.
Today, MCP clients can start Codex with the codex tool and continue a thread with codex-reply, but they cannot set, get, clear, or observe the native persisted goal state that /goal uses. The native goal API exists on the app-server protocol as thread/goal/{set,get,clear} with status, token budget, usage accounting, and lifecycle notifications, but that surface is not reachable over the MCP transport.
Current behavior
The Codex MCP server currently dispatches only standard MCP ClientRequest variants and exposes two tools:
codex-rs/mcp-server/src/message_processor.rs:96-165handles standard MCP requests and returnsMETHOD_NOT_FOUNDfor custom requests.codex-rs/mcp-server/src/message_processor.rs:313-349exposes onlycodexandcodex-replyviatools/listandtools/call.codex-rs/mcp-server/src/codex_tool_runner.rs:324-326explicitly ignoresThreadGoalUpdatedevents in the MCP tool runner.
The native goal API is available in the app-server protocol instead:
codex-rs/app-server-protocol/src/protocol/common.rs:533-546definesthread/goal/set,thread/goal/get, andthread/goal/clear.codex-rs/app-server-protocol/src/protocol/v2/thread.rs:734-832defines the goal object, status, token budget, usage, and request/response payloads.codex-rs/app-server-protocol/src/protocol/common.rs:1618-1619definesthread/goal/updatedandthread/goal/clearednotifications.codex-rs/app-server/src/message_processor.rs:1159-1170routes those app-server requests toThreadGoalRequestProcessor.
So the feature exists, but only behind a different protocol and daemon lifecycle.
Why this matters
MCP-based Codex integrations cannot programmatically use native goals without becoming an MCP-to-app-server bridge. That is much larger and riskier than the integration should need to be, because app-server has a separate stdio/WebSocket protocol and thread lifecycle (thread/start -> thread/goal/set -> turn/start).
For integrations that already rely on the MCP server, this means /goal is effectively unavailable even though the agent can otherwise be started and resumed through MCP.
Workaround
The current workaround is to stay on MCP and inject objective/goal text through developer instructions or prompt conditioning, then advertise the active goal in follow-up turns.
That can steer behavior and persist across codex-reply, but it is not equivalent to the native goal feature:
- no native goal status lifecycle (
active,paused,blocked,complete, etc.) - no token budget or usage accounting
- no
ThreadGoalUpdated/ThreadGoalClearednotifications for MCP clients - no shared persisted goal state that other Codex surfaces can read as a first-class goal
Requested behavior
Expose native goal control over the Codex MCP transport. Any one of these shapes would solve the integration gap:
- add MCP tools such as
codex-goal-set,codex-goal-get, andcodex-goal-clearthat operate on a Codex MCPthreadId - or add goal parameters to the existing
codex/codex-replytools where appropriate - or support an MCP-compatible custom request path for the existing
thread/goal/*operations
The key requirement is that MCP clients can set/get/clear the same persisted native goal state used by /goal, including status and token budget, without switching transports or reimplementing app-server.
Acceptance criteria
- An MCP client can start a Codex thread and set a native goal for that thread through MCP.
- An MCP client can read and clear that goal through MCP.
- Goal status and token budget use the same backing state as app-server
/goal. - Goal update/clear events are exposed to MCP clients in some documented form, or the absence of event streaming is explicitly documented.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗