Full-Text Search for Your Zotero Library
September 16, 2026
A Python tool that lets you search across your Zotero library — both metadata and full-text PDFs — from a local web interface or the command line.
Stage 1 — Query Zotero’s API for matching references (titles, authors, years)
Stage 2 — Search within the PDFs of those references for specific terms
You can use Stage 1 alone (metadata-only) or both stages together.
ZotGrep requires:
The recommended way is to install ZotGrep as a uv tool (isolated global command):
Enable the local API in Zotero:
Important
Zotero must be open and running whenever you use ZotGrep.

If you use linked file attachments in Zotero (rather than stored copies), note your Linked Attachment Base Directory from the same settings page (under Files and Folders).
You’ll need this path later for ZotGrep’s base_attachment_path setting.
Tip
If you only use Zotero-stored attachments (the default), you can skip this step.
Start the web interface with:
This opens a local Flask server at:
http://localhost:23120
The ZotGrep search page
The search page has two main input fields:
AND, OR, commas, and quoted phrasesEnter your Zotero metadata search terms and optionally add full-text search terms (comma-separated) to search inside matched PDFs.
Check “Metadata only” in Advanced Search Settings if you only want reference results without PDF processing.
Tip: Use the metadata search scope dropdown to switch between Title, Author & Year (fast, precise) and Everything (broader, includes Zotero-indexed content).
Results are grouped by reference, with occurrence counts, context snippets, and direct links:
Search results with occurrence counts, highlighted context, and Zotero links
Each result card shows:
algorithm: 12)First 10 hits per reference are shown; click to expand the rest.
The Zotero Metadata Search field (and --zotero) accepts Boolean queries:
| Syntax | Example | Meaning |
|---|---|---|
| Words | career engagement |
All words, in any field |
| Phrase | "career engagement" |
Exact phrase |
| OR / comma | "career engagement", motivation |
Either alternative |
| AND | burnout AND nurses |
Both must match |
| Combined | burnout AND nurses OR teachers |
AND binds tighter than OR |
Each alternative is a separate Zotero search; results are merged without duplicates. No wildcards (*) or parentheses here.
The Full-Text Search Terms field (and --fulltext) matches text inside PDFs:
| Syntax | Example | Meaning |
|---|---|---|
| Phrase | machine learning |
Exact phrase (quotes optional) |
| Wildcard | algorithm* |
Prefix match, e.g. algorithms |
| OR / comma | privacy, security |
Either term |
| AND | privacy AND fairness |
Both on the same page |
| Combined | privacy AND fairness OR bias |
AND binds tighter than OR |
No parentheses: write (a OR b) AND c as a AND c OR b AND c.
Two modes available via the dropdown:
titleCreatorYear (default)
everything
After a search, use the export buttons at the top of the results:
Export Results
| Format | Best for |
|---|---|
| CSV | Spreadsheet analysis (Excel, R, pandas) |
| JSON | Programmatic use, data pipelines |
| Markdown | Research notes, documentation |
The export includes all results from your last search, not just what’s currently visible on screen.
ZotGrep ships with three visual themes, selectable from the top-right corner:
Your choice is saved in the browser and persists across sessions.
Warning boxes above the results (or Warning: lines in the CLI) tell you when ZotGrep may have missed something:
| Warning | What to do |
|---|---|
| A metadata search reached the Max Results limit | Raise Max Results or narrow the query |
| Limit reached with a publication title filter | This filter is applied after Zotero returns results, so raise the limit |
| Stored PDF missing | Restore or sync the attachment in Zotero |
| Linked PDF skipped | Set base_attachment_path, or check that the file exists |
| Wildcards or parentheses in a metadata query | Use AND, OR, commas, and quotes instead |
Click “Advanced Search Settings” on the search page to expand filter options:
Advanced Search Settings panel
| Filter | What it does |
|---|---|
| Publication title | Only show results from specific journals/venues (applied after the Zotero search) |
| Item type | Filter by Zotero type (journalArticle, book, etc.) |
| Collection | Restrict to a Zotero collection (by key or exact name) |
| Tags | Filter by Zotero tags |
| Tag match mode | Require all tags or any tag |
| Max results | Stage 1 results per metadata alternative (default: 100) |
| Context window | Sentences before/after each match (default: 2) |
| Metadata only | Skip PDF processing entirely |
| Include abstracts | Show abstracts in result cards |
Navigate to General Settings (link in the top-right) to configure persistent defaults:
General Settings page
These settings are saved to ~/.config/zotgrep/config.json.
Note
The API key field stays blank when you reopen the page. Leave it blank to keep the saved key. For the local Zotero API the key is simply local.
You can also edit the config file directly:
Linked files?
If you use linked PDF attachments in Zotero (not stored in Zotero’s data directory), set base_attachment_path to the root directory containing your PDFs.
Use a different file with --config /path/to/config.json or the ZOTGREP_CONFIG_PATH environment variable.
Settings are resolved in this order (highest priority wins):
--base-path /Users/me/Papers)ZOTERO_BASE_ATTACHMENT_PATH)~/.config/zotgrep/config.json)| Variable | Config equivalent |
|---|---|
ZOTGREP_CONFIG_PATH |
Path to the config file itself |
ZOTERO_USER_ID |
zotero_user_id |
ZOTERO_API_KEY |
zotero_api_key |
ZOTERO_LIBRARY_TYPE |
library_type |
ZOTERO_BASE_ATTACHMENT_PATH |
base_attachment_path |
ZOTERO_MAX_RESULTS |
max_results_stage1 |
ZOTERO_CONTEXT_WINDOW |
context_sentence_window |
| Variable | Config equivalent |
|---|---|
ZOTERO_PUBLICATION_TITLE_FILTER |
publication_title_filter |
ZOTERO_ITEM_TYPE_FILTER |
item_type_filter |
ZOTERO_COLLECTION_FILTER |
collection_filter |
ZOTERO_TAG_FILTER |
tag_filter |
ZOTERO_TAG_MATCH_MODE |
tag_match_mode |
ZOTERO_METADATA_SEARCH_MODE |
metadata_search_mode |
ZOTERO_FULLTEXT_SOURCE |
fulltext_source |
ZOTERO_DEBUG_PUBLICATION_FILTER |
debug_publication_filter |
Run without arguments for an interactive prompt:
You’ll be prompted for:
Pass arguments directly for scripted/automated use:
# Metadata search only
zotgrep --zotero "machine learning health" --metadata-only
# Boolean metadata query: exact phrases as alternatives
zotgrep --zotero '"career engagement", "career orientation"' --metadata-only
# With full-text search
zotgrep --zotero "AI ethics" --fulltext "privacy AND fairness, bias"
# Filter by collection
zotgrep --zotero "career" --collection "Literature Review"
# Filter by tags
zotgrep --zotero "NLP" --tag "important, review" --tag-match any# Save to CSV
zotgrep --zotero "search terms" --csv results.csv
# Save to Markdown
zotgrep --zotero "search terms" --md results.md
# Save to JSON (explicit path)
zotgrep --zotero "search terms" --json results.json
# CSV only, no console output
zotgrep --zotero "search terms" --csv results.csv --csv-only
# Disable default JSON export
zotgrep --zotero "search terms" --no-json
# Multiple formats at once
zotgrep --zotero "search terms" --csv out.csv --md out.md --json out.json# Change metadata search scope
zotgrep --zotero "broad query" --search-mode everything
# Filter by publication title
zotgrep --zotero "term" --publication "Nature, Science"
# Filter by item type
zotgrep --zotero "term" --item-type "journalArticle, book"
# Adjust context window (sentences around each match)
zotgrep --zotero "term" --fulltext "word" --context-window 4
# Limit results (per metadata alternative)
zotgrep --zotero "term" --max-results 50
# Show publication titles before filtering (debug)
zotgrep --zotero "term" --publication "Nature" --debug-publication
# Use custom config file
zotgrep --zotero "term" --config /path/to/config.json| Feature | Web UI | CLI |
|---|---|---|
| Interactive search | Yes | Yes (interactive mode) |
| Scriptable | No | Yes |
| Export CSV/JSON/MD | Yes (buttons) | Yes (flags) |
| Advanced filters | Yes (UI panel) | Yes (arguments) |
| Persistent settings | Yes (settings page) | Yes (config file) |
| Zotero links | Clickable | In output files |
| Full-text source toggle | No (uses default) | Yes (--fulltext-source) |
Feedback welcome!
Open an issue on GitHub if you have questions or feature requests.
OR or commas, require terms with AND, and match exact "quoted phrases"127.0.0.1, avoiding slow IPv6 retriesAlready installed? Run
uv tool upgrade zotgrep.
ZotGrep — https://github.com/franciscowilhelm/zotgrep