Skip to main content

Production-quality MCP server exposing the UniProt REST API (search, entries, FASTA, ID mapping, taxonomy) to LLM clients over stdio.

Project description

uniprot-mcp

CI

GitHub repo: fzlzjerry/uniprot-mcp · PyPI package & command: uniprotkb-mcp (the Python import package is uniprot_mcp).

A production-quality MCP server that exposes the UniProt REST API to LLM clients (Claude Code, Claude Desktop, …) over stdio. Built with FastMCP and managed with uv.

Tools return compact, token-efficient summaries by default and full payloads only on request, with robust error handling and an embedded UniProt query cheat-sheet so the model writes valid queries.

Tools

Tool What it does
search_uniprotkb Search UniProtKB with native query syntax. reviewed / organism_id filters are added for you. Summary, FASTA, or TSV output.
get_entry One entry as a curated digest (function, names, organism, length, subcellular location, family/domains, key features, PTMs, keywords, PDB/AlphaFold/Ensembl/RefSeq/InterPro/GO cross-refs) or json/fasta/txt/gff.
get_fasta Raw FASTA for one accession or a batch.
map_ids Convert ids across databases via UniProt's async ID-mapping (e.g. RefSeq_ProteinUniProtKB, UniProtKB_AC-IDPDB). Returns mapped pairs and unmapped ids; validates the db pair against the live config.
get_taxonomy Resolve an organism name or taxon id → taxon id, names, rank, lineage. Turn "human" into organism_id:9606.
search_uniref Search UniRef100/90/50 sequence-similarity clusters.
search_proteomes Search proteomes (whole-organism protein sets); reference-proteome filter.

Plus an MCP resource resource://uniprot/query-cheatsheet documenting the UniProtKB query syntax (gene:, organism_id:, reviewed:true, length:[X TO Y], keyword:, ec:, boolean AND/OR/NOT, …).

Requirements

  • Python ≥ 3.10 (the repo pins 3.13 via .python-version)
  • uv

Install

git clone https://github.com/fzlzjerry/uniprot-mcp
cd uniprot-mcp
uv sync                 # creates .venv and installs fastmcp + httpx

Run

# stdio server (what MCP clients launch):
uv run uniprotkb-mcp

UniProt asks API clients to identify themselves with a contact address. Set one via the UNIPROT_MCP_CONTACT environment variable (it goes into the User-Agent); otherwise a placeholder is used.

UNIPROT_MCP_CONTACT="you@example.org" uv run uniprotkb-mcp

Run with uvx (no clone / no sync)

uvx (a.k.a. uv tool run) fetches, builds, and runs the console script in a throwaway environment — nothing to install first. Pick whichever source you have:

# From PyPI (once published — see "Releasing" below):
uvx uniprotkb-mcp

# From a Git repo (note: repo is uniprot-mcp, command is uniprotkb-mcp):
uvx --from git+https://github.com/fzlzjerry/uniprot-mcp uniprotkb-mcp

# From a local checkout (this directory):
uvx --from /ABSOLUTE/PATH/TO/uniprot-mcp uniprotkb-mcp

# From a built wheel:
uvx --from ./dist/uniprotkb_mcp-0.1.0-py3-none-any.whl uniprotkb-mcp

Pin a version with uvx uniprotkb-mcp@0.1.0, or force a refresh of the cached build with uvx --refresh --from <source> uniprotkb-mcp.

Register with Claude Desktop

Edit claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/claude_desktop_config.json, Windows: %APPDATA%\Claude\claude_desktop_config.json) and add:

{
  "mcpServers": {
    "uniprot": {
      "command": "uvx",
      "args": ["--from", "git+https://github.com/fzlzjerry/uniprot-mcp", "uniprotkb-mcp"],
      "env": { "UNIPROT_MCP_CONTACT": "you@example.org" }
    }
  }
}

Swap the --from source for a local path (/ABSOLUTE/PATH/TO/uniprot-mcp) or, once published, drop --from entirely and use "args": ["uniprotkb-mcp"]. Make sure uvx is on the PATH Claude Desktop sees (it ships with uv; give the absolute path to uvx if needed, e.g. ~/.local/bin/uvx). Restart Claude Desktop and the uniprot tools appear.

Prefer a cloned checkout instead of uvx? Use "command": "uv", "args": ["run", "--directory", "/ABSOLUTE/PATH/TO/uniprot-mcp", "uniprotkb-mcp"].

Register with Claude Code

Project-scoped via a .mcp.json in your project root (same shape):

{
  "mcpServers": {
    "uniprot": {
      "command": "uvx",
      "args": ["--from", "git+https://github.com/fzlzjerry/uniprot-mcp", "uniprotkb-mcp"],
      "env": { "UNIPROT_MCP_CONTACT": "you@example.org" }
    }
  }
}

Or from the CLI:

# via uvx (published / git / local source):
claude mcp add uniprot -e UNIPROT_MCP_CONTACT=you@example.org -- uvx uniprotkb-mcp

# via a local checkout with uv:
claude mcp add uniprot -e UNIPROT_MCP_CONTACT=you@example.org \
  -- uv run --directory /ABSOLUTE/PATH/TO/uniprot-mcp uniprotkb-mcp

Smoke test

Exercises every tool against the live API and prints the output:

UNIPROT_MCP_CONTACT="you@example.org" uv run python -m tests.smoke

Continuous integration

.github/workflows/ci.yml runs on every push / PR to main:

  • structure (Python 3.10 & 3.13) — byte-compile + offline checks that all 7 tools register, ctx stays out of the public schema, and the cheat-sheet resource is present (tests/check_structure.py).
  • smoke — the full live-API smoke test (tests/smoke.py).

Releasing (PyPI Trusted Publishing — no token)

Publishing uses OIDC Trusted Publishing, PyPI's recommended method: GitHub Actions proves its identity to PyPI directly, so no API token or secret is stored anywhere. .github/workflows/publish.yml builds and publishes on a version tag.

One-time PyPI setup — at https://pypi.org/manage/account/publishing/ add a pending publisher (pending because the project doesn't exist on PyPI yet; it becomes a normal trusted publisher after the first upload):

Field Value
PyPI Project Name uniprotkb-mcp
Owner fzlzjerry
Repository name uniprot-mcp
Workflow name publish.yml
Environment name pypi

Each release:

# bump `version` in pyproject.toml, commit, then tag:
git tag v0.1.0
git push origin v0.1.0

The tag triggers publish.yml, which checks the tag matches the pyproject version, builds the sdist + wheel, and uploads via OIDC. After the first upload, anyone can run uvx uniprotkb-mcp and the Claude config simplifies to "command": "uvx", "args": ["uniprotkb-mcp"].

Prefer a manual one-off? uv build && uv publish --token pypi-... still works, but Trusted Publishing is the recommended, token-free path.

Design notes

  • Single shared httpx.AsyncClient with a descriptive User-Agent including your contact.
  • Retry/backoff on 429 (honoring Retry-After) and 5xx; 400 surfaces UniProt's own error message; no raw tracebacks reach the client (errors are raised as ToolError).
  • Pagination via the Link header / x-total-results; result sizes are capped (≤ 500) and the total is always reported so you can narrow or page.
  • ID mapping follows the real async flow: POST /idmapping/run → poll /idmapping/status/{job} (a 303 + Location signals completion) → fetch results, automatically choosing the enriched UniProtKB results endpoint vs. the simple-pair endpoint based on the target database.

Project layout

src/uniprot_mcp/
  server.py       # FastMCP instance, the 7 tools, cheat-sheet resource, main()
  client.py       # shared AsyncClient, retry/backoff, error mapping, header parsing
  idmapping.py    # async run/poll/results flow with target-aware routing
  config.py       # cached idmapping db config + from/to validation
  formatting.py   # JSON -> compact summary digests
  cheatsheet.py   # UniProt query cheat-sheet
tests/smoke.py    # live-API smoke test

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

uniprotkb_mcp-0.1.0.tar.gz (118.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

uniprotkb_mcp-0.1.0-py3-none-any.whl (25.3 kB view details)

Uploaded Python 3

File details

Details for the file uniprotkb_mcp-0.1.0.tar.gz.

File metadata

  • Download URL: uniprotkb_mcp-0.1.0.tar.gz
  • Upload date:
  • Size: 118.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for uniprotkb_mcp-0.1.0.tar.gz
Algorithm Hash digest
SHA256 6748bf1cfcba907d35dea87fef73256b1189b708a46caa82c05d88db28f89ff8
MD5 9a48f359e11eb1a64596ac0a0ad7d91a
BLAKE2b-256 065ea9828d31cfb0bd9a0a8d283f01d992bb3531e6d53f25c036cff7da54fc86

See more details on using hashes here.

Provenance

The following attestation bundles were made for uniprotkb_mcp-0.1.0.tar.gz:

Publisher: publish.yml on fzlzjerry/uniprot-mcp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file uniprotkb_mcp-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: uniprotkb_mcp-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 25.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for uniprotkb_mcp-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 44b2b9fd9e37b4257c2d314f8f27dba450f1ad68d82667dbf37c5177a505c967
MD5 7beecf1b3049840e23bbc53ee55f8807
BLAKE2b-256 a1017aa5cf03df524ca395f0dbc4c3d247a41386b910b07f296d57a36be41420

See more details on using hashes here.

Provenance

The following attestation bundles were made for uniprotkb_mcp-0.1.0-py3-none-any.whl:

Publisher: publish.yml on fzlzjerry/uniprot-mcp

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page