sciagent-skill-creator
Scaffold a new SciAgent-Skills entry. Picks pipeline/toolkit/database/guide template, creates skills/{category}/{name}/SKILL.md with valid frontmatter, appends…
Query the ZINC22 virtual compound library (CartBlanche API, billions of make-on-demand + purchasable molecules). Look up substances by ZINC ID, resolve a SMILES to its ZINC ID (exact match), inspect purchasability/catalogs, and assemble compound sets for docking. Property
$ npx -y skills add jaechang-hits/SciAgent-Skills --skill zinc-database --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/zinc-databaseContext preview
The summary Claude sees to decide when to auto-load this skill.
Query the ZINC22 virtual compound library (CartBlanche API, billions of make-on-demand + purchasable molecules). Look up substances by ZINC ID, resolve a SMILES to its ZINC ID (exact match), inspect purchasability/catalogs, and assemble compound sets for docking. Property
name: "zinc-database" description: "Query the ZINC22 virtual compound library (CartBlanche API, billions of make-on-demand + purchasable molecules). Look up substances by ZINC ID, resolve a SMILES to its ZINC ID (exact match), inspect purchasability/catalogs, and assemble compound sets for docking. Property (MW/logP) filtering is done locally with RDKit. For bioactivity use chembl-database-bioactivity; for approved drugs use drugbank-database-access." license: "CC-BY-4.0"
ZINC (ZINC Is Not Commercial) is a free database of commercially available compounds curated for virtual screening. The current generation, **ZINC22**, holds billions of make-on-demand and in-stock molecules and is served through the **CartBlanche** web application at `cartblanche22.docking.org`. CartBlanche exposes a small JSON API to look up substances by ZINC ID, resolve a SMILES to its ZINC identifier, and inspect supplier/catalog purchasability.
> **Important — the old ZINC15 REST API no longer works for automated access.** > `zinc15.docking.org` (and `zinc.docking.org`) now sits behind a site-wide CAPTCHA: every request to `/substances.json`, `/tranches/...`, `/substances/{id}.json`, etc. is redirected to a `/captcha/` page or returns `403 Forbidden`. Any script using the `mwt__gte` / `availability` / `similarity` query parameters against `zinc15.docking.org` will fail. Use the ZINC22 CartBlanche endpoints documented below instead.
Three things about ZINC22/CartBlanche that change how you use this skill:
1. **There is no server-side property-range query.** ZINC22/CartBlanche has no `mwt__gte` / `logp__lte` / `hbd__lte` search. You filter by molecular property by either (a) selecting **tranches** (a 2D MW x logP grid) for bulk download, or (b) retrieving compounds and filtering locally with RDKit. This skill shows the local-RDKit approach. 2. **SMILES lookup is asynchronous.** You POST a SMILES, receive a `task` id, and poll for the result. Exact-match lookup completes in seconds. 3. **Reliable programmatic search = exact match.** The API's broader analog search (`dist` > 0) is slow and frequently times out on the public server, and the Smallworld similarity search is a website-only flow. Treat exact SMILES → ZINC ID lookup as the dependable primitive; see the "Analog / Similarity Search" note for the (limited) alternatives.
pip install requests pandas # optional, for local property filtering: pip install rdkit
import requests
BASE = "https://cartblanche22.docking.org"
HEADERS = {"User-Agent": "sciagent-zinc-skill/1.0"}
# Look up a substance by ZINC ID (synchronous, returns JSON immediately)
r = requests.get(f"{BASE}/substance/ZINC000000029632.json", headers=HEADERS, timeout=30)
r.raise_for_status()
c = r.json()
td = c["tranche_details"]
print(f"ZINC ID : {c['zinc_id']} (db: {c['db']})")
print(f"SMILES : {c['smiles']}")
print(f"MW : {td['mwt']:.2f} logP: {td['logp']:.2f} heavy atoms: {td['heavy_atoms']}")
print(f"InChIKey: {td['inchikey']}")
print(f"Catalogs: {len(c.get('catalogs', []))} supplier entries")Expected output (abridged):
ZINC ID : ZINC000000029632 (db: zinc20) SMILES : O=C([C@H]1CCCN1C(=O)Cc1c[nH]c2ccccc12)N1CCc2ccccc2C1 MW : 387.48 logP: 3.29 heavy atoms: 29 InChIKey: QCEMBLKSDIWPBK-JOCHJYFZSA-N Catalogs: 4 supplier entries
The CartBlanche base URL and two reusable helpers used throughout:
import requests, time
BASE = "https://cartblanche22.docking.org"
HEADERS = {"User-Agent": "sciagent-zinc-skill/1.0"}
def get_substance(zinc_id):
"""Fetch full record for one ZINC ID (synchronous)."""
r = requests.get(f"{BASE}/substance/{zinc_id}.json", headers=HEADERS, timeout=30)
r.raise_for_status()
return r.json()
def smiles_lookup(smiles, dist=0, adist=0, database="zinc22", timeout=120, poll=5):
"""Resolve a SMILES to ZINC22 substance dicts via the async task API.
dist=0, adist=0 -> exact match (fast, reliable; use this).
dist/adist > 0 -> near-neighbor analog search (slow; may time out — see note).
Returns a list of substance dicts (possibly empty).
"""
files = {"smiles": (None, smiles), "dist": (None, str(dist)),
"adist": (None, str(adist)), "database": (None, database)}
sub = requests.post(f"{BASE}/smiles.json", files=files, headers=HEADERS, timeout=60)
sub.raise_for_status()
task = sub.json()["task"] # async: returns {"task": "<uuid>"}
deadline = time.time() + timeout
while time.time() < deadline:
res = requests.get(f"{BASE}/search/result/{task}", headers=HEADERS, timeout=30).json()
if res.get("status") == "SUCCESS":
data = res.get("result")
# result is {"zinc22": [...], "zinc20": [...]} when hits exist,
# or an empty list when there are none.
if isinstTurn 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.
Scaffold a new SciAgent-Skills entry. Picks pipeline/toolkit/database/guide template, creates skills/{category}/{name}/SKILL.md with valid frontmatter, appends…
Bayesian modeling with PyMC 5: priors, likelihood, NUTS/ADVI sampling, diagnostics (R-hat, ESS), LOO/WAIC comparison, prediction. Hierarchical, logistic, GP…
Time-to-event modeling with scikit-survival: Cox PH (elastic net), Random Survival Forests, Boosting, SVMs for censored data. C-index, Brier, time-dependent…
Guided statistical analysis: test choice, assumption checks, effect sizes, power, APA reporting. Pick tests, verify assumptions, or format results for…
Python statistical modeling: regression (OLS, WLS, GLM), discrete (Logit, Poisson, NegBin), time series (ARIMA, SARIMAX, VAR), with rigorous inference,…
DL cell/nucleus segmentation for fluorescence and brightfield microscopy. Pre-trained models (cyto3, nuclei, tissuenet) and a generalist flow-based algorithm…