-
Notifications
You must be signed in to change notification settings - Fork 5.5k
fix: separate codex mcp
into codex mcp-server
and codex app-server
#4471
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
session_configured, | ||
.. | ||
}) => { | ||
let event = Event { | ||
id: "".to_string(), | ||
msg: EventMsg::SessionConfigured(session_configured.clone()), | ||
}; | ||
self.outgoing.send_event_as_notification(&event, None).await; | ||
self.outgoing | ||
.send_server_notification(ServerNotification::SessionConfigured( | ||
SessionConfiguredNotification { | ||
session_id: session_configured.session_id, | ||
model: session_configured.model.clone(), | ||
reasoning_effort: session_configured.reasoning_effort, | ||
history_log_id: session_configured.history_log_id, | ||
history_entry_count: session_configured.history_entry_count, | ||
initial_messages: session_configured.initial_messages.clone(), | ||
rollout_path: session_configured.rollout_path.clone(), | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resumed conversations no longer emit
codex/event/session_configured
The new resume_conversation
path now sends a ServerNotification::SessionConfigured
JSON‑RPC notification (method: "sessionConfigured"
) instead of reusing send_event_as_notification
to emit the standard codex/event/session_configured
event. There is no code anywhere in the repo that listens for sessionConfigured
(searching for SessionConfiguredNotification
or the method name returns nothing outside this file), while numerous consumers handle session initialization via EventMsg::SessionConfigured
routed through the generic codex/event
handler. This means a client resuming a conversation will no longer receive the expected session_configured event and will miss metadata like history log IDs, breaking any UI logic that depends on that event. Consider continuing to publish the event via the existing codex/event
path (possibly in addition to the new notification) or updating clients to handle the new method.
Useful? React with 👍 / 👎.
9a7aeeb
to
32e0d6e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall, LGTM. Left a few comments and decently skimmed the whole thing. I'm okay if you want to land this and then iterate.
Since we already have codex mcp
, should this be codex mcp start-server
?
Ok(()) | ||
} | ||
|
||
/// Send a `newConversation` JSON-RPC request. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These comments seem a bit redundant
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair point, though this is from the original version:
/// Send a `newConversation` JSON-RPC request. |
use std::process::Command as StdCommand; | ||
use tokio::process::Command; | ||
|
||
pub struct McpProcess { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you sure you want to call this McpProcess?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't, but from the PR body:
Because this is already a large diff, I tried not to change more than I had to, so codex-rs/app-server/tests/common/mcp_process.rs still uses the name McpProcess for now, but I will do some mechanical renamings to things like AppServer in subsequent PRs.
} | ||
|
||
async fn send_jsonrpc_message(&mut self, message: JSONRPCMessage) -> anyhow::Result<()> { | ||
eprintln!("writing message to stdin: {message:?}"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you mean to leave this in?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, these are in the existing codex-rs/mcp-server/tests/common/mcp_process.rs
that this is taken from. Note this is a test utility, so it's not that bad that they're here.
If we want to remove them, we should probably do it from both the app-server
and mcp-server
versions.
I don't think we should have |
Agree! |
This is a very large PR with some non-backwards-compatible changes.
Historically,
codex mcp
(orcodex mcp serve
) started a JSON-RPC-ish server that had two overlapping responsibilities:This PR aims to separate these into distinct concepts:
codex mcp-server
for the MCP servercodex app-server
for the "application server"Note
codex mcp
still exists because it already has its own subcommands for MCP management (list
,add
, etc.)The MCP logic continues to live in
codex-rs/mcp-server
whereas the refactored app server logic is in the newcodex-rs/app-server
folder. Note that most of the existing integration tests incodex-rs/mcp-server/tests/suite
were actually for the app server, so all the tests have been moved with the exception ofcodex-rs/mcp-server/tests/suite/mod.rs
.Because this is already a large diff, I tried not to change more than I had to, so
codex-rs/app-server/tests/common/mcp_process.rs
still uses the nameMcpProcess
for now, but I will do some mechanical renamings to things likeAppServer
in subsequent PRs.While
mcp-server
andapp-server
share some overlapping functionality (like reading streams of JSONL and dispatching based on message types) and some differences (completely different message types), I ended up doing a bit of copypasta between the two crates, as both have somewhat similarmessage_processor.rs
andoutgoing_message.rs
files for now, though I expect them to diverge more in the near future.One material change is that of the initialize handshake for
codex app-server
, as we no longer use the MCP types for that handshake. Instead, we updatecodex-rs/protocol/src/mcp_protocol.rs
to add anInitialize
variant toClientRequest
, which takes theClientInfo
object we need to update theUSER_AGENT_SUFFIX
incodex-rs/app-server/src/message_processor.rs
.One other material change is in
codex-rs/app-server/src/codex_message_processor.rs
where I eliminated a use of thesend_event_as_notification()
method I am generally trying to deprecate (because it blindly maps anEventMsg
into aJSONNotification
) in favor ofsend_server_notification()
, which takes aServerNotification
, as that is intended to be a custom enum of all notification types supported by the app server. So to make this update, I had to introduce a new variant ofServerNotification
,SessionConfigured
, which is a non-backwards compatible change with the oldcodex mcp
, and clients will have to be updated after the next release that contains this PR. Note thatcodex-rs/app-server/tests/suite/list_resume.rs
also had to be update to reflect this change.I introduced
codex-rs/utils/json-to-toml/src/lib.rs
as a small utility crate to avoid some of the copying betweenmcp-server
andapp-server
.