Agent skill

Ucsc Genome Browser

by jaechang-hits in jaechang-hits/SciAgent-Skills

Query UCSC Genome Browser REST API for DNA sequences, tracks, gene models, and conservation across 100+ assemblies.

Apache-2.0Auto-check passedResearch & Science

Install Ucsc Genome Browser

skills CLI
$ npx skills add jaechang-hits/SciAgent-Skills --skill ucsc-genome-browser -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install jaechang-hits/SciAgent-Skills ucsc-genome-browser --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ 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/ucsc-genome-browser .claude/skills/ucsc-genome-browser && rm -rf skills-src

Use ~/.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/

Facts

Skill name
ucsc-genome-browser
GitHub stars
374
Used in
1 other repo
Token cost
~6k tokens
SKILL.md length
1,088 words
Files
1
Skills in repo
169
Repo updated
First seen
Licence
Apache-2.0

At a glance

Query UCSC Genome Browser REST API for DNA sequences, tracks, gene models, and conservation across 100+ assemblies.

  • Works in 5 steps: Use 0-based coordinates throughout: The… → Add delays for batch queries: There is… → Discover track names before querying:… → …
  • UCSC annotations
  • SKILL.md covers Overview, When to Use, Prerequisites and Quick Start, plus 9 more sections
  • Calls pip; reaches api.genome.ucsc.edu

What it does

Ucsc Genome Browser is an agent skill from jaechang-hits/SciAgent-Skills. Query UCSC Genome Browser REST API for DNA sequences, tracks, gene models, and conservation across 100+ assemblies. Retrieve sequence by region, list/fetch BED/bigWig tracks, chromosome sizes, RefSeq/GENCODE gene structures, PhyloP/PhastCons scores. Use for UCSC annotations; Ensembl REST API for Ensembl gene IDs and VEP variant annotation.

Its SKILL.md is about 6k 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. It works with Ensembl. 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 Apache-2.0.

When your agent uses it

  • UCSC annotations
  • Ensembl REST API for Ensembl gene IDs and VEP variant annotation

Example prompts

  • “/ucsc-genome-browser”

Requirements

  • Python 3

Workflow steps

5 steps, taken from the first numbered list in SKILL.md.

  1. Use 0-based coordinates throughout: The API is BED-format; always subtract 1 from 1-based browser positions. Mixing conventions causes…
  2. Add delays for batch queries: There is no enforced rate limit, but UCSC's servers are shared resources. Insert time.sleep(0.5) between…
  3. Discover track names before querying: Track names (e.g., refGene, cpgIslandExt) are not always obvious. Call list/tracks first to find the…
  4. Handle missing track keys in response: The JSON key holding track records matches the track parameter name. Always use .get(track, []) to…
  5. Download chromosome sizes once and cache: For pipelines that need sizes across many regions, call list/chromosomes once and store the…

What it can do on your machine

Read from SKILL.md and the folder at commit 82c862c. It shows what the files ask for, not the result of running them.

  • Tool permissions

    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.

  • Runs code

    Shell commands in SKILL.md call:

    • pip

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Hosts in commands or code, which the agent is likely to contact:

    • api.genome.ucsc.edu

    Also links to:

    • genome.ucsc.edu
    • doi.org

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Ucsc Genome Browser loads about 6k tokens when it runs. Until then it costs about 90 tokens; SKILL.md has 1,088 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~90
When it runs · the whole SKILL.md, loaded when a task matches
~6k

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.

Safety

Auto-check passed

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.

SKILL.md

The full file from jaechang-hits/SciAgent-Skills at commit 82c862c, republished under its Apache-2.0 licence (© jaechang-hits). 1,088 words, ~5,989 tokens.

Download SKILL.mdSave it as .claude/skills/ucsc-genome-browser/SKILL.md (or your agent's skills folder).
name
ucsc-genome-browser
description
Query UCSC Genome Browser REST API for DNA sequences, tracks, gene models, and conservation across 100+ assemblies. Retrieve sequence by region, list/fetch BED/bigWig tracks, chromosome sizes, RefSeq/GENCODE gene structures, PhyloP/PhastCons scores. Use for UCSC annotations; Ensembl REST API for Ensembl gene IDs and VEP variant annotation.
license
Apache-2.0

UCSC Genome Browser

Overview

The UCSC Genome Browser REST API at https://api.genome.ucsc.edu/ provides programmatic access to genome sequences, annotation tracks, and hub data for 100+ assemblies including hg38, mm39, and dm6. The API is free, requires no authentication, and returns JSON. Use it with the requests library to fetch DNA sequences for genomic regions, retrieve track data (genes, repeats, conservation), list available tracks, and query chromosome sizes for genome-scale coordinate arithmetic.

When to Use

  • Fetching the reference DNA sequence for any genomic region (e.g., promoter, exon, CRISPR target) across human, mouse, or other assemblies
  • Retrieving RefSeq or GENCODE gene structure (exon coordinates, CDS boundaries, strand) for a locus of interest
  • Looking up PhyloP or PhastCons conservation scores to assess evolutionary constraint at a variant site
  • Listing and querying any of UCSC's 1000+ annotation tracks (repeats, regulatory elements, conservation) for a region
  • Getting chromosome sizes for a genome assembly to set up bedtools, pysam, or coverage pipelines
  • Accessing public UCSC track hubs (e.g., ENCODE, Roadmap Epigenomics) without downloading data locally
  • Use ensembl-database instead when you need Ensembl stable IDs, VEP variant annotation, or cross-species comparative genomics via the Ensembl REST API
  • For bulk local queries across millions of regions, use bedtools-genomic-intervals with pre-downloaded UCSC annotation files

Prerequisites

  • Python packages: requests, matplotlib (for visualization)
  • Data requirements: genomic coordinates (chrom, start, end in 0-based half-open BED format), genome assembly name (e.g., hg38, mm39)
  • Environment: internet connection; no authentication required
  • Rate limits: no official published limit; add 0.5s delays for batch requests (>100 queries)
bash
pip install requests matplotlib

Quick Start

python
import requests

BASE = "https://api.genome.ucsc.edu"

def get_sequence(genome, chrom, start, end):
    """Fetch DNA sequence for a genomic region (0-based, half-open)."""
    r = requests.get(f"{BASE}/getData/sequence",
                     params={"genome": genome, "chrom": chrom,
                             "start": start, "end": end})
    r.raise_for_status()
    return r.json()["dna"]

# Fetch 1 kb around the BRCA1 TSS on hg38
seq = get_sequence("hg38", "chr17", 43044294, 43045294)
print(f"Length: {len(seq)} bp")
print(f"Sequence: {seq[:60]}...")
# Length: 1000 bp
# Sequence: ATGATTGGTGGTTACATGCACAGTTGCTCTGGGAAGTTTCTTCTTCAGTTGAGAAAAGGT...

Core API

Query 1: Sequence Retrieval

Fetch the reference DNA sequence for any genomic region using the getData/sequence endpoint. Coordinates are 0-based, half-open (BED format).

python
import requests

BASE = "https://api.genome.ucsc.edu"

def get_sequence(genome, chrom, start, end):
    """Return DNA sequence string for the given region."""
    r = requests.get(f"{BASE}/getData/sequence",
                     params={"genome": genome, "chrom": chrom,
                             "start": start, "end": end})
    r.raise_for_status()
    data = r.json()
    return data["dna"]

# TP53 exon 4 region (hg38)
seq = get_sequence("hg38", "chr17", 7676520, 7676620)
print(f"Region: chr17:7,676,520-7,676,620 ({len(seq)} bp)")
print(f"Sequence: {seq}")
python
# Reverse-complement for minus-strand genes
def revcomp(seq):
    comp = str.maketrans("ACGTacgt", "TGCAtgca")
    return seq.translate(comp)[::-1]

# BRCA2 on minus strand (hg38)
seq_fwd = get_sequence("hg38", "chr13", 32315086, 32315186)
seq_rc  = revcomp(seq_fwd)
print(f"Forward: {seq_fwd[:30]}...")
print(f"RevComp: {seq_rc[:30]}...")
Query 2: Track Data Query

Retrieve annotation data (BED records) from any UCSC track for a genomic region.

python
import requests

BASE = "https://api.genome.ucsc.edu"

def get_track_data(genome, track, chrom, start, end):
    """Fetch annotation records from a UCSC track for a region."""
    r = requests.get(f"{BASE}/getData/track",
                     params={"genome": genome, "track": track,
                             "chrom": chrom, "start": start, "end": end})
    r.raise_for_status()
    data = r.json()
    # Track data is under the key matching the track name
    return data.get(track, data.get("data", []))

# Fetch RepeatMasker annotations in the MYC locus (hg38)
repeats = get_track_data("hg38", "rmsk", "chr8", 127_735_434, 127_742_951)
print(f"Repeat elements in MYC locus: {len(repeats)}")
for r in repeats[:3]:
    print(f"  {r.get('repName', r.get('name'))} | {r['chromStart']}-{r['chromEnd']}")
python
# Fetch CpG islands near a promoter
cpg_islands = get_track_data("hg38", "cpgIslandExt", "chr17", 43_044_000, 43_050_000)
print(f"CpG islands found: {len(cpg_islands)}")
for island in cpg_islands:
    print(f"  {island['name']}: {island['chromStart']}-{island['chromEnd']}, "
          f"obsExp={island.get('obsExp', 'n/a')}")
Query 3: Track List

List all available annotation tracks for a genome assembly to discover what data is available.

python
import requests

BASE = "https://api.genome.ucsc.edu"

def list_tracks(genome):
    """Return a dict of {track_name: track_metadata} for a genome assembly."""
    r = requests.get(f"{BASE}/list/tracks", params={"genome": genome})
    r.raise_for_status()
    return r.json().get("tracks", {})

tracks = list_tracks("hg38")
print(f"Total tracks in hg38: {len(tracks)}")

# Find conservation-related tracks
conserv = {k: v for k, v in tracks.items() if "conserv" in k.lower() or "phylop" in k.lower()}
for name, meta in list(conserv.items())[:5]:
    print(f"  {name}: {meta.get('shortLabel', '')}")
Query 4: Chromosome Sizes

Get the length of every chromosome (or scaffold) for a genome assembly.

python
import requests

BASE = "https://api.genome.ucsc.edu"

def get_chrom_sizes(genome):
    """Return {chrom: size_in_bp} for a genome assembly."""
    r = requests.get(f"{BASE}/list/chromosomes", params={"genome": genome})
    r.raise_for_status()
    return r.json().get("chromosomeSizes", {})

sizes = get_chrom_sizes("hg38")
print(f"hg38 chromosome count: {len(sizes)}")

# Show canonical autosomes + sex chromosomes
canonical = {c: sizes[c] for c in sorted(sizes) if c in
             [f"chr{i}" for i in range(1, 23)] + ["chrX", "chrY", "chrM"]}
for chrom, length in sorted(canonical.items(),
                             key=lambda x: int(x[0].replace("chr", "").replace("X", "23").replace("Y", "24").replace("M", "25"))):
    print(f"  {chrom}: {length:,} bp")
Query 5: Gene Annotation

Query RefSeq gene models (exon coordinates, CDS, strand) for a genomic region.

python
import requests

BASE = "https://api.genome.ucsc.edu"

def get_refgene(genome, chrom, start, end):
    """Retrieve RefSeq gene annotations for a region."""
    r = requests.get(f"{BASE}/getData/track",
                     params={"genome": genome, "track": "refGene",
                             "chrom": chrom, "start": start, "end": end})
    r.raise_for_status()
    return r.json().get("refGene", [])

# Query EGFR gene region (hg38)
genes = get_refgene("hg38", "chr7", 55_019_017, 55_211_628)
for g in genes:
    exon_count = g.get("exonCount", 0)
    print(f"  {g['name2']} ({g['name']}) | {g['strand']} | "
          f"tx: {g['txStart']}-{g['txEnd']} | exons: {exon_count}")
python
# Parse exon intervals from a refGene record
def parse_exons(gene_record):
    """Return list of (exon_start, exon_end) from a refGene record."""
    starts = [int(s) for s in gene_record["exonStarts"].strip(",").split(",") if s]
    ends   = [int(e) for e in gene_record["exonEnds"].strip(",").split(",") if e]
    return list(zip(starts, ends))

genes = get_refgene("hg38", "chr7", 55_019_017, 55_211_628)
if genes:
    g = genes[0]
    exons = parse_exons(g)
    print(f"{g['name2']}: {len(exons)} exons")
    for i, (s, e) in enumerate(exons[:4], 1):
        print(f"  Exon {i}: {s}-{e} ({e-s} bp)")
Query 6: Conservation Scores

Fetch per-base PhyloP or PhastCons conservation scores for a genomic region.

python
import requests

BASE = "https://api.genome.ucsc.edu"

def get_conservation(genome, track, chrom, start, end):
    """Retrieve per-base conservation scores from a bigWig track."""
    r = requests.get(f"{BASE}/getData/track",
                     params={"genome": genome, "track": track,
                             "chrom": chrom, "start": start, "end": end})
    r.raise_for_status()
    data = r.json()
    # bigWig tracks return a list of {start, end, value} intervals
    return data.get(track, [])

# PhyloP 100-way conservation at TP53 mutation hotspot (hg38)
# chr17:7,676,594 = codon 248 (R248W/Q common hotspot)
scores = get_conservation("hg38", "phyloP100way", "chr17", 7_676_580, 7_676_610)
print(f"PhyloP 100way scores ({len(scores)} intervals):")
for s in scores[:5]:
    print(f"  chr17:{s['start']}-{s['end']}: phyloP = {s['value']:.3f}")
# Positive scores = conserved; negative = fast-evolving
Query 7: Hub Access

Access public UCSC track hubs and list their available assemblies and tracks.

python
import requests

BASE = "https://api.genome.ucsc.edu"

def list_ucsc_genomes():
    """Return all UCSC-hosted genome assemblies."""
    r = requests.get(f"{BASE}/list/ucscGenomes")
    r.raise_for_status()
    return r.json().get("ucscGenomes", {})

genomes = list_ucsc_genomes()
print(f"Total UCSC genome assemblies: {len(genomes)}")

# Find all human assemblies
human = {k: v for k, v in genomes.items() if "Homo sapiens" in v.get("scientificName", "")}
for name, meta in sorted(human.items()):
    print(f"  {name}: {meta.get('description', '')}")

Key Concepts

0-Based vs. 1-Based Coordinates

The UCSC REST API uses 0-based, half-open intervals (BED format): start is inclusive, end is exclusive. This matches BED files and Python slicing. The UCSC Genome Browser web interface displays 1-based positions. To convert: API start = browser_start - 1, API end = browser_end.

python
# Browser position: chr17:7,676,521-7,676,620 (1-based, closed)
# API query (0-based, half-open):
start_api = 7_676_520   # browser_start - 1
end_api   = 7_676_620   # browser_end unchanged
seq = get_sequence("hg38", "chr17", start_api, end_api)
print(f"Fetched {len(seq)} bp (expected 100)")
Track Data Response Format

Track data returned from /getData/track is keyed by track name. BED-like tracks return a list of dicts with chrom, chromStart, chromEnd, name, score, strand. bigWig tracks (conservation, signal) return {start, end, value} intervals. Always check the actual key in the response JSON, which matches the track parameter name.

Common Workflows

Workflow 1: Extract Promoter Sequences for a Gene List

Goal: Retrieve 2 kb upstream of the TSS for each gene in a list, for motif analysis or primer design.

python
import requests
import time

BASE = "https://api.genome.ucsc.edu"
GENOME = "hg38"
PROMOTER_UP = 2000   # bp upstream of TSS

def get_refgene(genome, chrom, start, end):
    r = requests.get(f"{BASE}/getData/track",
                     params={"genome": genome, "track": "refGene",
                             "chrom": chrom, "start": start, "end": end})
    r.raise_for_status()
    return r.json().get("refGene", [])

def get_sequence(genome, chrom, start, end):
    r = requests.get(f"{BASE}/getData/sequence",
                     params={"genome": genome, "chrom": chrom,
                             "start": start, "end": end})
    r.raise_for_status()
    return r.json()["dna"]

def revcomp(seq):
    comp = str.maketrans("ACGTacgt", "TGCAtgca")
    return seq.translate(comp)[::-1]

# Genes of interest: query a known locus for each
gene_loci = {
    "BRCA1": ("chr17", 43_044_294, 43_125_482),
    "TP53":  ("chr17",  7_661_779,  7_687_538),
    "EGFR":  ("chr7",  55_019_017, 55_211_628),
}

results = {}
for gene, (chrom, locus_start, locus_end) in gene_loci.items():
    records = get_refgene(GENOME, chrom, locus_start, locus_end)
    # Pick the longest transcript
    records = [r for r in records if r.get("name2") == gene]
    if not records:
        print(f"  {gene}: not found")
        continue
    g = max(records, key=lambda x: x["txEnd"] - x["txStart"])
    if g["strand"] == "+":
        prom_start = max(0, g["txStart"] - PROMOTER_UP)
        prom_end   = g["txStart"]
    else:
        prom_start = g["txEnd"]
        prom_end   = g["txEnd"] + PROMOTER_UP
    seq = get_sequence(GENOME, chrom, prom_start, prom_end)
    if g["strand"] == "-":
        seq = revcomp(seq)
    results[gene] = {"chrom": chrom, "start": prom_start, "end": prom_end,
                     "strand": g["strand"], "seq": seq}
    print(f"  {gene}: {chrom}:{prom_start}-{prom_end} | strand={g['strand']} | {len(seq)} bp")
    time.sleep(0.5)

# Write FASTA
with open("promoters.fa", "w") as fh:
    for gene, d in results.items():
        fh.write(f">{gene} {d['chrom']}:{d['start']}-{d['end']}({d['strand']})\n")
        fh.write(d["seq"] + "\n")
print(f"\nSaved {len(results)} promoter sequences → promoters.fa")
Workflow 2: Visualize Gene Structure from refGene Track

Goal: Draw an exon-intron diagram for a gene using matplotlib from refGene track data.

python
import requests
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches

BASE = "https://api.genome.ucsc.edu"

def get_refgene(genome, chrom, start, end):
    r = requests.get(f"{BASE}/getData/track",
                     params={"genome": genome, "track": "refGene",
                             "chrom": chrom, "start": start, "end": end})
    r.raise_for_status()
    return r.json().get("refGene", [])

def parse_exons(rec):
    starts = [int(s) for s in rec["exonStarts"].strip(",").split(",") if s]
    ends   = [int(e) for e in rec["exonEnds"].strip(",").split(",") if e]
    return list(zip(starts, ends))

# Fetch BRCA1 transcripts (hg38)
genes = get_refgene("hg38", "chr17", 43_044_294, 43_125_482)
brca1 = [g for g in genes if g.get("name2") == "BRCA1"]
print(f"BRCA1 transcripts: {len(brca1)}")

# Plot the canonical transcript (longest)
g = max(brca1, key=lambda x: x["txEnd"] - x["txStart"])
exons = parse_exons(g)
tx_start, tx_end = g["txStart"], g["txEnd"]
cds_start, cds_end = g["cdsStart"], g["cdsEnd"]

fig, ax = plt.subplots(figsize=(12, 2.5))
ax.set_xlim(tx_start - 500, tx_end + 500)
ax.set_ylim(-0.5, 1.5)

# Intron line
ax.hlines(0.5, tx_start, tx_end, color="#555", lw=1.5, zorder=1)

# Exon boxes
for exon_s, exon_e in exons:
    # UTR portion (thin) vs CDS (thick)
    cds_s = max(exon_s, cds_start)
    cds_e = min(exon_e, cds_end)
    # Full exon box (UTR height)
    ax.add_patch(mpatches.FancyBboxPatch(
        (exon_s, 0.25), exon_e - exon_s, 0.5,
        boxstyle="square,pad=0", fc="#a8c4e0", ec="#2c6fad", lw=0.8, zorder=2))
    # CDS box (taller)
    if cds_s < cds_e:
        ax.add_patch(mpatches.FancyBboxPatch(
            (cds_s, 0.15), cds_e - cds_s, 0.7,
            boxstyle="square,pad=0", fc="#2c6fad", ec="#1a4a7a", lw=0.8, zorder=3))

strand_arrow = "→" if g["strand"] == "+" else "←"
ax.set_title(f"{g['name2']} ({g['name']}) {strand_arrow} — hg38 {g['chrom']}:"
             f"{tx_start:,}-{tx_end:,} | {g['exonCount']} exons", fontsize=11)
ax.set_xlabel("Genomic position (bp)")
ax.set_yticks([])
plt.tight_layout()
plt.savefig("brca1_gene_structure.png", dpi=150, bbox_inches="tight")
print("Saved: brca1_gene_structure.png")
plt.show()
Workflow 3: Batch Conservation Score Lookup

Goal: Retrieve mean PhyloP conservation for a list of variants or regions.

python
import requests
import time
import pandas as pd

BASE = "https://api.genome.ucsc.edu"

def get_conservation(genome, track, chrom, start, end):
    r = requests.get(f"{BASE}/getData/track",
                     params={"genome": genome, "track": track,
                             "chrom": chrom, "start": start, "end": end})
    r.raise_for_status()
    return r.json().get(track, [])

# Variants to score (1-based positions → convert to 0-based)
variants = [
    {"id": "rs28897672",  "chrom": "chr17", "pos": 7_676_594},  # TP53 R248
    {"id": "rs80357906",  "chrom": "chr17", "pos": 43_094_692}, # BRCA1
    {"id": "rs1042522",   "chrom": "chr17", "pos": 7_676_147},  # TP53 R72P (common)
]

results = []
for v in variants:
    # Query ±5 bp window around each variant
    scores = get_conservation("hg38", "phyloP100way",
                               v["chrom"], v["pos"] - 6, v["pos"] + 5)
    values = [s["value"] for s in scores]
    mean_score = sum(values) / len(values) if values else float("nan")
    results.append({**v, "phyloP100way_mean": round(mean_score, 3),
                    "n_intervals": len(scores)})
    print(f"  {v['id']}: mean phyloP = {mean_score:.3f}")
    time.sleep(0.5)

df = pd.DataFrame(results)
df.to_csv("variant_conservation.csv", index=False)
print(f"\nSaved → variant_conservation.csv\n{df.to_string(index=False)}")

Key Parameters

ParameterModuleDefaultRange / OptionsEffect
genomeAll endpoints—hg38, mm39, dm6, any UCSC assemblySelects the genome assembly
chromSequence, Track—chr1–chrY, chrMChromosome name (UCSC chr-prefix convention)
startSequence, Track—0–chrom_sizeRegion start (0-based, inclusive)
endSequence, Track—1–chrom_sizeRegion end (0-based, exclusive)
trackgetData/track—Any track name from list/tracksAnnotation track to retrieve
hubUrlHub endpoints—URL to hub.txtAccess a public or private track hub
Show full SKILL.md (483 more words)Show less

Best Practices

  1. Use 0-based coordinates throughout: The API is BED-format; always subtract 1 from 1-based browser positions. Mixing conventions causes silent off-by-one errors.

  2. Add delays for batch queries: There is no enforced rate limit, but UCSC's servers are shared resources. Insert time.sleep(0.5) between requests when processing >50 regions.

    python
    import time
    for region in regions:
        seq = get_sequence("hg38", region["chrom"], region["start"], region["end"])
        time.sleep(0.5)
  3. Discover track names before querying: Track names (e.g., refGene, cpgIslandExt) are not always obvious. Call list/tracks first to find the correct internal name, then query /getData/track.

  4. Handle missing track keys in response: The JSON key holding track records matches the track parameter name. Always use .get(track, []) to avoid KeyError when a track returns no data in a region.

  5. Download chromosome sizes once and cache: For pipelines that need sizes across many regions, call list/chromosomes once and store the result in a dict rather than re-requesting for each query.

Common Recipes

Recipe: Fetch Assembly List and Filter by Organism

When to use: Discover available genome assemblies for a specific species.

python
import requests

r = requests.get("https://api.genome.ucsc.edu/list/ucscGenomes")
r.raise_for_status()
genomes = r.json()["ucscGenomes"]

# All mouse assemblies
mouse = {k: v for k, v in genomes.items()
         if "Mus musculus" in v.get("scientificName", "")}
for name, meta in sorted(mouse.items()):
    print(f"  {name}: {meta.get('description', '')}")
Recipe: Write BED File from Track Query

When to use: Save UCSC track annotations as a BED file for downstream bedtools or IGV analysis.

python
import requests

BASE = "https://api.genome.ucsc.edu"

r = requests.get(f"{BASE}/getData/track",
                 params={"genome": "hg38", "track": "refGene",
                         "chrom": "chr7", "start": 55_019_017, "end": 55_211_628})
r.raise_for_status()
records = r.json().get("refGene", [])

with open("egfr_refgene.bed", "w") as fh:
    for rec in records:
        fh.write(f"{rec['chrom']}\t{rec['txStart']}\t{rec['txEnd']}\t"
                 f"{rec.get('name2', rec['name'])}\t0\t{rec['strand']}\n")
print(f"Wrote {len(records)} gene records → egfr_refgene.bed")
Recipe: GC Content for a Sequence

When to use: Compute GC content of a promoter or exon after fetching its sequence.

python
import requests

seq = requests.get(
    "https://api.genome.ucsc.edu/getData/sequence",
    params={"genome": "hg38", "chrom": "chr17",
            "start": 43_044_294, "end": 43_046_294}
).json()["dna"].upper()

gc = (seq.count("G") + seq.count("C")) / len(seq) * 100
print(f"Region length: {len(seq)} bp | GC content: {gc:.1f}%")
Recipe: Quick Coordinate Validation

When to use: Confirm coordinates are within chromosome bounds before submitting a batch.

python
import requests

sizes = requests.get("https://api.genome.ucsc.edu/list/chromosomes",
                     params={"genome": "hg38"}).json()["chromosomeSizes"]

def validate(chrom, start, end):
    if chrom not in sizes:
        return f"ERROR: {chrom} not in hg38"
    if start < 0 or end > sizes[chrom] or start >= end:
        return f"ERROR: {chrom}:{start}-{end} out of bounds (chrom size={sizes[chrom]})"
    return "OK"

print(validate("chr17", 43_044_294, 43_125_482))  # OK
print(validate("chr17", -1, 100))                  # ERROR

Troubleshooting

ProblemCauseSolution
HTTP 400 on sequence endpointCoordinates out of chromosome bounds or start >= endCheck chromosome size with list/chromosomes; swap start/end if reversed
Track query returns empty listNo features in the region for that trackConfirm track exists with list/tracks; widen the query window
KeyError on track responseResponse key differs from track parameterUse .get(track, data.get("data", [])) to handle variant key names
ConnectionError or timeoutNetwork issue or server loadRetry with requests.Session() and set timeout=30; add time.sleep(1)
Sequence is all lowercaseSoftmasked regions (RepeatMasker)Call .upper() on returned sequence if case is irrelevant to your use
Conservation track returns no dataTrack not available for that assemblyCheck list/tracks for the assembly; phyloP100way is hg38-only; use phyloP60way for mm10
Wrong gene retrievedMultiple transcripts at locusFilter by name2 (gene symbol) and select the longest transcript
  • ensembl-database — Ensembl REST API for gene/transcript annotations with stable Ensembl IDs, VEP variant effects, and cross-species homologs; preferred for Ensembl-centric workflows
  • encode-database — ENCODE portal for regulatory element datasets (ChIP-seq peaks, ATAC-seq) that feed into UCSC track hubs
  • bedtools-genomic-intervals — Perform intersection, coverage, and arithmetic on BED files downloaded from UCSC
  • regulomedb-database — RegulomeDB for regulatory variant scoring, which overlaps UCSC regulatory tracks

References

© jaechang-hits, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in skills/genomics-bioinformatics/databases/ucsc-genome-browser of jaechang-hits/SciAgent-Skills.

Open the folder on GitHubat commit 82c862c

Used in 1 other repository

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.

Compare with similar skills

Ucsc Genome Browser 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.

Ucsc Genome Browser compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Ucsc Genome Browser this skilljaechang-hits/SciAgent-Skills3741 repos~6kAutomated safety check: PassApache-2.0
External API ChangeGuyTeichman/RNAlysis139—~1.8kAutomated safety check: PassMIT
Ensembl Databasedavila7/claude-code-templates33k10 repos~2.1kAutomated safety check: PassMIT
Annotating Variantsmaziyarpanahi/openmed5.5k—~2.1kAutomated safety check: PassApache-2.0
Ggetdavila7/claude-code-templates33k10 repos~6.3kAutomated safety check: PassMIT
Ensembl Databasegoogle-deepmind/science-skills3.2k1 repos~2.2kAutomated safety check: PassApache-2.0

Similar skills

  • External API Change

    GuyTeichman/RNAlysis

    Workflow for fixing or changing RNAlysis code that talks to an EXTERNAL WEB SERVICE — UniProt, Ensembl, PANTHER, PhylomeDB, OrthoInspector, KEGG, or GO.

    139 GitHub stars~1.8k tokensUpdated 13 days ago
    Research & ScienceAuto-check passed
  • Ensembl Database

    davila7/claude-code-templates

    Query Ensembl genome database REST API for 250+ species. An agent skill from davila7/claude-code-templates.

    33k GitHub starsUsed in 10 repos~2.1k tokens
    Research & ScienceAuto-check passed
  • Annotating Variants

    maziyarpanahi/openmed

    Annotates VCF variants and normalizes HGVS nomenclature with public, license-free annotators (Ensembl VEP REST, VEP/SnpEff/ANNOVAR offline) and links variants to gnomAD population frequencies and…

    5.5k GitHub stars~2.1k tokensUpdated today
    Research & ScienceAuto-check passed
  • Gget

    davila7/claude-code-templates

    CLI/Python toolkit for rapid bioinformatics queries. An agent skill from davila7/claude-code-templates.

    33k GitHub starsUsed in 10 repos~6.3k tokens
    Research & ScienceAuto-check passed
  • Ensembl Database

    google-deepmind/science-skills

    Query the Ensembl database to resolve gene, transcript, and protein IDs, fetch genomic or protein sequences, retrieve gene structures (exons), and get variant consequence and effect predictions (VEP).

    3.2k GitHub starsUsed in 1 repo~2.2k tokens
    Research & ScienceAuto-check passed
  • gget CLI and Python workflow for quick genomic database queries, sequence lookup, BLAST-style searches, enrichment checks, and reproducible bioinformatics evidence logs.

    277k GitHub starsUsed in 1 repo~1.3k tokens
    Research & ScienceAuto-check passed

More from jaechang-hits/SciAgent-Skills

All 169 skills in this repo
  • Neb Irc Activation Energy

    jaechang-hits/SciAgent-Skills

    NEB-IRC activation energy pipeline for reaction barriers using GFN2-xTB and pysisyphus.

    374 GitHub stars~4k tokensUpdated 12 days ago
    Auto-check passed
  • Molecular Visualization 3dmol

    jaechang-hits/SciAgent-Skills

    3Dmol.js WebGL molecular visualization emitted as self-contained HTML.

    374 GitHub stars~3.2k tokensUpdated 12 days ago
    Auto-check passed
  • Cobrapy Metabolic Modeling

    jaechang-hits/SciAgent-Skills

    Constraint-based (COBRA) analysis of genome-scale metabolic models: FBA, FVA, knockouts, flux sampling, production envelopes, gapfilling, media optimization.

    374 GitHub starsUsed in 1 repo~4.9k tokens
    Auto-check passed
  • Rdkit Chemdraw Cdxml

    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.

    374 GitHub stars~6.9k tokensUpdated 12 days ago
    Auto-check passed
  • Pubmed Database

    jaechang-hits/SciAgent-Skills

    Programmatic PubMed access via NCBI E-utilities REST API. An agent skill from jaechang-hits/SciAgent-Skills.

    374 GitHub starsUsed in 1 repo~4.4k tokens
    Auto-check passed
  • Sciagent Skill Creator

    jaechang-hits/SciAgent-Skills

    Scaffold a new SciAgent-Skills entry. An agent skill from jaechang-hits/SciAgent-Skills.

    374 GitHub stars~2.3k tokensUpdated 12 days ago
    Auto-check passed

Works with

Questions about Ucsc Genome Browser

What does Ucsc Genome Browser do?

Query UCSC Genome Browser REST API for DNA sequences, tracks, gene models, and conservation across 100+ assemblies. Ucsc Genome Browser is an agent skill from jaechang-hits/SciAgent-Skills. Query UCSC Genome Browser REST API for DNA sequences, tracks, gene models, and conservation across 100+ assemblies.

When should I use Ucsc Genome Browser?

Ucsc Genome Browser fits situations like: UCSC annotations; ensembl REST API for Ensembl gene IDs and VEP variant annotation.

How do I install Ucsc Genome Browser in Claude Code?

Run `npx skills add jaechang-hits/SciAgent-Skills --skill ucsc-genome-browser -a claude-code`. Or copy the skill folder (skills/genomics-bioinformatics/databases/ucsc-genome-browser in jaechang-hits/SciAgent-Skills) into .claude/skills/ucsc-genome-browser in your project. Claude Code loads it when a task matches its description.

How do I install Ucsc Genome Browser in Codex?

Run `npx skills add jaechang-hits/SciAgent-Skills --skill ucsc-genome-browser -a codex`. Or copy the skill folder (skills/genomics-bioinformatics/databases/ucsc-genome-browser in jaechang-hits/SciAgent-Skills) into .agents/skills/ucsc-genome-browser in your project. Codex loads it when a task matches its description.

Can I use Ucsc Genome Browser in Cursor, Gemini CLI or GitHub Copilot?

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 ucsc-genome-browser -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/ucsc-genome-browser, .gemini/skills/ucsc-genome-browser, .github/skills/ucsc-genome-browser and .opencode/skills/ucsc-genome-browser in your project.

What does Ucsc Genome Browser need to run?

Going by SKILL.md and its folder, Ucsc Genome Browser needs the command-line tools its instructions call (pip). Our summary lists: Python 3.

Does Ucsc Genome Browser access the network?

SKILL.md names 3 domains. In commands or code: api.genome.ucsc.edu; the agent is likely to contact it when it follows the instructions. As links in the text: genome.ucsc.edu and doi.org. This is read from the text; nothing was executed.

Is Ucsc Genome Browser safe to install?

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.

What licence does Ucsc Genome Browser use?

Ucsc Genome Browser is published under the Apache-2.0 licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Ucsc Genome Browser use?

About 6k tokens (SKILL.md is roughly 24k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Ucsc Genome Browser?

Skills that share tags, products or a category with Ucsc Genome Browser: External API Change (GuyTeichman/RNAlysis, 139 stars), Ensembl Database (davila7/claude-code-templates, 33k stars), Annotating Variants (maziyarpanahi/openmed, 5.5k stars) and Gget (davila7/claude-code-templates, 33k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Ucsc Genome Browser?

jaechang-hits (a GitHub user) maintains it in jaechang-hits/SciAgent-Skills, which has 374 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.