Skip to main content

lean_ctx/tools/registered/
ctx_pack.rs

1use rmcp::model::Tool;
2use rmcp::ErrorData;
3use serde_json::{json, Map, Value};
4
5use crate::server::tool_trait::{get_int, get_str, McpTool, ToolContext, ToolOutput};
6use crate::tool_defs::tool_def;
7
8pub struct CtxPackTool;
9
10impl McpTool for CtxPackTool {
11    fn name(&self) -> &'static str {
12        "ctx_pack"
13    }
14
15    fn tool_def(&self) -> Tool {
16        tool_def(
17            "ctx_pack",
18            "PR Context Pack. action=pr yields changed files, related tests, impact summary, and relevant context artifacts.",
19            json!({
20                "type": "object",
21                "properties": {
22                    "action": {
23                        "type": "string",
24                        "enum": ["pr"],
25                        "description": "Pack action"
26                    },
27                    "project_root": {
28                        "type": "string",
29                        "description": "Project root (default: session project root)"
30                    },
31                    "base": {
32                        "type": "string",
33                        "description": "Git base ref (default: auto-detect or HEAD~1)"
34                    },
35                    "format": {
36                        "type": "string",
37                        "enum": ["markdown", "json"],
38                        "description": "Output format (default: markdown)"
39                    },
40                    "depth": {
41                        "type": "integer",
42                        "description": "Impact depth (default: 3)"
43                    },
44                    "diff": {
45                        "type": "string",
46                        "description": "Optional git diff --name-status text. If omitted, computed via git."
47                    }
48                },
49                "required": ["action"]
50            }),
51        )
52    }
53
54    fn handle(
55        &self,
56        args: &Map<String, Value>,
57        ctx: &ToolContext,
58    ) -> Result<ToolOutput, ErrorData> {
59        let action = get_str(args, "action")
60            .ok_or_else(|| ErrorData::invalid_params("action is required", None))?;
61        let base = get_str(args, "base");
62        let format = get_str(args, "format");
63        let depth = get_int(args, "depth").map(|d| d as usize);
64        let diff = get_str(args, "diff");
65        let project_root = ctx
66            .resolved_path("project_root")
67            .or(ctx.resolved_path("root"))
68            .unwrap_or(&ctx.project_root);
69
70        let result = crate::tools::ctx_pack::handle(
71            &action,
72            project_root,
73            base.as_deref(),
74            format.as_deref(),
75            depth,
76            diff.as_deref(),
77        );
78
79        Ok(ToolOutput::simple(result))
80    }
81}