Skip to main content

lean_ctx/tools/registered/
ctx_artifacts.rs

1use std::path::Path;
2
3use rmcp::model::Tool;
4use rmcp::ErrorData;
5use serde_json::{json, Map, Value};
6
7use crate::server::tool_trait::{get_int, get_str, McpTool, ToolContext, ToolOutput};
8use crate::tool_defs::tool_def;
9
10pub struct CtxArtifactsTool;
11
12impl McpTool for CtxArtifactsTool {
13    fn name(&self) -> &'static str {
14        "ctx_artifacts"
15    }
16
17    fn tool_def(&self) -> Tool {
18        tool_def(
19            "ctx_artifacts",
20            "Context artifact registry + BM25 index. Actions: list|status|index|reindex|search|remove.",
21            json!({
22                "type": "object",
23                "properties": {
24                    "action": {
25                        "type": "string",
26                        "enum": ["list", "status", "index", "reindex", "search", "remove"],
27                        "description": "Artifact action"
28                    },
29                    "project_root": {
30                        "type": "string",
31                        "description": "Project root (default: session project root)"
32                    },
33                    "query": {
34                        "type": "string",
35                        "description": "Search query (required for action=search)"
36                    },
37                    "name": {
38                        "type": "string",
39                        "description": "Artifact name (required for action=remove)"
40                    },
41                    "top_k": {
42                        "type": "integer",
43                        "description": "Max results (default: 10, max: 50)"
44                    },
45                    "format": {
46                        "type": "string",
47                        "enum": ["json", "markdown"],
48                        "description": "Output format (default: json)"
49                    }
50                },
51                "required": ["action"]
52            }),
53        )
54    }
55
56    fn handle(
57        &self,
58        args: &Map<String, Value>,
59        ctx: &ToolContext,
60    ) -> Result<ToolOutput, ErrorData> {
61        let action = get_str(args, "action")
62            .ok_or_else(|| ErrorData::invalid_params("action is required", None))?;
63        let format = get_str(args, "format");
64        let query = get_str(args, "query");
65        let name = get_str(args, "name");
66        let top_k = get_int(args, "top_k").map(|d| d as usize);
67        let root = ctx
68            .resolved_path("project_root")
69            .or(ctx.resolved_path("root"))
70            .unwrap_or(&ctx.project_root);
71
72        let result = crate::tools::ctx_artifacts::handle(
73            &action,
74            Path::new(root),
75            name.as_deref().or(query.as_deref()),
76            top_k,
77            format.as_deref(),
78        );
79
80        Ok(ToolOutput::simple(result))
81    }
82}