Skip to main content

lean_ctx/
tool_defs.rs

1use std::sync::Arc;
2
3use rmcp::model::*;
4use serde_json::{json, Map, Value};
5
6pub fn tool_def(name: &'static str, description: &'static str, schema_value: Value) -> Tool {
7    let schema: Map<String, Value> = match schema_value {
8        Value::Object(map) => map,
9        _ => Map::new(),
10    };
11    Tool::new(name, description, Arc::new(schema))
12}
13
14pub fn granular_tool_defs() -> Vec<Tool> {
15    vec![
16        tool_def(
17            "ctx_read",
18            "Read file (cached, compressed). Re-reads ~13 tok. Auto-selects optimal mode. \
19Modes: full|map|signatures|diff|aggressive|entropy|task|reference|lines:N-M. fresh=true re-reads.",
20            json!({
21                "type": "object",
22                "properties": {
23                    "path": { "type": "string", "description": "Absolute file path to read" },
24                    "mode": {
25                        "type": "string",
26                        "description": "Compression mode (default: full). Use 'map' for context-only files. For line ranges: 'lines:N-M' (e.g. 'lines:400-500')."
27                    },
28                    "start_line": {
29                        "type": "integer",
30                        "description": "Read from this line number to end of file. Bypasses cache stub — always returns actual content."
31                    },
32                    "fresh": {
33                        "type": "boolean",
34                        "description": "Bypass cache and force a full re-read. Use when running as a subagent that may not have the parent's context."
35                    }
36                },
37                "required": ["path"]
38            }),
39        ),
40        tool_def(
41            "ctx_multi_read",
42            "Batch read files in one call. Same modes as ctx_read.",
43            json!({
44                "type": "object",
45                "properties": {
46                    "paths": {
47                        "type": "array",
48                        "items": { "type": "string" },
49                        "description": "Absolute file paths to read, in order"
50                    },
51                    "mode": {
52                        "type": "string",
53                        "description": "Compression mode (default: full). Same modes as ctx_read (auto, full, map, signatures, diff, aggressive, entropy, task, reference, lines:N-M)."
54                    }
55                },
56                "required": ["paths"]
57            }),
58        ),
59        tool_def(
60            "ctx_tree",
61            "Directory listing with file counts.",
62            json!({
63                "type": "object",
64                "properties": {
65                    "path": { "type": "string", "description": "Directory path (default: .)" },
66                    "depth": { "type": "integer", "description": "Max depth (default: 3)" },
67                    "show_hidden": { "type": "boolean", "description": "Show hidden files" }
68                }
69            }),
70        ),
71        tool_def(
72            "ctx_shell",
73            "Run shell command (compressed output, 90+ patterns). Use raw=true to skip compression. cwd sets working directory (persists across calls via cd tracking).",
74            json!({
75                "type": "object",
76                "properties": {
77                    "command": { "type": "string", "description": "Shell command to execute" },
78                    "raw": { "type": "boolean", "description": "Skip compression, return full uncompressed output. Use for small outputs or when full detail is critical." },
79                    "cwd": { "type": "string", "description": "Working directory for the command. If omitted, uses last cd target or project root." }
80                },
81                "required": ["command"]
82            }),
83        ),
84        tool_def(
85            "ctx_search",
86            "Regex code search (.gitignore aware, compact results).",
87            json!({
88                "type": "object",
89                "properties": {
90                    "pattern": { "type": "string", "description": "Regex pattern" },
91                    "path": { "type": "string", "description": "Directory to search" },
92                    "ext": { "type": "string", "description": "File extension filter" },
93                    "max_results": { "type": "integer", "description": "Max results (default: 20)" },
94                    "ignore_gitignore": { "type": "boolean", "description": "Set true to scan ALL files including .gitignore'd paths (default: false)" }
95                },
96                "required": ["pattern"]
97            }),
98        ),
99        tool_def(
100            "ctx_compress",
101            "Context checkpoint for long conversations.",
102            json!({
103                "type": "object",
104                "properties": {
105                    "include_signatures": { "type": "boolean", "description": "Include signatures (default: true)" }
106                }
107            }),
108        ),
109        tool_def(
110            "ctx_benchmark",
111            "Benchmark compression modes for a file or project.",
112            json!({
113                "type": "object",
114                "properties": {
115                    "path": { "type": "string", "description": "File path (action=file) or project directory (action=project)" },
116                    "action": { "type": "string", "description": "file (default) or project", "default": "file" },
117                    "format": { "type": "string", "description": "Output format for project benchmark: terminal, markdown, json", "default": "terminal" }
118                },
119                "required": ["path"]
120            }),
121        ),
122        tool_def(
123            "ctx_metrics",
124            "Session token stats, cache rates, per-tool savings.",
125            json!({
126                "type": "object",
127                "properties": {}
128            }),
129        ),
130        tool_def(
131            "ctx_analyze",
132            "Entropy analysis — recommends optimal compression mode for a file.",
133            json!({
134                "type": "object",
135                "properties": {
136                    "path": { "type": "string", "description": "File path to analyze" }
137                },
138                "required": ["path"]
139            }),
140        ),
141        tool_def(
142            "ctx_cache",
143            "Cache ops: status|clear|invalidate.",
144            json!({
145                "type": "object",
146                "properties": {
147                    "action": {
148                        "type": "string",
149                        "enum": ["status", "clear", "invalidate"],
150                        "description": "Cache operation to perform"
151                    },
152                    "path": {
153                        "type": "string",
154                        "description": "File path (required for 'invalidate' action)"
155                    }
156                },
157                "required": ["action"]
158            }),
159        ),
160        tool_def(
161            "ctx_discover",
162            "Find missed compression opportunities in shell history.",
163            json!({
164                "type": "object",
165                "properties": {
166                    "limit": {
167                        "type": "integer",
168                        "description": "Max number of command types to show (default: 15)"
169                    }
170                }
171            }),
172        ),
173        tool_def(
174            "ctx_smart_read",
175            "Auto-select optimal read mode for a file.",
176            json!({
177                "type": "object",
178                "properties": {
179                    "path": { "type": "string", "description": "Absolute file path to read" }
180                },
181                "required": ["path"]
182            }),
183        ),
184        tool_def(
185            "ctx_delta",
186            "Incremental diff — sends only changed lines since last read.",
187            json!({
188                "type": "object",
189                "properties": {
190                    "path": { "type": "string", "description": "Absolute file path" }
191                },
192                "required": ["path"]
193            }),
194        ),
195        tool_def(
196            "ctx_edit",
197            "Edit a file via search-and-replace. Works without native Read/Edit tools. Use this when the IDE's Edit tool requires Read but Read is unavailable.",
198            json!({
199                "type": "object",
200                "properties": {
201                    "path": { "type": "string", "description": "Absolute file path" },
202                    "old_string": { "type": "string", "description": "Exact text to find and replace (must be unique unless replace_all=true)" },
203                    "new_string": { "type": "string", "description": "Replacement text" },
204                    "replace_all": { "type": "boolean", "description": "Replace all occurrences (default: false)", "default": false },
205                    "create": { "type": "boolean", "description": "Create a new file with new_string as content (ignores old_string)", "default": false }
206                },
207                "required": ["path", "new_string"]
208            }),
209        ),
210        tool_def(
211            "ctx_dedup",
212            "Cross-file dedup: analyze or apply shared block references.",
213            json!({
214                "type": "object",
215                "properties": {
216                    "action": {
217                        "type": "string",
218                        "description": "analyze (default) or apply (register shared blocks for auto-dedup in ctx_read)",
219                        "default": "analyze"
220                    }
221                }
222            }),
223        ),
224        tool_def(
225            "ctx_fill",
226            "Budget-aware context fill — auto-selects compression per file within token limit.",
227            json!({
228                "type": "object",
229                "properties": {
230                    "paths": {
231                        "type": "array",
232                        "items": { "type": "string" },
233                        "description": "File paths to consider"
234                    },
235                    "budget": {
236                        "type": "integer",
237                        "description": "Maximum token budget to fill"
238                    },
239                    "task": {
240                        "type": "string",
241                        "description": "Optional task for POP intent-driven pruning"
242                    }
243                },
244                "required": ["paths", "budget"]
245            }),
246        ),
247        tool_def(
248            "ctx_intent",
249            "Structured intent input (optional) — submit compact JSON or short text; server also infers intents automatically from tool calls.",
250            json!({
251                "type": "object",
252                "properties": {
253                    "query": { "type": "string", "description": "Compact JSON intent or short text" },
254                    "project_root": { "type": "string", "description": "Project root directory (default: .)" }
255                },
256                "required": ["query"]
257            }),
258        ),
259        tool_def(
260            "ctx_response",
261            "Compress LLM response text (remove filler, apply TDD).",
262            json!({
263                "type": "object",
264                "properties": {
265                    "text": { "type": "string", "description": "Response text to compress" }
266                },
267                "required": ["text"]
268            }),
269        ),
270        tool_def(
271            "ctx_context",
272            "Session context overview — cached files, seen files, session state.",
273            json!({
274                "type": "object",
275                "properties": {}
276            }),
277        ),
278        tool_def(
279            "ctx_graph",
280            "Code dependency graph. Actions: build (index project), related (find files connected to path), \
281symbol (lookup definition/usages as file::name), impact (blast radius of changes to path), status (index stats).",
282            json!({
283                "type": "object",
284                "properties": {
285                    "action": {
286                        "type": "string",
287                        "enum": ["build", "related", "symbol", "impact", "status"],
288                        "description": "Graph operation: build, related, symbol, impact, status"
289                    },
290                    "path": {
291                        "type": "string",
292                        "description": "File path (related/impact) or file::symbol_name (symbol)"
293                    },
294                    "project_root": {
295                        "type": "string",
296                        "description": "Project root directory (default: .)"
297                    }
298                },
299                "required": ["action"]
300            }),
301        ),
302        tool_def(
303            "ctx_session",
304            "Cross-session memory (CCP). Actions: load (restore previous session ~400 tok), \
305save, status, task (set current task), finding (record discovery), decision (record choice), \
306reset, list (show sessions), cleanup.",
307            json!({
308                "type": "object",
309                "properties": {
310                    "action": {
311                        "type": "string",
312                        "enum": ["status", "load", "save", "task", "finding", "decision", "reset", "list", "cleanup"],
313                        "description": "Session operation to perform"
314                    },
315                    "value": {
316                        "type": "string",
317                        "description": "Value for task/finding/decision actions"
318                    },
319                    "session_id": {
320                        "type": "string",
321                        "description": "Session ID for load action (default: latest)"
322                    }
323                },
324                "required": ["action"]
325            }),
326        ),
327        tool_def(
328            "ctx_knowledge",
329            "Persistent project knowledge (survives sessions). Actions: remember (store fact with temporal tracking + contradiction detection), \
330recall (search), pattern (record convention), consolidate (extract session findings), \
331gotcha (record a bug/mistake to never repeat — trigger+resolution required), \
332timeline (view fact history for a category), rooms (list knowledge categories), \
333search (cross-session search across ALL projects), wakeup (compact AAAK briefing), \
334status (list all), remove, export, embeddings_status|embeddings_reset|embeddings_reindex (local semantic index management for recall).",
335            json!({
336                "type": "object",
337                "properties": {
338                    "action": {
339                        "type": "string",
340                        "enum": ["remember", "recall", "pattern", "consolidate", "gotcha", "status", "remove", "export", "timeline", "rooms", "search", "wakeup", "embeddings_status", "embeddings_reset", "embeddings_reindex"],
341                        "description": "Knowledge operation. remember: auto-detects contradictions + tracks temporal validity. timeline: view version history. rooms: list categories. search: cross-project search. wakeup: compact AAAK briefing. embeddings_*: manage local semantic index for recall."
342                    },
343                    "trigger": {
344                        "type": "string",
345                        "description": "For gotcha action: what triggers the bug (e.g. 'cargo build fails with E0507 on match arms')"
346                    },
347                    "resolution": {
348                        "type": "string",
349                        "description": "For gotcha action: how to fix/avoid it (e.g. 'Use .clone() or ref pattern')"
350                    },
351                    "severity": {
352                        "type": "string",
353                        "enum": ["critical", "warning", "info"],
354                        "description": "For gotcha action: severity level (default: warning)"
355                    },
356                    "category": {
357                        "type": "string",
358                        "description": "Fact category (architecture, api, testing, deployment, conventions, dependencies)"
359                    },
360                    "key": {
361                        "type": "string",
362                        "description": "Fact key/identifier (e.g. 'auth-method', 'db-engine', 'test-framework')"
363                    },
364                    "value": {
365                        "type": "string",
366                        "description": "Fact value or pattern description"
367                    },
368                    "query": {
369                        "type": "string",
370                        "description": "Search query for recall action (matches against category, key, and value)"
371                    },
372                    "pattern_type": {
373                        "type": "string",
374                        "description": "Pattern type for pattern action (naming, structure, testing, error-handling)"
375                    },
376                    "examples": {
377                        "type": "array",
378                        "items": { "type": "string" },
379                        "description": "Examples for pattern action"
380                    },
381                    "confidence": {
382                        "type": "number",
383                        "description": "Confidence score 0.0-1.0 for remember action (default: 0.8)"
384                    }
385                },
386                "required": ["action"]
387            }),
388        ),
389        tool_def(
390            "ctx_agent",
391            "Multi-agent coordination (shared message bus + persistent diaries). Actions: register (join with agent_type+role), \
392post (broadcast or direct message with category), read (poll messages), status (update state: active|idle|finished), \
393handoff (transfer task to another agent with summary), sync (overview of all agents + pending messages + shared contexts), \
394diary (log discovery/decision/blocker/progress/insight — persisted across sessions), \
395recall_diary (read agent diary), diaries (list all agent diaries), \
396list, info.",
397            json!({
398                "type": "object",
399                "properties": {
400                    "action": {
401                        "type": "string",
402                        "enum": ["register", "list", "post", "read", "status", "info", "handoff", "sync", "diary", "recall_diary", "diaries"],
403                        "description": "Agent operation. diary: persistent log (category=discovery|decision|blocker|progress|insight). recall_diary: read diary. diaries: list all."
404                    },
405                    "agent_type": {
406                        "type": "string",
407                        "description": "Agent type for register (cursor, claude, codex, gemini, crush, subagent)"
408                    },
409                    "role": {
410                        "type": "string",
411                        "description": "Agent role (dev, review, test, plan)"
412                    },
413                    "message": {
414                        "type": "string",
415                        "description": "Message text for post action, or status detail for status action"
416                    },
417                    "category": {
418                        "type": "string",
419                        "description": "Message category for post (finding, warning, request, status)"
420                    },
421                    "to_agent": {
422                        "type": "string",
423                        "description": "Target agent ID for direct message (omit for broadcast)"
424                    },
425                    "status": {
426                        "type": "string",
427                        "enum": ["active", "idle", "finished"],
428                        "description": "New status for status action"
429                    }
430                },
431                "required": ["action"]
432            }),
433        ),
434        tool_def(
435            "ctx_share",
436            "Share cached file contexts between agents. Actions: push (share files from your cache to another agent), \
437pull (receive files shared by other agents), list (show all shared contexts), clear (remove your shared contexts).",
438            json!({
439                "type": "object",
440                "properties": {
441                    "action": {
442                        "type": "string",
443                        "enum": ["push", "pull", "list", "clear"],
444                        "description": "Share operation to perform"
445                    },
446                    "paths": {
447                        "type": "string",
448                        "description": "Comma-separated file paths to share (for push action)"
449                    },
450                    "to_agent": {
451                        "type": "string",
452                        "description": "Target agent ID (omit for broadcast to all agents)"
453                    },
454                    "message": {
455                        "type": "string",
456                        "description": "Optional context message explaining what was shared"
457                    }
458                },
459                "required": ["action"]
460            }),
461        ),
462        tool_def(
463            "ctx_overview",
464            "Task-relevant project map — use at session start.",
465            json!({
466                "type": "object",
467                "properties": {
468                    "task": {
469                        "type": "string",
470                        "description": "Task description for relevance scoring (e.g. 'fix auth bug in login flow')"
471                    },
472                    "path": {
473                        "type": "string",
474                        "description": "Project root directory (default: .)"
475                    }
476                }
477            }),
478        ),
479        tool_def(
480            "ctx_preload",
481            "Proactive context loader — caches task-relevant files, returns L-curve-optimized summary (~50-100 tokens vs ~5000 for individual reads).",
482            json!({
483                "type": "object",
484                "properties": {
485                    "task": {
486                        "type": "string",
487                        "description": "Task description (e.g. 'fix auth bug in validate_token')"
488                    },
489                    "path": {
490                        "type": "string",
491                        "description": "Project root (default: .)"
492                    }
493                },
494                "required": ["task"]
495            }),
496        ),
497        tool_def(
498            "ctx_prefetch",
499            "Predictive prefetch — prewarm cache for blast radius files (graph + task signals) within budgets.",
500            json!({
501                "type": "object",
502                "properties": {
503                    "root": { "type": "string", "description": "Project root (default: .)" },
504                    "task": { "type": "string", "description": "Optional task for relevance scoring" },
505                    "changed_files": { "type": "array", "items": { "type": "string" }, "description": "Optional changed files (paths) to compute blast radius" },
506                    "budget_tokens": { "type": "integer", "description": "Soft budget hint for mode selection (default: 3000)" },
507                    "max_files": { "type": "integer", "description": "Max files to prefetch (default: 10)" }
508                }
509            }),
510        ),
511        tool_def(
512            "ctx_wrapped",
513            "Savings report card. Periods: week|month|all.",
514            json!({
515                "type": "object",
516                "properties": {
517                    "period": {
518                        "type": "string",
519                        "enum": ["week", "month", "all"],
520                        "description": "Report period (default: week)"
521                    }
522                }
523            }),
524        ),
525        tool_def(
526            "ctx_cost",
527            "Cost attribution (local-first). Actions: report|agent|tools|json|reset.",
528            json!({
529                "type": "object",
530                "properties": {
531                    "action": {
532                        "type": "string",
533                        "enum": ["report", "agent", "tools", "json", "reset", "status"],
534                        "description": "Operation to perform (default: report)"
535                    },
536                    "agent_id": {
537                        "type": "string",
538                        "description": "Agent ID for action=agent (optional)"
539                    },
540                    "limit": {
541                        "type": "integer",
542                        "description": "Max rows (default: 10)"
543                    }
544                }
545            }),
546        ),
547        tool_def(
548            "ctx_gain",
549            "Gain report.",
550            json!({
551                "type": "object",
552                "properties": {
553                    "action": {
554                        "type": "string",
555                        "enum": ["status", "report", "score", "cost", "tasks", "heatmap", "wrapped", "agents", "json"]
556                    },
557                    "period": {
558                        "type": "string",
559                        "enum": ["week", "month", "all"]
560                    },
561                    "model": {
562                        "type": "string"
563                    },
564                    "limit": {
565                        "type": "integer"
566                    }
567                }
568            }),
569        ),
570        tool_def(
571            "ctx_feedback",
572            "Harness feedback for LLM output tokens/latency (local-first). Actions: record|report|json|reset|status.",
573            json!({
574                "type": "object",
575                "properties": {
576                    "action": {
577                        "type": "string",
578                        "enum": ["record", "report", "json", "reset", "status"],
579                        "description": "Operation to perform (default: report)"
580                    },
581                    "agent_id": { "type": "string", "description": "Agent ID (optional; defaults to current agent when available)" },
582                    "intent": { "type": "string", "description": "Intent/task string (optional)" },
583                    "model": { "type": "string", "description": "Model identifier (optional)" },
584                    "llm_input_tokens": { "type": "integer", "description": "Required for action=record" },
585                    "llm_output_tokens": { "type": "integer", "description": "Required for action=record" },
586                    "latency_ms": { "type": "integer", "description": "Optional for action=record" },
587                    "note": { "type": "string", "description": "Optional note (no prompts/PII)" },
588                    "limit": { "type": "integer", "description": "For report/json: how many recent events to consider (default: 500)" }
589                }
590            }),
591        ),
592        tool_def(
593            "ctx_handoff",
594            "Context Ledger Protocol (hashed, deterministic, local-first). Actions: create|show|list|pull|clear.",
595            json!({
596                "type": "object",
597                "properties": {
598                    "action": {
599                        "type": "string",
600                        "enum": ["create", "show", "list", "pull", "clear"],
601                        "description": "Operation to perform (default: list)"
602                    },
603                    "path": { "type": "string", "description": "Ledger file path (for show/pull)" },
604                    "paths": { "type": "array", "items": { "type": "string" }, "description": "Optional file paths to include as signatures-only curated refs (for create)" },
605                    "apply_workflow": { "type": "boolean", "description": "For pull: apply workflow state (default: true)" },
606                    "apply_session": { "type": "boolean", "description": "For pull: apply session/task snapshot (default: true)" },
607                    "apply_knowledge": { "type": "boolean", "description": "For pull: import knowledge facts (default: true)" }
608                }
609            }),
610        ),
611        tool_def(
612            "ctx_heatmap",
613            "File access heatmap (local-first). Actions: status|directory|cold|json.",
614            json!({
615                "type": "object",
616                "properties": {
617                    "action": {
618                        "type": "string",
619                        "enum": ["status", "directory", "dirs", "cold", "json"],
620                        "description": "Operation to perform (default: status)"
621                    },
622                    "path": {
623                        "type": "string",
624                        "description": "Project root for cold scan (default: .)"
625                    }
626                }
627            }),
628        ),
629        tool_def(
630            "ctx_task",
631            "Multi-agent task orchestration. Actions: create|update|list|get|cancel|message|info.",
632            json!({
633                "type": "object",
634                "properties": {
635                    "action": {
636                        "type": "string",
637                        "enum": ["create", "update", "list", "get", "cancel", "message", "info"],
638                        "description": "Task operation"
639                    },
640                    "task_id": { "type": "string", "description": "Task ID (required for update|get|cancel|message)" },
641                    "to_agent": { "type": "string", "description": "Target agent ID (required for create)" },
642                    "description": { "type": "string", "description": "Task description (for create)" },
643                    "state": { "type": "string", "description": "New state for update (working|input-required|completed|failed|canceled)" },
644                    "message": { "type": "string", "description": "Optional message / reason" }
645                },
646                "required": ["action"]
647            }),
648        ),
649        tool_def(
650            "ctx_impact",
651            "Graph-based impact analysis. Actions: analyze|chain|build|status.",
652            json!({
653                "type": "object",
654                "properties": {
655                    "action": {
656                        "type": "string",
657                        "enum": ["analyze", "chain", "build", "status"],
658                        "description": "Impact operation (default: analyze)"
659                    },
660                    "path": { "type": "string", "description": "Target file path (required for analyze). For chain: from->to spec." },
661                    "root": { "type": "string", "description": "Project root (default: .)" },
662                    "depth": { "type": "integer", "description": "Max traversal depth (default: 5)" }
663                }
664            }),
665        ),
666        tool_def(
667            "ctx_architecture",
668            "Graph-based architecture analysis. Actions: overview|clusters|layers|cycles|entrypoints|module.",
669            json!({
670                "type": "object",
671                "properties": {
672                    "action": {
673                        "type": "string",
674                        "enum": ["overview", "clusters", "layers", "cycles", "entrypoints", "module"],
675                        "description": "Architecture operation (default: overview)"
676                    },
677                    "path": { "type": "string", "description": "Used for action=module (module/file path)" },
678                    "root": { "type": "string", "description": "Project root (default: .)" }
679                }
680            }),
681        ),
682        tool_def(
683            "ctx_workflow",
684            "Workflow rails (state machine + evidence). Actions: start|status|transition|complete|evidence_add|evidence_list|stop.",
685            json!({
686                "type": "object",
687                "properties": {
688                    "action": {
689                        "type": "string",
690                        "enum": ["start", "status", "transition", "complete", "evidence_add", "evidence_list", "stop"],
691                        "description": "Workflow operation (default: status)"
692                    },
693                    "name": { "type": "string", "description": "Optional workflow name override (action=start)" },
694                    "spec": { "type": "string", "description": "WorkflowSpec JSON (action=start). If omitted, uses builtin plan_code_test." },
695                    "to": { "type": "string", "description": "Target state (action=transition)" },
696                    "key": { "type": "string", "description": "Evidence key (action=evidence_add)" },
697                    "value": { "type": "string", "description": "Optional evidence value / transition note" }
698                }
699            }),
700        ),
701        tool_def(
702            "ctx_semantic_search",
703            "Semantic code search (BM25 + optional embeddings/hybrid). action=reindex to rebuild.",
704            json!({
705                "type": "object",
706                "properties": {
707                    "query": { "type": "string", "description": "Natural language search query" },
708                    "path": { "type": "string", "description": "Project root to search (default: .)" },
709                    "top_k": { "type": "integer", "description": "Number of results (default: 10)" },
710                    "action": { "type": "string", "description": "reindex to rebuild index" },
711                    "mode": {
712                        "type": "string",
713                        "enum": ["bm25", "dense", "hybrid"],
714                        "description": "Search mode (default: hybrid). bm25=lexical only, dense=embeddings only, hybrid=BM25+embeddings"
715                    },
716                    "languages": {
717                        "type": "array",
718                        "items": { "type": "string" },
719                        "description": "Optional: restrict to languages/extensions (e.g. [\"rust\",\"ts\",\"py\"] or [\"rs\",\"tsx\"])"
720                    },
721                    "path_glob": {
722                        "type": "string",
723                        "description": "Optional: glob over relative file paths (e.g. \"rust/src/**\" or \"**/*.rs\")"
724                    }
725                },
726                "required": ["query"]
727            }),
728        ),
729        tool_def(
730            "ctx_execute",
731            "Run code in sandbox (11 languages). Only stdout enters context. Raw data never leaves subprocess. Languages: javascript, typescript, python, shell, ruby, go, rust, php, perl, r, elixir.",
732            json!({
733                "type": "object",
734                "properties": {
735                    "language": {
736                        "type": "string",
737                        "description": "Language: javascript|typescript|python|shell|ruby|go|rust|php|perl|r|elixir"
738                    },
739                    "code": {
740                        "type": "string",
741                        "description": "Code to execute in sandbox"
742                    },
743                    "intent": {
744                        "type": "string",
745                        "description": "What you want from the output (triggers intent-driven filtering for large results)"
746                    },
747                    "timeout": {
748                        "type": "integer",
749                        "description": "Timeout in seconds (default: 30)"
750                    },
751                    "action": {
752                        "type": "string",
753                        "description": "batch — execute multiple scripts. Provide items as JSON array [{language, code}]"
754                    },
755                    "items": {
756                        "type": "string",
757                        "description": "JSON array of [{\"language\": \"...\", \"code\": \"...\"}] for batch execution"
758                    },
759                    "path": {
760                        "type": "string",
761                        "description": "For action=file: process a file in sandbox (auto-detects language)"
762                    }
763                },
764                "required": ["language", "code"]
765            }),
766        ),
767        tool_def(
768            "ctx_symbol",
769            "Read a specific symbol (function, struct, class) by name. Returns only the symbol \
770code block instead of the entire file. 90-97% fewer tokens than full file read.",
771            json!({
772                "type": "object",
773                "properties": {
774                    "name": { "type": "string", "description": "Symbol name (function, struct, class, method)" },
775                    "file": { "type": "string", "description": "Optional: file path to narrow search" },
776                    "kind": { "type": "string", "description": "Optional: fn|struct|class|method|trait|enum" }
777                },
778                "required": ["name"]
779            }),
780        ),
781        tool_def(
782            "ctx_graph_diagram",
783            "Generate a Mermaid diagram of the dependency or call graph. Useful for understanding architecture.",
784            json!({
785                "type": "object",
786                "properties": {
787                    "file": { "type": "string", "description": "Optional: scope to dependencies of a specific file" },
788                    "depth": { "type": "integer", "description": "Max depth (default: 2)" },
789                    "kind": { "type": "string", "description": "deps (file dependencies) or calls (symbol call graph)" }
790                }
791            }),
792        ),
793        tool_def(
794            "ctx_routes",
795            "List HTTP routes/endpoints extracted from the project. Supports Express, Flask, FastAPI, Actix, Spring, Rails, Next.js.",
796            json!({
797                "type": "object",
798                "properties": {
799                    "method": { "type": "string", "description": "Optional: GET, POST, PUT, DELETE" },
800                    "path": { "type": "string", "description": "Optional: path prefix filter, e.g. /api/users" }
801                }
802            }),
803        ),
804        tool_def(
805            "ctx_compress_memory",
806            "Compress a memory/config file (CLAUDE.md, .cursorrules, etc.) to save tokens on every session start. \
807Preserves code blocks, URLs, paths, headings, tables. Creates .original.md backup.",
808            json!({
809                "type": "object",
810                "properties": {
811                    "path": { "type": "string", "description": "Path to memory file" }
812                },
813                "required": ["path"]
814            }),
815        ),
816        tool_def(
817            "ctx_callers",
818            "Find all symbols that call a given function/method. Returns caller file, symbol, and line.",
819            json!({
820                "type": "object",
821                "properties": {
822                    "symbol": { "type": "string", "description": "Symbol name to find callers of" },
823                    "file": { "type": "string", "description": "Optional: scope to a specific file" }
824                },
825                "required": ["symbol"]
826            }),
827        ),
828        tool_def(
829            "ctx_callees",
830            "Find all functions/methods called by a given symbol. Returns callee name, file, and line.",
831            json!({
832                "type": "object",
833                "properties": {
834                    "symbol": { "type": "string", "description": "Symbol name to find callees of" },
835                    "file": { "type": "string", "description": "Optional: scope to a specific file" }
836                },
837                "required": ["symbol"]
838            }),
839        ),
840        tool_def(
841            "ctx_outline",
842            "List all symbols in a file (functions, structs, classes, methods) with signatures. \
843Much fewer tokens than reading the full file.",
844            json!({
845                "type": "object",
846                "properties": {
847                    "path": { "type": "string", "description": "File path" },
848                    "kind": { "type": "string", "description": "Optional filter: fn|struct|class|all" }
849                },
850                "required": ["path"]
851            }),
852        ),
853    ]
854}
855
856pub fn unified_tool_defs() -> Vec<Tool> {
857    vec![
858        tool_def(
859            "ctx_read",
860            "Read file (cached, compressed). Modes: full|map|signatures|diff|aggressive|entropy|task|reference|lines:N-M. fresh=true re-reads.",
861            json!({
862                "type": "object",
863                "properties": {
864                    "path": { "type": "string", "description": "File path" },
865                    "mode": { "type": "string" },
866                    "start_line": { "type": "integer" },
867                    "fresh": { "type": "boolean" }
868                },
869                "required": ["path"]
870            }),
871        ),
872        tool_def(
873            "ctx_shell",
874            "Run shell command (compressed output). raw=true skips compression. cwd sets working directory.",
875            json!({
876                "type": "object",
877                "properties": {
878                    "command": { "type": "string", "description": "Shell command" },
879                    "raw": { "type": "boolean", "description": "Skip compression for full output" },
880                    "cwd": { "type": "string", "description": "Working directory (defaults to last cd or project root)" }
881                },
882                "required": ["command"]
883            }),
884        ),
885        tool_def(
886            "ctx_search",
887            "Regex code search (.gitignore aware).",
888            json!({
889                "type": "object",
890                "properties": {
891                    "pattern": { "type": "string", "description": "Regex pattern" },
892                    "path": { "type": "string" },
893                    "ext": { "type": "string" },
894                    "max_results": { "type": "integer" },
895                    "ignore_gitignore": { "type": "boolean" }
896                },
897                "required": ["pattern"]
898            }),
899        ),
900        tool_def(
901            "ctx_tree",
902            "Directory listing with file counts.",
903            json!({
904                "type": "object",
905                "properties": {
906                    "path": { "type": "string" },
907                    "depth": { "type": "integer" },
908                    "show_hidden": { "type": "boolean" }
909                }
910            }),
911        ),
912        tool_def(
913            "ctx",
914            "Meta-tool: set tool= to sub-tool name. Sub-tools: compress (checkpoint), metrics (stats), \
915analyze (entropy), cache (status|clear|invalidate), discover (missed patterns), smart_read (auto-mode), \
916delta (incremental diff), dedup (cross-file), fill (budget-aware batch read), intent (auto-read by task), \
917response (compress LLM text), context (session state), graph (build|related|symbol|impact|status), \
918session (load|save|task|finding|decision|status|reset|list|cleanup), \
919knowledge (remember|recall|pattern|consolidate|timeline|rooms|search|wakeup|status|remove|export|embeddings_status|embeddings_reset|embeddings_reindex), \
920agent (register|post|read|status|list|info|diary|recall_diary|diaries), overview (project map), \
921wrapped (savings report), benchmark (file|project), multi_read (batch), semantic_search (BM25), \
922cost (attribution), heatmap (file access), impact (graph impact), architecture (graph structure), \
923task (A2A tasks), workflow (state machine).",
924            json!({
925                "type": "object",
926                "properties": {
927                    "tool": {
928                        "type": "string",
929                        "description": "compress|metrics|analyze|cache|discover|smart_read|delta|dedup|fill|intent|response|context|graph|session|knowledge|agent|overview|wrapped|benchmark|multi_read|semantic_search|cost|heatmap|impact|architecture|task|workflow"
930                    },
931                    "action": { "type": "string" },
932                    "path": { "type": "string" },
933                    "paths": { "type": "array", "items": { "type": "string" } },
934                    "query": { "type": "string" },
935                    "value": { "type": "string" },
936                    "category": { "type": "string" },
937                    "key": { "type": "string" },
938                    "to": { "type": "string" },
939                    "spec": { "type": "string" },
940                    "budget": { "type": "integer" },
941                    "task": { "type": "string" },
942                    "mode": { "type": "string" },
943                    "text": { "type": "string" },
944                    "message": { "type": "string" },
945                    "session_id": { "type": "string" },
946                    "period": { "type": "string" },
947                    "format": { "type": "string" },
948                    "agent_type": { "type": "string" },
949                    "role": { "type": "string" },
950                    "status": { "type": "string" },
951                    "pattern_type": { "type": "string" },
952                    "examples": { "type": "array", "items": { "type": "string" } },
953                    "confidence": { "type": "number" },
954                    "project_root": { "type": "string" },
955                    "include_signatures": { "type": "boolean" },
956                    "limit": { "type": "integer" },
957                    "to_agent": { "type": "string" },
958                    "task_id": { "type": "string" },
959                    "agent_id": { "type": "string" },
960                    "description": { "type": "string" },
961                    "state": { "type": "string" },
962                    "root": { "type": "string" },
963                    "depth": { "type": "integer" },
964                    "show_hidden": { "type": "boolean" }
965                },
966                "required": ["tool"]
967            }),
968        ),
969    ]
970}
971
972const CORE_TOOL_NAMES: &[&str] = &[
973    "ctx_read",
974    "ctx_multi_read",
975    "ctx_shell",
976    "ctx_search",
977    "ctx_tree",
978    "ctx_edit",
979    "ctx_session",
980    "ctx_knowledge",
981];
982
983pub fn lazy_tool_defs() -> Vec<Tool> {
984    let all = granular_tool_defs();
985    let mut core: Vec<Tool> = all
986        .into_iter()
987        .filter(|t| CORE_TOOL_NAMES.contains(&t.name.as_ref()))
988        .collect();
989
990    core.push(tool_def(
991        "ctx_discover_tools",
992        "Search available lean-ctx tools by keyword. Returns matching tool names + descriptions for on-demand loading.",
993        json!({
994            "type": "object",
995            "properties": {
996                "query": {
997                    "type": "string",
998                    "description": "Search keyword (e.g. 'graph', 'cost', 'workflow', 'dedup')"
999                }
1000            },
1001            "required": ["query"]
1002        }),
1003    ));
1004
1005    core
1006}
1007
1008pub fn discover_tools(query: &str) -> String {
1009    let all = list_all_tool_defs();
1010    let query_lower = query.to_lowercase();
1011    let matches: Vec<(&str, &str)> = all
1012        .iter()
1013        .filter(|(name, desc, _)| {
1014            name.to_lowercase().contains(&query_lower) || desc.to_lowercase().contains(&query_lower)
1015        })
1016        .map(|(name, desc, _)| (*name, *desc))
1017        .collect();
1018
1019    if matches.is_empty() {
1020        return format!("No tools found matching '{query}'. Try broader terms like: graph, cost, session, search, compress, agent, workflow, gain.");
1021    }
1022
1023    let mut out = format!("{} tools matching '{query}':\n", matches.len());
1024    for (name, desc) in &matches {
1025        let short = if desc.len() > 80 { &desc[..80] } else { desc };
1026        out.push_str(&format!("  {name} — {short}\n"));
1027    }
1028    out.push_str("\nCall the tool directly by name to use it.");
1029    out
1030}
1031
1032pub fn is_lazy_mode() -> bool {
1033    std::env::var("LEAN_CTX_LAZY_TOOLS").is_ok()
1034}
1035
1036pub fn list_all_tool_defs() -> Vec<(&'static str, &'static str, Value)> {
1037    vec![
1038        ("ctx_read", "Read file (cached, compressed). Re-reads ~13 tok. Auto-selects optimal mode. \
1039Modes: full|map|signatures|diff|aggressive|entropy|task|reference|lines:N-M. fresh=true re-reads.", json!({"type": "object", "properties": {"path": {"type": "string"}, "mode": {"type": "string"}, "start_line": {"type": "integer"}, "fresh": {"type": "boolean"}}, "required": ["path"]})),
1040        ("ctx_multi_read", "Batch read files in one call. Same modes as ctx_read.", json!({"type": "object", "properties": {"paths": {"type": "array", "items": {"type": "string"}}, "mode": {"type": "string"}}, "required": ["paths"]})),
1041        ("ctx_tree", "Directory listing with file counts.", json!({"type": "object", "properties": {"path": {"type": "string"}, "depth": {"type": "integer"}, "show_hidden": {"type": "boolean"}}})),
1042        ("ctx_shell", "Run shell command (compressed output, 90+ patterns). cwd sets working directory.", json!({"type": "object", "properties": {"command": {"type": "string"}, "cwd": {"type": "string", "description": "Working directory"}}, "required": ["command"]})),
1043        ("ctx_search", "Regex code search (.gitignore aware, compact results).", json!({"type": "object", "properties": {"pattern": {"type": "string"}, "path": {"type": "string"}, "ext": {"type": "string"}, "max_results": {"type": "integer"}}, "required": ["pattern"]})),
1044        ("ctx_compress", "Context checkpoint for long conversations.", json!({"type": "object", "properties": {"include_signatures": {"type": "boolean"}}})),
1045        ("ctx_benchmark", "Benchmark compression modes for a file or project.", json!({"type": "object", "properties": {"path": {"type": "string"}, "action": {"type": "string"}, "format": {"type": "string"}}, "required": ["path"]})),
1046        ("ctx_metrics", "Session token stats, cache rates, per-tool savings.", json!({"type": "object", "properties": {}})),
1047        ("ctx_analyze", "Entropy analysis — recommends optimal compression mode for a file.", json!({"type": "object", "properties": {"path": {"type": "string"}}, "required": ["path"]})),
1048        ("ctx_cache", "Cache ops: status|clear|invalidate.", json!({"type": "object", "properties": {"action": {"type": "string"}, "path": {"type": "string"}}, "required": ["action"]})),
1049        ("ctx_discover", "Find missed compression opportunities in shell history.", json!({"type": "object", "properties": {"limit": {"type": "integer"}}})),
1050        ("ctx_smart_read", "Auto-select optimal read mode for a file.", json!({"type": "object", "properties": {"path": {"type": "string"}}, "required": ["path"]})),
1051        ("ctx_delta", "Incremental diff — sends only changed lines since last read.", json!({"type": "object", "properties": {"path": {"type": "string"}}, "required": ["path"]})),
1052        ("ctx_edit", "Edit a file via search-and-replace. Works without native Read/Edit tools. Use when Edit requires Read but Read is unavailable.", json!({"type": "object", "properties": {"path": {"type": "string"}, "old_string": {"type": "string"}, "new_string": {"type": "string"}, "replace_all": {"type": "boolean"}, "create": {"type": "boolean"}}, "required": ["path", "new_string"]})),
1053        ("ctx_dedup", "Cross-file dedup: analyze or apply shared block references.", json!({"type": "object", "properties": {"action": {"type": "string"}}})),
1054        ("ctx_fill", "Budget-aware context fill — auto-selects compression per file within token limit.", json!({"type": "object", "properties": {"paths": {"type": "array", "items": {"type": "string"}}, "budget": {"type": "integer"}, "task": {"type": "string"}}, "required": ["paths", "budget"]})),
1055        ("ctx_intent", "Structured intent input (optional) — submit compact JSON or short text; server also infers intents automatically from tool calls.", json!({"type": "object", "properties": {"query": {"type": "string"}, "project_root": {"type": "string"}}, "required": ["query"]})),
1056        ("ctx_response", "Compress LLM response text (remove filler, apply TDD).", json!({"type": "object", "properties": {"text": {"type": "string"}}, "required": ["text"]})),
1057        ("ctx_context", "Session context overview — cached files, seen files, session state.", json!({"type": "object", "properties": {}})),
1058        ("ctx_graph", "Code dependency graph. Actions: build (index project), related (find files connected to path), \
1059symbol (lookup definition/usages as file::name), impact (blast radius of changes to path), status (index stats).", json!({"type": "object", "properties": {"action": {"type": "string"}, "path": {"type": "string"}, "project_root": {"type": "string"}}, "required": ["action"]})),
1060        ("ctx_session", "Cross-session memory (CCP). Actions: load (restore previous session ~400 tok), \
1061save, status, task (set current task), finding (record discovery), decision (record choice), \
1062reset, list (show sessions), cleanup, snapshot (build compaction snapshot ~2KB), \
1063restore (rebuild state from snapshot after context compaction).", json!({"type": "object", "properties": {"action": {"type": "string"}, "value": {"type": "string"}, "session_id": {"type": "string"}}, "required": ["action"]})),
1064        ("ctx_knowledge", "Persistent project knowledge with temporal facts + contradiction detection. Actions: remember (auto-tracks validity + detects contradictions), recall, pattern, consolidate, \
1065gotcha (record a bug to never repeat — trigger+resolution), timeline (fact version history), rooms (list knowledge categories), \
1066search (cross-session/cross-project), wakeup (compact AAAK briefing), status, remove, export, embeddings_status|embeddings_reset|embeddings_reindex.", json!({"type": "object", "properties": {"action": {"type": "string"}, "category": {"type": "string"}, "key": {"type": "string"}, "value": {"type": "string"}, "query": {"type": "string"}, "trigger": {"type": "string"}, "resolution": {"type": "string"}, "severity": {"type": "string"}}, "required": ["action"]})),
1067        ("ctx_agent", "Multi-agent coordination with persistent diaries. Actions: register, \
1068post, read, status, handoff, sync, diary (log discovery/decision/blocker/progress/insight — persisted), \
1069recall_diary (read diary), diaries (list all), list, info.", json!({"type": "object", "properties": {"action": {"type": "string"}, "agent_type": {"type": "string"}, "role": {"type": "string"}, "message": {"type": "string"}, "to_agent": {"type": "string"}, "status": {"type": "string"}}, "required": ["action"]})),
1070        ("ctx_share", "Share cached file contexts between agents. Actions: push (share files from cache), \
1071pull (receive shared files), list (show all shared contexts), clear (remove your shared contexts).", json!({"type": "object", "properties": {"action": {"type": "string"}, "paths": {"type": "string"}, "to_agent": {"type": "string"}, "message": {"type": "string"}}, "required": ["action"]})),
1072        ("ctx_overview", "Task-relevant project map — use at session start.", json!({"type": "object", "properties": {"task": {"type": "string"}, "path": {"type": "string"}}})),
1073        ("ctx_preload", "Proactive context loader — reads and caches task-relevant files, returns compact L-curve-optimized summary with critical lines, imports, and signatures. Costs ~50-100 tokens instead of ~5000 for individual reads.", json!({"type": "object", "properties": {"task": {"type": "string", "description": "Task description (e.g. 'fix auth bug in validate_token')"}, "path": {"type": "string", "description": "Project root (default: .)"}}, "required": ["task"]})),
1074        ("ctx_prefetch", "Predictive prefetch — prewarm cache for blast radius files (graph + task signals) within budgets.", json!({"type": "object", "properties": {"root": {"type": "string"}, "task": {"type": "string"}, "changed_files": {"type": "array", "items": {"type": "string"}}, "budget_tokens": {"type": "integer"}, "max_files": {"type": "integer"}}})),
1075        ("ctx_wrapped", "Savings report card. Periods: week|month|all.", json!({"type": "object", "properties": {"period": {"type": "string"}}})),
1076        ("ctx_cost", "Cost attribution (local-first). Actions: report|agent|tools|json|reset.", json!({"type": "object", "properties": {"action": {"type": "string"}, "agent_id": {"type": "string"}, "limit": {"type": "integer"}}})),
1077        ("ctx_gain", "Gain report.", json!({"type": "object", "properties": {"action": {"type": "string"}, "period": {"type": "string"}, "model": {"type": "string"}, "limit": {"type": "integer"}}})),
1078        ("ctx_feedback", "Harness feedback for LLM output tokens/latency (local-first). Actions: record|report|json|reset|status.", json!({"type": "object", "properties": {"action": {"type": "string"}, "agent_id": {"type": "string"}, "intent": {"type": "string"}, "model": {"type": "string"}, "llm_input_tokens": {"type": "integer"}, "llm_output_tokens": {"type": "integer"}, "latency_ms": {"type": "integer"}, "note": {"type": "string"}, "limit": {"type": "integer"}}})),
1079        ("ctx_handoff", "Context Ledger Protocol (hashed, deterministic, local-first). Actions: create|show|list|pull|clear.", json!({"type": "object", "properties": {"action": {"type": "string"}, "path": {"type": "string"}, "paths": {"type": "array", "items": {"type": "string"}}, "apply_workflow": {"type": "boolean"}, "apply_session": {"type": "boolean"}, "apply_knowledge": {"type": "boolean"}}})),
1080        ("ctx_heatmap", "File access heatmap (local-first). Actions: status|directory|cold|json.", json!({"type": "object", "properties": {"action": {"type": "string"}, "path": {"type": "string"}}})),
1081        ("ctx_task", "Multi-agent task orchestration. Actions: create|update|list|get|cancel|message|info.", json!({"type": "object", "properties": {"action": {"type": "string"}, "task_id": {"type": "string"}, "to_agent": {"type": "string"}, "description": {"type": "string"}, "state": {"type": "string"}, "message": {"type": "string"}}, "required": ["action"]})),
1082        ("ctx_impact", "Graph-based impact analysis. Actions: analyze|chain|build|status.", json!({"type": "object", "properties": {"action": {"type": "string"}, "path": {"type": "string"}, "root": {"type": "string"}, "depth": {"type": "integer"}}})),
1083        ("ctx_architecture", "Graph-based architecture analysis. Actions: overview|clusters|layers|cycles|entrypoints|module.", json!({"type": "object", "properties": {"action": {"type": "string"}, "path": {"type": "string"}, "root": {"type": "string"}}})),
1084        ("ctx_workflow", "Workflow rails (state machine + evidence). Actions: start|status|transition|complete|evidence_add|evidence_list|stop.", json!({"type": "object", "properties": {"action": {"type": "string"}, "name": {"type": "string"}, "spec": {"type": "string"}, "to": {"type": "string"}, "key": {"type": "string"}, "value": {"type": "string"}}})),
1085        ("ctx_semantic_search", "Semantic code search (BM25 + optional embeddings/hybrid). action=reindex to rebuild.", json!({"type": "object", "properties": {"query": {"type": "string"}, "path": {"type": "string"}, "top_k": {"type": "integer"}, "action": {"type": "string"}, "mode": {"type": "string", "enum": ["bm25","dense","hybrid"]}, "languages": {"type": "array", "items": {"type": "string"}}, "path_glob": {"type": "string"}}, "required": ["query"]})),
1086        ("ctx_execute", "Run code in sandbox (11 languages). Only stdout enters context. Languages: javascript, typescript, python, shell, ruby, go, rust, php, perl, r, elixir. Actions: batch (multiple scripts), file (process file in sandbox).", json!({"type": "object", "properties": {"language": {"type": "string"}, "code": {"type": "string"}, "intent": {"type": "string"}, "timeout": {"type": "integer"}, "action": {"type": "string"}, "items": {"type": "string"}, "path": {"type": "string"}}, "required": ["language", "code"]})),
1087        ("ctx_symbol", "Read a specific symbol (function, struct, class) by name. Returns only the symbol code block instead of the entire file. 90-97% fewer tokens than full file read.", json!({"type": "object", "properties": {"name": {"type": "string"}, "file": {"type": "string"}, "kind": {"type": "string"}}, "required": ["name"]})),
1088        ("ctx_outline", "List all symbols in a file with signatures. Much fewer tokens than reading the full file.", json!({"type": "object", "properties": {"path": {"type": "string"}, "kind": {"type": "string"}}, "required": ["path"]})),
1089        ("ctx_compress_memory", "Compress a memory/config file (CLAUDE.md, .cursorrules) preserving code, URLs, paths. Creates .original.md backup.", json!({"type": "object", "properties": {"path": {"type": "string"}}, "required": ["path"]})),
1090        ("ctx_callers", "Find all symbols that call a given function/method.", json!({"type": "object", "properties": {"symbol": {"type": "string"}, "file": {"type": "string"}}, "required": ["symbol"]})),
1091        ("ctx_callees", "Find all functions/methods called by a given symbol.", json!({"type": "object", "properties": {"symbol": {"type": "string"}, "file": {"type": "string"}}, "required": ["symbol"]})),
1092        ("ctx_routes", "List HTTP routes/endpoints extracted from the project. Supports Express, Flask, FastAPI, Actix, Spring, Rails, Next.js.", json!({"type": "object", "properties": {"method": {"type": "string"}, "path": {"type": "string"}}})),
1093        ("ctx_graph_diagram", "Generate a Mermaid diagram of the dependency or call graph.", json!({"type": "object", "properties": {"file": {"type": "string"}, "depth": {"type": "integer"}, "kind": {"type": "string"}}})),
1094    ]
1095}