## Implement: biblio zotero pull — read items + PDFs from Zotero via API¶
Phase
Goal¶
(promoted from note)
Context¶
(see source note)
Prompt¶
Fix the issue described in /storage2/arash/projects/projio/docs/log/issue/issue-arash-20260403-210002-675833.md. Read it first, then implement the proposed fix.
Acceptance Criteria¶
- [ ]
Result¶
Completed in 432.4s (1 steps, model: opus)
Session: e7558a52-7468-42cd-9b68-bd33dd727fcf
Result note: /storage2/arash/worklog/workflow/captures/20260403-211239-6ebcdb/note.md
Output¶
Everything is in place. Here's what was implemented:
## Summary
Implemented **Phase 1: `biblio zotero pull`** — read-only pull with incremental sync from Zotero.
### Files created
- **`packages/biblio/src/biblio/zotero.py`** — Core module with:
- `ZoteroConfig` / `load_zotero_config()` — config from `zotero:` section in biblio.yml
- `SyncState` — load/save `.projio/biblio/zotero_sync.yml` for version-based incremental sync
- `ZoteroClient` — thin pyzotero wrapper (item_versions, fetch_items, fetch_attachment, deleted_since)
- `item_to_bibtex()` — Zotero JSON → BibTeX conversion with type mapping
- `pull()` — orchestrator: fetch changed items → write `bib/srcbib/zotero.bib` → download PDFs → handle deletions → update state → log
- `status()` — return sync state for display
### Files modified
- **`packages/biblio/pyproject.toml`** — Added `zotero = ["pyzotero>=1.6"]` optional dep
- **`packages/biblio/src/biblio/cli.py`** — Added `biblio zotero pull` and `biblio zotero status` subcommands
- **`packages/biblio/src/biblio/mcp.py`** — Added `zotero_pull()` and `zotero_status()` MCP wrappers
- **`src/projio/mcp/biblio.py`** — Added `biblio_zotero_pull()` and `biblio_zotero_status()` tool functions
- **`src/projio/mcp/server.py`** — Registered `biblio_zotero_pull` and `biblio_zotero_status` tools
## Next Steps
1. Run `biblio zotero pull --dry-run` against a real Zotero library to validate the end-to-end flow (requires `zotero:` section in biblio.yml and `pip install pyzotero`).
2. Update CLAUDE.md's MCP tool table and biblio.py docstring to document the new `biblio_zotero_pull` and `biblio_zotero_status` tools.
3. Implement Phase 2 (`biblio zotero push`) for writing tags, notes, and DOI/OpenAlex IDs back to Zotero.