From 13d866cc5f25bd356ad423c3a64111ba91159b9e Mon Sep 17 00:00:00 2001 From: hexin Date: Fri, 3 Jul 2026 15:32:00 +0800 Subject: [PATCH] fix(mcp): only advertise list-resource meta-tools when resources exist `list_mcp_resources` and `list_mcp_resource_templates` were injected whenever any MCP server was configured, regardless of whether any server actually exposes resources or templates. For tools-only servers this leaves the model with meta-tools that can only ever return empty results, wasting a tool slot and prompt tokens on every request. Gate each meta-tool on its own non-empty collection, mirroring the existing `mcp_read_resource` guard. --- crates/tui/src/mcp.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/crates/tui/src/mcp.rs b/crates/tui/src/mcp.rs index fc70bff3b5..f636cf3a36 100644 --- a/crates/tui/src/mcp.rs +++ b/crates/tui/src/mcp.rs @@ -1915,7 +1915,13 @@ impl McpPool { }); } - if !self.config.servers.is_empty() { + // Only advertise each resource-listing meta-tool when the servers actually + // expose the corresponding kind. Previously both were injected whenever any + // MCP server was configured, so tools-only servers left the model with + // meta-tools that can only ever return empty results — a wasted tool slot + // and prompt tokens. Gate each on its own non-empty collection, mirroring + // the `mcp_read_resource` guard below (`!resources.is_empty()`). + if !self.all_resources().is_empty() { api_tools.push(crate::models::Tool { tool_type: None, name: "list_mcp_resources".to_string(), @@ -1932,6 +1938,8 @@ impl McpPool { strict: None, cache_control: None, }); + } + if !self.all_resource_templates().is_empty() { api_tools.push(crate::models::Tool { tool_type: None, name: "list_mcp_resource_templates".to_string(),