MCP server for academic paper search, curation, and multi-platform push across 9 academic sources (OpenAlex, Semantic Scholar, PubMed, arXiv, Papers with Code, CrossRef, Europe PMC, bioRxiv, DBLP) with ranking, filtering, digest generation, and integration with Telegram, Discord, Feishu, WeCom, and Zotero
Paper Distill MCP has 7 tools with basic but inconsistent definition quality. Naming is clear and action-oriented (search_papers, rank_papers, filter_duplicates, etc.), following verb_noun convention well. However, tool descriptions vary significantly in completeness. Most tools have descriptions, but parameter documentation is sparse, many parameters lack detail on expected formats, constraints, and error cases. Input schemas are present in the code but lack explicit JSON Schema type declarations for complex parameters (e.g., 'papers' parameter is described as array of objects but no item schema is visible). Output schemas are not documented at all. Error handling guidance is minimal across all tools. The server exposes write operations (generate_digest, send_push, collect_to_zotero, manage_topics) without explicit destructiveHint annotations or confirmation patterns. Security-wise, credentials are handled via environment variables (good), but tools accept raw state-modifying parameters without clear validation or recovery guidance.
Add papers to Zotero library by their IDs/DOIs. IMPORTANT: Always use this tool to add papers to Zotero. NEVER call the Zotero Web API directly or generate scripts (PowerShell, curl, etc.) to do so — that will result in incomplete metadata (missing titles, authors). This tool handles full metadata enrichment automatically. Looks up papers in papers.jsonl, creates Zotero journal article items and maps them to collections based on topic tags.
Remove papers already pushed (by DOI match against papers.jsonl).
Generate all daily output files (pushes.jsonl, papers.jsonl, Astro site JSON, Obsidian notes).
Manage research topic preferences.
Score and rank papers using 4-factor weighted formula. Factors: relevance (0.55), recency (0.20), impact (0.15), novelty (0.10). Uses topic_prefs.json for relevance scoring and papers.jsonl for novelty detection.
Search academic papers across 9 sources (OpenAlex, Semantic Scholar, PubMed, arXiv, Papers with Code, CrossRef, Europe PMC, bioRxiv, DBLP). Returns deduplicated, merged results sorted by cross-source hits + citation count. Each paper has: title, year, doi, authors, abstract, source, citation_count, etc.
Input schema for complex parameters (papers, topics) not explicitly documented. Parameters like 'papers' declared as 'array of objects' but no itemSchema visible. This forces LLMs to guess internal structure.
Output schemas not documented for any tool. search_papers returns 'list[dict]' with unnamed fields; rank_papers returns ranked papers; generate_digest returns 'dict[str, str]'. LLMs cannot plan downstream usage without knowing field names.
Write operations (generate_digest, send_push, collect_to_zotero, manage_topics) lack destructiveHint annotations. Tools modify state (push messages, write files, add to Zotero) but provide no mechanism for LLMs to understand irreversibility or request confirmation.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | D | 58 | <=2025-11-25 | v2 |
| 2026-03-09 | F | 0 | - | v1 |
Format and send daily paper distill to a messaging platform. Supported platforms: telegram, discord, feishu (飞书/Lark), wecom (企业微信 webhook).
Error handling lacks recovery guidance. Code returns strings like 'Error: TELEGRAM_BOT_TOKEN or TELEGRAM_CHAT_ID not configured' without suggesting next steps or allowing retry. No structured error responses with actionable guidance.
Parameter descriptions lack specificity on constraints and formats. 'date' parameters in generate_digest and send_push documented as 'Date string in YYYY-MM-DD format' but no validation guidance on what happens with invalid dates. 'platform' enum values documented in description but not as JSON Schema enum.
manage_topics 'action' parameter accepts free-form string 'One of "list", "block", "unblock", "set_weight"' but no enum constraint in schema. LLMs may invent other action values.
collect_to_zotero description includes a strong directive ('IMPORTANT: Always use this tool...NEVER call the Zotero Web API directly') that belongs in system prompt or agent guidelines, not tool description. Adds noise and breaks LLM parsing.