ena-biosamples-mcp
Click on "Install 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., "@ena-biosamples-mcpHow many cattle sequencing runs are in ENA?"
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.
ena-biosamples-mcp
An MCP server that lets researchers ask questions about public genomics data in the European Nucleotide Archive (ENA) and BioSamples in plain English, from any MCP client (Claude, IDE agents, custom agents).
Question in, insight out: "How many domestic cattle samples were collected in the UK, and is their metadata good enough for a livestock project?" becomes a handful of API calls and a checked, explained answer.
Demo
1. Counting records with a country filter

2. Checking metadata against a livestock project's requirements

The second check found a real data-quality issue: the first UK "cattle" samples are rumen bacteria from an in vitro fermentation study, submitted under a metagenome checklist, so they can never carry sex or breed. Their coordinates are also written in degrees-minutes-seconds while labelled as decimal degrees.
Related MCP server: BV-BRC MCP Server
Tools
Tool | Example question | Source |
| "How many cattle sequencing runs are in ENA?" | ENA Portal API |
| "Show me cattle samples collected in the United Kingdom" | ENA Portal API |
| "What tissue and breed is sample SAMEA103957639?" | BioSamples API |
| "Does this sample have sex and breed for a FAANG-style project?" | BioSamples API |
check_sample_metadata always checks the fields ENA requires on every sample (organism,
collection date, geographic location) and accepts extra required fields per project. Each field is
reported as ok, absent, declared_missing (an INSDC missing-value term such as
"not collected") or invalid_format (e.g. a collection date that isn't ISO 8601).
Quick start
Claude desktop app (stdio)
Requires uv. Add to the MCP config and restart the app:
{
"mcpServers": {
"ena-biosamples": {
"command": "/full/path/to/uv",
"args": ["--directory", "/path/to/ena-biosamples-mcp", "run", "ena-mcp"]
}
}
}Docker (Streamable HTTP)
docker build -t ena-biosamples-mcp .
docker run --rm -p 8000:8000 ena-biosamples-mcp
# MCP endpoint: http://localhost:8000/mcpDevelopment
uv sync
uv run pytest # unit tests, no network
uv run ruff check .
uv run python scripts/smoke_live.py # live check against ENA and BioSamplesSettings can be overridden with ENA_MCP_* environment variables; see .env.example.
Design notes
Service layer. All HTTP calls live in
ena_service.pyandbiosamples_service.py. MCP tools inserver.pyonly delegate, and tests swap in a mock transport.Metadata rules are pure functions (
metadata_check.py), so consortium-specific rules can be added and tested without touching the network.Verified against the live APIs, not just the docs. Findings that shaped the code:
The ENA count endpoint returns TSV with a header line, not a bare number.
country="United Kingdom*"returns 0 results whilecountry="United Kingdom"returns 5,188, so countries are matched exactly (case-insensitive).country="*Kingdom*"returns the same 5,188, so no region-suffixed UK values are missed."cattle" resolves to the genus Bos, which also covers yak and zebu. Results carry a note telling the client to ask for a species such as Bos taurus.
Clear errors. Unknown species, private samples and wrong accession types come back as readable messages the model can relay to the user.
Roadmap
Validate coordinates (decimal degrees vs. degrees-minutes-seconds), found during the demo
Check samples against full ENA and consortium checklists (e.g. FAANG, ERGA)
Aggregate tools, e.g. samples per country or per year for a species
Response caching and polite rate limiting for bulk questions
License
MIT
Available Tools
4 toolscheck_sample_metadataA
Check whether an ENA/BioSamples sample's metadata is complete and well-formed.
Always checks the fields ENA requires on every sample (organism, collection date, geographic location). Flags fields that are absent, filled with an INSDC missing-value term (e.g. "not collected"), or badly formatted (collection date not ISO 8601).
Args: accession: BioSamples accession, e.g. "SAMEA7658521". extra_fields: Additional attributes to require, e.g. ["sex", "breed", "tissue"] for a livestock (FAANG-style) project.
| Name | Required | Description | Default |
|---|---|---|---|
| accession | Yes | ||
| extra_fields | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| fields | Yes | |
| passed | Yes | |
| summary | Yes | |
| accession | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden and does so partly: it discloses that the check always evaluates ENA's mandatory fields, defines what counts as a failure (absent, INSDC missing-value term, bad formatting), and implies this is a read-only validator by nature. It stops short of explicitly stating permissions, that the sample need not exist/be reachable, or that validation is non-mutating.
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?
The narrative is front-loaded and the Args block is compact and skimmable. Slight redundancy between the prose summary and the Args section, but every sentence adds information and no padding is present.
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?
For a two-parameter read-only validator with an output schema, the description covers purpose, semantics, and the validation criteria an agent needs to interpret results. The output schema handles return format, so the only missing element is explicit guidance on sibling selection and any preconditions on sample accessibility.
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 0%, so the description must compensate, and it does: 'accession' is grounded with a concrete example ('SAMEA7658521'), and 'extra_fields' is explained as additional required attributes with a domain-specific example. Both parameters' intent is fully recoverable from the description alone.
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 and resource ('Check whether an ENA/BioSamples sample's metadata is complete and well-formed') and immediately enumerates what the check covers (required fields, missing-value terms, ISO 8601 date format). This distinguishes it cleanly from siblings like get_biosample (retrieval) and count_records (aggregation), none of which validate metadata.
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 description gives clear positive context (validate a BioSamples sample's metadata, with an explicit livestock/FAANG example motivating extra_fields), so an agent knows when this tool applies. However it never states when NOT to use it or names an alternative among the siblings, so it falls short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
count_recordsB
Count records for a species in the European Nucleotide Archive (ENA, EMBL-EBI).
Args: species: Scientific or common name, e.g. "Bos taurus" or "cattle". record_type: "read_run" (sequencing runs), "sample", or "assembly". include_subspecies: Also count subspecies and breeds under this taxon.
| Name | Required | Description | Default |
|---|---|---|---|
| species | Yes | ||
| record_type | No | read_run | |
| include_subspecies | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| count | Yes | |
| query | Yes | |
| taxon | Yes | |
| record_type | Yes | |
| include_subspecies | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are supplied, so the description carries the full behavioral burden. It clarifies the meaning of include_subspecies and the record_type categories, and 'count' implies a read-only, non-mutating query, but it says nothing about permissions, rate limits, or whether counts are approximate — lean coverage on a read-only tool with an output schema.
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?
The purpose sentence is front-loaded and the Args block is compact, with each parameter getting exactly one explanatory line. No template boilerplate or restated field names beyond what is needed.
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?
For a low-complexity, single-taxon counting tool with a declared output schema, the definition gives enough to call it correctly: every parameter is explained and the domain is named. The remaining gap is the absence of routing guidance against the sibling tools.
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 0%, so the description must supply all parameter meaning, and it largely does: species accepts scientific or common names with worked examples ('Bos taurus' or 'cattle'), record_type enumerates the three values with 'read_run' glossed as sequencing runs, and include_subspecies is defined as counting subspecies and breeds. Only a fuller gloss on 'sample' and 'assembly' is missing.
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 states a specific verb and resource ('Count records') scoped to a species within a named repository (ENA, EMBL-EBI), which is clear enough to distinguish it from retrieval-oriented siblings like search_samples and get_biosample. It stops short of explicitly contrasting itself with those siblings, so it lands just below top marks.
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?
There is no statement of when to reach for count_records instead of search_samples, get_biosample, or check_sample_metadata, and no mention of prerequisites or cost tradeoffs of a counting query. The agent must infer the use case purely from the verb.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_biosampleA
Get an EMBL-EBI BioSamples record with all its attributes.
Attributes include organism, geographic location, tissue, breed and sex where submitted.
Args: accession: BioSamples accession, e.g. "SAMEA7658521". Use the accession returned by search_samples.
| Name | Required | Description | Default |
|---|---|---|---|
| accession | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | No | |
| tax_id | No | |
| accession | Yes | |
| update_date | No | |
| release_date | No | |
| characteristics | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the disclosure burden. It usefully signals that the full record's attributes are returned and that some fields exist only 'where submitted' (i.e. may be absent), which sets expectations. However, it says nothing about permissions, rate limits, or failure behavior when an accession is invalid.
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?
Front-loaded with the core action, and the attribute list is a single efficient clause. The 'Args:' block is slightly formal/verbose for a one-parameter tool but still earns its place by clarifying the accession format.
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?
An output schema exists, so return-value documentation is not required, and the single parameter is fully explained. What remains thin is operational context (auth, error handling), but for a simple one-param read tool the description is largely sufficient.
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 0%, so the description must compensate, and it does: it defines 'accession' as a BioSamples accession, gives a concrete example format ('SAMEA7658521'), and specifies the authoritative source (the output of search_samples). Only minor detail like locale/validation rules is missing.
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 and resource ('Get an EMBL-EBI BioSamples record') and enumerates the content it returns (organism, geographic location, tissue, breed, sex). It also routes the agent away from the sibling search_samples by tying the accession to that tool's output, so it is distinguishable without opening either schema.
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?
'Use the accession returned by search_samples' gives a clear usage path and identifies the correct upstream tool. It stops short of stating when NOT to use this tool or what to do if no accession is known, so it is strong but not exhaustive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_samplesA
Find samples in the European Nucleotide Archive (ENA, EMBL-EBI) for a species.
Optionally filter by country of origin.
Returns the total number of matching samples plus up to limit records with
accession, country, collection date, first public date, submitting centre and description.
Args: species: Scientific or common name, e.g. "Bos taurus" or "cattle". country: Country name, e.g. "United Kingdom" or "Kenya". Omit for all countries. limit: Max samples to return (1-100). Default 20. include_subspecies: Also include subspecies and breeds under this taxon.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| country | No | ||
| species | Yes | ||
| include_subspecies | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| query | Yes | |
| taxon | Yes | |
| samples | Yes | |
| returned | Yes | |
| country_filter | Yes | |
| total_matching | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It does disclose the return shape (total count plus up to `limit` records with named fields) and the bounded limit range, which is useful. However, it says nothing about authentication, rate limits, error behavior, or how pagination beyond `limit` works.
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?
Front-loads the purpose, then the return summary, then the argument list in a clean labeled block. No sentence is redundant and the optional-filter caveat is placed where it matters.
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 all parameters fully documented, the description is nearly self-sufficient for correct invocation. The remaining gap is the absence of any sibling-routing or access/permission context, which matters given three adjacent tools.
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 0%, so the description must compensate, and it does: every one of the four params is explained with meaning and examples (species as scientific or common name, country name with omit-for-all semantics, limit range 1-100 with default 20, include_subspecies covering subspecies and breeds).
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 concrete verb and resource ('Find samples in the European Nucleotide Archive for a species') and names the data source, which is more than a generic search label. It does not explicitly distinguish itself from siblings like get_biosample or count_records, so an agent must infer the boundary.
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 implied by the purpose and by the per-argument hints ('Omit for all countries', optional country filter). There is no explicit when-to-use/when-not guidance or mention of the alternatives (get_biosample, count_records), so the agent gets context but not routing rules.
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.
4 tool updates
v0.1.0- First observed
check_sample_metadata - First observed
count_records - First observed
get_biosample - First observed
search_samples
TDQS
Scored across 4 tools
count_records and search_samples overlap on the species+samples axis, since search_samples already returns a total count alongside records, which could cause hesitation about which to call for a simple sample tally. Otherwise the retrieval (get_biosample) and validation (check_sample_metadata) tools are clearly distinct despite sharing an accession argument.
All four tools follow a clean verb_noun snake_case pattern (count_records, search_samples, get_biosample, check_sample_metadata) with consistent, predictable verb semantics.
Four tools is on the lean side but coherent for a focused ENA/BioSamples lookup server, covering count, search, fetch, and validate without redundancy. It could arguably support one more retrieval tool, but nothing feels bloated.
The search→get→validate lifecycle for BioSamples is well covered and closure is sensible. Minor gaps: count_records tallies read_run and assembly records but there is no way to retrieve those records, and search_samples only filters by country.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Query your org's data in natural language — read-only MCP access to SQL, NoSQL, files & warehouses.
Auditable MCP server for PubMed, Europe PMC, ClinicalTrials.gov, and bioRxiv/medRxiv queries
Ask questions in plain language, get answers from your business database. No SQL required.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceMCP server for querying BV-BRC biological data, submitting analysis jobs (assembly, annotation, BLAST, etc.), and managing workspace files via natural language.-
- AlicenseNot gradedqualityDmaintenanceEnables querying and retrieving bacterial and viral genomic data, features, antimicrobial resistance, and epitopes from the BV-BRC API using natural language.MIT
- FlicenseNot gradedqualityBmaintenanceEnables searching and retrieving biomedical literature from Europe PMC, including abstracts, full-text (JATS XML), text-mined annotations, citations, references, and database cross-links, through natural language queries and automated data staging.-
- FlicenseNot gradedqualityBmaintenanceEnables natural-language Q&A, human-approved actions, and dashboard generation over a data ontology via MCP.-