Paperpile

SkillSearch

Use when the user asks to "add paper", "paperpile add", "fetch PDF for", "find and add", "search paperpile", "find in paperpile", "paperpile search", "label paper", "trash paper", "download paper", "paperpile index", "edit paper metadata", "update paper title", "fix paper author", "paperpile edit", "find PDF online", "search google for PDF", "resolve PDF", "fetch PDF for citation", "get full-text for DOI", "resolve cite to PDF", or any request to manage their Paperpile library or resolve a citation to a local PDF.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Paperpile skill

What this skill tells your AI

The instructions your AI receives, as published by edwinhu/workflows in skills/paperpile/SKILL.md and read by ahel’s review.

What this skill carries — grep references/ for any subject the names below miss: !d=${CLAUDE_SKILL_DIR}; command -v skill-toc >/dev/null 2>&1 && exec skill-toc "$d"; s=$HOME/.claude/skills/plugin-utils/bin/skill-toc; [ -x "$s" ] && exec "$s" "$d"; echo "(skill-toc unavailable: references and scripts are NOT listed here — install the plugin-utils plugin, or start a new session so its bin/ reaches PATH)"

Manage your Paperpile library and resolve citations to PDFs via the paperpile CLI.

CLI-first — this is the whole point of the skill. Every library operation (add, search, fetch, label, edit, trash, auth) goes through the paperpile CLI, which is pure HTTP. Never drive the Paperpile web app (app.paperpile.com) via browser automation to add or manage references — it is slower, the React forms reject synthetic input, and the CLI already does it. If the CLI fails, it is almost always stale auth — refresh cookies (below), do not reach for the browser.

Prerequisites

  • paperpile binary at ~/.local/bin/paperpile (Bun-compiled from ~/projects/paperpile-cli)
  • Valid auth cookies. If paperpile auth fails, refresh them automatically (no manual Cookie-Editor export needed): ${CLAUDE_SKILL_DIR}/scripts/refresh-auth.sh pulls the cookies from the logged-in browser over CDP (:9222 by default — the everyday browser, Chromium on Linux), imports them, and verifies.
  • For PDF resolution: a browser on CDP. resolve_pdf.py takes the first REACHABLE port from, in order, --cdp-port, $PAPERPILE_CDP_PORT, :9250 (the dedicated automation profile at ~/.config/chrome-cdp) and :9222 (the everyday browser). The everyday browser is often the one actually logged in, so it is tried rather than assumed absent — pass --cdp-port 9222 to force it.

Library Management

NeedCommand
Verify authpaperpile auth
Import cookiespaperpile auth import ~/cookies.json
Index/refresh librarypaperpile index --refresh
Search librarypaperpile search "proxy voting"
Download PDF by item IDpaperpile download <item_id>
Fetch PDF by bibkeypaperpile fetch Smith2024-ab
Add by DOIpaperpile add 10.1016/j.jfineco.2024.01.001
Add web source by URLpaperpile add https://example.com/article
Add remote PDFpaperpile add https://example.com/report.pdf
Add local PDFpaperpile add /path/to/report.pdf
Attach PDF to an EXISTING itempaperpile attach <bibkey-or-_id> /path/to/report.pdf --confirm
Add DOI stub (no metadata)paperpile add <doi> --force
List labelspaperpile label list
Create labelpaperpile label create "My Label"
Apply labelpaperpile label apply "My Label" Smith2024-ab
Remove labelpaperpile label remove "My Label" Smith2024-ab
Delete labelpaperpile label delete "My Label" --confirm
Trash itempaperpile trash Smith2024-ab --confirm
Restore from trashpaperpile trash Smith2024-ab --restore --confirm
Edit metadatapaperpile edit Smith2024-ab --title "..." --author "..." --year 2024 --confirm

Key behaviors:

  • add auto-detects input type:
    • DOI (10.xxx) -- lookup metadata via Guru, create entry
    • Web URL (https://...) -- create entry with url:[] field (no --force needed)
    • Remote PDF URL (https://.../*.pdf) -- download PDF, copy to Google Drive, attach to entry
    • Local PDF (/path/to/*.pdf) -- copy to Google Drive sync folder, create entry with PDF attached
    • All modes accept --title, --author, --year, --pubtype for metadata
    • --force only needed for DOIs when Guru metadata is unavailable
  • edit updates metadata fields on existing items via sync API. Dry-run by default -- pass --confirm to apply.
  • fetch resolves a bibkey to PDF via Paperpile API + Google Drive download.
  • search scores against a local index cache. Run paperpile index first.
  • trash and label delete are dry-run by default -- pass --confirm to execute.

Find and Add

One command: citation string → paper in Paperpile with PDF.

paperpile find-and-add "<citation>" [--doi DOI] [--ssrn ID] [--title T] [--author A] [--year Y] [--journal J] [--volume V] [--page P] [--json] [--no-pdf]

Examples

# Law review article (HeinOnline)
paperpile find-and-add "Robertson, Passive in Name Only, 36 Yale J. on Reg. 795 (2019)"

# SSRN working paper
paperpile find-and-add --ssrn 5093097

# Paper with known DOI
paperpile find-and-add --doi 10.1016/j.jfineco.2024.01.001

# Multi-author law review
paperpile find-and-add "Montagnes, Peskowitz and Sridharan, How Well Do Voting Choice Policies Represent Public and Investor Preferences, SSRN 5093097 (2024)"

What it does

  1. Parse citation string → extract author, title, journal, volume, page, year, DOI, SSRN ID
  2. Discover metadata: Guru title search → CrossRef → OpenAlex (law reviews skip CrossRef — too many false positives)
  3. Dedup against cached library index
  4. Add to Paperpile via POST /api/library
  5. Get PDF (automatic, no manual steps):
    • Guru pdf_url preprint/publisher download (pure HTTP)
    • HeinOnline via UVA EZproxy CDP (law reviews with volume/page/known journal)
    • EZproxy/OpenAthens/SSRN via native CDP
    • Google filetype:pdf search via CDP (final fallback)
  6. Copy PDF to Paperpile Google Drive sync folder (~/Google Drive/.../Paperpile/All Papers/<Letter>/)

Supported law review journals (HeinOnline)

UCLA L. Rev., Yale J. on Reg., Yale L.J., Harv. L. Rev., Stan. L. Rev., Colum. L. Rev., Mich. L. Rev., Va. L. Rev., U. Pa. L. Rev., N.Y.U. L. Rev., Chi. L. Rev., Geo. L.J., Duke L.J., Cornell L. Rev., Nw. U. L. Rev., Tex. L. Rev., B.U. L. Rev., and more (see heinonline.ts in paperpile-cli).

Key design decisions

  • Law review citations with volume+page+known journal handle skip CrossRef entirely (unreliable for HeinOnline-only journals) and construct metadata from parsed citation fields
  • Paperpile's PDF crawler runs in the browser extension, not server-side -- neither POST /api/library nor POST /api/sync triggers it. PDF resolution is always active (CDP or HTTP).
  • Guru title search works for finance/econ journals but returns 0 for law reviews (HeinOnline-only)
  • Shibboleth cookies (shibidp.its.virginia.edu) are now snapshotted -- EZproxy re-auth is transparent across browser restarts

Edit Metadata

Update title, author, year, and other fields on existing library items.

paperpile edit <bibkey-or-_id> --title "..." --author "..." --year 2024 [--confirm]

Supported flags: --title, --author, --year, --journal, --volume, --issue, --pages, --abstract, --url, --doi, --publisher, --language, --pubtype, --citekey

Examples

# Edit title and year (dry-run)
paperpile edit Smith2024-ab --title "New Title" --year 2025

# Apply the edit
paperpile edit Smith2024-ab --title "New Title" --year 2025 --confirm

# Institutional author (& treated as single author)
paperpile edit abc123 --author "Davis Polk & Wardwell" --confirm

# Multiple personal authors (comma-separated "First Last" pairs)
paperpile edit abc123 --author "Jack Pitcher, Emily Glazer" --confirm

# Set a DOI (e.g. after a PDF-first add mangled the metadata)
paperpile edit abc123 --doi "10.1111/jofi.12422" --confirm

# SSRN working paper: real DOI is 10.2139/ssrn.<abstract_id> + the abstract URL
paperpile edit abc123 --doi "10.2139/ssrn.666962" \
  --url "https://papers.ssrn.com/sol3/papers.cfm?abstract_id=666962" --confirm

Fixing PDF-first metadata damage: paperpile add <local.pdf> lets Paperpile's server-side PDF-text extractor populate metadata, which often drops co-authors, blanks the year, or duplicates the title. Prefer DOI-first adds. To repair an existing entry, set the correct DOI and repopulate authoritatively from Paperpile's own Guru resolver rather than hand-typing every field. SSRN papers do have real DOIs (10.2139/ssrn.<abstract_id>), but they resolve to preprint metadata — safe for genuine working papers, but don't attach them to a version that was later published (it regresses the journal/volume/page citation).

Key behaviors:

  • Dry-run by default -- shows what would change without applying. Pass --confirm to mutate.
  • Resolves bibkeys to pub _id via the local index (same as trash).
  • Uses POST /api/sync?v=3 with action: "update" to patch fields.
  • Author strings with & are treated as institutional (single author). Comma-separated "First Last" pairs are split into multiple personal authors.

Utilities

NeedCommand
Poll for PDF attachment${CLAUDE_SKILL_DIR}/scripts/poll_attachment.sh <item_id>
Warm up proxy session${CLAUDE_SKILL_DIR}/scripts/warmup.sh [CDP_PORT]
Refresh Paperpile auth${CLAUDE_SKILL_DIR}/scripts/refresh-auth.sh [CDP_PORT]
Resolve a DOI to a PDF${CLAUDE_SKILL_DIR}/scripts/resolve_pdf.py --doi <DOI> --out <DIR> --via-browser
Fetch the PUBLISHED version, not the library copy${CLAUDE_SKILL_DIR}/scripts/resolve_pdf.py <BIBKEY> --skip-paperpile --via-browser

--skip-paperpile bypasses BOTH Paperpile steps (paperpile-api and the synced paperpile dir) and goes straight to the institutional chain. Use it whenever the goal is the version of record: the library's own copy is often the SSRN preprint being replaced, and it short-circuits the chain before any publisher is tried.

Both Paperpile steps are gated on a title-similarity floor of 0.75 (difflib.SequenceMatcher over normalised lowercase titles) against the bib entry's title. A first-author collision on an unrelated paper logs best match '<title>' scored <x> < 0.75 and falls through to the next resolver instead of returning a wrong-title PDF.

warmup.sh auto-clicks the NetBadge cert login via CDP. Runs every 25 min via launchd (com.paperpile.warmup.plist).

CDP port

resolve_pdf.py and warmup.sh both resolve the port at runtime, taking the first that answers GET http://127.0.0.1:<port>/json/version:

  1. --cdp-port N (resolve_pdf.py) or the first positional argument (warmup.sh)
  2. $PAPERPILE_CDP_PORT
  3. 9250 — the dedicated automation profile (~/.config/chrome-cdp)
  4. 9222 — the everyday browser

Nothing is hardcoded to 9250 any more: when the automation profile is down, the everyday browser is used, and it is usually the one already logged into NetBadge and Paperpile. Failure messages name the ports actually tried.

--via-browser is the flag that turns on CDP driving in resolve_pdf.py. --via-dia still works as a deprecated, hidden alias for old callers; do not write it in new commands.

WRDS SOCKS Tunnel (preferred for PDF acquisition)

If the /fetch-paper skill is available (lives in dotfiles, not this plugin), prefer it for downloading paywalled PDFs. It uses a WRDS SOCKS tunnel to present a Penn IP — which is registered with publishers for IP-based access — and bypasses EZproxy entirely.

Check availability:

which wrds-tunnel && which fetch-paper-browser && echo "fetch-paper available" || echo "fetch-paper not available — falling back to EZproxy/CDP"

If available: use /fetch-paper for PDF acquisition, then attach the result:

  • entry already in the library (a DOI add that got no PDF) → paperpile attach <_id> <local.pdf> --confirm. Do NOT add the PDF — that creates a SECOND entry and lets the server's PDF-text extractor write the metadata (see the damage note above).
  • nothing in the library yetpaperpile add <local.pdf>. If not available: use the EZproxy/CDP pipeline in find-and-add as before.

See ${CLAUDE_SKILL_DIR}/references/institutional_access.md for technical details.

Integration

fetch-paper (dotfiles) → download PDF via WRDS SOCKS
Paperpile (this skill) → cite-check (upload PDFs to Gemini)
                       → nlm (upload to NotebookLM)

Auth & Data

  • Cookies: ~/.claude-work/skills/paperpile/cookies/<domain>.json
  • Cache: ~/.claude-work/skills/paperpile/cache/paperpile-index.json
  • Paperpile All Papers: ~/Library/CloudStorage/GoogleDrive-eddyhu@gmail.com/My Drive/resources/Paperpile/All Papers/
  • Cookies expire (~30 days for Paperpile, ~8-12h for Shibboleth hard expiry). To refresh, run ${CLAUDE_SKILL_DIR}/scripts/refresh-auth.sh — it extracts the live cookies from the logged-in browser via CDP (:9222 by default; pass a port argument to override) and paperpile auth imports them (no Cookie-Editor export). Requires being logged into Paperpile in that browser; if not, log in there first.

Red Flags

ActionWhy WrongDo Instead
About to drive the Paperpile web app (app.paperpile.com) via browser automation — CDP clicks, the Add → "Paste references" dialog, filling React formsThe paperpile CLI does every library op over HTTP. The web UI is slower and its React forms silently reject synthetic input (you'll wrestle a textarea that never registers). This is the #1 trap — reaching for the browser when a one-word CLI command exists.Use the CLI (paperpile add <doi|url|pdf>). If it errors on auth, run scripts/refresh-auth.sh, then retry.
Using --force without user approvalAdds DOI stubs without metadata -- clutters libraryAsk user before adding DOIs without Guru data. URLs and PDFs don't need --force
Running trash --confirm without showing dry runDestructive, cannot be undoneRun without --confirm first
Skipping paperpile index before searchStale results from cached indexRun paperpile index --refresh first
Calling Paperpile API directlySkips auth, cookies, error handlingAlways use the CLI
Using curl to fetch a DOI URLPublisher returns HTML paywall, not PDFUse paperpile find-and-add --doi
Running find-and-add with no browser on CDPCDP PDF fallbacks will failCheck both ports: curl -sf http://127.0.0.1:9250/json/version || curl -sf http://127.0.0.1:9222/json/version. Either one is enough — the resolver takes the first that answers.

Signals

GitHub stars
21
Forks
4
Last commit
Sep 2026

ahel review

  • K6low
    bundled executables the agent is told to run

Automated review, not a security audit. Ruleset v1+k2.

Advanced
Catalog kind
skill
Gateway key
paperpile
Source
github.com/edwinhu/workflows