A Model Context Protocol server for arXiv paper search and retrieval
The arXiv MCP server defines 3 search/retrieval tools with complete input schemas and reasonable descriptions. All tools follow verb_noun naming (search, search_advanced, get_paper). Parameter schemas are well-typed with descriptions. However, output schemas are not documented in the source code, the server returns Pydantic model instances (SearchResult, Paper) but the actual field structures are not visible in the provided code snippet. Descriptions are adequate (70-150 chars) but lack explicit guidance on when to use each tool vs. alternatives. The search_advanced tool requires 'at least one search field' validation (seen in code), but no error recovery hints are provided. Tool annotations are present (readOnlyHint, openWorldHint), which is good for protocol compliance. No destructive operations, so confirmation patterns not needed.
Get detailed information about a specific arXiv paper. Args: id_or_url: arXiv paper ID (e.g., '2301.00001') or full arXiv URL Returns: Paper details including title, abstract, authors, categories, and URLs
Search arXiv for papers matching the query. Args: query: Search query for arXiv papers (e.g., 'LLM', 'transformer architecture') category: Filter by arXiv category (e.g., 'cs.AI', 'cs.LG', 'stat.ML') author: Filter by author name sort_by: Sort order - 'relevance', 'date_desc', 'date_asc' page: Page number (default: 1) page_size: Results per page, max 50 (default: 25) Returns: Search results with papers containing title, abstract, authors, and URLs
Advanced search with specific field filters. Args: title: Search in paper titles abstract: Search in abstracts author: Search by author name category: Filter by arXiv category (e.g., 'cs.AI', 'cs.LG') id_arxiv: Search by arXiv ID pattern date_from: Start date filter (YYYY-MM-DD format) date_to: End date filter (YYYY-MM-DD format) sort_by: Sort order - 'relevance', 'date_desc', 'date_asc' page: Page number (default: 1) page_size: Results per page, max 50 (default: 25) Returns: Search results with papers containing title, abstract, authors, and URLs
Output schema not documented. SearchResult and Paper Pydantic models are used but field structure is not visible in provided code. LLMs cannot know what fields to expect in responses (e.g., does Paper have 'url_pdf' or 'pdf_url'? Is 'authors' an array of strings or objects?). This forces trial-and-error downstream tool planning.
search_advanced has a runtime validation error ('At least one search field is required') but this constraint is not documented in the parameter descriptions. LLMs will not know that all 7 optional params cannot simultaneously be None, and will waste a call discovering this. Add: 'At least one of title, abstract, author, category, id_arxiv must be provided' to the tool description.
Parameter 'sort_by' accepts 'relevance', 'date_desc', 'date_asc' but this enum is not formally declared in the input schema. The code consults SORT_OPTIONS dict, but the schema shows it as a plain string with default. LLMs may hallucinate other sort orders. Replace with explicit enum constraint in schema.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | B | 70 | 2026-07-28+ | v2 |
| 2026-03-09 | C | 60 | - | v1 |
Parameter 'category' lacks guidance on valid categories. The code references ARXIV_CATEGORIES constant (in models.py, not shown), but descriptions only give examples ('cs.AI', 'cs.LG', 'stat.ML'). LLMs cannot discover all valid categories. Consider returning a list_arxiv_categories tool or documenting the full set.
No error guidance. Code raises ValueError for HTTP errors and missing search fields, but the tool does not return actionable recovery hints. E.g., 'arXiv returned HTTP 503. Try again in 5 minutes or simplify your query.' LLMs need to know if errors are retryable, user-fixable, or fatal.
get_paper parameter 'id_or_url' accepts both arXiv ID and full URL but does not distinguish them in type or constraint. Description says 'arXiv paper ID (e.g., '2301.00001') or full arXiv URL' but this is ambiguous, is it one or the other, or can both be passed? The code extracts ID via regex, so both work, but the schema should clarify: oneOf or a more specific description like 'Either the arXiv ID (format: YYMM.NNNNN) or a full arxiv.org URL.'