Skip to content

Commit 2a002b7

Browse files
committed
fix: ensure output of codex-rs/mcp-types/generate_mcp_types.py matches codex-rs/mcp-types/src/lib.rs
1 parent 8d76608 commit 2a002b7

File tree

7 files changed

+37
-21
lines changed

7 files changed

+37
-21
lines changed

codex-rs/core/src/mcp_connection_manager.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use anyhow::Result;
1717
use anyhow::anyhow;
1818
use codex_mcp_client::McpClient;
1919
use mcp_types::ClientCapabilities;
20-
use mcp_types::McpClientInfo;
20+
use mcp_types::Implementation;
2121
use mcp_types::Tool;
2222

2323
use serde_json::json;
@@ -159,10 +159,14 @@ impl McpConnectionManager {
159159
// indicates this should be an empty object.
160160
elicitation: Some(json!({})),
161161
},
162-
client_info: McpClientInfo {
162+
client_info: Implementation {
163163
name: "codex-mcp-client".to_owned(),
164164
version: env!("CARGO_PKG_VERSION").to_owned(),
165165
title: Some("Codex".into()),
166+
// This field is used by Codex when it is an MCP
167+
// server: it should not be used when Codex is
168+
// an MCP client.
169+
user_agent: None,
166170
},
167171
protocol_version: mcp_types::MCP_SCHEMA_VERSION.to_owned(),
168172
};

codex-rs/mcp-client/src/main.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ use anyhow::Context;
1717
use anyhow::Result;
1818
use codex_mcp_client::McpClient;
1919
use mcp_types::ClientCapabilities;
20+
use mcp_types::Implementation;
2021
use mcp_types::InitializeRequestParams;
2122
use mcp_types::ListToolsRequestParams;
2223
use mcp_types::MCP_SCHEMA_VERSION;
23-
use mcp_types::McpClientInfo;
2424
use tracing_subscriber::EnvFilter;
2525

2626
#[tokio::main]
@@ -60,10 +60,13 @@ async fn main() -> Result<()> {
6060
sampling: None,
6161
elicitation: None,
6262
},
63-
client_info: McpClientInfo {
63+
client_info: Implementation {
6464
name: "codex-mcp-client".to_owned(),
6565
version: env!("CARGO_PKG_VERSION").to_owned(),
6666
title: Some("Codex".to_string()),
67+
// This field is used by Codex when it is an MCP server: it should
68+
// not be used when Codex is an MCP client.
69+
user_agent: None,
6770
},
6871
protocol_version: MCP_SCHEMA_VERSION.to_owned(),
6972
};

codex-rs/mcp-server/src/message_processor.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ impl MessageProcessor {
234234
},
235235
instructions: None,
236236
protocol_version: params.protocol_version.clone(),
237-
server_info: mcp_types::McpServerInfo {
237+
server_info: mcp_types::Implementation {
238238
name: "codex-mcp-server".to_string(),
239239
version: env!("CARGO_PKG_VERSION").to_string(),
240240
title: Some("Codex".to_string()),

codex-rs/mcp-server/tests/common/mcp_process.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,13 @@ use codex_protocol::mcp_protocol::SendUserTurnParams;
2626

2727
use mcp_types::CallToolRequestParams;
2828
use mcp_types::ClientCapabilities;
29+
use mcp_types::Implementation;
2930
use mcp_types::InitializeRequestParams;
3031
use mcp_types::JSONRPC_VERSION;
3132
use mcp_types::JSONRPCMessage;
3233
use mcp_types::JSONRPCNotification;
3334
use mcp_types::JSONRPCRequest;
3435
use mcp_types::JSONRPCResponse;
35-
use mcp_types::McpClientInfo;
3636
use mcp_types::ModelContextProtocolNotification;
3737
use mcp_types::ModelContextProtocolRequest;
3838
use mcp_types::RequestId;
@@ -134,10 +134,11 @@ impl McpProcess {
134134
roots: None,
135135
sampling: None,
136136
},
137-
client_info: McpClientInfo {
137+
client_info: Implementation {
138138
name: "elicitation test".into(),
139139
title: Some("Elicitation Test".into()),
140140
version: "0.0.0".into(),
141+
user_agent: None,
141142
},
142143
protocol_version: mcp_types::MCP_SCHEMA_VERSION.into(),
143144
};

codex-rs/mcp-types/generate_mcp_types.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,8 +265,11 @@ class StructField:
265265
name: str
266266
type_name: str
267267
serde: str | None = None
268+
comment: str | None = None
268269

269270
def append(self, out: list[str], supports_const: bool) -> None:
271+
if self.comment:
272+
out.append(f" // {self.comment}\n")
270273
if self.serde:
271274
out.append(f" {self.serde}\n")
272275
if self.viz == "const":
@@ -312,6 +315,18 @@ def define_struct(
312315
else:
313316
fields.append(StructField("pub", rs_prop.name, prop_type, rs_prop.serde))
314317

318+
# Special-case: add Codex-specific user_agent to Implementation
319+
if name == "Implementation":
320+
fields.append(
321+
StructField(
322+
"pub",
323+
"user_agent",
324+
"Option<String>",
325+
'#[serde(default, skip_serializing_if = "Option::is_none")]',
326+
"This is an extra field that the Codex MCP server sends as part of InitializeResult.",
327+
)
328+
)
329+
315330
if implements_request_trait(name):
316331
add_trait_impl(name, "ModelContextProtocolRequest", fields, out)
317332
elif implements_notification_trait(name):

codex-rs/mcp-types/src/lib.rs

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -482,20 +482,12 @@ pub struct ImageContent {
482482

483483
/// Describes the name and version of an MCP implementation, with an optional title for UI representation.
484484
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, TS)]
485-
pub struct McpClientInfo {
486-
pub name: String,
487-
#[serde(default, skip_serializing_if = "Option::is_none")]
488-
pub title: Option<String>,
489-
pub version: String,
490-
}
491-
492-
/// Describes the name and version of an MCP implementation, with an optional title for UI representation.
493-
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, TS)]
494-
pub struct McpServerInfo {
485+
pub struct Implementation {
495486
pub name: String,
496487
#[serde(default, skip_serializing_if = "Option::is_none")]
497488
pub title: Option<String>,
498489
pub version: String,
490+
// This is an extra field that the Codex MCP server sends as part of InitializeResult.
499491
#[serde(default, skip_serializing_if = "Option::is_none")]
500492
pub user_agent: Option<String>,
501493
}
@@ -513,7 +505,7 @@ impl ModelContextProtocolRequest for InitializeRequest {
513505
pub struct InitializeRequestParams {
514506
pub capabilities: ClientCapabilities,
515507
#[serde(rename = "clientInfo")]
516-
pub client_info: McpClientInfo,
508+
pub client_info: Implementation,
517509
#[serde(rename = "protocolVersion")]
518510
pub protocol_version: String,
519511
}
@@ -527,7 +519,7 @@ pub struct InitializeResult {
527519
#[serde(rename = "protocolVersion")]
528520
pub protocol_version: String,
529521
#[serde(rename = "serverInfo")]
530-
pub server_info: McpServerInfo,
522+
pub server_info: Implementation,
531523
}
532524

533525
impl From<InitializeResult> for serde_json::Value {

codex-rs/mcp-types/tests/suite/initialize.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
use mcp_types::ClientCapabilities;
22
use mcp_types::ClientRequest;
3+
use mcp_types::Implementation;
34
use mcp_types::InitializeRequestParams;
45
use mcp_types::JSONRPC_VERSION;
56
use mcp_types::JSONRPCMessage;
67
use mcp_types::JSONRPCRequest;
7-
use mcp_types::McpClientInfo;
88
use mcp_types::RequestId;
99
use serde_json::json;
1010

@@ -58,10 +58,11 @@ fn deserialize_initialize_request() {
5858
sampling: None,
5959
elicitation: None,
6060
},
61-
client_info: McpClientInfo {
61+
client_info: Implementation {
6262
name: "acme-client".into(),
6363
title: Some("Acme".to_string()),
6464
version: "1.2.3".into(),
65+
user_agent: None,
6566
},
6667
protocol_version: "2025-06-18".into(),
6768
}

0 commit comments

Comments
 (0)