mirror of
https://github.com/openai/codex.git
synced 2026-04-28 08:34:54 +00:00
feat: add threadId to MCP server messages (#9192)
This favors `threadId` instead of `conversationId` so we use the same terms as https://developers.openai.com/codex/sdk/. To test the local build: ``` cd codex-rs cargo build --bin codex npx -y @modelcontextprotocol/inspector ./target/debug/codex mcp-server ``` I sent: ```json { "method": "tools/call", "params": { "name": "codex", "arguments": { "prompt": "favorite ls option?" }, "_meta": { "progressToken": 0 } } } ``` and got: ```json { "content": [ { "type": "text", "text": "`ls -lah` (or `ls -alh`) — long listing, includes dotfiles, human-readable sizes." } ], "structuredContent": { "threadId": "019bbb20-bff6-7130-83aa-bf45ab33250e" } } ``` and successfully used the `threadId` in the follow-up with the `codex-reply` tool call: ```json { "method": "tools/call", "params": { "name": "codex-reply", "arguments": { "prompt": "what is the long versoin", "threadId": "019bbb20-bff6-7130-83aa-bf45ab33250e" }, "_meta": { "progressToken": 1 } } } ``` whose response also has the `threadId`: ```json { "content": [ { "type": "text", "text": "Long listing is `ls -l` (adds permissions, owner/group, size, timestamp)." } ], "structuredContent": { "threadId": "019bbb20-bff6-7130-83aa-bf45ab33250e" } } ``` Fixes https://github.com/openai/codex/issues/3712.
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
use codex_core::config::Config;
|
||||
use codex_core::config::ConfigOverrides;
|
||||
use codex_core::protocol::AskForApproval;
|
||||
use codex_protocol::ThreadId;
|
||||
use codex_protocol::config_types::SandboxMode;
|
||||
use codex_utils_json_to_toml::json_to_toml;
|
||||
use mcp_types::Tool;
|
||||
@@ -185,13 +186,36 @@ impl CodexToolCallParam {
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct CodexToolCallReplyParam {
|
||||
/// The conversation id for this Codex session.
|
||||
pub conversation_id: String,
|
||||
/// DEPRECATED: use threadId instead.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
conversation_id: Option<String>,
|
||||
|
||||
/// The thread id for this Codex session.
|
||||
/// This field is required, but we keep it optional here for backward
|
||||
/// compatibility for clients that still use conversationId.
|
||||
#[serde(default, skip_serializing_if = "Option::is_none")]
|
||||
thread_id: Option<String>,
|
||||
|
||||
/// The *next user prompt* to continue the Codex conversation.
|
||||
pub prompt: String,
|
||||
}
|
||||
|
||||
impl CodexToolCallReplyParam {
|
||||
pub(crate) fn get_thread_id(&self) -> anyhow::Result<ThreadId> {
|
||||
if let Some(thread_id) = &self.thread_id {
|
||||
let thread_id = ThreadId::from_string(thread_id)?;
|
||||
Ok(thread_id)
|
||||
} else if let Some(conversation_id) = &self.conversation_id {
|
||||
let thread_id = ThreadId::from_string(conversation_id)?;
|
||||
Ok(thread_id)
|
||||
} else {
|
||||
Err(anyhow::anyhow!(
|
||||
"either threadId or conversationId must be provided"
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Builds a `Tool` definition for the `codex-reply` tool-call.
|
||||
pub(crate) fn create_tool_for_codex_tool_call_reply_param() -> Tool {
|
||||
let schema = SchemaSettings::draft2019_09()
|
||||
@@ -217,8 +241,7 @@ pub(crate) fn create_tool_for_codex_tool_call_reply_param() -> Tool {
|
||||
input_schema: tool_input_schema,
|
||||
output_schema: None,
|
||||
description: Some(
|
||||
"Continue a Codex conversation by providing the conversation id and prompt."
|
||||
.to_string(),
|
||||
"Continue a Codex conversation by providing the thread id and prompt.".to_string(),
|
||||
),
|
||||
annotations: None,
|
||||
}
|
||||
@@ -317,20 +340,23 @@ mod tests {
|
||||
let tool = create_tool_for_codex_tool_call_reply_param();
|
||||
let tool_json = serde_json::to_value(&tool).expect("tool serializes");
|
||||
let expected_tool_json = serde_json::json!({
|
||||
"description": "Continue a Codex conversation by providing the conversation id and prompt.",
|
||||
"description": "Continue a Codex conversation by providing the thread id and prompt.",
|
||||
"inputSchema": {
|
||||
"properties": {
|
||||
"conversationId": {
|
||||
"description": "The conversation id for this Codex session.",
|
||||
"description": "DEPRECATED: use threadId instead.",
|
||||
"type": "string"
|
||||
},
|
||||
"prompt": {
|
||||
"description": "The *next user prompt* to continue the Codex conversation.",
|
||||
"type": "string"
|
||||
},
|
||||
"threadId": {
|
||||
"description": "The thread id for this Codex session. This field is required, but we keep it optional here for backward compatibility for clients that still use conversationId.",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"conversationId",
|
||||
"prompt",
|
||||
],
|
||||
"type": "object",
|
||||
|
||||
Reference in New Issue
Block a user