Skip to main content
Glama

NervusDB MCP Server

Official
by nervusdb
lib.rs6.65 kB
#![deny(clippy::all)] use napi::bindgen_prelude::*; use napi_derive::napi; use synapse_parser::{ LanguageManager as RustLanguageManager, LegacyASTParser as RustParser, }; /// NAPI AST Parser(旧版 - 保持向后兼容) #[napi(js_name = "ASTParser")] pub struct ASTParser { inner: RustParser, } /// Legacy AST Parser(别名,用于明确标识) pub type LegacyASTParser = ASTParser; #[napi] impl ASTParser { /// 创建新的解析器实例 #[napi(constructor)] pub fn new() -> Result<Self> { let inner = RustParser::new().map_err(|e| Error::from_reason(e))?; Ok(Self { inner }) } /// 解析文件 /// /// # Arguments /// /// * `file_path` - 文件路径 /// * `source_code` - 源代码内容 /// /// # Returns /// /// 返回 JSON 序列化的 ParseResult #[napi] pub fn parse_file(&mut self, file_path: String, source_code: String) -> Result<String> { let result = self .inner .parse_file(&file_path, &source_code) .map_err(|e| Error::from_reason(e))?; // 序列化为 JSON serde_json::to_string(&result).map_err(|e| Error::from_reason(e.to_string())) } /// 获取支持的文件扩展名 #[napi] pub fn get_supported_extensions() -> Vec<String> { vec![ ".ts".to_string(), ".tsx".to_string(), ".js".to_string(), ".jsx".to_string(), ] } /// 批量解析文件(性能优化版本) /// /// # Arguments /// /// * `files` - 文件列表,每个元素为 [file_path, source_code] /// /// # Returns /// /// 返回 JSON 数组,每个元素为解析结果 #[napi] pub fn parse_files_batch(&mut self, files: Vec<Vec<String>>) -> Result<Vec<String>> { files .into_iter() .map(|file_info| { if file_info.len() != 2 { return Err(Error::from_reason("Each file must have [path, content]")); } let file_path = &file_info[0]; let source_code = &file_info[1]; let result = self .inner .parse_file(file_path, source_code) .map_err(|e| Error::from_reason(e))?; serde_json::to_string(&result).map_err(|e| Error::from_reason(e.to_string())) }) .collect() } } /// 性能基准测试辅助函数 /// /// # Arguments /// /// * `source_code` - 源代码内容 /// * `iterations` - 迭代次数 /// /// # Returns /// /// 平均每次解析耗时(秒) #[napi] pub fn benchmark_parse(source_code: String, iterations: u32) -> Result<f64> { use std::time::Instant; let mut parser = RustParser::new().map_err(|e| Error::from_reason(e))?; let start = Instant::now(); for _ in 0..iterations { let _ = parser.parse_file("bench.ts", &source_code); } let duration = start.elapsed(); Ok(duration.as_secs_f64() / iterations as f64) } /// 解析文件并返回统计信息(用于快速检查) /// /// # Arguments /// /// * `source_code` - 源代码内容 /// /// # Returns /// /// 返回统计信息:{"functions": 10, "classes": 2, "imports": 5, "errors": 0} #[napi(object)] pub struct ParseStats { pub functions: u32, pub classes: u32, pub interfaces: u32, pub imports: u32, pub exports: u32, pub errors: u32, } #[napi] pub fn get_parse_stats(source_code: String) -> Result<ParseStats> { let mut parser = RustParser::new().map_err(|e| Error::from_reason(e))?; let result = parser .parse_file("temp.ts", &source_code) .map_err(|e| Error::from_reason(e))?; let mut stats = ParseStats { functions: 0, classes: 0, interfaces: 0, imports: result.imports.len() as u32, exports: result.exports.len() as u32, errors: result.errors.len() as u32, }; for entity in result.entities { match entity { synapse_parser::CodeEntity::Function(_) => stats.functions += 1, synapse_parser::CodeEntity::Class(_) => stats.classes += 1, synapse_parser::CodeEntity::Interface(_) => stats.interfaces += 1, _ => {} } } Ok(stats) } // ==================== 新版多语言 API ==================== /// 多语言解析器管理器(新版 API) #[napi] pub struct LanguageManager { inner: RustLanguageManager, } #[napi] impl LanguageManager { /// 创建新的语言管理器 #[napi(constructor)] pub fn new() -> Result<Self> { Ok(Self { inner: RustLanguageManager::new(), }) } /// 根据文件路径自动检测语言并解析 #[napi] pub fn parse_file(&mut self, file_path: String, source_code: String) -> Result<String> { let result = self .inner .parse_file(&file_path, &source_code) .map_err(|e| Error::from_reason(e))?; serde_json::to_string(&result).map_err(|e| Error::from_reason(e.to_string())) } /// 批量解析文件(性能优化版本) /// /// # Arguments /// /// * `files` - 文件列表,每个元素为 [file_path, source_code] /// /// # Returns /// /// 返回 JSON 数组,每个元素为解析结果 #[napi] pub fn parse_files_batch(&mut self, files: Vec<Vec<String>>) -> Result<Vec<String>> { let files_tuple: Vec<(String, String)> = files .into_iter() .filter_map(|file_info| { if file_info.len() == 2 { Some((file_info[0].clone(), file_info[1].clone())) } else { None } }) .collect(); let results = self .inner .parse_files_batch(files_tuple) .map_err(|e| Error::from_reason(e))?; results .iter() .map(|r| serde_json::to_string(r).map_err(|e| Error::from_reason(e.to_string()))) .collect() } /// 根据文件路径猜测语言 #[napi] pub fn guess_language(&self, file_path: String) -> Option<String> { self.inner.guess_language(&file_path).map(|lang| format!("{}", lang)) } /// 获取支持的语言列表 #[napi] pub fn get_supported_languages() -> Vec<String> { RustLanguageManager::supported_languages() .iter() .map(|lang| format!("{}", lang)) .collect() } }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/nervusdb/nervusdb-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server