cite-caddy
Cite Caddy gives full read/write access to a Zotero library — search, add, tag, update, delete, and move items; create, rename, and delete collections…
What it can do
- Search Items: Search the Zotero library. Read-only.
- Get Item: Fetch one item by key. Read-only. Use this to get an item's current `version` right before a mutating call, if you don't already have a fresh one from search_items. `creators` is a list of {
- List Trash: List items currently in the trash -- soft-deleted (e.g. via the Zotero desktop app's "Move to Trash", or trash_item), but not yet permanently gone. Read-only. Each result's `key`/`version`
What data it sees
Do you need an account
No: the server works without sign-in
Cite Caddy gives full read/write access to a Zotero library — search, add, tag, update, delete, and move items; create, rename, and delete collections; upload/download attachments and read their extracted full text; read and write item notes; manage tags, trash, and saved searches library-wide; and look up Zotero's own item-type/field schema.
How to connect
How to connect cite-caddy to Claude
The server address to paste into Claude settings:
https://cite-caddy--herbertkokholm.run.tools
- Open Claude (claude.ai or the desktop app).
- Go to Settings → Connectors.
- Click Add custom connector.
- Paste the server address copied below into Remote MCP server URL and click Add.
- In a chat, click + → Connectors and switch the new connector on.
Custom connectors are available on Free, Pro, Max, Team and Enterprise plans (Free is limited to one). On Team and Enterprise an organization Owner adds the connector first under Organization settings → Connectors.
Authorization
After you click Add, a sign-in window for the service opens. Sign in with your own account and approve access. Claude never sees your password.
How to connect cite-caddy to ChatGPT
The server address to paste into ChatGPT settings:
https://cite-caddy--herbertkokholm.run.tools
- Open ChatGPT in a browser (chatgpt.com). A Plus, Pro, Business, Enterprise or Edu plan is required.
- Turn on developer mode once: Settings → Apps → Advanced settings → Developer mode.
- Open Settings → Connectors and click Create.
- Fill in the form: Name (anything), Description (one line about what the service does), MCP server URL (copy it below).
- Under Authentication choose OAuth if the service requires sign-in, otherwise None. Click Create.
- In a new chat open + → Apps/Connectors and enable the connector.
OpenAI has renamed this section before (Connectors → Apps/Plugins). If the label differs, search settings for "developer mode". On Business/Enterprise workspaces an admin must allow custom connectors first.
Authorization
On first use ChatGPT opens the service's sign-in window. Sign in and approve access.
How to connect cite-caddy to Cursor
The server address to paste into Cursor settings:
https://cite-caddy--herbertkokholm.run.tools
Fastest: click Open in Cursor below and confirm the prompt.
Manually:
- In Cursor open Settings → Cursor Settings → MCP and click Add new global MCP server.
- Paste the JSON copied below into
~/.cursor/mcp.json(per project:.cursor/mcp.jsonin the repo root). - Save the file. The server appears in the MCP list; authorize it there if asked.
Authorization
If the service needs sign-in, an authorize button appears next to the server in the MCP list.
Server tool list (39)
Raw names from tools/list. Only developers need these.
| search_items | Search the Zotero library. Read-only. |
| get_item | Fetch one item by key. Read-only. Use this to get an item's current `version` right before a mutating call, if you don't already have a fresh one from search_items. `creators` is a list of {creatorType, firstName, lastName} (or {creatorType, name} for single-field/ institutional creators) entries -- see search_items' docstring. |
| list_trash | List items currently in the trash -- soft-deleted (e.g. via the Zotero desktop app's "Move to Trash", or trash_item), but not yet permanently gone. Read-only. Each result's `key`/`version` can be passed to restore_from_trash. limit/start: pagination (default limit 25). `creators` shape matches search_items/get_item. |
| list_collections | List all collections in the library (key, name, parent_collection). Read-only. |
| list_saved_searches | List saved searches -- Zotero's own stored search definitions (visible in the desktop app's left-hand pane), not ad-hoc calls to search_items. Read-only. Each result's `key` can be passed to delete_saved_search. |
| list_groups | List the Zotero groups the configured API key's user account belongs to. Read-only. Each result's `id` can be passed as target_library_id (with target_library_type="group") to move_item_to_different_library, if the group you want isn't this server's own configured library. |
| list_item_types | List every Zotero item type (e.g. "book", "journalArticle", "webpage") -- valid values for create_item's item_type argument. Read-only. |
| list_item_fields | List every bibliographic field Zotero recognizes across all item types combined -- not which fields are valid for one specific type (see list_item_type_fields for that, which is what create_item actually needs). Read-only. |
| list_item_type_fields | List the bibliographic fields valid for one item type -- only these keys are valid in create_item/update_item's `fields` argument for this item_type; anything else raises a validation error. Read-only. |
| list_item_creator_types | List the valid `creatorType` values (e.g. "author", "editor") for one item type -- for create_item/update_item's `creators` entries, e.g. {"creatorType": "author", ...}. Read-only. |
| list_creator_fields | List the name-shape fields Zotero recognizes on a `creators` entry (e.g. "firstName", "lastName", "name") -- for building creators entries in create_item/update_item's `creators` argument. Distinct from list_item_creator_types, which lists creatorType *roles* (author, editor, ...) rather than name fields. Read-only. |
| list_tags | List distinct tags used anywhere in the library -- not one item's tags (see search_items/get_item for those). Read-only. |
| list_attachments | List the file attachments (PDFs, snapshots, etc.) filed under an item -- not its notes. Read-only. Each result's `key` can be passed to download_attachment or get_fulltext. |
| get_fulltext | Fetch Zotero's extracted full-text content and indexing progress for an attachment (see list_attachments for keys). Only meaningful for attachments Zotero has indexed -- PDFs/text files with extracted text -- not e.g. images; raises an error if there's no indexed full text for this key. Read-only. |
| download_attachment | Download an attachment's file content (see list_attachments for keys). Read-only. Returns `content_base64` -- this server runs remotely, so raw bytes travel as a base64 string rather than a local file path; decode it to reconstruct the file. |
| list_notes | List the notes filed under an item -- not its file attachments (see list_attachments for those). Read-only. Each result includes full note content and `version` -- pass both to update_note. |
| export_bibliography | Generate formatted bibliography/citation entries or portable export data for one or more items. Read-only. |
| create_item | Add a new item to the library. Safe: creates a brand-new key, never touches an existing one. |
| create_collection | Create a new collection, optionally nested under parent_key. Safe. |
| create_saved_search | Create a new saved search. Safe: creates a brand-new key, never touches an existing one. |
| update_collection | Rename and/or move (reparent) a collection, in place. Safe: the collection's key is unchanged, so items filed in it and any sub-collections stay put. |
| trash_item | Move an item to the trash (soft delete). Unlike delete_item_permanently, this is reversible via restore_from_trash -- prefer it whenever a delete might need to be undone. Safe, key-preserving: the item's key is unchanged, so a Word citation referencing it keeps resolving unless/until it's later permanently deleted (e.g. via delete_item_permanently, or "Empty Trash" in the Zotero desktop app). |
| restore_from_trash | Remove an item from the trash, restoring it to the library. Safe, key-preserving. version: the item's current version (from list_trash). |
| upload_attachment | Upload a new file attachment as a child of an existing item (e.g. attach a PDF to a journalArticle item). Safe: creates a brand-new attachment item with its own key; never touches the parent item's own fields or version. |
| create_note | Add a new note as a child of an existing item (e.g. a research note attached to a journalArticle). Safe: creates a brand-new note item with its own key; never touches the parent item's own fields or version. |
| update_item | Edit bibliographic fields (title, date, DOI, url, abstractNote, publicationTitle, creators, etc.) on an existing item, in place. Safe: the item's key is unchanged, so any Word citation referencing it keeps working. `creators` (if included) replaces the whole author/editor list -- e.g. [{"creatorType": "author", "firstName": "Ada", "lastName": "Lovelace"}], not a merge into the existing list. |
| update_publication_status | Update an item in place to reflect that a preprint has been formally published -- e.g. an arXiv preprint that just received a journal DOI. Same key-preserving patch as update_item (Word citations keep working) -- prefer this or update_item over deleting and recreating the item whenever a preprint's status changes. |
| update_note | Edit a note's content, in place. Safe, key-preserving. version: the note's current version (from list_notes). |
| add_tags | Add one or more tags to an item, keeping its existing tags. Safe, key-preserving. version: the item's current version (see update_item). |
| remove_tags | Remove one or more tags from an item; other tags are kept. Safe, key-preserving. version: the item's current version (see update_item). |
| set_tags | Replace ALL of an item's tags with exactly this list (not merged -- use add_tags/remove_tags to change tags incrementally instead). Safe, key-preserving. version: the item's current version (see update_item). |
| rename_tag | Rename a tag across every item in the library that carries it (not just one item -- see add_tags/remove_tags/set_tags for single-item edits). Zotero has no native tag-rename: this adds new_tag and removes old_tag on each affected item individually, merging with each item's existing tags. |
| add_to_collection | File an item into a collection, in addition to any it's already in. Safe, key-preserving reorganization within the same library -- prefer this over move_item_to_different_library whenever the goal is just organizing, not actually relocating to a different library. version: the item's current version (see update_item). |
| remove_from_collection | Remove an item from one collection; it stays in the library and any other collections it's filed under. Safe, key-preserving. version: the item's current version (see update_item). |
| delete_item_permanently | DESTRUCTIVE -- permanently deletes the item from its library. Cannot be undone through this server. |
| delete_tag | DESTRUCTIVE -- permanently removes this tag from every item in the library that carries it (not one item -- see remove_tags for that). Cannot be undone through this server. |
| delete_collection | DESTRUCTIVE -- permanently deletes the collection. Matches Zotero's own "Delete Collection" behavior: any sub-collections nested under it are deleted too, cascading -- but items filed in it (or in a deleted sub-collection) are NOT deleted from the library, only unfiled from that collection. |
| delete_saved_search | DESTRUCTIVE, but low-risk -- permanently deletes this saved search definition. Unlike delete_item_permanently/delete_collection, this doesn't touch any items or their citations -- a saved search is just a stored filter, not a container. idempotency_key: optional opaque string; if a call with this exact key already completed, that same outcome is replayed instead of running against Zotero again -- see delete_item_permanently's docstring for the full explanation. |
| move_item_to_different_library | DESTRUCTIVE -- moves an item to a different Zotero library (e.g. from this user library into a group library, or vice versa). Zotero has no native cross-library move: this recreates the item in the target library under a BRAND-NEW key, then deletes the original. |