Link compounds to protein targets, rank bioactivity (IC50/Ki/EC50), and look up drug mechanisms and indications over ChEMBL via MCP. STDIO or Streamable HTTP.
- ✓Open-source license (Apache-2.0)
- ✓Actively maintained (<30d)
- ✓Clear description
- ✓Topics declared
- ✓Documented (README)
git clone https://github.com/cyanheads/chembl-mcp-server{
"mcpServers": {
"chembl": {
"command": "node",
"args": ["/path/to/chembl-mcp-server/dist/index.js"]
}
}
}MCP Servers overview
<div align="center"> <h1>@cyanheads/chembl-mcp-server</h1> <p><b>Link compounds to protein targets, rank bioactivity (IC50/Ki/EC50), and look up drug mechanisms and indications over ChEMBL via MCP. STDIO or Streamable HTTP.</b> <div>7 Tools (+1 opt-in) • 2 Resources</div> </p> </div> <div align="center"> [](./CHANGELOG.md) [](./LICENSE) [](https://github.com/users/cyanheads/packages/container/package/chembl-mcp-server) [](https://modelcontextprotocol.io/) [](https://www.npmjs.com/package/@cyanheads/chembl-mcp-server) [](https://www.typescriptlang.org/) [](https://bun.sh/) </div> <div align="center"> [](https://github.com/cyanheads/chembl-mcp-server/releases/latest/download/chembl-mcp-server.mcpb) [](https://cursor.com/en/install-mcp?name=chembl-mcp-server&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsIkBjeWFuaGVhZHMvY2hlbWJsLW1jcC1zZXJ2ZXIiXX0=) [](https://vscode.dev/redirect?url=vscode:mcp/install?%7B%22name%22%3A%22chembl-mcp-server%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22%40cyanheads%2Fchembl-mcp-server%22%5D%7D) [](https://www.npmjs.com/package/@cyanheads/mcp-ts-core) </div> <div align="center"> **Public Hosted Server:** [https://chembl.caseyjhand.com/mcp](https://chembl.caseyjhand.com/mcp) </div> --- ## Tools Eight tools — five for the ChEMBL compound/target/bioactivity surface, plus three for SQL analytics over the DuckDB-backed canvas that `chembl_get_bioactivities` spills to (the third is opt-in): | Tool | Description | |:---|:---| | `chembl_search_molecules` | Find compounds by name / ChEMBL ID / InChIKey, or run a structure search (exact \| similarity \| substructure) from a SMILES. | | `chembl_get_bioactivities` | The flagship compound↔target bridge: bioactivity measurements for a molecule, a target, or **both** (the compound×target pair), ranked on `pchembl_value`, or the measurements without one via `potency_view`. Large sets spill to a canvas. | | `chembl_search_targets` | Resolve a protein / gene symbol / UniProt accession to the ChEMBL target ID `chembl_get_bioactivities` needs. | | `chembl_get_drug_info` | Drug pharmacology — mechanism(s) of action, molecular target(s), action type, first-approval year, and clinical indications. | | `chembl_get_assay` | Assay provenance behind a bioactivity row — type, target, organism, and ChEMBL's 1–9 confidence score. | | `chembl_dataframe_query` | Run a read-only SQL `SELECT` over the bioactivity rows spilled to a canvas — rank, group, dedupe, aggregate across the full set. | | `chembl_dataframe_describe` | List the tables and columns staged on a canvas, so you can write correct SQL before querying. | | `chembl_dataframe_drop` | Drop a named staged table from a canvas. Opt-in via `CHEMBL_DATAFRAME_DROP_ENABLED=true` — absent from `tools/list` when off, since TTL already reclaims staged tables. | ### `chembl_search_molecules` The discovery entry point for compounds. - Default `search_type=name` matches drug names, synonyms, ChEMBL IDs, and InChIKeys in one query - A `query` that is exactly a ChEMBL ID or an InChIKey is routed to ChEMBL's single-record lookup rather than the fuzzy text index, so it returns `totalCount: 1` instead of a full-text relevance count. Adding `max_phase_min` returns the query to the text index, since that filter belongs to the search endpoint - Structure search via `search_type`: `exact` (exact match), `similarity` (Tanimoto ≥ threshold), or `substructure` (contains the query structure) — supply `structure` as a SMILES - `similarity_threshold` is an integer 40–100 (default 70; ChEMBL rejects values below 40) - `max_phase_min` restricts name searches to compounds at or above a max clinical phase (e.g. `4` for marketed drugs only) - Every row carries `max_phase` — the cheap druggability signal (4 = marketed, 0 = research) — plus MW, AlogP, Lipinski rule-of-five violations, and QED. Only `search_type=similarity` carries a Tanimoto `similarity` percent; `exact` and `substructure` results omit the field entirely, because ChEMBL supplies a score for similarity search alone - Results past `limit` are reachable: when more remain, the response carries a `nextCursor`, and passing it back as `cursor` returns the following page. It is omitted — not null — on the last page. Redeem a cursor with the same filters that minted it - Chain `molecule_chembl_id` into `chembl_get_bioactivities` or `chembl_get_drug_info` --- ### `chembl_get_bioactivities` The flagship tool and the reason the server exists — the curated compound↔target↔assay link. - Supply **at least one** of `molecule_chembl_id` (target deconvolution / selectivity) or `target_chembl_id` (lead finding); supplying **both** narrows to that compound–target pair — "how potently does this compound hit this target, and in which assays?" — while neither is a `missing_filter` error - Filter by `standard_type` (IC50 / Ki / EC50 / …), minimum potency `pchembl_value_min`, `assay_type`, and `organism`; rows are ranked on `pchembl_value` (−log10 molar potency) - **Ranking trap:** `pchembl_value` is comparable only within one `standard_type` — set the filter, because mixing IC50 and Ki is a scientific error - **Coverage trap:** many measurements have no derivable `pchembl_value` (non-standard types, censored relations) and are absent from the ranked view — aspirin `CHEMBL25` has 4,087 measurements but only 158 with a `pchembl_value`. `potency_view` picks the side you get: `potency_ranked` (default) or `null_potency` for exactly the excluded rows. `totalCount` spans both either way. The two are separate calls, not one merged stream, because ChEMBL sorts null-potency rows *first* under a descending potency sort - Numerics are coerced from upstream JSON strings to `number | null` at the service boundary — a missing potency reads as `null`, never `0` - A popular target carries tens of thousands of measurements: when the set exceeds the inline preview it **spills** to a DataCanvas table — call `chembl_dataframe_describe` for its columns, then `chembl_dataframe_query` for honest aggregates across the staged set — while the inline preview answers the immediate question. Each view stages its own table (`bioactivities` / `bioactivities_null_potency`), so running both against one `canvas_id` lets a `UNION ALL` rebuild the full set - The staged table is capped at `CHEMBL_MAX_SPILL_ROWS` (default 50,000), which also bounds the upstream page walk behind it. When the cap is hit, `truncated: true` and `staged_row_count` say so on both response surfaces — the table is a bounded slice, not the complete view; narrow with `standard_type` / `pchembl_value_min` to fit - The inline rows are always capped at `limit` (default 25) — spilled, fit inline, or canvas off — so compare that count against `totalCount` before treating them as the whole answer. Spilling the rest requires `CANVAS_PROVIDER_TYPE=duckdb`; without it the inline preview is all there is - The optional `canvas_id` reuses an existing canvas, but a view's table is always re-registered — a second query of the same view **replaces** its prior rows rather than appending; omit `canvas_id` to mint a fresh one --- ### `chembl_search_targets` Resolve a protein into the ChEMBL target ID downstream tools need. - Supply at least one of `accession` (UniProt, e.g. `P00533`), `gene_symbol` (e.g. `EGFR`), or `query` (free-text name); narrow further with `organism` and `target_type` - A UniProt accession is the most precise input — chain it from a `uniprot` / `protein` server - Each row carries the target type, organism, and component UniProt accessions + gene symbols (flattened from ChEMBL's nested component synonyms) - Results past `limit` are reachable the same way `chembl_search_molecules` does it — a `nextCursor` when more remain, passed back as `cursor`, omitted on the last page - Chain `target_chembl_id` into `chembl_get_bioactivities` --- ### `chembl_get_drug_info` Drug pharmacology for a molecule — distinct from the `openfda` server's label / adverse-event view. - Supply `molecule_chembl_id` (from `chembl_search_molecules`) - Returns mechanism(s) of action, the molecular target(s), action type (inhibitor / agonist / …), first-approval year, and clinical indications with the max phase reached for each - Composed from molecule + mechanisms + indications with `Promise.allSettled`, so a rejected mechanism or indication list degrades to a disclosed partial result rather than failing the call - Each list carries its own retrieval state — `mechanisms_status` / `indications_status` (`complete` / `truncated` / `failed`) next to `mechanisms_total_count` / `indications_total_count`, so an empty array is authoritative only when the status is `complete` - A mechanism's `target_chembl_id` chains into `chembl_get_bioactivities` for compounds hitting the same target --- ### `chembl_get_assay` Assay provenance behind a bioactivity row — call it to
What people ask about chembl-mcp-server
What is cyanheads/chembl-mcp-server?
+
cyanheads/chembl-mcp-server is mcp servers for the Claude AI ecosystem. Link compounds to protein targets, rank bioactivity (IC50/Ki/EC50), and look up drug mechanisms and indications over ChEMBL via MCP. STDIO or Streamable HTTP. It has 1 GitHub stars and its last recorded update is dated 2026-08-25.
How do I install chembl-mcp-server?
+
You can install chembl-mcp-server by cloning the repository (https://github.com/cyanheads/chembl-mcp-server) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.
Is cyanheads/chembl-mcp-server safe to use?
+
Our security agent has analyzed cyanheads/chembl-mcp-server and assigned a Trust Score of 95/100 (tier: Verified). See the full breakdown of passed checks and flags on this page.
Who maintains cyanheads/chembl-mcp-server?
+
cyanheads/chembl-mcp-server is maintained by cyanheads. The last recorded GitHub activity is dated 2026-08-25, with 2 open issues.
Are there alternatives to chembl-mcp-server?
+
Yes. On ClaudeWave you can browse similar mcp servers at /categories/mcp, sorted by popularity or recent activity.
Deploy chembl-mcp-server to your cloud
Ship this repo to production in minutes. Each platform spins up its own environment with editable env vars.
Maintain this repo? Add a badge to your README
Drop the badge into your GitHub README to show it's tracked on ClaudeWave. Each badge links back to this page and reflects the live Trust Score.
[](https://claudewave.com/repo/cyanheads-chembl-mcp-server)<a href="https://claudewave.com/repo/cyanheads-chembl-mcp-server"><img src="https://claudewave.com/api/badge/cyanheads-chembl-mcp-server" alt="Featured on ClaudeWave: cyanheads/chembl-mcp-server" width="320" height="64" /></a>More MCP Servers
Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.
User-friendly AI Interface (Supports Ollama, OpenAI API, ...)
An open-source AI agent that brings the power of Gemini directly into your terminal.
Real-time global intelligence dashboard. AI-powered news aggregation, geopolitical monitoring, and infrastructure tracking in a unified situational awareness interface
The fastest path to AI-powered full stack observability, even for lean teams.
🕷️ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl!