Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Retrieve records from NCBI databases using Biopython Bio.Entrez. Use when downloading sequences, fetching GenBank records, getting document summaries, or parsing NCBI data into Biopython objects.
.claude/skills/bio-entrez-fetch/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-03 | ✗→✓ | ▲ Improved | 110% | 0% |
| case-14 | ✗→✓ | ▲ Improved | 90% | 0% |
| case-15 | ✗→✓ | ▲ Improved | 27% | 0% |
| case-04 | ✗→✓ | ▲ Improved | 174% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 46% | 0% |
<!--
#
#
-->
Retrieve records from NCBI databases using Biopython's Entrez module (EFetch, ESummary utilities).
pythonfrom Bio import Entrez Entrez.email = 'your.email@example.com' # Required by NCBI Entrez.api_key = 'your_api_key' # Optional, raises rate limit 3->10 req/sec
Fetch complete records in various formats from any NCBI database.
python# Fetch GenBank record by ID handle = Entrez.efetch(db='nucleotide', id='NM_007294', rettype='gb', retmode='text') genbank_text = handle.read() handle.close() # Fetch FASTA sequence handle = Entrez.efetch(db='nucleotide', id='NM_007294', rettype='fasta', retmode='text') fasta_text = handle.read() handle.close() # Fetch multiple records handle = Entrez.efetch(db='nucleotide', id='NM_007294,NM_000059', rettype='fasta', retmode='text')
Key Parameters: | Parameter | Description | Example | |-----------|-------------|---------| | db | Database name | 'nucleotide', 'protein', 'pubmed' | | id | Record ID(s) | 'NM_007294' or '123,456,789' | | rettype | Return type | 'fasta', 'gb', 'abstract' | | retmode | Return mode | 'text', 'xml' | | retstart | Start index | 0 | | retmax | Max records | 20 | | WebEnv | History server session | From esearch | | query_key | History server query | From esearch |
Nucleotide/Protein: | rettype | retmode | Description | |---------|---------|-------------| | 'fasta' | 'text' | FASTA sequence | | 'gb' | 'text' | GenBank flat file | | 'gp' | 'text' | GenPept flat file (protein) | | 'gbwithparts' | 'text' | GenBank with contig sequences | | 'seqid' | 'text' | Seq-id only | | 'acc' | 'text' | Accession only |
PubMed: | rettype | retmode | Description | |---------|---------|-------------| | 'abstract' | 'text' | Abstract text | | 'medline' | 'text' | MEDLINE format | | 'xml' | 'xml' | Full PubMed XML |
Gene: | rettype | retmode | Description | |---------|---------|-------------| | 'gene_table' | 'text' | Gene table format | | 'xml' | 'xml' | Full gene XML |
Get brief summaries without downloading full records. Faster than efetch.
python# Get summary for nucleotide record handle = Entrez.esummary(db='nucleotide', id='NM_007294') record = Entrez.read(handle) handle.close() summary = record[0] # First (only) record print(f"Title: {summary['Title']}") print(f"Length: {summary['Length']}") print(f"Organism: {summary['Organism']}")
Common Summary Fields:
python# Nucleotide/Protein summary['Title'] # Record title/description summary['Caption'] # Short identifier summary['Length'] # Sequence length summary['Organism'] # Source organism summary['TaxId'] # Taxonomy ID summary['AccessionVersion'] # Full accession.version # PubMed summary['Title'] # Article title summary['AuthorList'] # Authors summary['Source'] # Journal summary['PubDate'] # Publication date summary['DOI'] # Digital Object Identifier
pythonfrom Bio import Entrez, SeqIO Entrez.email = 'your.email@example.com' # Parse GenBank into SeqRecord handle = Entrez.efetch(db='nucleotide', id='NM_007294', rettype='gb', retmode='text') record = SeqIO.read(handle, 'genbank') handle.close() print(f"ID: {record.id}") print(f"Length: {len(record.seq)}") print(f"Features: {len(record.features)}") # Parse FASTA into SeqRecord handle = Entrez.efetch(db='nucleotide', id='NM_007294', rettype='fasta', retmode='text') record = SeqIO.read(handle, 'fasta') handle.close()
python# Fetch multiple as FASTA handle = Entrez.efetch(db='nucleotide', id='NM_007294,NM_000059,NM_000546', rettype='fasta', retmode='text') records = list(SeqIO.parse(handle, 'fasta')) handle.close() for record in records: print(f"{record.id}: {len(record.seq)} bp")
python# For structured data, use XML mode handle = Entrez.efetch(db='gene', id='672', retmode='xml') records = Entrez.read(handle) handle.close() # Navigate nested structure gene = records[0] print(f"Gene: {gene['Entrezgene_gene']['Gene-ref']['Gene-ref_locus']}")
pythonfrom Bio import Entrez, SeqIO Entrez.email = 'your.email@example.com' def fetch_sequence(accession, db='nucleotide'): handle = Entrez.efetch(db=db, id=accession, rettype='fasta', retmode='text') record = SeqIO.read(handle, 'fasta') handle.close() return record seq = fetch_sequence('NM_007294') print(f"{seq.id}: {seq.seq[:50]}...")
pythondef fetch_genbank(accession): handle = Entrez.efetch(db='nucleotide', id=accession, rettype='gb', retmode='text') record = SeqIO.read(handle, 'genbank') handle.close() return record gb = fetch_genbank('NM_007294') for feature in gb.features: if feature.type == 'CDS': print(f"CDS: {feature.location}") print(f"Product: {feature.qualifiers.get('product', ['?'])[0]}")
pythondef fetch_abstract(pmid): handle = Entrez.efetch(db='pubmed', id=pmid, rettype='abstract', retmode='text') abstract = handle.read() handle.close() return abstract abstract = fetch_abstract('35412348') print(abstract)
pythondef get_summaries(db, ids): if isinstance(ids, list): ids = ','.join(ids) handle = Entrez.esummary(db=db, id=ids) records = Entrez.read(handle) handle.close() return records summaries = get_summaries('nucleotide', ['NM_007294', 'NM_000059']) for s in summaries: print(f"{s['Caption']}: {s['Title'][:50]}... ({s['Length']} bp)")
python# Search for records handle = Entrez.esearch(db='nucleotide', term='human[orgn] AND insulin[gene] AND mRNA[fkey]', retmax=5) search_results = Entrez.read(handle) handle.close() ids = search_results['IdList'] # Fetch the sequences handle = Entrez.efetch(db='nucleotide', id=','.join(ids), rettype='fasta', retmode='text') records = list(SeqIO.parse(handle, 'fasta')) handle.close() for record in records: print(f"{record.id}: {len(record.seq)} bp")
python# Search gene database handle = Entrez.esearch(db='gene', term='BRCA1[sym] AND human[orgn]') result = Entrez.read(handle) handle.close() gene_id = result['IdList'][0] # Get linked protein IDs handle = Entrez.elink(dbfrom='gene', db='protein', id=gene_id) links = Entrez.read(handle) handle.close() protein_ids = [link['Id'] for link in links[0]['LinkSetDb'][0]['Link'][:3]] # Fetch proteins handle = Entrez.efetch(db='protein', id=','.join(protein_ids), rettype='fasta', retmode='text') proteins = list(SeqIO.parse(handle, 'fasta')) handle.close()
pythondef download_sequences(ids, output_file, db='nucleotide', format='fasta'): handle = Entrez.efetch(db=db, id=','.join(ids), rettype=format, retmode='text') with open(output_file, 'w') as out: out.write(handle.read()) handle.close() download_sequences(['NM_007294', 'NM_000059'], 'brca_genes.fasta')
| Error | Cause | Solution | |-------|-------|----------| | HTTPError 400 | Invalid ID or parameters | Verify ID exists, check rettype | | HTTPError 429 | Rate limit exceeded | Add delays or use API key | | Empty result | Record doesn't exist | Verify accession in web browser | | ValueError in SeqIO | Wrong format specified | Match rettype with SeqIO format | | ExpatError | XML parsing error | Use retmode='text' instead |
Need to retrieve NCBI records?
├── Need full sequence?
│ └── Use efetch with rettype='fasta'
├── Need sequence + annotations?
│ └── Use efetch with rettype='gb' (GenBank)
├── Just need metadata (length, organism)?
│ └── Use esummary (faster)
├── Need PubMed abstract?
│ └── Use efetch with rettype='abstract'
├── Need structured data for parsing?
│ └── Use efetch with retmode='xml' + Entrez.read()
├── Downloading many records?
│ └── See batch-downloads skill
└── Need records from multiple databases?
└── See entrez-link skill first<!-- AUTHOR_SIGNATURE: 9a7f3c2e-MD-BABU-MIA-2026-MSSM-SECURE -->
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | pass→pass | 9,372 | 4,535 | -52% | 1 | 1 | 0% | 1,754 | 3,581 | +104% | 0 | 0 | — |
case-02 | pass→pass | 5,915 | 4,622 | -22% | 1 | 1 | 0% | 1,238 | 3,919 | +217% | 0 | 0 | — |
case-03 | fail→pass | 9,375 | 5,899 | -37% | 1 | 1 | 0% | 1,926 | 4,044 | +110% | 0 | 0 | — |
case-13 | pass→pass | 8,792 | 5,439 | -38% | 1 | 1 | 0% | 1,859 | 3,977 | +114% | 0 | 0 | — |
case-14 | fail→pass | 9,989 | 4,440 | -56% | 1 | 1 | 0% | 1,977 | 3,750 | +90% | 0 | 0 | — |
case-15 | fail→pass | 17,406 | 6,625 | -62% | 1 | 1 | 0% | 3,096 | 3,925 | +27% | 0 | 0 | — |
case-20 | pass→pass | 9,366 | 10,992 | +17% | 1 | 1 | 0% | 1,871 | 4,963 | +165% | 0 | 0 | — |
case-21 | pass→pass | 11,368 | 8,594 | -24% | 1 | 1 | 0% | 2,339 | 4,574 | +96% | 0 | 0 | — |
case-22 | pass→pass | 7,022 | 5,938 | -15% | 1 | 1 | 0% | 1,459 | 4,041 | +177% | 0 | 0 | — |
case-04 | fail→pass | 6,897 | 5,803 | -16% | 1 | 1 | 0% | 1,483 | 4,069 | +174% | 0 | 0 | — |
case-05 | fail→pass | 12,480 | 4,724 | -62% | 1 | 1 | 0% | 2,608 | 3,820 | +46% | 0 | 0 | — |
case-06 | pass→pass | 7,754 | 3,749 | -52% | 1 | 1 | 0% | 1,642 | 3,618 | +120% | 0 | 0 | — |
case-07 | pass→pass | 14,318 | 8,075 | -44% | 1 | 1 | 0% | 3,031 | 4,545 | +50% | 0 | 0 | — |
case-08 | pass→pass | 11,424 | 7,684 | -33% | 1 | 1 | 0% | 2,331 | 4,207 | +80% | 0 | 0 | — |
case-09 | pass→pass | 14,255 | 9,263 | -35% | 1 | 1 | 0% | 3,020 | 4,781 | +58% | 0 | 0 | — |
case-10 | fail→pass | 7,444 | 6,880 | -8% | 1 | 1 | 0% | 1,509 | 4,240 | +181% | 0 | 0 | — |
case-11 | pass→pass | 9,487 | 4,901 | -48% | 1 | 1 | 0% | 1,647 | 3,803 | +131% | 0 | 0 | — |
case-12 | pass→pass | 9,217 | 5,061 | -45% | 1 | 1 | 0% | 1,796 | 3,896 | +117% | 0 | 0 | — |
case-16 | fail→pass | 10,657 | 4,786 | -55% | 1 | 1 | 0% | 2,384 | 3,824 | +60% | 0 | 0 | — |
case-17 | pass→pass | 7,250 | 3,315 | -54% | 1 | 1 | 0% | 1,526 | 3,420 | +124% | 0 | 0 | — |
case-18 | pass→pass | 8,454 | 6,396 | -24% | 1 | 1 | 0% | 1,830 | 4,214 | +130% | 0 | 0 | — |
case-19 | pass→pass | 3,565 | 2,594 | -27% | 1 | 1 | 0% | 637 | 3,377 | +430% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +32 percentage points is the difference between those two pass rates over the 22 comparable cases.
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.
| Model | Method | Date | Lift |
|---|---|---|---|
| gemini-3.6-flash | verified | 7/26/2026 | +18% |
Other measured skills in the registry, with their headline benchmark lift.