Skip to main content

biothings_search

Search and understand any biological entity — gene, protein, variant, disease, drug, chemical, or pathway — from within AI coding agents.

Backed by BioThings APIs (MyGene.info, MyVariant.info, MyChem.info, MyDisease.info, and more) and UniProt.


Install

Requires Python 3.11 or newer.

pip install biothings-search
# or
uv add biothings-search

Then install the agent skills for your editor (they ship with the package):

biothings-search install-skills            # this project
biothings-search install-skills --global   # user-wide, all projects
biothings-search providers                 # list install targets

By default this writes the three locations named by the Agent Skills specification.agents/skills, .claude/skills and .github/skills. Between them they cover every client below.

Naming a client that reads .agents/skills installs there rather than creating a directory for it — saying --provider cursor tells us which agent you use, it does not ask for a .cursor/ folder. Only Codex needs its own.

Provider Installs to Notes
agents .agents/skills Standard. Any conforming agent reads this
claude .claude/skills Standard. Claude Code
github .github/skills, ~/.copilot/skills Standard. GitHub Copilot, VS Code
codex .codex/skills Codex CLI — the only client needing its own directory
cursor .agents/skills Reads the standard path
gemini .agents/skills Reads the standard path
pi .agents/skills Reads the standard path
opencode .agents/skills Reads the standard path
openclaw .agents/skills Reads the standard path

Quick start (CLI)

biothings-search BRCA1                        # auto-detect type
biothings-search NCBIGene:695                 # CURIE ID lookup
biothings-search BRCA1 TP53 aspirin           # batch: multiple queries at once
biothings-search gene TP53
biothings-search variant rs28934578
biothings-search chemical aspirin
biothings-search disease "breast cancer"
biothings-search protein P04637
biothings-search taxon "Homo sapiens"
biothings-search geneset "p53 pathway"
biothings-search phenotype seizure
biothings-search paper "BRCA1 breast cancer"
biothings-search trial "BRCA1 mutation"
biothings-search anatomy liver
biothings-search cell "T cell"
biothings-search gwas "breast cancer"
biothings-search drug ibuprofen
biothings-search chebi "CHEBI:15365"
biothings-search get 672 --type gene                 # fetch by specific ID
biothings-search get 695 7157 672 --type gene        # batch: one request, not three
biothings-search prefixes                            # list all supported CURIE prefixes
biothings-search sources                             # list the databases searched
biothings-search fields gene                         # list the fields a source offers

All commands accept --json / -j for machine-readable output and --size / -n. The default of 5 suits most lookups; raise it when you need to enumerate or post-process a set with --json. The ceiling is 1000, though each source clamps to what it will actually serve — UniProt tops out at 500.

Asking for more than the summary

Results are normalized down to the fields most questions need — name, canonical ID, taxon, summary. When you need more, name the source's own fields with --fields / -f and they come back under extra, nested the way the source returns them:

biothings-search gene BRCA1 -f genomic_pos,go.BP
biothings-search get 1017 --type gene -f genomic_pos
biothings-search gene BRCA1 -f all --json          # the whole record

biothings-search fields <type> lists what a source offers, straight from the source, so it is never out of date; --match narrows a long catalogue:

biothings-search fields gene --match genomic
biothings-search fields chemical --match drugbank

Requested fields are added to the ones the parser needs, never substituted — -f genomic_pos still returns a named, identified hit. Fields the record does not carry are simply absent from extra rather than reported as empty.

This applies to the BioThings sources. UniProt, PubMed and ClinicalTrials use their own field vocabularies; they accept --fields and ignore it, so a fan-out search never fails on the source that happens to answer.

A shorter command

biothings-search is the only console script installed. If you want a short form, add an alias to your shell profile:

alias bts='biothings-search'   # or biothings, bt, whatever you like

An alias only applies to what you type. It is not expanded inside scripts, or when another program invokes the command — so if you write a script, a Makefile or your own agent skill that calls the short name, use a symlink instead:

ln -s "$(command -v biothings-search)" ~/.local/bin/bts

(The skills shipped with this package call biothings-search directly, so they work either way.)

bts is deliberately not installed as a script: Debian's devscripts package already ships a /usr/bin/bts (the Bug Tracking System CLI), and shadowing it on every Debian and Ubuntu machine would be a poor trade for four saved keystrokes.


MCP server (AI agent integration)

Start the server:

biothings-search serve
# or directly:
biothings-search-server

Claude Code

claude mcp add biothings biothings-search-server

Claude Desktop

Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS):

{
  "mcpServers": {
    "biothings": {
      "command": "biothings-search-server"
    }
  }
}

Cursor

Add to .cursor/mcp.json in your project (already included in this repo):

{
  "mcpServers": {
    "biothings": {
      "command": "biothings-search-server"
    }
  }
}

Or add to Cursor's global MCP settings under Settings → MCP.

Windsurf

Add to Windsurf MCP settings (Settings → MCP Servers):

{
  "mcpServers": {
    "biothings": {
      "command": "biothings-search-server"
    }
  }
}

VS Code (Continue.dev)

Add to .continue/config.json:

{
  "mcpServers": [
    {
      "name": "biothings",
      "command": "biothings-search-server"
    }
  ]
}

Available MCP tools (22)

Tool Description
search_biothing Universal search — auto-detects entity type
search_biothing_batch Search multiple entities concurrently
search_gene Genes via MyGene.info
search_variant Variants via MyVariant.info
search_chemical Chemicals/drugs via MyChem.info
search_disease Diseases via MyDisease.info
search_protein Proteins via UniProt
search_taxon Taxonomy via MyTaxon.info
search_geneset Gene sets/pathways via MyGeneset.info
search_phenotype Phenotypes via Human Phenotype Ontology
search_paper Publications via PubMed
search_trial Clinical trials via ClinicalTrials.gov
search_anatomy Anatomy via Uberon
search_cell_type Cell types via Cell Ontology
search_gwas GWAS associations via GWAS Catalog
search_drug FDA-approved drugs
search_chebi Chemical ontology via ChEBI
get_entity Fetch entity by specific ID
get_entities Fetch several entities by ID in one batched request
list_entity_types List all supported types and CURIE prefixes
list_sources List the databases searched and how to address each
list_fields List the extra source fields available to fields

Agent skills (slash commands)

Install skills so you can invoke them with /biothings, /biothings-gene, etc.:

biothings-search install-skills                      # standard locations, this project
biothings-search install-skills --global             # under your home directory
biothings-search install-skills --provider cursor    # add a vendor directory
biothings-search install-skills --dry-run            # show what would be written

.agents/skills is the cross-client location: agents that follow the Agent Skills standard discover skills there with no vendor-specific setup. .claude/skills and .github/skills are the other two locations the specification names, for Claude Code and GitHub Copilot / VS Code respectively. Everything else is a vendor convention — the files are identical, so an extra copy costs nothing but a directory.

Note the home locations differ for two clients: Copilot reads ~/.copilot/skills rather than ~/.github/skills, and pi reads ~/.pi/agent/skills. --global handles both.

Contributors regenerating the copies committed in this repo use python scripts/build_skills.py instead; the source of truth is src/biothings_search/skills/.

Skill Command
Universal search /biothings BRCA1
Gene search /biothings-gene TP53
Variant search /biothings-variant rs28934578
Chemical search /biothings-chemical aspirin
Disease search /biothings-disease "breast cancer"
Protein search /biothings-protein P04637
Taxon search /biothings-taxon "Homo sapiens"
Geneset search /biothings-geneset "p53 pathway"
Phenotype search /biothings-phenotype seizure
Paper search /biothings-paper "BRCA1 2023"
Trial search /biothings-trial "BRCA1 mutation"
Anatomy search /biothings-anatomy liver
Cell type search /biothings-cell "T cell"
GWAS search /biothings-gwas "breast cancer"
Drug search /biothings-drug ibuprofen
ChEBI search /biothings-chebi "CHEBI:15365"
Help /biothings-help

CURIE ID support

Queries in CURIE format (prefix:id) are resolved directly to the correct entity and API — no text search needed. Prefixes follow the Biolink Model standard (validated against 4.4.4) and are case-insensitive.

biothings-search NCBIGene:695         # → gene BTK
biothings-search UniProtKB:P04637     # → protein TP53
biothings-search DBSNP:rs28934578     # → variant
biothings-search MONDO:0007254        # → disease breast cancer
biothings-search CHEBI:15365          # → aspirin
biothings-search CL:0000084           # → T cell
biothings-search NCT:NCT00000125      # → clinical trial
biothings-search NDC:66715-6526       # → an FDA-listed drug product

Run biothings-search prefixes to see all 51 supported prefixes with their canonical ID priority. Every prefix listed there is verified to resolve against the live API — a namespace with no reachable backend is left out rather than advertised and silently dead.

Input is deliberately more forgiving than output. Eleven of those prefixes (pubmed:, ensg:, chembl:, nct:, …) are conveniences that are not in the Biolink Model; they are accepted because people type them, and never emitted. Everything in canonical_id uses the model's own spelling.

biothings-search chebi and biothings-search gwas search those databases specifically, but their results are typed by what they are — a ChEBI entry is a chemical, a GWAS record is a variant — with the database in each hit's source. That keeps canonical_id usable for linking: the same compound has the same type and ID whether it came from ChEBI or MyChem.

Each result includes a canonical_id field — the highest-priority Biolink-standard CURIE available for that entity (e.g. NCBIGene:672 for BRCA1, UniProtKB:P04637 for TP53), following that class's id_prefixes order in the model.

One consequence worth knowing: a MyChem record contributed only by the NDC directory is a marketed drug product rather than a small molecule, so it comes back typed drug with an NDC: ID even from a chemical search. Biolink draws the same line — Drug carries NDC in its id_prefixes and SmallMolecule does not — and it is the difference between having a canonical ID and having none.


Entity type auto-detection

Bare identifiers are recognized automatically without a CURIE prefix:

Pattern Detected as
rs28934578 Variant (dbSNP rsID)
chr1:g.123A>T Variant (HGVS)
ENSG00000141510 Gene (Ensembl)
7157 (integer) Gene (Entrez ID)
P04637 Protein (UniProt)
CHEMBL25 Chemical (ChEMBL)
27-char InChIKey Chemical
DB00945 Chemical (DrugBank)
DOID:1612 Disease (DO)
MONDO:0007254 Disease (MONDO)
HP:0001250 Phenotype (HPO)
GO:0006915 Gene set (GO)
R-HSA-109582 Gene set (Reactome)
UBERON:0002107 Anatomy (Uberon)
CL:0000084 Cell type (CL)
CHEBI:15365 ChEBI chemical
PMID:12345678 Publication
NCT00000125 Clinical trial
GCST90428116 GWAS study

Unknown patterns trigger a concurrent fan-out search across genes, chemicals, diseases, and proteins.


Scoping to a species

Gene, protein and gene-set searches cover every organism by default, so a symbol query returns the same gene from dozens of species. Scope it once and forget it:

export BIOTHINGS_SEARCH_SPECIES=human        # or human,mouse — or a taxid
biothings-search gene BTK                    # human only
biothings-search gene BTK --species mouse    # per-command override
biothings-search gene BTK --species all      # opt back out

For an agent client, set it in the MCP server config — there is no per-call flag to reach for, and it applies to every tool:

{
  "mcpServers": {
    "biothings": {
      "command": "biothings-search-server",
      "env": { "BIOTHINGS_SEARCH_SPECIES": "human" }
    }
  }
}

The MCP tools also take a species argument that overrides it for one call.

Accepts a name (human, mouse, zebrafish, fruitfly, …), an NCBI taxid (9606), a comma-separated combination, or all. An unrecognised value fails immediately and lists the alternatives, rather than reaching the API as an opaque error.

Direct ID lookups are never scoped. biothings-search NCBIGene:12229 resolves the mouse record even under BIOTHINGS_SEARCH_SPECIES=human — a CURIE names one entity, so filtering it could only ever return nothing. Only searches are filtered. Variants, chemicals, diseases and the ontologies have no species concept and are unaffected.

Configuration

All optional; sensible defaults apply when unset.

Variable Default Purpose
BIOTHINGS_SEARCH_SPECIES all Restrict gene/protein/geneset searches to one or more organisms (name, NCBI taxid, or all). Never applied to ID lookups.
BIOTHINGS_TRANSLATOR_HOST https://biothings.transltr.io Host for the Translator-hosted sources (ChEBI, HPO, Uberon, Cell Ontology, GWAS, FDA, trials). Point at the CI deployment to test pre-release data.
NCBI_API_KEY Raises the PubMed rate limit from 3 to 10 requests/second. Get one here.
BIOTHINGS_SEARCH_EMAIL help@biothings.io Contact address sent to NCBI E-utilities.
BIOTHINGS_SEARCH_CACHE_TTL 300 Seconds a response stays cached. 0 disables caching.
BIOTHINGS_SEARCH_CACHE_SIZE 512 Maximum cached responses.

Requests are rate-limited per host, retried on transient failures (429 and 5xx) with exponential backoff, and cached in-process, so a batch of concurrent searches will not trip an upstream limit or re-fetch what it just read.


Data sources

Entity type API Coverage
Gene MyGene.info 40M+ annotations, 20K+ species
Variant MyVariant.info 900M+ human variants
Chemical MyChem.info ChEMBL, DrugBank, PubChem, FDA NDC
Disease MyDisease.info MONDO, OMIM, DO, NCIT
Protein UniProt Swiss-Prot / TrEMBL
Taxon MyTaxon.info NCBI Taxonomy
Gene set / Pathway MyGeneset.info GO, MSigDB, Reactome, WikiPathways, SMPDB
Phenotype Human Phenotype Ontology BioThings HPO API
Paper PubMed NCBI E-utilities
Clinical trial ClinicalTrials.gov BioThings CT API
Anatomy Uberon BioThings Uberon API
Cell type Cell Ontology BioThings CL API
GWAS GWAS Catalog BioThings GWAS API
Drug FDA Drugs@FDA BioThings FDA API
ChEBI ChEBI BioThings ChEBI API

Extending with new data sources

  1. Subclass BioThingsAPI in src/biothings_search/apis/biothings.py (or BaseAPI for a non-BioThings source) and implement _parse_hit(), setting canonical_id on each SearchHit
  2. Register in _TYPE_TO_API in search.py
  3. Add entries to _CURIE_MAP and CANONICAL_PREFIXES in models.py, verifying each prefix against the live API first
  4. Add a CLI command in cli.py and an MCP tool in server.py
  5. Create a skill in src/biothings_search/skills/ and run python scripts/build_skills.py
  6. Add a fixture case in tests/fixtures/_capture.py and a parser test

See CONTRIBUTING.md for details.


License

Apache License 2.0.

Commercial use is unrestricted. The licence covers copyright only — section 6 grants no trademark rights, so "BioThings" and the service names are governed separately by TRADEMARKS.md. In short: say your software works with BioThings as much as you like; don't name your software BioThings.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

biothings_search-0.2.0.tar.gz (129.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

biothings_search-0.2.0-py3-none-any.whl (88.9 kB view details)

Uploaded Python 3

File details

Details for the file biothings_search-0.2.0.tar.gz.

File metadata

  • Download URL: biothings_search-0.2.0.tar.gz
  • Upload date:
  • Size: 129.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for biothings_search-0.2.0.tar.gz
Algorithm Hash digest
SHA256 8e5a4639888529f10e84b28a19c5719a035623e9ac987f1db835bb73e3e584c2
MD5 026e9b4df1f84df45f061f9d94fc3eea
BLAKE2b-256 f27f93032382c25c26659c635f0cdf10f2f1e5676ddb390e52f29423440b7c28

See more details on using hashes here.

Provenance

The following attestation bundles were made for biothings_search-0.2.0.tar.gz:

Publisher: release.yml on biothings/biothings_search

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file biothings_search-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for biothings_search-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 862e8f341d4abf5858453ed62b6f1c006778462c109b72f79f76c27b203ff14c
MD5 f9d4099a5492aec70e3c1e4ed302d9aa
BLAKE2b-256 069fc208f9ea6628c1fb838fff8dd98aac9e8627224681e73473c074a81870c3

See more details on using hashes here.

Provenance

The following attestation bundles were made for biothings_search-0.2.0-py3-none-any.whl:

Publisher: release.yml on biothings/biothings_search

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.3.0

2 files

This release

0.2.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page