bioretrieval-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@bioretrieval-mcpFind cryo-EM maps for the sequence MKTAYIAKQRQISFVKSHFSRQLEERLGLIEVQ"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
bioretrieval-mcp
An MCP server that gives LLM agents typed access to cryo-EM, protein, and DNA-methylation research tools: EMDB search, UniProt lookups, ESM-2 embeddings, sequence-to-cryo-EM-map retrieval with a trained two-tower model, and GEO methylation-array search. It comes with a 40-question eval run with Claude as the MCP client.

Tools
Tool | What it does | Backend |
| Keyword or Solr search over EMDB; returns resolution, method, organisms, fitted PDBs, UniProt xrefs, Pfam, microscope, citation | EBI EMDB API |
| Sequence, curated function, Pfam families, genes, organism, review status, EMDB xrefs | UniProt REST |
| ESM-2 650M ( | local, torch |
| Top-k cryo-EM maps for a protein sequence from the two-tower retrieval model, with cosine scores | local, torch |
| GEO series on | NCBI E-utilities |
| Precomputed CpGPT sample embedding, registered only when an embedding store is configured | local |
Every tool has a typed JSON input schema (ranges, enums, required fields) and a typed outputSchema, so
clients get structuredContent as well as text. Tools are annotated read-only/idempotent.
Platform to GPL mapping used by search_geo_methylation (checked against the GEO platform records):
27K = GPL8490; 450K = GPL13534, GPL16304; EPIC = GPL21145, GPL23976; EPICv2 = GPL33022.
Related MCP server: BioLab MCP Server
Quick start
uv venv && uv pip install -e ".[ml,dev]" # drop [ml] for the API-only tools
# stdio (Claude Desktop / Claude Code / any MCP client)
bioretrieval-mcp
# streamable HTTP
bioretrieval-mcp --transport streamable-http --port 8000 # served at http://127.0.0.1:8000/mcpClaude Code: claude mcp add bioretrieval -- /path/to/.venv/bin/bioretrieval-mcp
Claude Desktop (claude_desktop_config.json):
{
"mcpServers": {
"bioretrieval": {
"command": "/path/to/.venv/bin/bioretrieval-mcp",
"env": {
"BIORETRIEVAL_MAP_INDEX": "/path/to/map_index.npz",
"BIORETRIEVAL_RETRIEVAL_CHECKPOINT": "/path/to/best.pt"
}
}
}
}Docker:
docker build -t bioretrieval-mcp . # API tools only
docker build --target ml -t bioretrieval-mcp:ml . # + ESM-2 / retrieval (CPU torch)
docker run -p 8000:8000 -v bioretrieval-data:/data bioretrieval-mcpConfiguration
Env var | Default | Purpose |
|
| HTTP response cache (SQLite) and ESM embedding cache |
|
| Per-request timeout |
|
| Retries on timeouts, connection errors, 408/425/429/5xx |
|
| Response cache TTL |
| unset | Map index |
| unset | Two-tower checkpoint (sequence tower) |
| unset | CpGPT embedding store; enables |
|
|
|
| unset | NCBI identification; the key raises the rate limit from 3 to 10 req/s |
Retrieval model
retrieve_maps serves the sequence tower of the multimodal model from the companion paper (ESM-2 650M sequence
encoder, 3D-CNN volume encoder, shared 512-d latent space, trained with JEPA prediction + symmetric InfoNCE +
VICReg on human EMDB maps). Only the sequence tower runs at query time; map embeddings are computed offline by
the volume tower and shipped as an index:
# 1. on the GPU box: encode every map with the volume tower -> map_emb.npy (N x 512), rows = metadata order
# 2. package it
python scripts/build_map_index.py two-tower --embeddings map_emb.npy \
--metadata metadata_curated.csv --model "JEPA+InfoNCE two-tower" --out map_index.npz --fetch-titles
# 3. serve
BIORETRIEVAL_MAP_INDEX=map_index.npz BIORETRIEVAL_RETRIEVAL_CHECKPOINT=best.pt bioretrieval-mcpThe checkpoint loader autodetects both trainer formats in the research repo (mmprotein trainer:
model_state_dict / seq_projector; end-to-end trainers: model / sequence_projection, including
fine-tuned ESM-2 weights when present) and rebuilds the projection head from the weight shapes.
Without a checkpoint, build_map_index.py esm-baseline builds an index where each map is represented by the
ESM-2 embedding of its paired UniProt sequence. Retrieval then reduces to sequence nearest-neighbour search.
The tool reports which model produced each result, so agents and users can tell them apart.
Engineering
Transports: stdio and streamable HTTP (both exercised in the test suite with a real server subprocess).
Caching: SQLite TTL cache for upstream responses; ESM embeddings cached on disk by sequence hash (cold 183-residue embedding about 7 s on Apple M-series including model load; cache hits return immediately).
Resilience: per-request timeouts, exponential backoff with jitter,
Retry-Aftersupport, per-host pacing for NCBI's rate limit. Upstream failures come back as MCP tool errors (isError: true) with an agent-readable message instead of crashing the session.Validation: UniProt accession regex, amino-acid alphabet and length checks (DNA input is rejected with a hint), Solr query sanitisation, bounded
k/limit/resolution_max, enum-typed platforms. Invalid input is rejected before any network call.Tests: 89 pytest tests, all upstream APIs mocked with
httpx.MockTransportand recorded fixtures. The GitHub Actions workflow runs them on Python 3.10/3.12/3.13 and adds a Docker build + HTTP smoke test.
pytest # offline, a few secondsEvaluation
40 research questions (eval/questions.jsonl) across UniProt (10), EMDB (9), GEO methylation (9),
embeddings (3), retrieval (5), and multi-tool chains (4). Each has a gold answer, deterministic key-fact checks,
and the tool calls that ground it. eval/verify_gold.py re-runs those calls against the live sources and
confirms every gold fact is present in current tool output, so no gold answer depends on model memory.
Claude (claude-opus-5-5) is the MCP client: it sees exactly the tool list the server advertises and every
call goes over a real stdio MCP session.
Metric | Definition |
Tool-selection accuracy | All tools required by the question were called (also: first-call accuracy, call precision) |
Answer correctness | Claude judge vs gold answer ( |
Faithfulness | Ragas definition: answer split into atomic claims, each checked for support in the context the agent had (the tool descriptions it was shown plus the tool outputs it received); supported / total |
python eval/verify_gold.py # ground-truth check, no LLM
python eval/run_eval.py --out eval/results/run.jsonl
python eval/score.py eval/results/run.jsonl # writes run.scores.json and run.summary.mdResults
Agent claude-opus-5-5 (effort medium), grader claude-opus-5-5, gold snapshot 2026-10-21, one run.
retrieve_maps used the ESM-2 baseline index, not the trained two-tower model (see below).
slice | n | tool selection | first call | call precision | key facts | judge correct | correct or partial | faithfulness |
all | 40 | 100.0% | 100.0% | 100.0% | 100.0% | 100.0% | 100.0% | 0.912 |
uniprot | 10 | 100.0% | 100.0% | 100.0% | 100.0% | 100.0% | 100.0% | 0.873 |
emdb | 9 | 100.0% | 100.0% | 100.0% | 100.0% | 100.0% | 100.0% | 0.949 |
geo | 9 | 100.0% | 100.0% | 100.0% | 100.0% | 100.0% | 100.0% | 0.923 |
embed | 3 | 100.0% | 100.0% | 100.0% | 100.0% | 100.0% | 100.0% | 0.832 |
retrieval | 5 | 100.0% | 100.0% | 100.0% | 100.0% | 100.0% | 100.0% | 0.929 |
multi | 4 | 100.0% | 100.0% | 100.0% | 100.0% | 100.0% | 100.0% | 0.944 |
60 tool calls in total (1.5 per question), 1 tool error (q10's deliberate lookup of a nonexistent accession,
which the agent reported correctly). Median latency 8.8 s per question, p90 16.4 s. One of 120 grading calls was
declined by a safety classifier and re-run on claude-opus-5 via server-side fallback.
What the numbers say, and what they don't.
Faithfulness is the informative metric here, and 0.912 is conservative. 72 of 1,021 answer claims (7.1%) were marked unsupported. They fall into two groups:
Background knowledge the agent added despite being told to ground every statement: protein biology (preproinsulin structure, mTOR domain positions) and general advice ("UniProt sometimes merges accessions", q10 at 0.33).
Grader false negatives. 44 of the 72 contain accessions, and every one of those accessions appears in the tool output the agent received. Spot checks (q15, q20, q33, q36, q37) confirmed the stated facts were in the output, so the true faithfulness is higher. The score is reported as graded, without heuristic correction.
Tool selection and correctness are at ceiling, so this set does not separate good from great. Most questions need one or two tool calls with clear routing cues. A harder set (ambiguous routing, longer chains, questions that should be refused or need clarification) is the obvious next step.
Retrieval questions mostly test plumbing. With the baseline index, a query whose exact sequence is in the index scores 1.0 against its own maps, so these 5 questions check that the agent chains UniProt to retrieval correctly, not that the trained model retrieves well. Retrieval quality is reported in the paper (median rank 2 to 3 over 3,275 maps).
Grader and agent are the same model, which can bias grading in the agent's favour. The deterministic key-fact checks (100%) do not depend on the grader and agree with it.
Eval corrections after the first run (disclosed). The first scoring pass gave 97.5% tool selection,
95.0% judge-correct and 0.905 faithfulness (eval/results/run.v1.summary.md). Reviewing the misses showed
three problems with the eval, not the agent, which are fixed in questions.jsonl (see each item's gold_note):
q22: the gold answer counted all 11 GEO hits as ovarian-cancer studies. The agent correctly excluded a cholangiocarcinoma series (GSE38860) and a SuperSeries duplicate, reporting 9.
q26: the gold answer treated every EPICv2 "placenta" hit as placental. The agent correctly identified a macrophage study and a twins study as off-topic.
q31: the question is answerable from
embed_sequence's advertised description (1,022-residue limit), so calling that tool became optional. Faithfulness now also counts tool descriptions as context, since the agent legitimately reads them.
The agent was not re-run; only the grading changed. The eval also surfaced a product fix: in q31 the agent had
to guess which 1,022 residues embed_sequence keeps. The embed_sequence and retrieve_maps descriptions now
state that the first 1,022 are kept (fixed after this run, so the run above used the old wording).
Layout
src/bioretrieval_mcp/
server.py tool definitions, transports, entry point
http.py cache.py retrying cached HTTP client
validation.py input validation
schemas.py typed tool outputs
sources/ emdb.py, uniprot.py, geo.py
ml/ esm.py (ESM-2 + cache), retrieval.py (two-tower), cpgpt.py
scripts/ build_map_index.py, export_cpgpt_embeddings.py
eval/ questions.jsonl, run_eval.py, score.py, verify_gold.py, demo.py
tests/ pytest suite + recorded API fixturesAvailable Tools
3 toolsget_uniprotGet UniProt entryARead-onlyIdempotent
Fetch a UniProtKB entry: amino-acid sequence, curated function, Pfam families, gene names, organism, review status, and EMDB cross-references.
| Name | Required | Description | Default |
|---|---|---|---|
| accession | Yes | UniProtKB accession, e.g. P02794 or P0DTC2. |
Output Schema
| Name | Required | Description |
|---|---|---|
| url | Yes | |
| pfam | Yes | |
| genes | Yes | |
| length | Yes | |
| function | Yes | UniProt 'FUNCTION' comment, if curated |
| organism | Yes | |
| reviewed | Yes | |
| sequence | Yes | |
| taxon_id | Yes | |
| accession | Yes | |
| entry_name | Yes | |
| protein_name | Yes | |
| emdb_cross_refs | Yes | EMDB entries cross-referenced by UniProt |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint and openWorldHint, so the safety profile is fully covered and the description isn't required to restate it. What the description adds is content scope — the specific categories of data returned — which helps the agent judge relevance, but it says nothing about not-found handling, format, or rate/access constraints.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One sentence, front-loaded with the action and resource, with the field enumeration following as supporting detail. Nothing is padded and nothing could be cut without losing information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With one documented parameter, a full output schema, and complete annotations, an agent has everything needed to call this correctly. The only gap is behavior on an invalid or nonexistent accession, which is a minor omission given the otherwise rich structured metadata.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There is only one parameter and schema description coverage is 100%, including concrete example accessions (P02794, P0DTC2). The description adds no further semantics, so the baseline 3 applies — the schema does all the work.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Fetch') and resource ('a UniProtKB entry') and then enumerates the payload the agent will get back (sequence, function, Pfam families, gene names, organism, review status, EMDB cross-references). The sibling tools (search_emdb, search_geo_methylation) are unrelated retrieval tools, so no differentiation is needed and none is confused.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The single required 'accession' parameter plus 'Fetch a UniProtKB entry' makes the usage pattern (lookup by identifier) obvious, but there is no explicit statement of when to reach for this versus a search tool, and no note about what happens for an unknown accession. Usage is implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_emdbSearch EMDBARead-onlyIdempotent
Search the Electron Microscopy Data Bank for cryo-EM entries.
Returns per-entry metadata: title, resolution (Ã…), method, source organisms, fitted PDB models, UniProt cross-references, Pfam names, microscope, release date and primary citation. Results are relevance-ranked by EMDB.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum entries to return. | |
| query | Yes | Keywords or EMDB Solr syntax, e.g. 'apoferritin', 'spike AND Homo sapiens', 'fitted_pdbs:7a6a', 'xref_UNIPROTKB:P02794'. | |
| resolution_max | No | Only return maps at or better than this resolution (Ã…). |
Output Schema
| Name | Required | Description |
|---|---|---|
| query | Yes | Exact Solr query sent to EMDB |
| entries | Yes | |
| returned | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint and openWorldHint, so safety is covered; the description adds genuine value by disclosing what is returned (resolution, fitted PDBs, UniProt/Pfam cross-refs) and that ranking is relevance-based with no sort control exposed. It does not mention result capping/pagination behavior, but the annotations carry most of the safety burden.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the core action and scope. The second sentence enumerates return fields, which is somewhat redundant given a dedicated output schema exists, but it is compact and skimmable rather than padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema, full parameter documentation and read-only/idempotent annotations, the description only needs to establish purpose and result character, which it does. The main remaining gap is the absence of any guidance tying this search to the sibling get_uniprot tool for cross-reference workflows.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% — query examples, limit bounds and resolution_max semantics are all fully documented in the schema — so the baseline of 3 applies. The description mentions resolution in the return payload, which loosely connects to resolution_max, but adds no filtering syntax or format detail beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb and resource ('Search the Electron Microscopy Data Bank for cryo-EM entries'), which is unambiguous and immediately separates it from the unrelated siblings get_uniprot and search_geo_methylation. It stops short of explicitly naming a sibling or boundary, but the domain is so distinct that confusion is unlikely.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied by the resource domain — an agent infers to call it when it wants cryo-EM map entries. There is no explicit when-to-use/when-not guidance, no mention of how it relates to get_uniprot (e.g., for cross-referenced protein data), and no hint about when to prefer structured Solr syntax versus a plain keyword query.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_geo_methylationSearch GEO methylation seriesARead-onlyIdempotent
Search NCBI GEO for DNA-methylation series (GSE) run on a given Illumina array.
Returns total hit count plus, per series: accession, title, summary (truncated), platforms, sample count, organisms, submission date and linked PubMed IDs.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum series to return. | |
| query | Yes | Free-text GEO query, e.g. 'Alzheimer brain', 'aging blood', 'colorectal cancer'. | |
| platform | Yes | Illumina array: 27K (GPL8490), 450K (GPL13534), EPIC (GPL21145), EPICv2 (GPL33022). |
Output Schema
| Name | Required | Description |
|---|---|---|
| query | Yes | |
| series | Yes | |
| platform | Yes | |
| returned | Yes | |
| total_count | Yes | Total matching series in GEO (results are paged) |
| platform_gpls | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent and openWorld, so the safety profile is covered. The description adds genuine behavioral detail beyond that: it returns a total hit count and flags that summaries are truncated — a real caveat an agent should know when consuming results.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, zero waste. The action and scope come first, followed by the return payload, which is the correct front-loading for a search tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present and full parameter documentation, the description only needs to frame scope and caveats, which it does. Minor gaps remain: no mention of result ordering or whether 'limit' paginates or merely truncates the hit set.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so all three parameters (limit, query, platform with GPL mappings) are already documented in the schema. The description only restates the 'given Illumina array' constraint and adds no syntax, default, or result-ordering detail beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Search NCBI GEO for DNA-methylation series (GSE)') plus a scoping constraint ('run on a given Illumina array'). Sibling tools (search_emdb, get_uniprot) are in entirely different domains, so no confusion is possible.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The domain context ('DNA-methylation series on an Illumina array') implies appropriate usage, but there is no explicit when-to-use guidance, no exclusions, and no mention of alternatives for e.g. non-methylation or non-array GEO records.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
3 tool updates
v0.1.0- First observed
get_uniprot - First observed
search_emdb - First observed
search_geo_methylation
TDQS
Scored across 3 tools
Each tool targets a clearly different resource and action: EMDB search, UniProt entry retrieval, and GEO methylation series search. There is no realistic overlap in selection, even though EMDB results may contain UniProt cross-references.
All tools use consistent snake_case verb_noun naming: search_emdb, get_uniprot, search_geo_methylation. The mix of search and get reflects the intended action rather than inconsistent conventions.
Three tools is well within a focused retrieval server’s scope, and each covers a distinct biological data source. None appears redundant or gratuitous.
Coverage is uneven: UniProt has fetch but no search, while EMDB and GEO methylation have search but no dedicated full-entry retrieval beyond returned metadata. These are notable gaps for common retrieval workflows, though partial workarounds exist via cross-references and search metadata.
Maintenance
Related MCP Connectors
Connect AI clients to biomedical data and tools.
Protein analysis: ESM-2/ESMC embeddings, mutation scoring, landscape scans, ESMFold structure.
- WauldoOAuthcom.wauldo
Stateless agentic tools over MCP: concept extraction, long-context, knowledge graph, planning.
Auditable MCP server for PubMed, Europe PMC, ClinicalTrials.gov, and bioRxiv/medRxiv queries
Related MCP Servers
- AlicenseAqualityAmaintenanceA high-performance MCP server that gives LLMs access to 25 biomedical tools federated across 50+ upstream APIs for genes, variants, drugs, diseases, literature, clinical trials, and structural biology.42352 npm12Apache 2.0
- AlicenseNot gradedqualityCmaintenanceUnified MCP server providing AI-agent-ready access to AlphaFold, PubMed, ChEMBL, Ensembl, and 37+ scientific databases.MIT
- AlicenseNot gradedqualityCmaintenanceMCP-native scientific skills for reproducible computational biology and AI-driven drug-discovery workflows. It combines deterministic scientific tools with an MCP server to give AI agents real computational capabilities.Apache 2.0
- AlicenseNot gradedqualityCmaintenanceEnables LLM agents to design proteins, predict structures, score interfaces, and run molecular dynamics simulations through a unified interface.1Apache 2.0