mirror of
https://github.com/openai/codex.git
synced 2026-10-29 19:08:43 +00:00
Stop exposing Codex context to direct MCP servers
Direct user-configured and plugin MCP servers sit outside the managed connector trust boundary, but Codex currently attaches its raw turn, thread, workspace, plugin, and trace metadata to their tool calls. That leaks host implementation context to arbitrary servers and makes direct egress broader than its intended MCP contract. Introduce a source-derived direct_mcp_v1 profile and enforce it again at the final connection-manager boundary. Direct calls now omit host-generated context and strip reserved OpenAI/Codex metadata supplied through app-server calls while retaining ordinary MCP metadata and sandbox state only when the server negotiated that capability. Compatibility and extension registrations retain host-owned behavior. Hoopa still depends on threadId for its legacy per-thread routing and is registered as an ordinary config server, so temporarily reserve the exact logical name hoopa as host-owned. This is intentional migration debt rather than a trust signal; it can be removed once Hoopa moves to a trusted registration or no longer routes through request metadata. Move authoritative hosted thread metadata behind the profile boundary and remove tests and fixtures that asserted direct servers receive the now-private context.
This commit is contained in:
@@ -1,7 +1,5 @@
|
||||
use super::*;
|
||||
|
||||
const MCP_TOOL_THREAD_ID_META_KEY: &str = "threadId";
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct McpRequestProcessor {
|
||||
auth_manager: Arc<AuthManager>,
|
||||
@@ -460,12 +458,11 @@ impl McpRequestProcessor {
|
||||
let outgoing = Arc::clone(&self.outgoing);
|
||||
let thread_id = params.thread_id.clone();
|
||||
let (_, thread) = self.load_thread(&thread_id).await?;
|
||||
let meta = with_mcp_tool_call_thread_id_meta(params.meta, &thread_id);
|
||||
let request_id = request_id.clone();
|
||||
|
||||
tokio::spawn(async move {
|
||||
let result = thread
|
||||
.call_mcp_tool(¶ms.server, ¶ms.tool, params.arguments, meta)
|
||||
.call_mcp_tool(¶ms.server, ¶ms.tool, params.arguments, params.meta)
|
||||
.await
|
||||
.map(McpServerToolCallResponse::from)
|
||||
.map_err(|error| internal_error(format!("{error:#}")));
|
||||
@@ -474,27 +471,3 @@ impl McpRequestProcessor {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn with_mcp_tool_call_thread_id_meta(
|
||||
meta: Option<serde_json::Value>,
|
||||
thread_id: &str,
|
||||
) -> Option<serde_json::Value> {
|
||||
match meta {
|
||||
Some(serde_json::Value::Object(mut map)) => {
|
||||
map.insert(
|
||||
MCP_TOOL_THREAD_ID_META_KEY.to_string(),
|
||||
serde_json::Value::String(thread_id.to_string()),
|
||||
);
|
||||
Some(serde_json::Value::Object(map))
|
||||
}
|
||||
None => {
|
||||
let mut map = serde_json::Map::new();
|
||||
map.insert(
|
||||
MCP_TOOL_THREAD_ID_META_KEY.to_string(),
|
||||
serde_json::Value::String(thread_id.to_string()),
|
||||
);
|
||||
Some(serde_json::Value::Object(map))
|
||||
}
|
||||
other => other,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,11 +122,9 @@ url = "{mcp_server_url}/mcp"
|
||||
)
|
||||
.await??;
|
||||
let ThreadStartResponse { thread, .. } = to_response(thread_start_resp)?;
|
||||
let thread_id = thread.id.clone();
|
||||
|
||||
let tool_call_request_id = mcp
|
||||
.send_mcp_server_tool_call_request(McpServerToolCallParams {
|
||||
thread_id: thread_id.clone(),
|
||||
thread_id: thread.id,
|
||||
server: TEST_SERVER_NAME.to_string(),
|
||||
tool: TEST_TOOL_NAME.to_string(),
|
||||
arguments: Some(json!({
|
||||
@@ -154,7 +152,6 @@ url = "{mcp_server_url}/mcp"
|
||||
response.structured_content,
|
||||
Some(json!({
|
||||
"echoed": "hello from app",
|
||||
"threadId": thread_id,
|
||||
}))
|
||||
);
|
||||
assert_eq!(response.is_error, Some(false));
|
||||
@@ -736,13 +733,6 @@ impl ServerHandler for ToolAppsMcpServer {
|
||||
.and_then(|arguments| arguments.get("message"))
|
||||
.and_then(|value| value.as_str())
|
||||
.unwrap_or_default();
|
||||
let thread_id = context
|
||||
.meta
|
||||
.0
|
||||
.get("threadId")
|
||||
.and_then(|value| value.as_str())
|
||||
.unwrap_or_default();
|
||||
|
||||
let mut meta = Meta::new();
|
||||
meta.0.insert("calledBy".to_string(), json!("mcp-app"));
|
||||
|
||||
@@ -810,7 +800,6 @@ impl ServerHandler for ToolAppsMcpServer {
|
||||
|
||||
let mut result = CallToolResult::structured(json!({
|
||||
"echoed": message,
|
||||
"threadId": thread_id,
|
||||
}));
|
||||
result.content = vec![Content::text(format!("echo: {message}"))];
|
||||
result.meta = Some(meta);
|
||||
|
||||
Reference in New Issue
Block a user