Cite Caddy
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| PORT | No | Set to run in HTTP mode; required for HTTP mode. If unset, runs in stdio mode. | |
| MCP_DATA_DIR | No | Where OAuth clients/tokens/tenants persist. Defaults to ./.data. | ./.data |
| MCP_PUBLIC_URL | No | Public HTTPS URL this server is reachable at. Required for HTTP mode. | |
| ZOTERO_API_KEY | No | Zotero API key from Zotero -> Settings -> Security -> Applications. Needs write permission. Required for stdio mode. | |
| MCP_WEBSITE_URL | No | Public site reported as serverInfo.website_url; also used to build serverInfo.icons[0].src as MCP_WEBSITE_URL + "icons/icon.svg". Optional. | |
| ZOTERO_LIBRARY_ID | No | Numeric library ID (user or group). Required for stdio mode. | |
| MCP_TOKEN_STORE_KEY | No | Fernet key encrypting onboarded tenants' API keys at rest. Generate once at deploy time. Required for HTTP mode. | |
| ZOTERO_LIBRARY_TYPE | No | "user" or "group" (default: user). | user |
Capabilities
Features and capabilities supported by this server
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| search_itemsA | Search the Zotero library. Read-only. query: substring match against title/creator/year (Zotero's quick
search), or omit to list items.
item_type: filter to one Zotero item type, e.g. "journalArticle",
"book", "report", "webpage".
tag: filter to items carrying this exact tag.
collection_key: filter to items filed in this collection (see
list_collections).
limit/start: pagination (default limit 25).
full_text: also match Each result includes |
| get_itemA | Fetch one item by key. Read-only. Use this to get an item's current
|
| list_trashA | 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 |
| list_collectionsA | List all collections in the library (key, name, parent_collection). Read-only. |
| list_saved_searchesA | 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 |
| list_groupsA | List the Zotero groups the configured API key's user account
belongs to. Read-only. Each result's |
| list_item_typesA | List every Zotero item type (e.g. "book", "journalArticle", "webpage") -- valid values for create_item's item_type argument. Read-only. |
| list_item_fieldsA | 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_fieldsA | List the bibliographic fields valid for one item type -- only
these keys are valid in create_item/update_item's |
| list_item_creator_typesA | List the valid |
| list_tagsA | List distinct tags used anywhere in the library -- not one item's tags (see search_items/get_item for those). Read-only. query: substring filter on tag name, or omit to list all tags. limit/start: pagination (default limit 100). |
| list_attachmentsA | List the file attachments (PDFs, snapshots, etc.) filed under an
item -- not its notes. Read-only. Each result's |
| get_fulltextA | 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_attachmentA | Download an attachment's file content (see list_attachments for
keys). Read-only. Returns |
| list_notesA | 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 |
| create_itemA | Add a new item to the library. Safe: creates a brand-new key, never touches an existing one. item_type: a Zotero item type, e.g. "journalArticle", "book", "report", "webpage", "conferencePaper". fields: bibliographic fields for that type, e.g. {"title": "...", "date": "2024", "DOI": "10.1/x", "url": "...", "abstractNote": "...", "publicationTitle": "..."}. Which fields are valid depends on item_type; an invalid field raises an error naming the problem. creators: e.g. [{"creatorType": "author", "firstName": "Ada", "lastName": "Lovelace"}]. tags: plain tag strings. collections: collection keys (see list_collections) to file the new item into immediately. |
| create_collectionB | Create a new collection, optionally nested under parent_key. Safe. |
| create_saved_searchA | Create a new saved search. Safe: creates a brand-new key, never touches an existing one. conditions: a list of dicts, each with exactly the keys "condition", "operator", "value", e.g. [{"condition": "itemType", "operator": "is", "value": "journalArticle"}]. Which condition/operator combinations are valid is Zotero-defined and fairly extensive; an invalid combination raises an error naming the problem. |
| update_collectionA | 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. name: new name; omit to leave the current name unchanged. parent_key: new parent collection's key, to nest this collection under it; pass "" (empty string) to move it to the top level (out of any parent); omit entirely to leave the parent unchanged. At least one of name/parent_key must be given. version: the collection's current version (from list_collections) -- refused if stale, same as update_item. |
| trash_itemA | 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). version: the item's current version (from search_items/get_item) -- refused if stale, same as update_item. |
| restore_from_trashA | Remove an item from the trash, restoring it to the library. Safe, key-preserving. version: the item's current version (from list_trash). |
| upload_attachmentA | 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. filename: name to store the file under, e.g. "paper.pdf" -- also used to guess Zotero's contentType from the extension. content_base64: the file's bytes, base64-encoded. This server runs remotely and has no access to the caller's local filesystem, so content must travel as a string rather than a local path. title: attachment title shown in Zotero; defaults to filename. |
| create_noteA | 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. content: the note's body, as Zotero-flavored HTML (e.g. "Some observation.") -- Zotero derives the note's display title from the first line of this content. tags: plain tag strings. |
| update_itemA | 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. version: the item's current version (from search_items/get_item) -- the edit is refused if this doesn't match the server's current version (someone else changed the item since you read it; re-fetch and retry). fields may NOT include tags/collections -- use add_tags/remove_tags/ set_tags and add_to_collection/remove_from_collection for those. |
| update_noteA | Edit a note's content, in place. Safe, key-preserving. version: the note's current version (from list_notes). |
| add_tagsA | 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_tagsA | 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_tagsA | 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_tagA | 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. Not atomic across items -- if it fails partway through (e.g. a concurrent edit on one item), re-run with the same arguments; already-renamed items are skipped since they no longer carry old_tag. |
| add_to_collectionA | 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_collectionA | 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_permanentlyA | DESTRUCTIVE -- permanently deletes the item from its library. Cannot be undone through this server. Any Word document citing this item via the Zotero Word plugin's live field code references it by this key; deleting it breaks that citation silently -- the document won't show an error, it'll just show stale or broken text next time someone updates fields. Only call this when that's a known, accepted consequence, not as a routine cleanup step. version: the item's current version (from search_items/get_item) -- the delete is refused if this doesn't match the server's current version, so a concurrent edit elsewhere isn't silently discarded along with the item. |
| delete_tagA | 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. Unlike delete_item_permanently/delete_collection, this has no caller-supplied version to check -- Zotero's tag-delete endpoint is gated on the library's own version internally. |
| delete_collectionA | 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. There is no confirmation step at this layer; check list_collections for sub-collections first if that matters before calling this. version: the collection's current version (from list_collections) -- the delete is refused if this doesn't match the server's current version. |
| delete_saved_searchA | 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. |
| move_item_to_different_libraryA | 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. Any Word citation referencing the original key is broken by this, exactly like delete_item_permanently -- silently and permanently. If the goal is just reorganizing within THIS library, use add_to_collection/remove_from_collection instead -- those preserve the key and citations keep working. target_library_id/target_library_type: the destination library; the configured ZOTERO_API_KEY must have write access to it. version: the item's current version in the source library (from search_items/get_item) -- refused if stale. Returns old_key and new_key -- report both to the caller so anyone relying on the old key knows it changed. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/herbertkokholm/cite-caddy'
If you have feedback or need assistance with the MCP directory API, please join our Discord server