Activating the skill & daily workflow
Activating the research workflow skill
The skill is a markdown file that tells Claude Code how to behave during research sessions. One-time installation:
# Create the skills folder in your vault
mkdir -p ~/Documents/ResearchVault/.claude/skills
# Copy the skill file to the vault
cp research-workflow-skill-v1.16.md ~/Documents/ResearchVault/.claude/skills/
Then add the following line to your CLAUDE.md (at the bottom):
## Active skills
- Read and follow `.claude/skills/research-workflow-skill-v1.16.md` during every research session.
From that point on, the skill is active as soon as you open Claude Code in your vault. You can start the workflow by typing: /research or simply "start research workflow".
Daily workflow after installation
Once everything is set up, the daily workflow is straightforward. The feedreader runs automatically — no action required.
- Browse the filtered feed at
http://localhost:8765/filtered.html(or in NetNewsWire viahttp://localhost:8765/filtered.xml). Items are sorted by relevance score. Send interesting ones to Zotero_inboxvia the browser extension or iOS app. - Start Zotero (so the local API is active)
- Open Terminal in your vault:
cd ~/Documents/ResearchVault && claude - Activate the skill: type
/researchor "start research workflow" - Claude Code asks an intake question and guides you interactively from there
You do not need to know exactly what you are looking for — the skill is designed to help you with that.
Full session flow
- Browse the filtered feed and forward interesting items to Zotero
_inbox - Start Zotero
- Open Terminal, navigate to your vault, and start Claude Code:
cd ~/Documents/ResearchVault claude - Activate the research workflow:
or just type:/researchstart research workflow - Optionally, run
index-score.pyfirst to prioritize your review:
This ranks all~/.local/share/uv/tools/zotero-mcp-server/bin/python3 .claude/index-score.py_inboxitems by semantic similarity to your existing library (using the ChromaDB embeddings from zotero-mcp), so you know which items to focus on. - Claude Code retrieves all items from your Zotero
_inboxand presents each one with a short summary and relevance assessment — the summary is generated locally by Qwen3.5:9b. You respond Go or No-go per item. - For each Go: Claude Code writes a structured literature note using the safe pipeline below.
- For each No-go: Claude Code removes the item from
_inbox(after your confirmation). - At the end of the session, Claude Code shows a summary: X approved, Y removed. If new papers were added, update the semantic search database:
Or use the alias:zotero-mcp update-db # quick (metadata only) zotero-mcp update-db --fulltext # recommended (includes full text)update-zotero(equivalent to--fulltext). Check database status withzotero-mcp db-status.
Helper scripts
The workflow uses three helper scripts in .claude/. They keep source content out of Claude Code's context and handle Zotero write operations.
fetch-fulltext.py — retrieve and save attachment text
Fetches the full text of a Zotero attachment and saves it to a local file. Only prints status; never prints content.
~/.local/share/uv/tools/zotero-mcp-server/bin/python3 .claude/fetch-fulltext.py ITEMKEY inbox/bron.txt
# Output: Saved: inbox/bron.txt (12,345 chars, type: application/pdf)
ollama-generate.py — generate text via Ollama REST API
Calls Ollama's REST API directly (no CLI, no ANSI codes). Prepends /no_think to suppress Qwen3.5:9b's reasoning step. Prints only status lines.
~/.local/share/uv/tools/zotero-mcp-server/bin/python3 .claude/ollama-generate.py \
--input inbox/bron.txt \
--output literature/notitie.md \
--prompt "Write a literature note in Dutch..."
# Output: Input: inbox/bron.txt (12,345 chars) | Written: literature/notitie.md (3,200 chars)
zotero-remove-from-inbox.py — remove processed item from _inbox
Removes the item from the _inbox collection in Zotero via the web API. Requires ZOTERO_API_KEY in the environment or .env file (see step 4d).
~/.local/share/uv/tools/zotero-mcp-server/bin/python3 .claude/zotero-remove-from-inbox.py ITEMKEY
# Output: Item ITEMKEY removed from _inbox.