# Send Zotero to your agent
Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.
## Fast path
- Download the package from Yavira.
- Extract it into a folder your agent can access.
- Paste one of the prompts below and point your agent at the extracted folder.
## Suggested prompts
### New install

```text
I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete.
```
### Upgrade existing

```text
I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run.
```
## Machine-readable fields
```json
{
  "schemaVersion": "1.0",
  "item": {
    "slug": "zotero",
    "name": "Zotero",
    "source": "tencent",
    "type": "skill",
    "category": "开发工具",
    "sourceUrl": "https://clawhub.ai/Terwox/zotero",
    "canonicalUrl": "https://clawhub.ai/Terwox/zotero",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadUrl": "/downloads/zotero",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=zotero",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "packageFormat": "ZIP package",
    "primaryDoc": "SKILL.md",
    "includedAssets": [
      "EVAL.md",
      "SKILL.md",
      "references/troubleshooting.md",
      "scripts/zotero.py"
    ],
    "downloadMode": "redirect",
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-05-07T17:22:31.273Z",
      "expiresAt": "2026-05-14T17:22:31.273Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=afrexai-annual-report",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=afrexai-annual-report",
        "contentDisposition": "attachment; filename=\"afrexai-annual-report-1.0.0.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/zotero"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    }
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/zotero",
    "downloadUrl": "https://openagent3.xyz/downloads/zotero",
    "agentUrl": "https://openagent3.xyz/skills/zotero/agent",
    "manifestUrl": "https://openagent3.xyz/skills/zotero/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/zotero/agent.md"
  }
}
```
## Documentation

### Zotero Skill

Interact with Zotero personal or group libraries via the REST API v3.

### Setup

Requires two environment variables:

ZOTERO_API_KEY   — Create at https://www.zotero.org/settings/keys/new
ZOTERO_USER_ID   — Found on the same page (numeric, not username)

For group libraries, set ZOTERO_GROUP_ID instead of ZOTERO_USER_ID.

Optional env var for CrossRef/Unpaywall polite pool (improves DOI lookup success rate):

CROSSREF_EMAIL   — Your email (optional; uses fallback if unset)

If credentials are missing, tell the user what's needed and link them to the key creation page.

### CLI Script

All operations use scripts/zotero.py (Python 3, zero external dependencies).

python3 scripts/zotero.py <command> [options]

### Commands

CommandDescriptionExampleitemsList top-level itemszotero.py items --limit 50searchSearch by queryzotero.py search "cognitive load"getFull item details + attachmentszotero.py get ITEMKEYcollectionsList all collectionszotero.py collectionstagsList all tagszotero.py tagschildrenList attachments/notes for itemzotero.py children ITEMKEYadd-doiAdd item by DOI (dedup enabled)zotero.py add-doi 10.1234/exampleadd-isbnAdd item by ISBN (dedup enabled)zotero.py add-isbn 978-0-123456-78-9add-pmidAdd item by PubMed IDzotero.py add-pmid 12345678deleteMove items to trash (recoverable by default)zotero.py delete KEY1 KEY2 --yesupdateModify item metadata/tagszotero.py update KEY --add-tags "new"exportExport as BibTeX/RIS/CSL-JSONzotero.py export --format bibtexbatch-addAdd multiple items from filezotero.py batch-add dois.txt --type doicheck-pdfsReport which items have/lack PDFszotero.py check-pdfscrossrefMatch citations vs libraryzotero.py crossref bibliography.txtfind-doisFind & add missing DOIs via CrossRefzotero.py find-dois --limit 10fetch-pdfsFetch open-access PDFs for itemszotero.py fetch-pdfs --dry-run

### Global Flags

--json — JSON output instead of human-readable (works with items, search, get)

### Common Options

--limit N — Max items to return (default 25)
--sort FIELD — Sort by dateModified, title, creator, date
--direction asc|desc — Sort direction
--collection KEY — Filter by or add to collection
--type TYPE — Filter by item type (journalArticle, book, conferencePaper, etc.)
--tags "tag1,tag2" — Add tags when creating items
--force — Skip duplicate detection on add commands

### Add a paper by DOI

python3 zotero.py add-doi "10.1093/jamia/ocaa037" --tags "review"
# Warns if already in library. Use --force to override.

Duplicate detection: translates DOI to metadata, searches library by first author, compares DOI fields.

### Bulk add from a file

# One identifier per line, # for comments
python3 zotero.py batch-add dois.txt --type doi --tags "imported"

Skips duplicates. Reports summary: added/skipped/failed.

### Export bibliography

python3 zotero.py export --format bibtex --output refs.bib
python3 zotero.py export --format csljson --collection COLLKEY

### Update tags/metadata

python3 zotero.py update ITEMKEY --add-tags "important" --remove-tags "unread"
python3 zotero.py update ITEMKEY --title "Corrected Title" --date "2024"
python3 zotero.py update ITEMKEY --doi "10.1234/example"
python3 zotero.py update ITEMKEY --url "https://example.com/paper"
python3 zotero.py update ITEMKEY --add-collection COLLKEY

### Delete items

python3 zotero.py delete KEY1 KEY2 --yes           # Trash (recoverable, default)
python3 zotero.py delete KEY1 --permanent --yes    # Permanent delete

### Cross-reference citations

python3 zotero.py crossref my-paper.txt

Extracts Author (Year) patterns from text and matches against library.

### Find missing DOIs

# Dry run (default) — show matches without writing anything
python3 zotero.py find-dois --limit 20

# Actually write DOIs to Zotero
python3 zotero.py find-dois --apply

# Filter by collection
python3 zotero.py find-dois --collection COLLKEY --apply

Scans journalArticle and conferencePaper items missing DOIs, queries CrossRef, and matches
by title similarity (>85%), exact year, and first author last name. Dry run by default — use
--apply to write. Only patches the DOI field; never touches other metadata. 1s delay between
CrossRef requests (polite pool with mailto).

### Fetch open-access PDFs

# Dry run — show which PDFs are available and from where
python3 zotero.py fetch-pdfs --dry-run --limit 10

# Fetch and attach as linked URLs (no storage quota used)
python3 zotero.py fetch-pdfs --limit 20

# Also save PDFs locally
python3 zotero.py fetch-pdfs --download-dir ./pdfs

# Upload to Zotero storage instead of linked URL
python3 zotero.py fetch-pdfs --upload --limit 10

# Only try specific sources
python3 zotero.py fetch-pdfs --sources unpaywall,semanticscholar

Tries three legal OA sources in order: Unpaywall → Semantic Scholar → DOI content negotiation.
By default creates linked URL attachments (no Zotero storage quota needed). Use --upload for
full S3 upload to Zotero storage. Use --download-dir to also save PDFs locally.

Sources: unpaywall, semanticscholar, doi (default: all three)

Rate limits: 1s between Unpaywall/Semantic Scholar requests, 2s between DOI requests.

### Scripting with JSON

python3 zotero.py --json items --limit 100 | jq '.items[].DOI'
python3 zotero.py --json get ITEMKEY | jq '.title'

### Notes

Zero dependencies — Python 3 stdlib only (urllib, json, argparse)
Write operations require an API key with write permissions
If Zotero translation server is down (503), DOI lookups fall back to CrossRef
Input validation: DOIs must be 10.xxxx/... format. Item keys are 8-char alphanumeric (e.g., VNPN6FHT). ISBNs must be valid checksums.
check-pdfs fetches all items; for large libraries (500+), this may be slow
fetch-pdfs also processes all items — use --collection to scope for large libraries
Rate limits are generous; batch-add includes 1s delay between items
For common errors and troubleshooting, see references/troubleshooting.md
## Trust
- Source: tencent
- Verification: Indexed source record
- Publisher: Terwox
- Version: 1.0.0
## Source health
- Status: healthy
- Source download looks usable.
- Yavira can redirect you to the upstream package for this source.
- Health scope: source
- Reason: direct_download_ok
- Checked at: 2026-05-07T17:22:31.273Z
- Expires at: 2026-05-14T17:22:31.273Z
- Recommended action: Download for OpenClaw
## Links
- [Detail page](https://openagent3.xyz/skills/zotero)
- [Send to Agent page](https://openagent3.xyz/skills/zotero/agent)
- [JSON manifest](https://openagent3.xyz/skills/zotero/agent.json)
- [Markdown brief](https://openagent3.xyz/skills/zotero/agent.md)
- [Download page](https://openagent3.xyz/downloads/zotero)