search_genes
Find genes by symbol or name keyword in cancer genomics data with pagination and sorting options.
Instructions
Search for genes by keyword in their symbol or name with pagination support.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| keyword | Yes | ||
| page_number | No | ||
| page_size | No | ||
| sort_by | No | ||
| direction | No | ASC | |
| limit | No |
Implementation Reference
- cbioportal_mcp/endpoints/genes.py:36-97 (handler)Core handler implementation of the search_genes tool in GenesEndpoints class. Performs input validation, constructs API parameters, calls the cBioPortal /genes endpoint, handles pagination metadata including 'has_more' flag and server-side limit.async def search_genes( self, keyword: str, page_number: int = 0, page_size: int = 50, sort_by: Optional[str] = None, direction: str = "ASC", limit: Optional[int] = None, ) -> Dict: """ Search for genes by keyword in their symbol or name with pagination support. """ # Input Validation validate_keyword(keyword) validate_page_params(page_number, page_size, limit) validate_sort_params(sort_by, direction) try: api_call_params = { "keyword": keyword, "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 genes_from_api = await self.api_client.make_api_request( "genes", params=api_call_params ) # Determine if the API might have more data api_might_have_more = len(genes_from_api) == api_call_params["pageSize"] # If 'fetch all' was intended and API returned less than max fetch size, then it's definitely the end. if ( api_call_params["pageSize"] == FETCH_ALL_PAGE_SIZE and len(genes_from_api) < FETCH_ALL_PAGE_SIZE ): api_might_have_more = False # Apply server-side limit if specified (after fetching the page from API) genes_for_response = genes_from_api if limit and limit > 0 and len(genes_from_api) > limit: genes_for_response = genes_from_api[:limit] # total_found in pagination now means number of items in this specific response payload # This makes the count consistent with the actual returned data structure total_items_in_response = len(genes_for_response) return { "genes": genes_for_response, "pagination": { "page": page_number, "page_size": page_size, # Report original requested page_size to client "total_found": total_items_in_response, "has_more": api_might_have_more, }, } except Exception as e: return {"error": f"Failed to search genes: {str(e)}"}
- cbioportal_mcp/server.py:96-131 (registration)The _register_tools method registers 'search_genes' (line 110) and other methods as MCP tools by adding them to FastMCP instance 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")
- cbioportal_mcp/server.py:217-229 (handler)Thin wrapper handler method search_genes on CBioPortalMCPServer class that delegates the call to self.genes.search_genes() - this is the method directly registered as the MCP tool.async def search_genes( self, keyword: str, page_number: int = 0, page_size: int = 50, sort_by: Optional[str] = None, direction: str = "ASC", limit: Optional[int] = None, ) -> Dict: """Search for genes by keyword in their symbol or name with pagination support.""" return await self.genes.search_genes( keyword, page_number, page_size, sort_by, direction, limit )
- validate_keyword function used for input validation of the keyword parameter in search_genes.def validate_keyword(keyword: str) -> None: """ Validate keyword parameter for search operations. Args: keyword: Search keyword Raises: TypeError: If keyword is not a string ValueError: If keyword is empty """ if not isinstance(keyword, str): raise TypeError("keyword must be a string") if not keyword: raise ValueError("keyword cannot be empty")
- validate_page_params function used for input validation of pagination parameters (page_number, page_size, limit) in search_genes.def validate_page_params( page_number: int, page_size: int, limit: Optional[int] = None, ) -> None: """ Validate pagination parameters. Args: page_number: Page number (0-based) page_size: Number of items per page limit: Optional limit on total results Raises: TypeError: If parameters are not the correct type ValueError: If parameters have invalid values """ if not isinstance(page_number, int): raise TypeError("page_number must be an integer") if page_number < 0: raise ValueError("page_number must be non-negative") if not isinstance(page_size, int): raise TypeError("page_size must be an integer") if page_size <= 0: raise ValueError("page_size must be positive") if limit is not None: if not isinstance(limit, int): raise TypeError("limit must be an integer if provided") if limit < 0: raise ValueError("limit must be non-negative if provided")