Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Query ChEMBL's bioactive molecules and drug discovery data. Search compounds by structure/properties, retrieve bioactivity data (IC50, Ki), find inhibitors, perform SAR studies, for medicinal chemistry.
.claude/skills/chembl-database/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-07 | ✗→✓ | ▲ Improved | — | — |
| case-06 | ✗→✓ | ▲ Improved | — | — |
| case-12 | ✗→✓ | ▲ Improved | — | — |
| case-05 | ✗→✗ | = Same ✗ | — | — |
| case-01 | ✗→✗ | = Same ✗ | — | — |
ChEMBL is a manually curated database of bioactive molecules maintained by the European Bioinformatics Institute (EBI), containing over 2 million compounds, 19 million bioactivity measurements, 13,000+ drug targets, and data on approved drugs and clinical candidates. Access and query this data programmatically using the ChEMBL Python client for drug discovery and medicinal chemistry research.
This skill should be used when:
The ChEMBL Python client is required for programmatic access:
bashuv pip install chembl_webresource_client
pythonfrom chembl_webresource_client.new_client import new_client # Access different endpoints molecule = new_client.molecule target = new_client.target activity = new_client.activity drug = new_client.drug
Retrieve by ChEMBL ID:
pythonmolecule = new_client.molecule aspirin = molecule.get('CHEMBL25')
Search by name:
pythonresults = molecule.filter(pref_name__icontains='aspirin')
Filter by properties:
python# Find small molecules (MW <= 500) with favorable LogP results = molecule.filter( molecule_properties__mw_freebase__lte=500, molecule_properties__alogp__lte=5 )
Retrieve target information:
pythontarget = new_client.target egfr = target.get('CHEMBL203')
Search for specific target types:
python# Find all kinase targets kinases = target.filter( target_type='SINGLE PROTEIN', pref_name__icontains='kinase' )
Query activities for a target:
pythonactivity = new_client.activity # Find potent EGFR inhibitors results = activity.filter( target_chembl_id='CHEMBL203', standard_type='IC50', standard_value__lte=100, standard_units='nM' )
Get all activities for a compound:
pythoncompound_activities = activity.filter( molecule_chembl_id='CHEMBL25', pchembl_value__isnull=False )
Similarity search:
pythonsimilarity = new_client.similarity # Find compounds similar to aspirin similar = similarity.filter( smiles='CC(=O)Oc1ccccc1C(=O)O', similarity=85 # 85% similarity threshold )
Substructure search:
pythonsubstructure = new_client.substructure # Find compounds containing benzene ring results = substructure.filter(smiles='c1ccccc1')
Retrieve drug data:
pythondrug = new_client.drug drug_info = drug.get('CHEMBL25')
Get mechanisms of action:
pythonmechanism = new_client.mechanism mechanisms = mechanism.filter(molecule_chembl_id='CHEMBL25')
Query drug indications:
pythondrug_indication = new_client.drug_indication indications = drug_indication.filter(molecule_chembl_id='CHEMBL25')
python targets = new_client.target.filter(pref_name__icontains='EGFR') target_id = targets[0]['target_chembl_id']
python activities = new_client.activity.filter( target_chembl_id=target_id, standard_type='IC50', standard_value__lte=100 )
python compound_ids = [act['molecule_chembl_id'] for act in activities] compounds = [new_client.molecule.get(cid) for cid in compound_ids]
python drug_info = new_client.drug.get('CHEMBL1234')
python mechanisms = new_client.mechanism.filter(molecule_chembl_id='CHEMBL1234')
python activities = new_client.activity.filter(molecule_chembl_id='CHEMBL1234')
python similar = new_client.similarity.filter(smiles='query_smiles', similarity=80)
python for compound in similar: activities = new_client.activity.filter( molecule_chembl_id=compound['molecule_chembl_id'] )
ChEMBL supports Django-style query filters:
__exact - Exact match__iexact - Case-insensitive exact match__contains / __icontains - Substring matching__startswith / __endswith - Prefix/suffix matching__gt, __gte, __lt, __lte - Numeric comparisons__range - Value in range__in - Value in list__isnull - Null/not null checkConvert results to pandas DataFrame for analysis:
pythonimport pandas as pd activities = new_client.activity.filter(target_chembl_id='CHEMBL203') df = pd.DataFrame(list(activities)) # Analyze results print(df['standard_value'].describe()) print(df.groupby('standard_type').size())
The client automatically caches results for 24 hours. Configure caching:
pythonfrom chembl_webresource_client.settings import Settings # Disable caching Settings.Instance().CACHING = False # Adjust cache expiration (seconds) Settings.Instance().CACHE_EXPIRE = 86400
Queries execute only when data is accessed. Convert to list to force execution:
python# Query is not executed yet results = molecule.filter(pref_name__icontains='aspirin') # Force execution results_list = list(results)
Results are paginated automatically. Iterate through all results:
pythonfor activity in new_client.activity.filter(target_chembl_id='CHEMBL203'): # Process each activity print(activity['molecule_chembl_id'])
python# Identify kinase targets kinases = new_client.target.filter( target_type='SINGLE PROTEIN', pref_name__icontains='kinase' ) # Get potent inhibitors for kinase in kinases[:5]: # First 5 kinases activities = new_client.activity.filter( target_chembl_id=kinase['target_chembl_id'], standard_type='IC50', standard_value__lte=50 )
python# Get approved drugs drugs = new_client.drug.filter() # For each drug, find all targets for drug in drugs[:10]: mechanisms = new_client.mechanism.filter( molecule_chembl_id=drug['molecule_chembl_id'] )
python# Find compounds with desired properties candidates = new_client.molecule.filter( molecule_properties__mw_freebase__range=[300, 500], molecule_properties__alogp__lte=5, molecule_properties__hba__lte=10, molecule_properties__hbd__lte=5 )
Ready-to-use Python functions demonstrating common ChEMBL query patterns:
get_molecule_info() - Retrieve molecule details by IDsearch_molecules_by_name() - Name-based molecule searchfind_molecules_by_properties() - Property-based filteringget_bioactivity_data() - Query bioactivities for targetsfind_similar_compounds() - Similarity searchingsubstructure_search() - Substructure matchingget_drug_info() - Retrieve drug informationfind_kinase_inhibitors() - Specialized kinase inhibitor searchexport_to_dataframe() - Convert results to pandas DataFrameConsult this script for implementation details and usage examples.
Comprehensive API documentation including:
Refer to this document when detailed API information is needed or when troubleshooting queries.
data_validity_comment field in activity recordspotential_duplicate flagspchembl_value provides normalized activity (-log scale)standard_type to understand measurement type (IC50, Ki, EC50, etc.)| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-05 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-01 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-07 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-08 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-13 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-19 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-21 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-22 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-10 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-04 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-09 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-15 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-03 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-06 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-18 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-14 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-02 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-16 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-11 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-20 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-17 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-12 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +14 percentage points is the difference between those two pass rates over the 22 comparable cases.
The per-case answers from this run were removed by the retention sweep, so the case table below shows the verdicts without the text either arm produced. The counts above were recorded at the time and are unaffected. Answers are now kept for 180 days.
Other measured skills in the registry, with their headline benchmark lift.