lean_ctx/tools/registered/
ctx_expand.rs1use rmcp::ErrorData;
2use rmcp::model::Tool;
3use serde_json::{Map, Value, json};
4
5use crate::server::tool_trait::{McpTool, ToolContext, ToolOutput};
6use crate::tool_defs::tool_def;
7
8pub struct CtxExpandTool;
9
10impl McpTool for CtxExpandTool {
11 fn name(&self) -> &'static str {
12 "ctx_expand"
13 }
14
15 fn tool_def(&self) -> Tool {
16 tool_def(
17 "ctx_expand",
18 "Retrieve archived tool output: see [Archived:ID] → ctx_expand id=ID \
19 (zero-loss, original preserved). head/tail/search filter lines; \
20 action=list|search_all browses/queries archives.\n\
21 ANTIPATTERN: not for project files — use ctx_read or ctx_compose.",
22 json!({
23 "type": "object",
24 "properties": {
25 "id": { "type": "string", "description": "Archive ID or @F1 ref" },
26 "action": { "type": "string", "description": "retrieve|list|search_all" },
27 "start_line": { "type": "integer" },
28 "end_line": { "type": "integer" },
29 "head": { "type": "integer" },
30 "tail": { "type": "integer" },
31 "search": { "type": "string" },
32 "json_keys": { "type": "boolean" },
33 "json_path": { "type": "string", "description": "e.g. data.items.0" },
34 "query": { "type": "string" },
35 "session_id": { "type": "string" }
36 },
37 "allOf": [
38 { "if": { "properties": { "action": { "const": "search_all" } }, "required": ["action"] }, "then": { "required": ["query"] } },
39 { "if": { "not": { "properties": { "action": { "enum": ["list", "search_all"] } }, "required": ["action"] } }, "then": { "required": ["id"] } }
40 ]
41 }),
42 )
43 }
44
45 fn handle(
46 &self,
47 args: &Map<String, Value>,
48 _ctx: &ToolContext,
49 ) -> Result<ToolOutput, ErrorData> {
50 let args_val = Value::Object(args.clone());
51 let result = crate::tools::ctx_expand::handle(&args_val);
52 Ok(ToolOutput::simple(result))
53 }
54}