Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Browse and search Gene Ontology annotations via the QuickGO API
.claude/skills/brycewang-stanford-quickgo-api/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-12 | ✗→✓ | ▲ Improved | -40% | 0% |
| case-15 | ✗→✓ | ▲ Improved | 99% | 0% |
| case-06 | ✓→✗ | ▼ Worse | 114% | 0% |
| case-01 | ✓→✓ | = Same ✓ | 142% | 0% |
| case-02 | ✓→✓ | = Same ✓ | 115% | 0% |
QuickGO is the EBI's fast browser and API for Gene Ontology (GO) annotations — the standard framework for describing gene/protein functions across all organisms. It provides access to 800M+ GO annotations covering biological processes, molecular functions, and cellular components. Essential for functional genomics, pathway analysis, and gene set enrichment. Free, no authentication.
https://www.ebi.ac.uk/QuickGO/servicesbash# Search terms by keyword curl "https://www.ebi.ac.uk/QuickGO/services/ontology/go/search?query=apoptosis&limit=20" # Get term details curl "https://www.ebi.ac.uk/QuickGO/services/ontology/go/terms/GO:0006915" # Get term ancestors/descendants curl "https://www.ebi.ac.uk/QuickGO/services/ontology/go/terms/GO:0006915/ancestors" curl "https://www.ebi.ac.uk/QuickGO/services/ontology/go/terms/GO:0006915/descendants"
bash# Get annotations for a protein (UniProt ID) curl "https://www.ebi.ac.uk/QuickGO/services/annotation/search?geneProductId=P04637&limit=50" # Annotations for a GO term curl "https://www.ebi.ac.uk/QuickGO/services/annotation/search?goId=GO:0006915&taxonId=9606&limit=50" # Filter by evidence code curl "https://www.ebi.ac.uk/QuickGO/services/annotation/search?\ goId=GO:0006915&taxonId=9606&evidence=EXP,IDA,IMP&limit=50" # Filter by aspect (ontology branch) curl "https://www.ebi.ac.uk/QuickGO/services/annotation/search?\ geneProductId=P04637&aspect=biological_process"
bash# Download as TSV curl "https://www.ebi.ac.uk/QuickGO/services/annotation/downloadSearch?\ goId=GO:0006915&taxonId=9606&downloadLimit=10000" -o annotations.tsv
| Aspect | Code | Description | |--------|------|-------------| | Biological Process | biological_process | What the gene does | | Molecular Function | molecular_function | Biochemical activity | | Cellular Component | cellular_component | Where in the cell |
| Code | Meaning | Reliability | |------|---------|-------------| | EXP | Inferred from Experiment | High | | IDA | Inferred from Direct Assay | High | | IMP | Inferred from Mutant Phenotype | High | | IPI | Inferred from Physical Interaction | Medium | | ISS | Inferred from Sequence Similarity | Medium | | IEA | Inferred from Electronic Annotation | Lower |
pythonimport requests BASE_URL = "https://www.ebi.ac.uk/QuickGO/services" def search_go_terms(query: str, limit: int = 20) -> list: """Search Gene Ontology terms.""" resp = requests.get( f"{BASE_URL}/ontology/go/search", params={"query": query, "limit": limit}, ) resp.raise_for_status() data = resp.json() results = [] for term in data.get("results", []): results.append({ "id": term.get("id"), "name": term.get("name"), "aspect": term.get("aspect"), "definition": term.get("definition", {}).get("text", ""), }) return results def get_protein_annotations(uniprot_id: str, aspect: str = None, experimental_only: bool = False) -> list: """Get GO annotations for a protein.""" params = {"geneProductId": uniprot_id, "limit": 100} if aspect: params["aspect"] = aspect if experimental_only: params["evidence"] = "EXP,IDA,IMP,IPI,IGI,IEP" resp = requests.get( f"{BASE_URL}/annotation/search", params=params, ) resp.raise_for_status() data = resp.json() annotations = [] for ann in data.get("results", []): annotations.append({ "go_id": ann.get("goId"), "go_name": ann.get("goName"), "aspect": ann.get("goAspect"), "evidence": ann.get("goEvidence"), "reference": ann.get("reference"), }) return annotations def get_term_genes(go_id: str, taxon_id: int = 9606, limit: int = 100) -> list: """Get genes annotated with a GO term.""" params = { "goId": go_id, "taxonId": taxon_id, "limit": limit, } resp = requests.get( f"{BASE_URL}/annotation/search", params=params, ) resp.raise_for_status() data = resp.json() genes = set() for ann in data.get("results", []): genes.add(ann.get("geneProductId", "")) return sorted(genes) # Example: search for apoptosis-related GO terms terms = search_go_terms("programmed cell death") for t in terms[:5]: print(f"{t['id']}: {t['name']} ({t['aspect']})") # Example: get p53 protein annotations annotations = get_protein_annotations("P04637", experimental_only=True) for a in annotations[:10]: print(f" {a['go_id']} {a['go_name']} [{a['evidence']}]")
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | pass→pass | 6,270 | 14,968 | +139% | 1 | 1 | 0% | 894 | 2,160 | +142% | 0 | 0 | — |
case-02 | pass→pass | 6,957 | 3,166 | -54% | 1 | 1 | 0% | 1,014 | 2,178 | +115% | 0 | 0 | — |
case-03 | pass→pass | 12,999 | 11,790 | -9% | 1 | 1 | 0% | 2,547 | 3,977 | +56% | 0 | 0 | — |
case-04 | pass→pass | 4,231 | 1,950 | -54% | 1 | 1 | 0% | 753 | 1,973 | +162% | 0 | 0 | — |
case-05 | pass→pass | 6,641 | 2,249 | -66% | 1 | 1 | 0% | 981 | 2,030 | +107% | 0 | 0 | — |
case-06 | pass→fail | 5,448 | 2,253 | -59% | 1 | 1 | 0% | 925 | 1,975 | +114% | 0 | 0 | — |
case-07 | pass→pass | 6,220 | 2,977 | -52% | 1 | 1 | 0% | 1,069 | 2,118 | +98% | 0 | 0 | — |
case-08 | pass→pass | 5,488 | 2,217 | -60% | 1 | 1 | 0% | 1,021 | 1,981 | +94% | 0 | 0 | — |
case-09 | pass→pass | 7,194 | 3,361 | -53% | 1 | 1 | 0% | 1,196 | 2,200 | +84% | 0 | 0 | — |
case-10 | pass→pass | 4,695 | 2,235 | -52% | 1 | 1 | 0% | 751 | 1,945 | +159% | 0 | 0 | — |
case-11 | pass→pass | 5,969 | 3,456 | -42% | 1 | 1 | 0% | 1,075 | 2,185 | +103% | 0 | 0 | — |
case-12 | fail→pass | 17,330 | 2,194 | -87% | 1 | 1 | 0% | 3,267 | 1,960 | -40% | 0 | 0 | — |
case-13 | pass→pass | 4,431 | 2,630 | -41% | 1 | 1 | 0% | 727 | 2,005 | +176% | 0 | 0 | — |
case-14 | pass→pass | 8,165 | 3,119 | -62% | 1 | 1 | 0% | 1,179 | 2,105 | +79% | 0 | 0 | — |
case-15 | fail→pass | 6,672 | 2,203 | -67% | 1 | 1 | 0% | 994 | 1,982 | +99% | 0 | 0 | — |
case-16 | pass→pass | 8,232 | 3,404 | -59% | 1 | 1 | 0% | 1,476 | 2,058 | +39% | 0 | 0 | — |
case-17 | pass→pass | 12,886 | 8,230 | -36% | 1 | 1 | 0% | 1,994 | 2,986 | +50% | 0 | 0 | — |
case-18 | pass→pass | 7,421 | 3,616 | -51% | 1 | 1 | 0% | 1,464 | 2,226 | +52% | 0 | 0 | — |
case-19 | pass→pass | 7,421 | 3,889 | -48% | 1 | 1 | 0% | 1,418 | 2,372 | +67% | 0 | 0 | — |
case-20 | pass→pass | 7,031 | 2,811 | -60% | 1 | 1 | 0% | 1,297 | 2,050 | +58% | 0 | 0 | — |
case-21 | pass→pass | 11,333 | 3,933 | -65% | 1 | 1 | 0% | 2,180 | 2,366 | +9% | 0 | 0 | — |
case-22 | pass→pass | 9,200 | 3,063 | -67% | 1 | 1 | 0% | 1,611 | 2,153 | +34% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +5 percentage points is the difference between those two pass rates over the 22 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.