lean_ctx/tools/registered/
ctx_verify.rs1use rmcp::ErrorData;
2use rmcp::model::Tool;
3use serde_json::{Map, Value, json};
4
5use crate::server::tool_trait::{McpTool, ToolContext, ToolOutput, get_str};
6use crate::tool_defs::tool_def;
7
8pub struct CtxVerifyTool;
9
10impl McpTool for CtxVerifyTool {
11 fn name(&self) -> &'static str {
12 "ctx_verify"
13 }
14
15 fn tool_def(&self) -> Tool {
16 tool_def(
17 "ctx_verify",
18 "Verification observability — tool call statistics and claim-based verification.\n\
19 WORKFLOW: action=stats to monitor tool usage; action=proof|v2 for Lean4 proof verification.\n\
20 Actions: stats|proof|v2 (format=summary|json|both, default summary).\n\
21 ANTIPATTERN: not for runtime verification during active development — use for periodic audit.",
22 json!({
23 "type": "object",
24 "properties": {
25 "action": {
26 "type": "string",
27 "enum": ["stats", "proof", "v2"],
28 "description": "stats|proof|v2"
29 },
30 "format": {
31 "type": "string",
32 "enum": ["summary", "json", "both"],
33 "description": "Output format: summary|json|both (default summary)"
34 }
35 }
36 }),
37 )
38 }
39
40 fn handle(
41 &self,
42 args: &Map<String, Value>,
43 _ctx: &ToolContext,
44 ) -> Result<ToolOutput, ErrorData> {
45 let action = get_str(args, "action").unwrap_or_else(|| "stats".to_string());
46 let format = get_str(args, "format");
47 match action.as_str() {
48 "stats" => {
49 let out = crate::tools::ctx_verify::handle_stats(format.as_deref())
50 .map_err(|e| ErrorData::invalid_params(e, None))?;
51 Ok(ToolOutput {
52 text: out,
53 original_tokens: 0,
54 saved_tokens: 0,
55 mode: Some(action),
56 path: None,
57 changed: false,
58 shell_outcome: None,
59 })
60 }
61 "proof" | "v2" => {
62 let out = crate::tools::ctx_verify::handle_proof(format.as_deref())
63 .map_err(|e| ErrorData::invalid_params(e, None))?;
64 Ok(ToolOutput {
65 text: out,
66 original_tokens: 0,
67 saved_tokens: 0,
68 mode: Some(action),
69 path: None,
70 changed: false,
71 shell_outcome: None,
72 })
73 }
74 _ => Err(ErrorData::invalid_params(
75 "unsupported action (expected: stats, proof, v2)",
76 None,
77 )),
78 }
79 }
80}