1pub mod analysis;
4pub mod files;
5pub mod search;
6
7use rmcp::model::{ErrorCode, Tool};
8use schemars::JsonSchema;
9use serde::{Deserialize, Serialize};
10use serde_json::Value;
11use std::sync::Arc;
12
13pub fn invalid_params(msg: impl Into<String>) -> rmcp::ErrorData {
15 rmcp::ErrorData::new(ErrorCode::INVALID_PARAMS, msg.into(), None)
16}
17
18pub fn parse_params<T: serde::de::DeserializeOwned>(
20 args: Option<&serde_json::Map<String, Value>>,
21) -> Result<T, rmcp::ErrorData> {
22 let args = args.ok_or_else(|| invalid_params("Missing required parameters"))?;
23
24 serde_json::from_value(Value::Object(args.clone())).map_err(|e| invalid_params(e.to_string()))
25}
26
27fn schema_for<T: JsonSchema>() -> Arc<serde_json::Map<String, serde_json::Value>> {
29 let schema = schemars::schema_for!(T);
30 let value = serde_json::to_value(schema).unwrap_or_default();
31 if let serde_json::Value::Object(obj) = value {
32 Arc::new(obj)
33 } else {
34 Arc::new(serde_json::Map::new())
35 }
36}
37
38pub fn get_all_tools() -> Vec<Tool> {
40 vec![
41 search::search_symbols_tool(),
43 search::get_definition_tool(),
44 search::find_references_tool(),
45 files::get_file_tool(),
47 files::get_file_tree_tool(),
48 analysis::get_callers_tool(),
50 analysis::get_callees_tool(),
51 analysis::smart_context_tool(),
52 ]
53}
54
55#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
59pub struct SearchParams {
60 pub query: String,
62 #[serde(default = "default_limit")]
64 pub limit: Option<i32>,
65 pub kind: Option<String>,
67 pub file: Option<String>,
69}
70
71#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
73pub struct DefinitionParams {
74 pub symbol: String,
76 pub file: Option<String>,
78 pub kind: Option<String>,
80}
81
82#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
84pub struct ReferencesParams {
85 pub symbol: String,
87 pub file: Option<String>,
89}
90
91#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
93pub struct GetFileParams {
94 pub path: String,
96}
97
98#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
100pub struct FileTreeParams {
101 pub path: Option<String>,
103 pub pattern: Option<String>,
105 pub depth: Option<u32>,
107}
108
109#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
111pub struct CallGraphParams {
112 pub function: String,
114 pub file: Option<String>,
116 #[serde(default = "default_depth")]
118 pub depth: Option<i32>,
119}
120
121#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
123pub struct SmartContextParams {
124 pub task: String,
126 #[serde(default = "default_max_tokens")]
128 pub max_tokens: Option<usize>,
129 #[serde(default = "default_depth")]
131 pub depth: Option<i32>,
132 #[serde(default = "default_top")]
134 pub top: Option<usize>,
135 #[serde(default)]
137 pub provider: Option<String>,
138 #[serde(default)]
140 pub use_openai: Option<bool>,
141}
142
143fn default_limit() -> Option<i32> {
144 Some(20)
145}
146
147fn default_depth() -> Option<i32> {
148 Some(3)
149}
150
151fn default_max_tokens() -> Option<usize> {
152 Some(8000)
153}
154
155fn default_top() -> Option<usize> {
156 Some(10)
157}