1pub mod audit;
56pub mod error;
57pub mod policy;
58pub mod presets;
59pub mod prompts;
60pub mod resources;
61pub mod serde_helpers;
62pub mod state;
63pub mod tools;
64
65pub use error::McpError;
66pub use state::{AppState, CredentialSource};
67
68#[cfg(test)]
69mod tests {
70 use super::*;
71 use std::sync::Arc;
72
73 #[test]
74 fn test_credential_source_profiles() {
75 let source = CredentialSource::Profiles(vec!["test".to_string()]);
76 match source {
77 CredentialSource::Profiles(profiles) => assert_eq!(profiles, vec!["test".to_string()]),
78 _ => panic!("Expected Profiles variant"),
79 }
80 }
81
82 #[test]
83 fn test_credential_source_multiple_profiles() {
84 let source = CredentialSource::Profiles(vec![
85 "cluster-west".to_string(),
86 "cluster-east".to_string(),
87 ]);
88 match source {
89 CredentialSource::Profiles(profiles) => {
90 assert_eq!(profiles.len(), 2);
91 assert_eq!(profiles[0], "cluster-west");
92 assert_eq!(profiles[1], "cluster-east");
93 }
94 _ => panic!("Expected Profiles variant"),
95 }
96 }
97
98 #[test]
99 fn test_credential_source_oauth() {
100 let source = CredentialSource::OAuth {
101 issuer: Some("https://example.com".to_string()),
102 audience: Some("my-api".to_string()),
103 };
104 match source {
105 CredentialSource::OAuth { issuer, audience } => {
106 assert_eq!(issuer, Some("https://example.com".to_string()));
107 assert_eq!(audience, Some("my-api".to_string()));
108 }
109 _ => panic!("Expected OAuth variant"),
110 }
111 }
112
113 #[test]
114 fn test_app_state_read_only() {
115 use policy::{Policy, PolicyConfig};
116 let read_only_policy = Arc::new(Policy::new(
117 PolicyConfig::default(), std::collections::HashMap::new(),
119 "test".to_string(),
120 ));
121 let state =
122 AppState::new(CredentialSource::Profiles(vec![]), read_only_policy, None).unwrap();
123
124 assert!(!state.is_write_allowed());
125 }
126
127 #[test]
128 fn test_app_state_write_allowed() {
129 use policy::{Policy, PolicyConfig, SafetyTier};
130 let write_policy = Arc::new(Policy::new(
131 PolicyConfig {
132 tier: SafetyTier::Full,
133 ..Default::default()
134 },
135 std::collections::HashMap::new(),
136 "test".to_string(),
137 ));
138 let state = AppState::new(CredentialSource::Profiles(vec![]), write_policy, None).unwrap();
139
140 assert!(state.is_write_allowed());
141 }
142
143 #[test]
144 fn test_app_state_database_url() {
145 let state = AppState::new(
146 CredentialSource::Profiles(vec![]),
147 AppState::test_policy(),
148 Some("redis://localhost:6379".to_string()),
149 )
150 .unwrap();
151
152 assert_eq!(
153 state.database_url,
154 Some("redis://localhost:6379".to_string())
155 );
156 }
157
158 #[test]
159 fn test_app_state_available_profiles() {
160 let state = AppState::new(
161 CredentialSource::Profiles(vec![
162 "cluster-west".to_string(),
163 "cluster-east".to_string(),
164 ]),
165 AppState::test_policy(),
166 None,
167 )
168 .unwrap();
169
170 let profiles = state.available_profiles();
171 assert_eq!(profiles.len(), 2);
172 assert_eq!(profiles[0], "cluster-west");
173 assert_eq!(profiles[1], "cluster-east");
174 }
175
176 #[cfg(feature = "cloud")]
177 #[test]
178 fn test_cloud_tools_build() {
179 let state = Arc::new(
180 AppState::new(
181 CredentialSource::Profiles(vec![]),
182 AppState::test_policy(),
183 None,
184 )
185 .unwrap(),
186 );
187
188 let _ = tools::cloud::list_subscriptions(state.clone());
191 let _ = tools::cloud::get_subscription(state.clone());
192 let _ = tools::cloud::list_databases(state.clone());
193 let _ = tools::cloud::get_database(state.clone());
194 let _ = tools::cloud::get_backup_status(state.clone());
195 let _ = tools::cloud::get_slow_log(state.clone());
196 let _ = tools::cloud::get_tags(state.clone());
197 let _ = tools::cloud::get_account(state.clone());
199 let _ = tools::cloud::get_regions(state.clone());
200 let _ = tools::cloud::get_modules(state.clone());
201 let _ = tools::cloud::list_account_users(state.clone());
202 let _ = tools::cloud::get_account_user(state.clone());
203 let _ = tools::cloud::list_acl_users(state.clone());
204 let _ = tools::cloud::get_acl_user(state.clone());
205 let _ = tools::cloud::list_acl_roles(state.clone());
206 let _ = tools::cloud::list_redis_rules(state.clone());
207 let _ = tools::cloud::get_system_logs(state.clone());
209 let _ = tools::cloud::get_session_logs(state.clone());
210 let _ = tools::cloud::list_tasks(state.clone());
212 let _ = tools::cloud::get_task(state.clone());
213 let _ = tools::cloud::create_database(state.clone());
215 let _ = tools::cloud::update_database(state.clone());
216 let _ = tools::cloud::delete_database(state.clone());
217 let _ = tools::cloud::backup_database(state.clone());
218 let _ = tools::cloud::import_database(state.clone());
219 let _ = tools::cloud::delete_subscription(state.clone());
220 let _ = tools::cloud::flush_database(state.clone());
221 let _ = tools::cloud::create_subscription(state.clone());
222 let _ = tools::cloud::cloud_raw_api(state.clone());
224 }
225
226 #[cfg(feature = "enterprise")]
227 #[test]
228 fn test_enterprise_tools_build() {
229 let state = Arc::new(
230 AppState::new(
231 CredentialSource::Profiles(vec![]),
232 AppState::test_policy(),
233 None,
234 )
235 .unwrap(),
236 );
237
238 let _ = tools::enterprise::get_cluster(state.clone());
241 let _ = tools::enterprise::get_license(state.clone());
243 let _ = tools::enterprise::get_license_usage(state.clone());
244 let _ = tools::enterprise::list_logs(state.clone());
246 let _ = tools::enterprise::list_databases(state.clone());
248 let _ = tools::enterprise::get_database(state.clone());
249 let _ = tools::enterprise::list_nodes(state.clone());
251 let _ = tools::enterprise::get_node(state.clone());
252 let _ = tools::enterprise::list_users(state.clone());
254 let _ = tools::enterprise::get_user(state.clone());
255 let _ = tools::enterprise::list_alerts(state.clone());
257 let _ = tools::enterprise::list_database_alerts(state.clone());
258 let _ = tools::enterprise::get_cluster_stats(state.clone());
260 let _ = tools::enterprise::get_database_stats(state.clone());
261 let _ = tools::enterprise::get_node_stats(state.clone());
262 let _ = tools::enterprise::get_all_nodes_stats(state.clone());
263 let _ = tools::enterprise::get_all_databases_stats(state.clone());
264 let _ = tools::enterprise::list_shards(state.clone());
266 let _ = tools::enterprise::get_shard(state.clone());
267 let _ = tools::enterprise::get_shard_stats(state.clone());
268 let _ = tools::enterprise::get_all_shards_stats(state.clone());
269 let _ = tools::enterprise::get_database_endpoints(state.clone());
271 let _ = tools::enterprise::list_debug_info_tasks(state.clone());
273 let _ = tools::enterprise::get_debug_info_status(state.clone());
274 let _ = tools::enterprise::list_modules(state.clone());
276 let _ = tools::enterprise::get_module(state.clone());
277 let _ = tools::enterprise::backup_enterprise_database(state.clone());
279 let _ = tools::enterprise::import_enterprise_database(state.clone());
280 let _ = tools::enterprise::create_enterprise_database(state.clone());
281 let _ = tools::enterprise::update_enterprise_database(state.clone());
282 let _ = tools::enterprise::delete_enterprise_database(state.clone());
283 let _ = tools::enterprise::flush_enterprise_database(state.clone());
284 let _ = tools::enterprise::enterprise_raw_api(state.clone());
286 }
287
288 #[cfg(feature = "database")]
289 #[test]
290 fn test_database_tools_build() {
291 let state = Arc::new(
292 AppState::new(
293 CredentialSource::Profiles(vec![]),
294 AppState::test_policy(),
295 Some("redis://localhost:6379".to_string()),
296 )
297 .unwrap(),
298 );
299
300 let _ = tools::redis::ping(state.clone());
302 let _ = tools::redis::info(state.clone());
303 let _ = tools::redis::keys(state.clone());
304 let _ = tools::redis::get(state.clone());
305 let _ = tools::redis::set(state.clone());
306 let _ = tools::redis::del(state.clone());
307 let _ = tools::redis::flushdb(state.clone());
308 let _ = tools::redis::redis_command(state.clone());
310 }
311
312 #[test]
313 fn test_profile_tools_build() {
314 let state = Arc::new(
315 AppState::new(
316 CredentialSource::Profiles(vec![]),
317 AppState::test_policy(),
318 None,
319 )
320 .unwrap(),
321 );
322
323 let _ = tools::profile::list_profiles(state.clone());
325 let _ = tools::profile::show_profile(state.clone());
326 let _ = tools::profile::config_path(state.clone());
327 let _ = tools::profile::validate_config(state.clone());
328 let _ = tools::profile::set_default_cloud(state.clone());
329 let _ = tools::profile::set_default_enterprise(state.clone());
330 let _ = tools::profile::delete_profile(state.clone());
331 }
332}