io.github.cyanheads/biorxiv-mcp-server
Measured conclusion: Deep-tested. L2 outcome: tools_ok.
Search and retrieve bioRxiv and medRxiv preprints — by DOI, date interval, or keyword — via MCP.
| Author | io.github.cyanheads |
|---|---|
| Access | mixed |
| Publisher key required | No |
| Measured state | Deep-tested |
| L1 liveness | alive |
| L1 latency | 507 ms |
| Last measured | 2026-10-26 |
Measured statistics
| Tools measured | 7 |
|---|---|
| Latency, 30-day median (L1) | 507 ms |
| Latency, latest (L1) | 507 ms |
| Safe-call success | 1/1 (100%) |
| 30-day success rate (L2) | 100% |
| Last checked | 2026-10-26 |
| Total checks | 4 |
Add to your agent
Copy this into your MCP client config:
{
"mcpServers": {
"biorxiv-mcp-server": {
"url": "https://biorxiv.caseyjhand.com/mcp",
"transport": "streamable-http"
}
}
}
Measured tools (7)
biorxiv_list_categoriesread-onlyList valid subject category strings for bioRxiv and medRxiv — the categories the listing API actually filters on. Use these strings as the `category` filter in biorxiv_list_recent to narrow results to a specific field; case, and "_" or "-" in place of a space, do not matter there. Run this tool before filtering to get the current valid values.
Hints: read-only yes · destructive not declared · idempotent yes · open-world no
biorxiv_list_recentread-onlyList preprints posted or revised within a date interval, optionally scoped to one server or a subject category. Returns 30 preprints per page (fixed by the API); pass `cursor` as an integer offset (0, 30, 60, …) to step through additional pages. Abstracts are omitted by default to keep the page small — pass include_abstract: true for the whole page (each row carries the latest-revision abstract of its preprint, whichever revision the row is), or call biorxiv_get_preprint (up to 10 DOIs per call) for a few. When server="both" (default), per-server pagination state is returned separately — use each server's `cursor` field for independent advancement. One server failing under server="both" does not abort the call: the other server's page is still returned and the failed one is named in `failed[]`, marking the result set as partial rather than complete. Every attempted server failing is a different case and does abort the call, with a retryable upstream_unavailable (or rate_limited) error — an empty page would otherwise be indistinguishable from an interval that genuinely holds nothing. Call biorxiv_list_categories for valid category strings; a server that answers a category filter with its unfiltered listing is left out with a notice, and invalid_category is raised when no server applied it. `funder` limits the listing to bioRxiv preprints funded by that organization, given its ROR ID; an ID api.biorxiv.org has no funder record for raises invalid_funder rather than returning an empty page.
Parameters:
start_date(required) — string — Start of the date interval (YYYY-MM-DD).end_date(required) — string — End of the date interval (YYYY-MM-DD).cursor— integer — Integer page offset (0, 30, 60, …). Defaults to 0 (first page).funder— string — Funder filter: the funder's ROR ID, bare ("021nxhr62" for the US National Science Foundation) or as a URL ("https://ror.org/021nxhr62"). bioRxiv only — medRxiv records carry no funder data, so server="both" queries bioRxiv alone and server="medrxiv" is rejected. Combines with category. Look the ID up by name at ror.org.server— string — Server to query. "both" fans out to bioRxiv and medRxiv in parallel.category— string — Subject category filter, matched case-insensitively with "_" and "-" read as a space — "Cell Biology", "cell biology", "cell_biology", and "cell-biology" are the same filter. Use biorxiv_list_categories for valid values.include_abstract— boolean — Include each preprint's abstract. Defaults to false: abstracts make up about three quarters of a page, and every other field is returned either way.
Hints: read-only yes · destructive not declared · idempotent not declared · open-world yes
biorxiv_get_preprintread-onlyFetch full metadata, the abstract, all revision history, JATS XML full-text links, and published-journal DOI for one or more preprints by DOI. Each DOI returns all revisions in one response, with the abstract on the latest revision only — the API keeps one abstract per preprint. Each call looks up the first 10 distinct DOIs and returns the rest, never looked up, in unprocessed[] — pass that list as dois in another call to continue; a repeated DOI is looked up once and an unparseable entry is reported in failed[], so neither counts toward the 10. When server="both" (default), each DOI is checked against both bioRxiv and medRxiv; the response includes which server the preprint was found on. Failed lookups are reported per-DOI in failed[] rather than aborting the batch, each carrying a reason (not_found, invalid_doi_format, upstream_unavailable, rate_limited) and a retryable flag; a rate_limited entry also carries the wait in seconds the origin asked for. preprints[], failed[], and unprocessed[] follow input order. DOIs must match the pattern 10.NNNN/…; a doi.org or article URL, a doi: label, and a trailing vN / .full suffix are stripped first, and results report the bare DOI.
Parameters:
dois(required) — array — Preprint DOIs to look up, up to 200 entries. The first 10 distinct DOIs are looked up; the rest are returned in unprocessed.server— string — Server to query. "both" checks bioRxiv and medRxiv in parallel for each DOI.
Hints: read-only yes · destructive not declared · idempotent yes · open-world yes
biorxiv_get_published_versionread-onlyResolve a DOI to its preprint-to-journal crosswalk record — preprint DOI, journal DOI, journal name, published date, and corresponding author details — from either side: a preprint DOI (10.1101/ or 10.64898/) finds the journal article it was published as, and any other DOI is read as a journal article's and finds the bioRxiv or medRxiv preprint it was posted as. Use when biorxiv_get_preprint shows a `publishedJournalDoi` and you need the journal details, or when you hold a journal article and want its preprint. bioRxiv and medRxiv share their DOI prefixes, so server="both" (the default) checks both in parallel and the response reports which server answered. When the crosswalk holds no record for a published preprint, the journal DOI still comes back from the preprint's own record, without journal name or date, and a notice says so. Returns a not-found error when no server holds the preprint, it lists no journal version, or no preprint is recorded for the journal DOI.
Parameters:
doi(required) — string — DOI to resolve: a preprint DOI (e.g. 10.1101/2024.01.15.575123 or 10.64898/2026.05.07.723463) or a journal article DOI (e.g. 10.1016/j.cell.2020.01.001). A doi.org or biorxiv.org/medrxiv.org article URL or a doi: prefix is accepted and stripped to the bare DOI, as is a vN, .full, or .pdf suffix; a journal DOI keeps its own components (10.7554/eLife.55185.sa1 is not 10.7554/eLife.55185). Cold Spring Harbor Laboratory Press journal DOIs (10.1101/gr.…, 10.1101/gad.…, 10.1101/lm.…) share the preprint prefix and cannot be resolved by DOI.server— string — Server the preprint was posted on. "both" (default) checks bioRxiv and medRxiv in parallel — use it when the DOI alone does not tell you which server holds the preprint.
Hints: read-only yes · destructive not declared · idempotent yes · open-world yes
biorxiv_list_published_versionsread-onlyList preprints that appeared as journal articles within a journal publication-date interval, each with its journal DOI, journal name, publication date, and preprint metadata — the same record biorxiv_get_published_version returns for one DOI. The dates filter on journal publication, not preprint posting, so most rows were posted months or years earlier; use biorxiv_list_recent for preprints posted in an interval. `publisher`, a journal DOI prefix such as 10.7554 for eLife, limits the listing to the bioRxiv preprints published under it; those rows carry no journal name, authors, or abstract, and a prefix api.biorxiv.org does not recognize raises invalid_publisher. Returns `limit` publications per server (default 25, up to 100 — the page api.biorxiv.org serves; a larger limit returns 100 and says so). Continue at the `nextCursor` a page returns rather than stepping `cursor` by a fixed amount; `limit: 100` walks an interval in the fewest calls. When server="both" (default), per-server pagination state is returned separately, since one cursor can be past the end of one server and inside the other — to continue a single server, pass its `nextCursor` with `server` set to that server. One server failing under server="both" does not abort the call: the other server's page is still returned and the failed one is named in `failed[]`. Every attempted server failing raises a retryable upstream_unavailable (or rate_limited) error rather than an empty page. Abstracts are omitted by default to keep the page small — pass include_abstract: true for the whole page. Every preprintDoi, 10.1101/ and 10.64898/ alike, is accepted by biorxiv_get_preprint and the other DOI tools.
Parameters:
start_date(required) — string — Start of the journal publication-date interval (YYYY-MM-DD), inclusive.end_date(required) — string — End of the journal publication-date interval (YYYY-MM-DD), inclusive.limit— integer — Rows to return per queried server, starting at cursor. Defaults to 25. Up to 100, the page api.biorxiv.org serves: a larger value returns 100 rows per server and says so in the notice. limit: 100 walks an interval in the fewest calls.cursor— integer — Integer row offset, applied to each queried server. Defaults to 0 (first page). To continue, pass the nextCursor the previous page returned for that server — it advances by the rows actually served.server— string — Preprint server to list. "both" lists bioRxiv and medRxiv in parallel; their rows do not overlap.publisher— string — Journal publisher filter: the DOI prefix its journal articles share, the part before the slash — "10.7554" for eLife, "10.1016" for Elsevier. Lists only the bioRxiv preprints published under that prefix: medRxiv has no publisher listing, so server="both" queries bioRxiv alone and server="medrxiv" is rejected. Rows listed this way carry no journal name, authors, corresponding author, or abstract.include_abstract— boolean — Include each preprint's abstract. Defaults to false: abstracts make up about three quarters of a page, and every other field is returned either way.
Hints: read-only yes · destructive not declared · idempotent not declared · open-world yes
biorxiv_search_preprintsread-onlySearch preprints by keyword and/or author using EuropePMC for relevance ranking, then enrich matching DOIs with full bioRxiv/medRxiv metadata. Provide a keyword query, an author name, or both — author maps to an EuropePMC AUTH: field query and is ANDed with the keyword query. Covers both servers by default. EuropePMC indexes new preprints within 1–2 days of posting; for preprints posted within the last day, prefer biorxiv_list_recent. Abstracts are included by default; include_abstract: false omits them from every result for a response about a third the size, and biorxiv_get_preprint returns the abstract for up to 10 DOIs per call. A EuropePMC rate limit (HTTP 429) fails the call with a retryable rate_limited error carrying the wait in seconds — a rate-limited metadata enrichment does not, and instead marks the affected record enrichment_error: "rate_limited".
Parameters:
limit— integer — Maximum results to return. Defaults to 25. Up to 100 per call: a larger value returns the first 100 and says so, and nextCursorMark continues the ranked list.query— string — Keyword search query. Optional when author is provided — supply at least one of query or author.author— string — Author name to filter by, mapped to an EuropePMC AUTH:"…" field query and ANDed with the keyword query. Optional when query is provided (e.g. "Jennifer Doudna").server— string — Server scope for enrichment. "both" checks all matching DOIs on both servers.date_to— string — Latest first-publication date filter (YYYY-MM-DD).date_from— string — Earliest first-publication date filter (YYYY-MM-DD).cursor_mark— string — Opaque page token for ranked EuropePMC results. Omit for the first page; pass the nextCursorMark returned by a prior call to fetch the next page. Pages through the same ranked list rather than raising limit. A token EuropePMC does not recognize fails with invalid_cursor_mark.include_abstract— boolean — Include each result's abstract. Defaults to true. false omits the abstract from every result, enriched and EuropePMC-fallback alike, and keeps every other field.
Hints: read-only yes · destructive not declared · idempotent not declared · open-world yes
biorxiv_get_fulltextread-onlyRetrieve a preprint's full text as best-effort Markdown, extracted from its rendered HTML article page. Reads the latest version unless one is requested (the version input, or a vN suffix on the DOI), confirms it via the details API, then fetches and extracts the body — abstract, sections, inline citation labels, and the reference list. Table cells are not on the article page: each table appears as its caption, and omittedTables names it with the URL that serves its cells. bioRxiv and medRxiv share the 10.1101/ DOI prefix, so server="both" (the default) resolves the DOI against both in parallel and the response reports which server answered. This is HTML-to-Markdown extraction, not structured JATS: section structure is approximate and not guaranteed. Long articles exceed a single response, so use offset and limit to page through them (the response reports totalChars, remainingChars, and hasMore); paging is cheap because the extracted article is cached per version for an hour after the first read, so only the first chunk pays for a fetch. Not every preprint has an extractable HTML page — some are PDF-only and some origins block programmatic access — in which case a fulltext_unavailable error routes you to biorxiv_get_preprint for the title, metadata, and current abstract. For a preprint that has been published in a journal, the journal's version may have richer full text elsewhere.
Parameters:
doi(required) — string — Preprint DOI (e.g. 10.1101/2024.05.28.596311 or 10.64898/2026.05.07.723463). A doi.org or biorxiv.org/medrxiv.org article URL, a doi: prefix, or a .full suffix is accepted and stripped; a trailing vN (…596311v2) requests that version. Without one, the latest version is resolved automatically.limit— integer — Maximum number of characters to return in this chunk. Default 20,000; a value past the remaining text returns the rest of the article. Check the length field for the actual count returned.offset— integer — Character offset into the full extracted text at which to start reading. 0 returns the beginning. To read the next chunk, use offset = prior_offset + prior_length (the length field from the previous response).server— string — Server the preprint was posted on. "both" (default) checks bioRxiv and medRxiv in parallel to resolve the DOI — the full-text fetch itself only ever targets whichever server resolved, and the output server field names it.version— integer — Preprint version to read (1, 2, …) — the revision numbers biorxiv_get_preprint lists. Omit for the latest version. Must match a vN suffix on the DOI when both are given.
Hints: read-only yes · destructive not declared · idempotent not declared · open-world yes
Measured by MCPYP probing. Untested fields are omitted, never estimated. Listing is always free; MCPYP never proxies calls or stores user tokens.