academic-workflow-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| OBSIDIAN_URL | No | Obsidian REST API base URL | http://127.0.0.1:27123 |
| ZOTERO_API_KEY | Yes | Zotero Web API key (required for write operations) | |
| OBSIDIAN_API_KEY | Yes | API key from the Obsidian Local REST API plugin | |
| ZOTERO_LOCAL_URL | No | Zotero local connector URL | http://127.0.0.1:23119 |
| LITERATURE_FOLDER | No | Vault folder for literature notes | 10-Literature |
| ZOTERO_LIBRARY_ID | Yes | Numeric library ID from zotero.org/settings/keys (required for write operations) | |
| OBSIDIAN_VAULT_NAME | No | Vault name for obsidian:// deep-links | |
| ZOTERO_LIBRARY_TYPE | No | Either 'user' or 'group' | 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 |
|---|---|
| workflow_get_paperA | Retrieve everything needed to analyze a paper: metadata, full text, and PDF annotations from Zotero — all in one call. Use this as the first step before generating a literature note. The returned data gives the LLM sufficient context to fill every section of the note template. Args: identifier: Zotero item key (e.g. "7BDH2DPA"), Better BibTeX citekey (e.g. "wang2024deep"), DOI, or title keywords. Returns: { "found": bool, "item": {key, citekey, title, authors, year, journal, doi, abstract, tags, zotero_link}, "fulltext": str, # indexed PDF text (may be empty) "annotations": [ # PDF highlights & notes {type, text, comment, color_label, page}, ... ], "has_fulltext": bool, "has_annotations": bool, "note_path": str, # expected Obsidian path for the note "note_exists": bool, # whether a note already exists } |
| workflow_write_noteA | Write a structured literature note directly to the Obsidian vault at 10-Literature/.md with proper YAML frontmatter and section headings. The note is created with status "pending-review". Call workflow_confirm_review after the human has checked the note. Args: citekey: Better BibTeX citation key (used as filename, e.g. "wang2024deep"). metadata: Dict with keys — title, authors (list[str]), year, journal, doi, zotero_link. Use the 'item' dict from workflow_get_paper. sections: Dict mapping section keys to content strings. Recognized keys: one_line_summary, research_question, methods, results, contributions, limitations, relevance, highlights, further_reading Any key may be omitted; the heading is still written with a placeholder. overwrite: If False (default) and a note already exists, returns an error so you do not silently clobber a reviewed note. Returns: {"success": bool, "path": str, "obsidian_link": str, "message": str} |
| workflow_attach_zotero_noteA | Create a short child note (≤200 chars) under the Zotero item that links back to the Obsidian deep note. Requires ZOTERO_API_KEY and ZOTERO_LIBRARY_ID to be set. Args: item_key: Zotero internal item key (8-char, e.g. "7BDH2DPA"). citekey: Better BibTeX citekey (used to build the obsidian:// link). summary: One-sentence summary of the paper (≤150 chars recommended). rating: Star rating, default "⭐⭐⭐". cite_in: Grant/paper section where this can be cited (e.g. "Methods 2.1"). Returns: {"success": bool, "key": str, "message": str} |
| workflow_sync_highlightsA | Pull PDF annotations from Zotero and update the 'Highlights from Paper' section of the corresponding Obsidian literature note. Run this any time after you have highlighted the PDF in Zotero. Existing highlight content is replaced; metadata sections are untouched. Args: citekey: Better BibTeX citekey (used to locate the Obsidian note). item_key: Zotero internal item key (needed to fetch annotations). Returns: {"success": bool, "count": int, "message": str} |
| workflow_confirm_reviewA | Mark a literature note as reviewed: update the Obsidian frontmatter status to 'reviewed' and update the Zotero item tags. Call this only after the human has reviewed and approved the note. Args: citekey: Better BibTeX citekey. item_key: Zotero internal item key. tag_remove: Zotero tag to remove (default "在读" / "reading"). tag_add: Zotero tag to add (default "已精读" / "reviewed"). Returns: {"success": bool, "obsidian": {...}, "zotero": {...}} |
| workflow_list_papersA | List papers from Zotero filtered by tag or collection, with optional cross-check against the Obsidian vault to see which already have notes. Use this to build a reading queue or to identify papers that still need to be processed. Args: tag: Zotero tag to filter by (e.g. "待读" or "#待读"). If empty, returns all items (up to limit). collection: Zotero collection name. Takes precedence over tag if both given. limit: Maximum number of items to return (default 30). check_notes: If True, adds "note_status" to each item showing the Obsidian note status (None = no note, "pending-review", "reviewed", etc.). Slower when True. Returns: {"count": int, "items": [{citekey, title, authors, year, tags, date_added, note_status?}, ...]} |
| workflow_get_noteA | Read the current content of a literature note from the Obsidian vault. Useful for reviewing what has already been written, checking the status, or deciding whether to overwrite vs. patch a note. Args: citekey: Better BibTeX citekey (= filename without .md). Returns: {"exists": bool, "path": str, "content": str, "status": str | None} |
| workflow_import_pdfsA | Import PDF files into Zotero with automatic title extraction and smart deduplication. Improvements over zotero-mcp's zotero_add_from_file:
Args: pdf_paths: List of absolute file paths to PDFs. collection: Zotero collection name (exact, case-sensitive). Leave empty for library root. item_type: Zotero item type for new parent items. Default "preprint". Other values: "journalArticle", "conferencePaper". Returns: { "imported": [ {item_key, attachment_key, title, title_source, filename_stem, title_mismatch, attached_to_existing, storage_copied, path} ], "skipped": [ {path, item_key, title, reason} ], "failed": [ {path, error} ], "warnings": [ {path, filename_stem, extracted_title, title_source, message} ], # title mismatches needing user review "count": int, # newly imported (excludes skipped) } |
| workflow_find_duplicatesA | Scan Zotero for duplicate items grouped by identical DOI or highly similar title. Run this before starting a reading session or after a batch import to catch entries that were added twice, preventing duplicate annotation work. Args: collections: Collection names to scan (e.g. ["1_SLAM与退化导航", "2_3DGS与三维重建"]). Leave empty to scan the entire library. title_threshold: Word-overlap ratio for title similarity (default 0.85). 0.85 catches near-identical titles; lower values cast a wider net. Returns: { "duplicate_groups": [ { "reason": "Same DOI" | "Similar title", "doi": str, "suggested_keep": str, # item key recommended to keep "items": [ {key, title, year, authors, journal, doi, zotero_link}, ... ], } ], "total_duplicates": int, # total number of items that are duplicates "group_count": int, "tip": str, } |
| workflow_sync_checkA | Bidirectional sync check between Zotero and Obsidian. Three checks are performed depending on
Default is dry_run mode (auto_apply=False) — reports findings without making any changes. Review the output before setting auto_apply=True. Args: direction: "trash_to_obs" | "obs_to_zotero" | "both" auto_apply: False (default) = report only. True = actually delete/trash. Returns: { "trash_to_obs": { "zotero_trash_items": [...], "orphan_notes_found": [...], # notes to delete "deleted_notes": [...], # notes actually deleted (auto_apply=True) }, "obs_to_zotero": { "obsidian_notes_total": int, "orphan_notes": [...], # notes with no Zotero item → delete note "deleted_orphan_notes": [...], "items_note_deleted": [...], # Zotero items whose notes were removed "trashed_items": [...], # items actually trashed (auto_apply=True) }, "auto_apply": bool, "summary": str, } |
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
- 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/wuruiqi/zo-bridge'
If you have feedback or need assistance with the MCP directory API, please join our Discord server