Protein Mcp Server

io.github.cyanheadsPublished by GitHub account cyanheadsv0.9.0Updated Nov 4, 2026

Federated protein structure & annotation across experimental (PDB) and predicted (AlphaFold) models.

VerifiedStreamable HTTPWeb executableKnowledge & MemoryData & AnalyticsAI & ML

Overview

AI-generated overview

Federated protein structure and annotation server: search, fetch, align and annotate PDB and AlphaFold models from one MCP surface.

What you can do
  • Search experimental and predicted structures by text, sequence, organism, method, resolution or bound ligand, with optional facets
  • Fetch structure metadata and coordinate file URLs for PDB entries, AlphaFold models, or a best-available pick
  • Find sequence or fold homologs and align structures with TM-align or jFATCAT, resuming long jobs by ticket or job ID
  • Resolve ligands, list structures containing one, and map binding-site pocket residues
  • Profile the PDB as counts, histograms, timelines and cross-tabs, and read UniProt features, variants and InterPro domains
  • Expose PDB and AlphaFold summaries as resources, plus a protein-guide skill on identifier forms and chain numbering
When to use it
Useful when an assistant needs structural biology lookups: finding structures for a protein, comparing or aligning models, checking ligands and binding sites, or pulling sequence annotations and PDB-wide statistics without switching between RCSB, AlphaFold DB, UniProt and InterPro by hand.
Requirements
Either the public hosted Streamable HTTP endpoint or a local process via npx, bunx or Docker; Bun v1.4.0+ or Node.js v24+ for local runs. No accounts or API keys are needed. All configuration variables are optional, including MCP_TRANSPORT_TYPE, MCP_HTTP_PORT, MCP_AUTH_MODE and the PROTEIN_* tuning limits. Network access to the upstream public databases is required.
Before you install
Read-only lookups against public databases; no writes, payments or credentials are involved. Upstream data carries its own licenses: CC BY and CC BY-SA sources such as AlphaFold DB, SWISS-MODEL, UniProt and GO require attribution on redistribution, so keep the attribution block when reusing results. Long Foldseek and alignment jobs may return a computing status with a resume handle rather than finished results.

Installation

In SourceWeft

  1. Open Protein Mcp Server in the dashboard and add it to a workspace.
  2. Enable the server for the chats that should use its tools.

Web executable via Streamable HTTP. Remote servers run from the web runtime once configured in a workspace.

Use with an agent

Paste this prompt into Claude Code, Codex, Cursor or another agent — or into SourceWeft chat. The agent reads this server's install guide, shows you its publisher, endpoint and sign-in, and adds it to your client once you agree. Keys never go into a command.

Read https://sourceweft.com/mcp/io.github.cyanheads%2Fprotein-mcp-server/install.md and connect the MCP server it describes to my client. Before changing any config, show me its publisher, endpoint and sign-in method and wait for my OK. Never put an API key in a command or in a file I would commit; ask me where it should come from.

Read the install guide the agent follows

Other MCP clients

Add this to your client's mcpServers config.

{
  "mcpServers": {
    "protein": {
      "type": "http",
      "url": "https://protein.caseyjhand.com/mcp"
    }
  }
}

README

@cyanheads/protein-mcp-server

Federated protein structure & annotation across experimental (PDB) and predicted (AlphaFold) models via MCP. STDIO or Streamable HTTP.

7 Tools • 2 Resources

Public Hosted Server: https://protein.caseyjhand.com/mcp


Overview

Experimental (PDB) and predicted (AlphaFold) protein structures behind one surface. Search, fetch, align, and annotate structures and their ligands across RCSB, AlphaFold DB, 3D-Beacons, UniProt, InterPro, and Foldseek. No API key required.

Tools

ToolDescription
protein_search_structuresSearch experimental and predicted structures by text, sequence, or organism/method/resolution, with optional facets
protein_get_structureFetch metadata and coordinate URLs for experimental, predicted, or best-available structures
protein_find_similarFind sequence homologs (RCSB mmseqs2) or fold homologs (Foldseek)
protein_track_ligandsResolve ligands to component IDs, find structures containing one, or map its binding site
protein_compare_structuresAlign structures with TM-align or jFATCAT, against a reference or all pairs
protein_analyze_collectionProfile the PDB as counts, histograms, timelines, and cross-tabs
protein_get_annotationsFetch UniProt features and variants plus InterPro domains with GO terms

Resources

ResourceDescription
pdb://{entry_id}Experimental structure summary for a PDB entry
af://{uniprot}AlphaFold DB predicted-structure summary for a UniProt accession

Both resources are also reachable through protein_get_structure, for clients that don't surface resources.

Skills

SkillDescription
protein-guideIdentifier forms each tool takes, author vs label chains, residue numbering, and the gates for best_available picks, sequence and Foldseek hits, ligand counts, and PDB profiles

Served over MCP as skill://protein-guide/SKILL.md; it also ships in plugin installs, the .mcpb bundle, the npm package, and the Docker image.

Capability reference

protein_search_structures tool

  • At least one of query, sequence (an mmseqs2 search; min_identity / max_evalue apply only with it), organism, method, max_resolution, or ligand (an exact component ID held as a bound copy); content_type is experimental, predicted, or all (default); up to 100 hits per page (default 25) via limit / start
  • organism takes a scientific name, an NCBI common name, or a taxon ID, and matches that taxon plus every taxon under it; a word fragment matches nothing. method takes one of the 13 RCSB experimental methods in any letter case, or an alias (cryo-EM, cryoEM, EM, X-ray, xray, NMR for both NMR methods); anything else fails as unknown_method
  • A sequence needs at least 10 residues; whitespace is stripped and case normalized, and an invalid one fails as invalid_sequence. Each hit names its source and an entry id you can pass to other tools, and carries organisms (a sequence hit's are the matched entity's). Sequence hits add identity, evalue, bitscore, and the aligned ranges, with queryLength at the response level
  • Optional facets (method, organism, polymer_type, resolution, release_year, molecular_weight) add a breakdown capped at PROTEIN_FACET_BUCKET_CAP buckets per dimension; facets count the filtered set, so an active organism or method filter constrains its own facet

protein_get_structure tool

  • source: experimental (default) takes PDB entry IDs and the AF_* / MA_* computed-model IDs search returns (these come back as source: predicted); predicted takes UniProt accessions, isoform accessions (P04637-2), or AlphaFold DB entry IDs (AF-P04637-2-F1) for AlphaFold models with pLDDT/PAE; best_available takes the same identifiers (an entry ID reduces to its accession) and returns the PDB entry with the widest UniProt coverage (ties to the finest resolution), else the model with the highest confidence on the lDDT scale. Best-available records carry coverage, uniprotStart, and uniprotEnd; a pick can come from a non-PDB provider, and only a record with pdbId is a PDB entry. If the PDB check is unavailable, the pick ranks the federated models alone and notice says so
  • A UniProt accession merged into another entry resolves to its successor's model with a notice; a demerged or deleted one lands in failed[] with its replacements
  • IDs are trimmed and de-duplicated (case-insensitive); up to PROTEIN_MAX_BATCH_IDS are looked up per call (default 25) and the remainder comes back in ignored. One 50 s budget covers all upstream lookups in a call; under predicted and best_available, an ID it stops, or whose upstream lookup fails (an error status, an HTML page, a network failure), lands in failed[] with a reason to re-call it
  • Unresolved IDs land in failed[]; when nothing resolves the call fails as upstream_unavailable (retryable, with data.failed) if every ID's lookup failed upstream or ran out of the 50 s budget, so none is known to lack a structure, and otherwise as all_failed (with data.failed); it fails mixed_id_types when the IDs don't fit source. Records include coordinateUrls for the files that exist, and organisms under experimental and predicted
  • include_coords inlines coordinate text in 24,000-character windows: a single selected structure pages with coords_offset, passing back coordinatesNextOffset until it is absent; several selected files inline whole only when together they fit one window, otherwise an overflow outline lists each file's length to re-call with sections: [id]. coords_offset above 0 needs exactly one selected structure (coords_offset_needs_one_structure)

protein_find_similar tool

  • by: sequence runs a synchronous RCSB mmseqs2 search over experimental PDB entries only (protein_search_structures with a sequence also reaches computed models) from sequence, pdb_id, or uniprot, filtered by max_evalue / min_identity; by: structure runs an async Foldseek search from pdb_id (its mmCIF file) or uniprot (its AlphaFold DB model) against pdb100 + afdb50 unless databases says otherwise. uniprot takes a canonical or isoform accession, or a UniProtKB entry name such as HBA_HUMAN (resolved to its entry's accession), in both modes and is shape-checked before any request (invalid_accession). databases takes exactly these case-sensitive names: pdb100, afdb50, afdb-swissprot, afdb-proteome, bfvd_v3, cath50, mgnify_esm30, gmgcl_id, bfmd; any other fails schema validation (-32602), and a name Foldseek itself refuses fails as databases_rejected. A field only the other mode reads fails as mode_mismatched_field; up to 100 hits per page (default 25)
  • Sequences follow the same rules as protein_search_structures, and a direct sequence wins over identifiers. A pdb_id sequence query searches one protein entity: the one holding chain (author chain, case-sensitive, by: sequence only, requires pdb_id), else the lowest-numbered protein entity of at least 10 residues; DNA and RNA entities are never searched. The response names it in queryEntityId, and a notice lists the entry's other protein entities. An unmatched chain fails as chain_not_found, and chain without pdb_id as chain_without_pdb_id
  • Hits name their source (and database for structure hits), ranked by score; sequence hits add identity, evalue, bitscore, and the aligned ranges. Responses report totalCount, nextStart, and queryLength
  • A merged uniprot accession answers for its successor with a notice; a demerged or deleted one fails as inactive_accession with its replacements. A by: structure coordinate file is limited to 16,000,000 characters, and a larger one fails as structure_too_large
  • A structure hit carries Foldseek's target name and an id only when the target resolves to a PDB entry or UniProt accession; bfvd_v3, mgnify_esm30, gmgcl_id, and bfmd hits have none. Other structure-hit fields: chain (a -N suffix marks a symmetry copy), title, probability, organisms / taxId (the target's, where Foldseek classifies it), and the aligned spans queryStart, queryEnd, targetStart, targetEnd, targetLength. A sequence hit's organisms are the matched entity's
  • A structure job still running at the poll budget returns status: computing with a ticketId; re-call with ticket_id to resume it. A job Foldseek accepted before the call's 50 s budget ran out comes back the same way. For a new search the poll window starts when the call does, so identifier lookups and the coordinate download come out of it. A multichain structure is searched one chain at a time via query (0-based, default 0) out of queryCount

protein_track_ligands tool

  • mode is find_ligand (query: a name or formula), structures_with_ligand (comp_id), or binding_site (pdb_id, optional comp_id); a missing mode input fails as missing_param. limit is 1–100 (default 25), and start pages the last two modes
  • find_ligand returns component IDs with formula, weight, SMILES, and InChIKey, ranked by depositionCount, with totalCount and candidatesConsidered showing when the candidate pool was cut short; structures_with_ligand lists entries highest resolution first, each with title, method, and hostEntities (the polymer entities whose chains the depositor assigned the ligand to)
  • Matching counts bound non-polymer copies only, not a residue inside a polymer chain or a sugar inside a branched glycan; depositionCount equals the totalCount of structures_with_ligand for the same component
  • binding_site returns pocket residues with contact distances, numbered in both label (asymId, seqId) and author (authAsymId, authSeqId) namespaces, for ligand instances in a fixed order (ligand entity number, author chain, author residue number) so start / limit pages read each once; it works on experimental structures only

protein_compare_structures tool

  • 2 structures up to PROTEIN_MAX_COMPARE_STRUCTURES (default 10, max 25), each a pdb_id with an optional label-namespace chain; method is tm-align (default), fatcat-rigid, or fatcat-flexible; reference is first (default) or all_pairs; timeout_s (5–120) sets the per-pair poll budget
  • Each pair row has a status (complete, computing, failed), tmScore, rmsd, alignedResidues, modeledResidues, and coverage; TM-score is normalized by a's length, so reversing a pair changes it. similarityScore and sequenceSimilarity appear when the upstream supplies them
  • Structures past the cap return in ignored as { pdb_id, chain? }, not compared. A computing pair returns its job uuid; re-call with { a, b, uuid } in resume[] to poll it instead of resubmitting. A mismatched method or pair fails as resume_method_mismatch or resume_job_mismatch

protein_analyze_collection tool

  • group_by takes one of method, organism, polymer_type, resolution, release_year, molecular_weight, or two distinct ones for a cross-tab; scope with query, organism, method, max_resolution, and content_type (default experimental); organism and method take the same forms as in protein_search_structures, and an unknown method fails as unknown_method. interval sets a numeric bin width for resolution / molecular_weight or "year" for release_year
  • Returns total and bucketsReturned; buckets carry label and count (numeric bins add rangeFrom / rangeTo), and every dimension reports missingValueCount
  • bucket_limit (1–500, default PROTEIN_FACET_BUCKET_CAP) caps each dimension separately; truncated and notice say where results were cut

protein_get_annotations tool

  • A canonical uniprot accession, or a pdb_id resolved through its UniProt cross-reference (author chain picks one accession); include is features, domains, variants, or all (default); limit pages each class separately (1–200, default 50), with independent zero-based features_offset, variants_offset, and domains_offset (default 0)
  • Returns UniProt features (domains, binding and active sites, PTMs, topology, processing products such as chains and signal peptides, mutagenesis, and more) and natural variants plus InterPro domains with GO terms; a PDB entry mapping to several accessions uses the lowest author chain and lists the rest in ambiguity
  • An isoform accession fails as invalid_accession, naming the canonical one. An accession UniProt merged into another entry answers as its successor, with the merge named first in notice; a demerged or deleted one fails as inactive_accession with its replacements
  • Each requested class carries featuresTotal, variantsTotal, or domainsTotal (InterPro's own membership count); a page with more records sets truncated and names the next offset in notice, and an InterPro walk that stops short of its count sets truncated and says how many memberships domains_offset can reach. One 50 s budget covers every upstream request in a call
  • Failures are typed as missing_identifier, invalid_accession, accession_not_found, inactive_accession, no_uniprot_mapping, or chain_not_found

pdb://{entry_id} resource

  • entry_id is a PDB entry ID (e.g. 4HHB); returns application/json with title, methods, resolution, organisms, ligands, and polymerEntities carrying both authAsymIds and labelAsymIds
  • Same data as protein_get_structure with source: experimental

af://{uniprot} resource

  • uniprot is a UniProt accession, an isoform accession (e.g. P04637-2), or an AlphaFold DB entry ID (e.g. AF-P69905-F1); returns application/json with meanPlddt, confidenceBuckets, cifUrl / pdbUrl / bcifUrl, and modelVersion, plus a notice when UniProt merged the accession into another entry (the successor's model answers)
  • Failures are typed as invalid_accession, no_model, accession_not_found, or inactive_accession (with its replacements)
  • Same data as protein_get_structure with source: predicted

Features

Built on @cyanheads/mcp-ts-core: stdio and Streamable HTTP transports, pluggable auth (none / jwt / oauth), swappable storage (in-memory, filesystem, Supabase, Cloudflare KV/R2/D1), structured logging with optional OpenTelemetry tracing.

PDB / AlphaFold-specific:

  • Search, fetch, and comparison treat experimental (PDB) and predicted (AlphaFold DB, ModelArchive, 3D-Beacons providers) structures the same way
  • Keyless across RCSB, AlphaFold DB, 3D-Beacons, UniProt, InterPro, and Foldseek
  • Collection analytics run on RCSB's facet engine and return bucket counts, not matching entries
  • Foldseek and alignment jobs poll for up to PROTEIN_ASYNC_POLL_TIMEOUT_MS (default 30 s), then hand back a resume handle (ticketId, per-pair uuid) instead of blocking
  • Chain namespaces stay separate: authAsymIds feed protein_get_annotations chain, labelAsymIds feed protein_compare_structures chain

Agent-friendly output:

  • Provenance: every hit names its source (experimental / predicted) and the engine or database behind it, and protein_get_structure and protein_get_annotations carry an attribution block (see Upstream data licensing)
  • Graceful partial failure: failed[] rows and per-pair status keep one bad ID or pair from failing the request
  • Paging and advisories: paged tools return totalCount and nextStart, a start past the end is flagged in notice separately from zero matches, and every advisory joins into that one notice

Getting started

Public Hosted Instance

A public instance is available at https://protein.caseyjhand.com/mcp, no installation required. Point any MCP client at it via Streamable HTTP:

json
{  "mcpServers": {    "protein-mcp-server": {      "type": "streamable-http",      "url": "https://protein.caseyjhand.com/mcp"    }  }}

Self-Hosted / Local

Add the following to your MCP client configuration file. No API key is needed.

json
{  "mcpServers": {    "protein-mcp-server": {      "type": "stdio",      "command": "bunx",      "args": ["@cyanheads/protein-mcp-server@latest"],      "env": {        "MCP_TRANSPORT_TYPE": "stdio",        "MCP_LOG_LEVEL": "info"      }    }  }}

Or with npx (no Bun required):

json
{  "mcpServers": {    "protein-mcp-server": {      "type": "stdio",      "command": "npx",      "args": ["-y", "@cyanheads/protein-mcp-server@latest"],      "env": {        "MCP_TRANSPORT_TYPE": "stdio",        "MCP_LOG_LEVEL": "info"      }    }  }}

Or with Docker:

json
{  "mcpServers": {    "protein-mcp-server": {      "type": "stdio",      "command": "docker",      "args": ["run", "-i", "--rm", "-e", "MCP_TRANSPORT_TYPE=stdio", "ghcr.io/cyanheads/protein-mcp-server:latest"]    }  }}

For Streamable HTTP, set the transport and start the server:

sh
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http# Server listens at http://localhost:3010/mcp

Prerequisites

  • Bun v1.4.0 or higher (or Node.js v24+).
  • No accounts or API keys: every upstream is public.

Installation

  1. Clone the repository:
sh
git clone https://github.com/cyanheads/protein-mcp-server.git
  1. Navigate into the directory:
sh
cd protein-mcp-server
  1. Install dependencies:
sh
bun install
  1. Configure environment (optional):
sh
cp .env.example .env# every variable has a working default

Configuration

Every variable is optional.

VariableDescriptionDefault
PROTEIN_ASYNC_POLL_TIMEOUT_MSPoll budget for an async alignment or Foldseek job before it returns computing (min 1000). For protein_find_similar keep it at or below 45000: the call's 50 s upstream budget ends a longer poll.30000
PROTEIN_MAX_BATCH_IDSMax IDs per protein_get_structure call (1–100).25
PROTEIN_MAX_COMPARE_STRUCTURESMax structures per protein_compare_structures call (2–25).10
PROTEIN_FACET_BUCKET_CAPBuckets per dimension for protein_search_structures facets, and the protein_analyze_collection default (1–500).50
PROTEIN_FANOUT_CONCURRENCYMax concurrent upstream requests for per-ID and per-pair fan-out (1–16).5
MCP_TRANSPORT_TYPETransport: stdio or http.stdio
MCP_HTTP_PORTHTTP server port.3010
MCP_SESSION_MODEHTTP session mode: stateless, stateful, or auto. Overrides the stateless mode the server declares in code.stateless
MCP_AUTH_MODEAuthentication: none, jwt, or oauth.none
MCP_LOG_LEVELLog level (RFC 5424).info
OTEL_ENABLEDEnable OpenTelemetry.false

Each upstream's base URL can also be pointed at a mirror: RCSB_SEARCH_BASE_URL, RCSB_DATA_BASE_URL, RCSB_FILES_BASE_URL, RCSB_MODELS_BASE_URL, RCSB_ALIGNMENT_BASE_URL, BEACONS_BASE_URL, ALPHAFOLD_BASE_URL, MODELARCHIVE_BASE_URL, FOLDSEEK_BASE_URL, UNIPROT_BASE_URL, INTERPRO_BASE_URL. See .env.example for their defaults and the full list of optional overrides.

Running the server

Local development

  • Build and run:

    sh
    # One-time buildbun run rebuild
    # Run the built serverbun run start:stdio# orbun run start:http
  • Run checks and tests:

    sh
    bun run devcheck   # Lint, format, typecheck, securitybun run test       # Vitest test suitebun run lint:mcp   # Validate MCP definitions against spec

Docker

sh
docker build -t protein-mcp-server .docker run --rm -p 3010:3010 protein-mcp-server

The Dockerfile defaults to HTTP transport, stateless session mode, and logs to /var/log/protein-mcp-server. OpenTelemetry peer dependencies are installed by default; build with --build-arg OTEL_ENABLED=false to omit them.

Project structure

DirectoryPurpose
src/index.tscreateApp() entry point: registers tools and resources, serves skills/, inits the provider services.
src/configServer-specific environment variable parsing and validation with Zod.
src/mcp-server/toolsTool definitions (*.tool.ts) and shared schemas (_schemas.ts).
src/mcp-server/resourcesResource definitions (*.resource.ts).
src/servicesUpstream clients: rcsb/ (search, data, facets), alphafold/, beacons/ (3D-Beacons), uniprot/ (UniProt, InterPro, GO), alignment/ (RCSB Structural Comparison), foldseek/, and shared/ HTTP, concurrency, identifier, and attribution helpers.
skills/The published protein-guide agent skill, served over MCP and shipped in plugin installs, the .mcpb bundle, the npm package, and the Docker image.
tests/Unit and integration tests mirroring src/.

Development guide

See CLAUDE.md/AGENTS.md for development guidelines and architectural rules. The short version:

  • Handlers throw, framework catches — no try/catch in tool logic
  • Use ctx.log for request-scoped logging, ctx.state for tenant-scoped storage
  • Export new definitions from the barrels in src/mcp-server/*/definitions/index.ts and register them in the createApp() arrays in src/index.ts
  • Wrap external API calls: validate raw → normalize to domain type → return output schema; never fabricate missing fields

Upstream data licensing

Structure and annotation data comes from public databases, each under its own license. protein_get_structure and protein_get_annotations return an attribution block with the license, citation, and homepage of every source that contributed to that response. CC BY and CC BY-SA sources require attribution on redistribution; CC0 sources ask only for citation.

SourceContributes toLicense
RCSB PDBprotein_get_structure — experimental recordsCC0 1.0 Universal
AlphaFold DBprotein_get_structure — predicted modelsCC BY 4.0
ModelArchiveprotein_get_structure — MA_* computed modelsCC BY 4.0
SWISS-MODELprotein_get_structure — best_available modelsCC BY-SA 4.0
BFVDprotein_get_structure — best_available modelsCC BY 4.0
UniProtprotein_get_annotationsCC BY 4.0
InterProprotein_get_annotations — domain/family dataCC0 1.0 Universal
GOprotein_get_annotations — GO termsCC BY 4.0

best_available models arrive through 3D-Beacons, so the block credits the provider that actually supplied the model; a provider with no curated entry gets a See provider terms fallback instead of a guessed license. InterPro and GO are credited separately, each only when it contributes. This table covers upstream data; the server's own code is licensed separately (see License).

Contributing

Issues are welcome. Run checks and tests before submitting:

sh
bun run devcheckbun run test

License

Apache-2.0 — see LICENSE for details.

Source: README.md at commit 2a27da2

Tools

7

protein_search_structures

protein-mcp-server: search structures

Search experimental (PDB) and predicted (computed-model) protein structures by free text, protein sequence (triggers an mmseqs2 similarity search), and/or organism, method, resolution, and bound-ligand filters. Returns ranked hits; the experimental page is enriched with title, method, resolution, and source organisms (for a sequence hit, those of the matched entity), and every sequence hit carries its identity, E-value, bit score, and aligned range against the query. Chain hit IDs into protein_get_structure. Optionally returns a facet breakdown (counts by method / organism / release year / …) alongside the hits in the same response. Facets count the filtered result set, so an active organism or method filter also constrains its own facet: the facet lists only the values found in the matching entries (other organisms in the same complexes, other methods deposited with the same entries), never the alternatives the filter excluded. Numeric histogram buckets (resolution, molecular weight) carry explicit rangeFrom/rangeTo bounds so a boundary label is unambiguous.

Parameterslimitquerystartfacetsligandmethodorganismsequencemax_evaluecontent_typemin_identitymax_resolution

protein_get_structure

protein-mcp-server: get structure

Fetch structures with metadata and coordinate-file URLs. source "experimental" takes PDB entry IDs, and also resolves the computed-model IDs protein_search_structures returns (AF_*/MA_*), which come back marked source "predicted" with their modelling provider; "predicted" takes UniProt accessions, isoform accessions (P04637-2), or AlphaFold DB entry IDs (AF-P04637-2-F1) (AlphaFold, with pLDDT/PAE confidence); "best_available" takes the same identifiers, an entry ID reduced to its accession, and returns the top federated model — the PDB entry with the widest UniProt coverage, ties going to the finest resolution (coverage measures the mapped span, so the pick can be an engineered mutant over the wild-type entry), else the model with the highest confidence on the lDDT scale (pLDDT/100 or QMEANDisCo), unscored models last, which can include an experimental model outside the PDB such as a SASBDB fit; best_available records carry coverage and the UniProt span. Under predicted and best_available, a UniProt accession merged into another entry resolves to its successor's model with a notice naming the merge, and a demerged or deleted accession lands in failed[] with its replacements. Records fetched under source "experimental", computed models included, also carry polymer entities with both chain namespaces (labelAsymIds for protein_compare_structures, authAsymIds for protein_get_annotations), bound ligands, molecular weight, and release date. Resolves up to the configured batch cap per call with per-ID partial success: IDs are trimmed and repeats looked up once, missed IDs are listed in failed[] with their reasons, and IDs beyond the cap are listed in ignored, never looked up. Upstream lookups share one time budget per call; under predicted and best_available, an ID not finished within it, or whose upstream lookup failed, lands in failed[] with a reason to re-call it. Set include_coords to inline coordinate text, held to 24000 characters per response on both surfaces: a lon

Parametersidsrequiredsourcesectionscoords_offsetinclude_coords

protein_find_similar

protein-mcp-server: find similar

Find structurally or evolutionarily related proteins. by:"sequence" runs an RCSB mmseqs2 sequence-similarity search (synchronous; experimental PDB entries only — protein_search_structures with a sequence also reaches computed models) over a sequence — supplied directly, taken from one protein entity of a PDB entry (chain picks it; by default the lowest-numbered protein entity of at least 10 residues; queryEntityId names it), or pulled from a UniProt accession (isoforms included) or entry name (HBA_HUMAN); each hit carries its identity, E-value, bit score, and aligned range. by:"structure" runs a Foldseek fold-similarity search (asynchronous) against experimental and predicted databases, uploading the PDB entry's mmCIF file or the accession's AlphaFold DB model, up to 16,000,000 characters; if the job is still computing when the poll budget elapses, or the call's 50 s budget runs out after Foldseek accepted the job, the response reports status "computing" with a ticket — re-call with ticket_id set to that value to resume the same job instead of resubmitting, and a complete response carries the same ticket so a finished job can be re-paged with a different start. Foldseek searches each chain of a multichain structure as its own query: a response covers one query (query, default 0), reports queryCount, and ranks that query's hits by score across all searched databases. Each mode reads only its own controls: sequence, chain, max_evalue and min_identity belong to by:"sequence"; ticket_id, databases and query belong to by:"structure"; pdb_id, uniprot, start and limit are shared. A field the selected mode cannot consume is rejected rather than silently ignored. A UniProt accession merged into another entry answers for its successor with a notice; a demerged or deleted one fails with its replacements. Output names the engine and database each hit came from; a structure hit also carries its Foldseek target name, and an id only where that name maps to a PDB entry or UniProt a

Parametersbyrequiredchainlimitquerystartpdb_iduniprotsequencedatabasesticket_idmax_evaluemin_identity

protein_track_ligands

protein-mcp-server: track ligands

Ligand discovery and binding-site analysis across the PDB. mode "find_ligand" resolves a name or formula to chemical component IDs with metadata (formula, weight, SMILES), ranked by deposition frequency — most-deposited component first, so the top hit is the most common match for the name, not necessarily an exact name-string match. The ranking covers a bounded candidate pool; totalCount and candidatesConsidered report how many components matched and how many were ranked. mode "structures_with_ligand" returns PDB entries holding a bound copy of a ligand (by exact component ID — get the ID from find_ligand first), highest-resolution first, each with its resolution in Å, title, method, and the polymer entities whose chains carry the ligand. This mode and find_ligand's depositionCount count bound copies only: a component present only as a residue inside a polymer chain (e.g. MSE in a selenomethionine protein) or a sugar inside a branched glycan is not counted. mode "binding_site" returns the protein residues lining a ligand's pocket in a given structure, with contact distances, each numbered in both the mmCIF label namespace (asymId, seqId) and the author namespace (authAsymId, authSeqId) used by deposited coordinates and most literature. Binding sites are experimental-only (computed from deposited coordinates; predicted models carry no bound ligands).

Parametersmoderequiredlimitquerystartpdb_idcomp_id

protein_compare_structures

protein-mcp-server: compare structures

Structurally align multiple structures (up to the configured batch cap; structures past it are returned in ignored) via the RCSB Structural Comparison service (TM-align / jFATCAT). reference:"first" aligns every structure to the first; reference:"all_pairs" computes the full pairwise matrix. Each pair is an independent async alignment job with per-pair partial success — a pair still computing when the budget elapses returns status "computing" with its job UUID, and a failed pair degrades its row without sinking the others. Re-call with a matching entry in resume[] to poll a computing pair's UUID instead of resubmitting; a resumed pair reports a and b in the order its job was submitted, and a resume under a different method is rejected. Returns TM-score, RMSD, and aligned-residue count per pair, plus each structure's modeled-residue count and alignment coverage. TM-score is length-normalized and can shift sharply between structures that differ only by a terminal residue or two — the greedy superposition can settle into a worse local optimum — so read tmScore alongside rmsd, alignedResidues, modeledResidues and coverage, the columns that make such cases diagnosable.

Parametersmethodresumereferencetimeout_sstructuresrequired

protein_analyze_collection

protein-mcp-server: analyze collection

Profile the PDB into distributions and trends over an optional scoping query: counts by method, organism, or polymer composition; resolution and molecular-weight histograms; release-year timelines; and multidimensional cross-tabs (e.g. method × release_year). Aggregation runs at RCSB, so the response carries compact counts per bucket rather than the matching entries. Pass one group_by dimension for a single breakdown, or two distinct dimensions for a cross-tab (the first nests the second). bucket_limit caps each dimension level separately rather than the response, so a cross-tab returns up to that many nested buckets under each of its capped parent buckets; bucketsReturned reports the realized total.

Parametersquerymethodgroup_byrequiredintervalorganismbucket_limitcontent_typemax_resolution

protein_get_annotations

protein-mcp-server: get annotations

Sequence and functional annotation for a protein: UniProt positional features (domains, binding and active sites, PTMs including cross-links and lipidation, topology, DNA binding, processing products such as chains and signal peptides, mutagenesis), natural variants, and InterPro domain/family memberships (Pfam, PROSITE, …) with GO terms. Provide a canonical UniProt accession directly, or a PDB ID — it is resolved to its UniProt accession via the structure's sequence cross-reference. A multi-chain PDB entry can map to several accessions; the default pick is deterministic (lowest author chain ID) and the alternatives are listed in "ambiguity" — pass "chain" to select a specific one. An accession UniProt merged into another entry answers for that successor with a notice; a demerged or deleted one fails with its replacement accessions. Use "include" to scope which annotation classes are fetched. Every response carries an "attribution" block with the upstream data licenses and citations.

Parameterschainlimitpdb_idincludeuniprotdomains_offsetfeatures_offsetvariants_offset

Version history

2
  1. v0.9.0LatestNov 4, 2026
  2. v1.0.3Sep 16, 2026

Score

100% of the applicable checks met

How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.

  • Reached in the last 30 daysRequired25 pts
  • Auth declaredRequired10 pts
  • Tools listedRequired15 pts
  • DescriptionRequired15 pts
  • Logo10 pts
  • Documentation15 pts
  • License10 pts