Claude-Guardian
Claude Guardian is an all-in-one Claude account safety and risk prevention skill. It intelligently assesses your device, account history, network environment, and payment options, then provides person
A skill for managing Zotero references programmatically — search, add, classify, annotate, and organize literature.
SkillsPythonGitHub @WenyuChiouSelf-installOwner unconfirmed
Paste into Claude or ChatGPT for installation instructions suited to your environment.
Have you tried it? One tap is enough. No sign-in needed.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Installable projects can be verified without a deployment domain. Use GitHub sign-in for a personal repository, or the repository verification file above for an organization repository.
Ask about other verification options
Loading the full README. The saved excerpt is shown below.
Zotero Skills — AI Coding Assistant Skill for Zotero CRUD
Comprehensive Zotero library management via dual-API architecture (local read + web write). Works with any AI coding assistant that supports skills or custom instructions.
📚 Part of the agentic AI learning roadmap — a 7-stage curated path for building agentic AI, multilingual (zh-TW · zh-CN · English). This skill is referenced in §13 (research workflow skills).Read the full README ↗Comprehensive Zotero library management via dual-API architecture (local read + web write). Works with any AI coding assistant that supports skills or custom instructions.
📚 Part of the agentic AI learning roadmap — a 7-stage curated path for building agentic AI, multilingual (zh-TW · zh-CN · English). This skill is referenced in §13 (research workflow skills).
A skill that gives AI coding assistants full CRUD access to your Zotero library. Search, add, classify, annotate, and organize references programmatically — all from your terminal.
See Features below for the full list.
Beyond standard CRUD, this skill does four things an AI agent often wrongly calls impossible:
~/.claude/.env, then config.json. Call credentials_status() to check which one is set (booleans and a source label only, never the value) instead of opening those files yourself.ZoteroDualClient.merge_duplicates() reproduces the core of a desktop merge (move every child, union collections/tags/relations, add a dc:replaces relation, then trash the duplicate, recoverable with restore_item()).attachment_simple fail silently. ZoteroDualClient.attach_pdf() copies to a short, safe, zot_-prefixed filename first and raises the failed-upload template pyzotero returns (it does not expose a deeper server reason) instead of staying silent.See the capability table in skills/zotero-skills/SKILL.md for the full list and what each one does not cover.
safe_api_call() wrapper prevents API quota violationszotero_client.py directly in any Python projectpip install pyzotero.env fileThe shared client resolves credentials in this order: environment variables → ~/.claude/.env → config.json. The simplest, safest way is a single file — create ~/.claude/.env and paste three lines:
ZOTERO_API_KEY=your_key_here
ZOTERO_LIBRARY_ID=your_library_id
ZOTERO_LIBRARY_TYPE=user
That's it — no code, works everywhere, and nothing to commit. (Setting the same three as shell environment variables works too.)
A stale OS-level credential overrides
~/.claude/.env. Diagnose the resolved source withcredentials_status(); never echo the API key, paste it into a chat, or open credential files for an agent. Review any change to credentials or persistent access yourself.
From the repository root (or the resolved marketplace plugin root), this read-only diagnostic prints presence and source labels without credential values:
python -c "from scripts.zotero_client import credentials_status; print(credentials_status())"
config.json still works but is deprecated — it emits a DeprecationWarning at runtime. It is gitignored so it is never committed. Prefer ~/.claude/.env; use this only if you cannot set env vars:
cp config.example.json config.json # then fill in your key + library id
{ "zotero_api_key": "YOUR_API_KEY", "zotero_library_id": "YOUR_LIBRARY_ID", "zotero_library_type": "user" }
Never commit credentials.
Install via the ai-research-skills Claude Code marketplace:
claude plugin marketplace add WenyuChiou/ai-research-skills
claude plugin install zotero-skills@ai-research-skills --scope user
Migrating from a previous
cp -r/git cloneinstall? SKILL.md moved from the repo root toskills/zotero-skills/SKILL.mdfor marketplace auto-discovery. The oldcp -r zotero-skills/ ~/.claude/skills/zotero-skills/layout no longer loads (Claude Code scans only one level deep). Remove the old copy (rm -rf ~/.claude/skills/zotero-skills) and run the marketplace install above.
This skill was developed for Claude Code but works with any AI assistant.
| CLI | How to load the skill |
|---|---|
| Claude Code | Place in ~/.claude/skills/ or .claude/skills/ — auto-loaded |
| Codex CLI | Load the inner skills/zotero-skills/SKILL.md through skills discovery or task context; -C / --cd selects the working directory, not a context file |
| Gemini CLI | Include SKILL.md in system prompt or project context |
| Cursor / Windsurf | Add SKILL.md to .cursor/rules or equivalent rules file |
| Any other tool | Paste relevant sections of SKILL.md into your system prompt |
zotero-skills/
├── .claude-plugin/plugin.json # Marketplace manifest
├── config.example.json # Template for API credentials
├── config.json # Your credentials (gitignored — never committed)
├── requirements.txt # pyzotero dependency
├── LICENSE # MIT
├── scripts/
│ ├── zotero_client.py # ZoteroDualClient + helpers
│ └── add_literature.py # Batch import script template
├── skills/zotero-skills/
│ ├── SKILL.md # Agent operating rules
│ └── references/ # api-setup, read/create/update/delete-operations,
│ └── ... # error-handling, endpoint-cheatsheet, api-reference, item-types
├── README.md # English
└── README_zh-TW.md # 繁體中文
Zotero exposes two APIs with different capabilities. This skill routes automatically.
Local API (localhost:23119) | Web API (api.zotero.org) | |
|---|---|---|
| Access | Requires Zotero desktop running | Works anywhere |
| Read | ✅ Fast, full-text search | ✅ Standard queries |
| Write | ❌ Not supported (501) | ✅ Full CRUD |
| Rate limit | None | ~100 req / 10 sec (dynamic; honor Backoff/Retry-After headers) |
| Auth | Zotero-Allowed-Request: true header | Zotero-API-Key: <key> header |
On initialization, ZoteroDualClient calls check_local_api() — a lightweight GET to localhost:23119.
from scripts.zotero_client import ZoteroDualClient
dual = ZoteroDualClient()
# dual.local_available → True if Zotero desktop running, False otherwise
results = dual.search("flood adaptation") # local API if available
dual.create_note("ITEM_KEY", "Section", "Notes...") # always web API
ZOTERO_LOCAL=true, its write tools will fail — use zotero_client.py for writesFrom scripts/zotero_client.py:
| Function | Description |
|---|---|
get_client() | Configured pyzotero.Zotero Web API instance |
get_collection(name) | Find collection key by display name from config.json |
add_note(zot, item_key, content) | Attach a child note to a library item |
check_duplicate(zot, title, doi) | Check if item with given title or DOI exists |
check_local_api(timeout, library_id) | Test if Zotero desktop local API is reachable |
ZoteroDualClient | Dual-API wrapper — local reads, web writes, auto-fallback |
safe_api_call(func) | API call wrapper with automatic rate-limit backoff |
Run from the repository/plugin root, which contains scripts/. A portable
SKILL.md copy alone does not include the shared client.
from scripts.zotero_client import ZoteroDualClient
dual = ZoteroDualClient()
print(f"Local API available: {dual.local_available}")
results = dual.search("flood risk perception")
dual.create_note("I3P2J58S", "Section 2", "<p>Discusses PMT framework.</p>")
from pyzotero import zotero
zot = zotero.Zotero("YOUR_LIBRARY_ID", "user", "YOUR_API_KEY")
template = zot.item_template("journalArticle")
template["title"] = "Deep Learning for NLP: A Survey"
template["creators"] = [{"creatorType": "author", "firstName": "Jane", "lastName": "Doe"}]
template["publicationTitle"] = "Nature Machine Intelligence"
template["date"] = "2025"
template["DOI"] = "10.1038/s42256-025-00001-1"
resp = zot.create_items([template])
items = zot.items(tag="machine-learning", limit=25)
for item in items:
print(f"{item['data']['title']} — {item['data'].get('date', 'n.d.')}")
MIT