AgentStack
SKILL unreviewed MIT Self-run

Setup Zotero References

skill-benjibromberg-zotero-context-setup-zotero-references · by benjibromberg

Use when the user wants to configure Zotero references for the current project, when they say "set up zotero", "configure zotero references", "/zotero-context:setup-zotero-references", or when starting a new project that should reference a Zotero library

No reviews yet
0 installs
0 views
view→install

Install

$ agentstack add skill-benjibromberg-zotero-context-setup-zotero-references

Open-source listing — not yet scanned by AgentStack. Follow the source repository for install instructions.

Security review

⚠ Flagged

1 finding(s); flagged for manual review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures
  • high Pipes remote content directly into a shell (remote code execution).

What it can access

  • Network access Used
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Setup Zotero References? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Setup Zotero References

Overview

One-time bootstrap: ensures uv is available, lists the user's Zotero libraries, prompts which to scope to this project, samples each chosen library, derives trigger keywords + a one-line description per library, vendors the search scripts into the repo, and renders the deployed using-zotero-references skill with the project-specific keywords.

After this skill runs, future Claude sessions in this repo will auto-trigger using-zotero-references for project-relevant topics and call .zotero-context/bin/search_items.py for reference lookups. Each vendored script is a PEP 723 self-contained inline-metadata script — uv reads its dependency declaration and provisions an isolated environment on first invocation. The user does NOT need to install pyzotero globally.

When to Use

  • User says "set up zotero", "configure zotero references", "/zotero-context:setup-zotero-references"
  • User asks how to make a Zotero library available to Claude in this project
  • User wants to scope new libraries to an existing .zotero-context/ config

Workflow

Run these steps sequentially. Stop after each user prompt and wait for input.

Step 0: Check for uv

The vendored scripts use uv to manage their Python dependencies (no global pip install required). Detect it:

command -v uv

If uv is found, proceed to Step 1.

If uv is not found, ask the user:

> The vendored Zotero scripts use uv (from Astral) to manage Python dependencies, so we don't have to install pyzotero globally. The official one-line installer is: > > ``bash > curl -LsSf https://astral.sh/uv/install.sh | sh > ` > > This is the install method recommended by the uv docs and matches the pattern used by rustup, nvm, bun, and homebrew`. Install it now? [y/N]

If the user confirms, run:

curl -LsSf https://astral.sh/uv/install.sh | sh

Then verify:

uv --version

If uv is still not on $PATH, point the user at the installer's output (it usually prints a source $HOME/.local/bin/env line) and ask them to restart their shell or source that file before re-running this skill.

If the user declines, stop here — the plugin requires uv to run the vendored scripts.

Step 1: Connectivity check

curl -s -o /dev/null -w "%{http_code}" http://localhost:23119/api/users/0/groups
  • If 200: local API works. Proceed.
  • Else: check .env for ZOTERO_API_KEY. If absent, print:

> Zotero is not reachable. Either start Zotero desktop (preferences → advanced → "Allow other applications") or add ZOTERO_API_KEY=... to .env. Re-run when ready. Then stop.

Step 2: List libraries

${CLAUDE_SKILL_DIR}/../../scripts/list_libraries.py

(${CLAUDE_SKILL_DIR} is the absolute path of this skill's directory, provided by Claude Code. The plugin root is two levels up.) The script's #!/usr/bin/env -S uv run --script shebang causes uv to provision a one-shot venv on first invocation (cached for subsequent runs).

Display the JSON to the user as a numbered list:

1. Personal — 73 items (user/12345)
2. Benji's Cell Ag Library — 187 items (group/5178481)
3. Methods Reading — 42 items (group/9999)

Step 3: Library selection

Ask the user which libraries to scope to this project (multi-select by number, comma-separated). Save the chosen IDs and types.

> Note: If the user picks the personal library and ZOTERO_API_KEY is not yet set, the stored library_id will be 0 (a local-only convention). This breaks web-API fallback when Zotero desktop is closed. Remind the user that adding ZOTERO_API_KEY to .env before or after setup lets list_libraries.py resolve a portable numeric user ID that works with both APIs.

Step 4: Sample fetch + keyword analysis

For each chosen library:

${CLAUDE_SKILL_DIR}/../../scripts/sample_library.py --lib  --type {user|group} --limit 30

(sample_library.py bypasses config loading, so it is safe to call before Step 5 writes config.json.)

Read the sample output. You (the running Claude session) propose:

  • 8–15 domain keywords representing the library's topical focus (no generic terms like "research", "paper").
  • A 1–2 sentence description of the library suitable for CLAUDE.md.

Show your proposal to the user:

For library "Benji's Cell Ag Library":

Description: Curated cellular agriculture literature spanning precision fermentation, scaffold biomaterials, and cultivated meat process development.

Trigger keywords:
- cellular agriculture
- precision fermentation
- ...

Wait for user edits/approval before proceeding.

Step 5: Write .zotero-context/config.json

Combine all libraries' descriptions and union all keywords into one project-level list (deduped).

{
  "version": 1,
  "libraries": [
    {"id": 5178481, "type": "group", "name": "Benji's Cell Ag Library", "description": "..."},
    ...
  ],
  "trigger_keywords": ["cellular agriculture", "precision fermentation", ...],
  "defaults": {
    "include_notes": true,
    "include_annotations": true,
    "output": "full"
  }
}

Step 6: Vendor scripts

mkdir -p .zotero-context/bin
cp ${CLAUDE_SKILL_DIR}/../../scripts/{common,zotero_client,list_libraries,search_items,get_item,enrich_abstract,sample_library}.py .zotero-context/bin/
chmod +x .zotero-context/bin/{list_libraries,search_items,get_item,enrich_abstract,sample_library}.py

The five entry-point scripts are made executable so the deployed skill can invoke them directly via shebang. common.py and zotero_client.py are imported as modules by the others and don't need to be executable.

Step 7: Render the deployed skill

Read ${CLAUDE_SKILL_DIR}/../../templates/using-zotero-references/SKILL.md.template. Substitute:

  • {{KEYWORDS}} → comma-joined trigger_keywords from config.
  • {{LIBRARY_DESCRIPTIONS}} → bullet list, one per library: - {name}: {description}.

Write the result to .claude/skills/using-zotero-references/SKILL.md.

Step 8: Gitignore

  • Always: ensure .env is in .gitignore. If absent, add it.
  • Prompt: "Should .zotero-context/ be gitignored? Default is no — committing it makes the repo self-contained for collaborators and future worktrees. (y/N)"
  • If yes, add .zotero-context/ to .gitignore.

Step 9: CLAUDE.md update

Append (or update an existing managed block):


## Zotero References

This project uses the `using-zotero-references` skill to look up curated literature in:

- {library 1 name}: {description}
- {library 2 name}: {description}

The skill auto-triggers on project-relevant topics and calls `.zotero-context/bin/search_items.py` (a self-contained `uv run --script` shebang). Run `/zotero-context:enrich-zotero-abstracts` to fix items with missing abstracts.

If the block already exists, replace it; otherwise append at the end of CLAUDE.md (or AGENTS.md if CLAUDE.md doesn't exist).

Step 10: Smoke test

.zotero-context/bin/search_items.py --query "" --limit 2

The first invocation triggers uv to install pyzotero into a script-scoped cache (~5MB, one-time). Show the user the JSON output and confirm setup is working.

Idempotency

When .zotero-context/config.json already exists, offer:

  • Add libraries — re-list, multi-select additions, re-derive keywords for new ones, merge into config.
  • Refresh keywords — re-sample chosen libraries, re-propose, replace trigger_keywords and re-render the deployed skill.
  • Re-vendor scripts — copy latest plugin scripts to .zotero-context/bin/ (use this after the plugin updates).

Never silently overwrite — confirm action with user.

Common Mistakes

  • Skipping Step 0 (uv check) — vendored scripts will fail with env: 'uv': No such file or directory if uv isn't on $PATH.
  • Skipping Step 4 and using library names as keywords. Library names are vague; sample-derived keywords trigger more reliably.
  • Hand-editing .claude/skills/using-zotero-references/SKILL.md and losing the changes on next setup re-run. Edit the template instead, then re-render.
  • Forgetting Step 6 (vendoring) — the deployed skill expects scripts at .zotero-context/bin/.
  • Forgetting Step 6's chmod +x — without the executable bit the shebang doesn't fire and Claude gets a "Permission denied" error.

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.