target-prioritization — multi-source drug-target due-diligence for ranked gene lists 🎯
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
ThreadPoolExecutordispatches 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.yamland 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.pyandscripts/aggregate.py— setFOCUS_DISEASE_TERMSto the lowercased substrings that should tag a drug or associated-disease entry as "in-scope":Domain Example FOCUS_DISEASE_TERMSExample 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). Drivescell_context_score. -
scripts/fetch_pubmed.py::CONTEXTS— adjust thefocus_diseaseandcell_contextPubMed query templates. Thecell_contextslot 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-researchorliterature-reviewskill
🔗 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
- GitHub: https://github.com/Agents365-ai
- Bilibili: https://space.bilibili.com/441831884
📄 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.
No comments yet
Be the first to share your take.