dropbox-paper-cli
A Python CLI tool for managing Dropbox Paper documents from the terminal — browse files, create and edit Paper docs, read as Markdown, search across your entire workspace with a local metadata cache, and interactively explore results in a TUI. Built on httpx for fully async HTTP communication.
Features
- OAuth2 Authentication — PKCE flow with automatic token refresh, optional
--loopbackfor paste-free login - Async HTTP — built on httpx with concurrent API requests and token auto-refresh
- File Operations — list, create, read, write, move, copy, delete, create folders, get sharing links
- Paper Doc Creation — create new Paper documents from Markdown, HTML, or plain text
- Paper Doc Updates — overwrite, append, prepend, or revision-safe update existing Paper documents
- Paper Doc Export — read Paper documents as Markdown directly in your terminal
- Local Cache & Search — sync your full Dropbox directory tree to a local SQLite database for instant keyword search with full CJK support, multi-keyword AND matching, and regex patterns
- Paper Doc Discovery — discovers all Paper 2.0 documents including those in team Paper folders
- URL Resolution — every cached item gets a web URL (constructed for files, sharing links for Paper docs)
- Interactive TUI Search — Textual-powered interactive search with F2 to copy link, F3 to open in browser, F5 to toggle regex mode
- Adaptive Concurrency — starts conservatively and ramps up, automatically backs off on 429 rate limits
- Two-Level Parallel Sync — expands top-level folders one level deep for dramatically higher parallelism (3x faster on large workspaces)
- Rich Progress Display — multi-phase progress bar showing metadata, preview URLs, and sharing link sync stages
- Team Account Support — automatic namespace detection for Dropbox Business accounts
- Cross-Platform — works on Linux, macOS, and Windows with platform-aware config paths
- SOCKS Proxy — built-in SOCKS5/SOCKS4 proxy support via
HTTPS_PROXY/ALL_PROXYenvironment variables - JSON Output —
--jsonflag on all commands for scripting - Verbose Logging —
--verboseflag for diagnostic output on all commands
Installation
Requires Python 3.12+.
# Run directly with uvx (no install needed)
uvx dropbox-paper-cli --help
# Or install with uv (recommended)
uv tool install dropbox-paper-cli
# Or with pip
pip install dropbox-paper-cli
Setup
1. Create a Dropbox App
Go to the Dropbox App Console and create a new app:
- Choose Scoped access
- Choose Full Dropbox access type
- Give it any name you like
Under the Permissions tab, enable:
files.metadata.readfiles.content.readfiles.content.writesharing.readsharing.write
2. Configure Credentials
Use the CLI to set your app credentials:
paper config set --app-key YOUR_APP_KEY
paper config set --app-secret YOUR_APP_SECRET # optional
Or create the config file manually at ~/.config/dropbox-paper-cli/config.json:
{
"app_key": "YOUR_APP_KEY",
"app_secret": "YOUR_APP_SECRET"
}
app_secret is optional — if omitted, the PKCE flow is used (no secret needed, recommended for personal use).
Environment variables DROPBOX_APP_KEY / DROPBOX_APP_SECRET take priority over the config file.
3. Authenticate
paper auth login
Follow the browser prompt to authorize the app, then paste the authorization code back into the terminal.
Loopback (paste-free) login
Add --loopback to skip the manual paste — the CLI starts a one-shot local HTTP server on port 53682 and captures the auth code from the redirect:
paper auth login --loopback
This requires registering http://localhost:53682/ as a Redirect URI in your Dropbox app's settings (App Console → your app → Settings → OAuth 2 → Redirect URIs).
Quick Start
# 1. Authenticate with Dropbox
paper auth login
# 2. Create a Paper document
echo "# My First Doc" | paper files create /My First Doc.paper
# 3. Read it back as Markdown
paper files read "/My First Doc.paper"
# 4. Sync metadata cache for search
paper cache sync
# 5. Search for documents
paper cache search "meeting notes"
Proxy Support
The CLI supports HTTP and SOCKS proxies via standard environment variables:
# HTTP/HTTPS proxy
export HTTPS_PROXY=http://proxy.example.com:8080
# SOCKS5 proxy
export ALL_PROXY=socks5://127.0.0.1:1080
SOCKS5/SOCKS4 support is built-in (via httpx[socks]). No additional configuration is needed.
Commands
Authentication
paper auth login # OAuth2 login flow (paste auth code)
paper auth login --loopback # Capture auth code via http://localhost:53682/ redirect
paper auth login --flow code # Use Authorization Code flow (requires app_secret)
paper auth logout # Clear stored credentials
paper auth status # Check authentication state
Configuration
paper config set --app-key KEY # Set Dropbox app key
paper config set --app-secret SECRET # Set Dropbox app secret
paper config show # Show current config
paper config path # Show config file path
File Operations
paper files list [PATH] # List files and folders
paper files metadata PATH # Get detailed metadata (incl. owner / last editor)
paper files read PATH # Read Paper doc as Markdown
paper files create PATH # Create a new Paper document
paper files write PATH # Update a Paper document
paper files link PATH # Get/create sharing link
paper files create-folder PATH # Create a new folder
paper files move SRC DST # Move file or folder
paper files copy SRC DST # Copy file or folder
paper files delete PATH # Delete file or folder
Creating Paper Documents
# From stdin (pipe-friendly)
echo "# Meeting Notes" | paper files create /notes/Meeting.paper
# From a local file
paper files create /notes/Meeting.paper --file notes.md
# HTML format
paper files create /doc.paper --format html --file page.html
Updating Paper Documents
# Overwrite entire content (default)
echo "# Updated" | paper files write /doc.paper
# Append content to end
echo "## Appendix" | paper files write /doc.paper --policy append
# Prepend content to beginning
echo "## Header" | paper files write /doc.paper --policy prepend
# Safe update with revision check (fails if doc changed since given revision)
paper files write /doc.paper --policy update --revision 5 --file new.md
# From a local file with format
paper files write /doc.paper --file content.md --format markdown
Cache & Search
paper cache sync # Incremental sync (default)
paper cache sync --full # Full resync
paper cache sync --path "/subfolder" # Sync specific subtree
paper cache sync --concurrency 10 # Custom worker count
paper cache search QUERY # Search by keyword
paper cache search "meeting notes" # Multi-keyword: AND logic (both must match)
paper cache search QUERY --regex # Regex pattern search
paper cache search "Q\d+" --regex # Example: match Q1, Q2, Q3...
paper cache search QUERY --url # Show URL for each result
paper cache search QUERY --type paper # Filter: paper docs only
paper cache search QUERY --type folder # Filter: folders only
paper cache search QUERY --type file # Filter: regular files only
paper cache search QUERY --limit 20 # Limit results
paper cache isearch # Interactive TUI search
paper cache isearch "initial query" # Open TUI with pre-filled query
Interactive Search (TUI) Key Bindings:
| Key | Action |
|---|---|
| Enter | Move focus to results table |
| F2 | Copy link to clipboard |
| F3 | Open in browser |
| F5 | Toggle regex mode |
| Escape | Quit |
Sharing
paper sharing info FOLDER_ID_OR_URL # Get sharing info for a shared folder
Global Options
paper --json ... # JSON output for scripting
paper --verbose ... # Diagnostic output to stderr
paper --version # Show version
Architecture
- HTTP Layer: httpx-based async client (
lib/http_client.py) with automatic token refresh, retry with exponential backoff, and Dropbox API v2 RPC/content endpoints - Adaptive Concurrency:
AdaptiveLimiterstarts at a conservative level, ramps up on success (+2), and backs off on 429 rate limits (ceiling × 0.7), settling at ceiling × 0.8 - Services:
DropboxService(file/folder ops),SharingService,SyncOrchestrator(parallel sync with two-level expansion), standalonesearch_cache()for keyword queries - Sync Pipeline: root listing → shallow expansion → parallel recursive on sub-folders, with per-folder cursors for efficient incremental sync
- CLI: Typer-based commands with
run_with_client()helper for consistent async execution - TUI: Textual-powered interactive search app with clipboard integration and browser launch
- Cache: SQLite with LIKE keyword search (full CJK support, multi-keyword AND, regex via Python
re), WAL mode, indexedpath_lowerfor fast subtree operations
Data Storage
Follows the XDG Base Directory Specification:
| Purpose | Default Path | Override |
|---|---|---|
| Config (config.json, tokens) | ~/.config/dropbox-paper-cli/ |
PAPER_CLI_CONFIG_DIR |
| Data (cache DB) | ~/.local/share/dropbox-paper-cli/ |
PAPER_CLI_DATA_DIR |
Development
# Clone and install dev dependencies
git clone https://github.com/Koswu/dropbox-paper-cli.git
cd dropbox-paper-cli
uv sync --group dev
# Run tests
uv run pytest
# Lint & format
uv run ruff check src/ tests/
uv run ruff format src/ tests/
# Type check
uv run ty check
# Pre-commit hooks (ruff + ty)
uv run pre-commit install
uv run pre-commit run --all-files
License
MIT
Release files for dropbox-paper-cli 0.5.9
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| dropbox_paper_cli-0.5.9.tar.gz | 234.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| dropbox_paper_cli-0.5.9-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 293.5 kB
Release files / dropbox_paper_cli-0.5.9.tar.gz
| Download URL | dropbox_paper_cli-0.5.9.tar.gz |
|---|---|
| Size | 234.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
91138d48e21e081ad018392e21787cc6f756850250259706347e28ec1ac6d23e
|
|
BLAKE2b-256 checksum How to use checksums |
f9d4ebb3ebe8807d36ada04949c095a61e3e884252d14980208489e74b8194be
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 19, 2026.
Transparency logRelease files / dropbox_paper_cli-0.5.9-py3-none-any.whl
| Download URL | dropbox_paper_cli-0.5.9-py3-none-any.whl |
|---|---|
| Size | 59.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5dc749870626f7662270db0470715e70a70c1fdf236eebaa816d0f63658e58da
|
|
BLAKE2b-256 checksum How to use checksums |
dce2c414e91a92c4f4e3c92294945656ace154570db11f48df817cadd3511965
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 19, 2026.
Transparency log