Skip to main content
Glama
biocontext-ai

BioContextAI Knowledgebase MCP

Official

bc_search_studies

Search clinical trials using filters for condition, intervention, sponsor, status, phase, study type, location, age, and sex to find relevant medical research studies.

Instructions

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.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
conditionNoMedical condition (e.g., 'cancer')
interventionNoDrug/therapy name (e.g., 'aspirin')
sponsorNoSponsor org (e.g., 'Pfizer')
statusNo'RECRUITING', 'ACTIVE_NOT_RECRUITING', 'COMPLETED', 'TERMINATED', 'SUSPENDED', 'WITHDRAWN', or 'NOT_YET_RECRUITING'
phaseNo'PHASE1', 'PHASE2', 'PHASE3', 'PHASE4', 'EARLY_PHASE1', or 'NA'
study_typeNo'INTERVENTIONAL', 'OBSERVATIONAL', or 'EXPANDED_ACCESS'
location_countryNoCountry (e.g., 'United States')
min_ageNoMin participant age (years)
max_ageNoMax participant age (years)
sexNo'ALL', 'FEMALE', or 'MALE'
page_sizeNoResults per page (1-1000)
sortNo'LastUpdatePostDate:desc', 'StudyFirstPostDate:desc', or 'EnrollmentCount:desc'LastUpdatePostDate:desc

Implementation Reference

  • Handler function for the 'search_studies' tool (likely 'bc_search_studies' under 'BC' MCP server). Executes advanced search on ClinicalTrials.gov API v2 with multiple filter parameters, constructs query, fetches and returns 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}"}
  • Creates the FastMCP server instance named 'BC' where all tools including search_studies are registered via @core_mcp.tool() decorator.
    core_mcp = FastMCP( # type: ignore "BC", instructions="Provides access to biomedical knowledge bases.", )
  • Registers 'search_studies' by importing and including it in __all__, making it available when clinicaltrials is imported in core/__init__.py.
    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", ]
  • Imports all clinicaltrials tools (including search_studies), triggering registration via decorators when the module is loaded.
    from .clinicaltrials import *

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/biocontext-ai/knowledgebase-mcp'

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