zotero-keeper

u9401066/zotero-keeper

3.2

If you are the rightful owner of zotero-keeper and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to dayong@mcphub.com.

Zotero Keeper is a Model Context Protocol (MCP) server designed to manage local Zotero libraries using AI agents, enabling seamless bibliographic operations.

Tools
4
Resources
0
Prompts
0

Zotero Keeper 📚

Let AI manage your references! A MCP Server connecting VS Code Copilot / Claude Desktop to your local Zotero library.

Python 3.11+ MCP SDK Zotero 7 CI

🌐 English |


🚀 One-Click Install (VS Code)

Prerequisites: Zotero 7 must be running

💡 Requires uv - Click installs automatically via uvx zotero-keeper


✨ What is this?

Zotero Keeper is a MCP Server that lets your AI assistant:

  • 🔍 Search references: "Find papers about CRISPR from 2024"
  • 📖 View details: "What's the abstract of this article?"
  • Add references: "Add this DOI to my Zotero" (with auto-fetch metadata!)
  • 🔄 PubMed integration: "Search PubMed, skip what I already have"
  • 📁 Interactive save: Shows collection options for you to choose!

No more manually searching, copying, pasting. Just tell your AI in natural language!


✨ Features

  • 🔌 MCP Native: Built with FastMCP SDK for seamless AI integration
  • 📖 MCP Resources: Browse Zotero data via URIs (zotero://collections, etc.)
  • 💬 MCP Elicitation: Interactive collection selection with numbered options
  • 🔒 Auto-fetch Metadata: DOI/PMID → complete abstract + all fields automatically!
  • � Citation Metrics: RCR, NIH Percentile → stored in Zotero extra field (v1.8.0)
  • 🛡️ Collection 防呆: Use collection_name for auto-validation (v1.8.0)
  • �📖 Read Operations: Search, list, retrieve items from local Zotero
  • ✏️ Write Operations: Add references via Connector API
  • 🧠 Smart Features: Duplicate detection, validation, intelligent import
  • 📁 Collection Support: Nested collections (folders) with hierarchy
  • 🏗️ Clean Architecture: DDD with onion architecture
  • 🔒 No Cloud Required: All operations are local

🚀 Quick Start

Prerequisites

Installation

# Clone the repository
git clone https://github.com/u9401066/zotero-keeper.git
cd zotero-keeper/mcp-server

# Install
pip install -e .
# or with uv:
uv pip install -e .

# Test (make sure Zotero is running)
python -m zotero_mcp

Configure VS Code Copilot

Create .vscode/mcp.json in your workspace:

{
  "servers": {
    "zotero-keeper": {
      "type": "stdio",
      "command": "uv",
      "args": [
        "run",
        "--directory",
        "/path/to/zotero-keeper/mcp-server",
        "python", "-m", "zotero_mcp"
      ]
    }
  }
}

Configure Claude Desktop

Add to claude_desktop_config.json:

{
  "mcpServers": {
    "zotero-keeper": {
      "command": "python",
      "args": ["-m", "zotero_mcp"],
      "cwd": "/path/to/zotero-keeper/mcp-server"
    }
  }
}

💡 Use absolute paths and ensure uv is installed.


🔧 Available Tools (25 Total)

💡 Tip: Most read operations can also be done via MCP Resources without calling tools.

📖 Core Tools (server.py - 6 tools)

ToolDescriptionExample
check_connectionTest Zotero connectivity"Is Zotero running?"
search_itemsSearch references"Find papers about CRISPR"
get_itemGet item details"Show abstract for key:ABC123"
list_itemsList recent items"Show papers in collection X"
list_tagsList all tags"What tags have I used?"
get_item_typesAvailable item types"What types can I add?"

📁 Collection Tools (server.py - 5 tools)

⚠️ These can also be accessed via zotero://collections/... Resources

ToolDescriptionEquivalent Resource
list_collectionsList all folderszotero://collections
get_collectionGet collection detailszotero://collections/{key}
get_collection_itemsItems in a collectionzotero://collections/{key}/items
get_collection_treeHierarchical tree viewzotero://collections/tree
find_collectionFind by name— (Tool only)

✏️ Save Tools (interactive_tools.py - 2 tools)

📊 Auto RCR: When PMID is provided, automatically fetches Relative Citation Ratio from iCite and stores in Zotero's extra field

ToolDescriptionExample
interactive_saveInteractive save + auto RCR"Save this paper to Zotero"
quick_saveQuick save + auto RCR"Quick save to AI Research"

🔍 Saved Search Tools (saved_search_tools.py - 3 tools)

ToolDescriptionExample
list_saved_searchesList all saved searches"What saved searches exist?"
run_saved_searchExecute a saved search"Which papers have no PDF?"
get_saved_search_detailsGet search conditions"What's in 'Missing PDF' search?"

🔍 Advanced Search & PubMed Integration (search_tools.py - 3 tools)

ToolDescriptionExample
advanced_searchMulti-condition search (itemType, tag, qmode)"Find all journal articles tagged with AI"
search_pubmed_exclude_ownedSearch PubMed, exclude owned"Find CRISPR papers I don't have"
check_articles_ownedCheck if PMIDs exist in Zotero"Do I have these PMIDs?"

📥 Import Tools (pubmed_tools.py - 3 tools, batch_tools.py - 1 tool)

📊 RCR Default ON: All PubMed import tools automatically fetch RCR by default

ToolDescriptionExample
quick_import_pmidsSimplest one-step import"Import these PMIDs"
import_ris_to_zoteroImport RIS citations"Import this RIS text"
import_from_pmidsImport by PMID + auto RCR"Import PMID 12345678"
batch_import_from_pubmedBatch import + validation + RCR"Import PMIDs to 'AI Research'"

📊 Analytics Tools (analytics_tools.py - 2 tools) ⭐ NEW!

ToolDescriptionExample
get_library_statsLibrary statistics (year/author/journal)"Show my library statistics"
find_orphan_itemsFind unorganized items"Which papers need organizing?"
batch_import_from_pubmed v1.8.0+ Features
# ✅ Simple: just provide PMIDs and collection
# RCR is automatically fetched by default!
batch_import_from_pubmed(
    pmids="38353755,37864754",
    collection_name="AI Research"  # Auto-validates name
)

# Zotero extra 欄位會包含:
# PMID: 38353755
# RCR: 5.23
# NIH Percentile: 85.2
# Citations: 127
advanced_search v1.8.0 新功能
# 🔍 依文獻類型搜尋
advanced_search(item_type="journalArticle")  # 只找期刊論文
advanced_search(item_type="book")  # 只找書籍
advanced_search(item_type="-attachment")  # 排除附件

# 🏷️ 依標籤搜尋
advanced_search(tag="AI")  # 具有 AI 標籤的文獻
advanced_search(tags=["AI", "Review"])  # 同時具有兩個標籤 (AND)
advanced_search(tag="AI || ML")  # 具有任一標籤 (OR)

# 📝 全文搜尋 (含 abstract)
advanced_search(q="XGBoost", qmode="everything")  # 搜尋摘要內容

# 🌟 組合條件
advanced_search(
    q="machine learning",
    item_type="journalArticle",
    tag="AI",
    sort="dateAdded",
    direction="desc"
)

📖 MCP Resources (Browsable Data)

No tool calls needed! AI can directly browse Zotero data:

Resource URIDescription
zotero://collectionsAll collections
zotero://collections/treeCollection hierarchy
zotero://collections/{key}Specific collection
zotero://collections/{key}/itemsItems in collection
zotero://itemsRecent items
zotero://items/{key}Item details
zotero://tagsAll tags
zotero://searchesSaved searches
zotero://searches/{key}Search details
zotero://schema/item-typesAvailable item types

🎯 Interactive Save (Recommended!)

The interactive_save tool uses MCP Elicitation to show collection options:

User: "Save this DOI:10.1234/example paper to Zotero"

[MCP Elicitation pops up]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📚 Saving: Deep Learning for Medical Imaging

⭐ Suggested:
   1. AI Research (match: 90%) - Title matches
   2. Medical Imaging (match: 75%) - Keyword matches

📂 All Collections:
   3. Biology (12 items)
   4. Chemistry (8 items)
   5. To Read (23 items)

0. Save to My Library (no collection)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Enter the number of your choice: [User enters: 1]

AI: ✅ Saved to 'AI Research' collection!

🔒 Data Integrity: Auto-fetch Metadata

When you provide a DOI or PMID, the tool automatically fetches complete metadata:

  • DOI → CrossRef API → Full abstract, authors, journal, date
  • PMID → PubMed API → Full abstract, MeSH terms, affiliations

No more missing abstracts! Just provide the identifier.


📁 Collection Organization

Zotero supports nested collections. Recommended strategies:

By Topic (Recommended)

📁 My Library
├── 📁 Research Topics
│   ├── 📂 CRISPR Gene Editing
│   ├── 📂 Machine Learning in Medicine
│   └── 📂 Anesthesia Safety
├── 📁 Projects
│   ├── 📂 2024 Paper Draft
│   └── 📂 PhD Thesis
└── 📁 Reading List
    ├── 📂 To Read
    └── 📂 Important

💡 Best Practice: Use collections for primary organization, tags for cross-cutting attributes (e.g., "to-read", "important", "review").


🔬 PubMed Integration

Works seamlessly with pubmed-search-mcp:

You: "Find new anesthesia AI papers from 2024 that I don't have"

AI executes:
1. search_pubmed_exclude_owned("anesthesia AI", min_year=2024)
   → Found 30, you own 5, returns 25 new ones

2. batch_import_from_pubmed(pmids="12345,67890,...")
   → Batch imports with complete abstracts, authors, DOI

You: Done! 25 new papers in Zotero

Install PubMed Integration

pip install -e ".[pubmed]"

🌐 Remote Zotero Setup

If Zotero runs on another computer:

1. On Zotero Machine (Windows)

# Enable Local API (in Zotero → Tools → Developer → Run JavaScript)
Zotero.Prefs.set("httpServer.localAPI.enabled", true)

# Open firewall
netsh advfirewall firewall add rule name="Zotero" dir=in action=allow protocol=TCP localport=23119

# Setup port proxy (Zotero only listens on 127.0.0.1)
netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=23119 connectaddress=127.0.0.1 connectport=23119

2. Configure MCP Server

{
  "env": {
    "ZOTERO_HOST": "192.168.1.100",
    "ZOTERO_PORT": "23119"
  }
}

🏗️ Architecture

┌─────────────────────────────────────────────────┐
│           AI Agent (VS Code / Claude)           │
└──────────────────────┬──────────────────────────┘
                       │ MCP Protocol
                       │ ├── Tools (22)
                       │ ├── Resources (10 URIs)
                       │ └── Elicitation (interactive input)
                       ▼
┌─────────────────────────────────────────────────┐
│              Zotero Keeper MCP Server           │
│  ┌───────────────────────────────────────────┐  │
│  │  MCP Layer                                │  │
│  │  ├── server.py (11 tools: 6 core + 5 collection) │
│  │  ├── resources.py (10 URIs, incl. collections)   │
│  ├── interactive_tools.py (2 save tools)  │  │
│  │  ├── saved_search_tools.py (3 tools)      │  │
│  │  ├── search_tools.py (3 tools)            │  │
│  │  ├── pubmed_tools.py (2 tools)            │  │
│  │  ├── batch_tools.py (1 tool)              │  │
│  │  └── smart_tools.py (helpers only)        │  │
│  └───────────────────────────────────────────┘  │
└──────────────────────┬──────────────────────────┘
                       │ HTTP (port 23119)
                       ▼
┌─────────────────────────────────────────────────┐
│              Zotero Desktop Client              │
│  ├── Local API (/api/...) → Read               │
│  └── Connector API (/connector/...) → Write    │
└─────────────────────────────────────────────────┘

⚠️ Zotero API Limitations (Important!)

� API Capability Matrix

Zotero provides two local APIs, but neither supports full CRUD:

APIEndpointReadCreateUpdateDelete
Local API/api/...
Connector API/connector/...

🔍 Technical Details

Local API (port 23119):

  • Designed for reading Zotero data (items, collections, tags)
  • Per official source code: "Write access is not yet supported."
  • DELETE/PATCH/PUT methods return 501 Not Implemented

Connector API (port 23119):

  • Designed for browser extensions to save new items
  • saveItems endpoint: Always creates NEW items, never updates
  • Even if you import the same PMID twice → creates duplicate items
  • No updateItem or deleteItem endpoints exist

🔴 Operations NOT Supported

OperationAPI SupportTechnical Reason
Delete items501 Not ImplementedLocal API is read-only
Update items501 Not ImplementedLocal API is read-only
Move items to collectionCannot modifyConnector API only creates, never updates
Add tags to existing itemsCannot modifyNo update endpoint available
Create collections400 Bad RequestConnector API doesn't support it
Delete collections501 Not ImplementedLocal API is read-only
Merge duplicatesNo APIMust use Zotero GUI

💡 What This Means

"Smart Management" Limitations:

❌ Cannot do:
- "Move these 10 papers to another collection"
- "Delete all duplicate references"
- "Help me organize my collections"
- "Archive old papers"

✅ Can do:
- "Add to specific collection when importing" (at creation time)
- "Search for matching references" (then handle manually)
- "List potential duplicates" (but manual deletion needed)

🛠️ Workarounds

NeedAlternative
Organize collectionsDrag & drop in Zotero GUI
Delete duplicatesZotero → Tools → "Merge duplicates"
Batch operationsUse Zotero Actions & Tags plugin
Auto-categorizeUse Zutilo plugin

🔮 Future Possibilities

Zotero team is working on Local API write support:

We'll update zotero-keeper as soon as Zotero supports it!


🌟 Local API Exclusive: Execute Saved Searches

APIExecute Saved Search
Web API (api.zotero.org)❌ Can only read search metadata
Local API✅ Can execute and retrieve results!

Recommended Saved Searches (create once, use forever):

NameConditionAI Prompt
Missing PDFAttachment File Type is not PDF"Which papers have no PDF?"
Missing DOIDOI is empty"Which items lack DOI?"
RecentDate Added in last 7 days"What did I add this week?"
UnreadTag is not "read""What haven't I read?"
DuplicatesSimilar titles"Potential duplicate items?"

🚧 Future: One-Click Installation

We understand that most users are researchers, not developers. Installing Python, uv, and configuring MCP can be daunting.

🎯 Planned Improvements

Current (v1.x)Future (v2.x)
Requires Python 3.11+Standalone executable (.exe / .app)
Requires pip installOne-click installer
Manual mcp.json configAuto-configure VS Code/Claude
Developer-friendlyResearcher-friendly

📦 Planned Distribution Methods

  1. PyPI Package: pip install zotero-keeper-mcp (simplified)
  2. Standalone Executable: PyInstaller bundle (no Python needed)
  3. VS Code Extension: One-click install from Marketplace (planned)
  4. Homebrew/Chocolatey: Package manager support

💡 Want to help? We welcome contributions to simplify installation! See for how to help.


🤔 Troubleshooting

Can't connect to Zotero?

  1. Make sure Zotero is running
  2. Test: curl http://127.0.0.1:23119/connector/ping
  3. Should return: Zotero is running

MCP Server not found?

  1. Use absolute paths
  2. Check Python environment
  3. Restart VS Code / Claude Desktop

PubMed features missing?

pip install -e ".[pubmed]"

📚 Resources

  • - Release notes
  • - Technical architecture
  • - How to contribute
  • - Development roadmap
  • pubmed-search-mcp - PubMed search (Apache 2.0)

🤝 Contributing

Contributions welcome! See .


📄 License

Apache 2.0 - See


Made with ❤️ for researchers
Let AI manage your references, focus on your research!