
Zotero Cli Cc
- 11 installs
- 194 repo stars
- Updated July 30, 2026
- agents365-ai/zotero-cli-cc
zotero-cli-cc is a Claude Code skill that uses the zot CLI to search, read, cite, organize, and RAG-query a Zotero reference library.
About
zotero-cli-cc is a Claude Code skill that uses the zot CLI to search, read, export, and organize a Zotero library, including workspace-based RAG over papers. A developer or researcher uses it to manage literature and produce citation-keyed evidence for grounded answers. Reads run offline on local SQLite while writes use the Zotero Web API, with dry-run and idempotency safety on mutations.
- zot CLI for Zotero: search, CRUD, PDF extraction, citation export, and workspace RAG
- zot ask returns a citation-keyed evidence pack for writing grounded answers
- Read ops work offline with zero config; write ops need Zotero Web API credentials
Zotero Cli Cc by the numbers
- 11 all-time installs (skills.sh)
- Ranked #482 of 688 Office & Documents skills by installs in the Skillselion catalog
- Data as of Aug 3, 2026 (Skillselion catalog sync)
zotero-cli-cc capabilities & compatibility
Free; reads need no config, writes need Zotero API credentials.
- Capabilities
- reference management · citation export · pdf extraction · literature rag
- Works with
- github
- Use cases
- research · pdf parsing · documentation
- Platforms
- Windows
- Pricing
- Free
What zotero-cli-cc says it does
`zot` is an all-in-one Zotero CLI: search, CRUD, PDF extraction, citation export, and workspace-based RAG.
`zot ask` when you need a citation-keyed evidence pack to write a grounded answer
npx skills add https://github.com/agents365-ai/zotero-cli-cc --skill zotero-cli-ccAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 11 |
|---|---|
| repo stars | ★ 194 |
| Last updated | July 30, 2026 |
| Repository | agents365-ai/zotero-cli-cc ↗ |
What it does
Manage and RAG-query a Zotero reference library through the zot CLI, including citation-keyed evidence packs.
Who is it for?
Searching, organizing, citing, and RAG-querying a Zotero library, including citation-keyed evidence packs via zot ask.
When should I use this skill?
The user mentions papers, references, citations, Zotero, literature, bibliography, or needs to search, read, export, or organize documents.
What you get
Search results, citations, PDF extracts, or a citation-keyed RAG evidence pack from the Zotero library.
- Citation-keyed RAG evidence packs
- Citation exports
- PDF text/outline/section extracts
By the numbers
- 7 critical rules
- 8-char Zotero item keys
Files
Zotero CLI Skill
zot is an all-in-one Zotero CLI: search, CRUD, PDF extraction, citation export, and workspace-based RAG. Local SQLite for reads, Zotero Web API for writes.
Quick Start
zot search "transformer attention" # Search papers
zot --json read ABC123 # View paper details (JSON)
zot export ABC123 # BibTeX export
zot workspace query "RLHF" --workspace my-ws # RAG searchCritical Rules
1. Always use `--json` for programmatic processing (auto-enabled when stdout is not a TTY). 2. Windows CJK encoding: On Windows with a CJK locale, recent zot versions auto-reconfigure stdout to UTF-8. For older versions or subprocess calls, set PYTHONIOENCODING=utf-8. See references/windows-encoding.md. 3. Write safety: Use --dry-run to preview mutations. Pass --idempotency-key on retries. 4. Large PDFs: Use --outline first, then --section N (the heading number from the outline) to extract selectively. Avoid pulling full text when >20k chars. 5. Workspace RAG index: Do not --force rebuild without user confirmation — it is slow. 6. Find Full Text: zot find-pdf KEY fetches paywalled PDFs but needs Zotero desktop running + the bridge plugin. One-time setup: zot bridge install. See references/commands.md. 7. Canonical schema: Run zot schema <cmd> for exhaustive flags, types, and safety tiers.
Routing Table
| User Intent | Command |
|---|---|
| Search metadata | zot --json search "query" |
| Read item detail | zot --json read KEY |
| Export BibTeX/RIS/JSON | zot export KEY --format bibtex |
| Formatted citation | zot cite KEY --style apa |
| Batch import DOIs | zot add --from-file dois.txt |
| Add single item | zot add --doi "10.1038/..." |
| Update metadata | zot update KEY --title "New" |
| Delete item | zot --no-interaction delete KEY |
| PDF full text | zot --json pdf KEY |
| PDF outline | zot --json pdf --outline KEY |
| PDF section | zot --json pdf --section N KEY |
| Fetch/attach missing PDF | zot find-pdf KEY (needs Zotero desktop + bridge) |
| Rename attachment files | zot rename KEY --dry-run (needs bridge; preview first) |
| Add journal metrics (IF/分区) | zot enrich KEY --set "JCR=Q1" or --from-map journals.toml |
| Set up find-pdf bridge | zot bridge install |
| Collection list | zot --json collection list |
| Collection items | zot --json collection items COLLKEY |
| Find duplicates | zot --json duplicates |
| Recent items | zot --json recent --days 7 |
| Library stats | zot --json stats |
| Workspace create | zot workspace new NAME |
| Workspace RAG query | zot workspace query "q" --workspace NAME |
| Ask (evidence pack) | zot --json ask "question" --workspace NAME |
| Group library | zot --library group:ID search "q" |
Rule of thumb: zot search for quick metadata lookups. zot workspace query for deep content search over curated papers. zot ask when you need a citation-keyed evidence pack to write a grounded answer — it returns chunks tagged with their Zotero item key plus answer_instructions; zot does not call an LLM, so you synthesize and cite the answer from the evidence.
Global Flags
| Flag | Purpose |
|---|---|
--json | JSON output (always use for programmatic processing) |
--limit N | Limit results (default: 50) |
--detail minimal | Only key/title/authors/year — saves tokens |
--detail full | All fields |
--no-interaction | Suppress prompts (automation) |
--verbose | Debug output |
Key Facts
- Read ops work offline with zero config
- Write ops need API credentials (
zot config init) - Item keys are 8-char alphanumeric strings (e.g.
K853PGUG) - Non-TTY stdout auto-emits JSON envelope — agents never need explicit
--json
References
references/commands.md— Full command reference with examplesreferences/workspaces.md— Workspace management and RAG deep divereferences/workflows.md— Common multi-step workflow patternsreferences/windows-encoding.md— Windows CJK encoding fix
Command Reference
Search & Browse
zot --json search "transformer attention"
zot --json search "BERT" --collection "NLP"
zot --json list --collection "Machine Learning" --limit 10
zot --json read ITEMKEY
zot --json relate ITEMKEYNotes & Tags
zot --json note ITEMKEY
zot note ITEMKEY --add "Key finding: ..."
zot --json tag ITEMKEY
zot tag ITEMKEY --add "important"
zot tag ITEMKEY --remove "to-read"Citation Export
zot export ITEMKEY # BibTeX (default)
zot export ITEMKEY --format csl-json # CSL-JSON
zot export ITEMKEY --format ris # RIS
zot export ITEMKEY --format json # Raw JSON
# Formatted citation (copies to clipboard)
zot cite ITEMKEY # APA (default)
zot cite ITEMKEY --style nature # Nature
zot cite ITEMKEY --style vancouver # VancouverItem Management (Write Ops)
zot add --doi "10.1038/s41586-023-06139-9"
zot add --url "https://arxiv.org/abs/2301.00001"
zot add --from-file dois.txt # Batch import (one DOI/URL per line)
zot add --pdf paper.pdf # Add from local PDF (auto-extract DOI)
zot --no-interaction delete ITEMKEY
zot update ITEMKEY --title "New Title"
zot update ITEMKEY --field volume=42 --field pages=1-10
zot attach ITEMKEY --file supplement.pdf # auto: bridge if desktop up (local), else cloud
zot attach ITEMKEY --file supplement.pdf --via-bridge # force LOCAL storage (needs Zotero desktop + bridge)
zot attach ITEMKEY --file supplement.pdf --no-via-bridge # force cloud (Web API); reports result=created|exists`zot attach` storage note. The default path uploads via the Web API into
zotero.org cloud storage — the file only appears in your local storage/after the desktop runs a file-sync (and "Sync attachment files" is enabled).
If you keep files locally (or use a mover like zotero-attanger) and the file
shows as "could not be found", use --via-bridge to import through the runningdesktop so the binary lands in local storage immediately.
Cleaning up orphaned attachments
When attachments show "the attached file could not be found" (file missing from local storage/), scan and clean them:
zot orphans list # classify: dead / recoverable / unknown
zot orphans list --dead-only # only ones with no copy anywhere
zot orphans clean --dry-run # preview (targets 'dead' only by default)
zot orphans clean --yes # delete dead orphans via the Web APIrecoverable orphans still have a server copy — run a Zotero file-sync to pull them down rather than deleting. clean --include-recoverable also deletes those (discards the cloud copy too), so use it with care.
Safety Flags
# Preview without writing — no API call
zot add --doi "10.1038/..." --dry-run
zot delete ITEMKEY --dry-run
zot update ITEMKEY --field volume=42 --dry-run
# Idempotency — safe retry after network failure
zot add --doi "10.1038/..." --idempotency-key abc-123
zot update ITEMKEY --title "X" --idempotency-key abc-124
zot attach ITEMKEY --file x.pdf --idempotency-key abc-125
zot delete ITEMKEY --yes --idempotency-key abc-126Find Full Text PDF (Zotero desktop bridge)
zot find-pdf triggers Zotero desktop's "Find Full Text", reusing the desktop's configured PDF resolvers AND its authenticated sessions / institutional proxies. This is the only way to reach paywalled PDFs from the CLI — the Zotero Web API cannot do it. Requires Zotero running with the zot-cli-bridge plugin installed.
zot find-pdf ITEMKEY # find & attach a PDF via desktop resolvers
zot find-pdf ITEMKEY --dry-run # only check the bridge is reachable
zot find-pdf ITEMKEY --timeout 180 # give slow resolvers more time
zot find-pdf ITEMKEY --library-id 42 # target a specific libraryOne-time bridge setup (enables find-pdf):
zot bridge install # build the plugin .xpi + print install steps
zot bridge install --output ~/zot-cli-bridge.xpi # choose where to write the .xpi
zot bridge status # check Zotero + plugin reachability
zot bridge uninstall # show how to remove the pluginzot bridge install builds the .xpi; you finish installation in Zotero via Tools -> Plugins -> gear -> Install Plugin From File (Zotero owns plugin installation, so the CLI cannot sideload silently).
Rename Attachment Files
zot rename renames an item's PDF attachment files from its metadata. Default template {journal}_{year}_{title}.pdf (tokens: {journal} {year} {title} {fulltitle} {shorttitle} {author}; {title} prefers Short Title when set). Non-PDF files (Excel/Word/snapshots) are skipped; supplementary PDFs are detected by filename and get an _SI suffix. Goes through the bridge plugin (needs v0.2.0+), so Zotero must be running.
zot rename ITEMKEY --dry-run # ALWAYS preview first: shows old -> new
zot rename ITEMKEY # rename main + supplementary PDFs
zot rename ITEMKEY1 ITEMKEY2 # several items at once
zot rename ITEMKEY --main-only # only the main PDF
zot rename ITEMKEY --template "{author}_{year}_{title}"
zot rename ITEMKEY --force # overwrite if the target name exists
zot rename --attachment ATTKEY --name "X.pdf" # rename one specific fileAlways `--dry-run` first so the user can confirm the new names before any files change.
Enrich with Journal Metrics
zot enrich writes journal metrics (impact factor, JCR/中科院 quartile, 北大/南大核心 flags, etc.) into an item's Extra field. Source-neutral: you supply the values (inline --set or a --from-map table you maintain); zot ships no journal data and calls no third-party API. Plain Web-API write (no bridge); needs API credentials.
zot enrich ITEMKEY --set "SCI IF=5.8" --set "JCR=Q1" --dry-run # preview first
zot enrich ITEMKEY --set "中科院分区=2区"
zot enrich ITEMKEY1 ITEMKEY2 --from-map journals.toml # apply table by journal name
zot enrich ITEMKEY --from-map journals.toml --set "JCR=Q1" # --set overrides the mapMetrics go in a <!-- zot:metrics --> block in Extra; re-running replaces only that block (idempotent) and preserves other Extra content. The --from-map file is TOML: a ["Journal Name"] table per journal with "metric" = "value" lines.
Collections
zot --json collection list
zot --json collection items COLLECTIONKEY
zot collection create "New Project"
zot collection move ITEMKEY COLLECTIONKEY
zot collection rename COLLECTIONKEY "New Name"
zot collection delete COLLECTIONKEYDuplicates, Recent & Trash
zot --json duplicates # DOI + title matching
zot --json duplicates --by title # Title-only matching
zot --json recent --days 7 # Recently added
zot --json recent --modified # Sort by date modified instead of date added
zot --json trash list # View trashed items
zot trash restore ITEMKEY # Restore from trashPDF & Summarization
zot --json pdf ITEMKEY # Full text extraction
zot --json pdf --outline ITEMKEY # Numbered section headings
zot --json pdf --section N ITEMKEY # Extract content under the N-th heading
zot pdf ITEMKEY --annotations # PDF annotations
zot --json summarize ITEMKEY
zot summarize-allToken-saving strategy: For large PDFs, use --outline to get section IDs first, then --section to extract only what you need.
Utilities
zot --json stats # Library statistics
zot open ITEMKEY # Open PDF in system viewer
zot open --url ITEMKEY # Open URL/DOI in browser
zot update-status --limit 20 # Check preprint publication status (needs S2_API_KEY)Group Library
zot --library group:12345 search "query"
zot --library group:12345 listAll commands support --library group:<id> to operate on group libraries.
Windows CJK Encoding Fix
Problem
zot is a Python/Click application. On Windows with a CJK system locale (Chinese, Japanese, Korean), stdout defaults to GBK/CP936 encoding. This causes two failures:
Failure 1: zot crashes on output
click.echo() encodes output as GBK. Unicode characters outside the GBK range (e.g. emoji ⛔ U+26D4) cause:
UnicodeEncodeError: 'gbk' codec can't encode character '⛔' in position 1061The JSON output never reaches stdout — the subprocess gets an empty result or a traceback.
Failure 2: subprocess decode error
Even when zot outputs GBK bytes successfully, Python's subprocess defaults to UTF-8 decoding:
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd6Solution (recent versions)
Recent zot releases auto-reconfigure stdout/stderr to UTF-8 on Windows when the system encoding is not UTF-8. No user action required.
Solution (older versions or subprocess calls)
Set PYTHONIOENCODING=utf-8 in the environment before invoking zot. This forces Python's stdin/stdout/stderr to use UTF-8, fixing both failures simultaneously.
Python subprocess
import subprocess, os
env = os.environ.copy()
env['PYTHONIOENCODING'] = 'utf-8'
result = subprocess.run(
['zot', '--json', 'search', 'query'],
capture_output=True,
env=env,
)
text = result.stdout.decode('utf-8')PowerShell
$env:PYTHONIOENCODING = "utf-8"
zot --json search "transformer"CMD
set PYTHONIOENCODING=utf-8
zot --json search "transformer"Persistent (recommended)
Set as a user environment variable so all new terminals inherit it:
[Environment]::SetEnvironmentVariable("PYTHONIOENCODING", "utf-8", "User")Why Not Other Approaches
| Approach | Problem |
|---|---|
chcp 65001 | Only changes the console code page, not Python's sys.stdout.encoding |
PowerShell Out-File -Encoding utf8 | PowerShell decodes zot's GBK output first, corrupting CJK characters |
result.stdout.decode('gbk') | Only fixes Failure 2; Failure 1 (zot crash) still produces no output |
Fallback Decoding
If PYTHONIOENCODING is not set and you are on an older version, use multi-stage decoding:
raw = result.stdout
try:
text = raw.decode('utf-8')
except UnicodeDecodeError:
text = raw.decode('gbk', errors='replace')Workflow Patterns
Pattern 1: Find and Read a Paper
# Step 1: Search
zot --json search "single cell RNA sequencing"
# Step 2: Read metadata
zot --json read K853PGUG
# Step 3: PDF — check structure first, extract selectively
zot --json pdf --outline K853PGUG # Get numbered section headings
zot --json pdf --section 10 K853PGUG # Extract only the section you need
zot --json pdf K853PGUG # Full text (only if short or necessary)Token budget: For PDFs >20k chars, always use --outline then --section instead of pulling full text.
No PDF attached? If zot pdf reports no attachment, run zot find-pdf K853PGUG to have Zotero desktop fetch and attach one (requires the bridge — see references/commands.md).
Pattern 2: Deep Content Search via Workspace RAG
# Step 1: Create workspace and populate
zot workspace new drug-resistance --description "Cancer drug resistance mechanisms"
zot --json search "drug resistance cancer" --limit 20
zot workspace add drug-resistance KEY1 KEY2 KEY3
# Step 2: Build index
zot workspace index drug-resistance
# Step 3: Query
zot --json workspace query "mechanisms of acquired resistance" --workspace drug-resistance --top-k 5
# Step 4: Drill into specific chunks for more context
zot --json pdf --outline ITEMKEY
zot --json pdf --section N ITEMKEYPattern 3: Batch Export from Collections
import subprocess, json, os
env = os.environ.copy()
env['PYTHONIOENCODING'] = 'utf-8' # Required on Windows CJK systems (older versions)
collections = {
'topic_a': 'COLLKEY1',
'topic_b': 'COLLKEY2',
}
for name, key in collections.items():
result = subprocess.run(
['zot', '--json', 'collection', 'items', key],
capture_output=True, env=env,
)
if result.returncode != 0:
print(f'{name}: error - {result.stderr.decode("utf-8", errors="replace")}')
continue
data = json.loads(result.stdout.decode('utf-8'))
with open(f'batch_{name}.json', 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=2)
print(f'{name}: {data["meta"]["count"]} items')Pattern 4: Library Reorganization
# Step 1: Export all abstracts
zot --json summarize-all > abstracts.json
# Step 2: Analyze and classify (AI or manual)
# Step 3: Create collections and move items
zot collection create "Category A"
zot collection move ITEMKEY COLLECTIONKEYPattern 5: Literature Review Pipeline
# 1. Import papers from DOI list
zot add --from-file dois.txt
# 2. Organize into workspace
zot workspace new lit-review --description "Systematic review papers"
zot workspace import lit-review --tag "review-candidate"
# 3. Build index for deep search
zot workspace index lit-review
# 4. Query for themes
zot --json workspace query "methodology comparison" --workspace lit-review --top-k 10Workspaces & RAG
Workspaces are local topic-based paper collections for organizing research. Each workspace stores item keys in a TOML file (~/.config/zot/workspaces/<name>.toml) — no Zotero API needed.
Workspace Management
# Create
zot workspace new llm-safety --description "LLM alignment and safety papers"
# Add/remove items
zot workspace add llm-safety KEY1 KEY2 KEY3
zot workspace remove llm-safety KEY1
# List and inspect
zot workspace list
zot --json workspace list
zot workspace show llm-safety
# Delete
zot workspace delete llm-safety --yesBulk Import
zot workspace import llm-safety --collection "Alignment"
zot workspace import llm-safety --tag "safety"
zot workspace import llm-safety --search "RLHF"Search Within Workspace
Metadata substring match (no index required):
zot workspace search "reward" --workspace llm-safety
zot --json workspace search "attention" --workspace llm-safetyExport
zot workspace export llm-safety # Markdown (default)
zot workspace export llm-safety --format json # JSON
zot workspace export llm-safety --format bibtex # BibTeXRAG Index
zot workspace index llm-safety # Incremental index
zot workspace index llm-safety --force # Full rebuild (slow — confirm with user first)
zot workspace index llm-safety --skip-tag skip-index # Skip PDFs carrying this tag (default: skip-index)Attachments tagged skip-index are skipped by default. Use --skip-tag to change which tag(s) are excluded — useful for keeping huge or irrelevant PDFs out of the index. Tag a PDF skip-index in Zotero to exclude it.
Important: Never --force rebuild without user confirmation. Incremental indexing is usually sufficient.
RAG Query
zot workspace query "reward hacking" --workspace llm-safety
zot workspace query "RLHF methods" --workspace llm-safety --top-k 10
zot --json workspace query "attention" --workspace llm-safetyRetrieval Modes
--mode bm25 # Keyword only (always available, zero deps)
--mode semantic # Embeddings only (requires ZOT_EMBEDDING_URL + ZOT_EMBEDDING_KEY)
--mode hybrid # BM25 + semantic fusion (auto-selected if embeddings available)Chunk Format
RAG results return chunks structured as:
{
"rank": 1,
"score": 0.0154,
"item_key": "B6TZ6TQX",
"source": "pdf",
"content": "[Title > Section Heading] chunk text..."
}Reading More Context from Chunks
When a chunk is incomplete, drill into the source:
zot --json pdf --outline ITEMKEY # Get numbered section headings
zot --json pdf --section N ITEMKEY # Extract content under the N-th headingConfiguration
- BM25: always available, zero additional dependencies
- Semantic search: set
ZOT_EMBEDDING_URLandZOT_EMBEDDING_KEYenvironment variables
Related skills
FAQ
What does zot ask return?
A citation-keyed evidence pack of chunks tagged with their Zotero item key plus answer_instructions; zot does not call an LLM, so the agent synthesizes and cites the answer.
Do read operations need setup?
No. Read ops work offline with zero config; write ops need API credentials via zot config init.