Skip to main content
Glama

louvain

Detect communities in single-cell RNA sequencing data using the Louvain clustering algorithm to identify cell types and functional groups.

Instructions

Louvain clustering algorithm for community detection

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
resolutionNoFor the default flavor ('vtraag') or for 'RAPIDS', you can provide a resolution (higher resolution means finding more and smaller clusters), which defaults to 1.0.
random_stateNoChange the initialization of the optimization.
key_addedNoKey under which to add the cluster labels.louvain
flavorNoPackage for computing the clustering: 'vtraag' (default, more powerful), 'igraph' (built-in method), or 'rapids' (GPU accelerated).vtraag
directedNoInterpret the adjacency matrix as directed graph.
use_weightsNoUse weights from knn graph.
partition_kwargsNoKey word arguments to pass to partitioning, if 'vtraag' method is being used.
neighbors_keyNoUse neighbors connectivities as adjacency. If specified, louvain looks .obsp[.uns[neighbors_key]['connectivities_key']] for connectivities.
obspNoUse .obsp[obsp] as adjacency. You can't specify both `obsp` and `neighbors_key` at the same time.

Implementation Reference

  • Generic handler function that dispatches to sc.tl.louvain for the 'louvain' tool by inspecting signature and calling with provided arguments.
    def run_tl_func(ads, func, arguments): adata = ads.adata_dic[ads.active] if func not in tl_func: raise ValueError(f"Unsupported function: {func}") run_func = tl_func[func] parameters = inspect.signature(run_func).parameters kwargs = {k: arguments.get(k) for k in parameters if k in arguments} try: res = run_func(adata, **kwargs) add_op_log(adata, run_func, kwargs) except Exception as e: logger.error(f"Error running function {func}: {e}") raise return
  • Pydantic input schema model for the louvain tool, defining parameters like resolution, flavor, etc., with validators.
    class LouvainModel(JSONParsingModel): """Input schema for the Louvain clustering algorithm.""" resolution: Optional[float] = Field( default=None, description="For the default flavor ('vtraag') or for 'RAPIDS', you can provide a resolution (higher resolution means finding more and smaller clusters), which defaults to 1.0." ) random_state: int = Field( default=0, description="Change the initialization of the optimization." ) key_added: str = Field( default='louvain', description="Key under which to add the cluster labels." ) flavor: Literal['vtraag', 'igraph', 'rapids'] = Field( default='vtraag', description="Package for computing the clustering: 'vtraag' (default, more powerful), 'igraph' (built-in method), or 'rapids' (GPU accelerated)." ) directed: bool = Field( default=True, description="Interpret the adjacency matrix as directed graph." ) use_weights: bool = Field( default=False, description="Use weights from knn graph." ) partition_kwargs: Optional[Dict[str, Any]] = Field( default=None, description="Key word arguments to pass to partitioning, if 'vtraag' method is being used." ) neighbors_key: Optional[str] = Field( default=None, description="Use neighbors connectivities as adjacency. If specified, louvain looks .obsp[.uns[neighbors_key]['connectivities_key']] for connectivities." ) obsp: Optional[str] = Field( default=None, description="Use .obsp[obsp] as adjacency. You can't specify both `obsp` and `neighbors_key` at the same time." ) @field_validator('resolution') def validate_resolution(cls, v: Optional[float]) -> Optional[float]: """Validate resolution is positive if provided""" if v is not None and v <= 0: raise ValueError("resolution must be a positive number") return v @field_validator('obsp', 'neighbors_key') def validate_graph_source(cls, v: Optional[str], info: ValidationInfo) -> Optional[str]: """Validate that obsp and neighbors_key are not both specified""" values = info.data if v is not None and 'obsp' in values and 'neighbors_key' in values: if values['obsp'] is not None and values['neighbors_key'] is not None: raise ValueError("Cannot specify both obsp and neighbors_key") return v @field_validator('flavor') def validate_flavor(cls, v: str) -> str: """Validate flavor is supported""" if v not in ['vtraag', 'igraph', 'rapids']: raise ValueError("flavor must be one of 'vtraag', 'igraph', or 'rapids'") return v
  • Creates the MCP Tool instance for 'louvain' with name, description, and schema reference.
    # Add louvain tool louvain_tool = types.Tool( name="louvain", description="Louvain clustering algorithm for community detection", inputSchema=LouvainModel.model_json_schema(), )
  • Registers the louvain_tool in the tl_tools dictionary, which is provided to the MCP server.
    tl_tools = { "tsne": tsne_tool, "umap": umap_tool, "draw_graph": draw_graph_tool, "diffmap": diffmap_tool, "embedding_density": embedding_density_tool, "leiden": leiden_tool, "louvain": louvain_tool, "dendrogram": dendrogram_tool, "dpt": dpt_tool, "paga": paga_tool, "ingest": ingest_tool, "rank_genes_groups": rank_genes_groups_tool, "filter_rank_genes_groups": filter_rank_genes_groups_tool, "marker_gene_overlap": marker_gene_overlap_tool, "score_genes": score_genes_tool, "score_genes_cell_cycle": score_genes_cell_cycle_tool, }
  • MCP server.list_tools() decorator that includes tl_tools.values(), exposing the louvain tool to clients.
    @server.list_tools() async def list_tools() -> list[types.Tool]: if MODULE == "io": tools = io_tools.values() elif MODULE == "pp": tools = pp_tools.values() elif MODULE == "tl": tools = tl_tools.values() elif MODULE == "pl": tools = pl_tools.values() elif MODULE == "util": tools = util_tools.values() else: tools = [ *io_tools.values(), *pp_tools.values(), *tl_tools.values(), *pl_tools.values(), *util_tools.values(), *ccc_tools.values(), ] return tools

Latest Blog Posts

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/huang-sh/scmcp'

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