Local MCP server for scientific paper research (OpenAlex + CrossRef + Unpaywall)
OpenPapers demonstrates solid tool design with clear naming (verb_noun pattern), comprehensive parameter descriptions, and well-documented schemas. All 5 tools have explicit descriptions (194 - 280 chars, within baseline 34 - 392 range). Input schemas are complete with type constraints (ge/le bounds on num_results, max_results). Output types are documented via Pydantic models (SearchResult, Paper, OAResult, DownloadResult, ResearchSummary). Error handling includes recovery guidance (e.g., 'Search failed: {e.status or network error}'). However, parameter descriptions lack explicit format/constraint details in some cases (e.g., DOI accepts 'bare string', 'URL form', or 'doi:...' prefix but this is buried in description text rather than formalized). Tool composition is clean, each tool has one responsibility, and outputs chain well (search_papers → get_paper → find_oa_pdf → download_pdf). Security is strong: no credentials in parameters, SSRF validation on download_pdf, PDF magic-byte verification. Minor gap: no explicit error classification (retryable vs fatal) in tool descriptions.
Download a PDF to the local PDF directory. Use `find_oa_pdf` first to obtain a URL. The URL is validated for SSRF safety (private/loopback/metadata IPs are refused) and the bytes are verified to start with the `%PDF-` magic marker. Downloads are capped at PDF_MAX_BYTES (default 100 MB) and written atomically — a failed download never leaves a partial file at the final path.
Find a legal Open Access PDF for a DOI via Unpaywall. Returns the OA status, the best OA location (with direct PDF URL if available), and a list of all OA locations (repository vs publisher, version, license).
Fetch full metadata for a single paper by DOI, including the abstract (reconstructed from OpenAlex), authors with ORCID/affiliations, concepts, and references (enriched from CrossRef).
Convenience workflow: search OpenAlex for `query`, then for each top result fetch OA status (Unpaywall). Returns a compact overview suitable for quickly assessing a research area. Abstracts are taken from the search response itself — no extra OpenAlex calls.
Search academic papers by relevance via OpenAlex. Returns a compact list with DOI, title, authors, year, venue, citation count, OA status, and top concepts. Use `year_from`/`year_to` to constrain the publication year.
DOI parameter accepts multiple formats (bare, URL, 'doi:' prefix) but format flexibility is only documented in description text, not formalized as a regex pattern or enum. LLMs may pass invalid formats.
Error handling in tool descriptions lacks explicit classification (retryable vs user-fixable vs fatal). E.g., 'Search failed: {e.status}' does not tell the LLM whether to retry or ask the user.
download_pdf description mentions SSRF safety and magic-byte verification but does not explicitly state that the tool is idempotent (safe to retry with same URL/DOI). Agents need to know retry safety.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 64 | <=2025-11-25 | v2 |
research_topic is a convenience workflow combining search + enrichment. While useful, it reduces agent flexibility, agents cannot customize the enrichment step (e.g., skip OA lookup for some results). Consider offering both the combined tool and lower-level primitives.
No pagination support in search_papers or research_topic. If an LLM wants to iterate through all results beyond num_results/max_results, there is no offset/cursor mechanism. Large result sets may be truncated without the agent knowing.