From 6b0c486861ffcf6e0bbab65697d181985e692ded Mon Sep 17 00:00:00 2001 From: Gabriel Peal Date: Fri, 17 Oct 2025 14:47:50 -0700 Subject: [PATCH] [MCP] Render full MCP errors to the model (#5298) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, the model couldn't see why MCP tool calls failed, many of which were the model using the parameters incorrectly. A common failure is the model stringifying the json for the notion-update-page tool which it then couldn't correct. I want to do some system prompt massaging around this as well. However, it is crucial that the model sees the error so it can fix it. Before: CleanShot 2025-10-17 at 13 02 36 After: CleanShot 2025-10-17 at 13 01 18 🎉 CleanShot 2025-10-17 at 13 09 30 Fixes #4707 --- codex-rs/core/src/mcp_tool_call.rs | 5 ++++- codex-rs/tui/src/history_cell.rs | 7 ++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/codex-rs/core/src/mcp_tool_call.rs b/codex-rs/core/src/mcp_tool_call.rs index 7091a056..21fdaf00 100644 --- a/codex-rs/core/src/mcp_tool_call.rs +++ b/codex-rs/core/src/mcp_tool_call.rs @@ -58,7 +58,10 @@ pub(crate) async fn handle_mcp_tool_call( let result = sess .call_tool(&server, &tool_name, arguments_value.clone()) .await - .map_err(|e| format!("tool call error: {e}")); + .map_err(|e| format!("tool call error: {e:?}")); + if let Err(e) = &result { + tracing::warn!("MCP tool call error: {e:?}"); + } let tool_call_end_event = EventMsg::McpToolCallEnd(McpToolCallEndEvent { call_id: call_id.clone(), invocation, diff --git a/codex-rs/tui/src/history_cell.rs b/codex-rs/tui/src/history_cell.rs index 85acaf9b..0a358257 100644 --- a/codex-rs/tui/src/history_cell.rs +++ b/codex-rs/tui/src/history_cell.rs @@ -854,7 +854,12 @@ impl HistoryCell for McpToolCallCell { } } Err(err) => { - let err_line = Line::from(format!("Error: {err}").dim()); + let err_text = format_and_truncate_tool_result( + &format!("Error: {err}"), + TOOL_CALL_MAX_LINES, + width as usize, + ); + let err_line = Line::from(err_text.dim()); let wrapped = word_wrap_line( &err_line, RtOptions::new((width as usize).saturating_sub(4))