Skip to main content

chembl-mcp-server

io.github.cyanheads/chembl-mcp-serverVersion 0.6.0

Link compounds to protein targets, rank bioactivity, and look up drug mechanisms and indications.

Status

Responds547 msAnswered our handshake without sign-in.

Registry data may be out of date

We could not refresh it, so this page shows the last copy.
Last checked
Nov 14, 2026, 14:48 UTC
Latency
547 ms
Remotes responding
1 of 1
Sign-in
No sign-in
Hosting
Hosted outside the EU (detected)
Registry data as of
Nov 14, 2026, 22:14 UTC

Data from the official MCP Registry, checked by run.zero. How we check

Connect

Streamable HTTP
https://chembl.caseyjhand.com/mcpResponds547 ms
No sign-in

Claude Code

claude mcp add --transport http chembl-mcp-server https://chembl.caseyjhand.com/mcp

Claude Desktop and claude.ai

Settings > Connectors > Add custom connector
Name: chembl-mcp-server
Remote MCP server URL: https://chembl.caseyjhand.com/mcp

Cursor

{
  "mcpServers": {
    "chembl-mcp-server": {
      "url": "https://chembl.caseyjhand.com/mcp"
    }
  }
}

VS Code

code --add-mcp '{"name":"chembl-mcp-server","type":"http","url":"https://chembl.caseyjhand.com/mcp"}'
Streamable HTTP
npm: @cyanheads/chembl-mcp-server 0.6.0
Package only

npm (npx)

claude mcp add chembl-mcp-server -- npx -y @cyanheads/chembl-mcp-server@0.6.0
Streamable HTTP
npm: @cyanheads/chembl-mcp-server 0.6.0
Package only

npm (npx)

claude mcp add chembl-mcp-server -- npx -y @cyanheads/chembl-mcp-server@0.6.0

Built your own server? run.zero hosts MCP servers on European infrastructure.

Host your own MCP server on run.zero

Tools

8 tools

Tools of chembl-mcp-server
Read-only
Idempotent
Open world
chembl_dataframe_describeList the tables and columns staged on a canvas by chembl_get_bioactivities — inspect before calling chembl_dataframe_query to write correct SQL. Returns each table with its row count, kind (table | view), and column names + types. Unavailable when the server sets CANVAS_PROVIDER_TYPE=none.Not declaredYesYesNo
chembl_dataframe_queryRun a read-only SQL SELECT over the bioactivity rows chembl_get_bioactivities staged on a canvas — rank, group, dedupe, and aggregate across the FULL set, not the inline preview. Reference each staged table by the name chembl_get_bioactivities returned — bioactivities for its potency_ranked view, bioactivities_null_potency for null_potency; discover the staged tables and their columns with chembl_dataframe_describe. Compute honest aggregates here (e.g. SELECT parent_molecule_chembl_id, MEDIAN(pchembl_value) AS med FROM bioactivities WHERE standard_type = 'IC50' AND potential_duplicate IS NOT TRUE GROUP BY 1 ORDER BY 2 DESC, which merges a drug with its salts and drops likely repeat citations). Every row the SQL returns comes back on both structuredContent and content[], so bound the result in the SQL itself: project only the columns you need and set a LIMIT. truncated is true when the result exceeded the canvas row cap; page past it with ORDER BY a unique column (e.g. activity_id) and LIMIT/OFFSET written into the query, in place of any LIMIT it already has — offsets reach rows beyond the cap. Unavailable when the server sets CANVAS_PROVIDER_TYPE=none.Not declaredYesYesNo
chembl_get_assayAssay provenance behind bioactivity rows, for one assay or a shortlist in one call: description, type (binding / functional / ADMET / toxicity), BioAssay Ontology format (single protein, cell-based, organism-based, …), the target it measures, organism, cell type, tissue, strain, source document, and ChEMBL's 0–9 confidence score (9 = direct single protein target, lower = homologous, complex, or non-protein targets, 0 = no target assigned yet). Supply assay_chembl_ids from chembl_get_bioactivities rows: the first 100 distinct IDs are looked up and returned in the order given, the rest come back in deferred_ids to pass again, and an ID with no assay record (a compound or target ID included) is listed in not_found_ids rather than failing the call. Call this to judge whether measurements are comparable before ranking them together.Not declaredYesYesYes
chembl_get_bioactivitiesThe flagship compound↔target bioactivity bridge: measurements for a molecule (target deconvolution / selectivity), a target (lead finding), or both together (how potently one compound hits one target). Supply at least one of molecule_chembl_id (from chembl_search_molecules) or target_chembl_id (from chembl_search_targets) — supplying both narrows to that compound–target pair, supplying neither is an error. A drug's measurements are often split across its salts and other alternate forms, so molecule_chembl_id reads that one form unless include_alternate_forms widens it to the whole family under its parent (a salt's ID included), every view, page, and spill reading the same family. Filter by standard_type (IC50/Ki/EC50/…), minimum potency pchembl_value_min, assay_type, organism, and variant (wild type, or one recorded mutant such as "T315I"). Each row carries its activity_comment and data_validity_comment, its assay variant, its source document for citation, its family parent_molecule_chembl_id (merge a drug with its salts on it), ChEMBL's potential_duplicate flag for repeat citations, and its assay format (bao_label). Not every measurement has a derivable pchembl_value, so potency_view picks which side of that split you get: the default "potency_ranked" returns the measurements that have one, most potent first (ChEMBL sorts the rest first otherwise, which is why they are not merged), and "null_potency" returns exactly the measurements that have none. totalCount is the honest full match count across both views either way. Mixing measurement types (IC50 vs Ki) is a scientific error — set standard_type to compare like with like. A popular target carries tens of thousands of rows: results spill to a DataCanvas table (call chembl_dataframe_describe for its columns, then chembl_dataframe_query for honest aggregates across the staged set), while an inline preview answers the immediate question. Each view stages its own table (bioactivities / bioactivities_null_potency), so Not declaredYesYesYes
chembl_get_documentsThe publication, patent, or deposited dataset behind ChEMBL document IDs, for one document or a shortlist in one call: type, title, authors, journal, year, volume, issue, pages, PubMed ID, DOI, and patent number. Supply document_chembl_ids from the document_chembl_id of chembl_get_bioactivities rows or chembl_get_assay records: the first 100 distinct IDs are looked up and returned in the order given, the rest come back in deferred_ids to pass again, and an ID with no document record (a compound, target, or assay ID included) is listed in not_found_ids rather than failing the call. Call this to cite a measurement; a pubmed_id or doi chains to a PubMed or Crossref server for the abstract.Not declaredYesYesYes
chembl_get_drug_infoPharmacology for a drug (molecule): mechanism(s) of action, the molecular target(s) it acts on, action type (inhibitor / agonist / …), max clinical phase, first-approval year, whether it has been withdrawn from a market or carries a boxed warning with ChEMBL's withdrawal and boxed-warning records, and clinical indications with the max phase reached for each. A withdrawn drug keeps max_phase 4 — read withdrawn and warnings before taking phase 4 as on the market. Supply molecule_chembl_id (from chembl_search_molecules) — a parent or any of its salts and other alternate forms reads the same family: ChEMBL often records a drug's mechanisms, approved indications, and warnings on a salt, so both flags and every list cover the whole family under parent_molecule_chembl_id, isotope-labelled and deuterated analogs included. max_phase and first_approval come from the queried form's own record, never from the family, since an analog filed under an approved parent can itself be investigational; re-call with parent_molecule_chembl_id to read them for the parent. Each mechanism and warning names the form it is recorded on, and each indication is listed once per MeSH/EFO pair at the highest phase any form reached, with the forms it is recorded on, each at its own phase. Distinct from the openfda server's label/adverse-event view — this is the curated mechanism-and-indication record. A mechanism's target_chembl_id chains into chembl_get_bioactivities for compounds hitting the same target. Each list carries its own retrieval state: an empty mechanisms, indications, or warnings array means the molecule has none recorded only when the matching mechanisms_status / indications_status / warnings_status is "complete" — "failed" means the list was not retrieved (the request ran out of time or ChEMBL answered with an error, as the matching *_failure says) and the array says nothing about the molecule, and "truncated" means the page cap fetched fewer rows than ChEMBL holds, which the matchingNot declaredYesYesYes
chembl_search_moleculesDiscovery entry point for compounds. Find by name / ChEMBL ID / InChIKey with the default search_type=name (supply query), or run a structure search with search_type exact | similarity | substructure (supply structure as a SMILES). At least one of query or structure is required, and structure is required for the three structure modes. Returns ChEMBL ID, preferred name, canonical SMILES, formula, MW, AlogP, Lipinski violations, QED, max clinical phase, and the family parent_chembl_id on every row; only search_type=similarity adds a Tanimoto similarity percent. Chain molecule_chembl_id into chembl_get_bioactivities or chembl_get_drug_info. A salt often ranks ahead of its parent and carries a small share of the family's measurements, so check parent_chembl_id before chaining. A capped result carries nextCursor — pass it back as cursor with the same filters to read the next page.Not declaredYesYesYes
chembl_search_targetsResolve a protein/gene/UniProt accession to the ChEMBL target ID that chembl_get_bioactivities needs for the target→leads workflow. Supply at least one of accession (UniProt, e.g. P00533), gene_symbol (e.g. EGFR), or query (free-text name, or a ChEMBL target ID such as CHEMBL203 to read that one target); filter further by organism and target_type. Returns each target with its type, organism, and component UniProt accessions + gene symbols. A UniProt accession from the uniprot/protein server is the most precise input. A capped result carries nextCursor — pass it back as cursor with the same filters to read the next page.Not declaredYesYesYes

Details

Registry status
Active
Published
Nov 11, 2026
Updated
Nov 11, 2026
Website
Not given
Categories (suggested)
DocumentsSuggested categories are assigned automatically from the registry text and may be wrong. Verified operators can correct them.
GDPR
Not declared

Are you the operator? Claim this listing