Supplementary Materials¶
Retrieve the figures, tables, spreadsheets, and documents that a journal publishes alongside an article.
Journal full text describes supplementary materials but does not contain
them. In JATS XML a <supplementary-material> element carries a label, a
caption, a filename, and a media type — the file itself is a separate
binary stored beside the XML. BioMCP locates those binaries, merges the
copies published by different providers into one list, and returns the
bytes unchanged. It does not convert or parse them on delivery; the
supplement text search reads them in place
without changing what downloads return.
Quick start¶
List what an article has, then download one file:
biomcp --json get article PMC7857465 assets
biomcp get article PMC7857465 asset TBBE_A_1426496_SM7925.docx > supplement.docx
The first command returns a manifest. Each entry in it carries a handle,
which is the exact command that retrieves that file.
Listing assets¶
<id> accepts a PMID, a PMCID, or a DOI. The manifest is JSON only;
running it without --json returns an error rather than a Markdown card.
The assets section must be the only section in the command. Combining it
with fulltext, annotations, or any other section is rejected.
Views¶
The manifest has two lists: assets, the files that can be retrieved, and
coverage, the files that were named but could not be. Select which to
return with --asset-view.
| View | Returns |
|---|---|
compact |
A short page of both lists. The default. |
retrievable |
The assets list only, paged. |
coverage |
The coverage list only, paged. |
Paging applies to whichever list the view selects.
| Option | Meaning |
|---|---|
--asset-limit <N> |
Page size, 1 to 100. |
--asset-offset <N> |
Zero-based offset into the list. |
Place these options before the article identifier:
Manifest entries¶
Each entry in assets describes one file:
| Field | Meaning |
|---|---|
filename |
The publisher's filename. |
asset_key |
The identifier used to retrieve the file. |
kind |
figure-image, supplementary-file, or other. |
media_type |
The declared MIME type, when the provider supplies one. |
size_bytes |
Size of the retrieved bytes. |
sha256 |
Digest of the retrieved bytes. |
provider |
The source that supplied the bytes. |
reuse |
License state for this file. See Licensing below. |
jats |
Label, caption, and source id from the article XML, when present. |
discovery_routes |
Every route that named this file. |
handle |
The command that retrieves this file. |
A file published through several providers appears once. Its
discovery_routes lists each route that found it, and provider names the
one that supplied the bytes.
Downloading an asset¶
The command writes the file to standard output with no conversion. Redirect it to a file or pipe it to another process:
Verify the download against the manifest's sha256 if integrity matters to
your workflow.
Asset keys come from the manifest. An unknown key returns not_found when
the manifest resolved successfully, and source_unavailable when no
provider could be reached.
Redirect binary downloads
Standard output receives the raw bytes. Running the command in a terminal without redirecting it prints binary content directly to the terminal, which can leave the terminal in an unusable state.
Reading coverage¶
coverage names files BioMCP found references to but did not return. It is
how you tell an article with no supplementary materials from an article
whose supplementary materials could not be reached.
| Outcome | Meaning |
|---|---|
retrievable |
The file is available; it also appears in assets. |
healthy_absent |
The provider confirmed the file does not exist. |
access_or_licence_denied |
The provider refused access. |
pmc_proof_of_work |
PMC answered with a challenge page instead of the file. |
unsupported_origin |
The link pointed somewhere BioMCP will not fetch from. |
source_unavailable |
The provider could not be reached, or returned unusable content. |
empty_response |
The route answered, but its reply held no bytes for the file. |
unusable_asset |
The route answered, but the bytes do not match the file name's type. |
Entries with a pmc_proof_of_work outcome carry no asset_key and no
handle. The file is named because the article references it, and BioMCP
will not present a challenge page as the file's contents.
A route that answers with a zero-byte body gets the empty_response
outcome: the download fails with an article_asset_not_retrievable error
naming the empty response, no output file is written, and the file is never
listed in assets. When the same filename is held by several routes, the
route that returned bytes stays listed under its own asset key and the
empty route is kept in coverage with the asset key it would have carried,
so a caller holding either key gets the copy that exists or a refusal that
names why.
Bytes that do not match the file name's type are refused the same way with
the unusable_asset outcome: a vendor HTML page under a .docx name is a
failed download, never a delivered file. The check reads the leading bytes
a file type commits to — PDF, the zip family (docx, xlsx, zip), the legacy
Office formats, gzip, and the common image types — and leaves text formats
unchecked.
When every route for one supplement is empty, wrong-type, or missing, the
manifest keeps the file in coverage with that reason, so a caller can tell
an article with no supplement from one whose copies all failed.
An article whose supplementary materials are deposited only as an author manuscript is the common case for this outcome. When Europe PMC holds its own copy the file is returned normally; when it does not, the file is named and not delivered.
Where assets come from¶
BioMCP consults these routes for a validated PMCID and merges the results:
| Route | Contents |
|---|---|
| PMC OA Archive | Media objects declared by the article's S3 package metadata. |
| PMC OA object | A single bucket object fetched by name when the package download failed or its member was refused. |
| Europe PMC | The article's supplementary files ZIP, validated in memory. |
| JATS XML | Supplement links declared in the article XML. |
| PMC HTML | Supplement links found on the article page, and the page's own file route for a supplement no other copy serves. |
| Figshare | Records discovered through Semantic Scholar for supported article URLs. |
A supplement whose only copy is Europe PMC's, and whose reply is empty or wrong-type, is looked up by file name in the PMC open-data bucket and on the PMC article page; a copy found there is listed like any other route.
The source_attempts array reports what each route returned, independently
of whether any file was found:
| Outcome | Meaning |
|---|---|
data |
The route returned usable content. |
degraded |
The route returned content with a recoverable problem. |
healthy_absent |
The route confirmed it holds nothing for this article. |
source_unavailable |
The route failed. |
timed_out |
The route exceeded its budget. |
Optional routes run under a shorter budget than the primary route, so a slow provider cannot withhold files another provider has already returned.
Provider URLs stay internal. Handles are BioMCP commands, never download links.
Licensing¶
Each asset carries its own reuse block. A file's license is not implied by
the article's license, and is frequently unknown:
license_present— whether BioMCP holds a license fact for this file.license— the license, when known.license_source— which provider supplied the license fact.reuse_warning— present when no license fact is available.
BioMCP does not enforce reuse terms. Review the returned license context and the provider's terms before redistributing a downloaded file. The durable inventory of provider terms is in Source Licensing.
Searching supplement text¶
The command extracts the text of the article's xlsx, xls, csv, docx, pdf
and zip supplements and reports each match. Protein substitutions match
their one-letter, three-letter and p. name forms, so P245S, Pro245Ser
and p.Pro245Ser find the same change. Other text uses case-sensitive
substring matching.
<id> accepts a PMID, a PMCID, or a DOI. Add --asset <asset-key> to
search one file from the manifest instead of all of them. Output is JSON
only.
Each hit carries the file it came from, the file's sha256 checksum, and
an exact locator:
| Format | Locator |
|---|---|
| xlsx, xls | Worksheet name and row (Sheet1 row 2780). |
| csv | Row, counting the header as row 1. |
| Page number. | |
| docx | Paragraph number. |
| zip | The member path, plus the member's own locator. |
The context field holds the matched row, page, or paragraph text, capped
at 400 bytes, so a hit can be verified at its locator.
Reading the file outcomes¶
The files array reports what happened to each searched file, and each
archive member inside one:
| Outcome | Meaning |
|---|---|
searched |
Text was extracted and searched. |
empty_text |
The file parsed but holds no text, such as a scanned PDF. |
unextractable |
The file could not be read; reason names why. |
An empty hits list with every file searched means the string appears
nowhere. A file reported unextractable was never searched, so its format
and reason tell the caller what is missing.
Search limits¶
Extraction is bounded. Beyond the retrieval limits above, text extraction
stops at 64 MiB per file, 64 MiB per archive member, 256 MiB aggregate per
file, 500 PDF pages, and 20 seconds per file; a file that crosses a limit
is reported with its reason. At most 200 hits are reported, and
hits_truncated says when to narrow the string.
Extracted text uses the managed HTTP cache, keyed by the source file's
SHA-256. The same bytes reuse their extraction until the configured
[cache].max_age_secs expires or cache maintenance removes the entry;
changed bytes get a new key. Cache statistics include extracted text, and
age, size and free-disk limits apply to it. --no-cache and
BIOMCP_CACHE_MODE=off skip both read and write.
Limits¶
Retrieval is bounded. Content beyond these limits is reported as unavailable rather than truncated:
- PMC OA objects: 8 MiB each, 256 objects, 64 MiB total.
- Europe PMC ZIP: 64 MiB compressed, 8 MiB per member, 64 MiB expanded, 256 members. Members are validated and never extracted to disk.
- Linked supplements: 256 candidates, 64 MiB total.
A resolved manifest is reused for five minutes, including paging
continuations. Pass --no-cache to bypass that reuse.
MCP clients¶
The assets manifest is available over MCP. Retrieving asset bytes is not —
asset <asset-key> returns an error directing the caller to the CLI. Binary
payloads are outside what the tool interface returns.
Troubleshooting¶
Article asset manifests are JSON-only; rerun with --json
Add --json. The manifest has no Markdown rendering.
assets is a standalone JSON-only article section; do not combine it with
other sections
Either another section was requested in the same command, or an option was
placed after the identifier and parsed as a second section. Put
--asset-view, --asset-limit, and --asset-offset before the
identifier.
The manifest is empty and coverage lists unfamiliar names
Those entries are references BioMCP found and would not fetch. Check the
outcome on each; unsupported_origin means the link pointed outside the
article's own provider.
Binary content printed to the terminal
asset <asset-key> writes to standard output. Redirect it.
A file is named in coverage but has no handle
The outcome explains why. pmc_proof_of_work, access_or_licence_denied,
and source_unavailable all name a file that exists without being able to
deliver it.
See also¶
- Article — search, retrieval, and full text.
- PubMed — the literature source.
- Data Sources — resolution order and bounds.
- Source Licensing — provider terms.