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 |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| 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_creator_fieldsA | List the name-shape fields Zotero recognizes on a |
| 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 |
| export_bibliographyA | Generate formatted bibliography/citation entries or portable export data for one or more items. Read-only. keys: item keys (see search_items/get_item). Keys not found in the
library are simply absent from the result -- not an error.
style: a Zotero/CSL style ID (e.g. "apa",
"modern-language-association", "chicago-note-bibliography") --
only used when format is "bibliography" or "citation"; ignored
otherwise. An unknown style raises an error naming the problem.
format:
"bibliography" (default) -- HTML reference-list entries, one per
found key, in Returns |
| 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_publication_statusA | 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. Unlike update_item, fields: same rules as update_item -- bibliographic fields such as DOI, url, date, publicationTitle, volume, issue, pages. May NOT include tags/collections/itemType/key/version -- use the dedicated tools for tags/collections, and item_type (not fields["itemType"]) to change the item type. item_type: new Zotero item type (see list_item_types); omit to leave it unchanged. version: the item's current version (from search_items/get_item) -- refused if stale, same as update_item. idempotency_key: an opaque string you generate once per logical request. If a call with this exact key and these exact arguments already completed -- success OR error -- that same outcome is replayed instead of running anything against Zotero again, so retrying after a lost response (e.g. a timeout) can't turn one edit into two. Reusing a key with DIFFERENT arguments raises an error instead of silently returning the old result -- use a fresh key per distinct request. |
| 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. idempotency_key: optional opaque string, generated once per logical request. If a call with this exact key and these exact arguments already completed -- success OR error -- that same outcome is replayed instead of deleting (or trying to delete) anything again, so retrying after a lost response can't do this twice. Reusing a key with different arguments raises an error instead of silently returning the old result. |
| 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. idempotency_key: optional opaque string; if a call with this exact key and tag already completed, that same outcome is replayed instead of running against Zotero again -- see delete_item_permanently's docstring for the full explanation. |
| 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. idempotency_key: optional opaque string; if a call with this exact key and these exact arguments already completed, that same outcome is replayed instead of running against Zotero again -- see delete_item_permanently's docstring for the full explanation. |
| 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. 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_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. idempotency_key: strongly recommended for this tool specifically. If the create-in-target step succeeds but the delete-from-source step then fails, this operation ends up erroring while the item now exists in BOTH libraries -- a bare retry would redo the whole thing and create a SECOND duplicate in the target library, since the source item's version hasn't changed. Passing the same idempotency_key on retry replays the original failure (and its "clean up manually" guidance) instead of touching Zotero again. Also protects the normal success path the same way delete_item_permanently's does. 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