Skip to main content
Glama
musharna

data-aggregator-mcp

by musharna

data-aggregator-mcp

data-aggregator-mcp is an MCP server that lets AI agents search 21 public research-data sources at once and get back one deduplicated list.

CI PyPI Python License DOI Glama

Install

Claude Code:

claude mcp add data-aggregator -- uvx data-aggregator-mcp

One-click install for VS Code or Cursor:

Install in VS Code Install in Cursor

Any other MCP client: run uvx data-aggregator-mcp as a stdio server.

Claude Desktop (claude_desktop_config.json) and most other clients:

{
  "mcpServers": {
    "data-aggregator": {
      "command": "uvx",
      "args": ["data-aggregator-mcp"],
      "env": { "NCBI_API_KEY": "your-optional-key" }
    }
  }
}

With pip:

pip install data-aggregator-mcp
data-aggregator-mcp        # or: python -m data_aggregator_mcp

operate (SQL and previews over remote files) needs an optional extra: pip install "data-aggregator-mcp[operate]".

Related MCP server: plant-genomics-mcp

What you can ask

"Find transcriptomes for Orobanche aegyptiaca." The species was renamed; NCBI Taxonomy maps it to Phelipanche aegyptiaca, and the sources that accept synonyms match both names (the demo above).

"What data came out of this paper?"

resolve("pubmed:40098680")
  links  geo:GSE284240, bioproject:PRJNA1198054, and 18 sra: experiments
  files  PMC11910882.xml   (open-access full text)

"Can I train a model on this dataset?"

resolve("hf:scikit-learn/iris", use="ml-training")
  license_compat  ALLOW: "CC0-1.0 grants the permission(s) required for
                  ml-training: commercial-use, modifications"

The verdict is read from the record's license metadata; it is advice, not a legal opinion. resolve also renders citations in any CSL style, checks Crossref for retractions, scores FAIRness, and exports Croissant or RO-Crate. relate reports how a set of records connect (a shared accession, DOI or explicit link).

How a search runs

A source that fails is named in the result's errors, never dropped silently.

What each source can fetch, and which checksum it is verified against: docs/sources.md.

What the benchmark shows

An agent using this server was compared with the same agent using web search, on held-out dataset-finding tasks scored by recall against independently built answer keys, 3 runs per task. Mean recall, server against web search: Claude Haiku 5.5 0.47 against 0.32 (higher on 8 of 10 tasks), Sonnet 5.5 0.54 against 0.52 (5 of 10), Opus 5.5 0.72 against 0.58 (6 of 10). With Haiku the server met round 5's pre-registered "better" rule (higher on at least 8 of 10 tasks, interval above 0) but not the stricter bar for a win across model tiers (9 of 10, Holm-adjusted sign test, p = 0.22); Sonnet and Opus met neither. With Opus it returned fewer wrong entries and answered in about a third of the time; with Sonnet it was faster on 9 of 10 tasks; with Haiku it cost less on 9 of 10.

The two latest Opus 5.5 rounds (2026-10-19, rules written before the runs):

Tools given to the agent

Round 4 (5 tasks)

Round 5 (10 tasks)

this server

0.66

0.72

web search

0.66

0.58

ToolUniverse

0.59

0.63

no tools (memory only)

0.02

0.09

In round 5 this server was higher on 6 of 10 tasks, where the pre-set rule needed 8. Web search hit the 15-minute limit in 11 of 30 runs, and a run that times out scores 0. In runs that finished, web search found more (0.90). The server answered in 203 s against 599 s (median), with fewer tool calls and fewer wrong entries (precision 0.95 against 0.62). It cost more per run than web search ($2.08 against $1.51, API-equivalent).

We chose the tasks and ran the benchmark ourselves; an outside re-run is welcome. Method and controls: benchmarks/h2h; the Haiku and Sonnet runs: 2026-10-20 re-run.

Compared with other servers

Server

Searches

One search

Checksum

Remote SQL

License check

data-aggregator-mcp

21 sources: data archives, omics, papers

yes, DOI dedup

where published

yes

yes

Mobus

20 general and ML data platforms

yes

—

row preview

yes

paper-search-mcp

papers: arXiv, PubMed, OpenAlex, Crossref and more

yes, deduplicated

—

—

—

ToolUniverse

1000+ tools: models, datasets, APIs, packages

papers

—

—

—

BioMCP

genes, variants, trials, drugs, proteins, papers

yes (search all)

—

—

—

— means the project's README doesn't describe it (READMEs read 2026-10-04). Where they are ahead: BioMCP reaches clinical trials, ChEMBL and AlphaFold; ToolUniverse covers far more ground overall; paper-search-mcp covers far more literature sources; Mobus also compares datasets and checks schema compatibility. More: docs/POSITIONING.md.

Reference and development

Every tool and parameter, the HTTP transport (--transport http) and the environment variables: docs/reference.md. Sources that need every word of a query, and how they are searched: every-word sources. Tests, linting and the live API probes: CONTRIBUTING.md.

License

MIT. See LICENSE.

Available Tools

6 tools
fetchA

Download a resource's files to local disk and return the PATHS (never the file contents). Tool names in this text are this server's own; your client may list them with a prefix (in Claude Code, mcp__data-aggregator__resolve): call the name it lists. Fetchable backends: Zenodo (md5-verified); SRA via ENA FASTQ (md5-verified); GEO supplementary files (unverified); DataCite sub-repos — Figshare/Dataverse/OSF (md5-verified), OpenNeuro (snapshot manifest, unverified), Dryad is manifest-only (resolve lists files, fetch fails loud), Mendeley + other DataCite repos fail loud; PubMed/OpenAIRE open-access full text (EuropePMC XML / Unpaywall PDF, unverified); HuggingFace Hub (unverified); DataONE Member-Node objects (md5/SHA-256-verified); OmicsDI — PRIDE (unverified) + MetaboLights (sha-256-verified) only, MassIVE/jPOST/iProX/PeptideAtlas/Panorama Public/GNPS/Metabolomics Workbench fail loud; DANDI dandisets (302→S3, sha-256-verified); CZ CELLxGENE H5AD/RDS assets (unverified); OpenML ARFF (md5-verified); RCSB PDB .cif/.pdb structure files (unverified); UniProtKB FASTA (unverified); BioStudies study files (unverified); GBIF Darwin Core Archives (unverified); data.gov dataset distributions (unverified). Fails loud if selected files exceed max_bytes unless force=true. Verifies md5/SHA-256 where the source publishes one; files marked unverified get no integrity check. Writes a .dataresource.json sidecar.

NameRequiredDescriptionDefault
idYesSource-prefixed id or bare Zenodo id
destNoDestination dir (default managed cache)
filesNoGlob over file names (default all)
forceNoOverride max_bytes
extractNoUnpack downloaded zip/tar archives into the destination (default false). Path-traversal-guarded; counts against max_bytes.
max_bytesNoByte ceiling before failing loud

Output Schema

NameRequiredDescription
bytesNo
pathsNo
resumedNo
skippedNo
unverifiedNo

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations: discloses integrity verification per source (md5/SHA-256 vs unverified), that it fails loud when max_bytes is exceeded unless force=true, that extract is path-traversal-guarded and counts against max_bytes, that it writes a .dataresource.json sidecar, and that it returns paths rather than contents. Annotations only say readOnly=false and non-idempotent, so this added context is substantial.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The opening sentences are well front-loaded with the core behavior and return-value contract. However, the backend enumeration is a very long run-on sentence dense with provider names and verification status; it earns its content but is hard to scan and would read better as a structured list.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given an output schema exists, return values need not be explained, yet the description still clarifies that paths (not contents) are returned. It covers failure modes, integrity guarantees, side effects (sidecar file), and per-source support, which is complete for a 6-parameter download tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3, but the description adds cross-parameter meaning: force exists specifically to override max_bytes, and extract counts against the byte ceiling. This interaction between force/max_bytes/extract is not obvious from the schema fields alone.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Download a resource's files to local disk') and explicitly scopes the return value ('return the PATHS (never the file contents)'). This clearly distinguishes it from siblings like resolve and search, which are about discovery rather than retrieval.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is strongly implied by the per-backend breakdown of what is fetchable, md5-verified, manifest-only, or fails loud, plus the note that Dryad is 'manifest-only (resolve lists files, fetch fails loud)' which routes the agent to resolve first in that case. It lacks an explicit 'use fetch when X, use resolve when Y' statement for other scenarios, so it stops 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.

list_sourcesA
Read-only

List wired data sources and their capabilities (layer, kinds, supported filters, auth requirement, rate limit, status). Tool names in this text are this server's own; your client may list them with a prefix (in Claude Code, mcp__data-aggregator__resolve): call the name it lists. filters_supported names the search parameters a source applies itself: cursor = it pages past page 1; published_after/published_before/kind = filtered upstream, so its total is filtered (any other source is filtered after fetch); organism/disease/tissue/chemical/assay = the synonym expansion reaches its query.

NameRequiredDescriptionDefault
check_healthNoWhen true, probe 5 sources (zenodo, datacite, omics, literature, huggingface) and attach a 'health' field ({status: up|down, latency_ms, detail}) to those entries; every other source gets health: null. Default false: returns the static catalog with no network.

Output Schema

NameRequiredDescription
sourcesYes

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations cover the read-only profile, and the description adds real context beyond them: it warns that tool names appearing in the text may be prefixed by the client (with a concrete Claude Code example), which prevents a common invocation mistake. It does not restate the no-network default, but that behavior is fully disclosed in the check_health schema description.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded in one sentence, then the dense second paragraph covers naming and filters_supported semantics, which are genuinely needed to interpret the output. Slightly wordy but no sentence is filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained, and the description still goes further by decoding the most ambiguous returned field (filters_supported) and its per-value meaning. Nothing an agent needs to call or interpret this tool correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With a single parameter and 100% schema description coverage, the schema already explains check_health's probing behavior, latency fields, and default. The description adds nothing about the parameter, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List wired data sources and their capabilities') and enumerates exactly what a capability record contains (layer, kinds, filters, auth, rate limit, status). This is clearly distinct from the generic verb siblings (search, resolve, fetch), though it never names an alternative explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no explicit 'use this before searching' or 'use X instead when…' statement; usage is only implied by the field inventory. The note that filters_supported reveals which search parameters a source applies upstream implicitly tells the agent to consult this before calling search, but the inference is left to the reader.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

operateA
Read-only

Inspect or query a remote tabular file (Parquet/CSV/TSV) WITHOUT downloading it. op='schema' returns columns+types; 'preview' a small sample; 'head' the first n rows; 'sql' a read-only SELECT against the file (exposed as the view 'data', e.g. "SELECT * FROM data WHERE x > 1"). op='peek' profiles every column WITHOUT downloading — type, null-rate, approximate distinct count, min/max, and numeric quartiles (a DuckDB SUMMARIZE; like head/sql it reads the whole file, so it honors the source-size ceiling). Tool names in this text are this server's own; your client may list them with a prefix (in Claude Code, mcp__data-aggregator__resolve): call the name it lists. Addresses a file by catalog id + file name (resolve the id first to see files[] and access_modes). Requires the [operate] extra; fails loud if the file is not an operable tabular file.

NameRequiredDescriptionDefault
nNoRow count for head/preview
idYesDataResource id (e.g. 'zenodo:1254563')
opYes
fileNoFile name within the record; optional when exactly one operable file is present.
queryNoRead-only SELECT for op='sql'.
columnsNoOptional column projection for head.

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the readOnlyHint annotation: it discloses that no download occurs, that 'sql' is read-only, that head/sql/peek read the whole file and therefore honor a source-size ceiling, and that peek is a DuckDB SUMMARIZE. These are non-obvious cost and side-effect traits an agent needs before choosing an op.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core promise, then a dense op-by-op breakdown where each clause adds information. However, the aside about tool-name prefixes ('in Claude Code, mcp__data-aggregator__resolve') is client-specific noise that doesn't help invoke this tool and slightly dilutes the signal.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Six parameters with mostly documented schema and no output schema, and the description sketches what each op returns (columns+types, sample rows, first n rows, column profile). Adequate for correct invocation; the main residual gap is not clarifying the exact shape/serialization of results or how 'preview' differs from 'head' beyond row count.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 83%, so the baseline is 3, but the description earns more by explaining the semantics of each enum value (schema/preview/head/sql/peek) and by giving a concrete SQL example against the view 'data'. The id-plus-file addressing model is also spelled out. It doesn't clarify the 'columns' projection or 'n' defaults, which the schema already covers.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Inspect or query a remote tabular file (Parquet/CSV/TSV)') and immediately clarifies scope with 'WITHOUT downloading it', which contrastively separates it from the fetch sibling. It then enumerates every op value, so an agent knows exactly what the tool covers without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear context: address files by catalog id + file name, and 'resolve the id first to see files[] and access_modes'. It also states the prerequisite ('Requires the [operate] extra') and the failure mode ('fails loud if the file is not an operable tabular file'). It does not explicitly name when to use fetch or search instead, so a 4 rather than a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

relateA
Read-only

Given 2-10 resource ids, return metadata-level join/harmonization HINTS: how the datasets relate and on what key they could be joined. Detects shared accessions (BioProject/SRA/GEO), shared cross-identifiers (doi/pmid/pmcid), explicit links between the inputs, and version lineage. Tool names in this text are this server's own; your client may list them with a prefix (in Claude Code, mcp__data-aggregator__resolve): call the name it lists. HINTS ONLY — it does not read file columns, fetch files, or execute any join/merge/conversion; each hint names the shared value as evidence. Resolve ids first if you only have a search result. Per-id resolve failures are reported, not fatal.

NameRequiredDescriptionDefault
idsYes2-10 source-prefixed resource ids to relate.

Output Schema

NameRequiredDescription
noteNo
hintsNo
errorsNo
resolvedYes
input_idsYes

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and the description does not contradict that — it reinforces it by stating no files are fetched and no joins are executed. Beyond the annotation it discloses that each hint names the shared value as evidence, and that per-id resolve failures are reported rather than fatal, which is exactly the kind of partial-failure behavior an agent needs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core contract (inputs, output kinds) before caveats, and every sentence carries information. The client-prefix aside about mcp__data-aggregator__resolve is useful but slightly peripheral, keeping it just short of a 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be described, and the description still characterizes what hints contain (join key plus the shared value as evidence). Combined with the failure-isolation note and the resolve prerequisite, an agent has everything needed to call this correctly and interpret results.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the schema documents the 2-10 range and 'source-prefixed resource ids,' so the description's job here is small. It still reinforces the count bound and the source-prefixed requirement, making the format constraint harder to miss than in schema alone.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (relate) plus the exact input shape (2-10 resource ids) and the output class (metadata-level join/harmonization hints), then enumerates the signal types it detects (shared accessions, cross-identifiers, explicit links, version lineage). This is clearly distinct from siblings like resolve and fetch, which return records rather than relationships.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly scopes use: 'HINTS ONLY — it does not read file columns, fetch files, or execute any join/merge/conversion,' which tells the agent when-not-to-use. It also gives a prerequisite ('Resolve ids first if you only have a search result') naming the correct sibling, so the ordering against resolve is unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

resolveA
Read-only

Tool names in this text are this server's own; your client may list them with a prefix (in Claude Code, mcp__data-aggregator__resolve): call the name it lists. Fetch the full DataResource for a known id (e.g. 'zenodo:1254563', 'datacite:10.5061/dryad.t4b8gtjgj', 'hf:davidcechak/Arabidopsis_thaliana_DNA_v0', a bare Zenodo record id, or a DOI), including the complete files[] manifest. Publication resolve also attaches normalized identifiers (pmid/pmcid/doi) and, when open access, a full-text file. Pass cite= to render a citation onto the result (citation field); omitted means no citation. Pass trust=true to attach retraction status (via Crossref) under trust{}. Pass fair=true to attach an RDA-grounded FAIRness score (0–100 + F/A/I/R sub-scores + actionable gaps) computed from the record under fair{}. Pass use= (commercial/redistribute/modify/ml-training) to attach a licence-compatibility advisory (ALLOW/REVIEW/DENY, not legal advice) under license_compat{}. Pass format=provenance for a one-call RO-Crate 1.1 data-availability dossier (under provenance{}) composing version-currency, licence+SPDX, FAIR score, retraction status, and the source/DOI/ID chain — it auto-attaches fair + trust.

NameRequiredDescriptionDefault
idYesSource-prefixed id, bare Zenodo id, or DOI
useNoWhen set, attach a licence-compatibility advisory under license_compat{} for an intended use of the record. Supported intents: 'commercial', 'redistribute', 'modify', 'ml-training' (training = a derivative+commercial use, our stated interpretation). The verdict is ALLOW/REVIEW/DENY computed from a bundled choosealicense.com licence matrix keyed on the normalized SPDX id, naming the governing clause — a metadata-derived advisory, NOT legal advice. An unrecognized or absent licence yields REVIEW (never a fabricated ALLOW/DENY); an unknown intent is an error.
citeNoOptional citation format to render onto the result: 'bibtex', 'ris', 'csl-json', or any CSL style name ('apa', 'mla', 'vancouver', ...). DOI-bearing records render via DOI content negotiation; non-DOI records support 'csl-json' only. Omitted = no citation. Failures degrade quietly (citation stays null).
fairNoWhen true, attach an RDA-grounded FAIRness assessment under fair{}: a 0–100 overall score plus findable/accessible/interoperable/reusable sub-scores, the count of indicators evaluated, and actionable gaps each naming its RDA FAIR Data Maturity Model indicator id. Pure/local — no network call. Only the machine-evaluable subset is scored (never fabricates what the metadata cannot show).
trustNoWhen true, attach trust signals (retraction status via Crossref) to the result under trust{}. One extra Crossref call; only meaningful for DOI-bearing records (a DataCite data DOI Crossref does not register leaves retracted=null = unknown, never a false clean claim).
formatNoOptional export to render onto the result. 'croissant' attaches a file-level Croissant JSON-LD manifest (croissant field); 'ro-crate' attaches a minimal RO-Crate 1.1 manifest (ro_crate field); 'provenance' attaches a one-call RO-Crate 1.1 data-availability dossier (provenance field) bundling version-currency, licence+SPDX, FAIR score, retraction status, and the source/DOI/ID chain — it auto-attaches fair{} and trust{} so the dossier is complete in one call (unknown signals are reported as unknown, never as a clean claim).

Output Schema

NameRequiredDescription
idYes
doiNo
fairNo
kindYes
taxaNo
yearNo
filesNo
linksNo
titleYes
trustNo
accessNo
errorsNo
sourceYes
fundingNo
licenseNo
methodsNo
metricsNo
mirrorsNo
citationNo
creatorsNo
organismNo
ro_crateNo
subjectsNo
croissantNo
is_latestNo
truncatedNo
accessionsNo
provenanceNo
descriptionNo
identifiersNo
access_modesNo
last_updatedNo
superseded_byNo
unshown_termsNo
license_compatNo
ranked_by_copyNo

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well past readOnlyHint=true, disclosing that trust adds a Crossref network call, that trust is only meaningful for DOI-bearing records leaving retracted=null rather than a false clean claim, that citation failures degrade quietly, and that provenance auto-attaches fair+trust. These are the kind of side-effect and failure-mode details annotations cannot convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Core purpose is front-loaded before the per-flag detail, and dense phrasing packs real information into each sentence. The opening client-prefix note is server-level meta rather than tool behavior, slightly diluting focus at the top.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read tool with an output schema, a full set of optional-flag behaviors, and explicit readOnlyHint, nothing needed to invoke it correctly is missing; the description covers id forms, each flag's effect, and fallback behavior.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the schema descriptions are already detailed, so the baseline is 3. The description still adds value by giving concrete id examples and clarifying the coupling between format=provenance and the auto-attached fair/trust signals.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (Fetch) and resource (full DataResource), scoped to 'a known id', and enumerates concrete id formats (zenodo:..., DOI, bare record id). An agent can tell this is a look-up-by-identifier, distinct from a search-by-query.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'For a known id' establishes the precondition to use this tool, and the optional-flag behaviors are spelled out. It never names the sibling `fetch` or `search` to route the agent explicitly, so the boundary with fetch in particular is left to inference.

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.

  1. 2 tool updatesv0.75.3
    • Changedoperate1 field changed
      • changedInput schema / properties / id / description
        Previous value: -"DataResource id (e.g. 'zenodo:7654321')"New value: +"DataResource id (e.g. 'zenodo:1254563')"
    • Changedsearch1 field changed
      • changedInput schema / properties / sources / description
        Previous value: -"Restrict fan-out to these sources (default: all). A dataset is often held only by a general archive (DataCite, Zenodo, DataONE), so leave this unset unless the user names the archives. Available: zenodo, dataone, gbif, cellxgene, datacite, dandi, omics, literature, huggingface, datagov, nasacmr, omicsdi, openml, pdb, uniprot, gwas, biostudies, ngdc, mwb, massive"New value: +"Restrict fan-out to these sources (default: all). A dataset is often held only by a general archive (DataCite, Zenodo, DataONE), so leave this unset unless the user names the archives. Available: zenodo, dataone, gbif, cellxgene, datacite, dandi, omics, literature, huggingface, datagov, nasacmr, omicsdi, openml, pdb, uniprot, gwas, biostudies, ngdc, mwb, massive, kaggle"
  2. 2 tool updatesv0.74.0
    • Changedresolve1 field changed
      • addedOutput schema / properties / ranked_by_copy
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Ranked By Copy"
        +}
    • Changedsearch3 fields changed
      • changedInput schema / properties / rank / description
        Previous value: -"Result ordering. 'relevance' (default) = hits that name more of the search first (each facet, then each query word, in the title, description, subjects or organism); among equal hits a data deposit (dataset, sequencing run, study) before a paper, figure or tool, then each source's own order. 'semantic' re-ranks the fetched page by embedding similarity to the query (needs EMBEDDING_API_BASE; degrades to relevance order with an errors['semantic'] note if unconfigured). In semantic mode pagination is window-based (each page consumes its full fetched window)."New value: +"Result ordering. 'relevance' (default) = hits that name more of the search first (each facet, then each query word, in the title, description, subjects or organism); among equal hits a data deposit (dataset, sequencing run, study) before a paper, figure or tool, then each source's own order. A deposit found in several sources is one hit, the most fetchable copy, ranked by its best-described copy; when that is another copy, ranked_by_copy names it (resolve it to see what matched). 'semantic' re-ranks the fetched page by embedding similarity to the query (needs EMBEDDING_API_BASE; degrades to relevance order with an errors['semantic'] note if unconfigured). In semantic mode pagination is window-based (each page consumes its full fetched window)."
      • changedInput schema / properties / sources / description
        Previous value: -"Restrict fan-out to these sources (default: all). Available: zenodo, dataone, gbif, cellxgene, datacite, dandi, omics, literature, huggingface, datagov, nasacmr, omicsdi, openml, pdb, uniprot, gwas, biostudies, ngdc, mwb, massive"New value: +"Restrict fan-out to these sources (default: all). A dataset is often held only by a general archive (DataCite, Zenodo, DataONE), so leave this unset unless the user names the archives. Available: zenodo, dataone, gbif, cellxgene, datacite, dandi, omics, literature, huggingface, datagov, nasacmr, omicsdi, openml, pdb, uniprot, gwas, biostudies, ngdc, mwb, massive"
      • addedOutput schema / $defs / DataResource / properties / ranked_by_copy
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Ranked By Copy"
        +}
  3. 2 tool updatesv0.71.0
    • Changedresolve2 fields changed
      • addedOutput schema / properties / methods
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Methods"
        +}
      • addedOutput schema / properties / unshown_terms
        Added value: +{
        +  "items": {
        +    "type": "string"
        +  },
        +  "title": "Unshown Terms",
        +  "type": "array"
        +}
    • Changedsearch4 fields changed
      • changedInput schema / properties / rank / description
        Previous value: -"Result ordering. 'relevance' (default) = hits that name more of the search first (each facet, then each query word, in the title, description, subjects or organism), each source's own order kept among equal hits. 'semantic' re-ranks the fetched page by embedding similarity to the query (needs EMBEDDING_API_BASE; degrades to relevance order with an errors['semantic'] note if unconfigured). In semantic mode pagination is window-based (each page consumes its full fetched window)."New value: +"Result ordering. 'relevance' (default) = hits that name more of the search first (each facet, then each query word, in the title, description, subjects or organism); among equal hits a data deposit (dataset, sequencing run, study) before a paper, figure or tool, then each source's own order. 'semantic' re-ranks the fetched page by embedding similarity to the query (needs EMBEDDING_API_BASE; degrades to relevance order with an errors['semantic'] note if unconfigured). In semantic mode pagination is window-based (each page consumes its full fetched window)."
      • changedInput schema / properties / sources / description
        Previous value: -"Restrict fan-out to these sources (default: all). Available: zenodo, dataone, gbif, cellxgene, datacite, dandi, omics, literature, huggingface, datagov, nasacmr, omicsdi, openml, pdb, uniprot, gwas, biostudies"New value: +"Restrict fan-out to these sources (default: all). Available: zenodo, dataone, gbif, cellxgene, datacite, dandi, omics, literature, huggingface, datagov, nasacmr, omicsdi, openml, pdb, uniprot, gwas, biostudies, ngdc, mwb, massive"
      • addedOutput schema / $defs / DataResource / properties / methods
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Methods"
        +}
      • addedOutput schema / $defs / DataResource / properties / unshown_terms
        Added value: +{
        +  "items": {
        +    "type": "string"
        +  },
        +  "title": "Unshown Terms",
        +  "type": "array"
        +}
  4. 1 tool updatev0.61.0
    • Changedsearch10 fields changed
      • changedInput schema / properties / chemical / description
        Previous value: -"Optional chemical/compound name. Resolved via ChEBI (EBI OLS); the query is expanded with the canonical name + exact synonyms (e.g. 'caffeine' also matches '1,3,7-trimethylxanthine'), capped to a bounded number of synonyms. An unknown term yields no expansion; an OLS failure surfaces in errors. The expansion is echoed in chemical_expansion."New value: +"Optional chemical/compound name. Resolved via ChEBI (EBI OLS); the query is expanded with the canonical name + exact synonyms (e.g. 'caffeine' also matches '1,3,7-trimethylxanthine'), capped to a bounded number of synonyms. An unknown term yields no expansion; an OLS failure surfaces in errors. The expansion is echoed in chemical_expansion. A name several terms carry resolves to the one it is the label of, else the one OLS ranks first; the others are listed in chemical_expansion.alternatives."
      • changedInput schema / properties / collapse_mirrors / description
        Previous value: -"Opt into conservative cross-repo content dedup (default false). On top of the always-on exact-DOI dedup, folds records that are the SAME dataset deposited under different (or no) DOIs — e.g. a Zenodo mirror of a figshare deposit, GEO<->ArrayExpress — into one record, annotating the survivor with the folded copies under mirrors[]. Conservative: a merge needs a shared file checksum OR identical (normalized-title, first-author name, year); title-only or partial matches never merge. Intra-page / best-effort only (a mirror on a different page is not collapsed), so a page may return fewer than size items; pagination is unaffected."New value: +"Opt into conservative cross-repo content dedup (default false). On top of the always-on exact-DOI dedup, folds records that are the SAME dataset deposited under different (or no) DOIs — e.g. a Zenodo mirror of a figshare deposit, GEO<->ArrayExpress — into one record, annotating the survivor with the folded copies under mirrors[]. Conservative: a merge needs a shared file checksum OR identical (normalized-title, first-author name, year); title-only or partial matches never merge. Records of one repository never fold into each other: versions and a concept DOI stay separate hits, and a copy elsewhere folds with the latest one. Intra-page / best-effort only (a mirror on a different page is not collapsed), so a page may return fewer than size items; pagination is unaffected."
      • changedInput schema / properties / organism / description
        Previous value: -"Optional organism name. Resolved via NCBI Taxonomy; the query is expanded with the canonical name + synonyms (e.g. 'Orobanche aegyptiaca' also matches 'Phelipanche aegyptiaca'). The expansion is echoed in taxon_expansion."New value: +"Optional organism name. Resolved via NCBI Taxonomy; the query is expanded with the canonical name + synonyms (e.g. 'Orobanche aegyptiaca' also matches 'Phelipanche aegyptiaca'). The expansion is echoed in taxon_expansion. A name matching several taxa resolves to the one it is the scientific name of, else the one with the most nucleotide records ('Drosophila' → the fly genus, not the fungus); the others are listed in taxon_expansion.alternatives."
      • changedInput schema / properties / rank / description
        Previous value: -"Result ordering. 'relevance' (default) = upstream/merged order. 'semantic' re-ranks the fetched page by embedding similarity to the query (needs EMBEDDING_API_BASE; degrades to relevance order with an errors['semantic'] note if unconfigured). In semantic mode pagination is window-based (each page consumes its full fetched window)."New value: +"Result ordering. 'relevance' (default) = hits that name more of the search first (each facet, then each query word, in the title, description, subjects or organism), each source's own order kept among equal hits. 'semantic' re-ranks the fetched page by embedding similarity to the query (needs EMBEDDING_API_BASE; degrades to relevance order with an errors['semantic'] note if unconfigured). In semantic mode pagination is window-based (each page consumes its full fetched window)."
      • changedInput schema / properties / tissue / description
        Previous value: -"Optional tissue/anatomy name. Resolved via UBERON (EBI OLS); the query is expanded with the canonical term + exact synonyms (e.g. 'liver' also matches 'iecur'/'jecur'). The expansion is echoed in tissue_expansion."New value: +"Optional tissue/anatomy name. Resolved via UBERON (EBI OLS); the query is expanded with the canonical term + exact synonyms (e.g. 'liver' also matches 'iecur'/'jecur'). The expansion is echoed in tissue_expansion. A name several terms carry resolves to the one it is the label of, else the one OLS ranks first ('skin' → 'zone of skin', whose exact synonym it is); the others are listed in tissue_expansion.alternatives."
      • addedOutput schema / $defs / ChemicalExpansion / properties / alternatives
        Added value: +{
        +  "items": {
        +    "$ref": "#/$defs/TermAlternative"
        +  },
        +  "title": "Alternatives",
        +  "type": "array"
        +}
      • addedOutput schema / $defs / TaxonAlternative
        Added value: +{
        +  "description": "Another taxon the organism name matched, not chosen.",
        +  "properties": {
        +    "name": {
        +      "title": "Name",
        +      "type": "string"
        +    },
        +    "taxid": {
        +      "title": "Taxid",
        +      "type": "integer"
        +    }
        +  },
        +  "required": [
        +    "taxid",
        +    "name"
        +  ],
        +  "title": "TaxonAlternative",
        +  "type": "object"
        +}
      • addedOutput schema / $defs / TaxonExpansion / properties / alternatives
        Added value: +{
        +  "items": {
        +    "$ref": "#/$defs/TaxonAlternative"
        +  },
        +  "title": "Alternatives",
        +  "type": "array"
        +}
      • addedOutput schema / $defs / TermAlternative
        Added value: +{
        +  "description": "Another ontology term the param matched, not chosen.",
        +  "properties": {
        +    "id": {
        +      "title": "Id",
        +      "type": "string"
        +    },
        +    "label": {
        +      "title": "Label",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "id",
        +    "label"
        +  ],
        +  "title": "TermAlternative",
        +  "type": "object"
        +}
      • addedOutput schema / $defs / TissueExpansion / properties / alternatives
        Added value: +{
        +  "items": {
        +    "$ref": "#/$defs/TermAlternative"
        +  },
        +  "title": "Alternatives",
        +  "type": "array"
        +}
  5. 1 tool updatev0.54.14
    • Changedsearch1 field changed
      • changedInput schema / properties / collapse_mirrors / description
        Previous value: -"Opt into conservative cross-repo content dedup (default false). On top of the always-on exact-DOI dedup, folds records that are the SAME dataset deposited under different (or no) DOIs — e.g. a Zenodo mirror of a figshare deposit, GEO<->ArrayExpress — into one record, annotating the survivor with the folded copies under mirrors[]. Conservative: a merge needs a shared file checksum OR identical (normalized-title, first-author-surname, year); title-only or partial matches never merge. Intra-page / best-effort only (a mirror on a different page is not collapsed), so a page may return fewer than size items; pagination is unaffected."New value: +"Opt into conservative cross-repo content dedup (default false). On top of the always-on exact-DOI dedup, folds records that are the SAME dataset deposited under different (or no) DOIs — e.g. a Zenodo mirror of a figshare deposit, GEO<->ArrayExpress — into one record, annotating the survivor with the folded copies under mirrors[]. Conservative: a merge needs a shared file checksum OR identical (normalized-title, first-author name, year); title-only or partial matches never merge. Intra-page / best-effort only (a mirror on a different page is not collapsed), so a page may return fewer than size items; pagination is unaffected."
  6. 6 tool updatesv0.54.1
    • Changedfetch1 field changed
      • addedInput schema / additionalProperties
        Added value: +false
    • Changedlist_sources1 field changed
      • addedInput schema / additionalProperties
        Added value: +false
    • Changedoperate1 field changed
      • addedInput schema / additionalProperties
        Added value: +false
    • Changedrelate1 field changed
      • addedInput schema / additionalProperties
        Added value: +false
    • Changedresolve3 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedOutput schema / properties / errors
        Added value: +{
        +  "additionalProperties": {
        +    "type": "string"
        +  },
        +  "title": "Errors",
        +  "type": "object"
        +}
      • addedOutput schema / properties / truncated
        Added value: +{
        +  "additionalProperties": {
        +    "type": "string"
        +  },
        +  "title": "Truncated",
        +  "type": "object"
        +}
    • Changedsearch3 fields changed
      • addedInput schema / additionalProperties
        Added value: +false
      • addedOutput schema / $defs / DataResource / properties / errors
        Added value: +{
        +  "additionalProperties": {
        +    "type": "string"
        +  },
        +  "title": "Errors",
        +  "type": "object"
        +}
      • addedOutput schema / $defs / DataResource / properties / truncated
        Added value: +{
        +  "additionalProperties": {
        +    "type": "string"
        +  },
        +  "title": "Truncated",
        +  "type": "object"
        +}
  7. 1 tool updatev0.46.0
    • Changedoperate1 field changed
      • addedInput schema / properties / n / minimum
        Added value: +1
  8. 1 tool updatev0.45.3
    • Changedfetch1 field changed
      • addedOutput schema / properties / unverified
        Added value: +{
        +  "items": {
        +    "type": "string"
        +  },
        +  "title": "Unverified",
        +  "type": "array"
        +}
  9. 2 tool updatesv0.45.1
    • Addedresolve
    • Addedsearch
  10. 3 tool updatesv0.43.0
    • Addedrelate
    • Removedresolve
    • Removedsearch
  11. 3 tool updatesv0.42.0
    • Changedlist_sources1 field changed
      • changedInput schema / properties / check_health / description
        Previous value: -"When true, probe 5 sources (zenodo, datacite, omics, literature, huggingface) and attach a 'health' field ({status: up|down, latency_ms, detail}) to those entries; the remaining 7 sources get health: null. Default false: returns the static catalog with no network."New value: +"When true, probe 5 sources (zenodo, datacite, omics, literature, huggingface) and attach a 'health' field ({status: up|down, latency_ms, detail}) to those entries; every other source gets health: null. Default false: returns the static catalog with no network."
    • Removedrelate
    • Changedsearch4 fields changed
      • changedInput schema / properties / sources / description
        Previous value: -"Restrict fan-out to these sources (default: all). Available: zenodo, dataone, cellxgene, datacite, dandi, omics, literature, huggingface, omicsdi, openml, pdb, uniprot, gwas"New value: +"Restrict fan-out to these sources (default: all). Available: zenodo, dataone, gbif, cellxgene, datacite, dandi, omics, literature, huggingface, datagov, nasacmr, omicsdi, openml, pdb, uniprot, gwas, biostudies"
      • addedOutput schema / $defs / QueryUnderstanding / properties / confidence
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "number"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Confidence"
        +}
      • addedOutput schema / $defs / UnresolvedEntity
        Added value: +{
        +  "description": "Echo of an ontology-typed search param that was supplied but matched NO term,\nso the query ran WITHOUT that expansion.\n\nDistinct from ``SearchResult.errors``: an entry there means the ontology LOOKUP\nFAILED (HTTP/parse) and the two are mutually exclusive per field. An entry here\nmeans the lookup SUCCEEDED and legitimately returned no match — the common case\nfor a common name the registry does not index (NCBI Taxonomy has no ``yeast``,\n``oak`` or ``cedar``; UBERON has no bare ``root``).\n\nWithout this echo the response for a silently-dropped param is byte-identical to\none where the param was never passed, so the caller cannot tell that the filter\nthey asked for was not applied.",
        +  "properties": {
        +    "field": {
        +      "title": "Field",
        +      "type": "string"
        +    },
        +    "input": {
        +      "title": "Input",
        +      "type": "string"
        +    },
        +    "note": {
        +      "title": "Note",
        +      "type": "string"
        +    },
        +    "ontology": {
        +      "title": "Ontology",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "field",
        +    "input",
        +    "ontology",
        +    "note"
        +  ],
        +  "title": "UnresolvedEntity",
        +  "type": "object"
        +}
      • addedOutput schema / properties / unresolved
        Added value: +{
        +  "items": {
        +    "$ref": "#/$defs/UnresolvedEntity"
        +  },
        +  "title": "Unresolved",
        +  "type": "array"
        +}
  12. 1 tool updatev0.41.1
    • Changedsearch1 field changed
      • changedInput schema / properties / sources / description
        Previous value: -"Restrict fan-out to these sources (default: all). Available: zenodo, dataone, cellxgene, datacite, dandi, omics, literature, huggingface, omicsdi, openml, pdb, gwas"New value: +"Restrict fan-out to these sources (default: all). Available: zenodo, dataone, cellxgene, datacite, dandi, omics, literature, huggingface, omicsdi, openml, pdb, uniprot, gwas"
  13. 5 tool updatesv0.40.0
    • Changedlist_sources1 field changed
      • changedInput schema / properties / check_health / description
        Previous value: -"When true, probe each source's base endpoint and attach a 'health' field ({status: up|down, latency_ms, detail}) to each source. Default false: returns the static catalog with no network."New value: +"When true, probe 5 sources (zenodo, datacite, omics, literature, huggingface) and attach a 'health' field ({status: up|down, latency_ms, detail}) to those entries; the remaining 7 sources get health: null. Default false: returns the static catalog with no network."
    • Changedoperate1 field changed
      • changedInput schema / properties / op / enum
        Previous value: -[
        -  "schema",
        -  "preview",
        -  "head",
        -  "sql"
        -]New value: +[
        +  "schema",
        +  "preview",
        +  "head",
        +  "sql",
        +  "peek"
        +]
    • Addedrelate
    • Changedresolve14 fields changed
      • addedInput schema / properties / fair
        Added value: +{
        +  "description": "When true, attach an RDA-grounded FAIRness assessment under fair{}: a 0–100 overall score plus findable/accessible/interoperable/reusable sub-scores, the count of indicators evaluated, and actionable gaps each naming its RDA FAIR Data Maturity Model indicator id. Pure/local — no network call. Only the machine-evaluable subset is scored (never fabricates what the metadata cannot show).",
        +  "type": "boolean"
        +}
      • changedInput schema / properties / format / description
        Previous value: -"Optional export to render onto the result. 'croissant' attaches a file-level Croissant JSON-LD manifest (croissant field); 'ro-crate' attaches a minimal RO-Crate 1.1 manifest (ro_crate field)."New value: +"Optional export to render onto the result. 'croissant' attaches a file-level Croissant JSON-LD manifest (croissant field); 'ro-crate' attaches a minimal RO-Crate 1.1 manifest (ro_crate field); 'provenance' attaches a one-call RO-Crate 1.1 data-availability dossier (provenance field) bundling version-currency, licence+SPDX, FAIR score, retraction status, and the source/DOI/ID chain — it auto-attaches fair{} and trust{} so the dossier is complete in one call (unknown signals are reported as unknown, never as a clean claim)."
      • changedInput schema / properties / format / enum
        Previous value: -[
        -  "croissant",
        -  "ro-crate"
        -]New value: +[
        +  "croissant",
        +  "ro-crate",
        +  "provenance"
        +]
      • addedInput schema / properties / trust
        Added value: +{
        +  "description": "When true, attach trust signals (retraction status via Crossref) to the result under trust{}. One extra Crossref call; only meaningful for DOI-bearing records (a DataCite data DOI Crossref does not register leaves retracted=null = unknown, never a false clean claim).",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / use
        Added value: +{
        +  "description": "When set, attach a licence-compatibility advisory under license_compat{} for an intended use of the record. Supported intents: 'commercial', 'redistribute', 'modify', 'ml-training' (training = a derivative+commercial use, our stated interpretation). The verdict is ALLOW/REVIEW/DENY computed from a bundled choosealicense.com licence matrix keyed on the normalized SPDX id, naming the governing clause — a metadata-derived advisory, NOT legal advice. An unrecognized or absent licence yields REVIEW (never a fabricated ALLOW/DENY); an unknown intent is an error.",
        +  "type": "string"
        +}
      • addedOutput schema / $defs / FairAssessment
        Added value: +{
        +  "description": "FAIRness assessment attached on resolve(fair=True). PURE-function output:\na 0–100 overall score plus 0–100 per-dimension sub-scores, grounded in the\nmachine-evaluable subset of the RDA FAIR Data Maturity Model. ``assessed`` is\nthe count of indicators actually evaluated (transparency — we never score what\nthe metadata can't show). ``gaps`` are failed-indicator reasons, each naming its\nRDA indicator id and framed as a metadata-exposure gap, not a value judgement.",
        +  "properties": {
        +    "accessible": {
        +      "title": "Accessible",
        +      "type": "integer"
        +    },
        +    "assessed": {
        +      "title": "Assessed",
        +      "type": "integer"
        +    },
        +    "findable": {
        +      "title": "Findable",
        +      "type": "integer"
        +    },
        +    "gaps": {
        +      "items": {
        +        "type": "string"
        +      },
        +      "title": "Gaps",
        +      "type": "array"
        +    },
        +    "interoperable": {
        +      "title": "Interoperable",
        +      "type": "integer"
        +    },
        +    "reusable": {
        +      "title": "Reusable",
        +      "type": "integer"
        +    },
        +    "score": {
        +      "title": "Score",
        +      "type": "integer"
        +    }
        +  },
        +  "required": [
        +    "score",
        +    "findable",
        +    "accessible",
        +    "interoperable",
        +    "reusable",
        +    "assessed"
        +  ],
        +  "title": "FairAssessment",
        +  "type": "object"
        +}
      • addedOutput schema / $defs / LicenseVerdict
        Added value: +{
        +  "description": "Licence-compatibility advisory attached on resolve(use=<intent>). PURE-function\noutput: an ALLOW / REVIEW / DENY verdict for an intended use of the resolved record,\ncomputed from a bundled licence matrix (choosealicense.com flag vocabulary) keyed on\nthe normalized SPDX id. ``spdx_id`` is None exactly when the licence was unrecognized\nor absent (→ REVIEW, never a fabricated ALLOW/DENY). ``reason`` names the governing\nclause; ``disclaimer`` states this is a metadata-derived advisory, not legal advice.",
        +  "properties": {
        +    "disclaimer": {
        +      "title": "Disclaimer",
        +      "type": "string"
        +    },
        +    "license_raw": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "title": "License Raw"
        +    },
        +    "reason": {
        +      "title": "Reason",
        +      "type": "string"
        +    },
        +    "spdx_id": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "title": "Spdx Id"
        +    },
        +    "use": {
        +      "title": "Use",
        +      "type": "string"
        +    },
        +    "verdict": {
        +      "enum": [
        +        "ALLOW",
        +        "REVIEW",
        +        "DENY"
        +      ],
        +      "title": "Verdict",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "use",
        +    "verdict",
        +    "spdx_id",
        +    "license_raw",
        +    "reason",
        +    "disclaimer"
        +  ],
        +  "title": "LicenseVerdict",
        +  "type": "object"
        +}
      • addedOutput schema / $defs / Mirror
        Added value: +{
        +  "description": "A same-dataset copy folded into this record by content dedup (resolve the\nmirror's id to reach the original deposit). Only populated when a search ran\nwith the opt-in ``collapse_mirrors`` flag.",
        +  "properties": {
        +    "doi": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "default": null,
        +      "title": "Doi"
        +    },
        +    "id": {
        +      "title": "Id",
        +      "type": "string"
        +    },
        +    "source": {
        +      "title": "Source",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "source",
        +    "id"
        +  ],
        +  "title": "Mirror",
        +  "type": "object"
        +}
      • addedOutput schema / $defs / TrustSignals
        Added value: +{
        +  "description": "Integrity/provenance signals attached on resolve(trust=True). All nullable:\nNone = not checked or not determinable (e.g. a DOI Crossref doesn't register) —\nNEVER a negative claim. A *found* Crossref work yields definitive booleans.",
        +  "properties": {
        +    "concern": {
        +      "anyOf": [
        +        {
        +          "type": "boolean"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "default": null,
        +      "title": "Concern"
        +    },
        +    "retracted": {
        +      "anyOf": [
        +        {
        +          "type": "boolean"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "default": null,
        +      "title": "Retracted"
        +    },
        +    "retraction_doi": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "default": null,
        +      "title": "Retraction Doi"
        +    }
        +  },
        +  "title": "TrustSignals",
        +  "type": "object"
        +}
      • addedOutput schema / properties / fair
        Added value: +{
        +  "anyOf": [
        +    {
        +      "$ref": "#/$defs/FairAssessment"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null
        +}
      • addedOutput schema / properties / license_compat
        Added value: +{
        +  "anyOf": [
        +    {
        +      "$ref": "#/$defs/LicenseVerdict"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null
        +}
      • addedOutput schema / properties / mirrors
        Added value: +{
        +  "items": {
        +    "$ref": "#/$defs/Mirror"
        +  },
        +  "title": "Mirrors",
        +  "type": "array"
        +}
      • addedOutput schema / properties / provenance
        Added value: +{
        +  "anyOf": [
        +    {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Provenance"
        +}
      • addedOutput schema / properties / trust
        Added value: +{
        +  "anyOf": [
        +    {
        +      "$ref": "#/$defs/TrustSignals"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null
        +}
    • Changedsearch31 fields changed
      • addedInput schema / properties / assay
        Added value: +{
        +  "description": "Optional assay/method name. Resolved via EDAM topics (EBI OLS); the query is expanded with the canonical name + exact synonyms (e.g. 'ChIP-seq' also matches 'ChIP-sequencing'/'ChIP-exo'). An unknown term yields no expansion; an OLS failure surfaces in errors. The expansion is echoed in assay_expansion.",
        +  "type": "string"
        +}
      • addedInput schema / properties / chemical
        Added value: +{
        +  "description": "Optional chemical/compound name. Resolved via ChEBI (EBI OLS); the query is expanded with the canonical name + exact synonyms (e.g. 'caffeine' also matches '1,3,7-trimethylxanthine'), capped to a bounded number of synonyms. An unknown term yields no expansion; an OLS failure surfaces in errors. The expansion is echoed in chemical_expansion.",
        +  "type": "string"
        +}
      • addedInput schema / properties / collapse_mirrors
        Added value: +{
        +  "default": false,
        +  "description": "Opt into conservative cross-repo content dedup (default false). On top of the always-on exact-DOI dedup, folds records that are the SAME dataset deposited under different (or no) DOIs — e.g. a Zenodo mirror of a figshare deposit, GEO<->ArrayExpress — into one record, annotating the survivor with the folded copies under mirrors[]. Conservative: a merge needs a shared file checksum OR identical (normalized-title, first-author-surname, year); title-only or partial matches never merge. Intra-page / best-effort only (a mirror on a different page is not collapsed), so a page may return fewer than size items; pagination is unaffected.",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / disease
        Added value: +{
        +  "description": "Optional disease/phenotype name. Resolved via MeSH (NCBI E-utilities); the query is expanded with the canonical descriptor + entry-term synonyms (e.g. 'breast cancer' also matches 'Breast Neoplasms'). The expansion is echoed in mesh_expansion.",
        +  "type": "string"
        +}
      • addedInput schema / properties / multi_query
        Added value: +{
        +  "default": false,
        +  "description": "Opt into diverse multi-query recall expansion: an LLM generates up to a few deliberately-diverse reformulations of your query, each is fanned out across all sources, and the deduped union is re-ranked against your original query — surfacing relevant records a single keyword query would miss. Costs N× the upstream calls (bounded). Requires an LLM endpoint (LLM_API_BASE); with none configured the search runs as a normal single query and notes it in errors['multi_query']. The variants used are echoed in query_expansion. Composes with understand=. NOTE: multi_query=true ALWAYS applies semantic re-ranking of the window internally regardless of rank=; the rank= param has no effect in this mode.",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / provenance
        Added value: +{
        +  "default": false,
        +  "description": "Opt into a whole-search RO-Crate 1.1 Run Crate (default false). Attaches provenance_crate{} — a machine-readable manifest documenting this search: the query, the sources queried, the ontology expansions that fired, the per-source errors (a partial search is disclosed), and per-hit provenance for every result (version-currency, licence + normalized SPDX, FAIR score). Per-hit RETRACTION is omitted — it would need one Crossref call per hit; use per-record resolve(format=provenance) for that. Covers THIS search page only (intra-page; each page of a paginated search gets its own crate).",
        +  "type": "boolean"
        +}
      • changedInput schema / properties / sources / description
        Previous value: -"Restrict fan-out to these sources (default: all). Available: zenodo, datacite, omics, literature, huggingface, dataone, omicsdi"New value: +"Restrict fan-out to these sources (default: all). Available: zenodo, dataone, cellxgene, datacite, dandi, omics, literature, huggingface, omicsdi, openml, pdb, gwas"
      • addedInput schema / properties / tissue
        Added value: +{
        +  "description": "Optional tissue/anatomy name. Resolved via UBERON (EBI OLS); the query is expanded with the canonical term + exact synonyms (e.g. 'liver' also matches 'iecur'/'jecur'). The expansion is echoed in tissue_expansion.",
        +  "type": "string"
        +}
      • addedInput schema / properties / understand
        Added value: +{
        +  "default": false,
        +  "description": "Opt into LLM query understanding: a free-text query is rewritten into a keyword core + structured params (organism/disease/tissue/chemical/assay, kind, year) before fan-out; extracted entities are validated by the same ontology resolvers (a hallucinated entity that doesn't resolve is simply dropped), explicit params you pass always win, and the interpretation is echoed in query_understanding. Requires an LLM endpoint (LLM_API_BASE); with none configured the search runs unchanged and notes it in errors['understand'].",
        +  "type": "boolean"
        +}
      • addedOutput schema / $defs / AssayExpansion
        Added value: +{
        +  "description": "Echo of EDAM assay-synonym expansion that fired for a search (transparency).",
        +  "properties": {
        +    "canonical_name": {
        +      "title": "Canonical Name",
        +      "type": "string"
        +    },
        +    "edam_id": {
        +      "title": "Edam Id",
        +      "type": "string"
        +    },
        +    "input": {
        +      "title": "Input",
        +      "type": "string"
        +    },
        +    "synonyms": {
        +      "items": {
        +        "type": "string"
        +      },
        +      "title": "Synonyms",
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "input",
        +    "edam_id",
        +    "canonical_name",
        +    "synonyms"
        +  ],
        +  "title": "AssayExpansion",
        +  "type": "object"
        +}
      • addedOutput schema / $defs / ChemicalExpansion
        Added value: +{
        +  "description": "Echo of ChEBI chemical-synonym expansion that fired for a search (transparency).",
        +  "properties": {
        +    "canonical_name": {
        +      "title": "Canonical Name",
        +      "type": "string"
        +    },
        +    "chebi_id": {
        +      "title": "Chebi Id",
        +      "type": "string"
        +    },
        +    "input": {
        +      "title": "Input",
        +      "type": "string"
        +    },
        +    "synonyms": {
        +      "items": {
        +        "type": "string"
        +      },
        +      "title": "Synonyms",
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "input",
        +    "chebi_id",
        +    "canonical_name",
        +    "synonyms"
        +  ],
        +  "title": "ChemicalExpansion",
        +  "type": "object"
        +}
      • addedOutput schema / $defs / DataResource / properties / fair
        Added value: +{
        +  "anyOf": [
        +    {
        +      "$ref": "#/$defs/FairAssessment"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null
        +}
      • addedOutput schema / $defs / DataResource / properties / license_compat
        Added value: +{
        +  "anyOf": [
        +    {
        +      "$ref": "#/$defs/LicenseVerdict"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null
        +}
      • addedOutput schema / $defs / DataResource / properties / mirrors
        Added value: +{
        +  "items": {
        +    "$ref": "#/$defs/Mirror"
        +  },
        +  "title": "Mirrors",
        +  "type": "array"
        +}
      • addedOutput schema / $defs / DataResource / properties / provenance
        Added value: +{
        +  "anyOf": [
        +    {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Provenance"
        +}
      • addedOutput schema / $defs / DataResource / properties / trust
        Added value: +{
        +  "anyOf": [
        +    {
        +      "$ref": "#/$defs/TrustSignals"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null
        +}
      • addedOutput schema / $defs / FairAssessment
        Added value: +{
        +  "description": "FAIRness assessment attached on resolve(fair=True). PURE-function output:\na 0–100 overall score plus 0–100 per-dimension sub-scores, grounded in the\nmachine-evaluable subset of the RDA FAIR Data Maturity Model. ``assessed`` is\nthe count of indicators actually evaluated (transparency — we never score what\nthe metadata can't show). ``gaps`` are failed-indicator reasons, each naming its\nRDA indicator id and framed as a metadata-exposure gap, not a value judgement.",
        +  "properties": {
        +    "accessible": {
        +      "title": "Accessible",
        +      "type": "integer"
        +    },
        +    "assessed": {
        +      "title": "Assessed",
        +      "type": "integer"
        +    },
        +    "findable": {
        +      "title": "Findable",
        +      "type": "integer"
        +    },
        +    "gaps": {
        +      "items": {
        +        "type": "string"
        +      },
        +      "title": "Gaps",
        +      "type": "array"
        +    },
        +    "interoperable": {
        +      "title": "Interoperable",
        +      "type": "integer"
        +    },
        +    "reusable": {
        +      "title": "Reusable",
        +      "type": "integer"
        +    },
        +    "score": {
        +      "title": "Score",
        +      "type": "integer"
        +    }
        +  },
        +  "required": [
        +    "score",
        +    "findable",
        +    "accessible",
        +    "interoperable",
        +    "reusable",
        +    "assessed"
        +  ],
        +  "title": "FairAssessment",
        +  "type": "object"
        +}
      • addedOutput schema / $defs / LicenseVerdict
        Added value: +{
        +  "description": "Licence-compatibility advisory attached on resolve(use=<intent>). PURE-function\noutput: an ALLOW / REVIEW / DENY verdict for an intended use of the resolved record,\ncomputed from a bundled licence matrix (choosealicense.com flag vocabulary) keyed on\nthe normalized SPDX id. ``spdx_id`` is None exactly when the licence was unrecognized\nor absent (→ REVIEW, never a fabricated ALLOW/DENY). ``reason`` names the governing\nclause; ``disclaimer`` states this is a metadata-derived advisory, not legal advice.",
        +  "properties": {
        +    "disclaimer": {
        +      "title": "Disclaimer",
        +      "type": "string"
        +    },
        +    "license_raw": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "title": "License Raw"
        +    },
        +    "reason": {
        +      "title": "Reason",
        +      "type": "string"
        +    },
        +    "spdx_id": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "title": "Spdx Id"
        +    },
        +    "use": {
        +      "title": "Use",
        +      "type": "string"
        +    },
        +    "verdict": {
        +      "enum": [
        +        "ALLOW",
        +        "REVIEW",
        +        "DENY"
        +      ],
        +      "title": "Verdict",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "use",
        +    "verdict",
        +    "spdx_id",
        +    "license_raw",
        +    "reason",
        +    "disclaimer"
        +  ],
        +  "title": "LicenseVerdict",
        +  "type": "object"
        +}
      • addedOutput schema / $defs / MeshExpansion
        Added value: +{
        +  "description": "Echo of MeSH-synonym expansion that fired for a search (transparency).",
        +  "properties": {
        +    "canonical_name": {
        +      "title": "Canonical Name",
        +      "type": "string"
        +    },
        +    "input": {
        +      "title": "Input",
        +      "type": "string"
        +    },
        +    "mesh_ui": {
        +      "title": "Mesh Ui",
        +      "type": "string"
        +    },
        +    "synonyms": {
        +      "items": {
        +        "type": "string"
        +      },
        +      "title": "Synonyms",
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "input",
        +    "mesh_ui",
        +    "canonical_name",
        +    "synonyms"
        +  ],
        +  "title": "MeshExpansion",
        +  "type": "object"
        +}
      • addedOutput schema / $defs / Mirror
        Added value: +{
        +  "description": "A same-dataset copy folded into this record by content dedup (resolve the\nmirror's id to reach the original deposit). Only populated when a search ran\nwith the opt-in ``collapse_mirrors`` flag.",
        +  "properties": {
        +    "doi": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "default": null,
        +      "title": "Doi"
        +    },
        +    "id": {
        +      "title": "Id",
        +      "type": "string"
        +    },
        +    "source": {
        +      "title": "Source",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "source",
        +    "id"
        +  ],
        +  "title": "Mirror",
        +  "type": "object"
        +}
      • addedOutput schema / $defs / QueryExpansion
        Added value: +{
        +  "description": "Transparency echo of A2.P2 multi-query recall expansion (search multi_query=true).\n\nWhen enabled and an LLM endpoint is configured, the LLM generates deliberately-diverse\nreformulations of the query; each variant is fanned out across all sources, and the\ndeduped union is re-ranked against the ORIGINAL query. ``variants`` lists the RAW variants\nactually fanned out, the original query first. Each variant received the same ontology\nexpansion (shown by the ``*_expansion`` echoes); results are the deduped union re-ranked\nagainst ``input``.",
        +  "properties": {
        +    "input": {
        +      "title": "Input",
        +      "type": "string"
        +    },
        +    "variants": {
        +      "items": {
        +        "type": "string"
        +      },
        +      "title": "Variants",
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "input",
        +    "variants"
        +  ],
        +  "title": "QueryExpansion",
        +  "type": "object"
        +}
      • addedOutput schema / $defs / QueryUnderstanding
        Added value: +{
        +  "description": "Echo of the LLM query-understanding rewrite that fired (transparency, A2.P1).\n\nThe LLM proposes; explicit caller params win; the ontology resolvers then VALIDATE the\nproposed entities. ``applied`` lists the fields the caller left None that were FED into\nthis search as parameters — for ontology entities (organism/disease/tissue/chemical/\nassay) this means \"passed to the resolver\", NOT \"resolved\": whether it actually expanded\nis shown by the corresponding ``*_expansion`` echo (None there ⇒ the entity did not\nresolve, and was never silently treated as a match). ``overridden`` lists fields the LLM\nproposed but the caller had set explicitly (so the LLM's value was ignored).",
        +  "properties": {
        +    "applied": {
        +      "additionalProperties": true,
        +      "title": "Applied",
        +      "type": "object"
        +    },
        +    "extracted": {
        +      "additionalProperties": true,
        +      "title": "Extracted",
        +      "type": "object"
        +    },
        +    "input": {
        +      "title": "Input",
        +      "type": "string"
        +    },
        +    "keyword_core": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "title": "Keyword Core"
        +    },
        +    "overridden": {
        +      "items": {
        +        "type": "string"
        +      },
        +      "title": "Overridden",
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "input",
        +    "keyword_core"
        +  ],
        +  "title": "QueryUnderstanding",
        +  "type": "object"
        +}
      • addedOutput schema / $defs / TissueExpansion
        Added value: +{
        +  "description": "Echo of UBERON tissue-synonym expansion that fired for a search (transparency).",
        +  "properties": {
        +    "canonical_name": {
        +      "title": "Canonical Name",
        +      "type": "string"
        +    },
        +    "input": {
        +      "title": "Input",
        +      "type": "string"
        +    },
        +    "synonyms": {
        +      "items": {
        +        "type": "string"
        +      },
        +      "title": "Synonyms",
        +      "type": "array"
        +    },
        +    "uberon_id": {
        +      "title": "Uberon Id",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "input",
        +    "uberon_id",
        +    "canonical_name",
        +    "synonyms"
        +  ],
        +  "title": "TissueExpansion",
        +  "type": "object"
        +}
      • addedOutput schema / $defs / TrustSignals
        Added value: +{
        +  "description": "Integrity/provenance signals attached on resolve(trust=True). All nullable:\nNone = not checked or not determinable (e.g. a DOI Crossref doesn't register) —\nNEVER a negative claim. A *found* Crossref work yields definitive booleans.",
        +  "properties": {
        +    "concern": {
        +      "anyOf": [
        +        {
        +          "type": "boolean"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "default": null,
        +      "title": "Concern"
        +    },
        +    "retracted": {
        +      "anyOf": [
        +        {
        +          "type": "boolean"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "default": null,
        +      "title": "Retracted"
        +    },
        +    "retraction_doi": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "default": null,
        +      "title": "Retraction Doi"
        +    }
        +  },
        +  "title": "TrustSignals",
        +  "type": "object"
        +}
      • addedOutput schema / properties / assay_expansion
        Added value: +{
        +  "anyOf": [
        +    {
        +      "$ref": "#/$defs/AssayExpansion"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null
        +}
      • addedOutput schema / properties / chemical_expansion
        Added value: +{
        +  "anyOf": [
        +    {
        +      "$ref": "#/$defs/ChemicalExpansion"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null
        +}
      • addedOutput schema / properties / mesh_expansion
        Added value: +{
        +  "anyOf": [
        +    {
        +      "$ref": "#/$defs/MeshExpansion"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null
        +}
      • addedOutput schema / properties / provenance_crate
        Added value: +{
        +  "anyOf": [
        +    {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Provenance Crate"
        +}
      • addedOutput schema / properties / query_expansion
        Added value: +{
        +  "anyOf": [
        +    {
        +      "$ref": "#/$defs/QueryExpansion"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null
        +}
      • addedOutput schema / properties / query_understanding
        Added value: +{
        +  "anyOf": [
        +    {
        +      "$ref": "#/$defs/QueryUnderstanding"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null
        +}
      • addedOutput schema / properties / tissue_expansion
        Added value: +{
        +  "anyOf": [
        +    {
        +      "$ref": "#/$defs/TissueExpansion"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null
        +}
  14. 3 tool updatesv0.20.0
    • Addedoperate
    • Changedresolve9 fields changed
      • addedInput schema / properties / format
        Added value: +{
        +  "description": "Optional export to render onto the result. 'croissant' attaches a file-level Croissant JSON-LD manifest (croissant field); 'ro-crate' attaches a minimal RO-Crate 1.1 manifest (ro_crate field).",
        +  "enum": [
        +    "croissant",
        +    "ro-crate"
        +  ],
        +  "type": "string"
        +}
      • addedOutput schema / $defs / Metrics
        Added value: +{
        +  "description": "Usage/impact signals, each a separate axis — NO blended score. All\nnullable: a source that does not expose an axis leaves it None.",
        +  "properties": {
        +    "citations": {
        +      "anyOf": [
        +        {
        +          "type": "integer"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "default": null,
        +      "title": "Citations"
        +    },
        +    "downloads": {
        +      "anyOf": [
        +        {
        +          "type": "integer"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "default": null,
        +      "title": "Downloads"
        +    },
        +    "likes": {
        +      "anyOf": [
        +        {
        +          "type": "integer"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "default": null,
        +      "title": "Likes"
        +    },
        +    "views": {
        +      "anyOf": [
        +        {
        +          "type": "integer"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "default": null,
        +      "title": "Views"
        +    }
        +  },
        +  "title": "Metrics",
        +  "type": "object"
        +}
      • addedOutput schema / properties / access_modes
        Added value: +{
        +  "items": {
        +    "type": "string"
        +  },
        +  "title": "Access Modes",
        +  "type": "array"
        +}
      • addedOutput schema / properties / croissant
        Added value: +{
        +  "anyOf": [
        +    {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Croissant"
        +}
      • addedOutput schema / properties / is_latest
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "boolean"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Is Latest"
        +}
      • addedOutput schema / properties / last_updated
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Last Updated"
        +}
      • addedOutput schema / properties / metrics
        Added value: +{
        +  "anyOf": [
        +    {
        +      "$ref": "#/$defs/Metrics"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null
        +}
      • addedOutput schema / properties / ro_crate
        Added value: +{
        +  "anyOf": [
        +    {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Ro Crate"
        +}
      • addedOutput schema / properties / superseded_by
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Superseded By"
        +}
    • Changedsearch9 fields changed
      • changedInput schema / properties / sources / description
        Previous value: -"Restrict fan-out to these sources (default: all). Available: zenodo, datacite, omics, literature, huggingface"New value: +"Restrict fan-out to these sources (default: all). Available: zenodo, datacite, omics, literature, huggingface, dataone, omicsdi"
      • addedOutput schema / $defs / DataResource / properties / access_modes
        Added value: +{
        +  "items": {
        +    "type": "string"
        +  },
        +  "title": "Access Modes",
        +  "type": "array"
        +}
      • addedOutput schema / $defs / DataResource / properties / croissant
        Added value: +{
        +  "anyOf": [
        +    {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Croissant"
        +}
      • addedOutput schema / $defs / DataResource / properties / is_latest
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "boolean"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Is Latest"
        +}
      • addedOutput schema / $defs / DataResource / properties / last_updated
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Last Updated"
        +}
      • addedOutput schema / $defs / DataResource / properties / metrics
        Added value: +{
        +  "anyOf": [
        +    {
        +      "$ref": "#/$defs/Metrics"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null
        +}
      • addedOutput schema / $defs / DataResource / properties / ro_crate
        Added value: +{
        +  "anyOf": [
        +    {
        +      "additionalProperties": true,
        +      "type": "object"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Ro Crate"
        +}
      • addedOutput schema / $defs / DataResource / properties / superseded_by
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Superseded By"
        +}
      • addedOutput schema / $defs / Metrics
        Added value: +{
        +  "description": "Usage/impact signals, each a separate axis — NO blended score. All\nnullable: a source that does not expose an axis leaves it None.",
        +  "properties": {
        +    "citations": {
        +      "anyOf": [
        +        {
        +          "type": "integer"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "default": null,
        +      "title": "Citations"
        +    },
        +    "downloads": {
        +      "anyOf": [
        +        {
        +          "type": "integer"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "default": null,
        +      "title": "Downloads"
        +    },
        +    "likes": {
        +      "anyOf": [
        +        {
        +          "type": "integer"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "default": null,
        +      "title": "Likes"
        +    },
        +    "views": {
        +      "anyOf": [
        +        {
        +          "type": "integer"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "default": null,
        +      "title": "Views"
        +    }
        +  },
        +  "title": "Metrics",
        +  "type": "object"
        +}
  15. 4 tool updatesv0.16.0
    • Changedfetch1 field changed
      • addedOutput schema / properties / resumed
        Added value: +{
        +  "items": {
        +    "type": "string"
        +  },
        +  "title": "Resumed",
        +  "type": "array"
        +}
    • Changedlist_sources1 field changed
      • addedInput schema / properties / check_health
        Added value: +{
        +  "default": false,
        +  "description": "When true, probe each source's base endpoint and attach a 'health' field ({status: up|down, latency_ms, detail}) to each source. Default false: returns the static catalog with no network.",
        +  "type": "boolean"
        +}
    • Changedresolve5 fields changed
      • addedOutput schema / $defs / Creator
        Added value: +{
        +  "properties": {
        +    "name": {
        +      "title": "Name",
        +      "type": "string"
        +    },
        +    "orcid": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "default": null,
        +      "title": "Orcid"
        +    }
        +  },
        +  "required": [
        +    "name"
        +  ],
        +  "title": "Creator",
        +  "type": "object"
        +}
      • addedOutput schema / $defs / FundingRef
        Added value: +{
        +  "properties": {
        +    "award": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "default": null,
        +      "title": "Award"
        +    },
        +    "funder": {
        +      "title": "Funder",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "funder"
        +  ],
        +  "title": "FundingRef",
        +  "type": "object"
        +}
      • addedOutput schema / properties / creators / items / $ref
        Added value: +"#/$defs/Creator"
      • removedOutput schema / properties / creators / items / type
        Removed value: -"string"
      • addedOutput schema / properties / funding
        Added value: +{
        +  "items": {
        +    "$ref": "#/$defs/FundingRef"
        +  },
        +  "title": "Funding",
        +  "type": "array"
        +}
    • Changedsearch12 fields changed
      • addedInput schema / properties / cursor
        Added value: +{
        +  "description": "Opaque pagination token from a prior search's next_cursor. When set, all other search params are read from the cursor.",
        +  "type": "string"
        +}
      • addedInput schema / properties / kind
        Added value: +{
        +  "description": "Keep only results of this kind.",
        +  "enum": [
        +    "dataset",
        +    "sequencing_run",
        +    "study",
        +    "publication",
        +    "software"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / published_after
        Added value: +{
        +  "description": "Keep results with year >= this.",
        +  "type": "integer"
        +}
      • addedInput schema / properties / published_before
        Added value: +{
        +  "description": "Keep results with year <= this.",
        +  "type": "integer"
        +}
      • addedInput schema / properties / rank
        Added value: +{
        +  "default": "relevance",
        +  "description": "Result ordering. 'relevance' (default) = upstream/merged order. 'semantic' re-ranks the fetched page by embedding similarity to the query (needs EMBEDDING_API_BASE; degrades to relevance order with an errors['semantic'] note if unconfigured). In semantic mode pagination is window-based (each page consumes its full fetched window).",
        +  "enum": [
        +    "relevance",
        +    "semantic"
        +  ],
        +  "type": "string"
        +}
      • changedInput schema / properties / sources / description
        Previous value: -"Restrict fan-out to these sources (default: all). Available: zenodo, datacite, omics, literature"New value: +"Restrict fan-out to these sources (default: all). Available: zenodo, datacite, omics, literature, huggingface"
      • removedInput schema / required
        Removed value: -[
        -  "query"
        -]
      • addedOutput schema / $defs / Creator
        Added value: +{
        +  "properties": {
        +    "name": {
        +      "title": "Name",
        +      "type": "string"
        +    },
        +    "orcid": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "default": null,
        +      "title": "Orcid"
        +    }
        +  },
        +  "required": [
        +    "name"
        +  ],
        +  "title": "Creator",
        +  "type": "object"
        +}
      • addedOutput schema / $defs / DataResource / properties / creators / items / $ref
        Added value: +"#/$defs/Creator"
      • removedOutput schema / $defs / DataResource / properties / creators / items / type
        Removed value: -"string"
      • addedOutput schema / $defs / DataResource / properties / funding
        Added value: +{
        +  "items": {
        +    "$ref": "#/$defs/FundingRef"
        +  },
        +  "title": "Funding",
        +  "type": "array"
        +}
      • addedOutput schema / $defs / FundingRef
        Added value: +{
        +  "properties": {
        +    "award": {
        +      "anyOf": [
        +        {
        +          "type": "string"
        +        },
        +        {
        +          "type": "null"
        +        }
        +      ],
        +      "default": null,
        +      "title": "Award"
        +    },
        +    "funder": {
        +      "title": "Funder",
        +      "type": "string"
        +    }
        +  },
        +  "required": [
        +    "funder"
        +  ],
        +  "title": "FundingRef",
        +  "type": "object"
        +}

TDQS

A4.4/5.0

Scored across 6 tools

Disambiguation5/5

Each tool has a distinct role: search discovers resources, resolve expands a known id, fetch downloads files, list_sources introspects coverage, operate analyzes remote tabular files without downloading, and relate compares resource ids. The adjacent file-related operations (resolve/fetch/operate) are explicitly scoped by description, so an agent can tell them apart.

Naming Consistency4/5

Five tools are bare lowercase verbs (search, resolve, fetch, operate, relate) and one is a snake_case verb_noun (list_sources), so the pattern is not perfectly uniform. It remains predictable and readable, with no chaotic mixing of camelCase or vague synonym pileups.

Tool Count5/5

Six tools is well-scoped for a read-only multi-archive research-data aggregator, and each tool covers a distinct workflow stage rather than duplicating another. The surface is neither thin nor bloated, and no obvious filler tool is present.

Completeness5/5

The set covers discovery, detailed record resolution, file download, source capability introspection, remote tabular inspection, and cross-resource relation hints, which is strong lifecycle coverage for this domain. Write/update operations are not expected for a read-only aggregation server, and remaining gaps look like minor conveniences rather than dead ends.

Maintenance

ActivityActive
ResponsivenessSlow

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    A
    maintenance
    Enables searching and downloading academic papers from 14 platforms including arXiv, PubMed, Google Scholar, Web of Science, Springer, and Sci-Hub with unified data format and intelligent rate limiting.
    21
    208 npm
    190
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    ▎ Provides 32 tools for plant-genomics locus lookup across 11 free public backends (Ensembl Plants, Phytozome, UniProtKB, Europe PMC, QuickGO, NCBI BLAST, Gramene, KEGG, STRING-DB, ATTED-II, BAR). Takes a TAIR-style locus plus optional organism and returns gene metadata, functional/pathway annotation, interactions, co-expression, and literature — in single-locus, batch, and cross-source synthesis.
    58
    240 PyPI
    8
    MIT
  • A
    license
    A
    quality
    C
    maintenance
    Enables users to search multiple public life-science data repositories (GEO, ENA, CELLxGENE, PRIDE, DataCite) with a single query, returning a unified ranked list of datasets with ontology-expanded terms and per-source error reporting.
    3
    MIT