io.github.cyanheads/protein-mcp-server

平台与服务

by cyanheads

用于获取和分析 3D 蛋白质结构数据的 MCP Server,支持 RCSB PDB、PDBe 与 UniProt。

什么是 io.github.cyanheads/protein-mcp-server?

用于获取和分析 3D 蛋白质结构数据的 MCP Server,支持 RCSB PDB、PDBe 与 UniProt。

README

<div align="center"> <h1>@cyanheads/protein-mcp-server</h1> <p><b>Federated protein structure & annotation across experimental (PDB) and predicted (AlphaFold) models via MCP. STDIO or Streamable HTTP.</b> <div>7 Tools • 2 Resources</div> </p> </div> <div align="center">

Version License Docker MCP SDK npm TypeScript Bun

</div> <div align="center">

Install in Claude Desktop Install in Cursor Install in VS Code

Framework

</div> <div align="center">

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

</div>

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.

Capability reference

protein_search_structures <sub>tool</sub>

  • At least one of query, sequence (an mmseqs2 search; min_identity / max_evalue apply only with it), organism, method, or max_resolution; content_type is experimental, predicted, or all (default); up to 100 hits per page (default 25) via limit / start
  • 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
  • Optional facets (method, organism, polymer_type, resolution, release_year, molecular_weight) add a breakdown capped at PROTEIN_FACET_BUCKET_CAP buckets per dimension

protein_get_structure <sub>tool</sub>

  • 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 for AlphaFold models with pLDDT/PAE; best_available takes UniProt accessions and returns the highest-resolution experimental structure, else the best prediction. Up to PROTEIN_MAX_BATCH_IDS IDs per call (default 25)
  • Unresolved IDs land in failed[], and requested / processed show IDs dropped past the cap; the call fails as all_failed when nothing resolves and mixed_id_types when the IDs don't fit source. Records include coordinateUrls for the files that exist
  • include_coords inlines coordinate text within a size budget; an over-budget batch returns an overflow outline to re-call with sections: [ids]

protein_find_similar <sub>tool</sub>

  • by: sequence runs a synchronous RCSB mmseqs2 search from sequence, pdb_id, or uniprot, filtered by max_evalue / min_identity; by: structure runs an async Foldseek search from pdb_id or uniprot against pdb100 + afdb50 unless databases says otherwise. 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. Hits name their source (and database for structure hits), ranked by score; responses report totalCount and nextStart
  • A structure job still running at the poll budget returns status: computing with a ticketId; re-call with ticket_id to resume it. A multichain structure is searched one chain at a time via query (0-based, default 0) out of queryCount

protein_track_ligands <sub>tool</sub>

  • 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
  • binding_site returns pocket residues with contact distances, numbered in both label (asymId, seqId) and author (authAsymId, authSeqId) namespaces; it works on experimental structures only

protein_compare_structures <sub>tool</sub>

  • 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
  • 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 <sub>tool</sub>

  • 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). 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 <sub>tool</sub>

  • A 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 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
  • Each requested class carries featuresTotal, variantsTotal, or domainsTotal; a page with more records sets truncated and names the next offset in notice
  • Failures are typed as missing_identifier, invalid_accession, no_uniprot_mapping, or chain_not_found

pdb://{entry_id} <sub>resource</sub>

  • 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} <sub>resource</sub>

  • uniprot is a UniProt accession or an AlphaFold DB entry ID (e.g. AF-P69905-F1); returns application/json with meanPlddt, confidenceBuckets, cifUrl / pdbUrl / bcifUrl, and modelVersion
  • 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).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 build
    bun run rebuild
    
    # Run the built server
    bun run start:stdio
    # or
    bun run start:http
    
  • Run checks and tests:

    sh
    bun run devcheck   # Lint, format, typecheck, security
    bun run test       # Vitest test suite
    bun 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, 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.
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 devcheck
bun run test

License

Apache-2.0 — see LICENSE for details.

常见问题

io.github.cyanheads/protein-mcp-server 是什么?

用于获取和分析 3D 蛋白质结构数据的 MCP Server,支持 RCSB PDB、PDBe 与 UniProt。

相关 Skills

MCP构建

by anthropics

Universal
热门

聚焦高质量 MCP Server 开发,覆盖协议研究、工具设计、错误处理与传输选型,适合用 FastMCP 或 MCP SDK 对接外部 API、封装服务能力。

✎ 想让 LLM 稳定调用外部 API,就用 MCP构建:从 Python 到 Node 都有成熟指引,帮你更快做出高质量 MCP 服务器。

平台与服务
未扫描176.4k

Slack动图

by anthropics

Universal
热门

面向Slack的动图制作Skill,内置emoji/消息GIF的尺寸、帧率和色彩约束、校验与优化流程,适合把创意或上传图片快速做成可直接发送的Slack动画。

✎ 帮你快速做出适配 Slack 的动图,内置约束规则和校验工具,少踩上传与播放坑,做表情包和演示都更省心。

平台与服务
未扫描176.4k

接口测试套件

by alirezarezvani

Universal
热门

扫描 Next.js、Express、FastAPI、Django REST 的 API 路由,自动生成覆盖鉴权、参数校验、错误码、分页、上传与限流场景的 Vitest 或 Pytest 测试套件。

✎ 帮你把API与集成测试自动化跑顺,减少回归漏测;能力全面,尤其适合复杂接口场景的QA团队。

平台与服务
未扫描26.0k

相关 MCP Server

Slack 消息

编辑精选

by Anthropic

热门

Slack 是让 AI 助手直接读写你的 Slack 频道和消息的 MCP 服务器。

✎ 这个服务器解决了团队协作中需要 AI 实时获取 Slack 信息的痛点,特别适合开发团队让 Claude 帮忙汇总频道讨论或发送通知。不过,它目前只是参考实现,文档有限,不建议在生产环境直接使用——更适合开发者学习 MCP 如何集成第三方服务。

平台与服务
89.7k

by netdata

热门

io.github.netdata/mcp-server 是让 AI 助手实时监控服务器指标和日志的 MCP 服务器。

✎ 这个工具解决了运维人员需要手动检查系统状态的痛点,最适合 DevOps 团队让 Claude 自动分析性能数据。不过,它依赖 NetData 的现有部署,如果你没用过这个监控平台,得先花时间配置。

平台与服务
80.0k

by d4vinci

热门

Scrapling MCP Server 是专为现代网页设计的智能爬虫工具,支持绕过 Cloudflare 等反爬机制。

✎ 这个工具解决了爬取动态网页和反爬网站时的头疼问题,特别适合需要批量采集电商价格或新闻数据的开发者。不过,它依赖外部浏览器引擎,资源消耗较大,不适合轻量级任务。

平台与服务
72.9k

评论