bc_search_studies
Search for clinical trials by conditions, interventions, sponsors, status, phase, and other study characteristics to support biomedical research and data retrieval.
Instructions
Search for clinical trials studies based on various criteria.
This function allows biomedical researchers to find relevant clinical trials by searching across conditions, interventions, sponsors, and other study characteristics.
Args: condition (str, optional): Medical condition or disease to search for. intervention (str, optional): Drug, therapy, or treatment name to search for. sponsor (str, optional): Study sponsor organization. status (str, optional): Current status of the study. phase (str, optional): Clinical trial phase. study_type (str, optional): Type of study (interventional, observational, etc.). location_country (str, optional): Country where study is conducted. min_age (int, optional): Minimum age of participants in years. max_age (int, optional): Maximum age of participants in years. sex (str, optional): Sex of participants. page_size (int): Number of results to return (default: 25, max: 1000). sort (str): Sort order for results (default: most recently updated).
Returns: dict: Study search results or error message
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| condition | No | Medical condition or disease (e.g., 'cancer', 'diabetes') | |
| intervention | No | Drug, therapy, or treatment name (e.g., 'aspirin', 'chemotherapy') | |
| location_country | No | Country where study is conducted (e.g., 'United States', 'Germany') | |
| max_age | No | Maximum age of participants in years | |
| min_age | No | Minimum age of participants in years | |
| page_size | No | Number of results to return | |
| phase | No | Study phase: 'PHASE1', 'PHASE2', 'PHASE3', 'PHASE4', 'EARLY_PHASE1', 'NA' | |
| sex | No | Sex of participants: 'ALL', 'FEMALE', 'MALE' | |
| sort | No | Sort order: 'LastUpdatePostDate:desc', 'StudyFirstPostDate:desc', 'EnrollmentCount:desc' | LastUpdatePostDate:desc |
| sponsor | No | Study sponsor organization (e.g., 'Pfizer', 'NIH') | |
| status | No | Study status: 'RECRUITING', 'ACTIVE_NOT_RECRUITING', 'COMPLETED', 'TERMINATED', 'SUSPENDED', 'WITHDRAWN', 'NOT_YET_RECRUITING' | |
| study_type | No | Type of study: 'INTERVENTIONAL', 'OBSERVATIONAL', 'EXPANDED_ACCESS' |
Implementation Reference
- The handler function for the 'search_studies' tool (likely 'bc_search_studies' under BC MCP prefix). Performs advanced search on ClinicalTrials.gov API using multiple filters like condition, intervention, status, etc., and returns paginated JSON results.@core_mcp.tool() def search_studies( condition: Annotated[Optional[str], Field(description="Medical condition (e.g., 'cancer')")] = None, intervention: Annotated[Optional[str], Field(description="Drug/therapy name (e.g., 'aspirin')")] = None, sponsor: Annotated[Optional[str], Field(description="Sponsor org (e.g., 'Pfizer')")] = None, status: Annotated[ Optional[str], Field( description="'RECRUITING', 'ACTIVE_NOT_RECRUITING', 'COMPLETED', 'TERMINATED', 'SUSPENDED', 'WITHDRAWN', or 'NOT_YET_RECRUITING'" ), ] = None, phase: Annotated[ Optional[str], Field(description="'PHASE1', 'PHASE2', 'PHASE3', 'PHASE4', 'EARLY_PHASE1', or 'NA'") ] = None, study_type: Annotated[ Optional[str], Field(description="'INTERVENTIONAL', 'OBSERVATIONAL', or 'EXPANDED_ACCESS'") ] = None, location_country: Annotated[Optional[str], Field(description="Country (e.g., 'United States')")] = None, min_age: Annotated[Optional[int], Field(description="Min participant age (years)", ge=0)] = None, max_age: Annotated[Optional[int], Field(description="Max participant age (years)", ge=0)] = None, sex: Annotated[Optional[str], Field(description="'ALL', 'FEMALE', or 'MALE'")] = None, page_size: Annotated[int, Field(description="Results per page (1-1000)", ge=1, le=1000)] = 25, sort: Annotated[ str, Field(description="'LastUpdatePostDate:desc', 'StudyFirstPostDate:desc', or 'EnrollmentCount:desc'"), ] = "LastUpdatePostDate:desc", ) -> Union[Dict[str, Any], dict]: """Advanced search for trials with flexible multi-field filtering. Specify at least one search parameter. Returns: dict: Paginated search results containing studies list with trial metadata or error message. """ # Ensure at least one search parameter was provided if not any([condition, intervention, sponsor, status, phase, study_type, location_country, min_age, max_age, sex]): return {"error": "At least one search parameter must be provided"} # Build query components query_parts = [] if condition: query_parts.append(f"AREA[ConditionSearch]{condition}") if intervention: query_parts.append(f"AREA[InterventionName]{intervention}") if sponsor: query_parts.append(f"AREA[LeadSponsorName]{sponsor}") if status: query_parts.append(f"AREA[OverallStatus]{status}") if phase: query_parts.append(f"AREA[Phase]{phase}") if study_type: query_parts.append(f"AREA[StudyType]{study_type}") if location_country: query_parts.append(f"AREA[LocationCountry]{location_country}") if sex: query_parts.append(f"AREA[Sex]{sex}") # Handle age range if min_age is not None and max_age is not None: query_parts.append(f"AREA[MinimumAge]RANGE[{min_age}, {max_age}]") elif min_age is not None: query_parts.append(f"AREA[MinimumAge]RANGE[{min_age}, MAX]") elif max_age is not None: query_parts.append(f"AREA[MaximumAge]RANGE[MIN, {max_age}]") # Join query parts with AND query = " AND ".join(query_parts) # URL encode the query encoded_query = quote(query) url = f"https://clinicaltrials.gov/api/v2/studies?query.term={encoded_query}&pageSize={page_size}&sort={sort}&format=json" try: response = requests.get(url) response.raise_for_status() return response.json() except requests.exceptions.RequestException as e: return {"error": f"Failed to fetch clinical trials: {e!s}"}
- src/biocontext_kb/core/clinicaltrials/__init__.py:5-13 (registration)Exports the search_studies tool function for use in the MCP server.from ._search_studies import search_studies __all__ = [ "get_recruiting_studies_by_location", "get_studies_by_condition", "get_studies_by_intervention", "get_study_details", "search_studies", ]
- Pydantic schema defined via Annotated types and Field descriptions for input validation of search parameters.def search_studies( condition: Annotated[Optional[str], Field(description="Medical condition (e.g., 'cancer')")] = None, intervention: Annotated[Optional[str], Field(description="Drug/therapy name (e.g., 'aspirin')")] = None, sponsor: Annotated[Optional[str], Field(description="Sponsor org (e.g., 'Pfizer')")] = None, status: Annotated[ Optional[str], Field( description="'RECRUITING', 'ACTIVE_NOT_RECRUITING', 'COMPLETED', 'TERMINATED', 'SUSPENDED', 'WITHDRAWN', or 'NOT_YET_RECRUITING'" ), ] = None, phase: Annotated[ Optional[str], Field(description="'PHASE1', 'PHASE2', 'PHASE3', 'PHASE4', 'EARLY_PHASE1', or 'NA'") ] = None, study_type: Annotated[ Optional[str], Field(description="'INTERVENTIONAL', 'OBSERVATIONAL', or 'EXPANDED_ACCESS'") ] = None, location_country: Annotated[Optional[str], Field(description="Country (e.g., 'United States')")] = None, min_age: Annotated[Optional[int], Field(description="Min participant age (years)", ge=0)] = None, max_age: Annotated[Optional[int], Field(description="Max participant age (years)", ge=0)] = None, sex: Annotated[Optional[str], Field(description="'ALL', 'FEMALE', or 'MALE'")] = None, page_size: Annotated[int, Field(description="Results per page (1-1000)", ge=1, le=1000)] = 25, sort: Annotated[ str, Field(description="'LastUpdatePostDate:desc', 'StudyFirstPostDate:desc', or 'EnrollmentCount:desc'"), ] = "LastUpdatePostDate:desc", ) -> Union[Dict[str, Any], dict]: