
Ontology Term Resolution
FreeAccurately resolve and validate ontology terms.
Free · Opens the source repo
What Ontology Term Resolution does
Ontology Term Resolution is a skill designed for researchers and developers working with scientific data that requires precise identification of terms from various ontologies. This skill allows you to resolve free-text scientific labels into their corresponding ontology term IDs and validate existing identifiers against the EBI Ontology Lookup Service (OLS4). The importance of this skill lies in its ability to prevent errors that can arise from incorrect or outdated ontology IDs, which can lead to significant inaccuracies in scientific datasets.
The skill operates through two main scripts: resolve_terms.py and validate_terms.py. The first script translates a given text label, like 'liver', into the correct ontology term ID, ensuring that the term corresponds to the intended concept. The second script checks whether an existing ontology ID is valid, current, and accurately labeled. This is crucial for maintaining the integrity of metadata in submissions to repositories such as GEO, ENA, and BioSamples, among others.
Users will find this skill particularly useful when preparing metadata for scientific submissions, auditing existing datasets, or ensuring that ontology terms are up-to-date. It provides a systematic approach to ontology management, helping to avoid the pitfalls of relying on memory or outdated references. By automating the lookup and validation process, it enhances the reliability of scientific communication and data sharing.
In summary, Ontology Term Resolution is an essential tool for anyone involved in scientific research that requires the use of ontologies. It minimizes the risk of errors in data annotation and ensures that the terms used are both accurate and current, thereby supporting better data quality and interoperability in scientific research.
When to use it
Use this skill whenever you need to annotate metadata with ontology terms, validate existing IDs, or check for obsolescence in your datasets.
When not to use it
This skill may not be suitable for applications that do not require precise ontology term validation or for users unfamiliar with ontology concepts.
What you can build with it
Annotating Metadata for GEO Submission
Use the skill to resolve tissue and cell type names to their corresponding ontology IDs before submitting to GEO.
Auditing Existing Metadata Tables
Validate a metadata table of term IDs to ensure all entries are current and correctly labeled.
Checking for Obsolete Terms
Verify if any ontology IDs in your dataset have been marked as obsolete and find their replacements.
How to install Ontology Term Resolution
View source1. Install with the skills CLI
npx skills add k-dense-ai/scientific-agent-skills/ontology-term-resolution --agent claude-code2. Or install it manually
Download the skill folder and drop it into ~/.claude/skills/ for all projects, or .claude/skills/ to scope it to one repo. Restart Claude Code so it picks up the new skill.
Anthropic's agentic coding CLI, and the reference implementation of Agent Skills. Drop a skill folder into ~/.claude/skills and Claude Code loads it automatically whenever a task matches the skill's description. Claude Code docs
Inside SKILL.md
Written by k-dense-aiOntology Term Resolution
When to use
Any time an ontology identifier is about to be written down or trusted: annotating a metadata column, filling a submission template, auditing a table someone else produced, or checking whether an ID in an old file is still current.
The rule
Never write an ontology ID from memory, and never accept one without checking it.
Ontology IDs are memorable in form and arbitrary in detail. A plausible-looking UBERON:0002108
is a real term (small intestine) that is not the liver, and nothing downstream will catch the
substitution — the ID is well-formed, the ontology is right, and the metadata is silently wrong.
Reviewers cannot spot it either, which is why these errors persist into published datasets.
Every ID this skill emits comes from a live OLS lookup. Every ID it is handed gets verified.
Two directions
| Direction | Script | Question answered |
|---|---|---|
| text → ID | scripts/resolve_terms.py | What is the term for "left ventricle"? |
| ID → verdict | scripts/validate_terms.py | Is EFO:0001067 real, current, and labelled what this file claims? |
Both take single values or files, emit TSV or JSON, and need no packages beyond the standard library.
Resolve text to terms
cd skills/ontology-term-resolution/scripts
# one string, constrained to the ontology that should define it
python3 resolve_terms.py "liver" --ontology uberon
query rank curie label ontology match_type strategy defining_ontology
liver 1 UBERON:0002107 liver uberon exact_label exact true
# a column of tissue names; anything not an exact hit is reported, not guessed
python3 resolve_terms.py --input tissues.txt --ontology uberon \
--exact-only --format tsv -o resolved.tsv
# accept fuzzy fallbacks, then review the partial hits by hand
python3 resolve_terms.py "left ventrical of heart" --ontology uberon --top 3
The search escalates exact (label and synonym) → token → fulltext and stops at the first
strategy that returns anything, reporting which one fired. --exact-only disables the ladder.
--branch UBERON:0000465 restricts candidates to descendants of a term.
Read match_type before using a result. exact_label and exact_synonym are safe;
partial means OLS returned its best guess for a string that does not exist as written, and
needs a human decision. unresolved is a legitimate output — see references/curation-rules.md
for the normalisations worth retrying first.
Validate existing IDs
python3 validate_terms.py UBERON:0002107 EFO:0001067 UBERON:9999999
id status actual_label ontology replacement detail
UBERON:0002107 ok liver uberon
EFO:0001067 obsolete obsolete_parasitic infection efo MONDO:0005135 obsolete; replaced by MONDO:0005135
UBERON:9999999 not_found no such term in the ontology this prefix names
Exit code is 1 if anything failed, 0 otherwise, 2 on usage or network trouble — so it works as a CI gate on a metadata file:
# id + label columns; catches IDs that exist but are labelled as something else
python3 validate_terms.py --input metadata.tsv --strict
# a tissue column must hold UBERON anatomical entities and nothing else
python3 validate_terms.py --input tissue_ids.tsv \
--branch UBERON:0000465 --expect-ontology uberon
| Status | Meaning | Verdict |
|---|---|---|
ok | Exists, current, consistent with everything asserted | pass |
matched_synonym | Claimed label is a synonym; primary label differs | warn |
imported_only | Home ontology no longer asserts this ID | warn |
not_a_class | Term is a property or individual | warn |
not_found | No such term | fail |
obsolete | Obsoleted; replacement gives the successor when one exists | fail |
label_mismatch | ID and claimed label describe different things | fail |
wrong_ontology | Right kind of ID, wrong ontology for this column | fail |
wrong_branch | Not a descendant of the required root | fail |
malformed_curie | Not of the form PREFIX:local | fail |
--strict promotes warnings to failures.
API behaviour that will mislead you
These are verified against the live service and are the reason this skill ships scripts rather
than a recipe. Full detail in references/ols4-api.md.
| Trap | Consequence |
|---|---|
exact=true is exact token matching | liver returns 161 hits in UBERON; adding queryFields=label returns 1 |
/search never returns is_obsolete or term_replaced_by | Named in fieldList they are dropped silently; only term detail can answer "is this ID still current" |
ontology=efo returns MONDO and CL hits | Ontologies import each other; filter on the CURIE prefix yourself |
| The same term appears once per importing ontology | Deduplicate on obo_id, keep is_defining_ontology: true |
The obo_id index has holes | MONDO:0000001 is live but unindexed by obo_id; an IRI fallback is required to avoid a false not_found |
| IRIs are not all OBO PURLs | EFO and Orphanet use their own namespaces — resolve IRIs, do not template them |
| OxO is retired | Returns HTML with HTTP 200; use term cross-references or SSSOM instead |
| A branch check does not exclude cell types from anatomy | CARO puts cell under anatomical structure; constrain the prefix too |
Choosing the ontology
MONDO for disease, HP for phenotype, UBERON for tissue, CL for cell type, EFO for assay, ChEBI for
compounds, NCBITaxon for organism, PATO for sex and for normal. Prefix-to-OLS-id mappings (HP
is served as hp, Orphanet as ordo), branch roots for --branch, and the overlapping-ontology
judgement calls are in references/ontology-registry.md.
Reporting results
Give the ID and the label, and say how each was matched. A table of bare IDs cannot be reviewed. State unresolved terms explicitly rather than filling them with the nearest hit.
References
references/ols4-api.md— endpoints, parameters, response fields, and every verified trap.references/ontology-registry.md— prefix/ontology-id table, branch roots, which ontology owns which concept.references/curation-rules.md— candidate-selection procedure, normalisations to retry, auditing an existing table, obsolete terms, cross-ontology mapping.
Frequently asked questions about Ontology Term Resolution
Similar skills
Single-Cell RNA-seq QC
Automate quality control for single-cell RNA-seq data.
Instrument Data to Allotrope Converter
Standardize lab data for seamless integration.
SQL Server Table Reconciliation
Efficiently compare SQL Server tables across instances.
Data Cleaning and Variable Screening
Streamline credit risk data preprocessing for modeling.
Arize Dataset
Manage and query Arize datasets efficiently.
Spreadsheet Management
Efficiently create, edit, and analyze spreadsheet files.
