Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ coverage.xml
.ruff_cache
htmlcov

# Ignore Claude Code
.claude

# Keep folders indicated by .gitkeep
!/**/.gitkeep
!/**/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,16 @@

@core_mcp.tool()
def get_alphafold_info_by_protein_symbol(
protein_symbol: Annotated[str, Field(description="The name of the gene to search for (e.g., 'SYNPO')")],
protein_symbol: Annotated[str, Field(description="Gene/protein name (e.g., 'SYNPO')")],
species: Annotated[
str,
Field(description="The organism ID (e.g., '9606' for human)"),
Field(description="Taxonomy ID (e.g., '9606' for human)"),
] = "9606",
) -> dict:
"""Query the AlphaFold database for the protein structure information using the protein name.

This function constructs a query URL to fetch data from the AlphaFold database based on the provided protein name.
The response contains links to the PDB and CIF files for the protein structure, as well as general information about
the protein.

Args:
protein_symbol (Annotated[str, Field, optional): The name of the protein to search for (e.g., "SYNPO").
species (str): The organism ID (e.g., "9606" for human). Default is "9606".
"""Query AlphaFold database using protein name. First converts protein symbol to UniProt ID, then fetches structure predictions.

Returns:
dict: Protein structure information or an error message.
dict: AlphaFold prediction data including PDB/CIF file URLs, confidence scores, and metadata or error message.
"""
# Get the UniProt Id from the protein_symbol
try:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,12 @@


def get_alphafold_info_by_uniprot_id(
uniprot_id: Annotated[str, Field(description="The UniProt ID of the protein (e.g., 'P62258')")],
uniprot_id: Annotated[str, Field(description="UniProt protein ID (e.g., 'P62258')")],
) -> dict:
"""Query the AlphaFold database for the protein structure information using the UniProt ID.

Args:
uniprot_id (str): The UniProt ID of the protein (e.g., "P62258").
"""Query AlphaFold database for protein structure data.

Returns:
dict: Protein structure information or an error message.
dict: AlphaFold prediction data including PDB/CIF file URLs, confidence scores, and metadata or error message.
"""
# Ensure the UniProt ID is in uppercase
uniprot_id = uniprot_id.upper()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,12 @@

@core_mcp.tool()
def get_antibody_information(
ab_id: Annotated[str, Field(description="Antibody ID from the Antibody Registry (e.g., '3643095')")],
ab_id: Annotated[str, Field(description="Antibody Registry ID (e.g., '3643095')")],
) -> dict:
"""Get detailed information for a specific antibody by its ID.

This function retrieves comprehensive information about a single antibody from the Antibody Registry
using its unique antibody ID (abId). The antibody ID is typically obtained from the results of
get_antibody_list() function, where each antibody entry contains an 'abId' field that can be used
with this function to get detailed information.

Note: Some information provided by the Antibody Registry is for non-commercial use only.
Users should refer to antibodyregistry.org for complete terms of use and licensing details.

Args:
ab_id (str): The unique antibody ID from the Antibody Registry. This is typically obtained
from the 'abId' field in the results of get_antibody_list(), unless the ID
is directly provided by the user.
"""Get detailed antibody information by ID. Retrieves catalog number, vendor, clonality, epitope, applications, and more.

Returns:
dict: Detailed antibody information including catalog number, vendor, clonality, epitope,
applications, target species, isotype, source organism, citations, and other metadata,
or error message if the request fails.
dict: Antibody details including abId, catalog numbers, vendor, clonality, epitope, applications, target species, isotype, citations or error message.
"""
ab_id = ab_id.strip()
if not ab_id:
Expand Down
19 changes: 3 additions & 16 deletions src/biocontext_kb/core/antibodyregistry/_get_antibody_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,12 @@

@core_mcp.tool()
def get_antibody_list(
search: Annotated[
str, Field(description="Search term for antibodies (e.g., gene symbol, protein name, UniProt ID)")
],
search: Annotated[str, Field(description="Gene symbol, protein name, or UniProt ID (e.g., 'TRPC6')")],
) -> dict:
"""Query the Antibody Registry for available antibodies.

This function searches the Antibody Registry database for antibodies matching the search term.
Common search parameters include gene symbols (e.g., 'TRPC6'), protein names, UniProt IDs,
or other relevant identifiers.

Note: Some information provided by the Antibody Registry is for non-commercial use only.
Users should refer to antibodyregistry.org for complete terms of use and licensing details.

Args:
search (str): Search term for antibodies. Can be a gene symbol, protein name, UniProt ID, or similar identifier.
"""Search Antibody Registry for antibodies. Returns catalog numbers, vendors, clonality, applications, and metadata.

Returns:
dict: Antibody search results including catalog numbers, vendor information, clonality,
applications, and other antibody metadata, or error message if the request fails.
dict: Search results containing list of antibodies with catalog numbers, vendors, clonality, applications, metadata or error message.
"""
search = search.strip()
if not search:
Expand Down
15 changes: 4 additions & 11 deletions src/biocontext_kb/core/biorxiv/_get_preprint_details.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,13 @@

@core_mcp.tool()
def get_biorxiv_preprint_details(
doi: Annotated[str, Field(description="DOI of the preprint (e.g., '10.1101/2020.09.09.20191205')")],
server: Annotated[str, Field(description="Server to search: 'biorxiv' or 'medrxiv'")] = "biorxiv",
doi: Annotated[str, Field(description="Preprint DOI (e.g., '10.1101/2020.09.09.20191205')")],
server: Annotated[str, Field(description="'biorxiv' or 'medrxiv'")] = "biorxiv",
) -> Dict[str, Any]:
"""Get detailed information about a specific preprint by DOI.

This tool retrieves detailed metadata for a single preprint from bioRxiv or medRxiv
using its DOI identifier.

Args:
doi (str): DOI of the preprint (e.g., '10.1101/2020.09.09.20191205').
server (str): Server to search - 'biorxiv' or 'medrxiv' (default: 'biorxiv').
"""Get detailed preprint metadata by DOI. Retrieves title, authors, abstract, date, version, category, license, and publication status.

Returns:
dict: Detailed preprint information or error message
dict: Preprint metadata including doi, title, authors, abstract, date, version, category, license, publication status or error message.
"""
# Validate server
if server.lower() not in ["biorxiv", "medrxiv"]:
Expand Down
34 changes: 10 additions & 24 deletions src/biocontext_kb/core/biorxiv/_get_recent_biorxiv_preprints.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,39 +12,25 @@

@core_mcp.tool()
def get_recent_biorxiv_preprints(
server: Annotated[str, Field(description="Server to search: 'biorxiv' or 'medrxiv'")] = "biorxiv",
start_date: Annotated[Optional[str], Field(description="Start date in YYYY-MM-DD format")] = None,
end_date: Annotated[Optional[str], Field(description="End date in YYYY-MM-DD format")] = None,
server: Annotated[str, Field(description="'biorxiv' or 'medrxiv'")] = "biorxiv",
start_date: Annotated[Optional[str], Field(description="Start date (YYYY-MM-DD)")] = None,
end_date: Annotated[Optional[str], Field(description="End date (YYYY-MM-DD)")] = None,
days: Annotated[
Optional[int], Field(description="Number of recent days to search (alternative to date range)", ge=1, le=365)
Optional[int], Field(description="Search last N days (1-365, alternative to date range)", ge=1, le=365)
] = None,
recent_count: Annotated[
Optional[int], Field(description="Number of most recent preprints (alternative to date range)", ge=1, le=1000)
Optional[int], Field(description="Most recent N preprints (1-1000, alternative to date range)", ge=1, le=1000)
] = None,
category: Annotated[
Optional[str], Field(description="Subject category filter (e.g., 'cell biology', 'neuroscience')")
Optional[str], Field(description="Filter by subject (e.g., 'cell biology', 'neuroscience')")
] = None,
cursor: Annotated[int, Field(description="Starting position for pagination", ge=0)] = 0,
max_results: Annotated[int, Field(description="Maximum number of results to return", ge=1, le=500)] = 100,
cursor: Annotated[int, Field(description="Pagination: starting position", ge=0)] = 0,
max_results: Annotated[int, Field(description="Max results per page (1-500)", ge=1, le=500)] = 100,
) -> Dict[str, Any]:
"""Get recent preprints from bioRxiv or medRxiv.

This tool searches the bioRxiv and medRxiv preprint servers for research papers.
You can search by date range, recent posts, or most recent papers.
Results are paginated with up to 100 papers per API call.

Args:
server (str): Server to search - 'biorxiv' or 'medrxiv' (default: 'biorxiv').
start_date (str, optional): Start date in YYYY-MM-DD format.
end_date (str, optional): End date in YYYY-MM-DD format.
days (int, optional): Number of recent days to search (1-365).
recent_count (int, optional): Number of most recent preprints (1-1000).
category (str, optional): Subject category filter (e.g., 'cell biology', 'neuroscience').
cursor (int): Starting position for pagination (default: 0).
max_results (int): Maximum number of results to return (default: 100, max: 500).
"""Search bioRxiv/medRxiv preprints by date range or recent count. Specify one search method: date range, days, or recent_count.

Returns:
dict: Preprint search results or error message
dict: Search results with server, search_params, total_returned, papers list (each with title, authors, abstract, metadata), pagination info or error message.
"""
# Validate server
if server.lower() not in ["biorxiv", "medrxiv"]:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,38 +8,18 @@

@core_mcp.tool()
def get_recruiting_studies_by_location(
location_country: Annotated[
str, Field(description="Country name (e.g., 'United States', 'Germany', 'United Kingdom')")
],
location_state: Annotated[
Optional[str], Field(description="State or province (e.g., 'California', 'New York')")
] = None,
location_city: Annotated[Optional[str], Field(description="City name (e.g., 'Los Angeles', 'Boston')")] = None,
condition: Annotated[
Optional[str], Field(description="Medical condition to filter by (e.g., 'cancer', 'diabetes')")
] = None,
study_type: Annotated[
Optional[str], Field(description="Type of study: 'INTERVENTIONAL', 'OBSERVATIONAL', 'ALL'")
] = "ALL",
age_range: Annotated[Optional[str], Field(description="Age group: 'CHILD', 'ADULT', 'OLDER_ADULT', 'ALL'")] = "ALL",
page_size: Annotated[int, Field(description="Number of results to return", ge=1, le=1000)] = 50,
location_country: Annotated[str, Field(description="Country name (e.g., 'United States', 'Germany')")],
location_state: Annotated[Optional[str], Field(description="State/province (e.g., 'California')")] = None,
location_city: Annotated[Optional[str], Field(description="City name")] = None,
condition: Annotated[Optional[str], Field(description="Medical condition filter (e.g., 'cancer')")] = None,
study_type: Annotated[Optional[str], Field(description="'INTERVENTIONAL', 'OBSERVATIONAL', or 'ALL'")] = "ALL",
age_range: Annotated[Optional[str], Field(description="'CHILD', 'ADULT', 'OLDER_ADULT', or 'ALL'")] = "ALL",
page_size: Annotated[int, Field(description="Results per page (1-1000)", ge=1, le=1000)] = 50,
) -> Union[Dict[str, Any], dict]:
"""Find recruiting clinical trials in a specific geographic location.

This function helps patients and healthcare providers find clinical trials
that are currently recruiting participants in their area.

Args:
location_country (str): Country name where studies are conducted.
location_state (str, optional): State or province name.
location_city (str, optional): City name.
condition (str, optional): Medical condition to filter by.
study_type (str, optional): Type of study filter (default: "ALL").
age_range (str, optional): Age group filter (default: "ALL").
page_size (int): Number of results to return (default: 50, max: 1000).
"""Find recruiting clinical trials by geographic location. Returns paginated results with summary breakdowns.

Returns:
dict: Recruiting studies in the specified location or error message
dict: Studies list with summary containing search location, total studies, study type/phase/condition breakdowns, recruiting locations or error message.
"""
if not location_country:
return {"error": "Location country must be provided"}
Expand Down
33 changes: 8 additions & 25 deletions src/biocontext_kb/core/clinicaltrials/_get_studies_by_condition.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,40 +8,23 @@

@core_mcp.tool()
def get_studies_by_condition(
condition: Annotated[
str, Field(description="Medical condition or disease name (e.g., 'breast cancer', 'diabetes', 'alzheimer')")
],
condition: Annotated[str, Field(description="Medical condition/disease (e.g., 'cancer', 'diabetes')")],
status: Annotated[
Optional[str],
Field(description="Study status filter: 'RECRUITING', 'ACTIVE_NOT_RECRUITING', 'COMPLETED', 'ALL'"),
Field(description="'RECRUITING', 'ACTIVE_NOT_RECRUITING', 'COMPLETED', or 'ALL'"),
] = "ALL",
study_type: Annotated[
Optional[str], Field(description="Type of study: 'INTERVENTIONAL', 'OBSERVATIONAL', 'ALL'")
] = "ALL",
location_country: Annotated[
Optional[str], Field(description="Country filter (e.g., 'United States', 'Germany')")
] = None,
page_size: Annotated[int, Field(description="Number of results to return", ge=1, le=1000)] = 50,
study_type: Annotated[Optional[str], Field(description="'INTERVENTIONAL', 'OBSERVATIONAL', or 'ALL'")] = "ALL",
location_country: Annotated[Optional[str], Field(description="Country filter (e.g., 'United States')")] = None,
page_size: Annotated[int, Field(description="Results per page (1-1000)", ge=1, le=1000)] = 50,
sort: Annotated[
str,
Field(description="Sort order: 'LastUpdatePostDate:desc', 'StudyFirstPostDate:desc', 'EnrollmentCount:desc'"),
Field(description="'LastUpdatePostDate:desc', 'StudyFirstPostDate:desc', or 'EnrollmentCount:desc'"),
] = "LastUpdatePostDate:desc",
) -> Union[Dict[str, Any], dict]:
"""Search for clinical trials by medical condition with simplified parameters.

This function provides a focused search for clinical trials related to a specific
medical condition, with common filters that biomedical researchers typically use.

Args:
condition (str): Medical condition or disease name to search for.
status (str, optional): Study status filter (default: "ALL").
study_type (str, optional): Type of study filter (default: "ALL").
location_country (str, optional): Country where studies are conducted.
page_size (int): Number of results to return (default: 50, max: 1000).
sort (str): Sort order for results (default: most recently updated).
"""Search trials by condition with summary statistics. Returns paginated results with breakdowns by status, study type, and phase.

Returns:
dict: Study search results with summary statistics or error message
dict: Studies list with summary containing condition searched, total studies, status/study type/phase breakdowns or error message.
"""
if not condition:
return {"error": "Medical condition must be provided"}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,45 +10,29 @@
def get_studies_by_intervention(
intervention: Annotated[
str,
Field(description="Drug, therapy, or treatment name (e.g., 'aspirin', 'pembrolizumab', 'radiation therapy')"),
Field(description="Drug/therapy name (e.g., 'aspirin', 'pembrolizumab', 'radiation')"),
],
condition: Annotated[
Optional[str], Field(description="Medical condition to filter by (e.g., 'cancer', 'diabetes')")
] = None,
condition: Annotated[Optional[str], Field(description="Medical condition filter (e.g., 'cancer')")] = None,
phase: Annotated[
Optional[str], Field(description="Clinical trial phase: 'PHASE1', 'PHASE2', 'PHASE3', 'PHASE4', 'EARLY_PHASE1'")
Optional[str], Field(description="'PHASE1', 'PHASE2', 'PHASE3', 'PHASE4', or 'EARLY_PHASE1'")
] = None,
status: Annotated[
Optional[str], Field(description="Study status: 'RECRUITING', 'ACTIVE_NOT_RECRUITING', 'COMPLETED', 'ALL'")
Optional[str], Field(description="'RECRUITING', 'ACTIVE_NOT_RECRUITING', 'COMPLETED', or 'ALL'")
] = "ALL",
intervention_type: Annotated[
Optional[str],
Field(
description="Type of intervention: 'DRUG', 'BIOLOGICAL', 'DEVICE', 'PROCEDURE', 'RADIATION', 'BEHAVIORAL', 'ALL'"
),
Field(description="'DRUG', 'BIOLOGICAL', 'DEVICE', 'PROCEDURE', 'RADIATION', 'BEHAVIORAL', or 'ALL'"),
] = "ALL",
page_size: Annotated[int, Field(description="Number of results to return", ge=1, le=1000)] = 50,
page_size: Annotated[int, Field(description="Results per page (1-1000)", ge=1, le=1000)] = 50,
sort: Annotated[
str,
Field(description="Sort order: 'LastUpdatePostDate:desc', 'StudyFirstPostDate:desc', 'EnrollmentCount:desc'"),
Field(description="'LastUpdatePostDate:desc', 'StudyFirstPostDate:desc', or 'EnrollmentCount:desc'"),
] = "LastUpdatePostDate:desc",
) -> Union[Dict[str, Any], dict]:
"""Search for clinical trials by drug or intervention name.

This function helps biomedical researchers find clinical trials testing specific
drugs, therapies, or treatments, with optional filters for condition and phase.

Args:
intervention (str): Drug, therapy, or treatment name to search for.
condition (str, optional): Medical condition to filter by.
phase (str, optional): Clinical trial phase to filter by.
status (str, optional): Study status filter (default: "ALL").
intervention_type (str, optional): Type of intervention filter (default: "ALL").
page_size (int): Number of results to return (default: 50, max: 1000).
sort (str): Sort order for results (default: most recently updated).
"""Search trials by intervention with condition and phase filters. Returns paginated results with breakdowns.

Returns:
dict: Study search results with summary statistics or error message
dict: Studies list with summary containing intervention searched, total studies, status/phase breakdowns, top conditions/sponsors or error message.
"""
if not intervention:
return {"error": "Intervention name must be provided"}
Expand Down
Loading
Loading