Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Use when needing clinical significance, pathogenicity classifications (e.g., Pathogenic, Benign, VUS), clinical evidence rationales, or finding "hard positive" benchmark controls for human genomic variants.
.claude/skills/mkurman-clinvar-database/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-06 | ✗→✓ | ▲ Improved | 181% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 201% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 117% | 0% |
| case-21 | ✗→✓ | ▲ Improved | 400% | 0% |
| case-15 | ✗→✓ | ▲ Improved | 200% | 0% |
uv: Read the uv skill and follow its Setup instructions to ensureuv is installed and on PATH.
this skill directory then (1) prominently notify the user to check the terms at https://www.ncbi.nlm.nih.gov/clinvar/, then (2) create the file recording the notification text and timestamp.
.env file: Make sure the .env file exists in your home directory.Create one if it does not exist.
NCBI_API_KEY (optional): Raises the NCBI rate limit from 3 to 10requests/second. The skill works without it, but a key is recommended if the user plans many queries or encounters a 429 error. The user can obtain one for free by registering at https://www.ncbi.nlm.nih.gov/account/settings/. If the variable is missing from .env, do NOT ask the user to paste it into the chat (this would leak the key into the agent's context). Instead, give the user this command — substituting ENV_FILE with the resolved literal path to the .env file:
bash printf "Enter NCBI API key (typing hidden): " && read -s key && echo && echo "NCBI_API_KEY=$key" >> "ENV_FILE" && echo "Saved."
The scripts load credentials automatically via dotenv. NEVER read, print, or inspect the .env file or its variables (e.g. no cat, grep, echo, printenv, or os.environ.get on keys). Credentials must stay out of the agent's context. See the API Key section for more details.
ClinVar is the primary consensus record for clinical classifications of human genomic variations. It provides the "clinical ground truth" for pathogenicity labels (Pathogenic, Likely Pathogenic, Benign, VUS) based on assertions from global laboratories.
Use when you need to:
specific variant.
clinical laboratory classifications.
specific variant.
HBB gene within 50bp of a signal").
organizations submitting each classification.
Do NOT use when you need to:
patterns (use OMIM).
skipping (use AlphaGenome).
variant (use GeneReviews).
AlphaFold).
ClinVar queries are executed via a robust Python wrapper script to handle strict rate limiting and XML/JSON parsing.
Example: Search for BRCA1 variants
bashuv run scripts/clinvar_api.py search --query "BRCA1[gene]" --output results.json
--retmax 200. Forany "List all" or gene-wide request, you MUST explicitly set --retmax higher (e.g., 1000) to ensure data completeness.
handles rate limiting, retries, and the complex XML parsing for you. If the script's parsed output does not contain the specific fields you need, you may modify the script or query the NCBI E-utilities API directly — but be aware that the raw XML schemas are complex and vary between record types.
prerequisite instructions above to help the user add NCBI_API_KEY to the .env file.
output.
count — Count Matching VariantsPurpose: Check how many variants match a query without fetching IDs. Use to decide whether a full search is warranted.
Arguments:
--query: (Required) NCBI Entrez search query string.--output: (Required) Output JSON file path.Example: `uv run scripts/clinvar_api.py count \ --query "TP53[gene] AND \"uncertain significance\"[clinsig]" \ --output count.json` Output: {"total_count": <int>}
search — Search VariantsPurpose: Identify variants based on genomic location, gene symbols, or clinical attributes using NCBI Entrez search syntax. The search command automatically paginates through all matching results to ensure complete, deterministic retrieval.
bash# Fetch ALL matching variants (default behavior) uv run scripts/clinvar_api.py search \ --query "BRCA1[gene]" --output results.json # Search by Chromosome and Position Range uv run scripts/clinvar_api.py search \ --query "11[chr] AND 5225000:5226000[chrpos]" --output results.json # Combine terms using Entrez syntax uv run scripts/clinvar_api.py search \ --query "HBB[gene] AND pathogenic[clinsig]" --output results.json # Cap results at 50 uv run scripts/clinvar_api.py search \ --query "TP53[gene]" --retmax 50 --output results.json
Arguments:
--query: (Required) NCBI Entrez search query string.--retmax: Maximum total number of variant IDs to return. Default is 0,which means "fetch all matching results." Set to a positive integer to cap the result set.
--page_size: Number of IDs to fetch per API request (default: 500, max:10000 per NCBI limits).
--output: (Required) Output JSON file path.Output: A JSON object containing:
total_count — Total number of matching variants in ClinVar.fetched_count — Number of IDs actually retrieved.variant_ids — List of ClinVar Variation ID strings.summary — Get Interpretation SummaryPurpose: Retrieve top-line clinical significance labels, star ratings (review status), and basic phenotype data for rapid variant screening.
bash# Get summary for one or more Variation IDs uv run scripts/clinvar_api.py summary \ --variant_ids 12345 67890 --output summary.json
Arguments:
--variant_ids: (Required) One or more ClinVar Variation IDs.--output: (Required) Output JSON file path.Output: A JSON list of summary objects, each containing:
variant_id, title, clinical_significance, review_status, \last_evaluated, phenotypes
genes — list of {gene_id, symbol, strand}variation_type — e.g., single nucleotide variant, Deletion, Insertionmolecular_consequences — list of strings (e.g., "missense variant", \"nonsense"])
evidence — Get Clinical EvidencePurpose: Fetch the full clinical record for a single variant, including free-text clinician rationales, assertion methods, and specific submitter notes.
bash# Get full evidence for a single Variation ID uv run scripts/clinvar_api.py evidence \ --variant_id 12345 --output evidence.json
Arguments:
--variant_id: (Required) A single ClinVar Variation ID.--output: (Required) Output JSON file path.Output: A JSON object containing:
variant_idallele_info — {chromosome, position_start, position_stop,reference_allele, alternate_allele, cytogenetic_band, dbsnp_rsid} (GRCh38 preferred)
conditions — list of {name, medgen_cui, omim_id, orphanet_id, hpo_terms}functional_consequences — list of {value, sequence_ontology_id}structural_variant_details — {outer_start, inner_start, inner_stop,outer_stop, copy_number} (present only for CNVs, otherwise null)
citation_references — list of PubMed IDs cited in the global "Citations"section
submissions — list of per-submitter records, each containing:submitter_name, classification, curator_notes,assertion_criteria
date_last_evaluated — when the submitter last reviewed theclassification
For large or unknown result sets, use count first to decide whether to proceed, then search (which auto-paginates and returns total_count / fetched_count), then summary to screen.
bash# Step 1: Gauge size (optional — search also returns total_count) uv run scripts/clinvar_api.py count \ --query "HBB[gene] AND pathogenic[clinsig]" --output count.json # Step 2: Fetch all variant IDs (auto-paginates) uv run scripts/clinvar_api.py search \ --query "HBB[gene] AND pathogenic[clinsig]" --output ids.json # Step 3: Get summaries (extract variant_ids from search output) uv run scripts/clinvar_api.py summary \ --variant_ids 12345 67890 --output summary.json
When you need the full clinical picture for a specific variant — including submitter rationales, PubMed citations, ontology-linked conditions, and allele coordinates — use evidence.
bashuv run scripts/clinvar_api.py evidence \ --variant_id 12345 --output evidence.json
ClinVar metadata is inconsistent. To fulfill "List all" requests, do not rely on a single filter. Perform the following in a single turn and merge results:
variant"molecular_consequence]).
c.*).[chrpos]).This "triangulation" ensures structural variants with missing labels are not overlooked.
molecular_consequences alone can be ambiguous (e.g., splice donor variant appears in both coding and non-coding contexts). Always cross-check the title field for HGVS patterns:
c.-… — 5' UTR (non-coding)c.*… — 3' UTR (non-coding)c.123+N / c.123-N — intronic (non-coding)p.Trp146Arg etc. — protein effect (coding)A variant with UTR/intronic HGVS and no p. annotation is non-coding, even with splicing labels. Conversely, any p. annotation indicates a coding effect.
"3 prime UTR variant"[mol_consequence]c.*"5 prime UTR variant"[mol_consequence]c.-review_status filter. This is the most efficient way to distinguish between single-laboratory assertions and panel-reviewed ground truth.
summary → clinical_significancesummary → genessummary → variation_typesummary → molecular_consequencesevidence → allele_infoevidence → conditionsevidence → functional_consequencesevidence →structural_variant_details
evidence → citation_referenceslast_evaluatedevidence → submissions[].curator_notesTo get precise genomic coordinates in the format <chrom>:<pos>:<ref>><alt> (e.g., chr5:70951945:G>A), you must use the evidence command, as these details are not available in the summary output.
You MUST always include genomic coordinates in the format <chrom>:<pos>:<ref>><alt> when listing or presenting variants, even if not explicitly requested by the user. If coordinates are missing from the summary, use the evidence command or dbSNP fallback to retrieve them.
<ID> --output evidence.json.
evidence command parses the XML. Extract:ChrpositionVCF (or start)referenceAlleleVCF (or referenceAllele)alternateAlleleVCF (or alternateAllele) from theSequenceLocation element with Assembly="GRCh38".
Fallback for Imprecise Coordinates (Gene Range): ClinVar often returns the full gene range for non-coding variants. If the extracted coordinates correspond to the gene range instead of a specific position, use the dbsnp-database skill to resolve the precise coordinates using the dbsnp_rsid or HGVS title: 1.Check for dbsnp_rsid in the evidence output. 2. Run uv run scripts/dbsnp_cli.py resolve-rsid {rsid} to get precise GRCh38 coordinates. 3. Format as <chrom>:<pos>:<ref>><alt> using the SPDI or HGVS data from dbSNP.
The structural_variant_details field is only populated for copy number variants (CNVs). For standard SNVs and small indels this field will be null. Use the allele_info fields (position_start, position_stop, reference_allele, alternate_allele) instead.
Large copy-number variants (CNVs) frequently have empty molecular_consequences. If a variant title mentions "del" and coordinates overlap your target region, it is relevant regardless of missing labels.
To increase the rate limit to 10 requests per second, you need to obtain an NCBI API key and add it to the .env file. You can obtain a key by following the instructions at NCBI ClinVar API docs]ncbi-api]
ncbi-api]: https://www.ncbi.nlm.nih.gov/clinvar/docs/api_http/
Once you have a key, follow the prerequisite instructions to add it to the .env file.
bashuv run scripts/clinvar_api.py search --query "BRCA1[gene]" --output results.json
If a RateLimitError is encountered, follow the prerequisite instructions to help the user add NCBI_API_KEY to the .env file, providing the NCBI ClinVar API docs]ncbi-api] URL for instructions on how to obtain one.
uv run to execute python.jq is unavailable pivot immediately to using Python one-liners forprocessing JSON (e.g., uv run python3 -c "import json; ...").
count before search to understand the result set size.search command fetches all results by default and includestotal_count and fetched_count in the output — always verify these match to confirm complete retrieval.
sort locally by last_evaluated.
provided clinvar_api.py client which handles the unpredictable XML schemas robustly.
telling you to pause. Follow the prerequisite instructions to help the user add NCBI_API_KEY to the .env file, then retry.
nomenclature, RS IDs, or proper Entrez coordinate syntax (11[chr] AND 1234[chrpos]), not raw ATCG strings.
AND "c.551C>T") is more reliable than coordinate searches (chrpos]), as many ClinVar records for these types lack precise genomic mappings.
strings. Always use case-insensitive matching (.lower()) when filtering.
search output as a bare list — search returns a JSON objectwith total_count, fetched_count, and variant_ids — not a bare list.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 18,967 | 6,652 | -65% | 1 | 1 | 0% | 3,670 | 4,825 | +31% | 0 | 0 | — |
case-02 | fail→fail | 10,104 | 7,249 | -28% | 1 | 1 | 0% | 1,593 | 4,827 | +203% | 0 | 0 | — |
case-03 | fail→fail | 20,876 | 8,439 | -60% | 1 | 1 | 0% | 3,881 | 4,819 | +24% | 0 | 0 | — |
case-04 | fail→fail | 15,426 | 7,931 | -49% | 1 | 1 | 0% | 2,186 | 4,868 | +123% | 0 | 0 | — |
case-05 | fail→fail | 26,275 | 28,618 | +9% | 1 | 1 | 0% | 2,372 | 6,984 | +194% | 0 | 0 | — |
case-06 | fail→pass | 13,629 | 9,062 | -34% | 1 | 1 | 0% | 2,042 | 5,748 | +181% | 0 | 0 | — |
case-07 | fail→fail | 13,935 | 11,995 | -14% | 1 | 1 | 0% | 2,304 | 5,268 | +129% | 0 | 0 | — |
case-08 | fail→pass | 9,518 | 4,641 | -51% | 1 | 1 | 0% | 1,726 | 5,193 | +201% | 0 | 0 | — |
case-09 | fail→fail | 7,183 | 7,423 | +3% | 1 | 1 | 0% | 1,214 | 4,840 | +299% | 0 | 0 | — |
case-10 | fail→fail | 13,530 | 10,449 | -23% | 1 | 1 | 0% | 2,250 | 6,122 | +172% | 0 | 0 | — |
case-11 | fail→pass | 15,774 | 7,270 | -54% | 1 | 1 | 0% | 2,597 | 5,647 | +117% | 0 | 0 | — |
case-12 | pass→fail | 8,531 | 8,182 | -4% | 1 | 1 | 0% | 1,355 | 4,977 | +267% | 0 | 0 | — |
case-21 | fail→pass | 13,386 | 3,411 | -75% | 1 | 1 | 0% | 968 | 4,844 | +400% | 0 | 0 | — |
case-13 | pass→pass | 13,252 | 13,210 | -0% | 1 | 1 | 0% | 2,305 | 6,193 | +169% | 0 | 0 | — |
case-14 | pass→pass | 12,838 | 6,609 | -49% | 1 | 1 | 0% | 2,248 | 5,519 | +146% | 0 | 0 | — |
case-15 | fail→pass | 9,957 | 2,812 | -72% | 1 | 1 | 0% | 1,652 | 4,952 | +200% | 0 | 0 | — |
case-16 | pass→pass | 8,553 | 8,276 | -3% | 1 | 1 | 0% | 1,557 | 5,266 | +238% | 0 | 0 | — |
case-17 | fail→pass | 12,811 | 7,330 | -43% | 1 | 1 | 0% | 1,904 | 5,796 | +204% | 0 | 0 | — |
case-18 | fail→pass | 8,012 | 5,084 | -37% | 1 | 1 | 0% | 1,160 | 5,117 | +341% | 0 | 0 | — |
case-19 | pass→fail | 14,545 | 8,240 | -43% | 1 | 1 | 0% | 2,047 | 5,027 | +146% | 0 | 0 | — |
case-20 | pass→pass | 10,776 | 5,268 | -51% | 1 | 1 | 0% | 1,741 | 5,227 | +200% | 0 | 0 | — |
case-22 | fail→pass | 8,689 | 2,669 | -69% | 1 | 1 | 0% | 1,595 | 4,899 | +207% | 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, and 14 counted toward the lift figure. The other 8 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +27 percentage points is the difference between those two pass rates over the 14 comparable cases. 5 cases got worse with the skill loaded, and they are 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.