data-aggregator-mcp
A single MCP server that searches 21 public research-data sources at once, returns one deduplicated list, and can then resolve, download, query and cross-relate the results.
search — fans out over 21 sources (Zenodo, DataCite, GEO/SRA/BioProject, PubMed/OpenAIRE, HuggingFace, OpenML, PDB, UniProt, GBIF, data.gov, Kaggle, and more), dedupes by DOI (optionally collapse mirrors), filters by kind and year, expands queries via NCBI Taxonomy, MeSH, UBERON, ChEBI and EDAM synonyms, and supports semantic ranking, LLM query understanding, multi-query recall expansion and an optional RO-Crate provenance manifest.
resolve — fetches the full record and complete file manifest for an id or DOI, and can attach a rendered citation (BibTeX/RIS/CSL), a Crossref retraction check, an RDA-grounded FAIR score, a licence-compatibility verdict (ALLOW/REVIEW/DENY), or a one-call provenance dossier / Croissant / RO-Crate export.
fetch — downloads a record's files to local disk (path, not contents), verifying md5/SHA-256 where the source publishes one, with a byte ceiling, archive extraction and a sidecar manifest.
operate — inspects or runs read-only SQL over a remote Parquet/CSV/TSV file without downloading it (schema, preview, head, sql, peek profiling).
relate — reports metadata-level join/harmonization hints across 2–10 resource ids (shared accessions, DOIs, explicit links, version lineage).
list_sources — lists wired sources with their layers, kinds, supported filters, auth and rate limits, plus an optional health probe.
Integrates with Figshare via DataCite for discovering and downloading research outputs, including md5 checksum verification.
Provides discovery of Mendeley records through DataCite integration, though fetching is not supported.
Supports search and file retrieval from OSF via DataCite, with md5 verification on downloads.
Enables searching PubMed articles and resolving them to open-access full text, with citation and cross-links to related data.
Enables searching for datasets and files on Zenodo, with support for fetching and checksum verification.
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.
Does it help?
Not shown yet: there has been one small held-out round (5 tasks, 2 runs each, Claude Sonnet 5.5), and on it this server is not separated from web search. Its mean recall was higher than web search's on 4 of 5 tasks (sign test p = 0.38):
Tools given to the agent | Mean recall |
this server | 0.49 |
web search | 0.35 |
ToolUniverse | 0.26 |
It made fewer tool calls than web search (7.7 fewer per run, 95% CI 1.8 to 13.1) and ToolUniverse; cost and wall time against web search are not separated. Method and controls: benchmarks/h2h.
Related MCP server: plant-genomics-mcp
Install
Claude Code:
claude mcp add data-aggregator -- uvx data-aggregator-mcpOne-click install for VS Code or 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_mcpoperate (SQL and previews over remote files) needs an optional extra:
pip install "data-aggregator-mcp[operate]".
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.
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 |
20 general and ML data platforms | yes | — | row preview | yes | |
papers: arXiv, PubMed, OpenAlex, Crossref and more | yes, deduplicated | — | — | — | |
1000+ tools: models, datasets, APIs, packages | papers | — | — | — | |
genes, variants, trials, drugs, proteins, papers | yes ( | — | — | — |
— 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 toolsfetchA
Download a resource's files to local disk and return the PATHS (never the file contents). 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.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Source-prefixed id or bare Zenodo id | |
| dest | No | Destination dir (default managed cache) | |
| files | No | Glob over file names (default all) | |
| force | No | Override max_bytes | |
| extract | No | Unpack downloaded zip/tar archives into the destination (default false). Path-traversal-guarded; counts against max_bytes. | |
| max_bytes | No | Byte ceiling before failing loud |
Output Schema
| Name | Required | Description |
|---|---|---|
| bytes | No | |
| paths | No | |
| resumed | No | |
| skipped | No | |
| unverified | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations: per-source md5/SHA-256 verification vs unverified status, the fail-loud behavior on max_bytes (unless force), the path-traversal-guarded extract behavior, and the .dataresource.json sidecar write. With readOnlyHint=false and idempotentHint=false declared, this explains the mutation profile in depth.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core purpose and mutation semantics are front-loaded in the first two sentences, and the backend enumeration is information-dense rather than filler. The long run-on source list is harder to scan than a structured list would be, costing a point.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be described, and the description covers every remaining agent-relevant concern: supported sources, integrity verification, failure modes, sidecar output, and archive extraction. Nothing needed to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real meaning: force is framed as overriding max_bytes specifically, extract 'counts against max_bytes', and the return contract (paths, not contents) contextualizes id/files/dest. It stops short of clarifying dest-vs-files interaction.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource+output contract: 'Download a resource's files to local disk and return the PATHS (never the file contents).' That single clause tells an agent exactly what it gets back and distinguishes it from a contents-returning read.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives detailed context on which backends are fetchable and which 'fail loud', and explicitly routes listing to the sibling ('Dryad is manifest-only (resolve lists files, fetch fails loud)'). It does not, however, state a general when-to-use-fetch vs search/operate condition.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_sourcesARead-only
List wired data sources and their capabilities (layer, kinds, supported filters, auth requirement, rate limit, status). 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.
| Name | Required | Description | Default |
|---|---|---|---|
| check_health | No | 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
| sources | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint=true, and the description adds real behavioral context beyond that: which filter values are applied upstream by a source versus 'after fetch', and that some sources have auth and rate-limit constraints. It stops short of describing the tool's own failure modes or cost of the network probe, which the schema covers instead.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose is front-loaded in a short first sentence; the second sentence is dense but every clause (cursor, date/kind, synonym-expansion filters) earns its place by defining a returned field's values. The semicolon-chained list is slightly run-on but not wasteful.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present and the single parameter fully documented in the schema, the description supplies what structured fields cannot: the semantics of filters_supported values. Nothing an agent needs to call this correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There is one parameter and schema description coverage is 100%, so the schema already fully documents check_health, including which five sources are probed and the health field shape. The description adds nothing about it, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('List wired data sources') and enumerates exactly what each entry carries (layer, kinds, filters, auth requirement, rate limit, status). No sibling tool (search/operate/resolve/fetch/relate) overlaps with enumerating sources, so the scope is unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: an agent can infer this is the discovery step before querying, but the description never says when to call it versus running a search directly, nor when to re-list. The filters_supported explanation helps interpret results but is not a when-to-use instruction.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
operateARead-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). 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.
| Name | Required | Description | Default |
|---|---|---|---|
| n | No | Row count for head/preview | |
| id | Yes | DataResource id (e.g. 'zenodo:1254563') | |
| op | Yes | ||
| file | No | File name within the record; optional when exactly one operable file is present. | |
| query | No | Read-only SELECT for op='sql'. | |
| columns | No | Optional column projection for head. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation it discloses non-obvious behavior: head/sql/peek read the whole file despite 'no download', the read is bounded by a source-size ceiling, the tool requires the [operate] extra, and it 'fails loud' when the file isn't an operable tabular file. Access mode and file-resolution constraints are also called out, which an agent could not infer from annotations alone.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core capability and constraint in the first sentence, then organized op-by-op. Dense and mostly waste-free, though the 'peek' sentence is long enough to be slightly heavy relative to the rest.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by describing what each op returns (columns+types, sample, first n rows, SELECT result, per-column profile). Only the 'sql' return shape and pagination/row limits for head beyond 'n' remain unspecified, which is minor.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 83%, so the baseline is 3, but the description meaningfully extends it by defining every 'op' enum value, naming the SQL view 'data' with an example query, and explaining how 'id' and 'file' combine to address a file. It adds little for 'n' and 'columns', which the schema already covers.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence names the specific action and resource ('Inspect or query a remote tabular file (Parquet/CSV/TSV)') plus the key differentiator ('WITHOUT downloading it'), and the op-by-op enumeration makes every mode's purpose explicit. An agent can distinguish this from fetch/search/resolve 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.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Each op is scoped ('schema' returns columns+types, 'head' the first n rows, 'peek' profiles every column), and the description supplies a prerequisite workflow: 'resolve the id first to see files[] and access_modes'. It does not explicitly name a sibling alternative (e.g. use fetch when you need the bytes), so it stops short of 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
relateARead-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. 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.
| Name | Required | Description | Default |
|---|---|---|---|
| ids | Yes | 2-10 source-prefixed resource ids to relate. |
Output Schema
| Name | Required | Description |
|---|---|---|
| note | No | |
| hints | No | |
| errors | No | |
| resolved | Yes | |
| input_ids | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond readOnlyHint=true by disclosing that output is hints only, that no file columns are read or files fetched, that each hint cites the shared value as evidence, and that per-id resolve failures are reported rather than fatal. These are exactly the behavioral traits an agent needs to set expectations for a non-authoritative, non-mutating analysis call.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core action and return type, then constraints and failure behavior in descending priority. Dense but almost every clause carries distinct information; the enumeration of detection categories is slightly listy but justified by the tool's discovery purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return-format explanation is unnecessary, and the description still covers scope boundaries, prerequisites, evidence semantics, and partial-failure behavior. Nothing an agent needs to call this correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the description restates the same facts (2-10 ids, source-prefixed) without adding syntax or format guidance beyond the schema. With a single fully documented parameter, this is the expected baseline rather than added value.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names a specific verb (relate) and resource (2-10 resource ids) and states precisely what is returned: metadata-level join/harmonization hints, with enumerated detection categories (shared accessions, cross-identifiers, explicit links, version lineage). It is clearly distinguishable from resolve/search/fetch because it explicitly says it does not read columns, fetch files, or execute joins.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit prerequisite ('Resolve ids first if you only have a search result') and a clear when-not-to-use boundary (it does not execute joins/merges, so it is not a substitute for an operate-style action). It does not, however, name the sibling tool an agent should reach for when it actually wants to execute a join, leaving that routing implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
resolveARead-only
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.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Source-prefixed id, bare Zenodo id, or DOI | |
| use | No | 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. | |
| cite | No | Optional 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). | |
| fair | No | 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). | |
| trust | No | 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). | |
| format | No | 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). |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | |
| doi | No | |
| fair | No | |
| kind | Yes | |
| taxa | No | |
| year | No | |
| files | No | |
| links | No | |
| title | Yes | |
| trust | No | |
| access | No | |
| errors | No | |
| source | Yes | |
| funding | No | |
| license | No | |
| methods | No | |
| metrics | No | |
| mirrors | No | |
| citation | No | |
| creators | No | |
| organism | No | |
| ro_crate | No | |
| subjects | No | |
| croissant | No | |
| is_latest | No | |
| truncated | No | |
| accessions | No | |
| provenance | No | |
| description | No | |
| identifiers | No | |
| access_modes | No | |
| last_updated | No | |
| superseded_by | No | |
| unshown_terms | No | |
| license_compat | No | |
| ranked_by_copy | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With readOnlyHint already set, the description still adds substantial behavior: citation failures degrade quietly to null, unresolved retraction returns null (never a false clean claim), unrecognized licences yield REVIEW instead of a fabricated verdict, and FAIR scoring is pure/local with no network call. It also discloses the cross-parameter coupling where format=provenance auto-attaches fair and trust.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core purpose is front-loaded in the first sentence, which is good. However the body is a dense, repetitive chain of 'Pass X=... to attach...' sentences that mirrors the schema descriptions almost verbatim, so much of the length does not earn its place beyond structured fields.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, and the description still covers each conditional attachment and the composite provenance mode well. Complete enough for a six-parameter, composable tool with one required parameter.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the five optional parameters are already documented in the schema; the description largely restates that same content and adds little net semantic value. Baseline 3 applies when the schema carries the parameter burden.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource — 'Fetch the full DataResource for a known id' — and enumerates the accepted id forms and the files[] manifest it returns. It does not explicitly distinguish itself from the sibling 'fetch' or 'search' tools, which is the only gap.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'known id' framing gives clear context: this is the tool for when you already hold an identifier, as opposed to discovery via search. It never names an alternative or states a when-not condition, so it stops short of explicit routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
searchARead-only
Search public research-data archives, omics registries, and the literature for datasets, software, publications, and sequencing data. Fans out across Zenodo, DataCite (Dryad, Figshare, Dataverse, OSF, Mendeley, OpenNeuro), NCBI omics (GEO, SRA, BioProject), literature (PubMed + OpenAIRE), HuggingFace Hub (datasets), DataONE (eco/environmental federation), OmicsDI (proteomics/metabolomics), RCSB PDB (macromolecular structures), GWAS Catalog (genotype-phenotype studies), OpenML (ML datasets), DANDI (neurophysiology dandisets), CZ CELLxGENE (single-cell datasets), GBIF (biodiversity datasets), data.gov (US government open data), NASA CMR (Earth-science collections), UniProt (protein entries), BioStudies (EMBL-EBI study records), NGDC (BioProjects deposited in China, with their GSA read sets), the Metabolomics Workbench (metabolomics studies), MassIVE (mass-spectrometry datasets: GNPS metabolomics, proteomics), and Kaggle (machine-learning datasets, many with no DOI). DataCite, OmicsDI, NCBI omics, CELLxGENE, the Metabolomics Workbench, MassIVE and Kaggle match only records holding every query word: errors.all_words names one that matched none, and a hit of theirs lists in unshown_terms the query words it matched in text the hit leaves out, such as a protocol, which resolve shows. DataCite, OmicsDI, CELLxGENE, the Workbench and MassIVE are also searched for records holding only some of the words, ranked below hits naming more; keep queries to NCBI omics and Kaggle short. Returns compact DataResource records (fields with no value left out; long lists cut to their first few, named in truncated{}); a page holds what fits in one tool result, so it can return fewer than size hits, with errors.page_size saying so and next_cursor continuing; errors.next_page counts hits already fetched that name every query word and come on the next page, so to find every match, page while it is there; per-source failures are reported in errors{}. Use resolve for the full record (SRA resolve attaches the ENA FASTQ manifest; publication resolve attaches links[] to datasets/accessions, normalized identifiers (pmid/pmcid/doi), and — when open access — a full-text file), then fetch to download files. Pass organism= to expand the query with NCBI-Taxonomy synonyms; results carry normalized taxa[] + plant cross-links. Pass disease= to expand the query with MeSH descriptor synonyms (e.g. 'breast cancer' also matches 'Breast Neoplasms'); the expansion is echoed in mesh_expansion. Pass tissue= to expand the query with UBERON synonyms (e.g. 'liver' also matches 'iecur'/'jecur'); the expansion is echoed in tissue_expansion. Pass chemical= to expand the query with ChEBI compound synonyms (e.g. 'caffeine' also matches '1,3,7-trimethylxanthine'); the expansion is echoed in chemical_expansion. Pass assay= to expand the query with EDAM assay/method synonyms (e.g. 'ChIP-seq' also matches 'ChIP-sequencing'); echoed in assay_expansion. Pass collapse_mirrors=true to opt into conservative cross-repo mirror collapse: same-dataset copies under different/no DOIs are folded into one record, with the folded copies annotated under mirrors[]. An ontology param that matches no term in its registry (e.g. organism='yeast' — NCBI Taxonomy indexes no such common name) is reported in unresolved[] and the search runs WITHOUT that expansion, so a dropped filter is never silent. Clients that support form elicitation are asked for a replacement term before the search runs.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | No | Keep only results of this kind. | |
| rank | No | 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). | relevance |
| size | No | Max results (1-50, default 10) | |
| assay | No | 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. | |
| query | No | Free-text search query | |
| cursor | No | Opaque pagination token from a prior search's next_cursor. When set, all other search params are read from the cursor. | |
| tissue | No | 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. | |
| disease | No | 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. | |
| sources | No | 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 | |
| chemical | No | 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. | |
| organism | No | 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. | |
| provenance | No | 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). | |
| understand | No | 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']. | |
| multi_query | No | 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. | |
| published_after | No | Keep results with year >= this. | |
| collapse_mirrors | No | 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. | |
| published_before | No | Keep results with year <= this. |
Output Schema
| Name | Required | Description |
|---|---|---|
| count | Yes | |
| query | Yes | |
| total | Yes | |
| errors | No | |
| results | No | |
| unresolved | No | |
| next_cursor | No | |
| mesh_expansion | No | |
| assay_expansion | No | |
| query_expansion | No | |
| taxon_expansion | No | |
| provenance_crate | No | |
| tissue_expansion | No | |
| chemical_expansion | No | |
| query_understanding | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnlyHint, so the description carries most of the burden and does so richly: per-source failures in errors{}, partial pages with errors.page_size and next_cursor semantics, per-source all-words vs some-words matching, silent-drop protection via unresolved[], and degradation notes for semantic/understand/multi_query when endpoints are unconfigured.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose is front-loaded, but the bulk is one enormous run-on paragraph that repeats ontology-expansion behavior already fully documented in the schema for organism, disease, tissue, chemical, and assay. Substantial compression is possible without losing callable information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 17-parameter fan-out search with an output schema and readOnly annotation, nothing an agent needs is missing: pagination, per-source failures, truncation, mirror collapsing, and LLM-dependent modes are all disclosed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 100% and the parameter descriptions are detailed, so the description is largely redundant on ontology params. It still adds value the schema lacks: the advice to keep NCBI/Kaggle queries short, the interaction between cursor and other params, and the note that rank= has no effect under multi_query.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb and resource ('Search public research-data archives, omics registries, and the literature') and enumerates the record kinds returned. It is unambiguous versus the siblings, and explicitly routes onward to resolve and fetch for full records and downloads.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Names the alternatives directly: 'Use resolve for the full record ... then fetch to download files.' It also gives conditional guidance for parameters (leave sources unset unless the user names archives; 'keep queries to NCBI omics and Kaggle short'; use collapse_mirrors only to opt into folding).
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.
2 tool updates
v0.75.3- Changed
operate1 field changed- changed
Input schema / properties / id / descriptionPrevious value: -"DataResource id (e.g. 'zenodo:7654321')"New value: +"DataResource id (e.g. 'zenodo:1254563')"
- Changed
search1 field changed- changed
Input schema / properties / sources / descriptionPrevious 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 tool updates
v0.74.0- Changed
resolve1 field changed- added
Output schema / properties / ranked_by_copyAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Ranked By Copy" +}
- Changed
search3 fields changed- changed
Input schema / properties / rank / descriptionPrevious 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)." - changed
Input schema / properties / sources / descriptionPrevious 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" - added
Output schema / $defs / DataResource / properties / ranked_by_copyAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Ranked By Copy" +}
2 tool updates
v0.71.0- Changed
resolve2 fields changed- added
Output schema / properties / methodsAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Methods" +} - added
Output schema / properties / unshown_termsAdded value: +{ + "items": { + "type": "string" + }, + "title": "Unshown Terms", + "type": "array" +}
- Changed
search4 fields changed- changed
Input schema / properties / rank / descriptionPrevious 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)." - changed
Input schema / properties / sources / descriptionPrevious 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" - added
Output schema / $defs / DataResource / properties / methodsAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Methods" +} - added
Output schema / $defs / DataResource / properties / unshown_termsAdded value: +{ + "items": { + "type": "string" + }, + "title": "Unshown Terms", + "type": "array" +}
1 tool update
v0.61.0- Changed
search10 fields changed- changed
Input schema / properties / chemical / descriptionPrevious 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." - changed
Input schema / properties / collapse_mirrors / descriptionPrevious 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." - changed
Input schema / properties / organism / descriptionPrevious 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." - changed
Input schema / properties / rank / descriptionPrevious 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)." - changed
Input schema / properties / tissue / descriptionPrevious 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." - added
Output schema / $defs / ChemicalExpansion / properties / alternativesAdded value: +{ + "items": { + "$ref": "#/$defs/TermAlternative" + }, + "title": "Alternatives", + "type": "array" +} - added
Output schema / $defs / TaxonAlternativeAdded 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" +} - added
Output schema / $defs / TaxonExpansion / properties / alternativesAdded value: +{ + "items": { + "$ref": "#/$defs/TaxonAlternative" + }, + "title": "Alternatives", + "type": "array" +} - added
Output schema / $defs / TermAlternativeAdded 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" +} - added
Output schema / $defs / TissueExpansion / properties / alternativesAdded value: +{ + "items": { + "$ref": "#/$defs/TermAlternative" + }, + "title": "Alternatives", + "type": "array" +}
1 tool update
v0.54.14- Changed
search1 field changed- changed
Input schema / properties / collapse_mirrors / descriptionPrevious 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 tool updates
v0.54.1- Changed
fetch1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
list_sources1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
operate1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
relate1 field changed- added
Input schema / additionalPropertiesAdded value: +false
- Changed
resolve3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Output schema / properties / errorsAdded value: +{ + "additionalProperties": { + "type": "string" + }, + "title": "Errors", + "type": "object" +} - added
Output schema / properties / truncatedAdded value: +{ + "additionalProperties": { + "type": "string" + }, + "title": "Truncated", + "type": "object" +}
- Changed
search3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Output schema / $defs / DataResource / properties / errorsAdded value: +{ + "additionalProperties": { + "type": "string" + }, + "title": "Errors", + "type": "object" +} - added
Output schema / $defs / DataResource / properties / truncatedAdded value: +{ + "additionalProperties": { + "type": "string" + }, + "title": "Truncated", + "type": "object" +}
1 tool update
v0.46.0- Changed
operate1 field changed- added
Input schema / properties / n / minimumAdded value: +1
1 tool update
v0.45.3- Changed
fetch1 field changed- added
Output schema / properties / unverifiedAdded value: +{ + "items": { + "type": "string" + }, + "title": "Unverified", + "type": "array" +}
2 tool updates
v0.45.1- Added
resolve - Added
search
3 tool updates
v0.43.0- Added
relate - Removed
resolve - Removed
search
3 tool updates
v0.42.0- Changed
list_sources1 field changed- changed
Input schema / properties / check_health / descriptionPrevious 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."
- Removed
relate - Changed
search4 fields changed- changed
Input schema / properties / sources / descriptionPrevious 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" - added
Output schema / $defs / QueryUnderstanding / properties / confidenceAdded value: +{ + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Confidence" +} - added
Output schema / $defs / UnresolvedEntityAdded 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" +} - added
Output schema / properties / unresolvedAdded value: +{ + "items": { + "$ref": "#/$defs/UnresolvedEntity" + }, + "title": "Unresolved", + "type": "array" +}
1 tool update
v0.41.1- Changed
search1 field changed- changed
Input schema / properties / sources / descriptionPrevious 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"
5 tool updates
v0.40.0- Changed
list_sources1 field changed- changed
Input schema / properties / check_health / descriptionPrevious 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."
- Changed
operate1 field changed- changed
Input schema / properties / op / enumPrevious value: -[ - "schema", - "preview", - "head", - "sql" -]New value: +[ + "schema", + "preview", + "head", + "sql", + "peek" +]
- Added
relate - Changed
resolve14 fields changed- added
Input schema / properties / fairAdded 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" +} - changed
Input schema / properties / format / descriptionPrevious 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)." - changed
Input schema / properties / format / enumPrevious value: -[ - "croissant", - "ro-crate" -]New value: +[ + "croissant", + "ro-crate", + "provenance" +] - added
Input schema / properties / trustAdded 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" +} - added
Input schema / properties / useAdded 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" +} - added
Output schema / $defs / FairAssessmentAdded 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" +} - added
Output schema / $defs / LicenseVerdictAdded 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" +} - added
Output schema / $defs / MirrorAdded 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" +} - added
Output schema / $defs / TrustSignalsAdded 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" +} - added
Output schema / properties / fairAdded value: +{ + "anyOf": [ + { + "$ref": "#/$defs/FairAssessment" + }, + { + "type": "null" + } + ], + "default": null +} - added
Output schema / properties / license_compatAdded value: +{ + "anyOf": [ + { + "$ref": "#/$defs/LicenseVerdict" + }, + { + "type": "null" + } + ], + "default": null +} - added
Output schema / properties / mirrorsAdded value: +{ + "items": { + "$ref": "#/$defs/Mirror" + }, + "title": "Mirrors", + "type": "array" +} - added
Output schema / properties / provenanceAdded value: +{ + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Provenance" +} - added
Output schema / properties / trustAdded value: +{ + "anyOf": [ + { + "$ref": "#/$defs/TrustSignals" + }, + { + "type": "null" + } + ], + "default": null +}
- Changed
search31 fields changed- added
Input schema / properties / assayAdded 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" +} - added
Input schema / properties / chemicalAdded 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" +} - added
Input schema / properties / collapse_mirrorsAdded 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" +} - added
Input schema / properties / diseaseAdded 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" +} - added
Input schema / properties / multi_queryAdded 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" +} - added
Input schema / properties / provenanceAdded 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" +} - changed
Input schema / properties / sources / descriptionPrevious 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" - added
Input schema / properties / tissueAdded 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" +} - added
Input schema / properties / understandAdded 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" +} - added
Output schema / $defs / AssayExpansionAdded 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" +} - added
Output schema / $defs / ChemicalExpansionAdded 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" +} - added
Output schema / $defs / DataResource / properties / fairAdded value: +{ + "anyOf": [ + { + "$ref": "#/$defs/FairAssessment" + }, + { + "type": "null" + } + ], + "default": null +} - added
Output schema / $defs / DataResource / properties / license_compatAdded value: +{ + "anyOf": [ + { + "$ref": "#/$defs/LicenseVerdict" + }, + { + "type": "null" + } + ], + "default": null +} - added
Output schema / $defs / DataResource / properties / mirrorsAdded value: +{ + "items": { + "$ref": "#/$defs/Mirror" + }, + "title": "Mirrors", + "type": "array" +} - added
Output schema / $defs / DataResource / properties / provenanceAdded value: +{ + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Provenance" +} - added
Output schema / $defs / DataResource / properties / trustAdded value: +{ + "anyOf": [ + { + "$ref": "#/$defs/TrustSignals" + }, + { + "type": "null" + } + ], + "default": null +} - added
Output schema / $defs / FairAssessmentAdded 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" +} - added
Output schema / $defs / LicenseVerdictAdded 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" +} - added
Output schema / $defs / MeshExpansionAdded 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" +} - added
Output schema / $defs / MirrorAdded 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" +} - added
Output schema / $defs / QueryExpansionAdded 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" +} - added
Output schema / $defs / QueryUnderstandingAdded 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" +} - added
Output schema / $defs / TissueExpansionAdded 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" +} - added
Output schema / $defs / TrustSignalsAdded 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" +} - added
Output schema / properties / assay_expansionAdded value: +{ + "anyOf": [ + { + "$ref": "#/$defs/AssayExpansion" + }, + { + "type": "null" + } + ], + "default": null +} - added
Output schema / properties / chemical_expansionAdded value: +{ + "anyOf": [ + { + "$ref": "#/$defs/ChemicalExpansion" + }, + { + "type": "null" + } + ], + "default": null +} - added
Output schema / properties / mesh_expansionAdded value: +{ + "anyOf": [ + { + "$ref": "#/$defs/MeshExpansion" + }, + { + "type": "null" + } + ], + "default": null +} - added
Output schema / properties / provenance_crateAdded value: +{ + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Provenance Crate" +} - added
Output schema / properties / query_expansionAdded value: +{ + "anyOf": [ + { + "$ref": "#/$defs/QueryExpansion" + }, + { + "type": "null" + } + ], + "default": null +} - added
Output schema / properties / query_understandingAdded value: +{ + "anyOf": [ + { + "$ref": "#/$defs/QueryUnderstanding" + }, + { + "type": "null" + } + ], + "default": null +} - added
Output schema / properties / tissue_expansionAdded value: +{ + "anyOf": [ + { + "$ref": "#/$defs/TissueExpansion" + }, + { + "type": "null" + } + ], + "default": null +}
3 tool updates
v0.20.0- Added
operate - Changed
resolve9 fields changed- added
Input schema / properties / formatAdded 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" +} - added
Output schema / $defs / MetricsAdded 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" +} - added
Output schema / properties / access_modesAdded value: +{ + "items": { + "type": "string" + }, + "title": "Access Modes", + "type": "array" +} - added
Output schema / properties / croissantAdded value: +{ + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Croissant" +} - added
Output schema / properties / is_latestAdded value: +{ + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Is Latest" +} - added
Output schema / properties / last_updatedAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Last Updated" +} - added
Output schema / properties / metricsAdded value: +{ + "anyOf": [ + { + "$ref": "#/$defs/Metrics" + }, + { + "type": "null" + } + ], + "default": null +} - added
Output schema / properties / ro_crateAdded value: +{ + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Ro Crate" +} - added
Output schema / properties / superseded_byAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Superseded By" +}
- Changed
search9 fields changed- changed
Input schema / properties / sources / descriptionPrevious 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" - added
Output schema / $defs / DataResource / properties / access_modesAdded value: +{ + "items": { + "type": "string" + }, + "title": "Access Modes", + "type": "array" +} - added
Output schema / $defs / DataResource / properties / croissantAdded value: +{ + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Croissant" +} - added
Output schema / $defs / DataResource / properties / is_latestAdded value: +{ + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Is Latest" +} - added
Output schema / $defs / DataResource / properties / last_updatedAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Last Updated" +} - added
Output schema / $defs / DataResource / properties / metricsAdded value: +{ + "anyOf": [ + { + "$ref": "#/$defs/Metrics" + }, + { + "type": "null" + } + ], + "default": null +} - added
Output schema / $defs / DataResource / properties / ro_crateAdded value: +{ + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Ro Crate" +} - added
Output schema / $defs / DataResource / properties / superseded_byAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Superseded By" +} - added
Output schema / $defs / MetricsAdded 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" +}
4 tool updates
v0.16.0- Changed
fetch1 field changed- added
Output schema / properties / resumedAdded value: +{ + "items": { + "type": "string" + }, + "title": "Resumed", + "type": "array" +}
- Changed
list_sources1 field changed- added
Input schema / properties / check_healthAdded 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" +}
- Changed
resolve5 fields changed- added
Output schema / $defs / CreatorAdded value: +{ + "properties": { + "name": { + "title": "Name", + "type": "string" + }, + "orcid": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Orcid" + } + }, + "required": [ + "name" + ], + "title": "Creator", + "type": "object" +} - added
Output schema / $defs / FundingRefAdded value: +{ + "properties": { + "award": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Award" + }, + "funder": { + "title": "Funder", + "type": "string" + } + }, + "required": [ + "funder" + ], + "title": "FundingRef", + "type": "object" +} - added
Output schema / properties / creators / items / $refAdded value: +"#/$defs/Creator" - removed
Output schema / properties / creators / items / typeRemoved value: -"string" - added
Output schema / properties / fundingAdded value: +{ + "items": { + "$ref": "#/$defs/FundingRef" + }, + "title": "Funding", + "type": "array" +}
- Changed
search12 fields changed- added
Input schema / properties / cursorAdded 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" +} - added
Input schema / properties / kindAdded value: +{ + "description": "Keep only results of this kind.", + "enum": [ + "dataset", + "sequencing_run", + "study", + "publication", + "software" + ], + "type": "string" +} - added
Input schema / properties / published_afterAdded value: +{ + "description": "Keep results with year >= this.", + "type": "integer" +} - added
Input schema / properties / published_beforeAdded value: +{ + "description": "Keep results with year <= this.", + "type": "integer" +} - added
Input schema / properties / rankAdded 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" +} - changed
Input schema / properties / sources / descriptionPrevious 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" - removed
Input schema / requiredRemoved value: -[ - "query" -] - added
Output schema / $defs / CreatorAdded value: +{ + "properties": { + "name": { + "title": "Name", + "type": "string" + }, + "orcid": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Orcid" + } + }, + "required": [ + "name" + ], + "title": "Creator", + "type": "object" +} - added
Output schema / $defs / DataResource / properties / creators / items / $refAdded value: +"#/$defs/Creator" - removed
Output schema / $defs / DataResource / properties / creators / items / typeRemoved value: -"string" - added
Output schema / $defs / DataResource / properties / fundingAdded value: +{ + "items": { + "$ref": "#/$defs/FundingRef" + }, + "title": "Funding", + "type": "array" +} - added
Output schema / $defs / FundingRefAdded value: +{ + "properties": { + "award": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Award" + }, + "funder": { + "title": "Funder", + "type": "string" + } + }, + "required": [ + "funder" + ], + "title": "FundingRef", + "type": "object" +}
4 tool updates
v0.11.0- First observed
fetch - First observed
list_sources - First observed
resolve - First observed
search
TDQS
Scored across 6 tools
Each tool targets a distinct phase of the data workflow: search finds, resolve expands a known id, operate queries remote tabular files without downloading, fetch writes files to disk, list_sources introspects capabilities, and relate proposes joins. The boundaries between operate (in-place query) and fetch (download) and between search (discovery) and resolve (known-id lookup) are clearly drawn in the descriptions.
Five tools are single snake_case verbs (search, resolve, operate, fetch, relate) and one is verb_noun (list_sources), a minor but readable deviation. No camelCase/snake_case mixing or synonym verbs like get/find/query for the same action.
Six tools is well-scoped for a federated data-aggregation server, covering discovery, expansion, remote query, download, source introspection, and cross-record linking. Each tool maps to a distinct, non-redundant capability with no filler.
The surface covers the full read-only lifecycle for a data-aggregation domain: find records (search), get full metadata/files (resolve), inspect tabular data (operate), download artifacts (fetch), understand coverage/limits (list_sources), and link datasets (relate). No obvious dead ends remain for a consumer of external archives.
Maintenance
Related MCP Connectors
Search DataCite datasets and software, fetch DOI metadata, trace relations, format citations.
arXiv, PubMed, Crossref and OpenAlex scholarly metadata.
Search and resolve Zenodo datasets, software, and publications by DOI; trace versions and funding.
Federated search of books and papers, BibTeX/RIS citations, open-access retrieval and reading.
Related MCP Servers
- AlicenseBqualityAmaintenanceEnables 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.211,036 npm187MIT
- AlicenseAqualityAmaintenance▎ 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.56455 PyPI8MIT
- AlicenseAqualityCmaintenanceEnables searching scholarly literature across CrossRef, ERIC, Semantic Scholar, and OpenAlex, and retrieving open-access PDFs via Unpaywall.9MIT
- AlicenseAqualityCmaintenanceEnables 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.3MIT