protein-mcp-server

by cyanheads

Not rated
GitHub

About

Protein structures (PDB, UniProt)

Details

Author
cyanheads
Categories
Productivity, Other, Database

Setup

Install protein-mcp-server in your MCP client (Claude Desktop, Cursor, Windsurf, and others).

Repository: https://github.com/cyanheads/protein-mcp-server

Follow the installation instructions in the repository README, then restart your MCP client.

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

Seven tools spanning the structure-research arc — discover, fetch, find homologs, track ligands, compare, profile the corpus, and annotate — over experimental (PDB) and predicted (AlphaFold) structures from one surface:

Federated search across experimental (PDB) and predicted (computed-model) structures via RCSB Search v2.

- Free-text, protein-sequence (triggers an mmseqs2 similarity search), and organism / method / resolution filters
- content_typescopes the search toexperimental,predicted, orall— the defaultallis a genuine union of both universes, so computed models appear alongside PDB entries
- Every hit names itssource; experimental hits are enriched with title, method, resolution, and organism, while computed models carry the UniProt accession parsed from their ID
- Optionalfacetsreturn a method / organism / release-year breakdown alongside the hits at no extra call, each reporting how many matches carry no value for that dimension; each dimension may be listed once
- Chain hit IDs straight intoprotein_get_structure

Fetch structures with metadata and coordinate-file URLs, resolving across providers bysource.

- source: experimentaltakes PDB entry IDs, batched in one RCSB GraphQL call; it also resolves the computed-model IDs search returns (AF_/MA_), which come back assource: predictedcredited to their modelling provider
- source: predictedtakes UniProt accessions and returns the AlphaFold model with pLDDT/PAE confidence
- source: best_availabletakes UniProt accessions and returns the top federated model (experimental if one exists, else the best prediction)
- Per-ID partial success — unresolved IDs are listed infailed
[], not a batch-level error
- include_coordsinlines coordinate content; when a batch overflows the response budget it returns a per-structure size outline, so you can re-call withsections: [ids]for specific structures
- Every response carries anattributionblock naming the upstream data licenses and citations (seeUpstream data licensing)

Find structurally or evolutionarily related proteins, by sequence or by fold.

- by: sequenceruns a synchronous RCSB mmseqs2 search;by: structureruns an asynchronous Foldseek search against experimental and predicted databases
- Query from a raw one-letter sequence, a PDB ID, or a UniProt accession
- Foldseek targets default topdb100+afdb50; override viadatabases(e.g.afdb-swissprot,BFVD)
- Async jobs that exceed the poll budget returnstatus: computingwith aticketId— re-call withticket_idset to that value to poll the same job instead of resubmitting
- Each hit names the engine and source database it came from

Ligand discovery and binding-site analysis across the PDB.

- mode: find_ligandresolves a name or formula to chemical component IDs with formula, weight, SMILES, and InChIKey
- mode: structures_with_ligandreturns PDB entries containing a ligand by exact component ID
- mode: binding_sitereturns the protein residues lining a ligand's pocket in a structure, with contact distances
- Binding sites are experimental-only — computed from deposited coordinates (predicted models carry no bound ligands)

Structural alignment of multiple structures (up to the configuredPROTEIN_MAX_COMPARE_STRUCTUREScap) via the RCSB Structural Comparison service.

- Methods:tm-align,fatcat-rigid,fatcat-flexible
- reference: firstaligns every structure to the first;reference: all_pairscomputes the full pairwise matrix
- Optional per-structurechainrestricts the alignment to a single chain
- A structure repeated instructures
[]is compared once — the repeat would only add a self-alignment and a mirrored pair, which the resume mechanism cannot tell apart from the original
- Each pair is an independent async job, fanned out with a concurrency cap and per-pair partial success — a pair still computing when the budget elapses returnsstatus: computingwith its jobuuid, and a failed pair degrades its row without sinking the others
- Re-call with a matching{ a, b, uuid }entry inresume[](copied from a prior response'spairs[]) to poll a computing pair's job instead of resubmitting
- Returns TM-score, RMSD, and aligned-residue count per pair, plusmodeledResiduesandcoverage— each a[a, b]tuple, with coverage a 0–100 percentage of that structure's own modeled-residue count

Profile the PDB into distributions and trends over an optional scoping query — backed by RCSB's server-side facet engine (one call, compact buckets, no row pull).

- Group bymethod,organism,polymer_type,resolution,release_year, ormolecular_weight
- Onegroup_bydimension for a breakdown, or two distinct dimensions for a cross-tab (the first nests the second); a repeated dimension is rejected
- intervalsets the bin width for value histograms or the period for date histograms (year/month/quarter)
- Scope with a free-textquery,organism,method, ormax_resolution;content_typeselects the structure universe
- bucket_limitcaps buckets per dimension level, not per response — a cross-tab applies it separately to the parent dimension and to the nested child inside each parent bucket, so up tobucket_limit × (1 + bucket_limit)buckets come back. Each level flags its own truncation, andbucketsReturnedgives the realized total
- Every dimension reportsmissingValueCount— matches in scope carrying no value for that attribute, which therefore fall in no bucket (aresolutionbreakdown does not cover NMR entries, and neithermethodnorresolutioncovers computed models)

Sequence and functional annotation for a protein.

- UniProt features (domains, binding sites, PTMs) and natural sequence variants
- InterPro domain/family memberships (Pfam, PROSITE, …) with associated GO terms
- Provide a UniProt accession directly, or a PDB ID — resolved to a UniProt accession via the structure's sequence cross-reference
- A multi-chain PDB entry can map to several accessions; the default is the deterministic lowest-author-chain pick, with the alternatives listed underambiguity. Passchain(an author chain ID, e.g.A) to select a specific one
- includescopes which annotation classes are fetched:features,domains,variants, orall
- Every response carries anattributionblock naming the upstream data licenses and citations (seeUpstream data licensing)

All resource data is also reachable via tools —pdb://{entry_id}mirrorsprotein_get_structureforsource: experimental, andaf://{uniprot}mirrors it forsource: predicted. Many MCP clients are tool-only and don't surface resources; the summaries remain reachable through the tools.

- Declarative tool and resource definitions — single file per primitive, framework handles registration and validation
- Unified error handling — handlers throw, framework catches, classifies, and formats
- Pluggable auth:none,jwt,oauth
- Swappable storage backends:in-memory,filesystem,Supabase,Cloudflare KV/R2/D1
- Structured logging with optional OpenTelemetry tracing
- STDIO and Streamable HTTP transports

- One federated surface over experimental (PDB) and predicted (AlphaFold / 3D-Beacons) structures — search, fetch, and compare treat both universes the same
- Keyless across every upstream — RCSB, AlphaFold DB, 3D-Beacons, UniProt, InterPro, and Foldseek, no API keys to provision
- Corpus analytics run server-side on RCSB's facet engine — distributions, histograms, and cross-tabs in one call, no row pull and no SQL workspace
- Async alignment and Foldseek jobs poll within a bounded budget and hand back a job ticket (ticketId/ per-pairuuid) instead of blocking — re-call withticket_idor aresume
[]entry to poll the same job instead of resubmitting

- Provenance on every response — each hit carries asource(experimental/predicted), the engine and database that produced it, and effective-query / total-count echoes so agents can reason about coverage
- Graceful partial failure — batch fetches and pairwise comparisons return per-item rows (failed[], per-pairstatus) instead of failing the whole request, each with actionable recovery text
- Discriminated output contracts — typedsourceandstatusunions,computingresults with resume tickets, and budget-overflow outlines let callers branch on data, not string parsing

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

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

Add the following to your MCP client configuration file. No API key is required — every upstream provider is keyless.

{ "mcpServers": { "protein-mcp-server": { "type": "stdio", "command": "bunx", "args": ["@cyanheads/protein-mcp-server@latest"], "env": { "MCP_TRANSPORT_TYPE": "stdio", "MCP_LOG_LEVEL": "info" } } } }
{ "mcpServers": { "protein-mcp-server": { "type": "stdio", "command": "npx", "args": ["-y", "@cyanheads/protein-mcp-server@latest"], "env": { "MCP_TRANSPORT_TYPE": "stdio", "MCP_LOG_LEVEL": "info" } } } }
{ "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:

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

- Bun v1.3.2or higher (or Node.js v24+).
- No accounts or API keys — RCSB, AlphaFold DB, 3D-Beacons, UniProt, InterPro, and Foldseek are all public and keyless.

git clone https://github.com/cyanheads/protein-mcp-server.git

All upstream providers are keyless, so the server runs out of the box with no configuration. Every variable below is optional.

See.env.examplefor the full list of provider base-URL overrides and tuning limits.

# One-time build bun run rebuild # Run the built server bun run start:stdio # or bun run start:http
bun run devcheck # Lint, format, typecheck, security bun run test # Vitest test suite bun run lint:mcp # Validate MCP definitions against spec
docker build -t protein-mcp-server . docker run --rm -e MCP_TRANSPORT_TYPE=http -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=falseto omit them.

SeeCLAUDE.md/AGENTS.mdfor development guidelines and architectural rules. The short version:

- Handlers throw, framework catches — notry/catchin tool logic
- Usectx.logfor request-scoped logging,ctx.statefor tenant-scoped storage
- Register new tools and resources via the barrels insrc/mcp-server//definitions/index.ts
- Wrap external API calls: validate raw → normalize to domain type → return output schema; never fabricate missing fields

Issues and pull requests are welcome. Run checks and tests before submitting:

Structure and annotation data comes from public upstream databases, each under its own license.protein_get_structureandprotein_get_annotationscarry anattributionblock on every response — the license, citation, and homepage for each source that contributed to that specific response — so the attribution obligation travels with the data to downstream consumers rather than living only here. CC BY / CC BY-SA sources require attribution on redistribution; CC0 sources are citation-only (attribution encouraged, not required).

best_availablefederates predicted models through3D-Beacons, so theattributionblock credits the actual contributing provider (AlphaFold DB, SWISS-MODEL, BFVD, …); a provider without a curated license entry carries aSee provider termsfallback pointing back to 3D-Beacons rather than a fabricated license. InterPro's own domain/family classifications are CC0; the GO terms carried alongside them are separately CC BY 4.0, so each is credited independently only when it actually contributes. Full citations for each source travel in theattributionblock of the relevant tool responses. This covers upstreamdata*licensing — the server's own code is licensed separately (seeLicense).

Access and interact with Allen Institute for Neural Dynamics (AIND) metadata directly within your IDE.

A high-performance JavaScript server for the Alliance of Genome Resources (AGR) MCP.

Access the AlphaFold Protein Structure Database for protein structure prediction and analysis.

Interface with Biomart, a biological data query tool, using the pybiomart Python package.

Agent-first rewrite of genomeoncology's BioMCP in TypeScript to provide next-gen biomedical data access for agents.

Perform complex queries on the DANDI Archive, a platform for neurophysiology data.

Interact with DROMA drug-omics association analysis databases using natural language.

A bridge to the Drug Gene Interaction Database (DGIdb) API, enabling AI clients to query drug-gene interaction data.

A search server for PubMed, the biomedical literature database, using a pure Node.js implementation.

Query the Materials Project database using the mp_api client. Requires an MP_API_KEY environment variable.

No reviews yet — be the first

Sign in to leave a review

Use Google, GitHub, or an email account so ratings stay tied to real people.

Email sign in

No reviews posted yet.