← Back to home@wolfsonliu

zotero-skill

An agent-usable Zotero skill for AI agent — search, read, and write your local Zotero library through a single Python CLI. | 面向 AI Agent 的 Zotero 技能:通过单一 Python CLI 搜索、读取、写入本地 Zotero 文献库。

Stars
0
Language
Python
Created
Aug 25, 2026
Updated
Sep 17, 2026

Introduction

zotero skill

English | 中文

Agent skill for read/write access to the local Zotero library.

Install

install.sh copies just the runtime bundle (SKILL.md, scripts/, references/, plus LICENSE/README where present) into an agent tool's skills directory — no git history, dev files, or caches. It needs only bash + POSIX tools.

./install.sh                 # DeepSeek Harness, global: ~/.dsh/skills/zotero

Pick the agent tool, scope, and method:

./install.sh --tool opencode             # ~/.config/opencode/skills/zotero
./install.sh --tool claude               # ~/.claude/skills/zotero
./install.sh --tool codex                # ~/.agents/skills/zotero ("agents" convention)
./install.sh --tool all                  # install to every tool above (global only)

./install.sh --scope local               # <project>/.dsh/skills/zotero
./install.sh --scope local --project ~/src/foo
./install.sh --tool claude --scope local # <project>/.claude/skills/zotero

./install.sh --method symlink            # symlink the checkout (live; git pull = update)
./install.sh --update                    # re-copy over an existing install
./install.sh --force                     # remove and reinstall

./install.sh --list      # print the tool -> directory table
./install.sh --dry-run   # preview without writing
ToolGlobalLocal (project)
dsh~/.dsh/skills.dsh/skills
opencode~/.config/opencode/skills.opencode/skills
claude~/.claude/skills.claude/skills
codex/agents~/.agents/skills.agents/skills

--project defaults to the nearest .git ancestor of the current directory (the DSH/OpenCode project-root convention). Global dirs honour DSH_HOME, DSH_AGENTS_HOME, and XDG_CONFIG_HOME. The agents directory (~/.agents/skills, .agents/skills) is the shared cross-tool location, also read by OpenCode and DeepSeek Harness.

Then:

  1. Install/update Zotero 10+.
  2. Enable the local API: Settings > Advanced > "Allow other applications on this computer to communicate with Zotero".
  3. Run the one-time setup: python3 scripts/zotero.py init.

Optional env vars (overrides): ZOTERO_DATA_DIR, ZOTERO_LOCAL_API_URL (default http://localhost:23119/api), ZOTERO_APP_NAME (name shown in the authorization dialog, default zotero-skill).

First time use

A step-by-step walkthrough for the first run on a new machine.

  1. Check Python — python3 --version (3.9+; only the standard library is used).

  2. Install Zotero 10+ and turn on its Local API — Settings > Advanced, then tick "Allow other applications on this computer to communicate with Zotero".

  3. Configure (one command) — with Zotero running, run

    python3 scripts/zotero.py init
    

    It auto-detects the data directory (reads extensions.zotero.dataDir from the profile's prefs.js, else falls back to ~/Zotero), writes ~/.config/zotero-skill/settings.json, and triggers the authorization dialog — click Always Allow to cache the write key. Check the result with python3 scripts/zotero.py config.

  4. Verify reads — with Zotero running:

    python3 scripts/zotero.py health          # ok:true, version 10.x, writesSupported:true
    python3 scripts/zotero.py search "protein folding"
    

    The data directory only matters for the SQLite fallback (recent, fulltext-words, attachments, and doi only when Zotero is closed) and for locating saved PDFs; metadata reads (including doi while Zotero is running) go through the Local API.

  5. Authorize writes (one time) — init caches the key, so a write usually needs no dialog. If you skipped it (init --no-auth), the first write pops the dialog; click Always Allow so the key is saved and reused. The key is cached at ~/.config/zotero-skill/state.json (mode 0600, keyed by Zotero server ID).

    python3 scripts/zotero.py create-item --type journalArticle --title "My first item"
    

    If you click Deny, writes fail with a clear error. Re-trigger authorization anytime with python3 scripts/zotero.py auth.

  6. Add your first note (overview/summary of a paper):

    python3 scripts/zotero.py add-note --parent <itemKey> --note "# Overview\n\nSummary."
    

Usage

python3 scripts/zotero.py health
python3 scripts/zotero.py search "protein folding"
python3 scripts/zotero.py read <attachmentKey> --text
python3 scripts/zotero.py create-item --type journalArticle --title "T" --doi "10.1/x"
python3 scripts/zotero.py count --collection "Project/bioq"
python3 scripts/zotero.py count --tag Harness
python3 scripts/zotero.py count --query "protein folding"
python3 scripts/zotero.py export --collection "Project/bioq" --format bibtex --output refs.bib

init pre-caches the write key, so a write usually needs no dialog. If you skipped init --no-auth, the first write asks you to click Always Allow in Zotero's dialog; the key is cached at ~/.config/zotero-skill/state.json (mode 0600, keyed by Zotero server ID).

Test

python3 -m unittest discover -s tests -v

License

MIT — see LICENSE.