Paper Search Mcp

by openags

1k downloads
Not rated
GitHub

About

A Model Context Protocol (MCP) server for searching and downloading academic papers from multiple sources, including arXiv, PubMed, bioRxiv, and Sci-Hub (optional). Designed for seamless integration with large language models like Claude Desktop.

Details

Author
openags
Downloads
1,008
Categories
Search, Knowledge Base, Other

- Search and download papers from arXiv, PubMed, bioRxiv, and Sci-Hub
- Returns papers in a consistent dictionary format using the Paper class
- Asynchronous network requests via httpx for efficient handling
- Seamless integration with MCP clients for LLM context enhancement
- Extensible design; easily add new academic platforms

Setting up with Highlight

This MCP is not yet compatible with Highlight’s one-click setup. However, you can still use it with Highlight by following these steps:

  1. Download and install Highlight from highlightai.com/download
  2. Navigate to the plugins tab and select "Add Custom Plugin"
  3. Configure the plugin with the settings below
    Plugin Name Paper Search Mcp
    Command (node, npx, python, etc.)

    Please refer to the README for specific instructions on how to obtain API keys or other required environment variables.

  4. Enable "Start Automatically" if you want the plugin to start when Highlight launches

From the repository

Install the package with uv add paper-search-mcp or pip install paper-search-mcp, then configure Claude Desktop by adding a JSON entry to the MCP servers configuration file. The server exposes tools such as search_arxiv and download_arxiv that can be invoked through any MCP-compatible client.

search_papers

Unified top-level search across all configured academic platforms. Args: query: Search query string. max_results_per_source: Max results to fetch from each selected source. sources: Comma-separated source names or 'all'. Available: arxiv,pubmed,biorxiv,medrxiv,google_scholar,iacr,semantic,crossref,openalex,pmc,core,europepmc,dblp,openaire,citeseerx,doaj,base,zenodo,hal,ssrn,unpaywall year: Optional year filter for Semantic Scholar only. Returns: Aggregated dictionary with per-source stats, errors, and deduplicated papers.

search_arxiv

Search academic papers from arXiv. Args: query: Search query string (e.g., 'machine learning'). max_results: Maximum number of papers to return (default: 10). sort_by: Sort criterion — 'relevance', 'submittedDate', or 'lastUpdatedDate' (default: 'relevance'). sort_order: Sort direction — 'descending' or 'ascending' (default: 'descending'). Returns: List of paper metadata in dictionary format.

search_pubmed

Search academic papers from PubMed. Args: query: Search query string (e.g., 'machine learning'). max_results: Maximum number of papers to return (default: 10). sort: Sort order — 'relevance' or 'pub_date' (default: 'relevance'). Returns: List of paper metadata in dictionary format.

search_biorxiv

Search academic papers from bioRxiv. Note: bioRxiv API filters by category name within the last 30 days, not full-text keyword search. Use a category keyword such as 'bioinformatics', 'neuroscience', 'cell biology', etc. Args: query: Category name to filter by (e.g., 'bioinformatics', 'neuroscience'). max_results: Maximum number of papers to return (default: 10). Returns: List of paper metadata in dictionary format.

search_medrxiv

Search academic papers from medRxiv. Note: medRxiv API filters by category name within the last 30 days, not full-text keyword search. Use a category keyword such as 'infectious_diseases', 'cardiovascular_medicine', 'oncology', etc. Args: query: Category name to filter by (e.g., 'infectious_diseases', 'oncology'). max_results: Maximum number of papers to return (default: 10). Returns: List of paper metadata in dictionary format.

search_google_scholar

Search academic papers from Google Scholar. Args: query: Search query string (e.g., 'machine learning'). max_results: Maximum number of papers to return (default: 10). Returns: List of paper metadata in dictionary format.

search_iacr

Search academic papers from IACR ePrint Archive. Args: query: Search query string (e.g., 'cryptography', 'secret sharing'). max_results: Maximum number of papers to return (default: 10). fetch_details: Whether to fetch detailed information for each paper (default: True). Returns: List of paper metadata in dictionary format.

download_arxiv

Download PDF of an arXiv paper. Args: paper_id: arXiv paper ID (e.g., '2106.12345'). save_path: Directory to save the PDF (default: './downloads'). Returns: Path to the downloaded PDF file.

download_pubmed

Attempt to download PDF of a PubMed paper. Args: paper_id: PubMed ID (PMID). save_path: Directory to save the PDF (default: './downloads'). Returns: str: Message indicating that direct PDF download is not supported.

download_biorxiv

Download PDF of a bioRxiv paper. Args: paper_id: bioRxiv DOI. save_path: Directory to save the PDF (default: './downloads'). Returns: Path to the downloaded PDF file.

download_medrxiv

Download PDF of a medRxiv paper. Args: paper_id: medRxiv DOI. save_path: Directory to save the PDF (default: './downloads'). Returns: Path to the downloaded PDF file.

download_iacr

Download PDF of an IACR ePrint paper. Args: paper_id: IACR paper ID (e.g., '2009/101'). save_path: Directory to save the PDF (default: './downloads'). Returns: Path to the downloaded PDF file.

read_arxiv_paper

Read and extract text content from an arXiv paper PDF. Args: paper_id: arXiv paper ID (e.g., '2106.12345'). save_path: Directory where the PDF is/will be saved (default: './downloads'). Returns: str: The extracted text content of the paper.

read_pubmed_paper

Read and extract text content from a PubMed paper. Args: paper_id: PubMed ID (PMID). save_path: Directory where the PDF would be saved (unused). Returns: str: Message indicating that direct paper reading is not supported.

read_biorxiv_paper

Read and extract text content from a bioRxiv paper PDF. Args: paper_id: bioRxiv DOI. save_path: Directory where the PDF is/will be saved (default: './downloads'). Returns: str: The extracted text content of the paper.

read_medrxiv_paper

Read and extract text content from a medRxiv paper PDF. Args: paper_id: medRxiv DOI. save_path: Directory where the PDF is/will be saved (default: './downloads'). Returns: str: The extracted text content of the paper.

read_iacr_paper

Read and extract text content from an IACR ePrint paper PDF. Args: paper_id: IACR paper ID (e.g., '2009/101'). save_path: Directory where the PDF is/will be saved (default: './downloads'). Returns: str: The extracted text content of the paper.

search_semantic

Search academic papers from Semantic Scholar. Args: query: Search query string (e.g., 'machine learning'). year: Optional year filter (e.g., '2019', '2016-2020', '2010-', '-2015'). max_results: Maximum number of papers to return (default: 10). Returns: List of paper metadata in dictionary format.

download_semantic

Download PDF of a Semantic Scholar paper. Args: paper_id: Semantic Scholar paper ID, Paper identifier in one of the following formats: - Semantic Scholar ID (e.g., "649def34f8be52c8b66281af98ae884c09aef38b") - DOI:<doi> (e.g., "DOI:10.18653/v1/N18-3011") - ARXIV:<id> (e.g., "ARXIV:2106.15928") - MAG:<id> (e.g., "MAG:112218234") - ACL:<id> (e.g., "ACL:W12-3903") - PMID:<id> (e.g., "PMID:19872477") - PMCID:<id> (e.g., "PMCID:2323736") - URL:<url> (e.g., "URL:https://arxiv.org/abs/2106.15928v1") save_path: Directory to save the PDF (default: './downloads'). Returns: Path to the downloaded PDF file.

read_semantic_paper

Read and extract text content from a Semantic Scholar paper. Args: paper_id: Semantic Scholar paper ID, Paper identifier in one of the following formats: - Semantic Scholar ID (e.g., "649def34f8be52c8b66281af98ae884c09aef38b") - DOI:<doi> (e.g., "DOI:10.18653/v1/N18-3011") - ARXIV:<id> (e.g., "ARXIV:2106.15928") - MAG:<id> (e.g., "MAG:112218234") - ACL:<id> (e.g., "ACL:W12-3903") - PMID:<id> (e.g., "PMID:19872477") - PMCID:<id> (e.g., "PMCID:2323736") - URL:<url> (e.g., "URL:https://arxiv.org/abs/2106.15928v1") save_path: Directory where the PDF is/will be saved (default: './downloads'). Returns: str: The extracted text content of the paper.

search_crossref

Search academic papers from CrossRef database. CrossRef is a scholarly infrastructure organization that provides persistent identifiers (DOIs) for scholarly content and metadata. It's one of the largest citation databases covering millions of academic papers, journals, books, and other scholarly content. Args: query: Search query string (e.g., 'machine learning', 'climate change'). max_results: Maximum number of papers to return (default: 10, max: 1000). filter: CrossRef filter string (e.g., 'has-full-text:true,from-pub-date:2020'). sort: Sort field ('relevance', 'published', 'updated', 'deposited', etc.). order: Sort order ('asc' or 'desc'). Returns: List of paper metadata in dictionary format.

get_crossref_paper_by_doi

Get a specific paper from CrossRef by its DOI. Args: doi: Digital Object Identifier (e.g., '10.1038/nature12373'). Returns: Paper metadata in dictionary format, or empty dict if not found. Example: get_crossref_paper_by_doi("10.1038/nature12373")

download_crossref

Attempt to download PDF of a CrossRef paper. Args: paper_id: CrossRef DOI (e.g., '10.1038/nature12373'). save_path: Directory to save the PDF (default: './downloads'). Returns: str: Message indicating that direct PDF download is not supported. Note: CrossRef is a citation database and doesn't provide direct PDF downloads. Use the DOI to access the paper through the publisher's website.

download_scihub

Download paper PDF via Sci-Hub (optional fallback connector). Args: identifier: DOI, title, PMID, or paper URL. save_path: Directory to save the PDF. base_url: Sci-Hub mirror URL. Returns: Downloaded PDF path on success; error message on failure.

download_with_fallback

Try source-native download, OA repositories, Unpaywall, then optional Sci-Hub. Args: source: Source name (arxiv, biorxiv, medrxiv, iacr, semantic, crossref, pubmed, pmc, core, europepmc, citeseerx, doaj, base, zenodo, hal, ssrn). paper_id: Source-native paper identifier. doi: Optional DOI used for repository/unpaywall/Sci-Hub fallback. title: Optional title used for repository/Sci-Hub fallback when DOI is unavailable. save_path: Directory to save downloaded files. use_scihub: Whether to fallback to Sci-Hub after OA attempts fail. scihub_base_url: Sci-Hub mirror URL for fallback. Returns: Download path on success or explanatory error message.

read_crossref_paper

Attempt to read and extract text content from a CrossRef paper. Args: paper_id: CrossRef DOI (e.g., '10.1038/nature12373'). save_path: Directory where the PDF is/will be saved (default: './downloads'). Returns: str: Message indicating that direct paper reading is not supported. Note: CrossRef is a citation database and doesn't provide direct paper content. Use the DOI to access the paper through the publisher's website.

search_openalex

Search academic papers from OpenAlex. Args: query: Search query string (e.g., 'machine learning'). max_results: Maximum number of papers to return (default: 10). Returns: List of paper metadata in dictionary format.

search_pmc

Search academic papers from PubMed Central (PMC). Args: query: Search query string (e.g., 'machine learning'). max_results: Maximum number of papers to return (default: 10). Returns: List of paper metadata in dictionary format.

search_core

Search academic papers from CORE. Args: query: Search query string (e.g., 'machine learning'). max_results: Maximum number of papers to return (default: 10). Returns: List of paper metadata in dictionary format.

search_europepmc

Search academic papers from Europe PMC. Args: query: Search query string (e.g., 'machine learning'). max_results: Maximum number of papers to return (default: 10). Returns: List of paper metadata in dictionary format.

search_dblp

Search academic papers from dblp computer science bibliography. Args: query: Search query string (e.g., 'machine learning'). max_results: Maximum number of papers to return (default: 10). Returns: List of paper metadata in dictionary format.

search_openaire

Search academic papers from OpenAIRE European Open Access infrastructure. Args: query: Search query string (e.g., 'machine learning'). max_results: Maximum number of papers to return (default: 10). Returns: List of paper metadata in dictionary format.

search_citeseerx

Search academic papers from CiteSeerX digital library. Args: query: Search query string (e.g., 'machine learning'). max_results: Maximum number of papers to return (default: 10). Returns: List of paper metadata in dictionary format.

search_doaj

Search academic papers from DOAJ (Directory of Open Access Journals). Args: query: Search query string (e.g., 'machine learning'). max_results: Maximum number of papers to return (default: 10). Returns: List of paper metadata in dictionary format.

search_base

Search academic papers from BASE (Bielefeld Academic Search Engine). Args: query: Search query string (e.g., 'machine learning'). max_results: Maximum number of papers to return (default: 10). Returns: List of paper metadata in dictionary format.

search_zenodo

Search academic papers from Zenodo open repository. Args: query: Search query string (e.g., 'machine learning'). max_results: Maximum number of papers to return (default: 10). Returns: List of paper metadata in dictionary format.

search_hal

Search academic papers from HAL open archive. Args: query: Search query string (e.g., 'machine learning'). max_results: Maximum number of papers to return (default: 10). Returns: List of paper metadata in dictionary format.

search_ssrn

Search metadata records from SSRN. Note: SSRN connector is metadata-only and does not support direct PDF download. Args: query: Search query string (e.g., 'machine learning'). max_results: Maximum number of papers to return (default: 10). Returns: List of paper metadata in dictionary format.

search_unpaywall

Lookup a DOI via Unpaywall and return OA metadata. Unpaywall is DOI-centric and does not support generic keyword search. This tool extracts the first DOI from `query` and returns at most one record. Args: query: DOI string or text containing a DOI. max_results: Kept for API consistency; Unpaywall returns max 1 record. Returns: List with one paper metadata dict when DOI is resolvable, else empty list.

read_dblp_paper

Attempt to read and extract text content from a dblp paper. Note: dblp doesn't provide direct paper content access. This function returns an informative message. Args: paper_id: dblp paper identifier. save_path: Directory where the PDF would be saved (unused). Returns: str: Message indicating that direct paper reading is not supported.

download_dblp

Download PDF for a paper from dblp. Note: dblp doesn't provide direct PDF access. This function returns an informative message. Args: paper_id: dblp paper identifier. save_path: Directory to save the PDF (default: './downloads'). Returns: str: Message indicating that direct PDF download is not supported.

read_openaire_paper

Attempt to read and extract text content from an OpenAIRE paper. Args: paper_id: OpenAIRE paper identifier. save_path: Directory where the PDF is/will be saved (default: './downloads'). Returns: str: Extracted text or error message.

download_openaire

Download PDF for a paper from OpenAIRE. Args: paper_id: OpenAIRE paper identifier. save_path: Directory to save the PDF (default: './downloads'). Returns: str: Path to downloaded PDF or error message.

read_citeseerx_paper

Read and extract text content from a CiteSeerX paper. Args: paper_id: CiteSeerX paper identifier. save_path: Directory where the PDF is/will be saved (default: './downloads'). Returns: str: Extracted text or fallback abstract/error message.

download_citeseerx

Download PDF for a paper from CiteSeerX. Args: paper_id: CiteSeerX paper identifier. save_path: Directory to save the PDF (default: './downloads'). Returns: str: Path to downloaded PDF or error message.

read_doaj_paper

Read and extract text content from a DOAJ paper. Args: paper_id: DOAJ paper identifier. save_path: Directory where the PDF is/will be saved (default: './downloads'). Returns: str: Extracted text content.

download_doaj

Download PDF for a paper from DOAJ. Args: paper_id: DOAJ paper identifier. save_path: Directory to save the PDF (default: './downloads'). Returns: str: Path to downloaded PDF.

read_base_paper

Read and extract text content from a BASE paper. Args: paper_id: BASE paper identifier. save_path: Directory where the PDF is/will be saved (default: './downloads'). Returns: str: Extracted text content.

download_base

Download PDF for a paper from BASE. Args: paper_id: BASE paper identifier. save_path: Directory to save the PDF (default: './downloads'). Returns: str: Path to downloaded PDF.

read_zenodo_paper

Read and extract text content from a Zenodo paper. Args: paper_id: Zenodo paper identifier. save_path: Directory where the PDF is/will be saved (default: './downloads'). Returns: str: Extracted text content.

download_zenodo

Download PDF for a paper from Zenodo. Args: paper_id: Zenodo paper identifier. save_path: Directory to save the PDF (default: './downloads'). Returns: str: Path to downloaded PDF.

read_hal_paper

Read and extract text content from a HAL paper. Args: paper_id: HAL paper identifier. save_path: Directory where the PDF is/will be saved (default: './downloads'). Returns: str: Extracted text content.

download_hal

Download PDF for a paper from HAL. Args: paper_id: HAL paper identifier. save_path: Directory to save the PDF (default: './downloads'). Returns: str: Path to downloaded PDF.

read_ssrn_paper

Read paper content from SSRN. Note: SSRN connector is metadata-only and read is not supported. Args: paper_id: SSRN paper identifier. save_path: Directory where the PDF is/will be saved (unused). Returns: str: Error message from metadata-only SSRN connector.

download_ssrn

Download PDF for a paper from SSRN. Note: SSRN connector is metadata-only and download is not supported. Args: paper_id: SSRN paper identifier. save_path: Directory to save the PDF (unused). Returns: str: Error message from metadata-only SSRN connector.

read_openalex_paper

Attempt to read and extract text content from an OpenAlex paper. Args: paper_id: OpenAlex paper ID. save_path: Directory where the PDF is/will be saved (default: './downloads'). Returns: str: Message indicating that direct paper reading is not supported natively.

download_openalex

Download PDF for a paper from OpenAlex. Args: paper_id: OpenAlex paper ID. save_path: Directory to save the PDF (default: './downloads'). Returns: str: Error message, typically OpenAlex relies on extracted pdf_url instead of direct downloads.

search_ieee

Search IEEE Xplore for papers. Requires PAPER_SEARCH_MCP_IEEE_API_KEY (or IEEE_API_KEY). Args: query: Search query string. max_results: Maximum number of results (default: 10). Returns: List of paper dicts from IEEE Xplore.

download_ieee

Download a PDF from IEEE Xplore. Requires PAPER_SEARCH_MCP_IEEE_API_KEY (or IEEE_API_KEY) and institutional access. Args: paper_id: IEEE Xplore paper identifier. save_path: Directory to save the PDF (default: './downloads'). Returns: str: Path to saved PDF or error message.

read_ieee_paper

Download and read an IEEE Xplore paper. Requires PAPER_SEARCH_MCP_IEEE_API_KEY (or IEEE_API_KEY). Args: paper_id: IEEE Xplore paper identifier. save_path: Directory where the PDF is/will be saved (default: './downloads'). Returns: str: Extracted text content.

search_acm

Search ACM Digital Library for papers. Requires PAPER_SEARCH_MCP_ACM_API_KEY (or ACM_API_KEY). Args: query: Search query string. max_results: Maximum number of results (default: 10). Returns: List of paper dicts from ACM DL.

download_acm

Download a PDF from ACM Digital Library. Requires PAPER_SEARCH_MCP_ACM_API_KEY (or ACM_API_KEY) and institutional access. Args: paper_id: ACM DL paper identifier. save_path: Directory to save the PDF (default: './downloads'). Returns: str: Path to saved PDF or error message.

read_acm_paper

Download and read an ACM Digital Library paper. Requires PAPER_SEARCH_MCP_ACM_API_KEY (or ACM_API_KEY). Args: paper_id: ACM DL paper identifier. save_path: Directory where the PDF is/will be saved (default: './downloads'). Returns: str: Extracted text content.

Claude Desktop / Cursor

Paste into your MCP client config file to install this server.

{
    "mcpServers": {
        "paper search mcp": {
            "paper-search-mcp": {
                "command": "uvx",
                "args": [
                    "paper-search-mcp"
                ],
                "env": {
                    "PAPER_SEARCH_MCP_UNPAYWALL_EMAIL": "your@email.com",
                    "PAPER_SEARCH_MCP_CORE_API_KEY": "",
                    "PAPER_SEARCH_MCP_SEMANTIC_SCHOLAR_API_KEY": "",
                    "PAPER_SEARCH_MCP_ZENODO_ACCESS_TOKEN": "",
                    "PAPER_SEARCH_MCP_GOOGLE_SCHOLAR_PROXY_URL": "",
                    "PAPER_SEARCH_MCP_IEEE_API_KEY": "",
                    "PAPER_SEARCH_MCP_ACM_API_KEY": ""
                }
            }
        }
    }
}

McpServers

{
    "paper-search-mcp": {
        "command": "uvx",
        "args": [
            "paper-search-mcp"
        ],
        "env": {
            "PAPER_SEARCH_MCP_UNPAYWALL_EMAIL": "your@email.com",
            "PAPER_SEARCH_MCP_CORE_API_KEY": "",
            "PAPER_SEARCH_MCP_SEMANTIC_SCHOLAR_API_KEY": "",
            "PAPER_SEARCH_MCP_ZENODO_ACCESS_TOKEN": "",
            "PAPER_SEARCH_MCP_GOOGLE_SCHOLAR_PROXY_URL": "",
            "PAPER_SEARCH_MCP_IEEE_API_KEY": "",
            "PAPER_SEARCH_MCP_ACM_API_KEY": ""
        }
    }
}

A Model Context Protocol (MCP) server for searching and downloading academic papers from multiple sources. The project follows a free-first strategy: prioritize open and public data sources, support optional API keys when they improve stability or coverage, and keep source-specific connectors extensible for advanced users.

- Overview
-
Project Principles
-
Features
-
Source Strategy
-
Sci-Hub Notice
-
Installation

- Claude Code (Skill)
-
Method 1 — Smithery
-
Method 2 — uvx
-
Method 3 — uv
-
Method 4 — pip
-
Method 5 — npx
-
Method 6 — Docker
-
Method 7 — Clone & run from source
-
Environment Variables

paper-search-mcpis a Python-based tool for searching and downloading academic papers from various platforms. It provides tools for searching papers, downloading PDFs, and extracting text, making it ideal for researchers and AI-driven workflows. It can be used as an MCP server (for Claude Desktop and other MCP clients) or as a Claude Code skill with a CLI interface.

- Free-First: Public and open sources are the default roadmap. Paid or restricted sources are not the core direction of this project.
- Optional API Keys: API keys are supported only when they improve stability, rate limits, or metadata quality. The MCP should still be usable without them whenever possible.
- LLM-Friendly Retrieval: Search results should be standardized, deduplicated, and as complete as possible for downstream LLM workflows.
- Source Transparency: Different sources have different strengths. The MCP should make those tradeoffs explicit instead of pretending every source supports full-text retrieval.

- Two-Layer Architecture:

- Layer 1 (Unified Tooling): High-levelsearch_papersfor multi-source concurrent search & deduplication, anddownload_with_fallbackrelying on publisher open access links with sequential fallbacks.
- Layer 2 (Platform Connectors): Modular connectors for specific academic platforms (arXiv, PubMed, bioRxiv, Semantic Scholar, etc.) equipped with intelligent DOI extraction via regex text analysis or API fields.

The long-term goal is not to depend on a single search engine, but to combine multiple free and public sources with clear roles:

- Open metadata backbone: Crossref, OpenAlex, Semantic Scholar, dblp, CiteSeerX, SSRN, Unpaywall (DOI-centric OA metadata).
- Discipline-specific sources: arXiv, PubMed, PubMed Central, Europe PMC, IACR.
- Open-access full-text sources: arXiv, PMC, CORE, OpenAIRE, DOAJ, BASE, Zenodo, HAL, publisher open-access links.
- Discovery and DOI recovery: Google Scholar can be useful for finding titles, versions, and DOI clues when other public metadata sources are incomplete.
- Keep current public sources stable.
- Add OpenAlex as a broad free metadata source.
- Add PubMed Central and Europe PMC for stronger biomedical full-text access.
- Add CORE and OpenAIRE for repository-based open-access retrieval.
- Use Google Scholar mainly as a discovery fallback, not as the primary canonical source.

This matrix reflectsverified live-integration resultsfrom functional and end-to-end regression tests in this repository. Columns show the highest capability level observed under normal conditions.

✅ = reliable in live tests. ⚠️ = works but subject to upstream instability or access restrictions. ❌ = not supported. 🔑 = key required. 🚧 = skeleton only.

All keys areoptionalunless noted. Configure them in~/.config/paper-search-mcp/.env(preferred) or as shell exports.

All variables follow thePAPER_SEARCH_MCP_<NAME>prefix scheme. Legacy names without the prefix (e.g.CORE_API_KEY,UNPAYWALL_EMAIL) are still supported for backward compatibility.

Some search failures are caused by external provider instability, not by bugs in this project:

Optional Paid Platform Connectors (Phase 3)

IEEE Xplore and ACM Digital Library connectors are included asopt-in skeletons. They aredisabled by default— no API calls are made unless you explicitly configure the corresponding keys.

export PAPER_SEARCH_MCP_IEEE_API_KEY=<your_ieee_key> # free key at https://developer.ieee.org/ export PAPER_SEARCH_MCP_ACM_API_KEY=<your_acm_key> # see https://libraries.acm.org/digital-library

Once a key is set, the corresponding source is automatically added toALL_SOURCESand its MCP tools (search_ieee/search_acm,download_ieee/download_acm,read_ieee_paper/read_acm_paper) are registered at server startup.

Without a key the connectors log a startup warning only — the rest of the server is unaffected.

Three additional free-source connectors are now integrated into the MCP server:

- zenodo: Official Zenodo REST API connector (search + record-dependent PDF/read support).
- hal: HAL public API connector (search + record-dependent PDF/read support).
- ssrn: Discovery-first connector with hardened parser and best-effort download/read when a direct public PDF link is available.
- unpaywall: DOI-centric OA metadata source for standalone lookup (search_unpaywall) and fallback URL resolution.

SSRN integration remains compliance-first: it only attempts direct public PDF links exposed by SSRN pages. If login/restricted delivery is required, the connector returns a clear message instead of bypassing access controls.

Sci-Hub support can remain available as an optional connector for users who explicitly choose to enable it, but it should not be treated as the default or recommended full-text path.

- Availability is unstable and mirrors change frequently.
- Legal and policy risks vary by jurisdiction.
- README and tool descriptions should clearly state that users are responsible for enabling and using it.
- Open-access and publisher-permitted sources should be tried first whenever possible.

Choose the method that best fits your workflow. All methods support the sameoptional API keys.

Claude Code (Skill) — recommended for Claude Code users

Install as a Claude Code skill instead of an MCP server. This gives Claude automatic access to paper search when you mention finding papers, academic literature, etc. — no MCP configuration needed.

mkdir -p ~/.claude/skills/paper-search curl -fsSL https://raw.githubusercontent.com/openags/paper-search-mcp/main/claude-code/SKILL.md \ -o ~/.claude/skills/paper-search/SKILL.md

Create~/.config/paper-search-mcp/.envfor optional API keys (seeEnvironment Variables).

That's it.Next time you start Claude Code, just ask it to find papers — the skill activates automatically. For example:

- "Find me recent papers on CRISPR base editing"
- "Search arxiv and semantic scholar for transformer attention mechanisms"
- "Download the PDF for arxiv paper 2106.12345"

The skill uses a CLI (paper-search) that wraps the same library as the MCP server, outputting JSON for search/download and plain text for read.

MCP Server Config file locations(for methods below)

- macOS:~/Library/Application Support/Claude/claude_desktop_config.json
- Windows:%APPDATA%\Claude\claude_desktop_config.json
- Linux:~/.config/Claude/claude_desktop_config.json

Method 1 — Smithery (one-command, recommended for Claude Desktop)

npx -y @smithery/cli install @openags/paper-search-mcp --client claude

Smithery automatically writes the correct config block for you. No manual JSON editing needed.

Method 2 —uvx(no install, always latest)

uvxruns the package directly from PyPI without a permanent install. Requiresuv.

# Install uv (skip if already installed) curl -LsSf https://astral.sh/uv/install.sh | sh

⚠️macOS note:uvxgenerated wrapper scripts rely onrealpath, which is not included in macOS by default. If you see arealpath: command not founderror, either install GNU coreutils (brew install coreutils) or useMethod 3 (uv run)instead — it does not have this limitation.

{ "mcpServers": { "paper-search-mcp": { "command": "uvx", "args": ["paper-search-mcp"], "env": { "PAPER_SEARCH_MCP_UNPAYWALL_EMAIL": "your@email.com", "PAPER_SEARCH_MCP_CORE_API_KEY": "", "PAPER_SEARCH_MCP_SEMANTIC_SCHOLAR_API_KEY": "", "PAPER_SEARCH_MCP_ZENODO_ACCESS_TOKEN": "", "PAPER_SEARCH_MCP_GOOGLE_SCHOLAR_PROXY_URL": "", "PAPER_SEARCH_MCP_IEEE_API_KEY": "", "PAPER_SEARCH_MCP_ACM_API_KEY": "" } } } }
{ "mcpServers": { "paper-search-mcp": { "command": "uv", "args": ["tool", "run", "paper-search-mcp"], "env": { "PAPER_SEARCH_MCP_UNPAYWALL_EMAIL": "your@email.com", "PAPER_SEARCH_MCP_CORE_API_KEY": "", "PAPER_SEARCH_MCP_SEMANTIC_SCHOLAR_API_KEY": "", "PAPER_SEARCH_MCP_ZENODO_ACCESS_TOKEN": "", "PAPER_SEARCH_MCP_GOOGLE_SCHOLAR_PROXY_URL": "", "PAPER_SEARCH_MCP_IEEE_API_KEY": "", "PAPER_SEARCH_MCP_ACM_API_KEY": "" } } } }

Method 4 —pip(standard Python install)

{ "mcpServers": { "paper-search-mcp": { "command": "python", "args": ["-m", "paper_search_mcp.server"], "env": { "PAPER_SEARCH_MCP_UNPAYWALL_EMAIL": "your@email.com", "PAPER_SEARCH_MCP_CORE_API_KEY": "", "PAPER_SEARCH_MCP_SEMANTIC_SCHOLAR_API_KEY": "", "PAPER_SEARCH_MCP_ZENODO_ACCESS_TOKEN": "", "PAPER_SEARCH_MCP_GOOGLE_SCHOLAR_PROXY_URL": "", "PAPER_SEARCH_MCP_IEEE_API_KEY": "", "PAPER_SEARCH_MCP_ACM_API_KEY": "" } } } }

Ifpythonis not on your PATH, replace it with the full path (e.g./usr/bin/python3orC:\Python311\python.exe). Runwhich python3/where pythonto find it.

Method 5 —npx(via Smithery CLI, no local Python needed)

npx -y @smithery/cli run @openags/paper-search-mcp
{ "mcpServers": { "paper-search-mcp": { "command": "npx", "args": ["-y", "@smithery/cli", "run", "@openags/paper-search-mcp"], "env": { "PAPER_SEARCH_MCP_UNPAYWALL_EMAIL": "your@email.com", "PAPER_SEARCH_MCP_CORE_API_KEY": "", "PAPER_SEARCH_MCP_SEMANTIC_SCHOLAR_API_KEY": "" } } } }
docker build -t paper-search-mcp . docker run --rm -i \ -e PAPER_SEARCH_MCP_UNPAYWALL_EMAIL=your@email.com \ -e PAPER_SEARCH_MCP_CORE_API_KEY=your_core_key \ paper-search-mcp
{ "mcpServers": { "paper-search-mcp": { "command": "docker", "args": ["run", "--rm", "-i", "paper-search-mcp"], "env": { "PAPER_SEARCH_MCP_UNPAYWALL_EMAIL": "your@email.com", "PAPER_SEARCH_MCP_CORE_API_KEY": "", "PAPER_SEARCH_MCP_SEMANTIC_SCHOLAR_API_KEY": "", "PAPER_SEARCH_MCP_ZENODO_ACCESS_TOKEN": "", "PAPER_SEARCH_MCP_GOOGLE_SCHOLAR_PROXY_URL": "", "PAPER_SEARCH_MCP_IEEE_API_KEY": "", "PAPER_SEARCH_MCP_ACM_API_KEY": "" } } } }

Method 7 — Clone & run from source (development / recommended for macOS local)

This is the most reliable method on macOS — no wrapper scripts, norealpathissues.

# 1. Install uv (skip if already installed) curl -LsSf https://astral.sh/uv/install.sh | sh # 2. Clone repo git clone https://github.com/openags/paper-search-mcp.git cd paper-search-mcp # 3. Verify it runs (uv auto-resolves dependencies, no manual install needed) uv run -m paper_search_mcp.server

Claude Desktop config(replace the directory path with your actual clone location):

{ "mcpServers": { "paper-search-mcp": { "command": "uv", "args": [ "run", "--directory", "/path/to/paper-search-mcp", "-m", "paper_search_mcp.server" ], "env": { "PAPER_SEARCH_MCP_UNPAYWALL_EMAIL": "your@email.com", "PAPER_SEARCH_MCP_CORE_API_KEY": "", "PAPER_SEARCH_MCP_SEMANTIC_SCHOLAR_API_KEY": "", "PAPER_SEARCH_MCP_ZENODO_ACCESS_TOKEN": "", "PAPER_SEARCH_MCP_GOOGLE_SCHOLAR_PROXY_URL": "", "PAPER_SEARCH_MCP_IEEE_API_KEY": "", "PAPER_SEARCH_MCP_ACM_API_KEY": "" } } } }

For example, if you cloned to/Users/mac/Pengsong/paper-search-mcp:

"args": ["run", "--directory", "/Users/mac/Pengsong/paper-search-mcp", "-m", "paper_search_mcp.server"]

uv runautomatically installs dependencies into an isolated environment on first run — nopip installorvenvneeded.

For active development, optionally install an editable copy:

uv venv && source .venv/bin/activate # Windows: .venv\Scripts\activate uv pip install -e ".[dev]"

Instead of putting keys directly in the JSON config you can store them in the user config file (auto-loaded on startup):

mkdir -p ~/.config/paper-search-mcp curl -fsSL https://raw.githubusercontent.com/openags/paper-search-mcp/main/.env.example \ -o ~/.config/paper-search-mcp/.env $EDITOR ~/.config/paper-search-mcp/.env
PAPER_SEARCH_MCP_UNPAYWALL_EMAIL=your@email.com PAPER_SEARCH_MCP_CORE_API_KEY= PAPER_SEARCH_MCP_SEMANTIC_SCHOLAR_API_KEY= PAPER_SEARCH_MCP_ZENODO_ACCESS_TOKEN= PAPER_SEARCH_MCP_GOOGLE_SCHOLAR_PROXY_URL= PAPER_SEARCH_MCP_IEEE_API_KEY= PAPER_SEARCH_MCP_ACM_API_KEY=

To use a custom path:export PAPER_SEARCH_MCP_ENV_FILE=/absolute/path/to/.env

Legacy variable names without thePAPER_SEARCH_MCP_prefix (e.g.CORE_API_KEY,UNPAYWALL_EMAIL) are still supported for backward compatibility.

We welcome contributions! Here's how to get started:
-

Fork the Repository: Click "Fork" on GitHub.

git clone https://github.com/yourusername/paper-search-mcp.git cd paper-search-mcp uv venv && source .venv/bin/activate uv pip install -e ".[dev]"

- Add new platforms inacademic_platforms/.
- Update tests intests/.

Submit a Pull Request: Push changes and create a PR on GitHub.

- [√] arXiv
- [√] PubMed
- [√] bioRxiv
- [√] medRxiv
- [√] Google Scholar
- [√] IACR ePrint Archive
- [√] Semantic Scholar
- [√] Crossref
- [√] PubMed Central (PMC)
- [√] CORE
- [√] Europe PMC
- [√] Sci-Hub warning and enablement docs

- [√] Fix Async search bugs and ensure reliable fast MCP events
- [√] End-to-End full pipeline testing script (search, parse, download)
- [√] Establish two-layer federated architecture (Layer 1 tool:search_papers)
- [√] Ensure pervasive DOI extraction across metadata fields & abstract fallbacks
- Citation graph & Paper relation context feature
- [√] Expand full-stack OpenAlex provider

- [√] PubMed Central (PMC)
- [√] CORE
- [√] OpenAlex
- [√] Europe PMC
- [√] OpenAIRE
- [√] dblp
- [√] CiteSeerX
- [√] DOAJ
- [√] BASE
- [√] Zenodo
- [√] HAL
- [√] SSRN (discovery + best-effort full-text)
- [√] Unpaywall (standalone DOI search source)

- ResearchGate
- JSTOR
- ScienceDirect
- Springer Link
- [√] IEEE Xplore (optional skeleton — activate withIEEE_API_KEY)
- [√] ACM Digital Library (optional skeleton — activate withACM_API_KEY)
- Web of Science
- Scopus

This project is licensed under the MIT License. See the LICENSE file for details.

Happy researching withpaper-search-mcp! If you encounter issues, open a GitHub issue.

Search global news using natural language. Webz.io News Search API returns the most relevant articles and content, with filters for source, country, language, date, sentiment, and category.

Fetch, convert, and search AWS documentation pages, with recommendations for related content.

Search campgrounds around the world on campertunity, check availability, and provide booking links.

No reviews yet — be the first

Sign in to leave a review

Use Google, GitHub, or an email account so ratings stay tied to real people.

Email sign in

No reviews posted yet.