target-prioritization — multi-source drug-target due-diligence for ranked gene lists 🎯

License: PolyForm-NC GitHub stars GitHub forks Latest Release Last Commit

SkillsMP Claude Code Plugin Agent Skills English · 中文

External references: UniProt REST · OpenTargets GraphQL · PubMed E-utilities · Human Protein Atlas · DepMap · gnomAD · ChEMBL

A skill that turns a ranked gene list (typically a scRNA-seq DE output) into a per-gene drug-target dossier — fanning out parallel queries to UniProt, OpenTargets (which carries DepMap CRISPR essentiality and gnomAD LoF constraint), PubMed, the Human Protein Atlas, and ChEMBL — then re-ranking everything by a composite score combining protein biology, druggability, disease genetics, tissue / cell-type specificity, dependency essentiality, LoF safety constraint, and research maturity.

  • Multi-source evidence — UniProt (localization, surface / secreted / MHC), OpenTargets (tractability, approved drugs, disease associations including GWAS-derived signal, DepMap CRISPR essentiality, gnomAD LOEUF / pLI constraint), PubMed (total + configurable disease-focus + cell-context paper counts), Human Protein Atlas (tissue + single-cell specificity and nCPM, expression cluster, cancer prognostics), ChEMBL (top-potency tool compounds — IC50, mechanism — dossier-only)
  • Parallel fetchers — Python ThreadPoolExecutor dispatches all sources concurrently
  • Composite re-ranking — per-component scores (druggability, disease genetics, tractability, tissue specificity, cell context, essentiality, safety constraint, expression, novelty) combined via fully configurable weights.yaml
  • No API keys, no external Python deps — stdlib + curl-compatible network only
  • Re-scorable — raw JSON cache lets you tweak weights.yaml and rerun aggregate in seconds without re-fetching

Works with Claude Code, OpenClaw, and SkillsMP — any agent that supports the Agent Skills format.

🔄 How it works

input gene list (CSV / TXT)
        │
        ▼
scripts/orchestrate.py
        │
        ├─► fetch_uniprot.py        → protein localization, surface, MHC, signal peptide
        ├─► fetch_opentargets.py    → tractability, approved drugs, focus-disease
        │                              trial tags, associated diseases (integrates
        │                              GWAS evidence), DepMap CRISPR essentiality,
        │                              gnomAD LOEUF / constraint
        ├─► fetch_pubmed.py         → total + focus-disease + cell-context paper
        │                              counts, maturity tag
        ├─► fetch_hpa.py            → HPA tissue / single-cell specificity tag,
        │                              top tissue/cell-type nTPM/nCPM, expression
        │                              cluster, cancer prognostics summary
        └─► fetch_chembl.py         → top-potency tool compounds (pIC50, IC50 nM,
                                       mechanism) — dossier-only, no score impact
        │
        ▼
scripts/aggregate.py — composite score + tier assignment
        │
        ▼
output/
  ├─ raw_data/*.json          (audit trail; reusable for re-scoring)
  ├─ targets_summary.csv      (composite-ranked flat table)
  ├─ targets_report.md        (per-gene markdown dossier; rationale slots
  │                            left for Claude to fill from the JSON cache)
  └─ targets_report.html      (self-contained interactive report;
                               built by scripts/build_html_report.py as
                               the final step, after rationales are filled)

Install

# Claude Code — plugin marketplace
> /plugin marketplace add Agents365-ai/365-skills
> /plugin install target-prioritization

# Or any agent (Cursor, Copilot, etc.) via the SkillsMP CLI
npx skills add Agents365-ai/365-skills -g

# Manual install — clone and symlink into ~/.claude/skills/
git clone https://github.com/Agents365-ai/target-prioritization.git
ln -s "$PWD/target-prioritization/skills/target-prioritization" \
      ~/.claude/skills/target-prioritization

No dependencies beyond Python 3.9+ and a curl-capable network.

Usage

Just describe what you want — the skill triggers on any DE-list triage request:

> Filter these candidate genes for druggable targets — TP53, EGFR, MYC, KRAS, BRCA1

> Make a target dossier for the top 50 genes in /path/to/de_output.csv

> Re-rank these with the druggability weight dialed up to 0.4

The skill is domain-agnostic and works equally well for oncology (TP53 / EGFR / MYC), neurodegeneration (APP / TREM2 / SNCA), metabolic disease (PCSK9 / GCK / PNPLA3), autoimmunity, and any other human-gene context. The focus-disease and cell-context PubMed queries plus the OpenTargets focus-disease tag are user-editable — see Retargeting below.

Or call the orchestrator directly:

python3 ~/.claude/skills/target-prioritization/scripts/orchestrate.py \
    --input  /path/to/de_output.csv \
    --output /tmp/targets_run1 \
    --top 50

After the run, ask Claude to fill in the rationale slots of targets_report.md using prompts/rationale_template.md. Then build the interactive HTML report:

python3 ~/.claude/skills/target-prioritization/scripts/build_html_report.py \
    --report-dir /tmp/targets_run1 \
    --subtitle "<cohort / contrast description>"

This writes targets_report.html — a single self-contained file with a sortable summary table, live search, tier-filter buttons, and one card per gene (evidence chips, full dossier grid, score-component bars). Share or open directly in a browser.

Output format

targets_summary.csv — one row per gene, sortable in Excel/pandas. Columns include:

Field group Example columns
Score composite_score, tier, plus per-component (druggability, disease_genetics, tractability, tissue_specificity, cell_context_score, essentiality_score, safety_constraint_score, expression, novelty, over_studied_penalty)
UniProt uniprot_id, protein_name, subcellular_location, is_surface, is_secreted, is_mhc, has_transmembrane
OpenTargets approved_drug_count, highest_clinical_phase, any_focus_disease_drug, focus_disease_drugs, tractability_small_molecule, tractability_antibody
Disease genetics any_disease_assoc, is_focus_disease_associated, focus_disease_traits, max_focus_disease_assoc_score, max_disease_assoc_score
PubMed pubmed_total, pubmed_focus_disease, pubmed_cell_context, maturity_tag
HPA hpa_tissue_specificity_tag, hpa_tissue_top_types, hpa_cell_specificity_tag, hpa_cell_top_types, hpa_focus_cell_hits, hpa_expression_cluster, hpa_n_prognostic_cancers, hpa_cancer_specificity
DepMap depmap_n_screens, depmap_mean_gene_effect, depmap_pct_essential
gnomAD constraint loeuf, constraint_oe_lof, constraint_top_decile
ChEMBL chembl_target_id, chembl_best_pchembl, chembl_best_ic50_nm, chembl_top_compounds

Tiers (after min-max rescaling): Tier-1-priority (≥0.75), Tier-2-candidate (≥0.50), Tier-3-watchlist (≥0.30), Tier-4-deprioritized (<0.30).

targets_report.md — markdown dossier with one section per gene, sorted by composite score. Each section has a metadata table plus blank rationale + next-step slots for Claude to fill from the JSON cache.

targets_report.html — self-contained interactive report built from the .md + .csv by scripts/build_html_report.py. No external dependencies; opens in any browser. Includes an executive summary, a sortable / searchable summary table with tier-filter buttons, and one card per gene with evidence chips (surface / secreted / MHC / focus-disease / approved-drug), full dossier grid, and a horizontal-bar score-component breakdown.

Retargeting for a different disease / cell context

The skill ships with an autoimmunity + T-cell default but is intentionally disease-agnostic. Three edits switch the focus:

  • skills/target-prioritization/scripts/fetch_opentargets.py and scripts/aggregate.py — set FOCUS_DISEASE_TERMS to the lowercased substrings that should tag a drug or associated-disease entry as "in-scope":

    Domain Example FOCUS_DISEASE_TERMS Example FOCUS_CELL_TYPES (HPA single-cell names)
    Oncology ("cancer", "carcinoma", "lymphoma", "leukemia", "tumor") ("Macrophages", "Fibroblasts", "T-cells")
    Neurodegeneration ("alzheimer", "parkinson", "huntington", "als") ("Excitatory neurons", "Microglial cells", "Astrocytes")
    Metabolic / liver ("diabetes", "obesity", "fatty liver", "nash") ("Hepatocytes", "Kupffer cells")
    Cardiovascular ("heart failure", "atherosclerosis", "myocardial", "hypertension") ("Cardiomyocytes", "Endothelial cells")
  • scripts/aggregate.py::FOCUS_CELL_TYPES — must match HPA's exact cell-type strings (case-sensitive). Drives cell_context_score.

  • scripts/fetch_pubmed.py::CONTEXTS — adjust the focus_disease and cell_context PubMed query templates. The cell_context slot accepts any cell-type / lineage string and is used only for the dossier counts.

CSV columns are already neutrally named (focus_disease_*, cell_context, hpa_focus_cell_hits); no downstream code changes are needed after retargeting.

Composite score

composite = 0.20 · druggability          + 0.15 · disease_genetics + 0.15 · tractability
          + 0.10 · tissue_specificity    + 0.10 · cell_context_score
          + 0.10 · essentiality_score    + 0.05 · safety_constraint_score
          + 0.10 · expression            + 0.05 · novelty
          - 0.10 · over_studied_penalty

Each component is clipped to [0, 1] before weighting. After summing the composite is min-max rescaled to [0, 1] across the run and bucketed into four tiers (Tier-1-priority ≥ 0.75, Tier-2-candidate ≥ 0.50, Tier-3-watchlist ≥ 0.30, Tier-4-deprioritized < 0.30).

What each component measures

Component What "high" means Source
druggability Approved drug exists OR Phase III candidate in adjacent indication OpenTargets drugAndClinicalCandidates
disease_genetics Strong OT disease association (+ bonus if focus-disease) OpenTargets associatedDiseases
tractability Surface or secreted vs intracellular UniProt + TM / signal peptide features
tissue_specificity HPA Tissue enriched / Group enriched — narrow tissue expression HPA RNA tissue specificity
cell_context_score A FOCUS_CELL_TYPES member ranks in the top of this gene's per-cell nCPM HPA RNA single cell type specific nCPM
essentiality_score 20–80% of DepMap cell lines depend on it (selective, not pan-essential) OpenTargets depMapEssentiality
safety_constraint_score gnomAD LOEUF ≥ 1.0 — natural LoF tolerated in humans OpenTargets geneticConstraint
expression High mean expression in the input DE contrast input CSV
novelty Moderately studied (≥ 5 and ≤ 100 PubMed papers) PubMed
over_studied_penalty Subtracted when PubMed total > 100 (diminishing returns) PubMed

Example: 4-gene smoke test

Running on EGFR, TP53, TNFRSF4, KRAS with the default FOCUS_CELL_TYPES = ("T-cells",):

Gene Tier composite essentiality safety cell_context best pIC50 (ChEMBL)
TNFRSF4 Tier-1-priority 1.000 0.001 1.000 0.400
EGFR Tier-2-candidate 0.669 0.224 0.596 0.000 11.0 (MOBOCERTINIB)
KRAS Tier-2-candidate 0.533 0.429 0.300 0.000 10.0
TP53 Tier-4-deprioritized 0.000 0.003 0.576 0.000

The ranking reflects biology: TNFRSF4 wins for the T-cell focus (default), KRAS shows the strongest cancer-cell-line dependency (34% essential), TP53 sinks because its KO helps tumor cells (mean geneEffect +0.38) and no potent IC50 tool compound exists in ChEMBL.

All weights live in weights.yaml and can be overridden per run with --weights. Re-scoring with new weights costs ~1s (no API re-fetch):

python3 ~/.claude/skills/target-prioritization/scripts/aggregate.py \
    --raw-dir /tmp/targets_run1/raw_data \
    --output-dir /tmp/targets_run1 \
    --weights ~/.claude/skills/target-prioritization/weights.yaml \
    --input-csv /path/to/expression_table_pass_either_1s.csv

Data sources

Source What it gives Rate-limit handling
UniProt REST Protein name, function summary, subcellular location, surface / secreted / MHC flags, transmembrane, signal peptide 100 req/sec, batched via accession queries
OpenTargets GraphQL Ensembl ID, tractability (SM + Ab + Pr + OC), approved drugs, max clinical phase, focus-disease-tagged drugs, associated diseases (integrates GWAS Catalog + other genetics sources) Generous, single endpoint
PubMed E-utilities Total paper count + two user-configurable context counts (focus_disease, cell_context) + maturity tag 3 req/sec without API key
Human Protein Atlas Tissue / single-cell specificity tag, top tissue nTPM, top single-cell nCPM, expression cluster, prognostic cancer count + cancer specificity None documented; fetcher sleeps 0.15s/gene
DepMap CRISPR essentiality Per-tissue + per-cell-line geneEffect, summarized as pct_essential and mean_gene_effect Piggybacks on OpenTargets — no extra HTTP
gnomAD constraint LOEUF (oeUpper of LoF row), oe_lof, top-decile flag Piggybacks on OpenTargets — bypasses gnomAD's WAF on direct API access
ChEMBL REST Top-5 most-potent IC50 tool compounds per gene + pIC50 / mechanism ~5 req/sec; fetcher sleeps 0.2s/gene

Compared to native Claude Code

Capability Native Claude Code target-prioritization
Look up UniProt for one gene ✅ via web ✅ batched + structured
Look up OpenTargets drugs / disease assoc ✅ via web ✅ schema-mapped, focus-disease-tagged
Count PubMed papers (+ disease context) ⚠ slow, manual queries ✅ parallel, deduped
HPA tissue / single-cell expression + cancer prognostics ✅ via web ✅ tagged, ranked, scored against FOCUS_CELL_TYPES
DepMap CRISPR essentiality summary ✅ per-gene pct_essential, pan-essentials capped
gnomAD LoF constraint (LOEUF / pLI) ✅ surfaced + folded into safety score
ChEMBL top tool compounds (IC50, mechanism) ✅ surfaced for "next experiment" rationale
Composite re-ranking + tiering ✅ configurable weights
Reproducible audit trail ✅ raw JSON cache
Re-score without re-fetching ✅ ~1s rerun

When NOT to use this skill

  • Single-gene lookups — overkill; ask Claude to web-search instead
  • Non-human genes — the APIs are human-centric; fetchers silently return empty
  • Cancer driver analysis — use CGC / OncoKB
  • Pure literature review without target ambition — use scholar-deep-research or literature-review skill

🔗 Related skills

Skill When to use
scholar-deep-research If the rationale step needs deeper literature evidence per gene
paper-fetch Pulling the full text of the focus-disease PMIDs surfaced by this skill

👤 Author

Agents365-ai

📄 License

PolyForm Noncommercial 1.0.0 — free for personal, academic, public-research, and other noncommercial use. Commercial use requires a separate license from the author.