Skip to content

Repository files navigation

PaperRelay

English · 简体中文

Turn a local paper source into a self-hosted web library and a continuous PDF reader.

CI License: MIT

Library list

Library list on wePaper, the maintainer’s live instance. That site is one operator’s library, not this repository.

Continuous PDF reader

PDF reader on the same instance: continuous scroll, in-page find, and Range fetches.

First-party sources are Zotero and a local folder of PDFs. A third adapter should not need changes to the sync engine, server, or reader.

Why it exists

Most paper tools give you an API, a plugin, or a hosted stack with Postgres and a worker. PaperRelay is the other shape: one process, SQLite, PDF files on disk, and a library you can actually read.

Paper source → source adapter → change probe / reconcile → sync engine
    → server (SQLite + blobs) → catalog revision → live library → continuous PDF reader

Architecture

wePaper is the maintainer’s production instance of this pipeline. PaperRelay is the reusable framework. Do not treat wePaper’s papers, tokens, or host as part of the install.

Supported sources

Adapter Where it runs What it reads
Zotero Agent on the Mac/PC that runs Zotero Local API, read-only. Collection filter. Never writes zotero.sqlite.
Folder Agent on the host that has the files, or a compose profile A directory of PDFs plus optional metadata.json / sidecar JSON.

A missing Zotero process or an unmounted folder aborts sync. It does not unpublish the library.

Adding a third source means implementing SourceAdapter and registering it. See docs/adapters.md. Mendeley, WebDAV, and Calibre are not shipped.

Deploy the server

Use the compose file from the GitHub Release / tag you are running. The file on main may not match a released image.

git clone --branch v0.2.0 https://github.com/rainhuang0220/PaperRelay.git
cd PaperRelay
cp .env.example .env
# set PAPERRELAY_SYNC_TOKEN to a long random string
docker compose pull
docker compose up -d

Open http://127.0.0.1:8788/

The container is the API and the UI. It does not talk to Zotero. SQLite and PDF blobs live in the Docker volume paperrelay-data at /var/lib/paperrelay. There is no Redis, Postgres, or worker.

To publish from a folder on the same host:

# in .env: PAPERRELAY_SOURCE=folder, PAPERRELAY_FOLDER_PATH=/papers, and the token
export PAPERRELAY_FOLDER_HOST_PATH=/path/to/papers
docker compose --profile folder-agent up -d

Without Docker: uv sync, build web/, then uv run paperrelay serve. Details in docs/deployment.md.

The image for this tag is ghcr.io/rainhuang0220/paperrelay:0.2.0. Use the compose file and the image tag from the same release.

Run the agent

The agent lives where the source lives.

# Python 3.12+
uv sync
export PAPERRELAY_SERVER_URL=http://127.0.0.1:8788
export PAPERRELAY_SYNC_TOKEN=the-same-token
# optional isolated agent state (otherwise ~/.config/paperrelay):
# export PAPERRELAY_STATE_DIR=$PWD/agent-state

# Zotero
export PAPERRELAY_SOURCE=zotero
export PAPERRELAY_ZOTERO_COLLECTIONS="My Papers"

# or Local Folder — put at least one PDF in the directory first
# export PAPERRELAY_SOURCE=folder
# export PAPERRELAY_FOLDER_PATH=/path/to/papers

uv run paperrelay doctor
uv run paperrelay daemon                 # automatic near-real-time sync
uv run paperrelay daemon install         # optional macOS LaunchAgent
# uv run paperrelay sync --once          # diagnostics only

doctor checks the source, the token, and whether a daemon is running. sources prints the configured adapter. daemon watches the source, reconciles, and retries. An already-open catalog refreshes when the server catalog version changes. sync --once is for diagnostics, not the daily path.

See docs/sync.md for probe vs periodic reconcile, latency, and troubleshooting.

Site title, subtitle, and footer are environment variables (PAPERRELAY_SITE_TITLE, …). You do not edit React to rename the library.

What this is not

An AI research assistant, a Zotero replacement, an annotation platform, or a document-management suite. The product is source → sync → serve → read.

Documentation

License

MIT. Third-party notices, including why this tree does not vendor Zotero’s AGPL reader, are in THIRD_PARTY_NOTICES.md.

About

Self-hosted framework that relays a local paper source to a web library and continuous PDF reader.

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages