
Tooluniverse Cancer Variant Interpretation
- 331 installs
- 1.6k repo stars
- Updated August 4, 2026
- mims-harvard/tooluniverse
tooluniverse-cancer-variant-interpretation is an agent skill that turns a gene-plus-variant input into a cancer-type-specific precision oncology report with CIViC and OncoKB evidence tiers, therapies, resistance, trials,
About
tooluniverse-cancer-variant-interpretation is a ToolUniverse clinical skill for somatic cancer mutation interpretation. Given a gene symbol, variant notation, and optional cancer type, it runs an 8-phase workflow: gene ID resolution, CIViC clinical evidence, cBioPortal prevalence, OpenTargets and ChEMBL therapeutics, resistance checks, ClinicalTrials.gov search, prognostic context, and a synthesized actionability report graded T1–T4. The skill enforces verified ToolUniverse parameter names, database-first lookups over guessing, and Python execution for scoring or enrichment. Developers reach for it when building agents that interpret tumor-board variant calls, prior-auth evidence packets, or treatment-selection questions like EGFR L858R in lung cancer.
- Oncogenic variant classification
- Clinical significance lookup
- Somatic annotation pipelines
- ToolUniverse genomics routing
- Tumor report triage support
Tooluniverse Cancer Variant Interpretation by the numbers
- 331 all-time installs (skills.sh)
- +6 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #561 of 2,064 Data Science & ML skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/mims-harvard/tooluniverse --skill tooluniverse-cancer-variant-interpretationAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 331 |
|---|---|
| repo stars | ★ 1.6k |
| Last updated | August 4, 2026 |
| Repository | mims-harvard/tooluniverse ↗ |
How do agents interpret somatic cancer variants clinically?
Enable agents to interpret somatic variants, oncogenic annotations, and clinical significance tiers when reviewing tumor sequencing reports or prior-auth evidence packets.
Who is it for?
Bioinformatics and clinical AI developers building agent workflows that interpret somatic mutations with curated oncology databases.
Skip if: General-purpose health chatbots or developers without ToolUniverse access who only need non-clinical coding help.
When should I use this skill?
A user asks to interpret a somatic mutation, assess targetability, find therapies or trials, or build tumor-board variant actionability reports.
What you get
A source-cited precision oncology report with evidence tiers, prioritized therapies, resistance mechanisms, trial matches, and prognostic notes.
- Precision oncology report file
- Evidence-tiered therapy list
- Clinical trial matches
By the numbers
- Executes an 8-phase clinical interpretation workflow from gene resolution to report synthesis
- Grades therapy recommendations on T1–T4 evidence tiers
Files
Cancer Variant Interpretation for Precision Oncology
Comprehensive clinical interpretation of somatic mutations in cancer. Transforms a gene + variant input into an actionable precision oncology report covering clinical evidence, therapeutic options, resistance mechanisms, clinical trials, and prognostic implications.
KEY PRINCIPLES: 1. Report-first approach - Create report file FIRST, then populate progressively 2. Evidence-graded - Every recommendation has an evidence tier (T1-T4) 3. Actionable output - Prioritized treatment options, not data dumps 4. Clinical focus - Answer "what should we treat with?" not "what databases exist?" 5. Resistance-aware - Always check for known resistance mechanisms 6. Cancer-type specific - Tailor all recommendations to the patient's cancer type when provided 7. Source-referenced - Every statement must cite the tool/database source 8. English-first queries - Always use English terms in tool calls (gene names, drug names, cancer types), even if the user writes in another language. Respond in the user's language
---
LOOK UP, DON'T GUESS
When uncertain about any scientific fact, SEARCH databases first (PubMed, UniProt, ChEMBL, ClinVar, etc.) rather than reasoning from memory. A database-verified answer is always more reliable than a guess.
---
COMPUTE, DON'T DESCRIBE
When analysis requires computation (statistics, data processing, scoring, enrichment), write and run Python code via Bash. Don't describe what you would do — execute it and report actual results. Use ToolUniverse tools to retrieve data, then Python (pandas, scipy, statsmodels, matplotlib) to analyze it.
When to Use
Apply when user asks:
- "What treatments exist for EGFR L858R in lung cancer?"
- "Patient has BRAF V600E melanoma - what are the options?"
- "Is KRAS G12C targetable?"
- "Patient progressed on osimertinib - what's next?"
- "What clinical trials are available for PIK3CA E545K?"
- "Interpret this somatic mutation: TP53 R273H"
---
Input Parsing
Required: Gene symbol + variant notation (e.g., "EGFR L858R", "BRAF p.V600E", "EML4-ALK fusion", "HER2 amplification") Optional: Cancer type (improves specificity)
Parse the gene symbol and variant separately. For fusions, use the kinase partner as the primary gene. For amplifications/deletions, use the gene name directly. Normalize common aliases: HER2 -> ERBB2, PD-L1 -> CD274, VEGF -> VEGFA.
---
Phase 0: Tool Parameter Verification (CRITICAL)
BEFORE calling ANY tool for the first time, verify its parameters.
| Tool | WRONG Parameter | CORRECT Parameter |
|---|---|---|
OpenTargets_get_associated_drugs_by_target_ensemblID | ensemblID | ensemblId (camelCase) |
OpenTargets_get_drug_chembId_by_generic_name | genericName | drugName |
OpenTargets_target_disease_evidence | ensemblID | ensemblId + efoId |
MyGene_query_genes | q | query |
search_clinical_trials | disease, biomarker | condition, query_term (required) |
civic_get_variants_by_gene | gene_symbol | gene_id (CIViC numeric ID) |
drugbank_* | any 3 params | ALL 4 required: query, case_sensitive, exact_match, limit |
ChEMBL_get_drug_mechanisms | chembl_id | drug_chembl_id__exact |
ensembl_lookup_gene | no species | species='homo_sapiens' is REQUIRED |
---
Workflow Overview
Input: Gene symbol + Variant notation + Optional cancer type
Phase 1: Gene Disambiguation & ID Resolution
- Resolve gene to Ensembl ID, UniProt accession, Entrez ID
- Get gene function, pathways, protein domains
- Identify cancer type EFO ID (if cancer type provided)
Phase 2: Clinical Variant Evidence (CIViC)
- Find gene in CIViC (via Entrez ID matching)
- Get all variants for the gene, match specific variant
- Retrieve evidence items (predictive, prognostic, diagnostic)
Phase 3: Mutation Prevalence (cBioPortal)
- Frequency across cancer studies
- Co-occurring mutations, cancer type distribution
Phase 4: Therapeutic Associations (OpenTargets + ChEMBL + FDA + DrugBank)
- FDA-approved targeted therapies
- Clinical trial drugs (phase 2-3), drug mechanisms
- Combination therapies
Phase 5: Resistance Mechanisms
- Known resistance variants (CIViC, literature)
- Bypass pathway analysis (Reactome)
Phase 6: Clinical Trials
- Active trials recruiting for this mutation
- Trial phase, status, eligibility
Phase 7: Prognostic Impact & Pathway Context
- Survival associations (literature)
- Pathway context (Reactome), Expression data (GTEx)
Phase 8: Report Synthesis
- Executive summary, clinical actionability score
- Treatment recommendations (prioritized), completeness checklistFor detailed code snippets and API call patterns for each phase, see ANALYSIS_DETAILS.md.
---
Clinical Reasoning Strategies
Driver vs Passenger Reasoning
Not every mutation in a tumor is driving the cancer. Before querying databases, form a hypothesis:
- Is this gene a known oncogene or tumor suppressor? Genes like EGFR, BRAF, KRAS, TP53, PIK3CA are well-established cancer drivers. A mutation in one of these warrants deep investigation. A mutation in a gene with no known cancer role is likely a passenger.
- Is this specific mutation recurrent across tumors (hotspot)? Use cBioPortal to check. A mutation seen in hundreds of independent tumors (e.g., BRAF V600E) is almost certainly a driver. A unique, never-before-seen missense in the same gene is less certain.
- What is the predicted functional impact? Truncating mutations (nonsense, frameshift) in tumor suppressors are likely loss-of-function drivers. Missense mutations in oncogenes at known hotspot residues are likely gain-of-function drivers.
- For unique (non-hotspot) missense in driver genes, look at mechanism, not just pathogenicity. AlphaMissense gives a score; the ESMC-6B SAE composite
ESM_explain_variant_mechanism(sequence=wt_protein_seq, position=..., ref_aa=..., alt_aa=..., top_k_features=5)answers how the substitution disrupts function — catalytic / ligand-binding / PTM / structural-stability loss. A unique missense that disrupts the same SAE feature category as a known driver hotspot in the same gene is more likely a driver than a missense that disrupts unrelated features. RequiresESM_API_KEY; missense only. - Conclusion pattern: A recurrent mutation in a known driver gene is likely actionable. A unique mutation in a gene not associated with cancer is likely a passenger. State your assessment and the reasoning behind it.
Actionability Reasoning
Actionable means a therapy exists that targets this alteration. Think in tiers based on evidence strength:
- Tier 1: FDA-approved drug for this mutation in this cancer type. The standard of care — recommend confidently. Example reasoning: "CIViC returns Level A evidence, FDA label confirms indication."
- Tier 2: FDA-approved for this mutation in a different cancer type, or strong clinical trial evidence (phase 2-3) in this cancer type. Reasonable to consider, especially under tumor-agnostic approvals or with molecular tumor board discussion.
- Tier 3: Preclinical evidence only — cell line data, animal models, or case reports. May justify clinical trial enrollment but not off-label use.
- Tier 4: Biological rationale but no direct evidence — the mutation is in a druggable pathway, or a structurally similar mutation responds to therapy. Hypothesis-generating only.
When synthesizing, state the tier and explain WHY you assigned it based on the evidence you found, not just which database returned a hit.
Resistance Reasoning
If the patient has already been treated, ask: could this mutation be a resistance mechanism?
- On-target resistance: Mutations in the drug target gene itself that restore signaling despite drug binding. These typically emerge at the drug-binding site (e.g., EGFR T790M after erlotinib, EGFR C797S after osimertinib, ABL T315I after imatinib).
- Bypass pathway activation: Mutations in parallel signaling pathways that render the target irrelevant (e.g., MET amplification bypassing EGFR inhibition, BRAF activation bypassing MEK inhibition).
- Phenotypic transformation: Lineage changes (e.g., small cell transformation in EGFR-mutant lung cancer) that eliminate dependence on the original driver.
- Timing matters: If the mutation was detected AFTER treatment, it is more likely a resistance mechanism than if it was present at diagnosis.
When to Use Which Tool
Form your clinical hypothesis FIRST based on gene function and mutation type, THEN use tools to validate:
- CIViC (
civic_search_genes,civic_get_variants_by_gene): Your primary source for clinical evidence. Returns curated evidence items with evidence levels, clinical significance, and associated therapies. Start here for any variant with potential clinical relevance. - cBioPortal (
cBioPortal_get_mutations): Use to assess mutation prevalence — is this a hotspot? How common is it across cancer types? This informs your driver vs passenger assessment. - OpenTargets (
OpenTargets_get_associated_drugs_by_target_ensemblID): Use for actionability — what drugs target this gene? Cross-reference with CIViC evidence to assign tiers. - PubMed (
PubMed_search_articles): Use when CIViC lacks entries for your variant, or to find resistance mechanism reports and recent clinical trial results. - ClinicalTrials.gov (
search_clinical_trials): Use after establishing the variant is potentially actionable, to find enrollment opportunities.
---
Tool Reference (Verified Parameters)
Gene Resolution
| Tool | Key Parameters | Response Key Fields |
|---|---|---|
MyGene_query_genes | query, species | hits[].ensembl.gene, .entrezgene, .symbol |
UniProt_search | query, organism, limit | results[].accession |
OpenTargets_get_target_id_description_by_name | targetName | data.search.hits[].id |
ensembl_lookup_gene | gene_id, species (REQUIRED) | data.id, .version |
Clinical Evidence
| Tool | Key Parameters | Response Key Fields |
|---|---|---|
civic_search_genes | query, limit | data.genes.nodes[].id, .entrezId |
civic_get_variants_by_gene | gene_id (CIViC numeric) | data.gene.variants.nodes[] |
civic_get_variant | variant_id | data.variant |
Drug Information
| Tool | Key Parameters | Response Key Fields |
|---|---|---|
OpenTargets_get_associated_drugs_by_target_ensemblID | ensemblId, size | data.target.drugAndClinicalCandidates.rows[] |
FDA_get_indications_by_drug_name | drug_name, limit | results[].indications_and_usage |
drugbank_get_drug_basic_info_by_drug_name_or_id | query, case_sensitive, exact_match, limit (ALL required) | results[] |
Mutation Prevalence
| Tool | Key Parameters | Response Key Fields |
|---|---|---|
cBioPortal_get_mutations | study_id, gene_list | data[].proteinChange |
cBioPortal_get_cancer_studies | limit | [].studyId, .cancerTypeId |
Clinical Trials & Literature
| Tool | Key Parameters | Response Key Fields |
|---|---|---|
search_clinical_trials | query_term (required), condition | studies[] |
PubMed_search_articles | query, limit, include_abstract | Returns list of dicts (NOT wrapped) |
Reactome_map_uniprot_to_pathways | id (UniProt accession) | Pathway mappings |
GTEx_get_median_gene_expression | gencode_id, operation="median" | Expression by tissue |
---
Fallback Strategy
When a primary tool returns no results, fall back rather than reporting "no data found":
- CIViC empty -> search PubMed for "[gene] [variant] clinical evidence"
- OpenTargets no drugs -> try ChEMBL drug search by target
- cBioPortal specific study empty -> try pan-cancer study (msk_impact_2017 or similar)
- Reactome no pathways -> use UniProt function annotation for pathway context
Cancer Variant Interpretation - Detailed Analysis Procedures
Phase 1: Gene Disambiguation & ID Resolution
1.1 MyGene ID Resolution (PRIMARY)
def resolve_gene_ids(tu, gene_symbol):
"""Resolve gene symbol to Ensembl, Entrez, UniProt IDs."""
result = tu.tools.MyGene_query_genes(query=gene_symbol, species='human')
hits = result.get('hits', [])
# Take the top hit where symbol matches exactly
gene_hit = None
for hit in hits:
if hit.get('symbol', '').upper() == gene_symbol.upper():
gene_hit = hit
break
if not gene_hit and hits:
gene_hit = hits[0]
ids = {
'symbol': gene_hit.get('symbol'),
'entrez_id': gene_hit.get('entrezgene'),
'ensembl_id': gene_hit.get('ensembl', {}).get('gene'),
'name': gene_hit.get('name'),
}
return idsResponse structure: {took, total, max_score, hits: [{_id, _score, ensembl: {gene}, entrezgene, name, symbol}]}
1.2 UniProt Accession
def get_uniprot_id(tu, gene_symbol):
"""Get UniProt accession for gene."""
result = tu.tools.UniProt_search(query=f'gene:{gene_symbol}', organism='human', limit=3)
# Response: {total_results, returned, results: [{accession, id, protein_name, gene_names, organism, length}]}
results = result.get('results', [])
if results:
return results[0].get('accession')
return None1.3 OpenTargets Target Resolution
def get_opentargets_info(tu, gene_symbol):
"""Resolve gene to OpenTargets ensemblId and description."""
result = tu.tools.OpenTargets_get_target_id_description_by_name(targetName=gene_symbol)
# Response: {data: {search: {hits: [{id (ensemblId), name, description}]}}}
hits = result.get('data', {}).get('search', {}).get('hits', [])
for hit in hits:
if hit.get('name', '').upper() == gene_symbol.upper():
return hit
return hits[0] if hits else None1.4 Cancer Type EFO Resolution (if cancer type provided)
def resolve_cancer_type(tu, cancer_type):
"""Resolve cancer type to EFO ID for OpenTargets queries."""
result = tu.tools.OpenTargets_get_disease_id_description_by_name(diseaseName=cancer_type)
hits = result.get('data', {}).get('search', {}).get('hits', [])
return hits[0] if hits else None1.5 Gene Function Context
def get_gene_function(tu, uniprot_accession):
"""Get protein function from UniProt.
NOTE: Returns a list of function description strings, NOT a dict.
"""
result = tu.tools.UniProt_get_function_by_accession(accession=uniprot_accession)
return result1.6 CIViC Gene ID Resolution
IMPORTANT: The civic_search_genes tool does NOT support name filtering in its GraphQL query. To find a gene in CIViC, either: 1. Paginate through results (inefficient, genes sorted alphabetically) 2. Use the Entrez ID from MyGene to construct a CIViC gene lookup
Workaround: Use civic_search_genes with limit=100 and search the results client-side.
Known CIViC Gene IDs (for common cancer genes):
| Gene | CIViC Gene ID | Entrez ID |
|---|---|---|
| BRAF | 5 | 673 |
| ABL1 | 4 | 25 |
| ALK | 1 | 238 |
---
Phase 2: Clinical Variant Evidence (CIViC)
2.1 Get Gene Variants from CIViC
def get_civic_variants(tu, civic_gene_id):
"""Get all variants for a gene in CIViC."""
result = tu.tools.civic_get_variants_by_gene(gene_id=civic_gene_id, limit=200)
variants = result.get('data', {}).get('gene', {}).get('variants', {}).get('nodes', [])
return variants2.2 Match Specific Variant
def find_variant_in_civic(variants, variant_name):
"""Find the specific variant in CIViC results."""
normalized = variant_name.replace('p.', '').strip()
for v in variants:
if v.get('name', '').upper() == normalized.upper():
return v
for v in variants:
if normalized.upper() in v.get('name', '').upper():
return v
return None2.3 Get Variant Details
def get_variant_details(tu, variant_id):
"""Get detailed variant information from CIViC."""
result = tu.tools.civic_get_variant(variant_id=variant_id)
return result.get('data', {}).get('variant', {})2.4 Get Molecular Profile Evidence
def get_molecular_profile(tu, molecular_profile_id):
"""Get molecular profile details (for evidence items)."""
result = tu.tools.civic_get_molecular_profile(molecular_profile_id=molecular_profile_id)
return result.get('data', {}).get('molecularProfile', {})2.5 CIViC Evidence Limitations and Fallback
The current CIViC tools return limited field sets from GraphQL. If CIViC data is sparse:
- Fallback to literature: Use PubMed to search for "{gene} {variant} clinical significance cancer"
- Fallback to OpenTargets: Use
OpenTargets_target_disease_evidencefor target-disease evidence
---
Phase 3: Mutation Prevalence (cBioPortal)
3.1 Find Relevant Studies
def find_cancer_studies(tu, cancer_keyword=None):
"""Find relevant cBioPortal studies."""
result = tu.tools.cBioPortal_get_cancer_studies(limit=50)
studies = result if isinstance(result, list) else result.get('data', [])
if cancer_keyword:
filtered = [s for s in studies
if cancer_keyword.lower() in str(s.get('name', '')).lower()
or cancer_keyword.lower() in str(s.get('cancerTypeId', '')).lower()]
return filtered
return studies3.2 Get Mutation Data
def get_mutation_prevalence(tu, gene_symbol, study_id):
"""Get mutation data for a gene in a specific study."""
result = tu.tools.cBioPortal_get_mutations(study_id=study_id, gene_list=gene_symbol)
if isinstance(result, list):
mutations = result
elif isinstance(result, dict):
mutations = result.get('data', []) if result.get('status') == 'success' else []
else:
mutations = []
return mutations3.3 Analyze Mutation Distribution
def analyze_mutation_distribution(mutations, target_variant):
"""Count how many samples have the target variant vs. others."""
from collections import Counter
protein_changes = [m.get('proteinChange', '') for m in mutations]
counts = Counter(protein_changes)
total_mutated = len(mutations)
target_count = sum(1 for m in mutations
if target_variant.upper() in str(m.get('proteinChange', '')).upper())
return {
'total_mutated_samples': total_mutated,
'target_variant_count': target_count,
'target_variant_frequency': target_count / total_mutated if total_mutated > 0 else 0,
'top_variants': counts.most_common(10),
}Key cBioPortal Studies for Common Cancer Types
| Cancer Type | Study ID | Description |
|---|---|---|
| Lung adenocarcinoma | luad_tcga | TCGA Lung Adenocarcinoma |
| Breast cancer | brca_tcga | TCGA Breast Cancer |
| Colorectal cancer | coadread_tcga | TCGA Colorectal |
| Melanoma | skcm_tcga | TCGA Melanoma |
| Pancreatic cancer | paad_tcga | TCGA Pancreatic |
| Glioblastoma | gbm_tcga | TCGA Glioblastoma |
| Prostate cancer | prad_tcga | TCGA Prostate |
| Ovarian cancer | ov_tcga | TCGA Ovarian |
---
Phase 4: Therapeutic Associations
4.1 OpenTargets Drug-Target Associations (PRIMARY)
def get_target_drugs(tu, ensembl_id, size=50):
"""Get all drugs associated with a target from OpenTargets."""
result = tu.tools.OpenTargets_get_associated_drugs_by_target_ensemblID(
ensemblId=ensembl_id, size=size
)
drugs = result.get('data', {}).get('target', {}).get('knownDrugs', {})
rows = drugs.get('rows', [])
approved = [r for r in rows if r.get('drug', {}).get('isApproved')]
phase3 = [r for r in rows if r.get('phase') == 3 and not r.get('drug', {}).get('isApproved')]
phase2 = [r for r in rows if r.get('phase') == 2]
return {
'total': drugs.get('count', 0),
'approved': approved,
'phase3': phase3,
'phase2': phase2,
'all_rows': rows
}4.2 OpenTargets Drug Mechanisms
def get_drug_mechanism(tu, chembl_id):
"""Get mechanism of action for a drug."""
result = tu.tools.OpenTargets_get_drug_mechanisms_of_action_by_chemblId(chemblId=chembl_id)
return result4.3 FDA Label Information
def get_fda_label(tu, drug_name):
"""Get FDA-approved indications and label info."""
indications = tu.tools.FDA_get_indications_by_drug_name(drug_name=drug_name, limit=3)
warnings = tu.tools.FDA_get_boxed_warning_info_by_drug_name(drug_name=drug_name, limit=3)
moa = tu.tools.FDA_get_mechanism_of_action_by_drug_name(drug_name=drug_name, limit=3)
return {'indications': indications, 'warnings': warnings, 'mechanism': moa}4.4 DrugBank Drug Information
def get_drugbank_info(tu, drug_name):
"""Get drug information from DrugBank."""
result = tu.tools.drugbank_get_drug_basic_info_by_drug_name_or_id(
query=drug_name, case_sensitive=False, exact_match=False, limit=3
)
return result4.5 ChEMBL Drug Mechanism
def get_chembl_mechanism(tu, chembl_drug_id):
"""Get drug mechanism from ChEMBL."""
result = tu.tools.ChEMBL_get_drug_mechanisms(drug_chembl_id__exact=chembl_drug_id, limit=10)
return result4.6 Disease-Specific Drug Filtering
def get_disease_specific_drugs(tu, efo_id, size=30):
"""Get drugs associated with a specific disease/cancer type."""
result = tu.tools.OpenTargets_get_associated_drugs_by_disease_efoId(efoId=efo_id, size=size)
return result---
Phase 5: Resistance Mechanisms
5.1 CIViC Resistance Evidence
Search CIViC for variants with resistance significance for the target gene. Get all variants and look for those with "Resistance" in the name or description.
5.2 Literature-Based Resistance Search
def search_resistance_literature(tu, gene_symbol, drug_name):
"""Search PubMed for resistance mechanisms.
NOTE: PubMed returns a plain list of article dicts, NOT {articles: [...]}.
"""
result = tu.tools.PubMed_search_articles(
query=f'"{gene_symbol}" AND "{drug_name}" AND resistance AND mechanism',
limit=15, include_abstract=True
)
articles = result if isinstance(result, list) else result.get('articles', []) if isinstance(result, dict) else []
return articles5.3 Pathway-Based Bypass Resistance
def get_bypass_pathways(tu, uniprot_id):
"""Get pathways that could mediate bypass resistance."""
result = tu.tools.Reactome_map_uniprot_to_pathways(id=uniprot_id)
return resultKnown Resistance Patterns (Reference)
| Primary Target | Primary Drug | Resistance Mutation | Mechanism | Strategy |
|---|---|---|---|---|
| EGFR L858R | Erlotinib/Gefitinib | T790M | Steric hindrance | Osimertinib (3rd-gen TKI) |
| EGFR T790M | Osimertinib | C797S | Covalent bond loss | 4th-gen TKI trials |
| BRAF V600E | Vemurafenib | Splice variants | Paradoxical activation | BRAF+MEK combination |
| ALK fusion | Crizotinib | L1196M, G1269A | Kinase domain mutations | Alectinib, Lorlatinib |
| KRAS G12C | Sotorasib | Y96D, R68S | Drug binding loss | KRAS G12C combo trials |
---
Phase 6: Clinical Trials
6.1 Search Strategy
def find_clinical_trials(tu, gene_symbol, variant_name, cancer_type=None):
"""Find clinical trials for this mutation."""
query1 = f'{gene_symbol} {variant_name}'
result1 = tu.tools.search_clinical_trials(
query_term=query1, condition=cancer_type or 'cancer', pageSize=20
)
result2 = tu.tools.search_clinical_trials(
query_term=f'{gene_symbol} mutation',
condition=cancer_type or 'cancer', pageSize=20
)
return {'variant_specific': result1, 'gene_level': result2}Response structure: {studies: [{NCT ID, brief_title, brief_summary, overall_status, condition, phase}], nextPageToken, total_count}
6.2 Trial Filtering
Prioritize trials that: 1. Are RECRUITING or NOT_YET_RECRUITING status 2. Match the specific variant (not just gene) 3. Are Phase 2 or 3 (closer to approval) 4. Have the right cancer type
---
Phase 7: Prognostic Impact & Pathway Context
7.1 Literature Evidence
def get_prognostic_literature(tu, gene_symbol, variant_name, cancer_type=None):
"""Search for prognostic associations."""
query = f'"{gene_symbol}" "{variant_name}" prognosis survival'
if cancer_type:
query += f' "{cancer_type}"'
result = tu.tools.PubMed_search_articles(query=query, limit=10, include_abstract=True)
return result7.2 Pathway Context (Reactome)
def get_pathway_context(tu, uniprot_id):
"""Get pathway context from Reactome."""
result = tu.tools.Reactome_map_uniprot_to_pathways(id=uniprot_id)
return result7.3 Gene Expression (GTEx)
def get_expression_context(tu, ensembl_id):
"""Get tissue expression data from GTEx."""
gene_info = tu.tools.ensembl_lookup_gene(gene_id=ensembl_id, species='homo_sapiens')
data = gene_info.get('data', gene_info) if isinstance(gene_info, dict) else {}
version = data.get('version', 1)
versioned_id = f"{ensembl_id}.{version}"
result = tu.tools.GTEx_get_median_gene_expression(
gencode_id=versioned_id, operation='median'
)
return result7.4 UniProt Disease Variants
def get_known_disease_variants(tu, uniprot_accession):
"""Get known disease-associated variants from UniProt."""
result = tu.tools.UniProt_get_disease_variants_by_accession(accession=uniprot_accession)
return resultCancer Variant Interpretation - Examples
Example 1: EGFR L858R in Lung Adenocarcinoma
Input
Interpret EGFR L858R for lung adenocarcinomaPhase 1: Gene Resolution (verified)
# MyGene
gene_info = tu.tools.MyGene_query_genes(query='EGFR', species='human')
# Result: symbol='EGFR', ensembl='ENSG00000146648', entrez='1956'
# UniProt
uniprot = tu.tools.UniProt_search(query='gene:EGFR', organism='human', limit=3)
# Result: accession='P00533'
# OpenTargets
ot = tu.tools.OpenTargets_get_target_id_description_by_name(targetName='EGFR')
# Result: id='ENSG00000146648', description='epidermal growth factor receptor'
# Cancer type
cancer = tu.tools.OpenTargets_get_disease_id_description_by_name(diseaseName='lung adenocarcinoma')
# Result: EFO hits with lung adenocarcinomaPhase 3: Mutation Prevalence (verified)
result = tu.tools.cBioPortal_get_mutations(study_id='luad_tcga', gene_list='EGFR')
# Returns: {status: 'success', data: [{proteinChange: 'R222L', ...}, {proteinChange: 'L858R', ...}, ...]}
# L858R found in TCGA-LUAD cohortPhase 4: Therapeutic Options (verified)
drugs = tu.tools.OpenTargets_get_associated_drugs_by_target_ensemblID(ensemblId='ENSG00000146648', size=20)
# Returns 1870+ drug entries including:
# - Osimertinib (CHEMBL3353410) - Phase 4, approved, EGFR inhibitor
# - Cetuximab (CHEMBL1201577) - Phase 4, approved
# - Lapatinib (CHEMBL1201179) - Phase 4, approved
# - Neratinib (CHEMBL3989921) - Phase 4, approved
fda = tu.tools.FDA_get_indications_by_drug_name(drug_name='osimertinib', limit=3)
# Returns: FDA label showing indications for:
# - Adjuvant therapy for EGFR exon 19 del or L858R NSCLC
# - First-line metastatic EGFR-mutant NSCLC
# - T790M-positive NSCLC after prior EGFR TKI
db = tu.tools.drugbank_get_drug_basic_info_by_drug_name_or_id(
query='osimertinib', case_sensitive=False, exact_match=False, limit=3
)
# Returns: DB09330, third-generation EGFR TKI descriptionPhase 6: Clinical Trials (verified)
trials = tu.tools.search_clinical_trials(
query_term='EGFR L858R mutation',
condition='non-small cell lung cancer',
pageSize=10
)
# Returns multiple trials including osimertinib combinationsExpected Report Summary
Clinical Actionability: HIGH
EGFR L858R is a well-characterized activating mutation in NSCLC. Osimertinib (Tagrisso) is FDA-approved as first-line therapy for EGFR exon 21 L858R mutation-positive metastatic NSCLC [T1 evidence].
---
Example 2: BRAF V600E in Melanoma
Input
Interpret BRAF V600E for melanomaKey Verified Results
# Gene resolution
# BRAF: ENSG00000157764, UniProt P15056
# CIViC (verified: CIViC gene_id=5 for BRAF)
variants = tu.tools.civic_get_variants_by_gene(gene_id=5, limit=200)
# V600E found: CIViC variant_id=12
molecular_profile = tu.tools.civic_get_molecular_profile(molecular_profile_id=12)
# Name: 'BRAF V600E'
# cBioPortal melanoma mutations
mutations = tu.tools.cBioPortal_get_mutations(study_id='skcm_tcga', gene_list='BRAF')
# V600E is the most common BRAF mutation in melanoma
# OpenTargets drugs
drugs = tu.tools.OpenTargets_get_associated_drugs_by_target_ensemblID(
ensemblId='ENSG00000157764', size=20
)
# Returns vemurafenib, dabrafenib, encorafenib, and MEK inhibitorsExpected Report Summary
Clinical Actionability: HIGH
BRAF V600E is the most common BRAF mutation in melanoma. FDA-approved therapies include BRAF inhibitors (vemurafenib, dabrafenib, encorafenib) combined with MEK inhibitors (trametinib, cobimetinib, binimetinib) [T1 evidence]. Single-agent BRAF inhibition is no longer recommended due to rapid resistance.
---
Example 3: KRAS G12C (Any Cancer Type)
Input
What targeted therapies exist for KRAS G12C?Key Verified Results
# Gene resolution
# KRAS: ENSG00000133703, Entrez 3845
# Mutation prevalence in pancreatic cancer
mutations = tu.tools.cBioPortal_get_mutations(study_id='paad_tcga', gene_list='KRAS')
# KRAS is mutated in >90% of pancreatic cancers, G12 variants dominant
# OpenTargets drugs
drugs = tu.tools.OpenTargets_get_associated_drugs_by_target_ensemblID(
ensemblId='ENSG00000133703', size=20
)
# Returns sotorasib and other KRAS-targeting agents
# FDA approval
fda = tu.tools.FDA_get_indications_by_drug_name(drug_name='sotorasib', limit=3)
# Sotorasib (Lumakras): FDA-approved for KRAS G12C NSCLCExpected Report Summary
Clinical Actionability: HIGH (for NSCLC), MODERATE (other cancer types)
KRAS G12C is now targetable with covalent inhibitors. Sotorasib (Lumakras) and adagrasib (Krazati) are FDA-approved for KRAS G12C-mutated NSCLC [T1 evidence]. Clinical trials are expanding to other cancer types including colorectal and pancreatic cancer.
---
Example 4: TP53 R273H (Complex/VUS-like)
Input
Interpret TP53 R273HKey Verified Results
# Gene resolution
# TP53: ENSG00000141510
# Drug landscape
drugs = tu.tools.OpenTargets_get_associated_drugs_by_target_ensemblID(
ensemblId='ENSG00000141510', size=20
)
# TP53 has limited direct targeted therapies
# Mutation in LUAD
mutations = tu.tools.cBioPortal_get_mutations(study_id='luad_tcga', gene_list='TP53')
# TP53 is frequently mutated across cancer types; R273H is a hotspot contact mutantExpected Report Summary
Clinical Actionability: LOW
TP53 R273H is a well-known hotspot "contact" mutation that disrupts DNA binding. While TP53 is the most commonly mutated gene in cancer, direct therapeutic targeting remains limited. Experimental approaches include p53 reactivators (APR-246/eprenetapopt) in clinical trials [T2-T3 evidence]. TP53 mutations have broad prognostic significance as markers of aggressive disease.
---
Response Structure Quick Reference
| Tool | Returns |
|---|---|
MyGene_query_genes | dict: {hits: [{symbol, ensembl: {gene}, entrezgene}]} |
UniProt_search | dict: {results: [{accession, gene_names}]} |
UniProt_get_function_by_accession | list of strings (NOT dict) |
OpenTargets_get_target_id_description_by_name | dict: {data: {search: {hits: [{id, name}]}}} |
cBioPortal_get_mutations | dict: {status: 'success', data: [{proteinChange, ...}]} |
OpenTargets_get_associated_drugs_by_target_ensemblID | dict: {data: {target: {knownDrugs: {count, rows}}}} |
FDA_get_indications_by_drug_name | dict: {results: [{indications_and_usage}]} |
drugbank_get_drug_basic_info_by_drug_name_or_id | dict: {results: [{drug_name, drugbank_id, description}]} |
PubMed_search_articles | list of dicts: [{pmid, title, authors}] (NOT wrapped) |
search_clinical_trials | dict: {studies: [{NCT ID, brief_title, overall_status, phase}]} |
civic_search_genes | dict: {data: {genes: {nodes: [{id, name, entrezId}]}}} |
civic_get_variants_by_gene | dict: {data: {gene: {variants: {nodes: [{id, name}]}}}} |
ensembl_lookup_gene | dict: {status, data: {id, version, display_name}} (REQUIRES species param) |
Reactome_map_uniprot_to_pathways | pathway mappings |
Cancer Variant Interpretation - Input Parsing & Parameter Corrections
Input Parsing
Required: Gene symbol + variant notation Optional: Cancer type (improves specificity)
Accepted Input Formats
| Format | Example | How to Parse |
|---|---|---|
| Gene + amino acid change | EGFR L858R | gene=EGFR, variant=L858R |
| Gene + HGVS protein | BRAF p.V600E | gene=BRAF, variant=V600E |
| Gene + exon notation | EGFR exon 19 deletion | gene=EGFR, variant=exon 19 deletion |
| Gene + fusion | EML4-ALK fusion | gene=ALK, variant=EML4-ALK |
| Gene + amplification | HER2 amplification | gene=ERBB2, variant=amplification |
| Full query with cancer | "EGFR L858R in lung adenocarcinoma" | gene=EGFR, variant=L858R, cancer=lung adenocarcinoma |
Gene Symbol Normalization
Common aliases to resolve:
- HER2 -> ERBB2
- ALK -> ALK (but EML4-ALK is a fusion)
- PD-L1 -> CD274
- VEGF -> VEGFA
Tool Parameter Corrections (CRITICAL)
BEFORE calling ANY tool for the first time, verify its parameters.
| Tool | WRONG Parameter | CORRECT Parameter |
|---|---|---|
OpenTargets_get_associated_drugs_by_target_ensemblID | ensemblID | ensemblId (camelCase) |
OpenTargets_get_drug_chembId_by_generic_name | genericName | drugName |
OpenTargets_target_disease_evidence | ensemblID | ensemblId + efoId |
MyGene_query_genes | q | query |
search_clinical_trials | disease, biomarker | condition, query_term (required) |
civic_get_variants_by_gene | gene_symbol | gene_id (CIViC numeric ID) |
drugbank_* | any 3 params | ALL 4 required: query, case_sensitive, exact_match, limit |
ChEMBL_get_drug_mechanisms | chembl_id | drug_chembl_id__exact |
ensembl_lookup_gene | no species | species='homo_sapiens' is REQUIRED for Ensembl IDs |
Cancer Variant Interpretation - Quick Start Guide
What This Skill Does
Given a cancer gene + variant (e.g., "EGFR L858R"), this skill produces a comprehensive clinical interpretation report covering:
- Clinical evidence and significance
- FDA-approved therapies
- Mutation prevalence
- Resistance mechanisms
- Clinical trials
- Prognostic implications
Basic Usage
Simple Variant Query
Interpret EGFR L858R for lung adenocarcinomaResistance Investigation
Patient progressed on osimertinib. EGFR T790M detected. What are the options?Trial Matching
Find clinical trials for KRAS G12C mutation in any cancer typeTumor Board Preparation
Prepare molecular tumor board report: BRAF V600E in colorectal cancerStep-by-Step Workflow
Step 1: Gene Resolution
Resolve the gene to all required IDs:
# MyGene: Get Ensembl + Entrez IDs
gene_info = tu.tools.MyGene_query_genes(query='EGFR', species='human')
# -> hits[0]: symbol='EGFR', ensembl.gene='ENSG00000146648', entrezgene='1956'
# UniProt: Get protein accession
uniprot = tu.tools.UniProt_search(query='gene:EGFR', organism='human', limit=3)
# -> results[0].accession = 'P00533'
# OpenTargets: Get ensemblId + description
ot = tu.tools.OpenTargets_get_target_id_description_by_name(targetName='EGFR')
# -> data.search.hits[0].id = 'ENSG00000146648'Step 2: Clinical Evidence (CIViC)
# Get gene from CIViC (paginate to find)
genes = tu.tools.civic_search_genes(limit=100)
# Find gene by name in results
# Get all variants for the gene
variants = tu.tools.civic_get_variants_by_gene(gene_id=CIVIC_GENE_ID, limit=200)
# Find matching variant by name (e.g., 'V600E')Step 3: Mutation Prevalence (cBioPortal)
# Get mutations in a TCGA study
mutations = tu.tools.cBioPortal_get_mutations(study_id='luad_tcga', gene_list='EGFR')
# Returns: [{proteinChange: 'L858R', mutationType: 'Missense_Mutation', sampleId: '...'}]Step 4: Therapeutic Options
# OpenTargets: All drugs targeting the gene
drugs = tu.tools.OpenTargets_get_associated_drugs_by_target_ensemblID(
ensemblId='ENSG00000146648', size=50
)
# Returns: approved drugs, phase info, mechanism of action
# FDA label
fda = tu.tools.FDA_get_indications_by_drug_name(drug_name='osimertinib', limit=3)
# Returns: approved indications, dosing
# DrugBank details
db = tu.tools.drugbank_get_drug_basic_info_by_drug_name_or_id(
query='osimertinib', case_sensitive=False, exact_match=False, limit=3
)
# Returns: drug description, mechanismStep 5: Clinical Trials
trials = tu.tools.search_clinical_trials(
query_term='EGFR L858R',
condition='non-small cell lung cancer',
pageSize=20
)
# Returns: {studies: [{NCT ID, brief_title, overall_status, phase}]}Step 6: Resistance & Literature
# Resistance literature
resistance = tu.tools.PubMed_search_articles(
query='"EGFR" AND "osimertinib" AND resistance',
limit=10, include_abstract=True
)
# Pathway context
pathways = tu.tools.Reactome_map_uniprot_to_pathways(id='P00533')Common Pitfalls
| Issue | Solution |
|---|---|
| OpenTargets param error | Use ensemblId (camelCase), NOT ensemblID |
| CIViC gene not found | Gene search returns alphabetically, limited to 100 per page |
| DrugBank error | All 4 params required: query, case_sensitive, exact_match, limit |
| MyGene param error | Use query, NOT q |
| Clinical trials empty | Use broader query_term (e.g., "EGFR mutation" instead of "EGFR L858R") |
| ChEMBL mechanisms error | Use drug_chembl_id__exact, NOT chembl_id |
| GTEx empty results | Use versioned Ensembl ID (e.g., ENSG00000146648.12) |
| OpenTargets drug lookup | Use drugName parameter, NOT genericName |
cBioPortal Study IDs (Quick Reference)
| Cancer Type | Study ID |
|---|---|
| Lung Adenocarcinoma | luad_tcga |
| Breast Cancer | brca_tcga |
| Colorectal | coadread_tcga |
| Melanoma | skcm_tcga |
| Pancreatic | paad_tcga |
| Glioblastoma | gbm_tcga |
| Prostate | prad_tcga |
Output Format
The skill generates a markdown report file named {GENE}_{VARIANT}_cancer_variant_report.md with sections:
1. Executive Summary (1-2 sentences + actionability score) 2. Gene & Variant Overview 3. Clinical Variant Evidence 4. Mutation Prevalence 5. Therapeutic Options (prioritized by evidence tier) 6. Resistance Mechanisms 7. Clinical Trials 8. Prognostic Impact 9. Evidence Grading Summary 10. Data Sources 11. Completeness Checklist
Cancer Variant Interpretation Report Template
Report File Naming
{GENE}_{VARIANT}_cancer_variant_report.md
Examples:
EGFR_L858R_cancer_variant_report.md
BRAF_V600E_cancer_variant_report.md
KRAS_G12C_cancer_variant_report.mdReport Template
# Cancer Variant Interpretation Report: {GENE} {VARIANT}
**Date**: {date}
**Cancer Type**: {cancer_type or "Not specified"}
---
## Executive Summary
{1-2 sentences summarizing the key finding and top recommendation}
**Clinical Actionability**: {Score: HIGH / MODERATE / LOW / UNKNOWN}
---
## 1. Gene & Variant Overview
| Field | Value |
|-------|-------|
| Gene Symbol | {symbol} |
| Full Name | {name} |
| Ensembl ID | {ensembl_id} |
| UniProt | {uniprot_accession} |
| Entrez ID | {entrez_id} |
| Variant | {variant_notation} |
| Protein Function | {function_summary} |
## 2. Clinical Variant Evidence
### 2.1 CIViC Clinical Interpretations
| Evidence Type | Description | Level | Clinical Significance |
|---------------|-------------|-------|----------------------|
| ... | ... | ... | ... |
### 2.2 Evidence Summary
{Summary of clinical evidence from CIViC and other sources}
*Source: CIViC via civic_get_variants_by_gene, civic_get_variant*
## 3. Mutation Prevalence
### 3.1 Frequency Across Cancer Types (cBioPortal)
| Study | Cancer Type | Total Mutated | This Variant | Frequency |
|-------|-------------|---------------|--------------|-----------|
| ... | ... | ... | ... | ... |
### 3.2 Co-occurring Mutations
{Top co-occurring mutations from cBioPortal data}
*Source: cBioPortal via cBioPortal_get_mutations*
## 4. Therapeutic Options
### 4.1 FDA-Approved Therapies (T1 Evidence)
| Drug | Trade Name | Indication | Mechanism | Phase |
|------|-----------|------------|-----------|-------|
| ... | ... | ... | ... | ... |
### 4.2 Clinical Trial Drugs (T2-T3 Evidence)
| Drug | ChEMBL ID | Phase | Mechanism | Disease |
|------|-----------|-------|-----------|---------|
| ... | ... | ... | ... | ... |
### 4.3 Drug Details
{For each recommended drug: mechanism of action, FDA label info, dosing, warnings}
*Sources: OpenTargets, FDA, DrugBank, ChEMBL*
## 5. Resistance Mechanisms
### 5.1 Known Resistance Patterns
| Resistance Mutation | Drug Affected | Mechanism | Strategy to Overcome |
|--------------------|---------------|-----------|---------------------|
| ... | ... | ... | ... |
### 5.2 Bypass Pathways
{Pathway analysis showing potential bypass resistance routes}
*Sources: CIViC, PubMed, Reactome*
## 6. Clinical Trials
### 6.1 Actively Recruiting Trials
| NCT ID | Phase | Agent(s) | Status | Biomarker Required |
|--------|-------|----------|--------|-------------------|
| ... | ... | ... | ... | ... |
### 6.2 Trial Recommendations
{Specific trial recommendations based on patient's mutation and cancer type}
*Source: ClinicalTrials.gov via search_clinical_trials*
## 7. Prognostic Impact
### 7.1 Survival Associations
{Literature-based prognostic data}
### 7.2 Pathway Context
{Pathway analysis and biological context}
### 7.3 Expression Profile
{Tissue expression data for the gene}
*Sources: PubMed, Reactome, GTEx*
## 8. Evidence Grading Summary
| Finding | Evidence Tier | Source | Confidence |
|---------|--------------|--------|------------|
| ... | T1/T2/T3/T4 | ... | High/Moderate/Low |
---
## Data Sources Queried
| Source | Tool(s) Used | Data Retrieved |
|--------|-------------|----------------|
| MyGene | MyGene_query_genes | Gene IDs |
| UniProt | UniProt_search, UniProt_get_function_by_accession | Protein function |
| OpenTargets | OpenTargets_get_associated_drugs_by_target_ensemblID | Drug associations |
| CIViC | civic_search_genes, civic_get_variants_by_gene | Clinical evidence |
| cBioPortal | cBioPortal_get_mutations | Mutation prevalence |
| FDA | FDA_get_indications_by_drug_name | Drug labels |
| DrugBank | drugbank_get_drug_basic_info_by_drug_name_or_id | Drug info |
| ChEMBL | ChEMBL_get_drug_mechanisms | Drug mechanisms |
| ClinicalTrials.gov | search_clinical_trials | Active trials |
| PubMed | PubMed_search_articles | Literature evidence |
| Reactome | Reactome_map_uniprot_to_pathways | Pathway context |
| GTEx | GTEx_get_median_gene_expression | Expression data |
---
## Completeness Checklist
- [ ] Gene resolved to Ensembl, UniProt, and Entrez IDs
- [ ] Clinical variant evidence queried (CIViC or alternative)
- [ ] Mutation prevalence assessed (cBioPortal, at least 1 study)
- [ ] At least 1 therapeutic option identified with evidence tier, OR documented as "no targeted therapy available"
- [ ] FDA label information retrieved for recommended drugs
- [ ] Resistance mechanisms assessed (known patterns + literature search)
- [ ] At least 3 clinical trials listed, OR "no matching trials found"
- [ ] Prognostic literature searched
- [ ] Pathway context provided (Reactome)
- [ ] Executive summary is actionable (says what to DO)
- [ ] All recommendations have source citations
- [ ] Evidence tiers assigned to all findingsCancer Variant Interpretation - Evidence Grading & Scoring
Evidence Level Mapping (CIViC)
| CIViC Level | Tier | Meaning | Clinical Action |
|---|---|---|---|
| A | T1 (highest) | FDA-approved, guideline | Standard of care |
| B | T2 | Clinical evidence | Strong recommendation |
| C | T2 | Case study | Consider with caution |
| D | T3 | Preclinical | Research context only |
| E | T4 | Inferential | Computational evidence |
Treatment Prioritization
| Priority | Criteria | Tier |
|---|---|---|
| 1st Line | FDA-approved for exact indication + biomarker | T1 |
| 2nd Line | FDA-approved for different indication, same biomarker | T1-T2 |
| 3rd Line | Phase 3 clinical trial data | T2 |
| 4th Line | Phase 1-2 data, off-label with evidence | T3 |
| 5th Line | Preclinical or computational only | T4 |
Evidence Grading System
| Tier | Symbol | Criteria | Examples |
|---|---|---|---|
| T1 | [T1] | FDA-approved therapy, Level A CIViC evidence, phase 3 trial | Osimertinib for EGFR T790M |
| T2 | [T2] | Phase 2/3 clinical data, Level B CIViC evidence | Combination trial data |
| T3 | [T3] | Preclinical data, Level D CIViC, case reports | Novel mechanisms, in vitro |
| T4 | [T4] | Computational prediction, pathway inference | Docking, pathway analysis |
Clinical Actionability Scoring
| Score | Criteria |
|---|---|
| HIGH | FDA-approved targeted therapy exists for this exact mutation + cancer type |
| MODERATE | Approved therapy exists for different cancer type with same mutation, OR phase 2-3 trial data |
| LOW | Only preclinical evidence or pathway-based rationale |
| UNKNOWN | Insufficient data to assess actionability |
Fallback Chains
| Primary Tool | Fallback | Use When |
|---|---|---|
| CIViC variant lookup | PubMed literature search | Gene not found in CIViC (search doesn't filter) |
| OpenTargets drugs | ChEMBL drug search | No OpenTargets drug hits |
| FDA indications | DrugBank drug info | Drug not in FDA database |
| cBioPortal TCGA study | cBioPortal pan-cancer | Specific cancer study not available |
| GTEx expression | Ensembl gene lookup | GTEx returns empty |
| Reactome pathways | UniProt function | Pathway mapping fails |
Quantified Minimums
| Section | Requirement |
|---|---|
| Gene IDs | At least Ensembl + UniProt resolved |
| Clinical evidence | CIViC queried + PubMed literature search |
| Mutation prevalence | At least 1 cBioPortal study |
| Therapeutic options | All approved drugs listed (OpenTargets) + FDA label for top drugs |
| Resistance | Literature search performed + known patterns documented |
| Clinical trials | At least 1 search query executed |
| Prognostic impact | PubMed literature search performed |
| Pathway context | Reactome pathway mapping attempted |
Common Use Cases
Use Case 1: Oncologist Evaluating Treatment Options
Input: "EGFR L858R in lung adenocarcinoma"
Expected Output: Report showing osimertinib as 1st-line [T1], with FDA label details, resistance pattern (T790M), clinical trials for combination therapies, and prognostic context.
Use Case 2: Molecular Tumor Board Preparation
Input: "BRAF V600E, colorectal cancer"
Expected Output: Report noting that BRAF V600E is actionable in melanoma but requires combination therapy in CRC (encorafenib + cetuximab), with different resistance patterns than melanoma.
Use Case 3: Clinical Trial Matching
Input: "KRAS G12C, any cancer type"
Expected Output: Report with sotorasib/adagrasib as approved options [T1], comprehensive trial listing for KRAS G12C inhibitors, resistance patterns (Y96D, etc.), and mutation prevalence across cancer types.
Use Case 4: Resistance Mechanism Investigation
Input: "EGFR T790M after osimertinib failure"
Expected Output: Report focused on C797S resistance mutation, available 4th-generation TKI trials, amivantamab/lazertinib combinations, and bypass pathway mechanisms (MET amplification, HER2 activation).
Use Case 5: VUS Interpretation
Input: "PIK3CA E545K"
Expected Output: Report showing this is a known hotspot oncogenic mutation (not a VUS), with alpelisib as FDA-approved therapy for HR+/HER2- breast cancer, and prevalence data across cancer types.
#!/usr/bin/env python3
"""
Comprehensive Test Suite for tooluniverse-cancer-variant-interpretation skill.
Tests all 8 phases of the cancer variant interpretation workflow
using real cancer variants: EGFR L858R, BRAF V600E, KRAS G12C.
"""
import json
import sys
import time
from collections import Counter
# Track results
test_results = []
total_start = time.time()
def record_result(name, passed, details=""):
status = "PASS" if passed else "FAIL"
test_results.append({"name": name, "passed": passed, "details": details})
print(f" [{status}] {name}")
if details and not passed:
print(f" {details}")
def run_tests():
print("=" * 70)
print("Cancer Variant Interpretation Skill - Test Suite")
print("=" * 70)
# Load ToolUniverse
print("\nLoading ToolUniverse...")
from tooluniverse import ToolUniverse
tu = ToolUniverse()
tu.load_tools()
print(f"Loaded {len(tu.all_tool_dict)} tools")
# ========================================================================
# TEST 1: Gene Resolution (Phase 1)
# ========================================================================
print("\n--- Phase 1: Gene Resolution ---")
# 1a: MyGene EGFR
try:
result = tu.tools.MyGene_query_genes(query='EGFR', species='human')
hits = result.get('hits', [])
egfr_hit = next((h for h in hits if h.get('symbol') == 'EGFR'), None)
has_ensembl = egfr_hit and egfr_hit.get('ensembl', {}).get('gene') == 'ENSG00000146648'
has_entrez = egfr_hit and str(egfr_hit.get('entrezgene')) == '1956'
record_result("1a: MyGene EGFR resolution", has_ensembl and has_entrez,
f"ensembl={'OK' if has_ensembl else 'MISSING'}, entrez={'OK' if has_entrez else 'MISSING'}")
except Exception as e:
record_result("1a: MyGene EGFR resolution", False, str(e))
# 1b: MyGene BRAF
try:
result = tu.tools.MyGene_query_genes(query='BRAF', species='human')
hits = result.get('hits', [])
braf_hit = next((h for h in hits if h.get('symbol') == 'BRAF'), None)
record_result("1b: MyGene BRAF resolution", braf_hit is not None,
f"Found BRAF: {braf_hit.get('ensembl', {}).get('gene') if braf_hit else 'NOT FOUND'}")
except Exception as e:
record_result("1b: MyGene BRAF resolution", False, str(e))
# 1c: UniProt search for EGFR
try:
result = tu.tools.UniProt_search(query='gene:EGFR', organism='human', limit=3)
results = result.get('results', [])
has_p00533 = any(r.get('accession') == 'P00533' for r in results)
record_result("1c: UniProt EGFR lookup", has_p00533,
f"P00533 found: {has_p00533}, total results: {len(results)}")
except Exception as e:
record_result("1c: UniProt EGFR lookup", False, str(e))
# 1d: OpenTargets target resolution
try:
result = tu.tools.OpenTargets_get_target_id_description_by_name(targetName='EGFR')
hits = result.get('data', {}).get('search', {}).get('hits', [])
egfr_ot = next((h for h in hits if h.get('name') == 'EGFR'), None)
correct_id = egfr_ot and egfr_ot.get('id') == 'ENSG00000146648'
record_result("1d: OpenTargets EGFR resolution", correct_id,
f"ID: {egfr_ot.get('id') if egfr_ot else 'NOT FOUND'}")
except Exception as e:
record_result("1d: OpenTargets EGFR resolution", False, str(e))
# 1e: Cancer type EFO resolution
try:
result = tu.tools.OpenTargets_get_disease_id_description_by_name(diseaseName='lung adenocarcinoma')
hits = result.get('data', {}).get('search', {}).get('hits', [])
has_hits = len(hits) > 0
record_result("1e: Cancer type EFO resolution", has_hits,
f"Hits: {len(hits)}, top: {hits[0].get('name') if hits else 'none'}")
except Exception as e:
record_result("1e: Cancer type EFO resolution", False, str(e))
# 1f: UniProt function (returns list of strings, not dict)
try:
result = tu.tools.UniProt_get_function_by_accession(accession='P00533')
has_data = result is not None and len(str(result)) > 10
# UniProt function returns list of function description strings
record_result("1f: UniProt function retrieval", has_data,
f"Type: {type(result).__name__}, content: {str(result)[:100]}...")
except Exception as e:
record_result("1f: UniProt function retrieval", False, str(e))
# ========================================================================
# TEST 2: Clinical Variant Evidence - CIViC (Phase 2)
# ========================================================================
print("\n--- Phase 2: Clinical Variant Evidence (CIViC) ---")
# 2a: CIViC gene search
try:
result = tu.tools.civic_search_genes(limit=100)
genes = result.get('data', {}).get('genes', {}).get('nodes', [])
braf_civic = next((g for g in genes if g.get('name') == 'BRAF'), None)
record_result("2a: CIViC gene search", braf_civic is not None,
f"BRAF found: gene_id={braf_civic.get('id') if braf_civic else 'NOT FOUND'}, total genes: {len(genes)}")
except Exception as e:
record_result("2a: CIViC gene search", False, str(e))
# 2b: CIViC variants for BRAF (gene_id=5)
try:
result = tu.tools.civic_get_variants_by_gene(gene_id=5, limit=200)
variants = result.get('data', {}).get('gene', {}).get('variants', {}).get('nodes', [])
v600e = next((v for v in variants if v.get('name') == 'V600E'), None)
record_result("2b: CIViC BRAF V600E variant", v600e is not None,
f"V600E found: id={v600e.get('id') if v600e else 'NOT FOUND'}, total variants: {len(variants)}")
except Exception as e:
record_result("2b: CIViC BRAF V600E variant", False, str(e))
# 2c: CIViC variant details
if v600e:
try:
result = tu.tools.civic_get_variant(variant_id=v600e['id'])
variant_data = result.get('data', {}).get('variant', {})
has_data = variant_data.get('id') is not None
record_result("2c: CIViC variant details", has_data,
f"Variant name: {variant_data.get('name')}")
except Exception as e:
record_result("2c: CIViC variant details", False, str(e))
else:
record_result("2c: CIViC variant details", False, "V600E not found in 2b")
# 2d: CIViC molecular profile
try:
result = tu.tools.civic_get_molecular_profile(molecular_profile_id=12)
mp = result.get('data', {}).get('molecularProfile', {})
has_name = mp.get('name') == 'BRAF V600E'
record_result("2d: CIViC molecular profile (BRAF V600E)", has_name,
f"Name: {mp.get('name')}")
except Exception as e:
record_result("2d: CIViC molecular profile (BRAF V600E)", False, str(e))
# ========================================================================
# TEST 3: Mutation Prevalence - cBioPortal (Phase 3)
# ========================================================================
print("\n--- Phase 3: Mutation Prevalence (cBioPortal) ---")
# 3a: cBioPortal cancer studies
try:
result = tu.tools.cBioPortal_get_cancer_studies(limit=20)
studies = result if isinstance(result, list) else result.get('data', [])
has_studies = len(studies) > 0
record_result("3a: cBioPortal cancer studies", has_studies,
f"Studies found: {len(studies)}")
except Exception as e:
record_result("3a: cBioPortal cancer studies", False, str(e))
# 3b: cBioPortal EGFR mutations in lung cancer
# Response can be: list directly OR {status: 'success', data: [...]}
try:
result = tu.tools.cBioPortal_get_mutations(study_id='luad_tcga', gene_list='EGFR')
if isinstance(result, list):
mutations = result
elif isinstance(result, dict):
mutations = result.get('data', []) if result.get('status') == 'success' else []
else:
mutations = []
has_mutations = len(mutations) > 0
l858r_count = sum(1 for m in mutations if 'L858R' in str(m.get('proteinChange', '')))
record_result("3b: cBioPortal EGFR mutations (LUAD)", has_mutations,
f"Total mutations: {len(mutations)}, L858R count: {l858r_count}")
except Exception as e:
record_result("3b: cBioPortal EGFR mutations (LUAD)", False, str(e))
# 3c: cBioPortal BRAF mutations in melanoma
try:
result = tu.tools.cBioPortal_get_mutations(study_id='skcm_tcga', gene_list='BRAF')
if isinstance(result, list):
mutations = result
elif isinstance(result, dict):
mutations = result.get('data', []) if result.get('status') == 'success' else []
else:
mutations = []
has_mutations = len(mutations) > 0
v600e_count = sum(1 for m in mutations if 'V600E' in str(m.get('proteinChange', '')))
record_result("3c: cBioPortal BRAF mutations (melanoma)", has_mutations,
f"Total mutations: {len(mutations)}, V600E count: {v600e_count}")
except Exception as e:
record_result("3c: cBioPortal BRAF mutations (melanoma)", False, str(e))
# 3d: Mutation distribution analysis
if mutations:
try:
protein_changes = [m.get('proteinChange', '') for m in mutations if m.get('proteinChange')]
counts = Counter(protein_changes)
top_5 = counts.most_common(5)
record_result("3d: Mutation distribution analysis", len(top_5) > 0,
f"Top mutations: {top_5[:3]}")
except Exception as e:
record_result("3d: Mutation distribution analysis", False, str(e))
# ========================================================================
# TEST 4: Therapeutic Associations (Phase 4)
# ========================================================================
print("\n--- Phase 4: Therapeutic Associations ---")
# 4a: OpenTargets drugs for EGFR
try:
result = tu.tools.OpenTargets_get_associated_drugs_by_target_ensemblID(
ensemblId='ENSG00000146648', size=20
)
drugs = result.get('data', {}).get('target', {}).get('knownDrugs', {})
total = drugs.get('count', 0)
rows = drugs.get('rows', [])
approved = [r for r in rows if r.get('drug', {}).get('isApproved')]
has_osimertinib = any('OSIMERTINIB' in str(r.get('drug', {}).get('name', '')).upper() for r in rows)
record_result("4a: OpenTargets EGFR drugs", total > 0 and has_osimertinib,
f"Total: {total}, approved: {len(approved)}, osimertinib found: {has_osimertinib}")
except Exception as e:
record_result("4a: OpenTargets EGFR drugs", False, str(e))
# 4b: FDA indications for osimertinib
try:
result = tu.tools.FDA_get_indications_by_drug_name(drug_name='osimertinib', limit=3)
fda_results = result.get('results', [])
has_fda = len(fda_results) > 0
has_indication = any('EGFR' in str(r.get('indications_and_usage', '')) for r in fda_results)
record_result("4b: FDA osimertinib indications", has_fda and has_indication,
f"FDA entries: {len(fda_results)}, mentions EGFR: {has_indication}")
except Exception as e:
record_result("4b: FDA osimertinib indications", False, str(e))
# 4c: DrugBank osimertinib info
try:
result = tu.tools.drugbank_get_drug_basic_info_by_drug_name_or_id(
query='osimertinib', case_sensitive=False, exact_match=False, limit=3
)
db_results = result.get('results', [])
has_db = len(db_results) > 0
has_db09330 = any('DB09330' in str(r.get('drugbank_id', '')) for r in db_results)
record_result("4c: DrugBank osimertinib", has_db and has_db09330,
f"Results: {len(db_results)}, DB09330 found: {has_db09330}")
except Exception as e:
record_result("4c: DrugBank osimertinib", False, str(e))
# 4d: OpenTargets drug name to ChEMBL ID
try:
result = tu.tools.OpenTargets_get_drug_chembId_by_generic_name(drugName='osimertinib')
hits = result.get('data', {}).get('search', {}).get('hits', [])
has_chembl = any('CHEMBL' in str(h.get('id', '')) for h in hits)
record_result("4d: OpenTargets drug ChEMBL resolution", has_chembl,
f"Hits: {len(hits)}, ChEMBL: {hits[0].get('id') if hits else 'none'}")
except Exception as e:
record_result("4d: OpenTargets drug ChEMBL resolution", False, str(e))
# 4e: FDA mechanism of action
try:
result = tu.tools.FDA_get_mechanism_of_action_by_drug_name(drug_name='osimertinib', limit=3)
fda_results = result.get('results', [])
has_moa = len(fda_results) > 0
record_result("4e: FDA mechanism of action", has_moa,
f"MOA entries: {len(fda_results)}")
except Exception as e:
record_result("4e: FDA mechanism of action", False, str(e))
# 4f: OpenTargets BRAF drugs (different target)
try:
result = tu.tools.OpenTargets_get_associated_drugs_by_target_ensemblID(
ensemblId='ENSG00000157764', size=20
)
drugs = result.get('data', {}).get('target', {}).get('knownDrugs', {})
total = drugs.get('count', 0)
rows = drugs.get('rows', [])
has_vemurafenib = any('VEMURAFENIB' in str(r.get('drug', {}).get('name', '')).upper() for r in rows)
has_dabrafenib = any('DABRAFENIB' in str(r.get('drug', {}).get('name', '')).upper() for r in rows)
record_result("4f: OpenTargets BRAF drugs", total > 0,
f"Total: {total}, vemurafenib: {has_vemurafenib}, dabrafenib: {has_dabrafenib}")
except Exception as e:
record_result("4f: OpenTargets BRAF drugs", False, str(e))
# ========================================================================
# TEST 5: Resistance Mechanisms (Phase 5)
# ========================================================================
print("\n--- Phase 5: Resistance Mechanisms ---")
# 5a: PubMed resistance literature (returns list directly)
try:
result = tu.tools.PubMed_search_articles(
query='"EGFR" AND "osimertinib" AND resistance AND mechanism',
limit=10, include_abstract=True
)
# PubMed returns a plain list of article dicts
articles = result if isinstance(result, list) else result.get('articles', []) if isinstance(result, dict) else []
has_articles = len(articles) > 0
record_result("5a: PubMed resistance literature", has_articles,
f"Articles: {len(articles)}")
except Exception as e:
record_result("5a: PubMed resistance literature", False, str(e))
# 5b: Reactome pathway context
try:
result = tu.tools.Reactome_map_uniprot_to_pathways(id='P00533')
has_pathways = result is not None and len(str(result)) > 10
record_result("5b: Reactome EGFR pathways", has_pathways,
f"Response length: {len(str(result)[:200])}")
except Exception as e:
record_result("5b: Reactome EGFR pathways", False, str(e))
# ========================================================================
# TEST 6: Clinical Trials (Phase 6)
# ========================================================================
print("\n--- Phase 6: Clinical Trials ---")
# 6a: Clinical trials for EGFR mutation
try:
result = tu.tools.search_clinical_trials(
query_term='EGFR L858R mutation',
condition='non-small cell lung cancer',
pageSize=10
)
studies = result.get('studies', [])
has_trials = len(studies) > 0
recruiting = [s for s in studies if s.get('overall_status') == 'RECRUITING']
record_result("6a: Clinical trials EGFR L858R NSCLC", has_trials,
f"Trials: {len(studies)}, recruiting: {len(recruiting)}")
except Exception as e:
record_result("6a: Clinical trials EGFR L858R NSCLC", False, str(e))
# 6b: Clinical trials for KRAS G12C
try:
result = tu.tools.search_clinical_trials(
query_term='KRAS G12C',
condition='cancer',
pageSize=10
)
studies = result.get('studies', [])
has_trials = len(studies) > 0
record_result("6b: Clinical trials KRAS G12C", has_trials,
f"Trials: {len(studies)}")
except Exception as e:
record_result("6b: Clinical trials KRAS G12C", False, str(e))
# 6c: Clinical trials for BRAF V600E
try:
result = tu.tools.search_clinical_trials(
query_term='BRAF V600E',
condition='melanoma',
pageSize=10
)
studies = result.get('studies', [])
has_trials = len(studies) > 0
record_result("6c: Clinical trials BRAF V600E melanoma", has_trials,
f"Trials: {len(studies)}")
except Exception as e:
record_result("6c: Clinical trials BRAF V600E melanoma", False, str(e))
# ========================================================================
# TEST 7: Prognostic & Pathway Context (Phase 7)
# ========================================================================
print("\n--- Phase 7: Prognostic & Pathway Context ---")
# 7a: PubMed prognostic literature (returns list directly)
try:
result = tu.tools.PubMed_search_articles(
query='"EGFR" "L858R" prognosis survival lung cancer',
limit=5, include_abstract=True
)
articles = result if isinstance(result, list) else result.get('articles', []) if isinstance(result, dict) else []
has_articles = len(articles) > 0
record_result("7a: PubMed prognostic literature", has_articles,
f"Articles: {len(articles)}")
except Exception as e:
record_result("7a: PubMed prognostic literature", False, str(e))
# 7b: UniProt disease variants
try:
result = tu.tools.UniProt_get_disease_variants_by_accession(accession='P00533')
has_variants = result is not None and len(str(result)) > 10
record_result("7b: UniProt EGFR disease variants", has_variants,
f"Response type: {type(result).__name__}")
except Exception as e:
record_result("7b: UniProt EGFR disease variants", False, str(e))
# 7c: Ensembl gene lookup (requires species parameter)
try:
result = tu.tools.ensembl_lookup_gene(gene_id='ENSG00000146648', species='homo_sapiens')
# Response: {status: 'success', data: {id, version, display_name, ...}}
data = result.get('data', result) if isinstance(result, dict) else {}
version = data.get('version')
has_version = version is not None
record_result("7c: Ensembl gene version lookup", has_version,
f"Version: {version}, display_name: {data.get('display_name', 'N/A')}")
except Exception as e:
record_result("7c: Ensembl gene version lookup", False, str(e))
# ========================================================================
# TEST 8: Cross-variant tests (KRAS G12C)
# ========================================================================
print("\n--- Phase 8: Cross-variant validation (KRAS G12C) ---")
# 8a: KRAS gene resolution
try:
result = tu.tools.MyGene_query_genes(query='KRAS', species='human')
hits = result.get('hits', [])
kras_hit = next((h for h in hits if h.get('symbol') == 'KRAS'), None)
kras_ensembl = kras_hit.get('ensembl', {}).get('gene') if kras_hit else None
record_result("8a: KRAS gene resolution", kras_ensembl is not None,
f"Ensembl: {kras_ensembl}")
except Exception as e:
record_result("8a: KRAS gene resolution", False, str(e))
# 8b: KRAS drugs from OpenTargets
try:
result = tu.tools.OpenTargets_get_associated_drugs_by_target_ensemblID(
ensemblId='ENSG00000133703', size=20
)
drugs = result.get('data', {}).get('target', {}).get('knownDrugs', {})
total = drugs.get('count', 0)
rows = drugs.get('rows', [])
has_sotorasib = any('SOTORASIB' in str(r.get('drug', {}).get('name', '')).upper() for r in rows)
record_result("8b: KRAS targeted drugs", total > 0,
f"Total: {total}, sotorasib found: {has_sotorasib}")
except Exception as e:
record_result("8b: KRAS targeted drugs", False, str(e))
# 8c: KRAS mutations in pancreatic cancer
try:
result = tu.tools.cBioPortal_get_mutations(study_id='paad_tcga', gene_list='KRAS')
if isinstance(result, list):
mutations = result
elif isinstance(result, dict):
mutations = result.get('data', []) if result.get('status') == 'success' else []
else:
mutations = []
g12_variants = [m for m in mutations if 'G12' in str(m.get('proteinChange', ''))]
record_result("8c: KRAS mutations in pancreatic cancer", len(mutations) > 0,
f"Total: {len(mutations)}, G12 variants: {len(g12_variants)}")
except Exception as e:
record_result("8c: KRAS mutations in pancreatic cancer", False, str(e))
# 8d: FDA sotorasib info
try:
result = tu.tools.FDA_get_indications_by_drug_name(drug_name='sotorasib', limit=3)
fda_results = result.get('results', [])
has_kras = any('KRAS' in str(r.get('indications_and_usage', '')) for r in fda_results)
record_result("8d: FDA sotorasib indications", len(fda_results) > 0,
f"FDA entries: {len(fda_results)}, mentions KRAS: {has_kras}")
except Exception as e:
record_result("8d: FDA sotorasib indications", False, str(e))
# ========================================================================
# TEST 9: TP53 R273H (VUS-like scenario)
# ========================================================================
print("\n--- Phase 9: TP53 R273H (complex variant) ---")
# 9a: TP53 gene resolution
try:
result = tu.tools.MyGene_query_genes(query='TP53', species='human')
hits = result.get('hits', [])
tp53_hit = next((h for h in hits if h.get('symbol') == 'TP53'), None)
tp53_ensembl = tp53_hit.get('ensembl', {}).get('gene') if tp53_hit else None
record_result("9a: TP53 gene resolution", tp53_ensembl is not None,
f"Ensembl: {tp53_ensembl}")
except Exception as e:
record_result("9a: TP53 gene resolution", False, str(e))
# 9b: TP53 drugs (should have fewer targeted therapies)
try:
result = tu.tools.OpenTargets_get_associated_drugs_by_target_ensemblID(
ensemblId='ENSG00000141510', size=20
)
drugs = result.get('data', {}).get('target', {}).get('knownDrugs', {})
total = drugs.get('count', 0)
record_result("9b: TP53 drug landscape", True, # Pass regardless - TP53 has limited targeted options
f"Total drug entries: {total} (TP53 has limited direct targets)")
except Exception as e:
record_result("9b: TP53 drug landscape", False, str(e))
# 9c: TP53 mutations across cancer types
try:
result = tu.tools.cBioPortal_get_mutations(study_id='luad_tcga', gene_list='TP53')
if isinstance(result, list):
mutations = result
elif isinstance(result, dict):
mutations = result.get('data', []) if result.get('status') == 'success' else []
else:
mutations = []
r273h_count = sum(1 for m in mutations if 'R273H' in str(m.get('proteinChange', '')))
record_result("9c: TP53 R273H in LUAD", len(mutations) > 0,
f"Total TP53 mutations: {len(mutations)}, R273H: {r273h_count}")
except Exception as e:
record_result("9c: TP53 R273H in LUAD", False, str(e))
# ========================================================================
# SUMMARY
# ========================================================================
elapsed = time.time() - total_start
passed = sum(1 for r in test_results if r['passed'])
failed = sum(1 for r in test_results if not r['passed'])
total = len(test_results)
print("\n" + "=" * 70)
print(f"TEST SUMMARY: {passed}/{total} passed, {failed} failed")
print(f"Time elapsed: {elapsed:.1f}s")
print("=" * 70)
if failed > 0:
print("\nFailed tests:")
for r in test_results:
if not r['passed']:
print(f" FAIL: {r['name']}")
if r['details']:
print(f" {r['details']}")
return passed, total
if __name__ == '__main__':
passed, total = run_tests()
sys.exit(0 if passed == total else 1)
Cancer Variant Interpretation - Tools Reference
Verified tool parameters and response structures for all tools used in this skill.
Gene Resolution Tools
MyGene_query_genes
Purpose: Resolve gene symbol to Ensembl, Entrez IDs Parameters:
query(string, REQUIRED): Gene symbol, name, or ID (e.g., 'EGFR')species(string, default='human'): Species filterfields(string): Comma-separated fields to return
Response: {took, total, max_score, hits: [{_id, _score, ensembl: {gene}, entrezgene, name, symbol}]}
Example:
result = tu.tools.MyGene_query_genes(query='EGFR', species='human')
# hits[0] = {symbol: 'EGFR', ensembl: {gene: 'ENSG00000146648'}, entrezgene: '1956', name: 'epidermal growth factor receptor'}UniProt_search
Purpose: Find protein accession Parameters:
query(string, REQUIRED): e.g., 'gene:EGFR'organism(string): e.g., 'human'limit(integer)
Response: {total_results, returned, results: [{accession, id, protein_name, gene_names, organism, length}]}
UniProt_get_function_by_accession
Purpose: Get protein function description Parameters: accession (string, REQUIRED): e.g., 'P00533'
Response: Returns a list of strings (NOT a dict). Each string is a function description paragraph.
# Example: ['Receptor tyrosine kinase binding ligands of the EGF family...', ...]UniProt_get_disease_variants_by_accession
Purpose: Get known disease-associated variants Parameters: accession (string, REQUIRED)
OpenTargets_get_target_id_description_by_name
Purpose: Resolve gene name to Ensembl ID in OpenTargets Parameters: targetName (string, REQUIRED)
Response: {data: {search: {hits: [{id (ensemblId), name, description}]}}}
OpenTargets_get_disease_id_description_by_name
Purpose: Resolve disease/cancer type to EFO ID Parameters: diseaseName (string, REQUIRED)
Response: {data: {search: {hits: [{id (efoId), name, description}]}}}
ensembl_lookup_gene
Purpose: Get gene details including version number Parameters:
gene_id(string, REQUIRED): Ensembl ID or gene symbolspecies(string, REQUIRED for Ensembl IDs): e.g., 'homo_sapiens' -- will error without this!
Response: {status: 'success', data: {id, version, display_name, species, biotype, start, end, seq_region_name, strand, canonical_transcript, assembly_name}}
---
CIViC Clinical Evidence Tools
civic_search_genes
Purpose: List genes in CIViC database Parameters:
query(string): Filter query (NOTE: does NOT filter in GraphQL, returns all genes alphabetically)limit(integer, default=10, max=100): Number to return
Response: {data: {genes: {nodes: [{id, name, description, entrezId}]}}}
LIMITATION: Returns genes alphabetically, max 100 per call. No server-side filtering. Genes beyond alphabetical position 100 (E-Z) require multiple paginated calls or known CIViC gene IDs.
civic_get_variants_by_gene
Purpose: Get all variants for a gene in CIViC Parameters:
gene_id(integer, REQUIRED): CIViC gene ID (NOT Entrez ID)limit(integer, default=50): Max variants to return
Response: {data: {gene: {variants: {nodes: [{id, name}]}}}}
civic_get_variant
Purpose: Get variant details Parameters: variant_id (integer, REQUIRED)
Response: {data: {variant: {id, name}}}
civic_get_molecular_profile
Purpose: Get molecular profile details Parameters: molecular_profile_id (integer, REQUIRED)
civic_search_evidence_items
Purpose: List evidence items Parameters: limit (integer, default=20)
Response: {data: {evidenceItems: {nodes: [{id, description, evidenceLevel, evidenceType}]}}}
civic_search_assertions
Purpose: List assertions Parameters: limit (integer, default=20)
civic_search_therapies
Purpose: List therapies Parameters: limit (integer, default=20)
---
cBioPortal Mutation Prevalence Tools
cBioPortal_get_mutations
Purpose: Get mutation data for genes in a study Parameters:
study_id(string): Cancer study ID (e.g., 'luad_tcga')gene_list(string): Comma-separated gene symbols (e.g., 'EGFR,KRAS')
Response: {status: 'success', data: [{proteinChange, mutationType, sampleId, entrezGeneId, studyId, mutationStatus, chr, startPosition, endPosition, ...}]}
IMPORTANT: Extract mutations via result.get('data', []), NOT treating result as a list directly.
cBioPortal_get_cancer_studies
Purpose: List available cancer studies Parameters: limit (integer, default=20)
Response: Array of [{studyId, name, description, cancerTypeId, ...}]
cBioPortal_get_molecular_profiles
Purpose: Get molecular profiles for a study Parameters: study_id (string, REQUIRED)
cBioPortal_get_gene_info
Purpose: Get gene info by Entrez ID Parameters: entrez_gene_id (integer, REQUIRED)
cBioPortal_get_samples
Purpose: Get samples from a study Parameters: study_id (string, REQUIRED)
---
Drug Information Tools
OpenTargets_get_associated_drugs_by_target_ensemblID
Purpose: Get ALL drugs targeting a gene (approved + clinical trials) Parameters:
ensemblId(string, REQUIRED): NOTE camelCasesize(integer): Number of drug entries
Response: {data: {target: {id, approvedSymbol, knownDrugs: {count, rows: [{drug: {id, name, tradeNames, maximumClinicalTrialPhase, isApproved, hasBeenWithdrawn}, phase, mechanismOfAction, disease: {id, name}}]}}}}
OpenTargets_get_drug_chembId_by_generic_name
Purpose: Resolve drug name to ChEMBL ID Parameters: drugName (string, REQUIRED)
Response: {data: {search: {hits: [{id (ChEMBL ID), name, description}]}}}
OpenTargets_get_drug_mechanisms_of_action_by_chemblId
Purpose: Drug mechanism of action Parameters: chemblId (string, REQUIRED)
OpenTargets_get_drug_indications_by_chemblId
Purpose: Drug indications Parameters: chemblId (string, REQUIRED)
OpenTargets_get_drug_adverse_events_by_chemblId
Purpose: Drug adverse events Parameters: chemblId (string, REQUIRED)
OpenTargets_get_associated_drugs_by_disease_efoId
Purpose: Get drugs for a specific disease Parameters: efoId (string, REQUIRED), size (integer, REQUIRED)
FDA_get_indications_by_drug_name
Purpose: FDA-approved indications Parameters: drug_name (string), limit (integer)
Response: {meta: {skip, limit, total}, results: [{openfda.brand_name, openfda.generic_name, indications_and_usage}]}
FDA_get_mechanism_of_action_by_drug_name
Purpose: FDA mechanism of action Parameters: drug_name (string), limit (integer)
FDA_get_boxed_warning_info_by_drug_name
Purpose: FDA black box warnings Parameters: drug_name (string), limit (integer)
FDA_get_clinical_studies_info_by_drug_name
Purpose: FDA clinical study data Parameters: drug_name (string), limit (integer)
drugbank_get_drug_basic_info_by_drug_name_or_id
Purpose: Drug info from DrugBank Parameters (ALL REQUIRED):
query(string): Drug name or DrugBank IDcase_sensitive(boolean): Use Falseexact_match(boolean): Use Falselimit(integer): e.g., 3
Response: {query, total_matches, total_returned_results, results: [{drug_name, drugbank_id, description, ...}]}
drugbank_get_pharmacology_by_drug_name_or_drugbank_id
Purpose: Pharmacology details Parameters (ALL REQUIRED): query, case_sensitive, exact_match, limit
drugbank_get_targets_by_drug_name_or_drugbank_id
Purpose: Drug targets Parameters (ALL REQUIRED): query, case_sensitive, exact_match, limit
ChEMBL_get_drug_mechanisms
Purpose: Drug mechanisms from ChEMBL Parameters: drug_chembl_id__exact (string, REQUIRED), limit, offset
ChEMBL_search_drugs
Purpose: Search drugs Parameters: pref_name__contains (string), max_phase (integer), limit
---
Clinical Trial Tools
search_clinical_trials
Purpose: Search ClinicalTrials.gov Parameters:
query_term(string, REQUIRED): Search querycondition(string): Disease/conditionintervention(string): Drug/interventionpageSize(integer): Max results (default 10, max 1000)
Response: {studies: [{NCT ID, brief_title, brief_summary, overall_status, condition, phase}], nextPageToken, total_count}
---
Literature & Pathway Tools
PubMed_search_articles
Purpose: Search PubMed literature Parameters:
query(string, REQUIRED): PubMed search querylimit(integer, default=10, max 200)include_abstract(boolean, default=False)
Response: Returns a plain list of article dicts (NOT wrapped in {articles: [...]}):
# [{pmid, title, authors, journal, pub_date, pub_year, doi, pmcid, article_type, url, abstract, ...}]Reactome_map_uniprot_to_pathways
Purpose: Map protein to biological pathways Parameters: id (string, REQUIRED): UniProt accession (e.g., 'P00533')
GTEx_get_median_gene_expression
Purpose: Tissue expression data Parameters:
gencode_id(string, REQUIRED): Versioned Ensembl ID (e.g., 'ENSG00000146648.12')operation(string): Use 'median'
OpenTargets_target_disease_evidence
Purpose: Evidence for target-disease association Parameters: efoId (string, REQUIRED), ensemblId (string, REQUIRED)
OpenTargets_get_publications_by_target_ensemblID
Purpose: Publications about target Parameters: ensemblId (string, REQUIRED)
---
Known CIViC Gene IDs (Common Cancer Genes)
These are pre-verified CIViC gene IDs to bypass the search limitation:
| Gene | CIViC Gene ID | Entrez ID |
|---|---|---|
| ABL1 | 4 | 25 |
| ALK | 1 | 238 |
| BRAF | 5 | 673 |
Note: For genes not in this table, use civic_search_genes(limit=100) and search results client-side. If gene starts with a letter beyond 'C', it may not be in the first 100 results.
Related skills
How it compares
Use tooluniverse-cancer-variant-interpretation for cancer-type-specific somatic variant actionability; use general biomedical search skills for non-oncology literature lookups.
FAQ
What input does tooluniverse-cancer-variant-interpretation need?
tooluniverse-cancer-variant-interpretation requires a gene symbol and variant notation such as EGFR L858R or BRAF V600E, with optional cancer type for specificity. It normalizes aliases like HER2 to ERBB2 before querying CIViC, cBioPortal, and related ToolUniverse tools.
Which databases does tooluniverse-cancer-variant-interpretation query?
tooluniverse-cancer-variant-interpretation calls ToolUniverse integrations including CIViC, cBioPortal, OpenTargets, ChEMBL, DrugBank, FDA labels, PubMed, ClinicalTrials.gov, Reactome, GTEx, UniProt, MyGene, and Ensembl across its 8-phase workflow.
How does tooluniverse-cancer-variant-interpretation grade therapies?
tooluniverse-cancer-variant-interpretation assigns T1–T4 evidence tiers: T1 for FDA-approved mutation-specific therapy, T2 for strong cross-indication or phase 2–3 data, T3 for preclinical evidence, and T4 for hypothesis-only rationale, each tied to database sources.