diff --git a/src-tauri/src/core/mcp/helpers.rs b/src-tauri/src/core/mcp/helpers.rs index 8b2fc0cba..03759dcfa 100644 --- a/src-tauri/src/core/mcp/helpers.rs +++ b/src-tauri/src/core/mcp/helpers.rs @@ -490,7 +490,7 @@ async fn schedule_mcp_start_task( reqwest::Client::builder() .default_headers({ // Map envs to request headers - let mut headers = reqwest::header::HeaderMap::new(); + let mut headers: tauri::http::HeaderMap = reqwest::header::HeaderMap::new(); for (key, value) in config_params.envs.iter() { if let Some(v_str) = value.as_str() { // Try to map env keys to HTTP header names (case-insensitive) @@ -508,6 +508,7 @@ async fn schedule_mcp_start_task( } headers }) + .connect_timeout(config_params.timeout.unwrap_or(Duration::MAX)) .build() .unwrap(), StreamableHttpClientTransportConfig { @@ -572,6 +573,7 @@ async fn schedule_mcp_start_task( } headers }) + .connect_timeout(config_params.timeout.unwrap_or(Duration::MAX)) .build() .unwrap(), rmcp::transport::sse_client::SseClientConfig { @@ -724,12 +726,14 @@ pub fn extract_command_args(config: &Value) -> Option { let args = obj.get("args")?.as_array()?.clone(); let url = obj.get("url").and_then(|u| u.as_str()).map(String::from); let transport_type = obj.get("type").and_then(|t| t.as_str()).map(String::from); + let timeout = obj.get("timeout").and_then(|t| t.as_u64()).map(Duration::from_secs); let envs = obj .get("env") .unwrap_or(&Value::Object(serde_json::Map::new())) .as_object()? .clone(); Some(McpServerConfig { + timeout, transport_type, url, command, diff --git a/src-tauri/src/core/mcp/models.rs b/src-tauri/src/core/mcp/models.rs index 3243935da..049aba1bb 100644 --- a/src-tauri/src/core/mcp/models.rs +++ b/src-tauri/src/core/mcp/models.rs @@ -1,3 +1,5 @@ +use std::time::Duration; + use serde::{Deserialize, Serialize}; use serde_json::Value; @@ -9,6 +11,7 @@ pub struct McpServerConfig { pub command: String, pub args: Vec, pub envs: serde_json::Map, + pub timeout: Option, } /// Tool with server information