lean_ctx/server/
registry.rs1use std::collections::HashMap;
2
3use rmcp::model::Tool;
4
5use super::tool_trait::McpTool;
6
7pub struct ToolRegistry {
11 tools: HashMap<&'static str, Box<dyn McpTool>>,
12}
13
14impl ToolRegistry {
15 pub fn new() -> Self {
16 Self {
17 tools: HashMap::new(),
18 }
19 }
20
21 pub fn register(&mut self, tool: Box<dyn McpTool>) {
22 self.tools.insert(tool.name(), tool);
23 }
24
25 pub fn get(&self, name: &str) -> Option<&dyn McpTool> {
26 self.tools.get(name).map(AsRef::as_ref)
27 }
28
29 pub fn contains(&self, name: &str) -> bool {
30 self.tools.contains_key(name)
31 }
32
33 pub fn tool_defs(&self) -> Vec<Tool> {
36 let mut defs: Vec<Tool> = self.tools.values().map(|t| t.tool_def()).collect();
37 defs.sort_by(|a, b| a.name.as_ref().cmp(b.name.as_ref()));
38 defs
39 }
40
41 pub fn active_tool_defs(&self) -> Vec<Tool> {
44 let Ok(state) = super::dynamic_tools::global().lock() else {
45 tracing::warn!("dynamic_tools mutex poisoned in active_tool_defs; returning all");
46 return self.tool_defs();
47 };
48 let mut defs: Vec<Tool> = self
49 .tools
50 .values()
51 .filter(|t| state.is_tool_active(t.name()))
52 .map(|t| t.tool_def())
53 .collect();
54 defs.sort_by(|a, b| a.name.as_ref().cmp(b.name.as_ref()));
55 defs
56 }
57
58 pub fn profile_tool_defs(
61 &self,
62 profile: &crate::core::tool_profiles::ToolProfile,
63 ) -> Vec<Tool> {
64 let mut defs: Vec<Tool> = self
65 .tools
66 .values()
67 .filter(|t| profile.is_tool_enabled(t.name()))
68 .map(|t| t.tool_def())
69 .collect();
70 defs.sort_by(|a, b| a.name.as_ref().cmp(b.name.as_ref()));
71 defs
72 }
73
74 pub fn len(&self) -> usize {
75 self.tools.len()
76 }
77
78 pub fn is_empty(&self) -> bool {
79 self.tools.is_empty()
80 }
81
82 pub fn names(&self) -> Vec<&'static str> {
83 let mut names: Vec<_> = self.tools.keys().copied().collect();
84 names.sort_unstable();
85 names
86 }
87}
88
89impl Default for ToolRegistry {
90 fn default() -> Self {
91 Self::new()
92 }
93}
94
95pub fn tool_count() -> usize {
99 build_registry().len()
100}
101
102pub fn build_registry() -> ToolRegistry {
105 let mut registry = ToolRegistry::new();
106
107 use crate::tools::registered;
108 registry.register(Box::new(registered::ctx_tree::CtxTreeTool));
109 registry.register(Box::new(registered::ctx_benchmark::CtxBenchmarkTool));
110 registry.register(Box::new(registered::ctx_analyze::CtxAnalyzeTool));
111 registry.register(Box::new(registered::ctx_discover::CtxDiscoverTool));
112 registry.register(Box::new(registered::ctx_response::CtxResponseTool));
113 registry.register(Box::new(registered::ctx_heatmap::CtxHeatmapTool));
114 registry.register(Box::new(registered::ctx_verify::CtxVerifyTool));
115 registry.register(Box::new(registered::ctx_outline::CtxOutlineTool));
116 registry.register(Box::new(registered::ctx_cost::CtxCostTool));
117 registry.register(Box::new(registered::ctx_gain::CtxGainTool));
118 registry.register(Box::new(registered::ctx_expand::CtxExpandTool));
119 registry.register(Box::new(registered::ctx_routes::CtxRoutesTool));
120 registry.register(Box::new(registered::ctx_call::CtxCallTool));
121 registry.register(Box::new(registered::ctx_callgraph::CtxCallgraphTool));
122 registry.register(Box::new(registered::ctx_refactor::CtxRefactorTool));
123 registry.register(Box::new(registered::ctx_repomap::CtxRepomapTool));
124 registry.register(Box::new(registered::ctx_symbol::CtxSymbolTool));
125 registry.register(Box::new(
126 registered::ctx_discover_tools::CtxDiscoverToolsTool,
127 ));
128 registry.register(Box::new(registered::ctx_review::CtxReviewTool));
129 registry.register(Box::new(registered::ctx_provider::CtxProviderTool));
130 registry.register(Box::new(registered::ctx_impact::CtxImpactTool));
131 registry.register(Box::new(registered::ctx_architecture::CtxArchitectureTool));
132 registry.register(Box::new(registered::ctx_smells::CtxSmellsTool));
133 registry.register(Box::new(registered::ctx_pack::CtxPackTool));
134 registry.register(Box::new(registered::ctx_plugins::CtxPluginsTool));
135 registry.register(Box::new(registered::ctx_rules::CtxRulesTool));
136 registry.register(Box::new(registered::ctx_index::CtxIndexTool));
137 registry.register(Box::new(registered::ctx_artifacts::CtxArtifactsTool));
138 registry.register(Box::new(
139 registered::ctx_compress_memory::CtxCompressMemoryTool,
140 ));
141 registry.register(Box::new(registered::ctx_read::CtxReadTool));
142 registry.register(Box::new(registered::ctx_multi_read::CtxMultiReadTool));
143 registry.register(Box::new(registered::ctx_multi_repo::CtxMultiRepoTool));
144 registry.register(Box::new(registered::ctx_smart_read::CtxSmartReadTool));
145 registry.register(Box::new(registered::ctx_delta::CtxDeltaTool));
146 registry.register(Box::new(registered::ctx_edit::CtxEditTool));
147 registry.register(Box::new(registered::ctx_fill::CtxFillTool));
148 registry.register(Box::new(registered::ctx_shell::CtxShellTool));
149 registry.register(Box::new(registered::shell_alias::ShellAliasTool));
150 registry.register(Box::new(registered::ctx_search::CtxSearchTool));
151 registry.register(Box::new(registered::ctx_compose::CtxComposeTool));
152 registry.register(Box::new(registered::ctx_execute::CtxExecuteTool));
153
154 registry.register(Box::new(registered::ctx_compress::CtxCompressTool));
156 registry.register(Box::new(registered::ctx_metrics::CtxMetricsTool));
157 registry.register(Box::new(registered::ctx_radar::CtxRadarTool));
158 registry.register(Box::new(registered::ctx_dedup::CtxDedupTool));
159 registry.register(Box::new(registered::ctx_intent::CtxIntentTool));
160 registry.register(Box::new(registered::ctx_context::CtxContextTool));
161 registry.register(Box::new(registered::ctx_graph::CtxGraphTool));
162 registry.register(Box::new(registered::ctx_proof::CtxProofTool));
163 registry.register(Box::new(registered::ctx_cache::CtxCacheTool));
164 registry.register(Box::new(registered::ctx_ledger::CtxLedgerTool));
165 registry.register(Box::new(registered::ctx_retrieve::CtxRetrieveTool));
166 registry.register(Box::new(registered::ctx_overview::CtxOverviewTool));
167 registry.register(Box::new(registered::ctx_preload::CtxPreloadTool));
168 registry.register(Box::new(registered::ctx_prefetch::CtxPrefetchTool));
169 registry.register(Box::new(
170 registered::ctx_semantic_search::CtxSemanticSearchTool,
171 ));
172 registry.register(Box::new(registered::ctx_feedback::CtxFeedbackTool));
173 registry.register(Box::new(registered::ctx_control::CtxControlTool));
174 registry.register(Box::new(registered::ctx_plan::CtxPlanTool));
175 registry.register(Box::new(registered::ctx_compile::CtxCompileTool));
176
177 registry.register(Box::new(registered::ctx_session::CtxSessionTool));
179 registry.register(Box::new(registered::ctx_knowledge::CtxKnowledgeTool));
180 registry.register(Box::new(registered::ctx_agent::CtxAgentTool));
181 registry.register(Box::new(registered::ctx_share::CtxShareTool));
182 registry.register(Box::new(registered::ctx_task::CtxTaskTool));
183 registry.register(Box::new(registered::ctx_handoff::CtxHandoffTool));
184 registry.register(Box::new(registered::ctx_workflow::CtxWorkflowTool));
185 registry.register(Box::new(registered::ctx_load_tools::CtxLoadToolsTool));
186
187 registry
188}