diff --git a/src/main.rs b/src/main.rs index b8f6978..5197e56 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,7 @@ use reqwest::{ Client as HttpClient, }; use serde::{Deserialize, Serialize}; +use serde_json::map::Entry; use serde_json::{json, Value}; use std::cmp::Ordering; use std::collections::HashSet; @@ -4579,15 +4580,23 @@ fn rewrite_tools_list(body: &str, creds: Option<&Credentials>) -> String { // Normalize no-arg object schemas so OpenAI-style function conversion // always gets an explicit `properties` object. if schema.get("type").and_then(|t| t.as_str()) == Some("object") { - schema - .entry("properties".to_string()) - .or_insert_with(|| json!({})); - schema - .entry("required".to_string()) - .or_insert_with(|| json!([])); - schema - .entry("additionalProperties".to_string()) - .or_insert_with(|| json!(false)); + let had_properties = match schema.entry("properties".to_string()) { + Entry::Occupied(_) => true, + Entry::Vacant(v) => { + v.insert(json!({})); + false + } + }; + if let Entry::Vacant(v) = schema.entry("required".to_string()) { + v.insert(json!([])); + } + if !had_properties { + if let Entry::Vacant(v) = + schema.entry("additionalProperties".to_string()) + { + v.insert(json!(false)); + } + } } // Add proxy-only confirmation flags / validation hints @@ -7624,6 +7633,35 @@ mod tests { ); } + #[test] + fn test_rewrite_tools_list_does_not_force_additional_properties_on_arg_schema() { + let body = serde_json::to_string(&json!({ + "jsonrpc": "2.0", + "id": 1, + "result": { + "tools": [{ + "name": "help", + "description": "Help", + "inputSchema": { + "type": "object", + "properties": {"query": {"type": "string"}} + } + }] + } + })) + .unwrap(); + + let result = rewrite_tools_list(&body, None); + let parsed: Value = serde_json::from_str(&result).unwrap(); + let schema = parsed["result"]["tools"][0]["inputSchema"] + .as_object() + .expect("inputSchema must be object"); + assert!( + !schema.contains_key("additionalProperties"), + "arg schema should keep JSON Schema default additionalProperties behavior" + ); + } + // --- MCP annotations tests --- #[test]