lean_ctx/tools/registered/
ctx_share.rs1use 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}