Boopmark — A bookmark manager for humans and AI agents

A fast, self-hostable bookmark manager for humans and AI agents.

License: MIT Latest Release GitHub Stars

Built with Rust, HTMX, and Tailwind CSS. Save, tag, and search your bookmarks from a clean web UI, a CLI (boop), or let your AI coding agents do it for you. Optional AI enrichment auto-generates tags and descriptions. Pluggable screenshot capture for page thumbnails.

--- ## Installation ### For humans Tell your AI coding agent: > Read https://raw.githubusercontent.com/willisrocks/boopmark/main/README.md and follow the installation instructions. Or follow the [Quick Start](#quick-start-self-hosting) and [CLI](#cli-boop) sections below. ### For AI agents #### Claude Code plugin Install the Boopmark plugin to give Claude Code the `boop` skill: ```bash claude plugin add willisrocks/boopmark ``` This adds the `boop` skill, which Claude Code will automatically use when you ask about bookmarks. #### CLI setup (all agents) Any AI agent with shell access can use the `boop` CLI directly: ```bash # 1. Install the binary curl -fsSL https://raw.githubusercontent.com/willisrocks/boopmark/main/install.sh | sh # 2. Point at your Boopmark server (local or hosted) boop config set-server http://localhost:4000 # local dev # or boop config set-server https://boopmark.yourdomain.com # your hosted instance # 3. Get your API key: log in to the Boopmark web app → Settings → Generate API Key boop config set-key YOUR_API_KEY # 4. Verify boop list ``` > **Important:** You need a running Boopmark server and a user account before the CLI will work. See [Quick Start](#quick-start-self-hosting) to set one up, then log in to the web app to generate your API key under **Settings**. To give Claude Code (or any AI agent) access without the plugin, add this to your project's `CLAUDE.md` or `AGENTS.md`: ```markdown ## Bookmarks Use the `boop` CLI to save and search bookmarks: - `boop add --tags "tag1,tag2"` — save a bookmark - `boop search ` — find bookmarks - `boop list` — list recent bookmarks - `boop add --suggest` — save with AI-suggested tags and description ``` ## Features - Save and tag bookmarks with automatic metadata extraction - Full-text search across titles, descriptions, and URLs - AI enrichment via Anthropic Claude (auto-tagging, descriptions) - CLI client (`boop`) for terminal and agent-based bookmark management - Claude Code skill support — agents can save and search bookmarks - Optional screenshot capture via Playwright sidecar - Invite-only access control with admin panel - Import/export (JSONL, CSV, Netscape HTML) - S3-compatible image storage (local disk or RustFS/AWS S3/R2) ## Quick Start (Self-Hosting) The fastest path uses Docker Compose and `just bootstrap`: ```bash # 1. Prerequisites: Docker, just, openssl git clone https://github.com/chrisfenton/boopmark cd boopmark # 2. Bootstrap: generates secrets, starts services, creates your owner account just bootstrap you@example.com --password yourpassword # 3. Open http://localhost:4000 and sign in ``` `just bootstrap` copies `.env.example` to `.env`, generates random secrets, starts the Docker stack, waits for readiness, and creates your owner account in one step. ## Configuration Copy `.env.example` to `.env` and customize. Only three variables are required; everything else has sensible defaults. | Variable | Default | Description | |----------|---------|-------------| | `DATABASE_URL` | — | Postgres connection string (required) | | `SESSION_SECRET` | — | Random hex string for session signing (required) | | `LLM_SETTINGS_ENCRYPTION_KEY` | — | Base64-encoded 32-byte key for encrypting API keys (required) | | `APP_URL` | `http://localhost:4000` | Public base URL | | `PORT` | `4000` | HTTP port | | `LOGIN_ADAPTER` | `local_password` | `local_password` or `google` | | `GOOGLE_CLIENT_ID` | — | Required when `LOGIN_ADAPTER=google` | | `GOOGLE_CLIENT_SECRET` | — | Required when `LOGIN_ADAPTER=google` | | `STORAGE_BACKEND` | `local` | `local` or `s3` | | `S3_ENDPOINT` | — | S3-compatible endpoint URL | | `S3_ACCESS_KEY` | — | S3 access key | | `S3_SECRET_KEY` | — | S3 secret key | | `S3_REGION` | `auto` | S3 region | | `S3_IMAGES_BUCKET` | `boopmark-images` | S3 bucket name | | `S3_IMAGES_PUBLIC_URL` | — | Public URL prefix for stored images | | `SCREENSHOT_BACKEND` | `disabled` | `disabled` or `playwright` | | `SCREENSHOT_SERVICE_URL` | — | Required when `SCREENSHOT_BACKEND=playwright` | | `METADATA_FALLBACK_BACKEND` | — | `iframely` or `opengraph_io` (optional) | | `IFRAMELY_API_KEY` | — | Required when `METADATA_FALLBACK_BACKEND=iframely` | | `OPENGRAPH_IO_API_KEY` | — | Required when `METADATA_FALLBACK_BACKEND=opengraph_io` | | `ENABLE_E2E_AUTH` | `0` | Set to `1` for E2E test auth bypass | ## Deployment Guides ### Docker Compose (default) ```bash just bootstrap you@example.com --password yourpassword ``` The server runs on port 4000. Add a reverse proxy (nginx, Caddy) for HTTPS. ### Railway + Neon 1. Provision a [Neon](https://neon.tech) Postgres database and copy the connection string. 2. Fork this repo and connect it to [Railway](https://railway.app). 3. Set environment variables in Railway: `DATABASE_URL`, `SESSION_SECRET`, `LLM_SETTINGS_ENCRYPTION_KEY`, `APP_URL`. 4. Deploy. Railway runs `./boopmark-server` which auto-migrates on startup. 5. Create your first user via the Railway shell: `./hash_password yourpassword` then insert directly. ### Optional: S3 Storage (RustFS) Uncomment the `rustfs` service in `docker-compose.yml`, then set: ``` STORAGE_BACKEND=s3 S3_ENDPOINT=http://rustfs:9000 S3_ACCESS_KEY=rustfsadmin S3_SECRET_KEY=rustfsadmin ``` ### Optional: Screenshot Capture Uncomment the `screenshot-svc` service in `docker-compose.yml`, then set: ``` SCREENSHOT_BACKEND=playwright SCREENSHOT_SERVICE_URL=http://screenshot-svc:3001 ``` ## CLI (`boop`) ```bash # Install curl -fsSL https://raw.githubusercontent.com/chrisfenton/boopmark/main/install.sh | sh # Configure boop config set-server https://your-boopmark-instance.example.com boop config set-key YOUR_API_KEY # Use boop add https://example.com --title "Example" --tags "ref,tools" boop list boop search "rust async" boop export --format jsonl > backup.jsonl ``` See `boop --help` for all commands. ## Development **Prerequisites:** Rust (stable), Node.js 24+, Docker, [just](https://github.com/casey/just) ```bash # One-time setup (starts db, runs migrations, installs deps, builds CSS) just setup # Start the server cargo run -p boopmark-server # Watch CSS changes just css # Run tests cargo test # Run linter cargo clippy -- -D warnings ``` For local HTTPS subdomains, install [devproxy](https://github.com/foundra-build/devproxy) and set `USE_DEVPROXY=1` in `.env`, then run `just dev`. ## Architecture Boopmark follows hexagonal (ports-and-adapters) architecture: - **Domain** (`server/src/domain/`) — pure business logic, no I/O - **Ports** (`server/src/domain/ports/`) — trait definitions for external dependencies - **Adapters** (`server/src/adapters/`) — concrete implementations (Postgres, S3, Anthropic, etc.) - **App services** (`server/src/app/`) — orchestration layer - **Web** (`server/src/web/`) — Axum handlers, templates, routing Key ports: `BookmarkRepository`, `MetadataExtractor`, `ObjectStorage`, `LlmEnricher`, `LoginProvider`, `ScreenshotProvider` See [CONTRIBUTING.md](CONTRIBUTING.md) for details on adding new adapters. ## Contributing See [CONTRIBUTING.md](CONTRIBUTING.md). ## License MIT — see [LICENSE](LICENSE).