Skip to main content
Glama
pickleton89

cBioPortal MCP Server

by pickleton89

get_multiple_genes

Retrieve genomic information for multiple cancer-related genes simultaneously from cBioPortal's cancer genomics database.

Instructions

Get information about multiple genes concurrently.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
gene_idsYes
gene_id_typeNoENTREZ_GENE_ID
projectionNoSUMMARY

Implementation Reference

  • MCP tool handler for get_multiple_genes, delegates to GenesEndpoints implementation.
    async def get_multiple_genes(
        self,
        gene_ids: List[str],
        gene_id_type: str = "ENTREZ_GENE_ID",
        projection: str = "SUMMARY",
    ) -> Dict:
        """Get information about multiple genes concurrently."""
        return await self.genes.get_multiple_genes(gene_ids, gene_id_type, projection)
  • Core implementation of get_multiple_genes using concurrent batch fetches to the cBioPortal genes/fetch endpoint, with error handling, batching, and metadata.
    async def get_multiple_genes(
        self,
        gene_ids: List[str],
        gene_id_type: str = "ENTREZ_GENE_ID",
        projection: str = "SUMMARY",
    ) -> Dict:
        """
        Get information about multiple genes concurrently.
    
        This method uses concurrency to fetch multiple genes in parallel,
        which is much more efficient than sequential requests for large batches.
    
        Args:
            gene_ids: List of gene IDs (Entrez IDs or Hugo symbols)
            gene_id_type: Type of gene ID provided (ENTREZ_GENE_ID or HUGO_GENE_SYMBOL)
            projection: Level of detail to return (ID, SUMMARY, DETAILED)
    
        Returns:
            Dictionary with gene information and performance metadata
        """
        overall_start_time = time.time()  # Single start time for the whole operation
        if not gene_ids:
            return {
                "genes": {},
                "metadata": {
                    "count": 0,
                    "total_requested": 0,
                    "errors": 0,
                    "concurrent": True,
                    "batches": 0,
                    "execution_time": round(time.time() - overall_start_time, 3),
                },
            }
    
        # For large gene lists, break into smaller batches for API compatibility
        batch_size = (
            self.config.get("api.batch_size.genes", 100) if self.config
            else 100  # Default to 100 if no config provided
        )
        gene_batches = [
            gene_ids[i : i + batch_size] for i in range(0, len(gene_ids), batch_size)
        ]
    
        async def fetch_gene_batch(batch):
            try:
                params = {"geneIdType": gene_id_type, "projection": projection}
                batch_data = await self.api_client.make_api_request(
                    "genes/fetch", method="POST", params=params, json_data=batch
                )
                return {"data": batch_data, "success": True}
            except Exception as e:
                return {"error": str(e), "success": False}
    
        # Create tasks for all batches and run them concurrently
        tasks = [fetch_gene_batch(batch) for batch in gene_batches]
        batch_results = await asyncio.gather(*tasks)
    
        # Process results
        all_genes = []
        error_count = 0
    
        for result in batch_results:
            if result["success"]:
                all_genes.extend(result["data"])
            else:
                error_count += 1
    
        # Convert to dictionary for easier lookup
        genes_dict = {}
        key_field = (
            "hugoGeneSymbol" if gene_id_type == "HUGO_GENE_SYMBOL" else "entrezGeneId"
        )
        for gene in all_genes:
            gene_key_value = gene.get(key_field)
            if gene_key_value:
                genes_dict[str(gene_key_value)] = gene
    
        return {
            "genes": genes_dict,
            "metadata": {
                "count": len(genes_dict),
                "total_requested": len(gene_ids),
                "errors": error_count,
                "execution_time": round(time.time() - overall_start_time, 3),
                "concurrent": True,
                "batches": len(gene_batches),
            },
        }
  • Tool registration method that includes 'get_multiple_genes' in the tool_methods list and registers it with FastMCP via self.mcp.add_tool.
    def _register_tools(self):
        """Register tool methods as MCP tools."""
        # List of methods to register as tools (explicitly defined)
        tool_methods = [
            # Pagination utilities
            "paginate_results",
            "collect_all_results",
            # Studies endpoints
            "get_cancer_studies",
            "get_cancer_types",
            "search_studies",
            "get_study_details",
            "get_multiple_studies",
            # Genes endpoints
            "search_genes",
            "get_genes",
            "get_multiple_genes",
            "get_mutations_in_gene",
            # Samples endpoints
            "get_samples_in_study",
            "get_sample_list_id",
            # Molecular profiles endpoints
            "get_molecular_profiles",
            "get_clinical_data",
            "get_gene_panels_for_study",
            "get_gene_panel_details",
        ]
    
        for method_name in tool_methods:
            if hasattr(self, method_name):
                method = getattr(self, method_name)
                self.mcp.add_tool(method)
                logger.debug(f"Registered tool: {method_name}")
            else:
                logger.warning(f"Method {method_name} not found for tool registration")
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It mentions concurrent retrieval but fails to detail critical aspects such as rate limits, authentication requirements, error handling, or response format. This leaves significant gaps for an agent to understand operational constraints.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence that directly states the tool's purpose without unnecessary elaboration. It is front-loaded and wastes no words, making it easy to parse quickly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity of a batch retrieval tool with 3 parameters, 0% schema coverage, no annotations, and no output schema, the description is inadequate. It omits essential details about parameters, behavioral traits, and output expectations, failing to provide a complete operational picture.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate for undocumented parameters. It does not explain the meaning or usage of 'gene_ids', 'gene_id_type', or 'projection', nor does it clarify default values or acceptable inputs. This lack of semantic context hinders effective parameter selection.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Get information') and resource ('multiple genes'), specifying the concurrent nature of the operation. However, it does not distinguish this tool from its sibling 'get_genes' or 'search_genes', leaving ambiguity about when to use this specific tool versus alternatives.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No explicit guidance is provided on when to use this tool versus alternatives like 'get_genes' or 'search_genes'. The description implies batch processing but lacks context on prerequisites, exclusions, or comparative use cases with sibling tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other 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/pickleton89/cbioportal-mcp'

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