From 0e1c636b8f0b774f81798af51e27d398d3054fba Mon Sep 17 00:00:00 2001 From: Jean Mertz Date: Mon, 2 Feb 2026 06:45:34 +0100 Subject: [PATCH 1/2] refactor(cli, mcp): use `HashSet` for active MCP server IDs Update the MCP server configuration logic to use a `HashSet` instead of a `Vec` when identifying active servers. This change ensures that each unique MCP server is only processed once, preventing potential duplicate connections. The `run_services` method in `jp_mcp` now accepts an owned `HashSet`, reducing the need for explicit cloning during the service startup loop. Additionally, this commit fixes a logging bug in the MCP environment variable loader by correctly using `inspect_err` and formatting the error output. Signed-off-by: Jean Mertz --- crates/jp_cli/src/ctx.rs | 7 ++++--- crates/jp_mcp/src/client.rs | 11 +++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/crates/jp_cli/src/ctx.rs b/crates/jp_cli/src/ctx.rs index c471da58..adb4e608 100644 --- a/crates/jp_cli/src/ctx.rs +++ b/crates/jp_cli/src/ctx.rs @@ -1,4 +1,5 @@ use std::{ + collections::HashSet, io::{self, IsTerminal as _}, sync::Arc, }; @@ -124,7 +125,7 @@ impl Ctx { pub(crate) async fn configure_active_mcp_servers( &mut self, ) -> Result>> { - let mut server_ids = vec![]; + let mut server_ids = HashSet::new(); for (name, cfg) in self.config.conversation.tools.iter() { if !cfg.enable() { @@ -145,11 +146,11 @@ impl Ctx { } }; - server_ids.push(server_id); + server_ids.insert(server_id); } self.mcp_client - .run_services(&server_ids, self.handle().clone()) + .run_services(server_ids, self.handle().clone()) .await .map_err(Into::into) } diff --git a/crates/jp_mcp/src/client.rs b/crates/jp_mcp/src/client.rs index 4775c1ff..2838f96c 100644 --- a/crates/jp_mcp/src/client.rs +++ b/crates/jp_mcp/src/client.rs @@ -174,7 +174,7 @@ impl Client { pub async fn run_services( &mut self, - server_ids: &[McpServerId], + server_ids: HashSet, handle: Handle, ) -> Result>> { let mut clients = self.services.write().await; @@ -195,7 +195,7 @@ impl Client { for server_id in server_ids { // Determine which servers to start (in configs but not currently // active) - if clients.contains_key(server_id) { + if clients.contains_key(&server_id) { continue; } @@ -204,7 +204,6 @@ impl Client { joins.spawn({ let servers = self.servers.clone(); let clients = self.services.clone(); - let server_id = server_id.clone(); async move { let servers = servers.read().await; let server = servers @@ -243,11 +242,11 @@ impl Client { .iter() .filter_map(|key| { env::var(key) - .inspect(|error| { + .inspect_err(|error| { warn!( key, - error, - server = %id, + error = error.to_string(), + server = id.to_string(), "Failed to read MCP server environment variable" ); }) From a820765a25361212eeae2d3e58f5ecc7bc0a734f Mon Sep 17 00:00:00 2001 From: Jean Mertz Date: Mon, 2 Feb 2026 06:50:18 +0100 Subject: [PATCH 2/2] fixup! refactor(cli, mcp): use `HashSet` for active MCP server IDs Signed-off-by: Jean Mertz --- crates/jp_mcp/src/client.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/crates/jp_mcp/src/client.rs b/crates/jp_mcp/src/client.rs index 2838f96c..723db508 100644 --- a/crates/jp_mcp/src/client.rs +++ b/crates/jp_mcp/src/client.rs @@ -1,4 +1,11 @@ -use std::{collections::HashMap, env, path::Path, process::Stdio, sync::Arc, time::Duration}; +use std::{ + collections::{HashMap, HashSet}, + env, + path::Path, + process::Stdio, + sync::Arc, + time::Duration, +}; use indexmap::IndexMap; use jp_config::providers::mcp::{AlgorithmConfig, McpProviderConfig};