Skip to main content
Glama
pickleton89

cBioPortal MCP Server

by pickleton89

get_clinical_data

Retrieve clinical data for patients in a cancer study with customizable pagination, sorting, and attribute filtering. Supports detailed exploration of specific or all attributes.

Instructions

Get clinical data for patients in a study with pagination support. Can fetch specific attributes or all.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
attribute_idsNo
directionNoASC
limitNo
page_numberNo
page_sizeNo
sort_byNo
study_idYes

Implementation Reference

  • The primary handler function for the get_clinical_data tool. Fetches clinical data from the cBioPortal API using GET or POST depending on whether specific attributes are requested, processes the flat list into a nested dictionary by patient ID, applies pagination and limits, and returns structured data with pagination metadata.
    async def get_clinical_data( self, study_id: str, attribute_ids: Optional[List[str]] = None, page_number: int = 0, page_size: int = 50, sort_by: Optional[str] = None, direction: str = "ASC", limit: Optional[int] = None, ) -> Dict: """ Get clinical data for patients in a study with pagination support. Can fetch specific attributes or all. """ try: api_call_params = { "pageNumber": page_number, "pageSize": page_size, "direction": direction, "clinicalDataType": "PATIENT", # Assuming PATIENT level data } if sort_by: api_call_params["sortBy"] = sort_by if limit == 0: api_call_params["pageSize"] = FETCH_ALL_PAGE_SIZE clinical_data_from_api = [] if attribute_ids: endpoint = f"studies/{study_id}/clinical-data/fetch" payload = {"attributeIds": attribute_ids, "clinicalDataType": "PATIENT"} clinical_data_from_api = await self.api_client.make_api_request( endpoint, method="POST", params=api_call_params, json_data=payload ) else: endpoint = f"studies/{study_id}/clinical-data" clinical_data_from_api = await self.api_client.make_api_request( endpoint, method="GET", params=api_call_params ) if ( isinstance(clinical_data_from_api, dict) and "api_error" in clinical_data_from_api ): return { "error": "API error fetching clinical data", "details": clinical_data_from_api, "request_params": api_call_params, } if not isinstance(clinical_data_from_api, list): return { "error": "Unexpected API response type for clinical data (expected list)", "details": clinical_data_from_api, "request_params": api_call_params, } api_might_have_more = ( len(clinical_data_from_api) == api_call_params["pageSize"] ) if ( api_call_params["pageSize"] == FETCH_ALL_PAGE_SIZE and len(clinical_data_from_api) < FETCH_ALL_PAGE_SIZE ): api_might_have_more = False # Apply server-side limit to the data that will be processed and returned data_to_process = clinical_data_from_api if limit and limit > 0 and len(clinical_data_from_api) > limit: data_to_process = clinical_data_from_api[:limit] by_patient = {} for item in data_to_process: patient_id = item.get("patientId") if patient_id: if patient_id not in by_patient: by_patient[patient_id] = {} by_patient[patient_id][item.get("clinicalAttributeId")] = item.get( "value" ) # Update total_found to be the number of unique patients, not raw data items # This makes the count consistent with the actual returned data structure total_patients = len(by_patient) return { "clinical_data_by_patient": by_patient, # This contains unique patients with their attributes "pagination": { "page": page_number, "page_size": page_size, "total_found": total_patients, # Now using patient count for consistency "has_more": api_might_have_more, }, } except Exception as e: return { "error": f"Failed to get clinical data for study {study_id}: {str(e)}" }
  • Thin wrapper handler in the main CBioPortalMCPServer class that delegates the get_clinical_data call to the specialized MolecularProfilesEndpoints instance.
    async def get_clinical_data( self, study_id: str, attribute_ids: Optional[List[str]] = None, page_number: int = 0, page_size: int = 50, sort_by: Optional[str] = None, direction: str = "ASC", limit: Optional[int] = None, ) -> Dict: """Get clinical data for patients in a study with pagination support. Can fetch specific attributes or all.""" return await self.molecular_profiles.get_clinical_data( study_id, attribute_ids, page_number, page_size, sort_by, direction, limit )
  • Registers all tool methods, including 'get_clinical_data', as MCP tools by adding them to the FastMCP instance using 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")

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