Skip to main content
Glama

Convex MCP server

Official
by get-convex
file_based_routing.rs3.42 kB
use std::collections::{ btree_map::Entry, BTreeMap, }; use common::{ bootstrap_model::components::definition::ComponentExport, components::Reference, }; use errors::ErrorMetadata; use sync_types::{ path::PathComponent, CanonicalizedModulePath, CanonicalizedUdfPath, FunctionName, ModulePath, }; use crate::modules::module_versions::{ AnalyzedModule, Visibility, }; pub fn file_based_exports( functions: &BTreeMap<CanonicalizedModulePath, AnalyzedModule>, ) -> anyhow::Result<BTreeMap<PathComponent, ComponentExport>> { let mut exports = BTreeMap::new(); for (module_path, module) in functions { let stripped = module_path.clone().strip(); let identifiers = stripped .components() .collect::<anyhow::Result<Vec<_>>>() .or_else(|e| { anyhow::bail!(ErrorMetadata::bad_request( "InvalidModulePath", e.to_string() )) })?; for function in &module.functions { if function.visibility != Some(Visibility::Public) { continue; } let mut path = identifiers.clone(); path.push(function.name.clone().into()); let (last, prefix) = path.split_last().unwrap(); let mut current = &mut exports; for identifier in prefix { let current_node = current .entry(identifier.clone()) .or_insert_with(|| ComponentExport::Branch(BTreeMap::new())); current = match current_node { ComponentExport::Branch(ref mut branch) => branch, ComponentExport::Leaf(..) => anyhow::bail!(ErrorMetadata::bad_request( "InvalidExport", format!( "Path {module_path:?}:{} conflicts with existing export", function.name ) )), } } match current.entry(last.clone()) { Entry::Vacant(e) => { let path = CanonicalizedUdfPath::new(module_path.clone(), function.name.clone()); let reference = Reference::Function(path); e.insert(ComponentExport::Leaf(reference)); }, Entry::Occupied(_) => anyhow::bail!(ErrorMetadata::bad_request( "InvalidExport", format!( "Path {module_path:?}:{} conflicts with existing export", function.name ) )), } } } Ok(exports) } pub fn export_to_udf_path(attributes: &[PathComponent]) -> anyhow::Result<CanonicalizedUdfPath> { let Some((last, prefix)) = attributes.split_last() else { anyhow::bail!("Expected at least one path component"); }; let mut module_path = String::new(); let mut first = true; for attribute in prefix { if !first { module_path.push('/'); } module_path.push_str(&attribute[..]); first = false; } let module_path: ModulePath = module_path.parse()?; let name: FunctionName = last.parse()?; Ok(CanonicalizedUdfPath::new(module_path.canonicalize(), name)) }

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/get-convex/convex-backend'

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