io.github.rcsb/rcsb-mcp
Enables discovery, inspection, and cross-referencing of Protein Data Bank structures through three RCSB APIs: search, data, and sequence coordinates.
README
<!-- mcp-name: io.github.rcsb/rcsb-mcp -->
rcsb-mcp
An MCP server for interrogating Protein Data Bank structures — discover, inspect, and cross-reference — from LLM clients (Claude Desktop, MCP Inspector, Cursor, etc.). It spans three RCSB APIs:
- Discover — find structures with the Search API (keyword, attribute, sequence, chemistry, 3D shape, motif).
- Inspect — fetch entry / entity / assembly / ligand details and annotations from the Data API.
- Relate — map sequences and positional features across PDB, UniProt, and NCBI with the Sequence Coordinates API.
Tools
Search (search.rcsb.org)
| Tool | What it does |
|---|---|
rcsb_list_pdb_search_attributes |
Discover searchable attribute paths, types, and operators. schema="structure" (default, ~677) or schema="chemical" (~57: chem_comp.*, drugbank_info.*, ...). |
rcsb_find_go_terms |
Resolve a free-text molecular function / biological process / cellular component to Gene Ontology ids (via EBI QuickGO), annotated with PDB entry counts — then search by rcsb_polymer_entity_annotation.annotation_lineage.id. |
rcsb_find_interpro_domains |
Resolve a free-text protein domain / family / fold to InterPro ids (via EBI InterPro API), annotated with PDB entry counts — then search by rcsb_polymer_entity_annotation.annotation_id. |
rcsb_find_enzyme_classes |
Resolve a free-text enzyme / reaction to Enzyme Commission (EC) numbers (via EBI Search/IntEnz), annotated with PDB entry counts — then search by rcsb_polymer_entity.rcsb_ec_lineage.id (hierarchical). |
rcsb_find_disease_terms |
Resolve a free-text disease / condition to MONDO ids (via EBI OLS), annotated with PDB entry counts — then search by rcsb_uniprot_annotation.annotation_lineage.id (hierarchical, UniProt-based). |
rcsb_find_organisms |
Resolve a free-text organism / common name / clade to NCBI Taxonomy ids (via UniProt taxonomy), annotated with PDB entry counts — then search by rcsb_entity_source_organism.taxonomy_lineage.id (hierarchical: a clade id matches every organism beneath it). |
rcsb_search_fulltext |
Free-text keyword search (e.g. "CRISPR Cas9"), optionally refined with structured attributes filters (AND/OR) and sort. |
rcsb_search_by_attribute |
Structured search on one or more indexed attributes (resolution, organism, release date, ...) combined with a single AND/OR. Each AttributeFilter supports exists, negation, case_sensitive; chemical=True (text_chem). |
rcsb_search_by_sequence |
MMseqs2 sequence-similarity search (BLAST-like). |
rcsb_search_by_chemical |
Chemical search by SMILES/InChI descriptor (whole-molecule or substructure) or molecular formula. |
rcsb_search_by_structure |
3D shape-similarity search against a reference PDB assembly or chain. |
rcsb_search_by_seqmotif |
Short sequence-motif search (PROSITE pattern, regex, or simple wildcards). |
rcsb_search_strucmotif |
3D structural-motif search: structures sharing a geometric arrangement of specific residues (e.g. a catalytic triad). |
The two text tools (rcsb_search_fulltext, rcsb_search_by_attribute)
also take group_by_identity (100/95/90/70/50/30) to return one representative
per sequence-identity cluster — i.e. non-redundant results. To search
chemical-component attributes, find the path with
rcsb_list_pdb_search_attributes(schema="chemical"), then pass chemical=True to
rcsb_search_by_attribute / rcsb_search_fulltext (usually with return_type="mol_definition").
Both catalogs (structure and chemical) are generated from the live metadata schemas by
scripts/generate_search_attributes.py.
Counting and faceting are output options on every rcsb_search_* tool, not separate
tools: each response includes total_count (the full match count — for "how many ..." run a
search with limit=1 and read it), and passing facets returns a breakdown
(terms/histogram/date_histogram/range/cardinality) instead of hits. The rcsb_search_by_*
service tools (sequence, chemical, structure, seq/struc-motif) also take optional attributes
filters, so e.g. a sequence search can be restricted to an organism in one call.
Sorting is likewise available on every rcsb_search_* tool via sort_by (an
attribute path) + sort_direction (asc/desc), replacing the default score ordering (for
the similarity searches this overrides the similarity-ranked order). Only attributes indexed
for sorting work — those exposing exact_match (strings) or equals (numbers/dates) in
rcsb_list_pdb_search_attributes; sorting is not available for return_type="mol_definition"
(chemical-component results are ranked by score only).
Paging. Every search tool that returns hits accepts limit (1–100, default
10) and offset (default 0). Each response reports total_count, has_more,
and next_offset; to fetch the next page, call the tool again with the same
query and offset set to the returned next_offset.
Data (data.rcsb.org/graphql)
There is one tool per Data API GraphQL root field. Each takes a list of IDs
(singular lookups = a one-element list) plus an optional fields argument to
override the curated default selection with your own GraphQL sub-selection.
Unknown IDs are reported under not_found. Discover the paths to put in fields
with rcsb_describe_data_object — browse a level, drill into a nested object with
into=, or search the schema by keyword with query= + max_depth=. Every path it
returns is verified against the live schema, so don't guess field names.
| Tool | Object | Example ID |
|---|---|---|
rcsb_get_entries |
PDB entries | "4HHB" |
rcsb_get_polymer_entities |
Polymer entities (protein/NA) | "4HHB_1" |
rcsb_get_nonpolymer_entities |
Ligand/cofactor entities | "4HHB_3" |
rcsb_get_branched_entities |
Carbohydrate entities | "5FMB_2" |
rcsb_get_polymer_entity_instances |
Polymer chains | "4HHB.A" |
rcsb_get_nonpolymer_entity_instances |
Bound-ligand instances | "4HHB.E" |
rcsb_get_branched_entity_instances |
Glycan chains | "5FMB.C" |
rcsb_get_assemblies |
Biological assemblies | "4HHB-1" |
rcsb_get_interfaces |
Assembly interfaces | "1BMV-1.1" |
rcsb_get_chem_comps |
Chemical components / ligands | "HEM", "ATP" |
rcsb_get_entry_groups |
Entry groups | "G_1002266" |
rcsb_get_polymer_entity_groups |
Polymer entity groups (seq. clusters) | "85_70" |
rcsb_get_nonpolymer_entity_groups |
Non-polymer entity groups | "ATP" |
rcsb_get_uniprot |
UniProt record (single) | "P69905" |
rcsb_get_pubmed |
PubMed record (single, integer) | 6726807 |
rcsb_get_group_provenance |
Grouping provenance (single) | "provenance_sequence_identity" |
rcsb_describe_data_object |
Introspect an object's live GraphQL schema to build a fields= selection: browse a level, drill into a nested object with into=, or search by keyword with query= + max_depth= (flat, incl. nested + cross-object paths). Returns verified dotted paths. The Data API analogue of rcsb_list_pdb_search_attributes. |
— |
The Search API only returns identifiers, so a search is the first step: batch the
returned ids into the matching rcsb_get_* tool to fetch titles, organisms, and
other metadata (these tools query the GraphQL endpoint, batching every requested ID
into one request). All 16 typed tools are generated from a single registry in
queries.py (DATA_OBJECTS), so adding a field or
endpoint is a one-line change.
Sequence Coordinates (sequence-coordinates.rcsb.org/graphql)
Maps alignments and positional annotations between sequence reference systems
(UNIPROT, NCBI_PROTEIN, NCBI_GENOME, PDB_ENTITY, PDB_INSTANCE). Each
tool takes an optional fields argument to override the default selection; use
rcsb_describe_seqcoord_object to discover what fields are available.
This is the only RCSB API that cross-references NCBI (RefSeq protein /
genome) — the Data API only knows UniProt. So "what NCBI proteins map to a PDB
structure?" is answered by rcsb_seqcoord_alignments, not the Data API. PDB query
ids must be entity-level (4HHB_1), not a bare entry (4HHB); for a whole
entry, query each polymer entity.
| Tool | What it does |
|---|---|
rcsb_seqcoord_alignments |
Cross-reference a sequence across PDB / UniProt / NCBI with aligned ranges (e.g. 4HHB_1 → NCBI proteins NP_000508, NP_000549). |
rcsb_seqcoord_annotations |
Positional features for one sequence, from one or more annotation sources (UNIPROT, PDB_ENTITY, PDB_INSTANCE, PDB_INTERFACE). |
rcsb_seqcoord_group_alignments |
Alignments among members of a sequence group (MATCHING_UNIPROT_ACCESSION / SEQUENCE_IDENTITY). |
rcsb_seqcoord_group_annotations |
Annotations across a group; summary=True returns a positional summary. |
rcsb_describe_seqcoord_object |
Introspect the live schema to discover fields available on a seqcoord object (for use with fields=). |
Install
# run the published package without installing (recommended for clients)
uvx rcsb-mcp
# or install it
pip install rcsb-mcp
rcsb-mcp is listed in the Official MCP Registry
as io.github.rcsb/rcsb-mcp, so registry-aware clients can discover it directly.
For local development, install from the project root instead:
pip install -e .
# or with uv
uv pip install -e .
Run / test
# unit tests (no network)
hatch test # or: python tests/test_queries.py
# run the server over stdio
python -m rcsb_mcp.server
# or, after install:
rcsb-mcp
# inspect interactively
npx @modelcontextprotocol/inspector python -m rcsb_mcp.server
There is also an end-to-end evaluation suite (evals/) — 10
read-only, stable questions that measure how well an LLM can drive these tools to
answer real PDB questions. See evals/README.md to run it.
Connect to Claude Desktop
Edit claude_desktop_config.json:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"rcsb-mcp": {
"command": "uvx",
"args": ["rcsb-mcp"]
}
}
}
For a local source checkout, point at the module instead:
{
"mcpServers": {
"rcsb-mcp": {
"command": "python",
"args": ["-m", "rcsb_mcp.server"],
"cwd": "/absolute/path/to/rcsb-mcp/src"
}
}
}
Restart Claude Desktop. The tools appear under the connectors (plug) icon.
Example prompts
- "Find high-resolution human hemoglobin structures." →
rcsb_search_fulltext(keyword +attributes) - "Human hemoglobin structures better than 2 Å, best resolution first." →
rcsb_search_fulltext(keyword +attributes,sort_by) - "What PDB entries match this protein sequence: MTEY..." →
rcsb_search_by_sequence - "Find structures containing a ligand like this SMILES / with formula C8H9NO2." →
rcsb_search_by_chemical - "Which structures have a 3D fold similar to 4HHB?" →
rcsb_search_by_structure - "Find proteins with a zinc-finger motif." →
rcsb_search_by_seqmotif - "Structures of proteins with kinase activity / involved in DNA repair / in the mitochondrial membrane." →
rcsb_find_go_terms→rcsb_search_by_attributeonrcsb_polymer_entity_annotation.annotation_lineage.id - "Structures containing an SH2 domain / immunoglobulin fold." →
rcsb_find_interpro_domains→rcsb_search_by_attributeonrcsb_polymer_entity_annotation.annotation_id - "Alcohol dehydrogenase structures / any EC 3.4.21 serine protease." →
rcsb_find_enzyme_classes→rcsb_search_by_attributeonrcsb_polymer_entity.rcsb_ec_lineage.id - "Structures of proteins associated with cystic fibrosis / breast cancer." →
rcsb_find_disease_terms→rcsb_search_by_attributeonrcsb_uniprot_annotation.annotation_lineage.id - "Structures from mammals / from a particular organism or clade." →
rcsb_find_organisms→rcsb_search_by_attributeonrcsb_entity_source_organism.taxonomy_lineage.id - "Non-redundant human kinase structures (90% identity clusters)." →
rcsb_search_fulltextwithgroup_by_identity=90 - "How many human X-ray structures are there?" →
rcsb_search_by_attribute(readtotal_count) - "Break down ribosome structures by experimental method / by release year." →
rcsb_search_fulltextwithfacets - "Find structures with the same catalytic-site geometry as residues 162/193/219 of 2MNR." →
rcsb_search_strucmotif - "Find chemical components under 150 Da." →
rcsb_list_pdb_search_attributes(schema="chemical")+rcsb_search_by_attributewithchemical=True - "Summarize PDB entries 4HHB, 1MBN and 6VXX." →
rcsb_get_entries - "What's the sequence and organism of entity 4HHB_1?" →
rcsb_get_polymer_entities - "Tell me about the ligand HEM." →
rcsb_get_chem_comps - "What's the composition of the 4HHB biological assembly?" →
rcsb_get_assemblies - "Which PDB entries does P69905 map to?" →
rcsb_get_uniprot - "Which PDB entities align to UniProt P69905, and over what ranges?" →
rcsb_seqcoord_alignments - "What NCBI proteins map to 4HHB?" →
rcsb_seqcoord_alignmentsper entity (4HHB_1,4HHB_2),to_ref=NCBI_PROTEIN - "Show UniProt features mapped onto PDB entity 4HHB_1." →
rcsb_seqcoord_annotations - "Pull a field the compact defaults don't include." →
rcsb_describe_data_objectto find the path, then the matchingrcsb_get_*tool withfields=
Report output (RCSB_MCP_REPORT_BASE_URL)
rcsb_render_report returns a self-contained link, not the markup — so the
agent never has to reproduce the ~20 KB document (the single most expensive step
of a report turn). The whole report is gzip+base64url-packed into the URL, so the
server stores nothing and any replica renders any link on demand.
Set RCSB_MCP_REPORT_BASE_URL to the origin that serves this MCP (e.g.
https://rcsb-mcp.rcsb.org) and the tool returns
{ url: "<base>/r?d=<packed report>", html: null }. The agent hands the user that
link; opening it hits the stateless render endpoint:
GET /r?d=<gzip+base64url of the report JSON> → text/html
The endpoint decodes, validates against the report schema, and renders with the
fixed template. It is hardened for a public route: the d token and its
decompressed size are both capped (a gzip bomb is refused before it expands), the
page carries Content-Security-Policy: default-src 'none' + noindex, and every
value is escaped by the template — a crafted link can only ever produce an escaped
report.
Fallback. When RCSB_MCP_REPORT_BASE_URL is unset (e.g. local stdio dev with
no reachable endpoint) or a report is too large to pack into a URL, the tool
returns html instead of url, and the rcsb_search_assistant prompt tells the model to
write it to a .html file. Reports compress to ~1 KB even at 50 rows, so the
size fallback is rare.
Notes
- Search endpoint:
https://search.rcsb.org/rcsbsearch/v2/query(POST, JSON body). - Data endpoint:
https://data.rcsb.org/graphql(POST, GraphQL). It returns HTTP 200 even for query errors, reporting them in anerrorsarray. - Sequence Coordinates endpoint:
https://sequence-coordinates.rcsb.org/graphql(POST, GraphQL; same HTTP-200-with-errorsbehavior). - The
rcsb_find_*resolvers map free text to ontology ids via EBI services — the non-RCSB dependencies: GO via QuickGO (.../QuickGO/services/ontology/go/search), InterPro (.../interpro/api/entry/interpro/), EC via EBI Search/IntEnz (.../ebisearch/ws/rest/intenz), and disease via OLS/MONDO (.../ols4/api/search?ontology=mondo). The resolved ids then drive RCSB annotation searches (rcsb_polymer_entity_annotation.*,rcsb_polymer_entity.rcsb_ec_lineage.id,rcsb_uniprot_annotation.annotation_lineage.id). - No API key required; the APIs are public. Be considerate with request volume.
- A full list of searchable attributes for
rcsb_search_by_attributeis in the Search API attribute reference; the Data API schema is documented at data.rcsb.org/index.html#gql-api.
Prompt
The server also exposes an MCP prompt, rcsb_search_assistant ("RCSB PDB search
assistant") — the full tool-routing guide, followed by the search requirements and the
HTML-report output format. Because it is served over the protocol's prompts
capability, any MCP client can list and invoke it (e.g. Claude Desktop surfaces server
prompts in the + / prompt menu); there's nothing to copy-paste. The policy half lives
in
src/rcsb_mcp/prompts/rcsb_search_assistant.md
and the guide half is
rcsb_mcp_guide.md, joined at request time so
the two never drift; both ship with the package.
Invoke it when you want answers formatted as a PDB report. It is self-sufficient: the
appended guide is the same text as the always-on server instructions, so the prompt
still works on clients that never inject those — and the tool descriptions' "see the
server instructions" cross-references resolve against it. A second prompt,
rcsb_mcp_guide, serves that guide on its own for sessions that want the routing
guidance without the report policy; load one or the other, not both.
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。