Skip to content
Development
Skill

/drugbank-database-access

Parse local DrugBank XML for drug info, interactions, targets, and properties. Search by ID/name/CAS, extract DDIs with severity, map targets/enzymes/transporters, compute SMILES similarity. Primary via local XML; REST API rate-limited (3k/month dev). For live bioactivity use

From plugin
sciagent-skills
364200 skills
Install
$ npx -y skills add jaechang-hits/SciAgent-Skills --skill drugbank-database-access --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/drugbank-database-access

Context preview

The summary Claude sees to decide when to auto-load this skill.

Parse local DrugBank XML for drug info, interactions, targets, and properties. Search by ID/name/CAS, extract DDIs with severity, map targets/enzymes/transporters, compute SMILES similarity. Primary via local XML; REST API rate-limited (3k/month dev). For live bioactivity use

SKILL.md

drugbank-database-access.SKILL.md
name: "drugbank-database-access"
description: "Parse local DrugBank XML for drug info, interactions, targets, and properties. Search by ID/name/CAS, extract DDIs with severity, map targets/enzymes/transporters, compute SMILES similarity. Primary via local XML; REST API rate-limited (3k/month dev). For live bioactivity use chembl-database-bioactivity; for compound properties use pubchem-compound-search."
license: "Unknown"

DrugBank Database — Local XML Access

Overview

Query the DrugBank comprehensive drug database (14,000+ drug entries, 5,000+ protein targets, 17,000+ drug interactions) by parsing the locally downloaded XML file with Python's ElementTree. Covers drug lookups, interaction checking, target/pathway extraction, chemical property analysis, and cross-database identifier mapping.

When to Use

  • Looking up drug information (description, indication, mechanism, pharmacology) by DrugBank ID, name, or CAS number
  • Checking drug-drug interactions and severity classifications for polypharmacy safety
  • Extracting drug targets, enzymes, transporters, and carriers with UniProt accessions
  • Retrieving chemical properties (SMILES, InChI, molecular weight) for cheminformatics analysis
  • Mapping DrugBank entries to external databases (PubChem, ChEMBL, UniProt, KEGG)
  • Building drug similarity matrices from molecular fingerprints
  • For live bioactivity data (IC50, Ki, EC50) use `chembl-database-bioactivity` instead
  • For compound property lookups without downloading a database use `pubchem-compound-search` instead

Prerequisites

  • **DrugBank account**: Register at https://go.drugbank.com/ (free academic license)
  • **XML download**: Download `drugbank_all_full_database.xml.zip` after registration (~1.5 GB uncompressed)
  • **Python packages**: `lxml`, `rdkit` (similarity), `pandas` (tabular analysis)
  • **REST API** (optional): 3,000 req/month dev tier; use local XML for batch work
pip install lxml pandas
pip install rdkit-pypi          # chemical similarity
pip install drugbank-downloader  # programmatic XML download

Quick Start

import xml.etree.ElementTree as ET

NS = {'db': 'http://www.drugbank.ca'}  # Required for ALL XPath queries

tree = ET.parse('drugbank_all_full_database.xml')  # 30-60s for full XML
root = tree.getroot()

# Build lookup index (DrugBank ID + lowercase name → element)
drug_index = {}
for drug in root.findall('db:drug', NS):
    db_id = drug.find('db:drugbank-id[@primary="true"]', NS)
    name = drug.find('db:name', NS)
    if db_id is not None and name is not None:
        drug_index[db_id.text] = drug
        drug_index[name.text.lower()] = drug

def find_drug(query):
    """Find drug by DrugBank ID, name (case-insensitive), or CAS number."""
    result = drug_index.get(query) or drug_index.get(query.lower())
    if result is not None:
        return result
    for drug in root.findall('db:drug', NS):  # CAS fallback
        cas = drug.find('db:cas-number', NS)
        if cas is not None and cas.text == query:
            return drug
    return None

drug = find_drug('DB00945')  # Aspirin
name = drug.find('db:name', NS).text
print(f"{name}: {drug.find('db:description', NS).text[:100]}...")

Core API

1. Data Access and Setup

import xml.etree.ElementTree as ET

NS = {'db': 'http://www.drugbank.ca'}
tree = ET.parse('drugbank_all_full_database.xml')
root = tree.getroot()
print(f"Total drug entries: {len(root.findall('db:drug', NS))}")

For memory-constrained environments, use iterparse:

drug_names = {}
for event, elem in ET.iterparse('drugbank_all_full_database.xml', events=('end',)):
    if elem.tag == '{http://www.drugbank.ca}drug':
        db_id = elem.find('{http://www.drugbank.ca}drugbank-id[@primary="true"]')
        name = elem.find('{http://www.drugbank.ca}name')
        if db_id is not None and name is not None:
            drug_names[db_id.text] = name.text
        elem.clear()  # Free memory
print(f"Parsed {len(drug_names)} drugs via iterparse")

2. Drug Information Queries

def get_drug_info(drug_element):
    """Extract comprehensive drug information."""
    def txt(path):
        el = drug_element.find(path, NS)
        return el.text if el is not None and el.text else None

    return {
        'drugbank_id': txt('db:drugbank-id[@primary="true"]'),
        'name': txt('db:name'),
        'type': drug_element.get('type'),
        'description': txt('db:description'),
        'indication': txt('db:indication'),
        'mechanism_of_action': txt('db:mechanism-of-action'),
        'cas_number': txt('db:cas-number'),
        'groups': [g.text for g in drug_element.findall('db:groups/db:group', NS)],
    }

info = get_drug_info(find_drug('Metformin'))
print(f"{info['name']} ({info['type']}): Groups={info['groups']}")
# Search by name pattern (partial match)
def search_by_name(pattern):
    pattern_lower = pattern.lower()
    return [d for d in root.findall('db:drug', NS)
            if d.find('db:name', NS) is not None
            and pattern_lower in d.find('db:name', NS).text.lower()]

statins = search_by_name('statin')
print(f"Found {len(statins)} drugs matching 'statin'")

3. Drug-Drug Interactions

def get_interactions(drug_element):
    """Extract all drug-drug interactions."""
    return [{
        'drugbank_id': i.find('db:drugbank-id', NS).text,
        'name': i.find('db:name', NS).text,
        'description': i.find('db:description', NS).text,
    } for i in drug_element.findall('db:drug-interactions/db:drug-interaction', NS)]

def classify_severity(description):
    """Classify severity from interaction description text."""
    if not description:
        return 'unknown'
    dl = description.lower()
    if any(w in dl for w in ['contraindicated', 'avoid', 'fatal', 'life-threatening']):
        return 'major'
    if any(w in dl for w in ['increase', 'decrease', 'enhance', 'reduce', 'alter']):
        return 'moderate
Read more
Ships withsciagent-skills

Turn your AI coding agent into a life sciences expert — 199 bioinformatics skills for Claude Code covering RNA-seq, single-cell analysis, genomics, proteomics, drug discovery, and more. Boosted BixBench from 65% to 92%. Open source.

Get the whole plugin

Other skills on sciagent-skills.