From 09151e37efd09616a9badac2523d51e8fe4a4f17 Mon Sep 17 00:00:00 2001 From: Timmy Date: Tue, 21 Apr 2026 12:15:04 +0100 Subject: [PATCH] Fix gateway bot Claude Code cwd so MCP tools are discovered In gateway mode the bot's Claude Code CLI was spawned with cwd set to a nonexistent project subdirectory (gateway_config_dir/project_name). This meant it couldn't find .mcp.json and had no MCP tools available. Now the bot uses the gateway config directory as cwd in gateway mode, where the auto-generated .mcp.json points to the gateway's MCP proxy. Also fixes cargo fmt formatting. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../src/chat/transport/matrix/bot/context.rs | 5 +++- .../src/chat/transport/matrix/bot/messages.rs | 24 ++++++++++++------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/server/src/chat/transport/matrix/bot/context.rs b/server/src/chat/transport/matrix/bot/context.rs index b964a864..1cb67a97 100644 --- a/server/src/chat/transport/matrix/bot/context.rs +++ b/server/src/chat/transport/matrix/bot/context.rs @@ -114,7 +114,10 @@ impl BotContext { match client.post(&url).json(&body).send().await { Ok(resp) if resp.status().is_success() => { match resp.json::().await { - Ok(json) => json.get("response").and_then(|v| v.as_str()).map(String::from), + Ok(json) => json + .get("response") + .and_then(|v| v.as_str()) + .map(String::from), Err(e) => Some(format!("Failed to parse response from project server: {e}")), } } diff --git a/server/src/chat/transport/matrix/bot/messages.rs b/server/src/chat/transport/matrix/bot/messages.rs index f0cde960..481a891a 100644 --- a/server/src/chat/transport/matrix/bot/messages.rs +++ b/server/src/chat/transport/matrix/bot/messages.rs @@ -207,8 +207,10 @@ pub(super) async fn on_room_message( && (crate::chat::commands::commands() .iter() .any(|c| c.name == cmd) - || ["assign", "start", "delete", "rebuild", "rmtree", "htop", "timer"] - .contains(&cmd.as_str())); + || [ + "assign", "start", "delete", "rebuild", "rmtree", "htop", "timer", + ] + .contains(&cmd.as_str())); if is_known_command { // Proxy to the active project server. @@ -643,12 +645,18 @@ pub(super) async fn handle_message( let sent_any_chunk = Arc::new(AtomicBool::new(false)); let sent_any_chunk_for_callback = Arc::clone(&sent_any_chunk); - // In gateway mode, run Claude Code in the active project's directory. - let project_root_str = ctx - .effective_project_root() - .await - .to_string_lossy() - .to_string(); + // In gateway mode, run Claude Code in the gateway config directory so it + // picks up the `.mcp.json` that points to the gateway's MCP proxy endpoint. + // The gateway proxies tool calls to the active project automatically. + // In standalone mode, use the project root directly. + let project_root_str = if ctx.is_gateway() { + ctx.project_root.to_string_lossy().to_string() + } else { + ctx.effective_project_root() + .await + .to_string_lossy() + .to_string() + }; let chat_fut = provider.chat_stream( &prompt, &project_root_str,