From 5bdb54c80745344bab442fa29a511b71f447f2a7 Mon Sep 17 00:00:00 2001 From: wsp1911 Date: Mon, 29 Jun 2026 18:59:24 +0800 Subject: [PATCH] fix(mcp): route large tool output through shared storage policy Remove the MCP adapter's 12k pre-truncation so oversized MCP tool results can be handled by the shared tool-result storage policy instead. Add coverage to ensure MCP rendering preserves output beyond the old limit before storage budgeting runs. --- .../core/src/service/mcp/adapter/tool.rs | 36 +++++++++++++++---- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/src/crates/assembly/core/src/service/mcp/adapter/tool.rs b/src/crates/assembly/core/src/service/mcp/adapter/tool.rs index d3ce8bdfe8..3b8c25841f 100644 --- a/src/crates/assembly/core/src/service/mcp/adapter/tool.rs +++ b/src/crates/assembly/core/src/service/mcp/adapter/tool.rs @@ -28,8 +28,6 @@ pub struct MCPToolWrapper { } impl MCPToolWrapper { - const MAX_RESULT_TEXT_CHARS: usize = 12_000; - /// Creates a new MCP tool wrapper. pub fn new( mcp_tool: MCPTool, @@ -54,6 +52,12 @@ impl MCPToolWrapper { fn is_blocked_in_context(&self, _context: Option<&ToolUseContext>) -> bool { false } + + // Do not pre-truncate MCP output here. The shared tool-result storage policy + // owns the model-visible budget and persists oversized results with a preview. + fn render_mcp_result_for_assistant(tool_name: &str, result: &MCPToolResult) -> String { + render_mcp_tool_result_for_assistant(tool_name, result, usize::MAX) + } } #[async_trait] @@ -166,11 +170,7 @@ impl Tool for MCPToolWrapper { fn render_result_for_assistant(&self, output: &Value) -> String { if let Ok(result) = serde_json::from_value::(output.clone()) { - return render_mcp_tool_result_for_assistant( - &self.mcp_tool.name, - &result, - Self::MAX_RESULT_TEXT_CHARS, - ); + return Self::render_mcp_result_for_assistant(&self.mcp_tool.name, &result); } "MCP tool execution completed".to_string() @@ -315,3 +315,25 @@ impl Default for MCPToolAdapter { Self::new() } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::service::mcp::protocol::MCPToolResultContent; + + #[test] + fn mcp_tool_result_rendering_does_not_pretruncate_before_storage_policy() { + let text = "x".repeat(12_001); + let result = MCPToolResult { + content: Some(vec![MCPToolResultContent::Text { text: text.clone() }]), + is_error: false, + structured_content: None, + meta: None, + }; + + let rendered = MCPToolWrapper::render_mcp_result_for_assistant("large_output", &result); + + assert_eq!(rendered, text); + assert!(!rendered.contains("[Result truncated:")); + } +}