pagecite
Summaries of research PDFs you can actually trust: every claim cites its page, and every quote and number is checked against the PDF before you see it.
Point it at a paper, an analyst report or a pitch deck (a file, a folder or a URL). Claude writes the TL;DR, key arguments, data points, quotes worth keeping and open questions. Then pagecite checks each one against the PDF's own text, with no model involved: is the quote really on the cited page? Do the numbers appear there? Anything that fails is kept but marked ⚠ not verified, with the reason, so a wrong page or a mangled figure never passes as fact.
pagecite demo: a fictional report and a sample summary bundled with pagecite (no API call),
with two claims deliberately wrong. The checks are the real ones.
Why
AI summaries read well and are hard to audit. The usual failure isn't a summary that's obviously wrong. It's a plausible sentence with a number that drifted ("27%" where the report says 22%), or a quote that's real but from a different section than the claim it supports. You only catch those by rereading the document, which is what the summary was supposed to save you.
pagecite splits the work:
| Who | What | |
|---|---|---|
| Writes | Claude (claude-opus-5-5) |
Reads the PDF page by page and returns a structured summary. Every argument and data point carries its page numbers and a verbatim quote. |
| Checks | Plain code, verify.py |
Finds each quote on its cited page and each number in the data points on that page. No model, so no second opinion that can also be wrong. |
| Decides | You | Verified claims are marked ✓. Flagged ones stay in, marked ⚠ with the reason ("quote is on p. 7, not the cited p. 5", "27 not on the cited page"). |
What it does
- Any PDF source: a file, every PDF in a folder, or an
http(s)URL. - Checked summary: TL;DR, key arguments, data points, quotes worth keeping, open questions and tags, each with page numbers. Quotes and figures are verified; open questions and the TL;DR show their pages but have nothing quotable to check.
- Obsidian notes:
-o ~/Vault/Paperswrites each summary as a Markdown note with YAML frontmatter (source, pages, model, verified/flagged counts, tags) and the flags inline. - A library: every PDF you read is stored with its page text, keyed by its SHA-256. Summarising
the same file again (even under another name) costs nothing.
pagecite searchruns full-text search over every page you've read. - Ask with citations:
pagecite ask "what drives the cost gap?" --doc 3answers from the document with citations returned by the API itself, so every sentence points to a page. For one document all its pages are sent with a cache breakpoint, so follow-up questions read them from the prompt cache. Without--doc, the best-matching pages across your library are sent. - MCP server: Claude Desktop, Claude Code or any MCP client can summarise PDFs, search your library, read pages and ask cited questions.
Quickstart
pipx install pagecite
pagecite demo # a checked summary on a fictional report, no key needed
With your own documents:
mkdir -p ~/.pagecite && echo 'ANTHROPIC_API_KEY=sk-ant-...' >> ~/.pagecite/.env # or `ant auth login`
pagecite summarize paper.pdf
pagecite summarize ~/Downloads/reports -o ~/Obsidian/Papers # a whole folder, as notes
pagecite summarize https://arxiv.org/pdf/1706.03762
pagecite ask "what did they measure, and on what data?" --doc 1
| Command | |
|---|---|
pagecite summarize SOURCE… [-o DIR] [--refresh] |
Summarise files, folders or URLs (alias sum) |
pagecite ask QUESTION [--doc ID] |
Answer from one document or the whole library, with page citations |
pagecite list |
The PDFs in your library (alias ls) |
pagecite show ID [--markdown] |
Print a stored summary, or its Obsidian note |
pagecite search QUERY [--doc ID] |
Full-text search over every page |
pagecite mcp |
Run the MCP server over stdio |
pagecite demo |
The demo above |
What counts as verified
verify.py is short and has no dependencies, so the rules are easy to check:
- Quotes must appear on the page(s) they cite. Matching ignores case, punctuation, spacing,
ligatures (
fi) and words split across lines (con-/straint), but keeps decimal points, so "4.2" never matches "42". An ellipsis splits a quote into parts that must appear in order. Quotes under four words are flagged as too short to prove anything. - Numbers in a data point's value must all appear on the cited page: "USD 115 per kWh, down
14%" needs both 115 and 14 there. Thousands separators are normalised (
3,200=3200=3 200). - Pages must exist in the document.
- When a quote is on a different page, the flag says where it really is. pagecite never moves the citation for you.
What it can't check: whether a sentence in Claude's own words fairly represents its quote. That's why each claim shows the quote right under it.
Scanned PDFs without a text layer are refused (OCR them first). Documents too long for one pass are refused rather than silently truncated.
What leaves your machine
| Sent to Anthropic | |
|---|---|
summarize |
the extracted text of the whole PDF |
ask --doc ID |
every page of that document |
ask |
only the best-matching pages from your library |
list, show, search, demo |
nothing |
Your library is one SQLite file, ~/.pagecite/library.db.
MCP
Add to Claude Desktop's claude_desktop_config.json (or claude mcp add pagecite -- pagecite mcp
in Claude Code):
{
"mcpServers": {
"pagecite": { "command": "pagecite", "args": ["mcp"] }
}
}
Install with pipx install 'pagecite[mcp]'. Tools: summarize_pdf (returns each claim with its
check result), ask_library, search, read (page text) and documents. search, read and
documents need no API key.
Configuration
In ~/.pagecite/.env or the environment (see .env.example):
| Variable | Default | |
|---|---|---|
ANTHROPIC_API_KEY |
Or log in once with ant auth login |
|
PAGECITE_NOTES_DIR |
Always write notes here (e.g. a folder in your vault) | |
PAGECITE_MODEL |
claude-opus-5-5 |
|
PAGECITE_DB |
~/.pagecite/library.db |
How it works
flowchart LR
In[file · folder · URL] --> PDF[pdf.py<br/>page texts + SHA-256]
PDF --> Lib[(library.db<br/>pages, FTS5)]
Lib -->|new file| Sum[summarize.py<br/>Claude: structured summary]
Sum --> Lib
Lib --> Verify[verify.py<br/>quotes + numbers vs page text]
Verify --> Out[terminal · Obsidian note · MCP]
Lib --> Ask[ask.py<br/>search-result blocks, cited answers]
Verification runs every time a summary is shown, against the stored page text, so a stored summary never carries a stale result.
Development
git clone https://github.com/owen-alderson/pagecite && cd pagecite
python -m venv .venv && . .venv/bin/activate
pip install -e '.[dev]'
pytest # no network: Claude and HTTP are faked, test PDFs are generated
Releases: push a vX.Y.Z tag and GitHub Actions publishes to PyPI. Re-record the demo with
vhs docs/demo.tape.
The original Streamlit app (pdf-research-summarizer) is kept at tag
v1-streamlit.
License
MIT
Metadata
Release files for pagecite 2.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| pagecite-2.0.0.tar.gz | 34.8 kB | With provenance | Details for pagecite-2.0.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| pagecite-2.0.0-py3-none-any.whl | Python 3 | none | any | Details for pagecite-2.0.0-py3-none-any.whl |
Total release size: 61.6 kB
Release files / pagecite-2.0.0.tar.gz
| Download URL | pagecite-2.0.0.tar.gz |
|---|---|
| Size | 34.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3b21ff6ab01177a36d4b68621efbd6fbd5a15ede9717b1841d325cc9377be71f
|
|
BLAKE2b-256 checksum How to use checksums |
a122d955f33c8f92d91d4a6de4955348cb1308a992847fcedf1f3258b0d52542
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Oct 11, 2026.
Transparency logRelease files / pagecite-2.0.0-py3-none-any.whl
| Download URL | pagecite-2.0.0-py3-none-any.whl |
|---|---|
| Size | 26.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
941fcdddbbb4fb45a787543798fd7ddb85b0eac28676a47291ad7e70abf809a2
|
|
BLAKE2b-256 checksum How to use checksums |
de761afdbc71994624e1cc29a2be4c71dfc57208093e3130da3bbc3bb5d6111b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Oct 11, 2026.
Transparency logSecurity for pagecite 2.0.0
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.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for pagecite-2.0.0.tar.gz
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 Oct 11, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.