diff --git a/src/gateway/runtime.rs b/src/gateway/runtime.rs index a7557d6..2da441f 100644 --- a/src/gateway/runtime.rs +++ b/src/gateway/runtime.rs @@ -124,10 +124,51 @@ pub(crate) fn build_session_manager_with_sender( factory }; + // Wait for MCP connections and collect MCP tools for subagents + // This needs to happen before building subagent tools + let mut mcp_tools_for_subagents: Vec = Vec::new(); + if mcp_initializer.is_enabled() { + tokio::task::block_in_place(|| { + tokio::runtime::Handle::current().block_on(async { + // Wait for connections to complete + if let Err(e) = mcp_initializer.wait_for_connections().await { + tracing::error!(error = %e, "Failed to wait for MCP connections"); + return; + } + + // Collect MCP tools for subagents + if let Some(manager) = mcp_initializer.manager() { + let all_tools = manager.all_tools().await; + for (server_key, tool_info) in all_tools { + let wrapper = crate::mcp::tool_adapter::McpToolWrapper::new( + manager.clone(), + server_key.clone(), + tool_info, + ); + mcp_tools_for_subagents.push(wrapper); + } + tracing::info!( + tool_count = mcp_tools_for_subagents.len(), + "Collected MCP tools for subagents" + ); + } + }) + }); + } + // Create SubAgentRuntime (if task tool is enabled) let (factory, task_repository): (_, Arc) = if task_config.enabled { let task_repository = Arc::new(InMemoryTaskRepository::new()); - let subagent_tools = Arc::new(factory.build_subagent_tools()); + // Build subagent tools with MCP tools + let subagent_tools = Arc::new( + factory.build_subagent_tools( + if mcp_tools_for_subagents.is_empty() { + None + } else { + Some(mcp_tools_for_subagents.clone()) + } + ) + ); // Create subagent catalog with discovery let catalog = Arc::new(SubagentCatalog::discover(&subagents_config)); @@ -157,14 +198,16 @@ pub(crate) fn build_session_manager_with_sender( // Build base tools let mut tools = factory.build(); - // Register MCP tools (async) - // This waits briefly for connections, then registers available tools + // Register MCP tools to main agent (async) + // Note: MCP tools for subagents are already collected above if mcp_initializer.is_enabled() { tokio::task::block_in_place(|| { tokio::runtime::Handle::current().block_on(async { - if let Err(e) = mcp_initializer.register_tools(&mut tools).await { - tracing::error!(error = %e, "Failed to register MCP tools"); + // Register pre-collected MCP tools + for tool in mcp_tools_for_subagents { + tools.register(tool); } + tracing::info!("Registered MCP tools to main agent"); }) }); } diff --git a/src/gateway/tool_registry_factory.rs b/src/gateway/tool_registry_factory.rs index 3f60d82..69f7c3e 100644 --- a/src/gateway/tool_registry_factory.rs +++ b/src/gateway/tool_registry_factory.rs @@ -142,7 +142,11 @@ impl ToolRegistryFactory { } /// 构建子代理专用工具集(不包含 task 工具防止递归) - pub(crate) fn build_subagent_tools(&self) -> ToolRegistry { + /// 可选地包含 MCP 工具(通过 mcp_tools 参数传递) + pub(crate) fn build_subagent_tools( + &self, + mcp_tools: Option>, + ) -> ToolRegistry { let mut registry = ToolRegistry::new(); // 基础工具 @@ -194,6 +198,13 @@ impl ToolRegistryFactory { registry.register(SessionSendTool::new(self.session_message_sender.clone())); } + // 注册 MCP 工具(如果提供) + if let Some(mcp_tools) = mcp_tools { + for tool in mcp_tools { + registry.register(tool); + } + } + // 注意:不注册 task 工具,防止递归创建子代理 registry diff --git a/src/mcp/tool_adapter.rs b/src/mcp/tool_adapter.rs index 01d6a70..e32441e 100644 --- a/src/mcp/tool_adapter.rs +++ b/src/mcp/tool_adapter.rs @@ -9,6 +9,7 @@ use crate::mcp::client::McpClientManager; use crate::tools::traits::{Tool as PicoBotTool, ToolResult}; /// Wrapper that adapts an MCP tool to PicoBot's Tool trait +#[derive(Clone)] pub struct McpToolWrapper { /// The MCP client manager manager: Arc,