lean_ctx/tools/registered/
ctx_skillify.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 CtxSkillifyTool;
9
10impl McpTool for CtxSkillifyTool {
11 fn name(&self) -> &'static str {
12 "ctx_skillify"
13 }
14
15 fn tool_def(&self) -> Tool {
16 tool_def(
17 "ctx_skillify",
18 "WORKFLOW: mine to extract patterns → list to review → promote to activate.\n\
19 Codifies patterns into .cursor/rules/skillify-*.mdc.\n\
20 Actions: mine|list|status|promote. Idempotent.\n\
21 ANTIPATTERN: one-off rules → write .mdc by hand.",
22 json!({
23 "type": "object",
24 "properties": {
25 "action": {
26 "type": "string",
27 "enum": ["mine", "list", "status", "promote"],
28 "description": "mine|list|status|promote"
29 },
30 "slug": {
31 "type": "string",
32 "description": "Rule slug (for promote)"
33 }
34 }
35 }),
36 )
37 }
38
39 fn handle(
40 &self,
41 args: &Map<String, Value>,
42 ctx: &ToolContext,
43 ) -> Result<ToolOutput, ErrorData> {
44 let action = get_str(args, "action").unwrap_or_else(|| "mine".to_string());
45 let slug = get_str(args, "slug");
46 let result =
47 crate::tools::ctx_skillify::handle(&ctx.project_root, &action, slug.as_deref());
48 Ok(ToolOutput::simple(result))
49 }
50}