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
Tool call template
This tool declares no required parameters. Add optional parameters from the input schema as needed.
{
"id": 1,
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"arguments": {},
"name": "louvain"
}
}Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| resolution | No | 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 | No | Change the initialization of the optimization. | |
| key_added | No | Key under which to add the cluster labels. | louvain |
| flavor | No | Package for computing the clustering: 'vtraag' (default, more powerful), 'igraph' (built-in method), or 'rapids' (GPU accelerated). | vtraag |
| directed | No | Interpret the adjacency matrix as directed graph. | |
| use_weights | No | Use weights from knn graph. | |
| partition_kwargs | No | Key word arguments to pass to partitioning, if 'vtraag' method is being used. | |
| neighbors_key | No | Use neighbors connectivities as adjacency. If specified, louvain looks .obsp[.uns[neighbors_key]['connectivities_key']] for connectivities. | |
| obsp | No | Use .obsp[obsp] as adjacency. You can't specify both `obsp` and `neighbors_key` at the same time. |
Implementation Reference
- src/scmcp/tool/tl.py:164-177 (handler)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 - src/scmcp/schema/tl.py:344-414 (schema)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 - src/scmcp/tool/tl.py:54-59 (registration)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(), ) - src/scmcp/tool/tl.py:145-162 (registration)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, } - src/scmcp/server.py:35-56 (registration)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