Skip to main content
Glama
pickleton89

cBioPortal MCP Server

by pickleton89

get_mutations_in_gene

Retrieve mutation data for a specific gene within cancer study samples, enabling genomic analysis with pagination support.

Instructions

Get mutations in a specific gene for a given study and sample list, with pagination support.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
gene_idYes
study_idYes
sample_list_idYes
page_numberNo
page_sizeNo
sort_byNo
directionNoASC
limitNo

Implementation Reference

  • Core handler function implementing the logic to retrieve mutations in a specific gene for a study and sample list. Fetches the appropriate molecular profile, makes API request to mutations endpoint, handles pagination, limits, sorting, and errors.
    @handle_api_errors("get mutations in gene")
    async def get_mutations_in_gene(
        self,
        gene_id: str,
        study_id: str,
        sample_list_id: str,
        page_number: int = 0,
        page_size: int = 50,
        sort_by: Optional[str] = None,
        direction: str = "ASC",
        limit: Optional[int] = None,
    ) -> Dict:
        """
        Get mutations in a specific gene for a given study and sample list, with pagination support.
        Uses the /molecular-profiles/{molecularProfileId}/mutations endpoint with GET and query parameters.
        The molecularProfileId is dynamically determined based on the studyId.
        """
        try:
            molecular_profiles_response = await self.api_client.make_api_request(
                f"studies/{study_id}/molecular-profiles"
            )
            if (
                isinstance(molecular_profiles_response, dict)
                and "api_error" in molecular_profiles_response
            ):
                return {
                    "error": f"Failed to fetch molecular profiles for study {study_id} to find mutation profile",
                    "details": molecular_profiles_response,
                }
    
            mutation_profile_id = None
            if isinstance(molecular_profiles_response, list):
                for profile in molecular_profiles_response:
                    if profile.get("molecularAlterationType") == "MUTATION_EXTENDED":
                        mutation_profile_id = profile.get("molecularProfileId")
                        break
    
            if not mutation_profile_id:
                return {
                    "error": f"No MUTATION_EXTENDED molecular profile found for study {study_id}"
                }
    
            api_call_params = {
                "studyId": study_id,
                "sampleListId": sample_list_id,
                "pageNumber": page_number,
                "pageSize": page_size,
                "direction": direction,
            }
            if sort_by:
                api_call_params["sortBy"] = sort_by
            if limit == 0:
                api_call_params["pageSize"] = FETCH_ALL_PAGE_SIZE
    
            if str(gene_id).isdigit():
                api_call_params["entrezGeneId"] = gene_id
            else:
                api_call_params["hugoGeneSymbol"] = gene_id
    
            endpoint = f"molecular-profiles/{mutation_profile_id}/mutations"
            mutations_from_api = await self.api_client.make_api_request(
                endpoint, method="GET", params=api_call_params
            )
    
            if (
                isinstance(mutations_from_api, dict)
                and "api_error" in mutations_from_api
            ):
                return {
                    "error": "API error fetching mutations",
                    "details": mutations_from_api,
                    "request_params": api_call_params,
                }
            if not isinstance(mutations_from_api, list):
                return {
                    "error": "Unexpected API response type for mutations (expected list)",
                    "details": mutations_from_api,
                    "request_params": api_call_params,
                }
    
            api_might_have_more = len(mutations_from_api) == api_call_params["pageSize"]
            if (
                api_call_params["pageSize"] == FETCH_ALL_PAGE_SIZE
                and len(mutations_from_api) < FETCH_ALL_PAGE_SIZE
            ):
                api_might_have_more = False
    
            mutations_for_response = mutations_from_api
            if limit and limit > 0 and len(mutations_from_api) > limit:
                mutations_for_response = mutations_from_api[:limit]
    
            total_items_in_response = len(mutations_for_response)
    
            return {
                "mutations": mutations_for_response,
                "pagination": {
                    "page": page_number,
                    "page_size": page_size,
                    "total_found": total_items_in_response,
                    "has_more": api_might_have_more,
                },
            }
        except Exception as e:
            return {
                "error": f"An unexpected error occurred in get_mutations_in_gene: {str(e)}"
            }
  • Tool registration in _register_tools method where 'get_mutations_in_gene' is listed in tool_methods and registered via self.mcp.add_tool(self.get_mutations_in_gene).
    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")
  • Wrapper handler method on the main server class that delegates to the GenesEndpoints implementation. This is the method directly registered as the MCP tool.
    async def get_mutations_in_gene(
        self,
        gene_id: str,
        study_id: str,
        sample_list_id: str,
        page_number: int = 0,
        page_size: int = 50,
        sort_by: Optional[str] = None,
        direction: str = "ASC",
        limit: Optional[int] = None,
    ) -> Dict:
        """Get mutations in a specific gene for a given study and sample list, with pagination support."""
        return await self.genes.get_mutations_in_gene(
            gene_id,
            study_id,
            sample_list_id,
            page_number,
            page_size,
            sort_by,
            direction,
            limit,
        )
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 'pagination support' which is helpful, but doesn't describe authentication needs, rate limits, error conditions, or what the response looks like (e.g., format, structure). For a tool with 8 parameters and no output schema, this leaves significant behavioral gaps.

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 front-loads the core purpose. Every word earns its place: 'Get mutations' (action), 'in a specific gene for a given study and sample list' (scope), 'with pagination support' (key feature). No wasted words or redundancy.

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 (8 parameters, no annotations, no output schema), the description is incomplete. It doesn't explain the return format, error handling, or behavioral constraints. While it mentions pagination, it doesn't detail how pagination works with other parameters like 'limit'. For a data retrieval tool with multiple filtering/sorting options, more context is needed.

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 only mentions 'gene', 'study', 'sample list', and 'pagination', covering 3 of the 8 parameters (gene_id, study_id, sample_list_id, and implicitly page_number/page_size). It doesn't explain 'sort_by', 'direction', or 'limit', leaving most parameters without semantic context beyond their titles.

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 tool's purpose: 'Get mutations in a specific gene for a given study and sample list, with pagination support.' It specifies the verb ('Get'), resource ('mutations'), and scope ('specific gene, study, sample list'), but doesn't explicitly differentiate from sibling tools like 'get_clinical_data' or 'get_molecular_profiles' that might also retrieve mutation-related data.

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?

The description provides no guidance on when to use this tool versus alternatives. It doesn't mention sibling tools like 'paginate_results' (which might handle pagination generically) or 'get_multiple_genes' (which might retrieve mutations for multiple genes), nor does it specify prerequisites or exclusions for usage.

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