From 5860d14de7ecf9f3e499f58b16ddb66cc2d064d1 Mon Sep 17 00:00:00 2001 From: Vaiz <4908982+Vaiz@users.noreply.github.com> Date: Sun, 5 Apr 2026 18:54:02 +0200 Subject: [PATCH 1/5] skip roots request if client doesn't support it --- src/workspace.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/workspace.rs b/src/workspace.rs index 60e0b52..495a5ed 100644 --- a/src/workspace.rs +++ b/src/workspace.rs @@ -32,7 +32,12 @@ pub fn detect_rust_workspace(context: NotificationContext) { .peer_info() .and_then(|info| info.capabilities.roots.as_ref()) .is_some(); + tracing::info!("Checking client roots capability: supports_roots={supports_roots}"); + if !supports_roots { + tracing::warn!("Client does not support roots capability; cannot auto-detect workspace"); + return; + } // Spawn onto a separate task to avoid blocking the notification handler, // which would deadlock if the client waits for the server to finish From 2d19aa2a35e9b30aa734234fb16beb3b8f18cbaa Mon Sep 17 00:00:00 2001 From: Vaiz <4908982+Vaiz@users.noreply.github.com> Date: Sun, 5 Apr 2026 19:21:16 +0200 Subject: [PATCH 2/5] use cargo test for updating insta snapshots --- src/tools/cargo_insta.rs | 87 ++++++++----------- ...ta_update_snapshots_all_features_args.snap | 2 - ...o_insta_update_snapshots_default_args.snap | 2 - ...e_snapshots_features_and_targets_args.snap | 2 - ..._update_snapshots_manifest_path_args.snap} | 4 - ..._update_snapshots_nextest_runner_args.snap | 14 --- 6 files changed, 38 insertions(+), 73 deletions(-) rename src/tools/snapshots/{rust_mcp_server__tools__cargo_insta__tests__cargo_insta_update_snapshots_manifest_workspace_root_args.snap => rust_mcp_server__tools__cargo_insta__tests__cargo_insta_update_snapshots_manifest_path_args.snap} (64%) delete mode 100644 src/tools/snapshots/rust_mcp_server__tools__cargo_insta__tests__cargo_insta_update_snapshots_nextest_runner_args.snap diff --git a/src/tools/cargo_insta.rs b/src/tools/cargo_insta.rs index 03ed450..047e416 100644 --- a/src/tools/cargo_insta.rs +++ b/src/tools/cargo_insta.rs @@ -9,26 +9,15 @@ use crate::{ #[derive(Debug, ::serde::Deserialize, schemars::JsonSchema)] pub struct CargoInstaUpdateSnapshotsRequest { + /// Forcibly updates snapshot files, even if assertions pass (`INSTA_UPDATE=force`). + /// When `false` (default), uses `INSTA_UPDATE=always` to update failing snapshots. + #[serde(default)] + force: Option, + /// Path to `Cargo.toml` #[serde(default, deserialize_with = "deserialize_string")] manifest_path: Option, - /// Explicit path to the workspace root - #[serde(default, deserialize_with = "deserialize_string")] - workspace_root: Option, - - /// Handle unreferenced snapshots after a successful test run. - /// - /// Valid options: auto, reject, delete, warn, ignore - #[serde(default, deserialize_with = "deserialize_string")] - unreferenced: Option, - - /// Picks the test runner. - /// - /// Valid options: auto (default), cargo-test, nextest - #[serde(default, deserialize_with = "deserialize_string")] - test_runner: Option, - // ── Package / target selection ──────────────────────────────────────────── /// Package(s) to run tests for #[serde(default, deserialize_with = "deserialize_string_vec")] @@ -75,7 +64,15 @@ pub struct CargoInstaUpdateSnapshotsRequest { impl CargoInstaUpdateSnapshotsRequest { pub fn build_cmd(&self) -> Result { let mut cmd = Command::new("cargo"); - cmd.arg("insta").arg("test").arg("--accept"); + cmd.arg("test"); + + // Set INSTA_UPDATE env var (defaults to "always" to bypass review) + let insta_update = if self.force.unwrap_or(false) { + "force" + } else { + "always" + }; + cmd.env("INSTA_UPDATE", insta_update); // Workspace / manifest selection if let Some(manifest_path) = &self.manifest_path { @@ -85,19 +82,6 @@ impl CargoInstaUpdateSnapshotsRequest { cmd.arg("--workspace"); } - if let Some(workspace_root) = &self.workspace_root { - cmd.arg("--workspace-root").arg(workspace_root); - } - - // Insta-specific flags - if let Some(unreferenced) = &self.unreferenced { - cmd.arg("--unreferenced").arg(unreferenced); - } - - if let Some(test_runner) = &self.test_runner { - cmd.arg("--test-runner").arg(test_runner); - } - // Package selection if let Some(packages) = &self.package { for p in packages { @@ -156,8 +140,7 @@ pub struct CargoInstaUpdateSnapshotsRmcpTool; impl Tool for CargoInstaUpdateSnapshotsRmcpTool { const NAME: &'static str = "cargo-insta-update-snapshots"; const TITLE: &'static str = "Update insta snapshots"; - const DESCRIPTION: &'static str = - "Generates and updates `cargo insta` snapshot files fixing tests with outdated snapshots"; + const DESCRIPTION: &'static str = "Runs `cargo test` with the `INSTA_UPDATE` environment variable to update insta snapshot files."; type RequestArgs = CargoInstaUpdateSnapshotsRequest; fn call_rmcp_tool(&self, request: Self::RequestArgs) -> Result { @@ -171,7 +154,7 @@ mod tests { use insta::assert_debug_snapshot; use serde_json::json; - fn cmd_args(request: CargoInstaUpdateSnapshotsRequest) -> Vec { + fn cmd_args(request: &CargoInstaUpdateSnapshotsRequest) -> Vec { request .build_cmd() .expect("Should build command") @@ -180,27 +163,35 @@ mod tests { .collect() } + fn cmd_env_insta_update(request: &CargoInstaUpdateSnapshotsRequest) -> String { + request + .build_cmd() + .expect("Should build command") + .get_envs() + .find(|(k, _)| k == &"INSTA_UPDATE") + .and_then(|(_, v)| v) + .map(|v| v.to_string_lossy().to_string()) + .unwrap_or_default() + } + #[test] fn test_update_snapshots_default_args() { let request: CargoInstaUpdateSnapshotsRequest = serde_json::from_value(json!({})).expect("Should deserialize empty request"); - let args = cmd_args(request); + let args = cmd_args(&request); assert_debug_snapshot!("cargo_insta_update_snapshots_default_args", args); + assert_eq!(cmd_env_insta_update(&request), "always"); } #[test] - fn test_update_snapshots_with_manifest_and_workspace_root() { + fn test_update_snapshots_with_manifest_path() { let request: CargoInstaUpdateSnapshotsRequest = serde_json::from_value(json!({ - "manifest_path": "Cargo.toml", - "workspace_root": "." + "manifest_path": "Cargo.toml" })) .expect("Should deserialize request"); - let args = cmd_args(request); - assert_debug_snapshot!( - "cargo_insta_update_snapshots_manifest_workspace_root_args", - args - ); + let args = cmd_args(&request); + assert_debug_snapshot!("cargo_insta_update_snapshots_manifest_path_args", args); } #[test] @@ -209,7 +200,7 @@ mod tests { "all_features": true })) .expect("Should deserialize request"); - let args = cmd_args(request); + let args = cmd_args(&request); assert_debug_snapshot!("cargo_insta_update_snapshots_all_features_args", args); } @@ -222,7 +213,7 @@ mod tests { "jobs": 4 })) .expect("Should deserialize request"); - let args = cmd_args(request); + let args = cmd_args(&request); assert_debug_snapshot!( "cargo_insta_update_snapshots_features_and_targets_args", args @@ -230,13 +221,11 @@ mod tests { } #[test] - fn test_update_snapshots_nextest_runner() { + fn test_update_snapshots_force_flag() { let request: CargoInstaUpdateSnapshotsRequest = serde_json::from_value(json!({ - "test_runner": "nextest", - "unreferenced": "delete" + "force": true })) .expect("Should deserialize request"); - let args = cmd_args(request); - assert_debug_snapshot!("cargo_insta_update_snapshots_nextest_runner_args", args); + assert_eq!(cmd_env_insta_update(&request), "force"); } } diff --git a/src/tools/snapshots/rust_mcp_server__tools__cargo_insta__tests__cargo_insta_update_snapshots_all_features_args.snap b/src/tools/snapshots/rust_mcp_server__tools__cargo_insta__tests__cargo_insta_update_snapshots_all_features_args.snap index 9efee3a..94b9e3d 100644 --- a/src/tools/snapshots/rust_mcp_server__tools__cargo_insta__tests__cargo_insta_update_snapshots_all_features_args.snap +++ b/src/tools/snapshots/rust_mcp_server__tools__cargo_insta__tests__cargo_insta_update_snapshots_all_features_args.snap @@ -3,9 +3,7 @@ source: src/tools/cargo_insta.rs expression: args --- [ - "insta", "test", - "--accept", "--workspace", "--all-features", ] diff --git a/src/tools/snapshots/rust_mcp_server__tools__cargo_insta__tests__cargo_insta_update_snapshots_default_args.snap b/src/tools/snapshots/rust_mcp_server__tools__cargo_insta__tests__cargo_insta_update_snapshots_default_args.snap index 0762baa..59cfde5 100644 --- a/src/tools/snapshots/rust_mcp_server__tools__cargo_insta__tests__cargo_insta_update_snapshots_default_args.snap +++ b/src/tools/snapshots/rust_mcp_server__tools__cargo_insta__tests__cargo_insta_update_snapshots_default_args.snap @@ -3,8 +3,6 @@ source: src/tools/cargo_insta.rs expression: args --- [ - "insta", "test", - "--accept", "--workspace", ] diff --git a/src/tools/snapshots/rust_mcp_server__tools__cargo_insta__tests__cargo_insta_update_snapshots_features_and_targets_args.snap b/src/tools/snapshots/rust_mcp_server__tools__cargo_insta__tests__cargo_insta_update_snapshots_features_and_targets_args.snap index ba74000..ddff723 100644 --- a/src/tools/snapshots/rust_mcp_server__tools__cargo_insta__tests__cargo_insta_update_snapshots_features_and_targets_args.snap +++ b/src/tools/snapshots/rust_mcp_server__tools__cargo_insta__tests__cargo_insta_update_snapshots_features_and_targets_args.snap @@ -3,9 +3,7 @@ source: src/tools/cargo_insta.rs expression: args --- [ - "insta", "test", - "--accept", "--workspace", "--lib", "--features", diff --git a/src/tools/snapshots/rust_mcp_server__tools__cargo_insta__tests__cargo_insta_update_snapshots_manifest_workspace_root_args.snap b/src/tools/snapshots/rust_mcp_server__tools__cargo_insta__tests__cargo_insta_update_snapshots_manifest_path_args.snap similarity index 64% rename from src/tools/snapshots/rust_mcp_server__tools__cargo_insta__tests__cargo_insta_update_snapshots_manifest_workspace_root_args.snap rename to src/tools/snapshots/rust_mcp_server__tools__cargo_insta__tests__cargo_insta_update_snapshots_manifest_path_args.snap index fdd98e2..3f3ac69 100644 --- a/src/tools/snapshots/rust_mcp_server__tools__cargo_insta__tests__cargo_insta_update_snapshots_manifest_workspace_root_args.snap +++ b/src/tools/snapshots/rust_mcp_server__tools__cargo_insta__tests__cargo_insta_update_snapshots_manifest_path_args.snap @@ -3,11 +3,7 @@ source: src/tools/cargo_insta.rs expression: args --- [ - "insta", "test", - "--accept", "--manifest-path", "Cargo.toml", - "--workspace-root", - ".", ] diff --git a/src/tools/snapshots/rust_mcp_server__tools__cargo_insta__tests__cargo_insta_update_snapshots_nextest_runner_args.snap b/src/tools/snapshots/rust_mcp_server__tools__cargo_insta__tests__cargo_insta_update_snapshots_nextest_runner_args.snap deleted file mode 100644 index 89c7e97..0000000 --- a/src/tools/snapshots/rust_mcp_server__tools__cargo_insta__tests__cargo_insta_update_snapshots_nextest_runner_args.snap +++ /dev/null @@ -1,14 +0,0 @@ ---- -source: src/tools/cargo_insta.rs -expression: args ---- -[ - "insta", - "test", - "--accept", - "--workspace", - "--unreferenced", - "delete", - "--test-runner", - "nextest", -] From 4e5d55d56127fa2262cf04b0afa383f5c3adb9b6 Mon Sep 17 00:00:00 2001 From: Vaiz <4908982+Vaiz@users.noreply.github.com> Date: Sun, 5 Apr 2026 19:33:15 +0200 Subject: [PATCH 3/5] output_verbosity --- src/tools/cargo_insta.rs | 15 ++++++++++++++- ..._insta_update_snapshots_all_features_args.snap | 1 + ...cargo_insta_update_snapshots_default_args.snap | 1 + ...pdate_snapshots_features_and_targets_args.snap | 1 + ...insta_update_snapshots_manifest_path_args.snap | 1 + 5 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/tools/cargo_insta.rs b/src/tools/cargo_insta.rs index 047e416..8e91967 100644 --- a/src/tools/cargo_insta.rs +++ b/src/tools/cargo_insta.rs @@ -4,7 +4,7 @@ use rmcp::ErrorData; use crate::{ Tool, execute_command, - serde_utils::{deserialize_string, deserialize_string_vec}, + serde_utils::{deserialize_string, deserialize_string_vec, output_verbosity_to_cli_flags}, }; #[derive(Debug, ::serde::Deserialize, schemars::JsonSchema)] @@ -59,6 +59,15 @@ pub struct CargoInstaUpdateSnapshotsRequest { /// Number of parallel jobs, defaults to # of CPUs #[serde(default)] jobs: Option, + + /// Output verbosity level. + /// + /// Valid options: + /// - "quiet" (default): Show only the essential command output + /// - "normal": Show standard output (no additional flags) + /// - "verbose": Show detailed output including build information + #[serde(default, deserialize_with = "deserialize_string")] + output_verbosity: Option, } impl CargoInstaUpdateSnapshotsRequest { @@ -131,6 +140,10 @@ impl CargoInstaUpdateSnapshotsRequest { cmd.arg("--jobs").arg(jobs.to_string()); } + // Output options + let output_flags = output_verbosity_to_cli_flags(self.output_verbosity.as_deref())?; + cmd.args(output_flags); + Ok(cmd) } } diff --git a/src/tools/snapshots/rust_mcp_server__tools__cargo_insta__tests__cargo_insta_update_snapshots_all_features_args.snap b/src/tools/snapshots/rust_mcp_server__tools__cargo_insta__tests__cargo_insta_update_snapshots_all_features_args.snap index 94b9e3d..f74b4f0 100644 --- a/src/tools/snapshots/rust_mcp_server__tools__cargo_insta__tests__cargo_insta_update_snapshots_all_features_args.snap +++ b/src/tools/snapshots/rust_mcp_server__tools__cargo_insta__tests__cargo_insta_update_snapshots_all_features_args.snap @@ -6,4 +6,5 @@ expression: args "test", "--workspace", "--all-features", + "--quiet", ] diff --git a/src/tools/snapshots/rust_mcp_server__tools__cargo_insta__tests__cargo_insta_update_snapshots_default_args.snap b/src/tools/snapshots/rust_mcp_server__tools__cargo_insta__tests__cargo_insta_update_snapshots_default_args.snap index 59cfde5..6fcb4aa 100644 --- a/src/tools/snapshots/rust_mcp_server__tools__cargo_insta__tests__cargo_insta_update_snapshots_default_args.snap +++ b/src/tools/snapshots/rust_mcp_server__tools__cargo_insta__tests__cargo_insta_update_snapshots_default_args.snap @@ -5,4 +5,5 @@ expression: args [ "test", "--workspace", + "--quiet", ] diff --git a/src/tools/snapshots/rust_mcp_server__tools__cargo_insta__tests__cargo_insta_update_snapshots_features_and_targets_args.snap b/src/tools/snapshots/rust_mcp_server__tools__cargo_insta__tests__cargo_insta_update_snapshots_features_and_targets_args.snap index ddff723..b17577a 100644 --- a/src/tools/snapshots/rust_mcp_server__tools__cargo_insta__tests__cargo_insta_update_snapshots_features_and_targets_args.snap +++ b/src/tools/snapshots/rust_mcp_server__tools__cargo_insta__tests__cargo_insta_update_snapshots_features_and_targets_args.snap @@ -11,4 +11,5 @@ expression: args "--no-default-features", "--jobs", "4", + "--quiet", ] diff --git a/src/tools/snapshots/rust_mcp_server__tools__cargo_insta__tests__cargo_insta_update_snapshots_manifest_path_args.snap b/src/tools/snapshots/rust_mcp_server__tools__cargo_insta__tests__cargo_insta_update_snapshots_manifest_path_args.snap index 3f3ac69..09535de 100644 --- a/src/tools/snapshots/rust_mcp_server__tools__cargo_insta__tests__cargo_insta_update_snapshots_manifest_path_args.snap +++ b/src/tools/snapshots/rust_mcp_server__tools__cargo_insta__tests__cargo_insta_update_snapshots_manifest_path_args.snap @@ -6,4 +6,5 @@ expression: args "test", "--manifest-path", "Cargo.toml", + "--quiet", ] From ce581d8b3e46187816563923fa685fa71cb84407 Mon Sep 17 00:00:00 2001 From: Vaiz <4908982+Vaiz@users.noreply.github.com> Date: Sun, 5 Apr 2026 19:36:22 +0200 Subject: [PATCH 4/5] clippy --- src/workspace.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/workspace.rs b/src/workspace.rs index 495a5ed..8217555 100644 --- a/src/workspace.rs +++ b/src/workspace.rs @@ -110,7 +110,7 @@ fn file_uri_to_path(uri: &str) -> Option { if b.len() >= 3 && b[0] == b'/' && b[1].is_ascii_alphabetic() && b[2] == b':' { &decoded[1..] } else { - &decoded + decoded } }; Some(std::path::PathBuf::from(decoded)) From f3e8794c2328359222812a757d2f1e379befd691 Mon Sep 17 00:00:00 2001 From: Vaiz <4908982+Vaiz@users.noreply.github.com> Date: Sun, 5 Apr 2026 19:36:29 +0200 Subject: [PATCH 5/5] tools --- tools.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tools.md b/tools.md index 4f9e73e..1cfaceb 100644 --- a/tools.md +++ b/tools.md @@ -315,22 +315,21 @@ - version : string
- **cargo-insta-update-snapshots** - - Generates and updates `cargo insta` snapshot files fixing tests with outdated snapshots + - Runs `cargo test` with the `INSTA_UPDATE` environment variable to update insta snapshot files. - **Inputs:** - all_features : boolean
- all_targets : boolean
- exclude : string [ ]
- features : string [ ]
+ - force : boolean
- jobs : integer
- lib : boolean
- manifest_path : string
- no_default_features : boolean
+ - output_verbosity : string
- package : string [ ]
- test : string
- - test_runner : string
- tests : boolean
- - unreferenced : string
- - workspace_root : string
- **cargo-list** - Lists installed cargo commands using 'cargo --list'.