Skip to content
Development
Skill

/emdb-database

Look up EMDB cryo-EM density maps and fitted atomic models via the entry REST API + EBI Search WS. Fetch entry metadata (resolution, method, organism, sample), map download URLs, fitted PDB IDs, and citations. Keyword search via EBI Search. No auth. For atomic coordinates use

From plugin
sciagent-skills
364200 skills
Install
$ npx -y skills add jaechang-hits/SciAgent-Skills --skill emdb-database --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/emdb-database

Context preview

The summary Claude sees to decide when to auto-load this skill.

Look up EMDB cryo-EM density maps and fitted atomic models via the entry REST API + EBI Search WS. Fetch entry metadata (resolution, method, organism, sample), map download URLs, fitted PDB IDs, and citations. Keyword search via EBI Search. No auth. For atomic coordinates use

SKILL.md

emdb-database.SKILL.md
name: "emdb-database"
description: "Look up EMDB cryo-EM density maps and fitted atomic models via the entry REST API + EBI Search WS. Fetch entry metadata (resolution, method, organism, sample), map download URLs, fitted PDB IDs, and citations. Keyword search via EBI Search. No auth. For atomic coordinates use pdb-database; for AlphaFold predictions use alphafold-database-access."
license: "CC-BY-4.0"

EMDB Database

Overview

The Electron Microscopy Data Bank (EMDB) at EBI archives 3D electron microscopy density maps — primarily cryo-EM and cryo-ET — for macromolecular assemblies (30,000+ entries: ribosomes, membrane proteins, viruses, large complexes). Access is split across two services:

  • **EMDB Entry API** (`https://www.ebi.ac.uk/emdb/api/entry/{EMD-XXXXX}`) — the canonical per-entry JSON containing metadata, map header, fitted PDB list, and citation. Sub-endpoints like `/map`, `/fitted`, `/publications` do **not** exist — all those data live inside the single entry response.
  • **EBI Search WS** (`https://www.ebi.ac.uk/ebisearch/ws/rest/emdb`) — the real keyword search backend (the bare `https://www.ebi.ac.uk/emdb/api/search/` endpoint ignores the query and just returns recent entries).

No authentication or API key is required.

When to Use

  • Finding cryo-EM density maps by keyword (e.g., "spike protein", "ribosome 70S")
  • Fetching the download URL of a `.map.gz` density file for use in ChimeraX / PyMOL
  • Identifying fitted PDB atomic models for an EMDB map (and the reverse)
  • Retrieving entry metadata — resolution, reconstruction method, organism, sample
  • Listing cryo-EM structures filtered by organism or resolution cutoff
  • Pulling the primary citation (journal, DOI, PubMed ID) for an EMDB entry
  • Use `pdb-database` instead when you need experimentally determined atomic coordinates
  • Use `alphafold-database-access` for AI-predicted structures; EMDB is for experimental EM maps only

Prerequisites

  • **Python packages**: `requests`, `pandas`, `matplotlib`
  • **Data requirements**: EMDB entry IDs (`EMD-XXXXX`), keyword search strings, or PDB IDs for cross-referencing
  • **Environment**: internet connection; no API key
  • **Rate limits**: no official published limits; add `time.sleep(0.2)` between requests in batch loops for polite access
pip install requests pandas matplotlib

Quick Start

import requests

EMDB_API   = "https://www.ebi.ac.uk/emdb/api"
EBI_SEARCH = "https://www.ebi.ac.uk/ebisearch/ws/rest/emdb"

# Keyword search via EBI Search WS (NOT /emdb/api/search/, which ignores q=)
r = requests.get(EBI_SEARCH,
                 params={"query": "sars-cov-2 spike", "size": 5, "format": "json",
                         "fields": "id,name,resolution,em_method,organism"},
                 timeout=30)
r.raise_for_status()
res = r.json()
print(f"Total hits: {res['hitCount']}")
for e in res["entries"]:
    f = e["fields"]
    name = (f.get("name") or [""])[0][:60]
    resol = (f.get("resolution") or ["?"])[0]
    print(f"  {e['id']}: {name}  ({resol} Å)")

Core API

Query 1: Keyword Search (EBI Search WS)

Returns a paged hit list keyed by EMDB ID, with the requested `fields` per entry.

import requests, pandas as pd

EBI_SEARCH = "https://www.ebi.ac.uk/ebisearch/ws/rest/emdb"

def emdb_search(query, size=20, start=0,
                fields="id,name,resolution,em_method,organism"):
    r = requests.get(EBI_SEARCH,
                     params={"query": query, "size": size, "start": start,
                             "format": "json", "fields": fields},
                     timeout=30)
    r.raise_for_status()
    return r.json()

data = emdb_search("ribosome 70S", size=10)
rows = []
for e in data["entries"]:
    f = e["fields"]
    rows.append({
        "emdb_id": e["id"],
        "name": (f.get("name") or [""])[0],
        "resolution_A": float((f.get("resolution") or [0])[0] or 0) or None,
        "em_method": (f.get("em_method") or [""])[0],
        "organism": (f.get("organism") or [""])[0],
    })
df = pd.DataFrame(rows)
print(f"hitCount={data['hitCount']}; first {len(df)} rows:")
print(df.to_string(index=False))
# Paged retrieval — iterate `start` until exhausting hitCount
def emdb_search_all(query, size=100, max_pages=5,
                    fields="id,name,resolution,em_method"):
    out = []
    for page in range(max_pages):
        d = emdb_search(query, size=size, start=page * size, fields=fields)
        if not d["entries"]:
            break
        out.extend(d["entries"])
        if len(out) >= d["hitCount"]:
            break
    return out

hits = emdb_search_all("ferritin", size=50, max_pages=2)
print(f"Pulled {len(hits)} ferritin entries")

Query 2: Entry Metadata

The single entry endpoint returns all metadata, the map header, fitted PDB list, and the citation in one document. Read field paths carefully — most are nested.

import requests

EMDB_API = "https://www.ebi.ac.uk/emdb/api"

def emdb_entry(emdb_id):
    r = requests.get(f"{EMDB_API}/entry/{emdb_id}", timeout=30)
    r.raise_for_status()
    return r.json()

e = emdb_entry("EMD-30210")  # nsp12-nsp7-nsp8 + Remdesivir (RdRp)
print(f"Title       : {e['admin']['title']}")
print(f"Status      : {e['admin']['current_status']}")
print(f"Key dates   : {e['admin'].get('key_dates')}")

sd = e["structure_determination_list"]["structure_determination"][0]
ip = sd["image_processing"][0]
res = ip["final_reconstruction"]["resolution"]
print(f"Method      : {sd['method']}")
print(f"Resolution  : {res['valueOf_']} {res['units']}  (type: {res['res_type']})")

Query 3: Map Header / Download Info

`entry["map"]` contains the file name, format, voxel grid, axis order, cell, contour level(s), and recommended display threshold.

import requests

EMDB_API = "https://www.ebi.ac.uk/emdb/api"
e = requests.get(f"{EMDB_API}/entry/EMD-30210", timeout=30).json()

m = e["map"]
print(f"Map file     : {m.get('file')}")
Read more
Ships withsciagent-skills

Turn your AI coding agent into a life sciences expert — 199 bioinformatics skills for Claude Code covering RNA-seq, single-cell analysis, genomics, proteomics, drug discovery, and more. Boosted BixBench from 65% to 92%. Open source.

Get the whole plugin

Other skills on sciagent-skills.