aprender_mcp/tools/
validate.rs1#![allow(clippy::disallowed_methods)] use crate::tools::subprocess::run_apr;
14use crate::types::{InputSchema, ToolCallResult, ToolDefinition};
15
16pub const NAME: &str = "apr.validate";
18
19#[must_use]
28pub fn validate_tool_definition() -> ToolDefinition {
29 let input_schema: InputSchema = serde_json::from_str(crate::schemas::APR_VALIDATE_SCHEMA)
30 .expect(
31 "FALSIFY-MCP-008: apr.validate codegen constant must parse as InputSchema; \
32 regenerate by editing contracts/apr-mcp-tool-schemas-v1.yaml and rebuilding",
33 );
34 ToolDefinition {
35 name: NAME.to_string(),
36 description: crate::schemas::APR_VALIDATE_DESCRIPTION.to_string(),
37 input_schema,
38 }
39}
40
41#[must_use]
43pub fn call(args: &serde_json::Value) -> ToolCallResult {
44 let Some(model_path) = args.get("model_path").and_then(|v| v.as_str()) else {
45 return ToolCallResult::error("Missing required argument: model_path");
46 };
47 run_apr(&["validate", model_path, "--json"])
48}
49
50pub fn dispatch(
52 args: &serde_json::Value,
53 _cancel: &std::sync::mpsc::Receiver<()>,
54 _sink: Option<&crate::server::NotificationSink>,
55 _token: Option<serde_json::Value>,
56) -> ToolCallResult {
57 call(args)
58}
59
60crate::register_mcp_tool!(
61 name: NAME,
62 definition: validate_tool_definition,
63 dispatch: dispatch,
64);
65
66#[cfg(test)]
67#[allow(clippy::disallowed_methods)] mod tests {
69 use super::*;
70
71 #[test]
72 fn definition_has_correct_name_and_required_field() {
73 let def = validate_tool_definition();
74 assert_eq!(def.name, "apr.validate");
75 assert_eq!(def.input_schema.schema_type, "object");
76 assert_eq!(def.input_schema.required, vec!["model_path".to_string()]);
77 assert!(def.input_schema.properties.contains_key("model_path"));
78 }
79
80 #[test]
81 fn missing_model_path_returns_error() {
82 let result = call(&serde_json::json!({}));
83 assert_eq!(result.is_error, Some(true));
84 assert!(result.content[0].text.contains("model_path"));
85 }
86
87 #[test]
88 fn nonstring_model_path_returns_error() {
89 let result = call(&serde_json::json!({ "model_path": 42 }));
90 assert_eq!(result.is_error, Some(true));
91 }
92}