Bio Ensembl REST
GPTomics/bioSkills
Query the Ensembl REST API for gene/transcript/protein lookup, sequence retrieval, comparative genomics (Compara), variant effect prediction (VEP), regulatory features, and cross-species…
Query the ClinPGx (formerly PharmGKB) REST API plus the CPIC PostgREST companion API for pharmacogenomic clinical annotations, CPIC/DPWG dosing guidelines, gene-drug pairs, variant-drug…
$ npx skills add jaechang-hits/SciAgent-Skills --skill clinpgx-database -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install jaechang-hits/SciAgent-Skills clinpgx-database --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/jaechang-hits/SciAgent-Skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/genomics-bioinformatics/databases/clinpgx-database .claude/skills/clinpgx-database && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "clinpgx-database" agent skill from https://github.com/jaechang-hits/SciAgent-Skills/tree/main/skills/genomics-bioinformatics/databases/clinpgx-database into .claude/skills/clinpgx-database/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "clinpgx-database", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/jaechang-hits/SciAgent-Skills/tree/main/skills/genomics-bioinformatics/databases/clinpgx-databaseType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add jaechang-hits/SciAgent-Skills --skill clinpgx-database -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install jaechang-hits/SciAgent-Skills clinpgx-database --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/jaechang-hits/SciAgent-Skills.git skills-src && mkdir -p .agents/skills && cp -r skills-src/skills/genomics-bioinformatics/databases/clinpgx-database .agents/skills/clinpgx-database && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "clinpgx-database" agent skill from https://github.com/jaechang-hits/SciAgent-Skills/tree/main/skills/genomics-bioinformatics/databases/clinpgx-database into .agents/skills/clinpgx-database/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "clinpgx-database", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add jaechang-hits/SciAgent-Skills --skill clinpgx-database -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install jaechang-hits/SciAgent-Skills clinpgx-database --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/jaechang-hits/SciAgent-Skills.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/skills/genomics-bioinformatics/databases/clinpgx-database .cursor/skills/clinpgx-database && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "clinpgx-database" agent skill from https://github.com/jaechang-hits/SciAgent-Skills/tree/main/skills/genomics-bioinformatics/databases/clinpgx-database into .cursor/skills/clinpgx-database/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "clinpgx-database", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/jaechang-hits/SciAgent-Skills.git --path skills/genomics-bioinformatics/databases/clinpgx-database--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add jaechang-hits/SciAgent-Skills --skill clinpgx-database -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install jaechang-hits/SciAgent-Skills clinpgx-database --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/jaechang-hits/SciAgent-Skills.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/skills/genomics-bioinformatics/databases/clinpgx-database .gemini/skills/clinpgx-database && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "clinpgx-database" agent skill from https://github.com/jaechang-hits/SciAgent-Skills/tree/main/skills/genomics-bioinformatics/databases/clinpgx-database into .gemini/skills/clinpgx-database/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "clinpgx-database", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install jaechang-hits/SciAgent-Skills clinpgx-databaseInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add jaechang-hits/SciAgent-Skills --skill clinpgx-database -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/jaechang-hits/SciAgent-Skills.git skills-src && mkdir -p .github/skills && cp -r skills-src/skills/genomics-bioinformatics/databases/clinpgx-database .github/skills/clinpgx-database && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "clinpgx-database" agent skill from https://github.com/jaechang-hits/SciAgent-Skills/tree/main/skills/genomics-bioinformatics/databases/clinpgx-database into .github/skills/clinpgx-database/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "clinpgx-database", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add jaechang-hits/SciAgent-Skills --skill clinpgx-database -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install jaechang-hits/SciAgent-Skills clinpgx-database --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/jaechang-hits/SciAgent-Skills.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/skills/genomics-bioinformatics/databases/clinpgx-database .opencode/skills/clinpgx-database && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "clinpgx-database" agent skill from https://github.com/jaechang-hits/SciAgent-Skills/tree/main/skills/genomics-bioinformatics/databases/clinpgx-database into .opencode/skills/clinpgx-database/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "clinpgx-database", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
clinpgx-databaseQuery the ClinPGx (formerly PharmGKB) REST API plus the CPIC PostgREST companion API for pharmacogenomic clinical annotations, CPIC/DPWG dosing guidelines, gene-drug pairs, variant-drug…
Clinpgx Database is an agent skill from jaechang-hits/SciAgent-Skills. Query the ClinPGx (formerly PharmGKB) REST API plus the CPIC PostgREST companion API for pharmacogenomic clinical annotations, CPIC/DPWG dosing guidelines, gene-drug pairs, variant-drug associations, FDA/EMA drug labels, and PGx pathways. Two-host architecture: api.clinpgx.org for annotation records, api.cpicpgx.org for genotype→recommendation lookups. No auth. For germline pathogenicity use clinvar-database; for somatic cancer PGx use cosmic-database or opentargets-database; for drug bioactivity use…
Its SKILL.md is about 7.2k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Research & Science, covering Bioinformatics and REST APIs. The repository describes itself as: 197 bioinformatics & life science skills for Claude Code and AI agents — BixBench 92.0% accuracy. RNA-seq, single-cell, drug discovery, proteomics, and more. Powers OmicsHorizon. The licence is CC-BY-SA-4.0.
7 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit 82c862c. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
pipFrom the folder's file list and the shell code blocks in SKILL.md.
Hosts in commands or code, which the agent is likely to contact:
api.clinpgx.orgapi.cpicpgx.orgapi.pharmgkb.orgAlso links to:
clinpgx.orgdoi.orgcpicpgx.orgFrom URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Clinpgx Database loads about 7.2k tokens when it runs. Until then it costs about 138 tokens; SKILL.md has 1,541 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from jaechang-hits/SciAgent-Skills at commit 82c862c, republished under its CC-BY-SA-4.0 licence (© jaechang-hits). 1,541 words, ~7,225 tokens.
.claude/skills/clinpgx-database/SKILL.md (or your agent's skills folder).PharmGKB rebranded as ClinPGx in 2024 and the API moved from api.pharmgkb.org to api.clinpgx.org. The old host now returns 404/405; every example here uses the new endpoints. Two complementary APIs are used together:
api.clinpgx.org/v1) — record-style access to genes, drugs, variants, clinical annotations, guideline annotations, drug labels, and pathways. Responses wrap data as {"data": [...], "status": "success"}. Filters use dotted property paths (e.g. relatedChemicals.name=clopidogrel, levelOfEvidence.term=1A).api.cpicpgx.org/v1) — relational lookup of genotype → drug recommendation rows. PostgREST filter syntax (column=eq.value, JSON cs.{...} for jsonb containment). Returns flat JSON arrays.Use ClinPGx for what is known about a gene/drug/variant; use CPIC for how to prescribe given a phenotype. The pattern is ClinPGx for annotations, CPIC for recommendations.
data/clinicalAnnotationdata/guidelineAnnotationdata/{gene,drug,variant}POST /site/searchdata/labelclinvar-databasecosmic-database or opentargets-databaserequests, pandas — both already in standard environmentstime.sleep(0.3–0.5) between sequential calls. CPIC is more permissive.If you are inside a pixi/conda environment that already provides requests and pandas, skip the install — invoke scripts with pixi run python ....
pip install requests pandasimport requests
CLINPGX = "https://api.clinpgx.org/v1"
CPIC = "https://api.cpicpgx.org/v1"
# CPIC genotype → recommendation: clopidogrel + CYP2C19 Poor Metabolizer
drug = requests.get(f"{CPIC}/drug", params={"name": "eq.clopidogrel"}).json()[0]
recs = requests.get(f"{CPIC}/recommendation",
params={"drugid": f"eq.{drug['drugid']}",
"phenotypes": 'cs.{"CYP2C19":"Poor Metabolizer"}'}).json()
print(f"clopidogrel CYP2C19=PM: {len(recs)} recommendation(s)")
for rec in recs[:2]:
print(f" [{rec['classification']}] {rec['drugrecommendation'][:80]}…")
# ClinPGx side: how many CPIC guideline annotations cover CYP2C19?
glines = requests.get(f"{CLINPGX}/data/guidelineAnnotation",
params={"relatedGenes.symbol": "CYP2C19",
"source": "CPIC", "view": "base"}).json()["data"]
print(f"CYP2C19 CPIC guidelines: {len(glines)}")POST /site/search with a JSON body {"query": "<term>"} is the canonical entry point when you don't know the PA ID. It searches across drugs, genes, variants, clinical annotations, guideline annotations, and labels in one shot.
import requests
CLINPGX = "https://api.clinpgx.org/v1"
r = requests.post(f"{CLINPGX}/site/search",
json={"query": "rs4149056"}, timeout=15)
r.raise_for_status()
hits = r.json()["data"]["hits"]
print(f"Total hits: {r.json()['data']['total']}")
for h in hits[:5]:
print(f" id={h.get('id')} name={h.get('name')[:80]}")# Broader concept search
r = requests.post(f"{CLINPGX}/site/search",
json={"query": "TPMT azathioprine"}, timeout=15)
hits = r.json()["data"]["hits"]
print(f"TPMT+azathioprine hits: {len(hits)}")
for h in hits[:5]:
print(f" {h.get('id'):>15} {h.get('name','')[:80]}")The /data/{type} endpoints accept simple property filters. All return {"data": [...], "status": "success"} — use view=base for summary, view=max for full nested objects.
import requests
CLINPGX = "https://api.clinpgx.org/v1"
# Gene by HGNC symbol
gene = requests.get(f"{CLINPGX}/data/gene",
params={"symbol": "CYP2D6", "view": "base"}).json()["data"][0]
print(f"{gene['symbol']} id={gene['id']} {gene['name']}")
# Drug by name (lowercase generic preferred)
drug = requests.get(f"{CLINPGX}/data/drug",
params={"name": "warfarin", "view": "base"}).json()["data"][0]
print(f"{drug['name']} id={drug['id']}")
# Variant by rsID
var = requests.get(f"{CLINPGX}/data/variant",
params={"name": "rs4149056", "view": "base"}).json()["data"][0]
print(f"{var['name']} id={var['id']} significance={var.get('clinicalSignificance')}")# Direct record fetch when you already have a PA ID
r = requests.get(f"{CLINPGX}/data/drug/PA449088", params={"view": "max"}).json()
d = r["data"]
print(f"PA449088 → {d['name']} (objCls={d['objCls']})")data/clinicalAnnotation records associate a variant (location) with one or more drugs (relatedChemicals) and an evidence level (levelOfEvidence.term). The two supported filters are relatedChemicals.name= and levelOfEvidence.term=. There is no working gene= filter on this endpoint — see Module 4 for gene-driven access.
import requests, pandas as pd
CLINPGX = "https://api.clinpgx.org/v1"
# All clinical annotations for clopidogrel
data = requests.get(f"{CLINPGX}/data/clinicalAnnotation",
params={"relatedChemicals.name": "clopidogrel",
"view": "base"}).json()["data"]
print(f"clopidogrel annotations: {len(data)}")
rows = []
for ann in data[:10]:
loc = ann.get("location") or {}
drugs = ", ".join(c.get("name", "") for c in ann.get("relatedChemicals", []))
rows.append({
"id": ann["id"],
"variant": loc.get("displayName"),
"gene": (loc.get("genes") or [{}])[0].get("symbol"),
"drug": drugs,
"level": (ann.get("levelOfEvidence") or {}).get("term"),
"score": ann.get("score"),
})
print(pd.DataFrame(rows).to_string(index=False))# All Level 1A clinical annotations (highest evidence)
data = requests.get(f"{CLINPGX}/data/clinicalAnnotation",
params={"levelOfEvidence.term": "1A",
"view": "base"}).json()["data"]
print(f"Level 1A annotations: {len(data)}")
drug_to_count = {}
for ann in data:
for c in ann.get("relatedChemicals") or []:
drug_to_count[c["name"]] = drug_to_count.get(c["name"], 0) + 1
top = sorted(drug_to_count.items(), key=lambda x: -x[1])[:10]
for d, n in top:
print(f" {n:3} {d}")data/guidelineAnnotation supports both relatedGenes.symbol= and relatedChemicals.name=, plus source= (CPIC, DPWG, CPNDS, RNPGx). This is the canonical way to get gene→guideline coverage.
import requests
CLINPGX = "https://api.clinpgx.org/v1"
# All CPIC guidelines mentioning CYP2C19
data = requests.get(f"{CLINPGX}/data/guidelineAnnotation",
params={"relatedGenes.symbol": "CYP2C19",
"source": "CPIC",
"view": "base"}).json()["data"]
print(f"CYP2C19 CPIC guidelines: {len(data)}")
for g in data[:5]:
print(f" PA{g['id']}: {g['name'][:80]}")# Guidelines for a specific drug across all bodies (CPIC, DPWG, …)
data = requests.get(f"{CLINPGX}/data/guidelineAnnotation",
params={"relatedChemicals.name": "clopidogrel",
"view": "base"}).json()["data"]
by_source = {}
for g in data:
for s in (g.get("crossReferences") or []):
by_source.setdefault(s.get("resource", "?"), 0)
by_source[s["resource"]] = by_source.get(s["resource"], 0) + 1
print(f"clopidogrel guidelines: {len(data)} ({list({g.get('source') for g in data})})")data/label records are PharmGKB-curated annotations of FDA/EMA pharmacogenomic labeling. Filter by relatedChemicals.name= and source= (FDA, EMA, HCSC, PMDA, Swissmedic).
import requests, pandas as pd
CLINPGX = "https://api.clinpgx.org/v1"
data = requests.get(f"{CLINPGX}/data/label",
params={"relatedChemicals.name": "warfarin",
"source": "FDA",
"view": "base"}).json()["data"]
print(f"warfarin FDA labels: {len(data)}")
rows = [{
"name": d["name"][:60],
"biomarker_status": d.get("biomarkerStatus"),
"testing_required": d.get("testingRequired"),
"alternate_drug": d.get("alternateDrugAvailable"),
} for d in data]
print(pd.DataFrame(rows).to_string(index=False))CPIC's PostgREST API uses column=eq.value for equality and column=cs.{...} for JSONB containment. The standard lookup chain is drug → drugid → recommendation, optionally filtered by phenotype.
import requests
CPIC = "https://api.cpicpgx.org/v1"
# Resolve drug name to drugid (RxNorm-prefixed)
drug = requests.get(f"{CPIC}/drug",
params={"name": "eq.clopidogrel"}).json()[0]
print(f"clopidogrel drugid: {drug['drugid']}")
# All phenotype-specific recommendations for clopidogrel
recs = requests.get(f"{CPIC}/recommendation",
params={"drugid": f"eq.{drug['drugid']}"}).json()
print(f"Total recommendations: {len(recs)}")
for rec in recs[:3]:
print(f" {rec['phenotypes']} [{rec['classification']}]")
print(f" {rec['drugrecommendation'][:90]}…")# Phenotype filter via jsonb containment (cs.{...})
# The phenotypes column is a jsonb dict; cs. checks that the query is a subset.
recs = requests.get(f"{CPIC}/recommendation",
params={"drugid": f"eq.{drug['drugid']}",
"phenotypes": 'cs.{"CYP2C19":"Poor Metabolizer"}'}
).json()
for rec in recs:
print(f" [{rec['classification']}] {rec['drugrecommendation'][:90]}…")
# Gene-driven: list every drug with a CPIC pair for CYP2C19
pairs = requests.get(f"{CPIC}/pair",
params={"genesymbol": "eq.CYP2C19"}).json()
print(f"\nCYP2C19 CPIC pairs: {len(pairs)}")
drug_ids = sorted({p["drugid"] for p in pairs})
print(f"Sample drug IDs: {drug_ids[:5]}")| Question | Use | Why |
|---|---|---|
| What clinical annotations exist for this drug? | ClinPGx data/clinicalAnnotation | Annotation-level evidence with curated levelOfEvidence.term |
| What CPIC guidelines cover this gene? | ClinPGx data/guidelineAnnotation | Filter by relatedGenes.symbol; no working gene= filter on clinicalAnnotation |
| Given phenotype X, what should I prescribe? | CPIC recommendation + phenotypes | Structured genotype→action rows; CPIC is the prescribing-rule oracle |
| What FDA labels mention this drug + gene? | ClinPGx data/label?source=FDA | Curated regulatory PGx labeling |
| Free-text "anything about X" | ClinPGx POST /site/search | Cross-record-type fan-out |
Levels 1A → 4 in decreasing evidence quality:
Filter via levelOfEvidence.term on data/clinicalAnnotation. The term is a string, not an enum ("1A" not 1A).
Every ClinPGx /data/... response is {"data": [...] | {...}, "status": "success" | "fail"}. On failure the body is {"status": "fail", "data": {"errors": [{"message": "..."}]}} — always read both keys.
view=base (default) — flat summary record; recommended for bulk filtersview=max — full nested objects (relatedDiseases, allelePhenotypes, scoreDetails, …). Larger payload, slower; use only for single-record details.Goal: Given a patient's pharmacogene panel, count how many CPIC guideline annotations cover each gene.
import requests, pandas as pd, time
CLINPGX = "https://api.clinpgx.org/v1"
pharmacogenes = ["CYP2D6", "CYP2C19", "CYP2C9", "DPYD", "TPMT", "SLCO1B1"]
rows = []
for g in pharmacogenes:
data = requests.get(f"{CLINPGX}/data/guidelineAnnotation",
params={"relatedGenes.symbol": g,
"source": "CPIC", "view": "base"},
timeout=20).json()["data"]
drugs = sorted({c["name"] for guideline in data
for c in (guideline.get("relatedChemicals") or [])})
rows.append({"gene": g, "cpic_guidelines": len(data),
"n_drugs": len(drugs), "sample": ", ".join(drugs[:3])})
time.sleep(0.3)
df = pd.DataFrame(rows).sort_values("cpic_guidelines", ascending=False)
print(df.to_string(index=False))
df.to_csv("pharmacogene_cpic_coverage.csv", index=False)Goal: Given a prescribed drug list, identify which have CPIC genotype-specific recommendations and surface the rule rows.
import requests, pandas as pd, time
CPIC = "https://api.cpicpgx.org/v1"
drugs = ["warfarin", "clopidogrel", "codeine", "simvastatin",
"metoprolol", "omeprazole", "azathioprine", "tacrolimus"]
rows = []
for name in drugs:
drug = requests.get(f"{CPIC}/drug", params={"name": f"eq.{name}"}, timeout=15).json()
if not drug:
rows.append({"drug": name, "in_cpic": False, "n_recs": 0, "phenotypes": ""}); continue
did = drug[0]["drugid"]
recs = requests.get(f"{CPIC}/recommendation",
params={"drugid": f"eq.{did}"}, timeout=15).json()
phens = sorted({f"{k}={v}" for rec in recs
for k, v in (rec.get("phenotypes") or {}).items()})
rows.append({"drug": name, "in_cpic": True, "n_recs": len(recs),
"phenotypes": "; ".join(phens[:3])})
time.sleep(0.3)
df = pd.DataFrame(rows).sort_values(["in_cpic", "n_recs"], ascending=[False, False])
print(df.to_string(index=False))Goal: Starting from a single rsID (e.g., SLCO1B1 *5 = rs4149056), find every clinical annotation that involves it.
The Data API does not accept rsID as a filter property. Use POST /site/search to discover related annotation IDs, then fetch each by ID.
import requests
CLINPGX = "https://api.clinpgx.org/v1"
rsid = "rs4149056"
hits = requests.post(f"{CLINPGX}/site/search",
json={"query": rsid}, timeout=15).json()["data"]["hits"]
print(f"{rsid}: {len(hits)} hits")
# Filter hits that look like clinical annotations
ann_hits = [h for h in hits if h.get("name", "").lower().startswith("clinical annotation")]
print(f"Clinical-annotation hits: {len(ann_hits)}")
for h in ann_hits[:5]:
print(f" id={h['id']} {h['name'][:90]}")
# Dereference one annotation by ID for full detail
if ann_hits:
ann = requests.get(f"{CLINPGX}/data/clinicalAnnotation/{ann_hits[0]['id']}",
params={"view": "max"}, timeout=15).json()["data"]
drugs = ", ".join(c["name"] for c in (ann.get("relatedChemicals") or []))
print(f"\nFirst annotation:")
print(f" drugs: {drugs}")
print(f" level: {(ann.get('levelOfEvidence') or {}).get('term')}")| Parameter | Module / Endpoint | Default | Range / Options | Effect |
|---|---|---|---|---|
view | all /data/... | base | base, min, max | Field detail level; max includes all nested arrays (slow but complete) |
relatedChemicals.name | clinicalAnnotation, variantAnnotation, guidelineAnnotation, label, pathway | — | lowercase generic drug name | Filter records related to a drug |
relatedGenes.symbol | guidelineAnnotation, pathway | — | HGNC gene symbol | Filter records related to a gene (not available on clinicalAnnotation) |
levelOfEvidence.term | clinicalAnnotation | — | "1A", "1B", "2A", "2B", "3", "4" | Minimum evidence level |
source | guidelineAnnotation, label | — | CPIC, DPWG, FDA, EMA, HCSC, PMDA, Swissmedic | Issuing body |
symbol | data/gene | — | HGNC gene symbol | Gene record lookup |
name | data/drug, data/variant | — | drug name or rsID | Record lookup by canonical name |
CPIC column=eq.value | all api.cpicpgx.org/v1/... | — | PostgREST equality | Filter by exact match |
CPIC phenotypes=cs.{json} | recommendation | — | JSON-encoded jsonb subset | Filter by phenotype containment (must URL-encode if special chars) |
Resolve PA identifiers once. Never hand-construct ClinPGx PA IDs. Call data/{type}?{symbol|name}=... (or site/search) once and cache the returned id for reuse — gene/PA128 for CYP2D6, drug/PA449088 for clopidogrel, variant/PA166154579 for rs4149056.
Pick the right host for the question. Use ClinPGx for what is annotated and CPIC for what to prescribe. Trying to derive genotype-specific recommendations from ClinPGx alone misses the structured recommendation.phenotypes rows.
Filter by evidence level upfront when building clinical workflows. levelOfEvidence.term=1A returns 312 actionable annotations across all of ClinPGx; Level 3/4 records are exploratory and shouldn't drive prescribing.
Don't filter clinicalAnnotation by gene — filter by guidelineAnnotation with relatedGenes.symbol. The clinicalAnnotation endpoint has no working gene property and returns HTTP 400 for any attempt.
Use view=base for bulk filters, view=max for single-record drill-downs. A list query with view=max can time out or hit 429; the difference is roughly 5–10× payload size.
Throttle the ClinPGx host. Insert time.sleep(0.3) between sequential queries in loops; the API returns occasional HTTP 429s on tight loops. CPIC tolerates faster iteration.
URL-encode cs.{...} jsonb filters when phenotype values contain spaces or special characters. requests.get(..., params={"phenotypes": 'cs.{"CYP2C19":"Poor Metabolizer"}'}) works because requests does the encoding; a manual URL string needs urllib.parse.quote.
When to use: you have an arbitrary string (rsID, drug name, gene, allele) and want to find related ClinPGx records without knowing which endpoint to hit.
import requests
r = requests.post("https://api.clinpgx.org/v1/site/search",
json={"query": "VKORC1 warfarin"}, timeout=15)
hits = r.json()["data"]["hits"]
for h in hits[:10]:
print(f" {h.get('id'):>15} {h.get('name','')[:80]}")When to use: build a leaderboard of the most actionable PGx drugs.
import requests, pandas as pd
data = requests.get("https://api.clinpgx.org/v1/data/clinicalAnnotation",
params={"levelOfEvidence.term": "1A", "view": "base"},
timeout=30).json()["data"]
counts = {}
for ann in data:
for c in ann.get("relatedChemicals") or []:
counts[c["name"]] = counts.get(c["name"], 0) + 1
df = pd.DataFrame(sorted(counts.items(), key=lambda x: -x[1]),
columns=["drug", "n_1A_annotations"]).head(15)
print(df.to_string(index=False))When to use: given a phenotype call from a PGx test, surface every CPIC recommendation row.
import requests
CPIC = "https://api.cpicpgx.org/v1"
genotype = {"CYP2C19": "Poor Metabolizer"}
drug = "clopidogrel"
did = requests.get(f"{CPIC}/drug", params={"name": f"eq.{drug}"}).json()[0]["drugid"]
import json
recs = requests.get(f"{CPIC}/recommendation",
params={"drugid": f"eq.{did}",
"phenotypes": f"cs.{json.dumps(genotype)}"}).json()
for rec in recs:
print(f"[{rec['classification']}] {rec['drugrecommendation']}")
print(f" implications: {rec['implications']}")When to use: long-running loops over many genes / drugs / variants.
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
s = requests.Session()
s.headers.update({"Accept": "application/json"})
s.mount("https://", HTTPAdapter(max_retries=Retry(
total=4, backoff_factor=1.0,
status_forcelist=[429, 500, 502, 503, 504],
allowed_methods=["GET", "POST"])))
r = s.get("https://api.clinpgx.org/v1/data/gene",
params={"symbol": "CYP2D6", "view": "base"}, timeout=20)
r.raise_for_status()
print(r.json()["data"][0]["name"])| Problem | Cause | Solution |
|---|---|---|
HTTP 404/405 on https://api.pharmgkb.org/v1/... | Old PharmGKB host is dead; the service rebranded to ClinPGx in 2024 | Migrate to https://api.clinpgx.org/v1/.... Old /clinicalAnnotation?gene=X is now data/clinicalAnnotation with different filters. |
{"status":"fail","data":{"errors":[{"message":"No such property: 'gene'"}]}} | data/clinicalAnnotation does not accept gene= or relatedGenes.symbol= | Use data/guidelineAnnotation?relatedGenes.symbol=X for gene-driven access, or ?relatedChemicals.name=Y for drug-driven. |
{"status":"fail","data":{"errors":[{"message":"Missing criteria."}]}} | A data/{type} list query has no filter and no ID | Add at least one filter (name=, symbol=, relatedChemicals.name=, …) or fetch by ID via data/{type}/{paId}. |
HTTP 405 on GET /site/search?query=... | site/search only accepts POST with a JSON body | Use requests.post(url, json={"query": "..."}). |
| HTTP 429 mid-loop | Hit ClinPGx rate limit | Insert time.sleep(0.3–0.5) between calls; use the Retry session in Recipe 4. |
HTTP 400 on https://api.cpicpgx.org/v1/recommendation?phenotypes=cs.{...} | The cs. JSON wasn't URL-encoded | Pass via requests params={"phenotypes": 'cs.{"CYP2C19":"Poor Metabolizer"}'} (auto-encoded) or urllib.parse.quote manually. |
Empty data list for an obviously-real drug | Drug name mismatch (brand vs. generic; capitalization) | Try lowercase generic name; fall back to POST /site/search to fan out and find the canonical PA ID. |
data/variant?name=rs... returns 1 record but data/clinicalAnnotation?location.name=rs... returns 404 | rsID is stored under location.displayName/location.rsid, not exposed as a filterable property | Use site/search to discover annotation IDs by rsID, then dereference each with data/clinicalAnnotation/{id}. (Workflow 3.) |
clinvar-database — germline pathogenicity / clinical significance for variants found in PharmGKB (complementary; ClinVar is disease-focused, ClinPGx is drug-response-focused)opentargets-database — drug-target associations and safety signals overlapping ClinPGx pharmacogene targetschembl-database-bioactivity — bioactivity and binding data for the drugs annotated in ClinPGxcosmic-database — somatic cancer mutations and tumor-specific PGx (orthogonal to germline PGx covered here)data/{type}/{paId} URL shapedata/... and site/search schemasrecommendation rows; canonical genotype-prescribing oracle© jaechang-hits, CC-BY-SA-4.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in skills/genomics-bioinformatics/databases/clinpgx-database of jaechang-hits/SciAgent-Skills.
Open the folder on GitHubat commit 82c862c
We found 1 copy of this SKILL.md (exact, near-identical or edited) in other folders, from 1 other GitHub owner. This page covers the copy in jaechang-hits/SciAgent-Skills, which our catalogue first saw on October 7, 2026.
Clinpgx Database next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Clinpgx Database this skilljaechang-hits/SciAgent-Skills | 371 | 1 repos | ~7.2k | Automated safety check: Pass | CC-BY-SA-4.0 | |
| Bio Ensembl RESTGPTomics/bioSkills | 1.2k | 2 repos | ~3.6k | Automated safety check: Pass | MIT | |
| Pride FetchClawBio/ClawBio | 1.2k | — | ~4.2k | Automated safety check: Pass | MIT | |
| Ensembl Databaseaipoch/medical-research-skills | 2k | — | ~1.5k | Automated safety check: Pass | MIT | |
| UniProt Database Accessdavila7/claude-code-templates | 32k | 14 repos | ~1.7k | Automated safety check: Pass | MIT | |
| Singlecell Portalaipoch/medical-research-skills | 2k | — | ~1.2k | Automated safety check: Pass | MIT |
GPTomics/bioSkills
Query the Ensembl REST API for gene/transcript/protein lookup, sequence retrieval, comparative genomics (Compara), variant effect prediction (VEP), regulatory features, and cross-species…
ClawBio/ClawBio
Query metadata and download data from the PRIDE Archive, EMBL-EBI's proteomics identifications database, via the PRIDE Archive REST API v3.
aipoch/medical-research-skills
Access Ensembl REST API for vertebrate genomic data; use when you need gene/ID lookups, sequence retrieval, variant effect prediction (VEP), or homology/assembly coordinate mapping.
davila7/claude-code-templates
Queries the UniProt REST API directly to search proteins, fetch FASTA sequences, map IDs between databases and read Swiss-Prot and TrEMBL entries.
aipoch/medical-research-skills
Programmatically query public single-cell study metadata from the Broad Institute Single Cell Portal REST API when you need to search and filter datasets by organism, tissue, disease, or cell type…
aipoch/medical-research-skills
Access the European Nucleotide Archive (ENA) via REST APIs and FTP/Aspera to search and retrieve sequences, raw reads (FASTQ), assemblies, and metadata when you have accession IDs or need…
jaechang-hits/SciAgent-Skills
NEB-IRC activation energy pipeline for reaction barriers using GFN2-xTB and pysisyphus.
jaechang-hits/SciAgent-Skills
3Dmol.js WebGL molecular visualization emitted as self-contained HTML.
jaechang-hits/SciAgent-Skills
Constraint-based (COBRA) analysis of genome-scale metabolic models: FBA, FVA, knockouts, flux sampling, production envelopes, gapfilling, media optimization.
jaechang-hits/SciAgent-Skills
Read, write, and edit ChemDraw CDX/CDXML files with RDKit's rdkit.Chem.rdChemDraw plus direct XML editing, always paired with a rendered PNG.
jaechang-hits/SciAgent-Skills
Programmatic PubMed access via NCBI E-utilities REST API. An agent skill from jaechang-hits/SciAgent-Skills.
jaechang-hits/SciAgent-Skills
Scaffold a new SciAgent-Skills entry. An agent skill from jaechang-hits/SciAgent-Skills.
Categories
Query the ClinPGx (formerly PharmGKB) REST API plus the CPIC PostgREST companion API for pharmacogenomic clinical annotations, CPIC/DPWG dosing guidelines, gene-drug pairs, variant-drug…. Clinpgx Database is an agent skill from jaechang-hits/SciAgent-Skills. Query the ClinPGx (formerly PharmGKB) REST API plus the CPIC PostgREST companion API for pharmacogenomic clinical annotations, CPIC/DPWG dosing guidelines, gene-drug pairs, variant-drug associations, FDA/EMA drug labels, and PGx pathways.
Clinpgx Database fits situations like: tasks that involve Bioinformatics; tasks that involve REST APIs.
Run `npx skills add jaechang-hits/SciAgent-Skills --skill clinpgx-database -a claude-code`. Or copy the skill folder (skills/genomics-bioinformatics/databases/clinpgx-database in jaechang-hits/SciAgent-Skills) into .claude/skills/clinpgx-database in your project. Claude Code loads it when a task matches its description.
Run `npx skills add jaechang-hits/SciAgent-Skills --skill clinpgx-database -a codex`. Or copy the skill folder (skills/genomics-bioinformatics/databases/clinpgx-database in jaechang-hits/SciAgent-Skills) into .agents/skills/clinpgx-database in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add jaechang-hits/SciAgent-Skills --skill clinpgx-database -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/clinpgx-database, .gemini/skills/clinpgx-database, .github/skills/clinpgx-database and .opencode/skills/clinpgx-database in your project.
Going by SKILL.md and its folder, Clinpgx Database needs the command-line tools its instructions call (pip). Our summary lists: Python 3.
SKILL.md names 6 domains. In commands or code: api.clinpgx.org, api.cpicpgx.org and api.pharmgkb.org; the agent is likely to contact these when it follows the instructions. As links in the text: clinpgx.org, doi.org and cpicpgx.org. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Clinpgx Database is published under the CC-BY-SA-4.0 licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.
About 7.2k tokens (SKILL.md is roughly 29k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Clinpgx Database: Bio Ensembl REST (GPTomics/bioSkills, 1.2k stars), Pride Fetch (ClawBio/ClawBio, 1.2k stars), Ensembl Database (aipoch/medical-research-skills, 2k stars) and UniProt Database Access (davila7/claude-code-templates, 32k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
jaechang-hits (a GitHub user) maintains it in jaechang-hits/SciAgent-Skills, which has 371 GitHub stars. The repository holds 169 skills in this directory. The repository was last updated on September 29, 2026.
Source: jaechang-hits/SciAgent-Skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.