Skip to main content
Glama
jbdamask

NIH RePORTER MCP

by jbdamask

search_combined

Search NIH-funded research projects and their related publications in a single query using filters like fiscal years, PI names, organization, funding type, and award amounts.

Instructions

Search for NIH projects and their related publications in a single query

Args:
    fiscal_years: Comma-separated list of fiscal years (e.g., "2022,2023")
    pi_names: Comma-separated list of PI names
    organization: Name of the organization
    org_state: Two-letter state code (e.g., "CA", "NY")
    funding_mechanism: Type of funding (e.g., "R01", "F32", "K99")
    ic_code: Institute or Center code (e.g., "NCI", "NIMH")
    min_amount: Minimum award amount
    max_amount: Maximum award amount
    covid_response: COVID-19 response category
    include_publications: Whether to include related publications
    publication_years: Comma-separated list of publication years
    limit: Maximum number of results to return (default: 10, max: 50)

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
fiscal_yearsNo
pi_namesNo
organizationNo
org_stateNo
funding_mechanismNo
ic_codeNo
min_amountNo
max_amountNo
covid_responseNo
include_publicationsNo
publication_yearsNo
limitNo

Implementation Reference

  • The handler function for the 'search_combined' tool, registered via @mcp.tool(). It constructs criteria for NIH RePORTER API to search projects, optionally fetches related publications, and formats results in markdown.
    @mcp.tool()
    async def search_combined(
        # Project search parameters
        fiscal_years: Optional[str] = None,
        pi_names: Optional[str] = None,
        organization: Optional[str] = None,
        org_state: Optional[str] = None,
        funding_mechanism: Optional[str] = None,
        ic_code: Optional[str] = None,
        min_amount: Optional[float] = None,
        max_amount: Optional[float] = None,
        covid_response: Optional[str] = None,
        
        # Publication parameters
        include_publications: Optional[bool] = True,
        publication_years: Optional[str] = None,
        
        # General parameters
        limit: Optional[int] = 10
    ) -> str:
        """
        Search for NIH projects and their related publications in a single query
        
        Args:
            fiscal_years: Comma-separated list of fiscal years (e.g., "2022,2023")
            pi_names: Comma-separated list of PI names
            organization: Name of the organization
            org_state: Two-letter state code (e.g., "CA", "NY")
            funding_mechanism: Type of funding (e.g., "R01", "F32", "K99")
            ic_code: Institute or Center code (e.g., "NCI", "NIMH")
            min_amount: Minimum award amount
            max_amount: Maximum award amount
            covid_response: COVID-19 response category
            include_publications: Whether to include related publications
            publication_years: Comma-separated list of publication years
            limit: Maximum number of results to return (default: 10, max: 50)
        """
        try:
            logger.info(f"Combined search request received with parameters: {locals()}")
            
            # First, search for projects
            project_criteria = {}
            
            if fiscal_years:
                try:
                    # Handle escaped quotes and clean the input string
                    years_str = fiscal_years.replace('\\"', '').replace('"', '').strip()
                    years = [int(year.strip()) for year in years_str.split(",") if year.strip()]
                    if not years:
                        raise ValueError("No valid years found after parsing")
                    project_criteria["fiscal_years"] = years
                except ValueError as e:
                    logger.error(f"Invalid fiscal years format: {fiscal_years}, error: {str(e)}")
                    return f"Error: Invalid fiscal years format. Please provide comma-separated years (e.g., 2020,2021)"
            
            if pi_names:
                try:
                    # Handle escaped quotes and clean the input string
                    names_str = pi_names.replace('\\"', '').replace('"', '').strip()
                    names = [name.strip() for name in names_str.split(",") if name.strip()]
                    if not names:
                        raise ValueError("No valid names found after parsing")
                    project_criteria["pi_names"] = [{"any_name": name} for name in names]
                except Exception as e:
                    logger.error(f"Invalid PI names format: {pi_names}, error: {str(e)}")
                    return f"Error: Invalid PI names format. Please provide comma-separated names"
            
            if organization:
                project_criteria["org_names"] = [organization]
            
            if org_state:
                project_criteria["org_states"] = [org_state.upper()]
                
            if funding_mechanism:
                project_criteria["funding_mechanism"] = funding_mechanism.strip().strip('"').strip("'")
                
            if ic_code:
                project_criteria["agency_ic_admin"] = ic_code.strip().strip('"').strip("'").upper()
                
            if min_amount is not None or max_amount is not None:
                project_criteria["award_amount_range"] = {
                    "min_amount": min_amount if min_amount is not None else 0,
                    "max_amount": max_amount if max_amount is not None else float('inf')
                }
                
            if covid_response:
                project_criteria["covid_response"] = [covid_response]
            
            project_criteria["limit"] = min(max(1, limit), 50)
            
            logger.info(f"Searching for projects with criteria: {json.dumps(project_criteria, indent=2)}")
            project_results = await api_client.get_projects(project_criteria)
            
            # If we want publications, get them for each project
            if include_publications:
                project_nums = []
                for project in project_results.get("results", []):
                    if project.get("project_num"):
                        project_nums.append(project["project_num"])
                
                if project_nums:
                    logger.info(f"Found project numbers for publication search: {project_nums}")
                    pub_criteria = {
                        "criteria": {
                            "core_project_nums": project_nums
                        },
                        "limit": 100  # Get more publications since they're related
                    }
                    
                    # Only add publication years if explicitly specified by the user
                    if publication_years:
                        try:
                            years_str = publication_years.strip().strip('"').strip("'")
                            years = [int(year.strip()) for year in years_str.split(",")]
                            pub_criteria["criteria"]["publication_years"] = years
                            logger.info(f"Filtering publications by years: {years}")
                        except ValueError as e:
                            logger.error(f"Invalid publication years format: {publication_years}")
                            return f"Error: Invalid publication years format. Please provide comma-separated years without quotes (e.g., 2020,2021)"
                    
                    logger.info(f"Searching for publications with criteria: {json.dumps(pub_criteria, indent=2)}")
                    pub_results = await api_client.get_publications(pub_criteria)
                    
                    # Add publications to each project
                    pub_by_project = {}
                    for pub in pub_results.get("results", []):
                        proj_num = pub.get("core_project_num")
                        if proj_num:
                            if proj_num not in pub_by_project:
                                pub_by_project[proj_num] = []
                            pub_by_project[proj_num].append(pub)
                    
                    for project in project_results.get("results", []):
                        proj_num = project.get("project_num")
                        if proj_num in pub_by_project:
                            project["related_publications"] = pub_by_project[proj_num]
            
            return api_client.format_project_results(project_results, include_publications=include_publications)
            
        except Exception as e:
            logger.error(f"Combined search failed: {str(e)}", exc_info=True)
            return f"Combined search failed: {str(e)}\nPlease check the logs for more details."

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/jbdamask/mcp-nih-reporter'

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