
[!NOTE] This project is in a stable state as of May 2026 but is not under active maintenance.
Shelfmark is a self-hosted web interface for searching and requesting books and audiobooks across multiple sources. Bring your own sources, metadata providers, and download clients to build a single hub for your digital library. Supports multiple users with a built-in request system, so you can share your instance with others and let them browse and request books on their own.
Works great alongside the following library tools, with support for automatic imports: - Calibre - Calibre-Web - Calibre-Web-Automated - Grimmory - Audiobookshelf
Home screen

Search results

Multi-source downloads

Download queue

Download the docker-compose file:
bash
curl -O https://raw.githubusercontent.com/calibrain/shelfmark/main/compose/docker-compose.yml
Start the service:
bash
docker compose up -d
Open http://localhost:8084
Open the web interface, then configure the sources and settings you want to use.
volumes:
- /your/config/path:/config # Config, database, and artwork cache directory
- /your/download/path:/books # Downloaded books
- /client/path:/client/path # Optional: For Torrent/Usenet downloads, match your client directory exactly.
Tip: Point the download volume to your CWA or Grimmory ingest folder for automatic import.
Note: CIFS shares require
nobrlmount option to avoid database lock errors.
1000:1000 with Docker user: "1000:1000" or docker run --user 1000:1000.runAsUser: 1000, runAsGroup: 1000, and runAsNonRoot: true together.PUID/PGID keep the default root startup flow.1000:1000.USING_TOR=true requires root startup.Direct - Queries configured sources directly
Universal (recommended) - Search via metadata providers (Hardcover, Open Library, Google Books) for richer results - Aggregates releases from multiple configured sources - Full audiobook support
Environment variables work for initial setup and Docker deployments. They serve as defaults that can be overridden in the web interface.
| Variable | Description | Default |
|---|---|---|
FLASK_PORT |
Web interface port | 8084 |
INGEST_DIR |
Book download directory | /books |
TZ |
Container timezone | UTC |
PUID / PGID |
Runtime user/group for the default root-startup flow (also supports legacy UID/GID) |
1000 / 1000 |
SEARCH_MODE |
direct or universal |
universal |
USING_TOR |
Enable Tor routing (requires root startup) | false |
See the full Environment Variables Reference for all available options.
Some of the additional options available in Settings: - Prowlarr - Configure indexers and download clients to download books and audiobooks - Additional audiobook sources - Configure additional sources for audiobook discovery - IRC - Add details for IRC book sources and download directly from the UI - Library Link - Add a link to your Calibre-Web or Grimmory instance in the UI header - File processing - Customiseable download paths, file renaming and directory creation with template-based renaming - Network Settings - Custom proxy support (SOCKS5 + HTTP/S) and configurable DNS - Format & Language - Filter downloads by preferred formats, languages and sorting order - Metadata Providers - Configure API keys for Hardcover, Open Library, etc.
docker compose up -d
The full-featured image with all network capabilities included.
Optional Tor support for network privacy:
curl -O https://raw.githubusercontent.com/calibrain/shelfmark/main/compose/docker-compose.tor.yml
docker compose -f docker-compose.tor.yml up -d
Notes:
- Requires root startup
- Requires NET_ADMIN and NET_RAW capabilities
- Timezone is auto-detected from Tor exit node
- Custom DNS/proxy settings are ignored when Tor is active
A lighter image without the built-in browser automation. Ideal for:
curl -O https://raw.githubusercontent.com/calibrain/shelfmark/main/compose/docker-compose.lite.yml
docker compose -f docker-compose.lite.yml up -d
If you need browser-based access with the Lite image, configure an external resolver in Settings.
Authentication is optional but recommended for shared or exposed instances. Multiple authentication methods are available in Settings:
1. Single Username/Password
2. Proxy (Forward) Authentication
Proxy auth trusts headers set by your reverse proxy (e.g. X-Auth-User). Ensure Shelfmark is not directly exposed, and configure your proxy to strip/overwrite these headers for all inbound requests.
3. OIDC (OpenID Connect)
Integrate with your identity provider (Authelia, Authentik, Keycloak, etc.) for single sign-on. Supports PKCE flow, auto-discovery, group-based admin mapping, and auto-provisioning of new users.
4. Calibre-Web Database
If you're running Calibre-Web, you can reuse its user database by mounting it:
volumes:
- /path/to/calibre-web/app.db:/auth/app.db:ro
With any authentication method enabled, Shelfmark supports multi-user management with admin/user roles. Users can have per-user settings for download destinations, email recipients, and notification preferences. Non-admin users only see their own downloads and can submit book requests for admin review. Admins can configure request policies per source to control whether users can download directly, must submit a request, or are blocked entirely.
Shelfmark is a manual search and download tool, the entry point to your book library, not a library manager. It finds books, downloads them, and sends them to a configured destination. That's the full scope.
Shelfmark intentionally does not:
These are non-goals, not missing features.
Shelfmark's core feature set is complete. Development focuses on stability, bug fixes, quality-of-life improvements, and refining the search experience. Contributions in these areas are welcome, please file issues or submit pull requests on GitHub.
Feature requests that fall outside the project scope (library integration, automation, collection management) will be closed. If you're unsure whether something fits, open a discussion first.
The application exposes a health endpoint at /api/health (no authentication required). Add a health check to your compose:
healthcheck:
test: ["CMD", "curl", "-sf", "http://localhost:8084/api/health"]
interval: 30s
timeout: 30s
retries: 3
Logs are available via:
- docker logs <container-name>
- /var/log/shelfmark/ inside the container (when ENABLE_LOGGING=true)
Log level is configurable via Settings or LOG_LEVEL environment variable.
# Quality checks
make checks # Run ALL static analysis (frontend + Python)
make python-checks # Run Ruff, BasedPyright, and Vulture
make install-python-dev # Sync Python runtime + dev tools with uv
# Frontend development
make install # Install dependencies
make dev # Start Vite dev server (localhost:5173)
make build # Production build
make frontend-typecheck # TypeScript checks
# Backend (Docker)
make up # Start backend via docker-compose.dev.yml
make down # Stop services
make refresh # Rebuild and restart
make restart # Restart container
The frontend dev server proxies to the backend on port 8084.
MIT License - see LICENSE for details.
Shelfmark is a search interface that displays results from external metadata providers and sources. It does not host, store, or distribute any content. The developers are not responsible for how the tool is used or what is accessed through it.
Users are solely responsible for: - Ensuring they have the legal right to download any material they access - Complying with copyright laws and intellectual property rights in their jurisdiction - Understanding and accepting the terms of any sources they configure
Use of this tool is entirely at your own risk.
For issues or questions, please file an issue on GitHub.
$ claude mcp add shelfmark \
-- python -m otcore.mcp_server <graph>