diff --git a/crates/goose-mcp/src/developer/analyze/types.rs b/crates/goose-mcp/src/developer/analyze/types.rs index 344fc23d090c..e64a3fa919b4 100644 --- a/crates/goose-mcp/src/developer/analyze/types.rs +++ b/crates/goose-mcp/src/developer/analyze/types.rs @@ -2,6 +2,22 @@ use rmcp::schemars::JsonSchema; use serde::{Deserialize, Serialize}; use std::path::PathBuf; +fn deserialize_string_or_u32<'de, D>(d: D) -> Result +where + D: serde::Deserializer<'de>, +{ + #[derive(Deserialize)] + #[serde(untagged)] + enum StrOrU32 { + S(String), + N(u32), + } + match StrOrU32::deserialize(d)? { + StrOrU32::S(s) => s.parse().map_err(serde::de::Error::custom), + StrOrU32::N(n) => Ok(n), + } +} + #[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] pub struct AnalyzeParams { pub path: String, @@ -9,11 +25,17 @@ pub struct AnalyzeParams { pub focus: Option, /// Call graph depth. 0=where defined, 1=direct callers/callees, 2+=transitive chains - #[serde(default = "default_follow_depth")] + #[serde( + default = "default_follow_depth", + deserialize_with = "deserialize_string_or_u32" + )] pub follow_depth: u32, /// Directory recursion limit. 0=unlimited (warning: fails on binary files) - #[serde(default = "default_max_depth")] + #[serde( + default = "default_max_depth", + deserialize_with = "deserialize_string_or_u32" + )] pub max_depth: u32, /// Maximum depth for recursive AST traversal (prevents stack overflow in deeply nested code)