Skip to main content

lean_ctx/tools/registered/
ctx_share.rs

1use rmcp::model::Tool;
2use rmcp::ErrorData;
3use serde_json::{json, Map, Value};
4
5use crate::server::tool_trait::{get_str, McpTool, ToolContext, ToolOutput};
6use crate::tool_defs::tool_def;
7
8pub struct CtxShareTool;
9
10impl McpTool for CtxShareTool {
11    fn name(&self) -> &'static str {
12        "ctx_share"
13    }
14
15    fn tool_def(&self) -> Tool {
16        tool_def(
17            "ctx_share",
18            "Share cached file contexts between agents. Actions: push (share files from your cache to another agent), \
19pull (receive files shared by other agents), list (show all shared contexts), clear (remove your shared contexts).",
20            json!({
21                "type": "object",
22                "properties": {
23                    "action": {
24                        "type": "string",
25                        "enum": ["push", "pull", "list", "clear"],
26                        "description": "Share operation to perform"
27                    },
28                    "paths": {
29                        "type": "string",
30                        "description": "Comma-separated file paths to share (for push action)"
31                    },
32                    "to_agent": {
33                        "type": "string",
34                        "description": "Target agent ID (omit for broadcast to all agents)"
35                    },
36                    "message": {
37                        "type": "string",
38                        "description": "Optional context message explaining what was shared"
39                    }
40                },
41                "required": ["action"]
42            }),
43        )
44    }
45
46    fn handle(
47        &self,
48        args: &Map<String, Value>,
49        ctx: &ToolContext,
50    ) -> Result<ToolOutput, ErrorData> {
51        let action = get_str(args, "action")
52            .ok_or_else(|| ErrorData::invalid_params("action is required", None))?;
53        let to_agent = get_str(args, "to_agent");
54        let paths = get_str(args, "paths");
55        let message = get_str(args, "message");
56
57        let from_agent = ctx
58            .agent_id
59            .as_ref()
60            .map(|a| a.blocking_read().clone())
61            .unwrap_or_default();
62
63        let cache_handle = ctx
64            .cache
65            .as_ref()
66            .ok_or_else(|| ErrorData::internal_error("cache not available", None))?;
67        let cache = cache_handle.blocking_read();
68        let result = crate::tools::ctx_share::handle(
69            &action,
70            from_agent.as_deref(),
71            to_agent.as_deref(),
72            paths.as_deref(),
73            message.as_deref(),
74            &cache,
75            &ctx.project_root,
76        );
77        drop(cache);
78
79        Ok(ToolOutput {
80            text: result,
81            original_tokens: 0,
82            saved_tokens: 0,
83            mode: Some(action),
84            path: None,
85            changed: false,
86        })
87    }
88}