Command reference¶
Every papio command, generated directly from the binary. The --json flag is accepted globally, but it does not guarantee JSON output: init prints setup text, and mcp runs a server. Result-producing commands such as acquire, daemon status, and native-host status honor the flag. See the user guide for the operational workflow and the configuration reference for policy.
JSON output contract¶
Every list-shaped --json payload is a JSON object with exactly two keys, rows first: a named array and truncated (bool) — never a bare top-level array. An empty result is [], never null. truncated: true means the page filled its row cap (the default or --limit bound), so more rows may exist; it is not proof there are more — raise --limit or paginate to check.
This is the same envelope the MCP resources (papio://jobs and friends) already return, so one parser handles both surfaces:
Commands that return a single structured record — papio jobs get, papio doctor, papio status, papio batch report, papio zotio plan, papio inbox — return that object directly; they are not list envelopes and carry no truncated key.
A failing command in --json mode prints one line on stderr, {"error":{"code":"not_found","message":"..."}}, and exits with the status below. code is the daemon's error code when the daemon refused the request, daemon_unreachable when no daemon answered, invalid_argument for a bad flag or argument count, and error otherwise; class, hint, and http_status appear when the daemon supplied them. Exit status: 0 on success, 2 for a usage error (a bad flag, argument count, or --config path; --json code invalid_argument), 3 when no daemon answered (daemon_unreachable), and 1 for every other failure, including an error the daemon returned. A command that already printed its structured result to stdout and then exits 1 (for example papio doctor with a failing check) keeps the plain papio: <message> stderr line instead, so read its stdout. Without --json, stderr is always the plain papio: <message> line.
Global flags¶
These flags are available on every command. --version is not one of them: it is a root-only flag, so run papio --version, not papio <subcommand> --version.
| Flag | Type | Default | Description |
|---|---|---|---|
--config |
string |
config TOML path | |
--json |
bool |
false |
emit structured JSON |
papio acquire¶
Submit one paper-acquisition request
| Flag | Type | Default | Description |
|---|---|---|---|
--access-mode |
string |
per-request access-mode override | |
--arxiv |
string |
arXiv ID | |
--author |
stringSlice |
[] |
author (repeatable) |
--auto-import |
bool |
false |
plan and apply zotio import automatically when ready |
--batch |
string |
submit works from a JSONL, RIS, BibTeX, CSL-JSON, MEDLINE/NBIB, or one-identifier-per-line file (or - for standard input) | |
--collection |
string |
target Zotero collection name (key when used with --from-zotio) | |
--consumer |
string |
name the submitting consumer, for per-consumer accounting on a shared daemon | |
--deny-source |
stringSlice |
[] |
deny this source (repeatable) |
--desired-version |
string |
any |
published, accepted, preprint, or any |
--doi |
string |
DOI | |
--force |
bool |
false |
create a fresh job even when this work is already in flight |
--from-digest |
int64 |
0 |
queue pending entries from an alert watch; queued works are set to import into Zotero automatically when ready |
--from-zotio |
bool |
false |
queue zotio items missing an attached PDF |
--include-owned |
bool |
false |
with --batch, submit works already carrying a PDF in zotio |
--isbn |
string |
ISBN | |
--keys |
stringArray |
[] |
digest work key to queue (repeatable) |
--label |
string |
query context; also the default target collection when --collection is unset | |
--limit |
int |
25 |
maximum zotio items to queue |
--max-cost |
float64 |
0 |
maximum paid-source cost in USD |
--openalex |
string |
OpenAlex work ID | |
--pmid |
string |
PubMed ID | |
--request-id |
string |
convergence key: resubmitting it returns the same still-live job; once that job finishes, the same key queues a fresh attempt | |
--resolver |
string |
named institutional OpenURL resolver profile | |
--source |
stringSlice |
[] |
allow only this source (repeatable) |
--title |
string |
work title | |
--wait |
bool |
false |
wait for a terminal or human-action state |
--year |
int |
0 |
publication year |
--zotio-item-key |
string |
existing Zotero item key |
papio actions¶
Inspect required human actions
papio actions dismiss¶
Close a stale human action; cancels its parked job when it was the last open action
Close a stale human action.
An advisory on a terminal job has no other way out: cancel refuses a terminal job, resolve is identity-review only, and the startup sweep deliberately leaves informational advisories alone so a real trace survives. Without this, retiring one meant editing the database or retrying the job purely to cancel it again.
When the dismissed action is the job's last open action and the job is parked on it (awaiting_human on an openurl_handoff, manual_download, openurl_available, or document_delivery action; needs_review on a verify_identity or unsafe_pdf action), dismissing it also cancels the job. Otherwise the job is left untouched.
--revision guards against dismissing an action that changed after you
listed it; take it from the revision column of papio actions list.
| Flag | Type | Default | Description |
|---|---|---|---|
--revision |
int64 |
0 |
revision the action had when you listed it |
papio actions list¶
List open human actions
List open human actions.
An action queued long enough to look abandoned is reported stale — age_seconds and stale in --json, a trailing marker in the text listing — against the configured actions.stale_after_seconds. Staleness is a label and nothing else: no handoff is ever cancelled on a timer, because giving up on an acquisition is your call.
| Flag | Type | Default | Description |
|---|---|---|---|
--all |
bool |
false |
include resolved actions |
--consumer |
string |
only actions whose job was submitted under this consumer name | |
--limit |
int |
100 |
maximum rows (1-500) |
papio actions open¶
Open the current browser handoff queue
Open the current browser handoff queue.
With no selector this opens the whole openable queue, newest first. --job or --action opens exactly one row instead, for a caller that ranked the queue itself and wants the row it chose. A job holding several open actions is refused with their ids rather than resolved by picking one, and a selector naming no open action is an error: falling back to the head of the queue would open somebody else's handoff and report success.
A manual download opens on your library's route, with one exception. When an open-access route left the download, or your library has already reported no entitlement for the paper, that route cannot serve it: papio sends the job back to resolving instead, where it looks up the open-access route again and offers it in the browser. No library link opens. --dry-run prints each such job with "would return to resolving".
The selector is for choosing a row, not for iterating the queue. A background caller that loops it over every row has built the autonomous drain ADR-0009 does not ratify: your browser is one serial surface, and filling it with tabs nobody asked for is not acquisition progress.
| Flag | Type | Default | Description |
|---|---|---|---|
--action |
int64 |
0 |
open only this action id |
--dry-run |
bool |
false |
print URLs, and the jobs sent back to resolving, without opening anything |
--job |
string |
open only this job's open action | |
--limit |
int |
0 |
maximum actions to open (default all) |
papio actions resolve¶
Accept or reject a parked identity or unsafe-PDF review
Accept or reject a parked identity or unsafe-PDF review.
The verdict applies only to the review you inspected. --revision is
required for both verdicts, and --accept also needs --sha256, the
quarantined file's digest; take the revision from the revision column of
papio actions list and the digest from papio actions list --json
(quarantine_sha256). If the action or its file changed since
you listed it, nothing is applied and the command exits nonzero: list
the action again and re-inspect the file before deciding.
--reject cancels the job for an identity review; for an unsafe PDF it sends the job back to awaiting_human for a manual download.
| Flag | Type | Default | Description |
|---|---|---|---|
--accept |
bool |
false |
accept the identity review |
--reject |
bool |
false |
reject the identity review |
--revision |
int64 |
0 |
revision the action had when you listed it |
--sha256 |
string |
quarantine_sha256 of the file you inspected (required with --accept) |
papio actions retry-publisher¶
Retry a failed route through the DOI or an upgraded institution adapter
Retry a failed browser route through the paper's DOI in your browser.
If the DOI retry has already failed, this command re-offers the original institutional route only when the refusing adapter has since been upgraded. Use the action id and revision from the revision column of 'papio actions list'. The failed action and its evidence remain in the job history. Each route can be retried once. Pending sign-ins, challenges, terms, downloads, and unresolved browser effects must be handled first. Neither retry establishes entitlement.
| Flag | Type | Default | Description |
|---|---|---|---|
--revision |
int64 |
0 |
revision the failed action had when you listed it |
papio activity¶
Show recent daemon activity
| Flag | Type | Default | Description |
|---|---|---|---|
--before-seq |
int64 |
0 |
show only events older than this sequence number (the seq of the last row of the previous page); 0 starts at the newest |
--job |
string |
filter activity to one job ID | |
--limit |
int |
30 |
maximum activity rows (1-200) |
papio adapter¶
Inspect provider and adapter interactions
papio adapter capture¶
Capture a provider page through the connected browser
| Flag | Type | Default | Description |
|---|---|---|---|
--provider |
string |
provider adapter id: lowercase, such as wiley or sage | |
--scenario |
string |
fixture scenario | |
--settle-ms |
int64 |
0 |
milliseconds to settle after page load (0-10000) |
papio adapter captures¶
List stored diagnostic page captures
papio adapter captures purge¶
Remove stored diagnostic page captures
Remove stored diagnostic page captures for one host (--host) or for every host (--all). One of the two is required: a bare purge is refused.
The removal includes captures pinned as incident evidence (the first decisive and latest capture of an open incident) and cannot be undone. Run with --dry-run first to see how many captures would be removed.
| Flag | Type | Default | Description |
|---|---|---|---|
--all |
bool |
false |
purge captures for every host |
--dry-run |
bool |
false |
count the captures that would be removed without removing anything |
--host |
string |
purge captures for one host |
papio adapter diagnose¶
Build a sanitized support report for a job
papio adapter repair¶
Scaffold a reviewed adapter repair workspace
| Flag | Type | Default | Description |
|---|---|---|---|
--provider |
string |
provider adapter id (must match daemon capture metadata) | |
--recovery-job |
string |
job that recorded this capture, failed declaratively, then reached ready with a validated PDF | |
--scenario |
string |
fixture scenario (must match daemon capture metadata) |
papio artifacts¶
Inspect validated immutable artifacts
papio artifacts get¶
Show a validated artifact
| Flag | Type | Default | Description |
|---|---|---|---|
--sha256 |
bool |
false |
interpret argument as an artifact hash |
papio artifacts locate¶
Print where one job's validated artifact bytes live
papio artifacts text¶
Print the extracted text of a validated artifact, one page range at a time
Print the text of a validated artifact, extracted by the daemon's bounded pdftotext (the same tool, timeout and process-tree kill validation uses). No OCR runs: ocr_used is always false, so a scanned PDF yields little or no text.
Only the artifact of a job in state ready or imported is served. A job in any other state, a quarantined file, a hash held only by jobs that are not ready or imported, and an unknown hash are each refused with a distinct error.
One read returns at most 131072 bytes (128 KiB) of text, a limit chosen so the
JSON-escaped result always fits the daemon's 1 MiB result cap. --max-bytes may
lower that limit, never raise it. Page ranges are the paging mechanism: when
truncated is true, read on from last_page with --pages
--pages 2-3 pages 2 and 3 --pages 5 page 5 only --sha256 treat the argument as an artifact hash, not a job id
--json prints {text, first_page, last_page, pages_total, chars, truncated, ocr_used}. Without --json the text is printed with terminal control characters removed (the text comes from an untrusted file); --json keeps it byte-exact.
| Flag | Type | Default | Description |
|---|---|---|---|
--max-bytes |
int |
131072 |
lower the per-read byte limit (never above 131072) |
--pages |
string |
page range to read, a-b or a (default: the whole document, up to the byte limit) | |
--sha256 |
bool |
false |
interpret argument as an artifact hash |
papio artifacts validation¶
Print the full validation report for every candidate a job validated
Print the full validation report for every candidate a job validated.
artifacts get returns the shared, content-addressed artifact row —
which is all it can return, because an artifact belongs to every job
that obtained the same bytes (ADR-0007). This is the per-job evidence:
the payload gate, the structural parse, text extraction, and the
identity decision, each with the reasons and capability evidence behind
it, for the candidates that were kept AND the ones that were rejected.
Each report is a versioned document (validation-report/1). A job validated before this evidence was recorded lists no reports; that is an absence, not an empty verdict.
papio batch¶
Inspect persisted acquisition batches
papio batch report¶
Join a batch manifest with live acquisition outcomes
| Flag | Type | Default | Description |
|---|---|---|---|
--markdown |
bool |
false |
emit an agent-ready Markdown digest |
papio bench¶
Run the hermetic comparative acquisition benchmark over a cohort file
| Flag | Type | Default | Description |
|---|---|---|---|
--cohort |
string |
path to a papio-bench-cohort/1 document | |
--fixtures |
string |
fixture directory (default: the cohort file's sibling "fixtures" directory) |
papio browser¶
Inspect and switch connected browser sessions
papio browser permit¶
Recover daemon-owned browser effect permits
papio browser permit resolve¶
Release one unknown-completion browser effect permit
Release one exact unknown-completion effect permit after an operator has independently resolved whether its browser effect completed. This is break-glass recovery; it never releases a held permit.
| Flag | Type | Default | Description |
|---|---|---|---|
--reason |
string |
operator reason recorded in the durable audit event |
papio browser reload¶
Reload the connected development-mode extension from disk
Reload a development-mode extension from disk. --session selects a connected browser by unambiguous session-id prefix, promoting a pending session first. Without it, reload the current holder. The extension refuses reload unless chrome.management.getSelf() reports installType "development".
| Flag | Type | Default | Description |
|---|---|---|---|
--session |
string |
reload this browser session (unambiguous id prefix); promote it if pending | |
--timeout |
duration |
15s |
how long to wait for the reloaded extension to reconnect (0 waits not at all) |
papio browser sessions¶
List currently connected browser sessions
papio browser use¶
Give one browser session the papio offer/handoff flow
| Flag | Type | Default | Description |
|---|---|---|---|
--latest |
bool |
false |
switch to the most recently active pending session |
papio bundle¶
Read and export validated acquisition bundles
papio bundle document¶
Print the acquisition bundle without writing it anywhere
papio bundle export¶
Export an idempotent bundle directory
| Flag | Type | Default | Description |
|---|---|---|---|
-o, --output |
string |
destination directory |
papio campaign¶
Stage a selected citation export in bounded acquisition chunks
papio campaign import¶
Preview and persist up to 200 source records without submitting jobs
| Flag | Type | Default | Description |
|---|---|---|---|
--collection |
string |
destination collection; automatic Zotero import stays off | |
--resolver |
string |
institution resolver profile |
papio campaign list¶
List staged campaigns: id, creation time, works, acknowledged chunks and paused state
papio campaign pause¶
Prevent further staged submission
papio campaign preview¶
Classify all campaign works without submitting
papio campaign report¶
Return one outcome for every original source record
papio campaign resume¶
Allow staged submission without submitting yet
papio campaign run¶
Submit at most one chunk within the 50-active-work window
papio config¶
Manage papio configuration
papio config acknowledge-closure¶
Reopen paid egress for a source that closed on price or balance drift (requires --confirm)
A source's paid egress closes, and stays closed with no timed reopen, when the provider's prices stop matching the schedule papio committed against or when its prepaid balance falls below the starting observation. 'papio doctor' names the closed source and the reason.
This command acknowledges the closure after you have checked the provider's account, and reopens egress. The next response from the provider sets the new balance baseline. Without --confirm nothing changes. It exits nonzero when the source was not closed.
| Flag | Type | Default | Description |
|---|---|---|---|
--confirm |
bool |
false |
reopen paid egress for the source |
papio config agent¶
Configure optional article-agent decisions
papio config agent remove¶
Disable the configured agent while preserving stored credentials
papio config agent set¶
Enable TypeSafe/Jev with a key saved in the OS credential store
Enable cloud article decisions for this configuration profile. This sends article DOIs, bounded titles and sanitized control descriptions to TypeSafe. The key is stored as a shared-service typed credential with an explicit reference. Input is hidden; use --key-stdin for a secret-manager pipe. The running daemon keeps the old setting until it is stopped: run 'papio daemon stop' after changing it, and the next papio command starts the daemon with it.
| Flag | Type | Default | Description |
|---|---|---|---|
--key-stdin |
bool |
false |
read the API key from standard input instead of a hidden terminal prompt |
papio config agent status¶
Show agent configuration without revealing credentials
papio config credentials¶
Manage integration credentials in the OS store or environment
papio config credentials bind¶
Reuse an existing typed credential for this configuration
papio config credentials delete¶
Delete a stored record without changing configurations that reference it (requires --yes)
Delete one stored credential record. Deletion cannot be undone, and a record can be shared: another configuration bound to it keeps a reference that no longer resolves, and its integration fails after the next restart. Papio cannot see other configurations. It refuses to delete a record this configuration binds (detach it first), and without --yes it only describes the deletion and exits nonzero.
| Flag | Type | Default | Description |
|---|---|---|---|
--yes |
bool |
false |
delete the record; without it the command only describes the deletion |
papio config credentials detach¶
Remove a configuration binding while preserving the stored record
papio config credentials migrate¶
Move this configuration's legacy secrets into verified OS records
Migrate supported literal credentials and this profile's legacy TypeSafe key. New records are verified before one guarded config update. Existing vault entries are retained. Interrupted operations report staged references for inspection or explicit deletion. The previous config is saved to config.toml.bak (mode 0600) and may still hold the literal secrets; delete it once you have checked the result. An active legacy TypeSafe environment override must be removed before migration.
papio config credentials set¶
Save a new credential and bind this configuration to it
Create a fresh OS credential record for one integration. Supply a single API key at the hidden prompt or with --key-stdin. For sources.openaire and notify.webhook, use --key-stdin with a version-1 typed JSON credential record. TypeSafe setup enrolls this profile in cloud article decisions. The running daemon keeps the old credential until it is stopped: run 'papio daemon stop' after changes, and the next papio command starts the daemon with them.
| Flag | Type | Default | Description |
|---|---|---|---|
--key-stdin |
bool |
false |
read a key or typed JSON record from standard input |
papio config credentials status¶
Show selected credential sources without revealing values
papio config init¶
Write explicit first-run configuration
Write a new configuration with defaults and the given access mode. With --force it replaces an existing file: every other setting, including data_dir, institutions, sources, hooks and credential bindings, is reset to defaults. The previous file is saved to config.toml.bak (mode 0600, replacing any older backup); it may hold plaintext secrets. To change only the access mode, use 'papio config set-access-mode'.
| Flag | Type | Default | Description |
|---|---|---|---|
--access-mode |
string |
required: conservative, assisted, or delegated | |
--data-dir |
string |
artifact and database directory | |
--email |
string |
contact email for polite APIs | |
--force |
bool |
false |
replace an existing config and reset every other setting |
papio config set-access-mode¶
Change access_mode in the existing config and keep every other setting
Set access_mode to conservative, assisted, or delegated in the existing configuration. Every other setting is kept. A running daemon keeps its old mode until it restarts.
papio daemon¶
Run or control the local acquisition daemon
| Flag | Type | Default | Description |
|---|---|---|---|
--socket |
string |
Unix socket path |
papio daemon status¶
Check the running daemon without autostarting one
papio daemon stop¶
Stop the running daemon without autostarting one
papio delivery¶
Manage document-delivery and ILL requests
papio delivery cancel¶
Cancel a document-delivery request that has not reached the provider
Cancel a document-delivery request that has not reached the provider.
papio cancels a request locally while it is still offered or declined. It cannot cancel a request that is already live at the provider: no provider adapter supports API cancellation, so cancel that one directly with the institution. For a request in unknown_outcome, check with the provider and then use 'papio delivery confirm-absent'. A refused cancellation exits nonzero.
papio delivery confirm-absent¶
Confirm no request exists at the provider, cancel the stale row, and reopen reconciliation for a deliberate decision (v1 never auto-resubmits)
papio delivery confirm-exists¶
Confirm a lodged request exists at the provider and resume polling
papio delivery get¶
Show a job's document-delivery request and compiled gate
papio delivery history¶
Show a delivery request's history for reconciliation (Decision 4's open_request_history)
papio delivery resume¶
Clear a live delivery request's poll-failure bookkeeping (e.g. a contract-drift park) so the next poll is no longer a no-op
papio delivery submit¶
Route a job to document delivery; may place a real ILL request with the provider (requires --confirm)
Route a job to document delivery.
This runs the document-delivery Branch/gate decision and acts on it. When the institution's gate allows automatic submission, papio places a real request with the provider — which can count against a request allowance or cost the institution money, and which papio cannot cancel through the provider. Otherwise it opens a prefill or reconciliation action.
Without --confirm nothing is submitted: the command reports what --confirm would do for this job (a real provider request, a prefill action, or the handling of an existing request) and exits nonzero.
| Flag | Type | Default | Description |
|---|---|---|---|
--confirm |
bool |
false |
run the gate and, when it allows, place the provider request |
papio doctor¶
Check acquisition readiness and local integrations
papio drive¶
Inspect and pause the paced drive of parked handoffs
The paced drive opens parked handoffs for you, one at a time, oldest first, through the same path as 'papio actions open'. It is off unless [drive] enabled = true in the config, and it waits whenever the browser is busy, a sign-in is open, a provider is refusing this browser, or the hourly bound is spent. A sign-in nobody completes pauses it and notifies you.
papio drive pause¶
Stop paced opens until 'papio drive resume'
papio drive resume¶
Let the paced drive open handoffs again
papio drive status¶
Show whether the paced drive would open a handoff, and what blocks it
papio export¶
Export normalized citation records (CSL-JSON, RIS, BibTeX)
| Flag | Type | Default | Description |
|---|---|---|---|
--force |
bool |
false |
replace the -o file when it already exists (without it, an existing file is refused) |
--format |
string |
citation format: csl-json, ris, or bibtex (default csl-json, inferred from -o's extension) | |
--include-duplicates |
bool |
false |
keep records whose canonical identity repeats instead of collapsing them |
-o, --output |
string |
write citations to this file instead of stdout (required with --json) |
papio export batch¶
Export every work in the batch manifest in manifest order, including skipped and unavailable works
papio export campaign¶
Export every distinct work staged in a campaign (read-only: no daemon call); unparseable source records are skipped and counted
papio export job¶
Export the named jobs in argument order (any state: citation metadata stays useful when retrieval failed)
papio export ledger¶
Export one record per canonical work (validated acquisitions by default)
| Flag | Type | Default | Description |
|---|---|---|---|
--consumer |
string |
only works submitted by this consumer | |
--since |
string |
only works submitted after this instant (RFC3339) or within this duration (e.g. 24h, 7d) | |
--state |
string |
acquired |
which works to export: acquired (ready or imported; validated acquisitions), ready (not yet imported) or any (every job) |
papio export search¶
Export the rows of a saved search snapshot (read-only: no daemon call)
| Flag | Type | Default | Description |
|---|---|---|---|
--keys |
stringSlice |
[] |
export only these snapshot row keys (comma-separated; an unknown key is an error) |
papio export watch¶
Export a watch's pending digest entries
papio failures¶
Aggregate unavailable and parked acquisition reasons
| Flag | Type | Default | Description |
|---|---|---|---|
--by-provider |
bool |
false |
group by provider host/source instead of reason |
--limit |
int |
20 |
maximum aggregate rows (1-200) |
papio grabs¶
Manage captured PDF grabs
papio grabs binds¶
List captures papio filed automatically, without asking
List captures papio bound to a pending job on its own, newest first.
papio only does this when a settled, DOI-less capture qualifies exactly one pending job; everything else still parks for a human. Because there is no unbind command, this listing — the rule version, how many candidates were on the table, and the evidence that made one of them the winner — is the only way to check an automatic filing after the fact.
One page holds at most 200 binds. When more exist, the listing ends with the command for the next page: --before with the last grab id shown.
| Flag | Type | Default | Description |
|---|---|---|---|
--before |
string |
list only binds older than this grab id (the last grab of the previous page) | |
--limit |
int |
50 |
maximum autonomous binds to list (default 50, max 200) |
papio grabs confirm¶
File a parked capture against the job you picked
Bind a parked capture to a specific pending job chosen by a human —
typically the top (or any) row of papio grabs suggest's ranking.
papio still refuses the pick if the document's own front matter names a different paper: extracted identity outranks a human pick, the same rule autonomous binding already applies to itself. A refusal changes nothing — no job is created and the capture stays parked exactly as it was before.
| Flag | Type | Default | Description |
|---|---|---|---|
--job |
string |
pending job id to file this capture against |
papio grabs identify¶
Bind an operator-supplied identifier to a captured PDF grab
Bind an operator-supplied identifier to a captured PDF grab that parked without one, creating or joining the job for that work.
When a ready job already holds the identifier, the outcome is already_owned
and the capture is kept, still parked: nothing checks the typed identifier
against the file, so it may be a different paper or version. Discard it
with papio inbox decide pdf_grab:<grab-id> --op dismiss --delete-grab.
| Flag | Type | Default | Description |
|---|---|---|---|
--arxiv |
string |
identify by arXiv ID | |
--doi |
string |
identify by DOI | |
--pmid |
string |
identify by PubMed ID |
papio grabs suggest¶
Rank pending jobs against a parked capture: which paper is this?
Rank the pending jobs that best match a capture which parked instead of
binding on its own, most-likely first, with the evidence behind each
ranking. Nothing is filed by running this — it only orders the candidates
a human would otherwise have to hunt through by hand; pick one and run
papio grabs confirm to actually file it.
If the captured file states its own DOI, PMID, or arXiv ID in its front
matter, that identifier is printed first: papio grabs identify with that
value is faster and more certain than picking from the ranked list below it.
| Flag | Type | Default | Description |
|---|---|---|---|
--limit |
int |
5 |
maximum ranked suggestions to return (default 5, max 25) |
papio inbox¶
Show the triage inbox
| Flag | Type | Default | Description |
|---|---|---|---|
--cursor |
string |
continue from the cursor printed after the previous page | |
--limit |
int |
0 |
maximum items (default 50, maximum 100) |
papio inbox counts¶
Show complete triage inbox counts
papio inbox decide¶
Acquire or dismiss one triage inbox item
Acquire or dismiss one triage inbox item. papio inbox (also id in papio inbox --json).
Dismissing a captured PDF grab (an item id starting with "pdf_grab:")
permanently deletes the captured file and its grab record; papio grabs
suggest and papio grabs identify cannot recover it afterwards. That
dismissal is refused unless --delete-grab confirms it.
A decision that did not apply (conflict or invalid) exits nonzero after printing its outcome.
| Flag | Type | Default | Description |
|---|---|---|---|
--delete-grab |
bool |
false |
confirm that dismissing a captured PDF grab permanently deletes its file |
--op |
string |
acquire or dismiss | |
--watch-scope |
string |
all |
for dismiss: all, or a comma-separated list of watch IDs |
papio init¶
Set up papio for a first run
| Flag | Type | Default | Description |
|---|---|---|---|
--attachment-mode |
string |
zotio attachment mode: stored or linked-file | |
--check-updates |
bool |
true |
check for papio and zotio updates once a day via GitHub releases (sends nothing else) |
--email |
string |
contact email for polite API pools | |
--extension-id |
string |
Chrome extension ID allowed to reach the native host, or an unpacked extension folder path (papio computes its ID) | |
--firefox-extension-id |
string |
Firefox add-on ID allowed to reach the native host | |
--institution-url |
string |
library discovery or resolver URL; papio derives the OpenURL base | |
--libkey-library-id |
string |
numeric Third Iron library id, or a BrowZine/LibKey.io URL containing /libraries/ |
|
--non-interactive |
bool |
false |
do not prompt; retain existing values unless a flag overrides them |
--openurl-base |
string |
institution OpenURL resolver base URL | |
--proquest-account-id |
string |
ProQuest account id, or a ProQuest URL containing accountid= | |
--shibboleth-entity-id |
string |
Shibboleth IdP entityID for federated login-routing | |
--skip-browser |
bool |
false |
skip Chrome extension and native-host setup |
--zotio-path |
string |
zotio executable path |
papio jobs¶
Inspect and control acquisition jobs
papio jobs add-component¶
Add a supplement or appendix PDF from any path to a job
Add a supplement or appendix to a job that already holds its main PDF (ready or imported). The file can be anywhere on this computer. papio copies it into its data directory and runs the same payload and structure checks as a main PDF; a supplement is not checked against the requested work. Your original file is not changed.
Use supply-pdf for a job's main file.
| Flag | Type | Default | Description |
|---|---|---|---|
--role |
string |
component role: supplement or appendix |
papio jobs archive¶
Archive a validated acquisition without deleting its artifact
| Flag | Type | Default | Description |
|---|---|---|---|
--confirm |
bool |
false |
confirm the archive decision; do not delete retained artifacts |
papio jobs cancel¶
Cancel a nonterminal job
papio jobs diagnose¶
Explain why one job needs attention and what can happen next
papio jobs disposition¶
Inspect acquisition disposition and retained artifact
papio jobs failures¶
Group acquisition jobs that need attention
Group acquisition jobs that need attention.
Incident fingerprints omit raw hosts and identifiers and are keyed per installation; local output intentionally includes bounded safety_domain and registrable host_family labels for diagnosis.
| Flag | Type | Default | Description |
|---|---|---|---|
--limit |
int |
50 |
maximum groups (1-200) |
--since |
string |
include jobs updated since an RFC3339 timestamp or within this duration (e.g. 24h, 7d) |
papio jobs filing¶
Inspect and retry durable managed folder filing
papio jobs filing inspect¶
Inspect managed destination receipts and retry state
| Flag | Type | Default | Description |
|---|---|---|---|
--limit |
int |
100 |
maximum receipts (1-500) |
papio jobs filing list¶
Inspect managed destination receipts and retry state
| Flag | Type | Default | Description |
|---|---|---|---|
--limit |
int |
100 |
maximum receipts (1-500) |
papio jobs filing retry¶
Safely replay a journaled managed folder destination
| Flag | Type | Default | Description |
|---|---|---|---|
--destination |
string |
journaled folder destination; default is the configured folder |
papio jobs get¶
Show one job with events and actions
| Flag | Type | Default | Description |
|---|---|---|---|
--wait |
bool |
false |
wait for completion or human action |
papio jobs incidents¶
Group decisive provider incidents
Group decisive provider incidents by keyed failure shape.
The fingerprint omits raw hosts and identifiers and is keyed per installation; local output intentionally includes bounded safety_domain and registrable host_family labels for diagnosis.
| Flag | Type | Default | Description |
|---|---|---|---|
--limit |
int |
50 |
maximum groups (1-200) |
--since |
string |
include incidents recorded since an RFC3339 timestamp or within this duration (e.g. 24h, 7d) |
papio jobs list¶
List jobs
| Flag | Type | Default | Description |
|---|---|---|---|
--consumer |
string |
only jobs submitted under this consumer name | |
--limit |
int |
100 |
maximum rows (1-500) |
--state |
string |
only jobs in this state: queued, resolving, fetching, validating, ready, imported, awaiting_human, retry_wait, needs_review, unavailable, failed, cancelled |
papio jobs receipt¶
Show the outcome and component index for one job
papio jobs redrive¶
Replace a spent manual download, open-access handoff, or terms park with an institutional handoff
Replace a parked manual download, an open-access browser handoff whose URL answered HTML, or an open terms_acceptance_required action with no live browser claim, with a fresh institutional handoff.
An unavailable job whose terminal reason is browser_rejected is also accepted with --revision 0: that reason came from an empty browser job_reject, which says nothing about the paper, and redrive returns the job to awaiting_human with a fresh institutional handoff.
A needs_review job whose one open manual download asks you to remove an adopted file that failed validation is accepted once that file is gone from the job's adoption directory. Redrive returns it to awaiting_human with a fresh institutional handoff; while the file remains, it refuses.
Two parks go back to resolving instead, with no new action: a manual download left by an open-access browser route, where papio looks up that route again, and any spent route of a job whose institution has already reported no entitlement. Resolving offers a live open-access handoff when one remains, an untried institutional handoff next, and otherwise settles the job.
Redrive accepts nothing on the provider: the extension's own terms consent setting decides again when the handoff is driven, and without consent the job parks on terms again.
Use the revision column of papio actions list. For a job
whose action is already resolved and has no open action, use --revision 0.
This runs once per observed browser outcome. It does not open a tab.
| Flag | Type | Default | Description |
|---|---|---|---|
--revision |
int64 |
0 |
revision of the open manual download, open-access handoff, or terms action; 0 if no action is open |
papio jobs refile¶
Run the configured on-ready filing hook again
Run the [hooks] on_ready command from your configuration again for a ready or imported job. The command runs through your shell with the daemon's environment, and whatever it files is written to your library, so check the job id first.
--dry-run prints the command that would run, and the refusals that would stop it, without running anything.
| Flag | Type | Default | Description |
|---|---|---|---|
--dry-run |
bool |
false |
print the hook command that would run, without running it |
papio jobs repair-awaiting-human¶
Return an orphaned awaiting-human job with no open actions to resolving
papio jobs restore¶
Restore an archived acquisition to the actionable ready view
papio jobs retry¶
Explicitly retry a failed, unavailable, or retry-wait job
papio jobs show¶
Show one job with events and actions
| Flag | Type | Default | Description |
|---|---|---|---|
--wait |
bool |
false |
wait for completion or human action |
papio jobs supply-pdf¶
Supply a local PDF as a job's main file
Supply a PDF you already have — an email attachment, an interlibrary loan copy, or an earlier download — as the main file of an existing job. papio copies the file into its data directory and runs the same checks as a browser download: the PDF must be readable and must be the requested work. A PDF of a different work goes to identity review or is rejected; it never becomes ready unchecked. Your original file is not changed.
The job must still be open: queued, resolving, fetching, waiting to retry (retry_wait),
or awaiting a human download. A finished job (ready, imported, unavailable, failed, or
cancelled) cannot take a PDF: submit the work again with papio acquire, then supply the
PDF to the new job id.
Use add-component for supplements and appendices.
papio jobs unfiled¶
List ready jobs whose on-ready filing is missing or failed
| Flag | Type | Default | Description |
|---|---|---|---|
--filter |
string |
all |
filing filter: failed, missing, or all |
--limit |
int |
100 |
maximum rows (1-500) |
papio mcp¶
Serve papio tools and resources over MCP stdio
papio native-host¶
Manage browser native-messaging host registration
papio native-host install¶
Register native-messaging host manifests and the host executable
| Flag | Type | Default | Description |
|---|---|---|---|
--firefox-manifest-dir |
string |
override the Firefox native-messaging manifest directory | |
--manifest-dir |
string |
override the Chrome native-messaging manifest directory |
papio native-host status¶
Report native-messaging host registration state
| Flag | Type | Default | Description |
|---|---|---|---|
--firefox-manifest-dir |
string |
override the Firefox native-messaging manifest directory | |
--manifest-dir |
string |
override the Chrome native-messaging manifest directory |
papio native-host uninstall¶
Remove native-messaging host manifests and the host executable
Remove the native-messaging manifests of every known browser (Chrome, Edge, Vivaldi, Brave, Opera, Chromium, Firefox) and the shared host executable. With --manifest-dir or --firefox-manifest-dir, act only on the named directories (Chrome manifest, Firefox manifest) and keep the host executable unless --remove-host is given.
| Flag | Type | Default | Description |
|---|---|---|---|
--dry-run |
bool |
false |
list what would be removed without removing it |
--firefox-manifest-dir |
string |
remove only the Firefox manifest in this directory; other browsers and the host executable stay | |
--manifest-dir |
string |
remove only the Chrome manifest in this directory; other browsers and the host executable stay | |
--remove-host |
bool |
false |
with a directory override, also remove the shared host executable that every browser uses |
papio notify¶
Inspect and test notification routing
papio notify preview¶
Preview notification copy without sending
| Flag | Type | Default | Description |
|---|---|---|---|
--count |
int |
1 |
number of events represented in the preview |
papio notify show¶
Show effective notification routing
papio notify test¶
Send one local or webhook notification test
Send one test notification for a category. By default the test goes to the local desktop channel. With --webhook it is posted once to the configured webhook in its configured notify.webhook_format, bypasses the ledger, and reports whether the endpoint answered with a 2xx status.
| Flag | Type | Default | Description |
|---|---|---|---|
--webhook |
bool |
false |
send the test through the configured webhook instead of the desktop |
papio pulse¶
Show the daemon's current work pulse
papio search¶
Search configured discovery backends for scholarly works
| Flag | Type | Default | Description |
|---|---|---|---|
--cited-by |
string |
DOI to find papers it cites (backward references; OpenAlex cited_by: filter) | |
--cites |
string |
DOI to find papers citing it (forward citations; OpenAlex cites: filter) | |
--continuation |
string |
resume a new-only search with its exact query and filters | |
--limit |
int |
20 |
maximum results (1-50) |
--new-only |
bool |
false |
page until the requested unowned count or a disclosed scan budget |
--oa-only |
bool |
false |
return only open-access works |
--related-to |
string |
DOI to find OpenAlex-related papers (related_to: filter) | |
--source |
string |
discovery backend: arxiv, openalex, or semanticscholar (default: all configured) | |
--year-from |
int |
0 |
minimum publication year |
--year-to |
int |
0 |
maximum publication year |
papio search acquire¶
Preview selected search keys; submit only with --confirm
| Flag | Type | Default | Description |
|---|---|---|---|
--collection |
string |
destination collection | |
--confirm |
bool |
false |
submit exactly the selected works after current ownership classification |
--keys |
stringSlice |
[] |
comma-separated exact keys from the search snapshot |
--label |
string |
search selection |
batch label |
--resolver |
string |
institution resolver profile |
papio search save¶
Save a bounded search result set for explicit selection
| Flag | Type | Default | Description |
|---|---|---|---|
--limit |
int |
20 |
maximum selected search candidates (1-50) |
--new-only |
bool |
false |
fill the bounded snapshot with unowned results |
--oa-only |
bool |
false |
open-access results only |
--source |
string |
configured discovery backend | |
--year-from |
int |
0 |
minimum publication year |
--year-to |
int |
0 |
maximum publication year |
papio stats¶
Show lifetime acquisition totals by access basis
papio stats page-bulk¶
Show page-bulk scan/submit funnel and identifier yield
papio stats producers¶
Show who produced each acquired artifact and how many needed a person
| Flag | Type | Default | Description |
|---|---|---|---|
--since |
string |
24h |
count promotions since this RFC3339 instant or within this duration (e.g. 24h, 7d) |
--until |
string |
count promotions before this RFC3339 instant (default now) |
papio status¶
Show active and recent acquisition jobs
| Flag | Type | Default | Description |
|---|---|---|---|
--follow |
bool |
false |
refresh every 2 seconds |
papio version¶
Print version information
papio watch¶
Manage scheduled discovery watchlists
papio watch add¶
Add a scheduled discovery watch
Add a scheduled discovery watch. Backfill watches take no query. Alert-mode discovery watches report new works without acquiring them.
By default (--mode acquire, --cadence daily) a discovery watch runs on its own schedule and submits up to --limit-per-run new works each run, and every job it submits asks for automatic Zotero import once it is ready, whatever zotio.auto_import says (zotio.auto_import_paused still pauses it). Use --mode alert to only report new works to the watch digest and acquire them on demand.
| Flag | Type | Default | Description |
|---|---|---|---|
--cadence |
string |
daily |
daily, weekly, or Nh |
--cited-by |
string |
DOI to find papers it cites (backward references; OpenAlex cited_by: filter); replaces the query and excludes --cites | |
--cites |
string |
DOI to find papers citing it (forward citations; OpenAlex cites: filter); replaces the query and excludes --cited-by | |
--collection |
string |
zotio collection for queued papers | |
--kind |
string |
discovery |
watch kind: discovery or backfill |
--label |
string |
human label (defaults to query) | |
--limit-per-run |
int |
10 |
maximum new papers queued per run (1-50) |
--mode |
string |
acquire |
discovery mode: acquire or alert |
--oa-only |
bool |
false |
return only open-access works |
--year-from |
int |
0 |
minimum publication year |
--year-to |
int |
0 |
maximum publication year |
papio watch backfill¶
Manage explicit non-Zotero library backfill
papio watch backfill add¶
Schedule missing PDFs from a declared record_present source
| Flag | Type | Default | Description |
|---|---|---|---|
--cadence |
string |
daily |
daily, weekly, or Nh |
--label |
string |
human label | |
--limit-per-run |
int |
10 |
maximum new papers per run (1-50) |
--source |
string |
configured record_present library source name (required) |
papio watch digest¶
Show recently reported works from an alert watch
| Flag | Type | Default | Description |
|---|---|---|---|
--limit |
int |
100 |
maximum digest entries to show (1-500) |
papio watch digest clear¶
Clear pending works from an alert watch digest
Discard every pending work in an alert watch digest, including works
papio watch digest did not show (it lists 100 by default). A cleared work
is never reported again. Clearing requires --all; --dry-run counts the
pending works without clearing them. To discard single works instead,
use papio inbox decide <item-id> --op dismiss.
| Flag | Type | Default | Description |
|---|---|---|---|
--all |
bool |
false |
confirm clearing every pending work, including works the digest view did not show |
--dry-run |
bool |
false |
count the pending works without clearing them |
papio watch edit¶
Change operational watch settings without resetting history
| Flag | Type | Default | Description |
|---|---|---|---|
--cadence |
string |
daily, weekly, or Nh | |
--collection |
string |
destination collection | |
--label |
string |
human label | |
--limit-per-run |
int |
0 |
maximum papers per run (1-50) |
--oa-only |
bool |
false |
return only open-access works |
--year-from |
int |
0 |
minimum publication year (0 clears) |
--year-to |
int |
0 |
maximum publication year (0 clears) |
papio watch list¶
List scheduled discovery watches
papio watch publication¶
Monitor acquired preprints without replacing their PDFs
papio watch publication acquire¶
Explicitly acquire a published manifestation and keep the original
| Flag | Type | Default | Description |
|---|---|---|---|
--confirm |
bool |
false |
approve acquisition of this exact published manifestation |
papio watch publication add¶
Opt in an acquired preprint or accepted manuscript
| Flag | Type | Default | Description |
|---|---|---|---|
--cadence |
string |
weekly |
daily, weekly, or Nh |
papio watch publication list¶
List publication watches
papio watch publication notices¶
List verified publication notices
papio watch publication pause¶
Stop scheduled checks and keep notice history
papio watch publication run¶
Check typed publication relations now
papio watch remove¶
Remove a scheduled discovery watch
Remove a scheduled discovery watch. Jobs and Zotero items earlier runs created stay. The watch's digest is deleted with it, so removing a watch that still has pending (unreviewed) digest works is refused unless --discard-digest confirms that those works are discarded too.
| Flag | Type | Default | Description |
|---|---|---|---|
--discard-digest |
bool |
false |
remove the watch even though pending digest works are deleted with it |
papio watch resume¶
Re-enable a watch that repeated failures disabled
Re-enable a watch that five consecutive failures disabled, keeping its id, query, and digest history.
Fix the failing source first, then force a run with papio watch run <id>. Resume refuses until a run has succeeded since the watch was disabled.
papio watch run¶
Force-run a scheduled discovery watch now
papio zotio¶
Preview and apply Zotero integration through zotio
papio zotio apply¶
Apply one immutable zotio plan after SHA-256 confirmation
| Flag | Type | Default | Description |
|---|---|---|---|
--confirm-sha256 |
string |
Exact confirmation SHA-256 printed by papio zotio plan |
papio zotio import-backfill¶
Backfill stranded ready papers into Zotero (dry-run by default)
Deliver validated ready jobs whose Zotero import never succeeded.
Dry-run is the default: the command reports what it would import, which papers are already owned (and would be marked duplicate), and which are expected to fail (for example bundle validation on an empty title). Pass --apply to write to your library.
Jobs submitted without policy.auto_import are excluded unless you pass --include-not-requested, because importing them was never requested.
| Flag | Type | Default | Description |
|---|---|---|---|
--apply |
bool |
false |
apply imports to the configured Zotero library (default is dry-run) |
--cursor |
string |
resume after the cursor returned by a previous invocation | |
--include-not-requested |
bool |
false |
include ready jobs that did not request policy.auto_import |
--limit |
int |
50 |
maximum jobs per invocation (1-50) |
papio zotio plan¶
Export ready jobs and preview exact zotio mutations
papio zotio preflight¶
Verify the configured zotio version and capabilities
papio zotio tags¶
Manage the exception-tag ledger on linked Zotero items
papio zotio tags reconcile¶
Converge papio:needs-action / papio:unavailable tags with current job states
Run now the papio-owned tag pass that the daemon runs automatically. It writes to Zotero immediately, with no preview.
papio zotio tags retractions¶
Preview or apply the papio:retracted tag on items with a verified retraction notice
Previews by default: lists the Zotero items whose DOI exactly matches a current verified retraction notice and the papio-owned tags no longer warranted. --apply writes the automatic papio:retracted tag and removes only papio-owned ones. Corrections and expressions of concern are never tagged, a manual tag is never changed, and acknowledging the inbox alert does not remove the tag. With zotio.retraction_tags off, --apply only removes papio-owned tags.
| Flag | Type | Default | Description |
|---|---|---|---|
--apply |
bool |
false |
Write the changes instead of only previewing them |