mirror of
https://github.com/openai/codex.git
synced 2026-10-28 18:58:46 +00:00
update
This commit is contained in:
@@ -1213,12 +1213,16 @@
|
||||
"server": {
|
||||
"type": "string"
|
||||
},
|
||||
"threadId": {
|
||||
"type": "string"
|
||||
},
|
||||
"uri": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"server",
|
||||
"threadId",
|
||||
"uri"
|
||||
],
|
||||
"type": "object"
|
||||
|
||||
@@ -8785,12 +8785,16 @@
|
||||
"server": {
|
||||
"type": "string"
|
||||
},
|
||||
"threadId": {
|
||||
"type": "string"
|
||||
},
|
||||
"uri": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"server",
|
||||
"threadId",
|
||||
"uri"
|
||||
],
|
||||
"title": "McpResourceReadParams",
|
||||
|
||||
@@ -5599,12 +5599,16 @@
|
||||
"server": {
|
||||
"type": "string"
|
||||
},
|
||||
"threadId": {
|
||||
"type": "string"
|
||||
},
|
||||
"uri": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"server",
|
||||
"threadId",
|
||||
"uri"
|
||||
],
|
||||
"title": "McpResourceReadParams",
|
||||
|
||||
@@ -4,12 +4,16 @@
|
||||
"server": {
|
||||
"type": "string"
|
||||
},
|
||||
"threadId": {
|
||||
"type": "string"
|
||||
},
|
||||
"uri": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"server",
|
||||
"threadId",
|
||||
"uri"
|
||||
],
|
||||
"title": "McpResourceReadParams",
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
|
||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
||||
|
||||
export type McpResourceReadParams = { server: string, uri: string, };
|
||||
export type McpResourceReadParams = { threadId: string, server: string, uri: string, };
|
||||
|
||||
@@ -1972,6 +1972,7 @@ pub struct ListMcpServerStatusResponse {
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct McpResourceReadParams {
|
||||
pub thread_id: String,
|
||||
pub server: String,
|
||||
pub uri: String,
|
||||
}
|
||||
|
||||
@@ -187,7 +187,7 @@ Example with notification opt-out:
|
||||
- `tool/requestUserInput` — prompt the user with 1–3 short questions for a tool call and return their answers (experimental).
|
||||
- `config/mcpServer/reload` — reload MCP server config from disk and queue a refresh for loaded threads (applied on each thread's next active turn); returns `{}`. Use this after editing `config.toml` without restarting the server.
|
||||
- `mcpServerStatus/list` — enumerate configured MCP servers with their tools, resources, resource templates, and auth status; supports cursor+limit pagination.
|
||||
- `mcpResource/read` — read a resource from a configured MCP server by `server` and `uri`, returning the resource `contents`.
|
||||
- `mcpResource/read` — read a resource from a thread's configured MCP server by `threadId`, `server`, and `uri`, returning the resource `contents`.
|
||||
- `windowsSandbox/setupStart` — start Windows sandbox setup for the selected mode (`elevated` or `unelevated`); accepts an optional absolute `cwd` to target setup for a specific workspace, returns `{ started: true }` immediately, and later emits `windowsSandbox/setupCompleted`.
|
||||
- `feedback/upload` — submit a feedback report (classification + optional reason/logs, conversation_id, and optional `extraLogFiles` attachments array); returns the tracking thread id.
|
||||
- `config/read` — fetch the effective config on disk after resolving config layering.
|
||||
|
||||
@@ -224,7 +224,6 @@ use codex_core::mcp::auth::discover_supported_scopes;
|
||||
use codex_core::mcp::auth::resolve_oauth_scopes;
|
||||
use codex_core::mcp::collect_mcp_snapshot;
|
||||
use codex_core::mcp::group_tools_by_server;
|
||||
use codex_core::mcp::read_mcp_resource;
|
||||
use codex_core::models_manager::collaboration_mode_presets::CollaborationModesConfig;
|
||||
use codex_core::parse_cursor;
|
||||
use codex_core::plugins::MarketplaceError;
|
||||
@@ -5141,8 +5140,8 @@ impl CodexMessageProcessor {
|
||||
params: McpResourceReadParams,
|
||||
) {
|
||||
let outgoing = Arc::clone(&self.outgoing);
|
||||
let config = match self.load_latest_config(/*fallback_cwd*/ None).await {
|
||||
Ok(config) => config,
|
||||
let (_, thread) = match self.load_thread(¶ms.thread_id).await {
|
||||
Ok(thread) => thread,
|
||||
Err(error) => {
|
||||
self.outgoing.send_error(request_id, error).await;
|
||||
return;
|
||||
@@ -5150,7 +5149,7 @@ impl CodexMessageProcessor {
|
||||
};
|
||||
|
||||
tokio::spawn(async move {
|
||||
let result = read_mcp_resource(&config, ¶ms.server, ¶ms.uri).await;
|
||||
let result = thread.read_mcp_resource(¶ms.server, ¶ms.uri).await;
|
||||
match result {
|
||||
Ok(result) => match serde_json::from_value::<McpResourceReadResponse>(result) {
|
||||
Ok(response) => {
|
||||
|
||||
@@ -22,6 +22,7 @@ use codex_protocol::protocol::SessionSource;
|
||||
use codex_protocol::protocol::TokenUsage;
|
||||
use codex_protocol::protocol::W3cTraceContext;
|
||||
use codex_protocol::user_input::UserInput;
|
||||
use rmcp::model::ReadResourceRequestParams;
|
||||
use std::path::PathBuf;
|
||||
use tokio::sync::Mutex;
|
||||
use tokio::sync::watch;
|
||||
@@ -198,6 +199,26 @@ impl CodexThread {
|
||||
self.codex.thread_config_snapshot().await
|
||||
}
|
||||
|
||||
pub async fn read_mcp_resource(
|
||||
&self,
|
||||
server: &str,
|
||||
uri: &str,
|
||||
) -> anyhow::Result<serde_json::Value> {
|
||||
let result = self
|
||||
.codex
|
||||
.session
|
||||
.read_resource(
|
||||
server,
|
||||
ReadResourceRequestParams {
|
||||
meta: None,
|
||||
uri: uri.to_string(),
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(serde_json::to_value(result)?)
|
||||
}
|
||||
|
||||
pub fn enabled(&self, feature: Feature) -> bool {
|
||||
self.codex.enabled(feature)
|
||||
}
|
||||
|
||||
@@ -14,20 +14,16 @@ use codex_protocol::mcp::ResourceTemplate;
|
||||
use codex_protocol::mcp::Tool;
|
||||
use codex_protocol::protocol::McpListToolsResponseEvent;
|
||||
use codex_protocol::protocol::SandboxPolicy;
|
||||
use rmcp::model::ReadResourceRequestParams;
|
||||
use serde_json::Value;
|
||||
use tokio_util::sync::CancellationToken;
|
||||
|
||||
use crate::AuthManager;
|
||||
use crate::CodexAuth;
|
||||
use crate::config::Config;
|
||||
use crate::config::types::McpServerConfig;
|
||||
use crate::config::types::McpServerTransportConfig;
|
||||
use crate::mcp::auth::McpAuthStatusEntry;
|
||||
use crate::mcp::auth::compute_auth_statuses;
|
||||
use crate::mcp_connection_manager::McpConnectionManager;
|
||||
use crate::mcp_connection_manager::SandboxState;
|
||||
use crate::mcp_connection_manager::ToolInfo;
|
||||
use crate::mcp_connection_manager::codex_apps_tools_cache_key;
|
||||
use crate::plugins::PluginCapabilitySummary;
|
||||
use crate::plugins::PluginsManager;
|
||||
@@ -281,52 +277,6 @@ fn effective_mcp_servers(
|
||||
}
|
||||
|
||||
pub async fn collect_mcp_snapshot(config: &Config) -> McpListToolsResponseEvent {
|
||||
let (mcp_connection_manager, cancel_token, auth_status_entries) =
|
||||
new_mcp_connection_manager(config).await;
|
||||
if !mcp_connection_manager.has_servers() {
|
||||
cancel_token.cancel();
|
||||
return McpListToolsResponseEvent {
|
||||
tools: HashMap::new(),
|
||||
resources: HashMap::new(),
|
||||
resource_templates: HashMap::new(),
|
||||
auth_statuses: HashMap::new(),
|
||||
};
|
||||
}
|
||||
|
||||
let snapshot =
|
||||
collect_mcp_snapshot_from_manager(&mcp_connection_manager, auth_status_entries).await;
|
||||
|
||||
cancel_token.cancel();
|
||||
|
||||
snapshot
|
||||
}
|
||||
|
||||
pub async fn read_mcp_resource(config: &Config, server: &str, uri: &str) -> anyhow::Result<Value> {
|
||||
let (mcp_connection_manager, cancel_token, _auth_status_entries) =
|
||||
new_mcp_connection_manager(config).await;
|
||||
|
||||
let result = mcp_connection_manager
|
||||
.read_resource(
|
||||
server,
|
||||
ReadResourceRequestParams {
|
||||
meta: None,
|
||||
uri: uri.to_string(),
|
||||
},
|
||||
)
|
||||
.await;
|
||||
|
||||
cancel_token.cancel();
|
||||
|
||||
Ok(serde_json::to_value(result?)?)
|
||||
}
|
||||
|
||||
async fn new_mcp_connection_manager(
|
||||
config: &Config,
|
||||
) -> (
|
||||
McpConnectionManager,
|
||||
CancellationToken,
|
||||
HashMap<String, McpAuthStatusEntry>,
|
||||
) {
|
||||
let auth_manager = AuthManager::shared(
|
||||
config.codex_home.clone(),
|
||||
/*enable_codex_api_key_env*/ false,
|
||||
@@ -337,13 +287,12 @@ async fn new_mcp_connection_manager(
|
||||
let mcp_servers = mcp_manager.effective_servers(config, auth.as_ref());
|
||||
let tool_plugin_provenance = mcp_manager.tool_plugin_provenance(config);
|
||||
if mcp_servers.is_empty() {
|
||||
let cancel_token = CancellationToken::new();
|
||||
cancel_token.cancel();
|
||||
return (
|
||||
McpConnectionManager::new_uninitialized(&config.permissions.approval_policy),
|
||||
cancel_token,
|
||||
HashMap::new(),
|
||||
);
|
||||
return McpListToolsResponseEvent {
|
||||
tools: HashMap::new(),
|
||||
resources: HashMap::new(),
|
||||
resource_templates: HashMap::new(),
|
||||
auth_statuses: HashMap::new(),
|
||||
};
|
||||
}
|
||||
|
||||
let auth_status_entries =
|
||||
@@ -352,6 +301,7 @@ async fn new_mcp_connection_manager(
|
||||
let (tx_event, rx_event) = unbounded();
|
||||
drop(rx_event);
|
||||
|
||||
// Use ReadOnly sandbox policy for MCP snapshot collection (safest default)
|
||||
let sandbox_state = SandboxState {
|
||||
sandbox_policy: SandboxPolicy::new_read_only_policy(),
|
||||
codex_linux_sandbox_exe: config.codex_linux_sandbox_exe.clone(),
|
||||
@@ -372,7 +322,12 @@ async fn new_mcp_connection_manager(
|
||||
)
|
||||
.await;
|
||||
|
||||
(mcp_connection_manager, cancel_token, auth_status_entries)
|
||||
let snapshot =
|
||||
collect_mcp_snapshot_from_manager(&mcp_connection_manager, auth_status_entries).await;
|
||||
|
||||
cancel_token.cancel();
|
||||
|
||||
snapshot
|
||||
}
|
||||
|
||||
pub fn split_qualified_tool_name(qualified_name: &str) -> Option<(String, String)> {
|
||||
@@ -404,21 +359,6 @@ pub fn group_tools_by_server(
|
||||
grouped
|
||||
}
|
||||
|
||||
fn get_mcp_snapshot_tool_name(tool: &ToolInfo) -> String {
|
||||
if tool.server_name != CODEX_APPS_MCP_SERVER_NAME {
|
||||
format!(
|
||||
"{}{}{}{}{}",
|
||||
MCP_TOOL_NAME_PREFIX,
|
||||
MCP_TOOL_NAME_DELIMITER,
|
||||
tool.server_name,
|
||||
MCP_TOOL_NAME_DELIMITER,
|
||||
tool.tool_name
|
||||
)
|
||||
} else {
|
||||
format!("{}{}", tool.tool_namespace, tool.tool_name)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn collect_mcp_snapshot_from_manager(
|
||||
mcp_connection_manager: &McpConnectionManager,
|
||||
auth_status_entries: HashMap<String, crate::mcp::auth::McpAuthStatusEntry>,
|
||||
@@ -436,22 +376,16 @@ pub(crate) async fn collect_mcp_snapshot_from_manager(
|
||||
|
||||
let tools = tools
|
||||
.into_iter()
|
||||
.filter_map(|(_name, tool)| match serde_json::to_value(&tool.tool) {
|
||||
.filter_map(|(name, tool)| match serde_json::to_value(tool.tool) {
|
||||
Ok(value) => match Tool::from_mcp_value(value) {
|
||||
Ok(tool_value) => Some((get_mcp_snapshot_tool_name(&tool), tool_value)),
|
||||
Ok(tool) => Some((name, tool)),
|
||||
Err(err) => {
|
||||
tracing::warn!(
|
||||
"Failed to convert MCP tool '{}': {err}",
|
||||
get_mcp_snapshot_tool_name(&tool)
|
||||
);
|
||||
tracing::warn!("Failed to convert MCP tool '{name}': {err}");
|
||||
None
|
||||
}
|
||||
},
|
||||
Err(err) => {
|
||||
tracing::warn!(
|
||||
"Failed to serialize MCP tool '{}': {err}",
|
||||
get_mcp_snapshot_tool_name(&tool)
|
||||
);
|
||||
tracing::warn!("Failed to serialize MCP tool '{name}': {err}");
|
||||
None
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user