BioMCP
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| S2_API_KEY | No | Semantic Scholar API key to prevent 429 rate limits | |
| NCI_API_KEY | No | NCI Clinical Trials API | |
| NCBI_API_KEY | No | NCBI API key for higher PubMed/NCBI rate limits | |
| ONCOKB_TOKEN | No | OncoKB cancer variant annotations | |
| UMLS_API_KEY | No | UMLS terminology services | |
| OPENFDA_API_KEY | No | OpenFDA API access | |
| DISGENET_API_KEY | No | DisGeNET disease-gene associations | |
| ALPHAGENOME_API_KEY | No | AlphaGenome variant scores |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| gene_searchC | Search for genes by symbol, name, or keyword |
| gene_getA | Get detailed gene information by symbol. Response section keys mirror the requested section names: sections:["clinical_evidence"] returns sections.clinical_evidence, "protein_atlas" returns sections.protein_atlas, "dosage_sensitivity" returns sections.dosage_sensitivity, "disease_associations" returns sections.disease_associations — the legacy storage keys (civic, hpa, clingen, disgenet) never appear in responses. |
| gene_diseasesA | Get diseases associated with a gene. Requires DISGENET_API_KEY environment variable for DisGeNET data; falls back to OpenTargets gene-disease associations when unavailable. |
| gene_drugsA | Find drugs targeting a gene. Results are ranked by max clinical phase, then trial-report count, with salt forms collapsed. Response is an envelope: { results, warnings?, errors? } — OpenTargets failures and unresolved genes ride in errors[] as { source, message, retryable? } instead of inline items (issues #130, #179) |
| gene_trialsA | Find clinical trials for a gene |
| gene_articlesA | Find articles about a gene. Response is an envelope: { results, warnings?, errors? } — per-backend failures ride in |
| gene_enrichA | Perform pathway enrichment analysis for a gene list (Reactome over-representation). Requires at least 3 genes; the list is deduplicated (case-insensitive) before submission. Each pathway reports genes_overlap — the count of unique SUBMITTED genes Reactome matched there, resolved with one follow-up token lookup (Reactome's entity-level match count can exceed the gene count when one gene maps to multiple entities, e.g. a UniProt entry plus Ensembl gene/transcript). The reply also reports how many pathways Reactome found in total alongside the returned page. Typical completion is 15–45 s (the Reactome analysis takes 8–22 s per step across two sequential steps), with a worst case around 105 s including one retry per step; requires reachability of reactome.org, and clients whose request timeout is 60 s may need to raise it for large result follow-ups. |
| variant_searchA | Search for variants. Use structured parameters for best results:
|
| variant_getA | Get detailed variant information with optional sections. Core data (id, gene, rsid, significance) is always returned at the top level. Use sections to request additional data. Response section keys mirror the requested section names: sections:["alphagenome_scores"] returns sections.alphagenome_scores — the legacy storage key (alphagenome) never appears in responses. |
| variant_oncokbB | Get OncoKB annotations for a variant in a cancer gene. Requires ONCOKB_TOKEN environment variable. |
| variant_trialsA | Find clinical trials for a variant. Response is an envelope: { results, warnings? } — when MyVariant.info ID resolution fails, a warning rides alongside the results (which then come from searching the raw identifier) so a backend failure never masquerades as "no trials exist"; retry may resolve BRAF V600E-style naming (issue #198) |
| drug_searchA | Search for drugs by name or keyword (chemical identity: names, synonyms, and identifiers in ChEMBL/MyChem). This is NOT a mechanism or target search — MyChem has no mechanism text in this query, so "EGFR inhibitor"-style queries return nothing. For drugs targeting a gene/mechanism, use gene_drugs with the target gene symbol. |
| drug_getC | Get detailed drug information by name |
| drug_trialsB | Find clinical trials for a drug |
| disease_searchA | Search for diseases by name, phenotype, or keyword. Response is an envelope: { results, warnings?, errors? } (issue #130) |
| disease_getC | Get detailed disease information by ID |
| disease_drugsA | Get drugs for a disease via OpenTargets. Results are ranked by max clinical phase, then trial-report count, with salt forms collapsed. Response is an envelope: { results, warnings?, errors? } — OpenTargets failures and unresolved diseases ride in errors[] as { source, message, retryable? } instead of inline items (issue #130) |
| disease_trialsB | Get clinical trials for a disease. Response is an envelope: { results, warnings?, errors? } (issue #130) |
| article_searchA | Search literature across multiple backends with federated search and deduplication. Response is an envelope: { results, warnings?, errors? } — per-source failures ride in |
| article_getA | Get article by PMID/PMCID/DOI. Section response keys differ from request names: "oa" is stored as sections.open_access, "graph" as sections.citation_graph. Preprint DOIs (bioRxiv/medRxiv, e.g. "10.1101/2025.03.05.641768" or new prefix "10.64898/...") return the preprint record: all versions, license, category, funders, JATS full-text URL, published-version mapping, and (with sections=["citation"]) Europe PMC preprint citations. Journal articles, sections=["fulltext"]: returns the ACTUAL full text when freely readable in PMC/Europe PMC (open-access AND free-to-read). fulltext.status is "available" or "unavailable"; when unavailable, fulltext.reason is one of paywalled | no_pmcid | no_machine_readable_xml | not_implemented_for_preprints | fetch_failed (with alternatives in links, e.g. doi_url); a transiently failed OA-status lookup counts as no status info, so a paywalled in-PMC article surfaces as fetch_failed until a retry reclassifies it as paywalled. The five-value open-access vocabulary — open_access | free_to_read | paywalled | not_in_pmc | unknown — is sections.open_access.status (request sections:["oa"]); fulltext.oa_status echoes it so paywalled vs not-in-PMC is visible without the oa section. Default (fulltext_output="file"): the complete text is written to a server-side markdown file and the reply carries file_path plus an outline with per-section line numbers and char counts — Read/Grep the file selectively instead of loading it into context. fulltext_output="inline" (use only if you cannot read server-side files): fulltext.sections is an ordered array of {heading, text, truncated} objects plus char_count/total_char_count/truncated/omitted_sections, capped by fulltext_max_chars. sections=["oa"] returns license/access metadata and links ONLY (pdf_url presence does not by itself mean the text is fetchable — use fulltext for content). "all" = oa+annotations+graph+citation WITHOUT fulltext (request ["fulltext"] separately). oa/fulltext do not apply to preprints (see the jatsxml_url link). Journal-article citation: fast mode (~4s, 4 providers, auto-fallback to PubMed) or full mode (~15-30s, all 5 providers incl. PubMed). Forward citation lists come from Europe PMC, Semantic Scholar, and OpenCitations; Crossref provides counts and references only. |
| preprint_fulltextA | On-demand bioRxiv/medRxiv preprint full text (JATS XML, parsed to sections). Input: a preprint DOI (e.g. "10.1101/2025.03.05.641768"), optional version (default: latest). Downloads are strictly on-demand (never run during search), paced, and cached per (doi, version) — JATS per version is immutable, so repeat calls are served from cache without re-downloading. www.biorxiv.org rate-limits aggressively: on a 429/Cloudflare verdict this tool pauses downloads for >=60s (Retry-After honored) and every call during the cooldown returns an honest unavailable/rate_limited envelope with retry_after_sec — cached copies are still served instantly. The per-article license (cc by, cc by-nc-nd, na, ...) rides on every reply and governs reuse; for corpus-scale text mining use the bioRxiv/medRxiv monthly S3 buckets (see https://www.biorxiv.org/tdm). Output "file" (default): complete text written to a server-side markdown file, reply carries file_path + outline (Read/Grep selectively); "inline": capped text sections (fulltext_max_chars, default 40000). |
| journal_metricsA | Journal quality metrics — an open-access alternative to the Clarivate impact factor (IF). Returns the OpenAlex 2-year mean citedness score (an IF-style metric), h-index, i10-index, citation counts, open-access flag (is_oa), and quality-list tiers (e.g. medline, norway-2, jufo-3…). Accepts a journal name, NLM abbreviation (e.g. 'N Engl J Med'), or ISSN (e.g. '0028-0836'; article records carry journal_issn). |
| trial_searchC | Search clinical trials by condition, intervention, or keyword |
| trial_getC | Get detailed trial information by NCT ID |
| discoverA | Free-text concept resolution - find entities matching a free-text query. Prefers a candidate whose name/symbol exactly matches the query (case-insensitive), ranks those exact matches first across entity types, and demotes numbered susceptibility-locus labels (e.g. "lung cancer susceptibility 1") within each backend's candidates; each result's matched_on field reports why it was picked ("exact" or "first") |
| batch_getA | Get multiple entities in parallel. Article items return metadata (with inline abstract) by default; for full text pass sections:["fulltext"] on the item — PMC articles then return a small file handle (file_path + outline, never body text inline) while non-PMC articles return an explicit unavailable + reason. Nonexistent PMIDs yield a per-item error and the batch continues. For inline text use article_get with fulltext_output="inline" |
| pdbA | Access the Protein Data Bank (RCSB PDB) for macromolecular structure data. SEARCH: Provide "query" to find structures (e.g., "kinase inhibitor", "hemoglobin"). GET: Provide "pdb_id" to retrieve entry metadata with optional detail sections. Sections list per-entity records (polymer_entities, ligands, assembly); when some records fail while siblings succeed, each failure appears as an inline {_error} item AND the response carries a top-level "warnings" array naming the section and failed item. DOWNLOAD: Provide "pdb_id" + download=true to save the structure file and get the file path. |
| patent_searchA | Search patents worldwide (US, EP, WO, JP, and 100+ authorities). Quote exact multi-word concepts (e.g. "flow cytometry") to avoid off-topic matches. Backend characters: ppubs = USPTO Public Search full-text conceptual search (US only, keyless, relevance-ranked; default US backend) | ops = EPO OPS worldwide bibliographic search over titles/abstracts (needs EPO_OPS_CONSUMER_KEY/EPO_OPS_CONSUMER_SECRET) | uspto_odp = US application metadata, bibliographic only but inventor/CPC/continuity-rich (needs USPTO_API_KEY) | google_patents = worldwide best-effort (often unavailable). Auto mode queries worldwide + ppubs concurrently; if ppubs fails hard it falls back to uspto_odp once (noted in warnings). Per-backend failures and degradation notes are reported out of band in the response |
| patent_getA | Get patent details by publication number (e.g. "US11027025B2", "EP3904939B1", "US20260240819A1"). Sections: abstract, claims (US fulltext via USPTO Public Search; EP/WO via EPO OPS when configured, otherwise Google Patents pages — see per-section source fields), citations (backward + forward), family, classifications. US claims may fall back to an unofficial Google Patents rendering when PPUBS is slow or unreachable — flagged in _warnings. Section failures are reported per section (inline error entry plus a _warnings note), never by failing the whole call. |
| geo_searchA | Search NCBI GEO (Gene Expression Omnibus) for functional genomics studies — expression microarrays, RNA-seq, and other high-throughput sequencing series. Queries accept plain terms ("breast cancer RNA-seq", "melanoma single cell") or NCBI field syntax ("GSE183947[Accession]"). Every result carries accession (→ geo_get for full details), bioproject, and pubmed_ids (→ article_get). sra_project (→ sra_get) appears only when NCBI has linked the SRA study to the series — many newer series lack the link — so geo_get(accession) is the reliable route to SRA accessions (its sra field). |
| geo_getA | Get the full SOFT record details for a GEO entry: series (GSE...), sample (GSM...), or platform (GPL...). A series detail includes summary, organisms, platform_ids, a sample preview, supplementary file URLs, and cross-references for chaining: sra → sra_get(SRP.../SRR...), pubmed_ids → article_get, samples → geo_get(GSM...), platform_ids → geo_get(GPL...). GDS accessions (curated DataSets, not served by SOFT) return structured guidance as data — { accession, guidance, see_also: { series: "GSE…", sample: "GSM…" } } — pointing at the underlying series/sample records; this is a successful result, not an error. Malformed accessions still fail at schema validation. download=true additionally saves a supplementary file to a local temp path and returns its path, size, and source URL — the pick prefers .gz/.csv/.txt, else the first listed supplementary file (subject to max_bytes). |
| sra_searchA | Search NCBI's Sequence Read Archive (SRA) for sequencing experiments and runs. The query may be free text, an accession (SRP study, SRX experiment, SRR run, SRS sample), or NCBI field syntax ("RNA-SEQ AND Homo sapiens[Organism]"). Results list experiment/study/sample accessions (NCBI S…, European E…, or DDBJ D… prefixes — all resolvable by sra_get), organism, library strategy, run count, and first_run_accession for chaining into sra_get. |
| sra_getA | Get full details for an SRA accession indexed by NCBI: run (SRR/ERR/DRR — instrument, spots, bases, size), experiment (SRX/ERX/DRX — library design), study (SRP/ERP/DRP — experiment list), or sample (SRS/ERS/DRS). NCBI SRA indexes NCBI, European (ENA), and DDBJ submissions alike, so accessions returned by sra_search resolve here regardless of prefix. Chain from geo_get (sra field) or sra_search (experiment_accession / first_run_accession). |
| genbank_searchA | Search NCBI nucleotide records (GenBank/RefSeq/INSDC). Queries may be plain terms, an accession, or NCBI field syntax ("TP53[Gene Name] AND Homo sapiens[Organism]", "BRCA1[Gene Name]"). Results include accession.version, definition, length_bp, organism, and topology — chain accessions into genbank_get or genbank_genes. |
| genbank_getA | Fetch a GenBank/RefSeq nucleotide record as text (GenBank flat file or FASTA). Whole-record fetches are capped at 2,000,000 bp — larger records require a seq_start/seq_stop region (1-based, inclusive, up to 10 Mb span; set strand=2 for a reverse-strand slice where seq_start > seq_stop — the region field echoes the request as given, while NCBI's text shows complement(min..max)). Output: records up to 1,000 characters are returned inline (sequence_text with char_count/truncated). Anything larger defaults to file mode — the FULL text is written to a server-side cache file and the reply carries mode:"file", file_path, char_count, and total_char_count instead of sequence_text (never truncated); Read/Grep the file selectively. The cache is ephemeral (pruned after ~7 days / 500 files) and the path is server-local; re-call to regenerate. sequence_output:"inline" opts back into inline text capped at 200,000 characters — use it only if you cannot read server-side files. |
| genbank_genesA | Map a GenBank/RefSeq nucleotide accession to its NCBI Gene IDs (elink nuccore→gene). The returned gene_ids are NCBI Gene (entrezgene) IDs. gene_get takes an HGNC gene symbol, NOT a numeric entrez id, so an id must first be resolved to its symbol — gene_search result rows carry both symbol and entrez_id, so the id→symbol bridge exists via gene_search. Useful bridge from a sequence record to gene-level annotation. |
| gtex_expressionA | Get median gene expression across GTEx tissues (GTEx Analysis v10, 54 tissue sites, TPM, sorted highest first). Accepts an HGNC symbol (TP53) or Ensembl gene ID (ENSG00000141510, versioned or bare). Optionally filter to a single tissue via its tissueSiteDetailId (e.g. Brain_Cortex, Whole_Blood). |
| gtex_eqtlA | Get significant cis-eQTL associations for a gene in a specific GTEx tissue (GTEx Analysis v10): variant_id, p_value, and NES (effect direction/size), sorted by ascending p-value. tissue is a required GTEx tissueSiteDetailId (e.g. Whole_Blood, Brain_Cortex). An empty associations list is a VALID scientific result — the gene was tested but has no significant cis-eQTLs in that tissue (not a lookup failure). In that case the result carries a note listing other tissues where significant eQTLs DO exist (or stating that none exist in any tissue). |
| ensembl_lookupA | Resolve a gene in Ensembl terms for ANY Ensembl species (356 available): stable ID (ENSG…), symbol↔ID mapping, versioned identifier, canonical transcript, and coordinates on the current assembly (GRCh38 human, GRCm39 mouse, …). With expand=true, returns all transcripts with translation/protein IDs. Accepts an HGNC symbol (BRAF) or Ensembl gene ID (ENSG00000157764, versioned or bare — versions are resolved to the current record). Species accepts scientific names or aliases ('homo_sapiens'/'human', 'mus_musculus'/'mouse'). For rich human gene annotation (summary, pathways, drugs, diseases) use gene_get instead — this tool is the identifier/structure authority. |
| ensembl_homologyA | Find orthologues or paralogues of a gene across species (Ensembl Compara) — the cross-species gene mapping source in biomcp. Returns target stable IDs, gene symbols (when the assembly provides them, e.g. ARAF/RAF1 for BRAF paralogs), species, taxonomy level, and percent identity, sorted by identity. Accepts an HGNC symbol or Ensembl gene ID; scope to one species with target_species ('mouse') or target_taxon (10090). Use it for conservation questions ('is this gene conserved?', 'what is the mouse orthologue of BRAF?'). |
| ensembl_consequenceA | Predict the functional consequence of a variant on demand via Ensembl VEP — works even for NOVEL variants absent from every database, and for non-human species. Input forms: HGVS c./p./g. notation ("NM_004333:c.1799T>A", "NM_004333.6:c.1799T>A") or a dbSNP rsID ("rs113488060"). Prefer HGVS over rsIDs when both are available — rsIDs are resolved through dbSNP's coordinate mapping, which can yield less specific consequences. RefSeq accessions may carry a version ("NM_004333.6:c.1799T>A"); when the version is not carried by the current Ensembl release the call is retried against the bare accession and the result flags the reinterpretation in warnings. Per-species rules: the variant must be valid on a transcript of THAT species — RefSeq NM_ accessions work cross-species only when the transcript belongs to it (e.g. "NM_011640:c.100A>G" + species 'mouse' is mouse Trp53; a human NM_ fed to species 'mouse' fails). Ensembl transcript IDs (ENST…, ENSMUST…) are accepted for their own species, and c./p. positions must be in range for the transcript. Invalid input returns the upstream VEP error explaining what could not be mapped. Returns the most severe consequence plus per-transcript effects (impact, codon/amino-acid change, SIFT/PolyPhen where available) and co-located known variants (ClinVar/COSMIC IDs, gnomAD/1000G frequencies when present). For KNOWN human variants, variant_get additionally provides deep pre-computed scores (CADD, REVEL, AlphaMissense, ClinVar stars) — prefer it there. |
| ensembl_regionA | Query what lives in a genomic interval on the current assembly (GRCh38 for human): genes/transcripts (stable IDs, symbols, biotypes) and known variants (rsIDs, alleles, consequence terms, clinical significance). Ideal for locus triage — "what genes and known variants sit in this GWAS hit interval?". Genes/transcripts are always fetched for the FULL requested span, but variation density can reach ~100k variants in dense loci (which times out upstream), so when the span exceeds 50 kb variation is queried only for a 50 kb window centered on the region midpoint — the result echoes effective_variation_window (the coordinates actually queried for variation) and variation_truncated (names the dropped span) when this cap applies. To sweep variation across a large interval, issue adjacent region calls. Keep spans modest (<1 Mb recommended); output is capped at limit with a truncated marker. For sequence text use genbank_get; for entity-level annotation chain IDs into gene_get / variant_get. |
| biomcp_configureA | Inspect and configure biomcp — unified observability and restricted controllability for every parameter. What it covers: three optional feature groups (database, analysis_r, analysis_biowasm) whose knobs live in the .biomcp.json project config file (written by this tool, loaded at server startup — a restart applies changes), plus every environment-only parameter (API keys, proxy, security boundaries), which is query-only. Actions:
Hard rules: environment parameters are never settable here (the response tells you how to set them in your client's env block); env var values are never displayed (masked: presence + fingerprint only); the file write is refused when the server's working directory is not a project root — the response then carries a paste-ready env block instead. Examples: {"action":"status"} · {"action":"status","filter":"features.analysis_r"} · {"action":"set","values":{"features.analysis_biowasm.enabled":true}} · {"action":"set","values":{"features.database.enabled":true,"features.database.type":"sqlite","features.database.sqlite_path":["data/geo.db"]}} · {"action":"set","values":{"features.analysis_r.mirror_url":null}} · {"action":"reset","target":"analysis_r"} Changes apply at server startup: finish dependency prerequisites first (see prerequisites in the response), then restart the client/session once, then re-call this tool with {} to verify running_now. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 43 tools
Most tools follow a clear entity+action split (gene_/variant_/drug_/disease_/article_/trial_/geo_/sra_/genbank_/patent_ + search/get), and descriptions actively steer agents apart (e.g. drug_search explicitly says it is not a target search, use gene_drugs; gene_get vs ensembl_lookup is carved out). A few overlaps remain that will cause misselection: five routes into clinical trials (drug_trials, gene_trials, variant_trials, disease_trials, trial_search), preprint_fulltext versus article_get on a preprint DOI, and discover versus the per-entity *_search tools. Batch_get also shadows every get tool.
The dominant convention is consistent snake_case entity_verb (gene_search/gene_get, variant_trials, article_get, geo_search, patent_get), which makes the set predictable. Deviations exist: pdb is a bare noun doing search/get/download in one tool, discover and batch_get are generic verbs without an entity, and journal_metrics/gene_enrich are noun_verb or verb-only rather than entity_action.
43 tools is heavy, but the breadth is genuine (genes, variants, drugs, diseases, trials, literature, patents, PDB, GEO/SRA/GenBank, GTEx, Ensembl, config), and most domains are well-scoped search/get pairs that earn their place. Still, several convenience wrappers (gene_articles, gene_diseases, gene_drugs, gene_trials, batch_get) could be folded into generic search tools, so the surface feels larger than strictly necessary.
Coverage of the bioinformatics domain is broad and lifecycle-complete for most entities: search+get for genes, variants, drugs, diseases, trials, articles, patents, sequences, structures, with rich cross-linking hints (sra→sra_get, geo→sra, genbank_genes→gene_search). Minor gaps: Reactome enrichment is the only pathway tool and has no reverse lookup, there is no protein/UniProt target tool separate from PDB, and no batch/list-upload path except the generic batch_get and gene_enrich gene lists.