MCP server for downloading academic papers from multiple sources
Project description
Paper Download MCP Server
MCP server for downloading academic papers from multiple sources with intelligent routing.
Features
- Multi-Source Support: Downloads from Sci-Hub and Unpaywall with automatic fallback
- Intelligent Routing: Year-based source selection (<2021 → Sci-Hub, ≥2021 → Unpaywall)
- 3 MCP Tools:
paper_download- Download single paper by DOI or URLpaper_batch_download- Download multiple papers with progress reportingpaper_metadata- Get paper metadata without downloading PDF
- Clean Filenames:
[YYYY] - Paper Title.pdfformat - Rate Limiting: Built-in delays for API compliance
- Comprehensive Error Messages: Actionable suggestions on failures
Installation
For Users (Recommended)
No manual installation required! Use uvx for automatic environment management:
{
"mcpServers": {
"paper-download": {
"command": "uvx",
"args": ["paper-download-mcp"],
"env": {
"SCIHUB_CLI_EMAIL": "your-email@university.edu"
}
}
}
}
For Developers
git clone <repository-url>
cd paper-download-mcp
uv sync
uv run python -m paper_download_mcp.server
Configuration
Required Environment Variables
SCIHUB_CLI_EMAIL: Your email address (required for Unpaywall API compliance)- Example:
researcher@university.edu - Used for Unpaywall API tracking and contact purposes
- Example:
Optional Environment Variables
SCIHUB_OUTPUT_DIR: Default output directory (default:./downloads)
Claude Desktop Setup
Add to your claude_desktop_config.json:
{
"mcpServers": {
"paper-download": {
"command": "uvx",
"args": ["paper-download-mcp"],
"env": {
"SCIHUB_CLI_EMAIL": "your-email@university.edu",
"SCIHUB_OUTPUT_DIR": "/path/to/papers"
}
}
}
}
After configuration, restart Claude Desktop.
Tools
paper_download
Download a single academic paper by DOI or URL.
Parameters:
identifier(required): DOI or URL (e.g.,10.1038/nature12373)output_dir(optional): Output directory (default:./downloads)
Example:
Download the paper 10.1038/nature12373
Returns:
- Markdown with download details (file path, size, source, timing)
- Error message with suggestions if download fails
paper_batch_download
Download multiple papers sequentially with progress reporting.
Parameters:
identifiers(required): List of DOIs or URLs (1-50 maximum)output_dir(optional): Output directory (default:./downloads)
Example:
Download these papers: 10.1038/nature12373, 10.1126/science.1234567
Returns:
- Markdown summary with statistics
- List of successful downloads
- List of failed downloads with errors
Note: Downloads are sequential with 2-second delays for rate limiting.
paper_metadata
Retrieve paper metadata without downloading the PDF.
Parameters:
identifier(required): DOI or URL
Example:
Get metadata for 10.1038/nature12373
Returns:
- JSON with paper details:
- DOI, title, year, authors, journal
- Open access status
- Available download sources
How It Works
Intelligent Source Routing
The server uses year-based routing to maximize download success:
- Publication year < 2021: Try Sci-Hub first (frozen in 2020), fallback to Unpaywall
- Publication year ≥ 2021: Try Unpaywall first (legal OA), fallback to Sci-Hub
- Year unknown: Conservative approach (Unpaywall → Sci-Hub)
Download Process
- Normalize DOI from URL/identifier
- Detect publication year via Crossref API
- Route to appropriate source based on year
- Download PDF with retry on failure
- Validate file (PDF header, size check)
- Generate filename:
[YYYY] - Title.pdf - Return absolute file path
Rate Limiting
- 2-second delay between batch downloads
- Respects Unpaywall API limits (~100k requests/day)
- Built-in exponential backoff retry (3 attempts max)
Troubleshooting
"SCIHUB_CLI_EMAIL environment variable is required"
Solution: Set the email in your Claude Desktop config (see Configuration section above).
"Paper not found in any source"
Possible causes:
- Invalid or incorrect DOI
- Paper too recent (not yet indexed)
- Paper behind paywall with no open access version
- Sci-Hub mirrors temporarily unavailable
Solutions:
- Verify DOI on doi.org
- Use
paper_metadatato check availability - Try again later (mirrors may recover)
Download times out
Causes:
- Slow network connection
- Sci-Hub mirror selection taking too long
- Large PDF file
Solutions:
- Check internet connection
- Retry (mirror selection is cached after first success)
- Single papers typically complete in <10 seconds
Downloaded file is corrupted
The server validates PDFs before returning. If you encounter corruption:
- Check disk space
- Verify file permissions in output directory
- Try different paper (may be source issue)
Testing
MCP Inspector
Test the server with MCP Inspector:
npx @modelcontextprotocol/inspector uv run python -m paper_download_mcp.server
Set SCIHUB_CLI_EMAIL before running.
Unit Tests
uv run pytest
Legal Notice
IMPORTANT: This tool provides access to academic papers through multiple sources:
-
Unpaywall (https://unpaywall.org): Legal open-access aggregator operated by OurResearch. Recommended and prioritized when available.
-
Sci-Hub: Operates in a legal gray area. While it provides access to research, it may violate copyright laws in some jurisdictions. Use at your own risk.
User Responsibilities:
- You are responsible for compliance with applicable copyright laws in your jurisdiction
- This tool is intended for research and educational purposes only
- The maintainers assume no liability for how you use this tool
- When possible, prefer legal open-access sources (Unpaywall)
By using this tool, you acknowledge these legal considerations and agree to use it responsibly.
Project Structure
paper-download-mcp/
├── src/
│ └── paper_download_mcp/
│ ├── server.py # FastMCP entry point
│ ├── models.py # Pydantic input schemas
│ ├── formatters.py # Markdown/JSON formatters
│ ├── tools/
│ │ ├── download.py # Download tools
│ │ └── metadata.py # Metadata tool
│ └── scihub_core/ # Copied from scihub-cli
├── pyproject.toml
├── README.md
└── .gitignore
Architecture
Layer Architecture
- FastMCP Server Layer: Protocol handling, tool registration, config validation
- MCP Tools Layer: Request parsing, response formatting, async coordination
- Models & Formatters: Data validation, output serialization
- scihub_core Layer: Academic paper logic (unchanged from scihub-cli)
Async Pattern
All tools use asyncio.to_thread() to wrap synchronous scihub-cli code:
@mcp.tool()
async def paper_download(...):
def _sync_download():
# Synchronous scihub-cli code
client = SciHubClient()
return client.download_paper(doi)
# Run in thread pool
result = await asyncio.to_thread(_sync_download)
return format_result(result)
This preserves the battle-tested scihub-cli code without modifications.
Performance
| Operation | Target | Typical | Max |
|---|---|---|---|
| Get Metadata | <1s | 0.5s | 2s |
| Single Download | <5s | 2-3s | 10s |
| Batch (10 papers) | <40s | 25-30s | 60s |
Note: First download may take longer (5-10s) due to mirror selection. Subsequent downloads use cached mirror.
Contributing
This project uses OpenSpec for specification-driven development. See openspec/ directory for design documents.
For Maintainers: Syncing from scihub-cli
The scihub_core/ directory contains code copied from the upstream scihub-cli project. When bugs are fixed or features added to scihub-cli:
Workflow:
- Fix/implement in
scihub-cliproject first - Run tests and commit to scihub-cli
- Copy updated files to
paper-download-mcp/src/paper_download_mcp/scihub_core/ - Test MCP server functionality
- Commit with message referencing upstream commit:
sync: Update <file> from scihub-cli (<description>) Synced from scihub-cli commit <hash> <details of changes>
Last sync: scihub-cli@9787efc (2024-12-02) - Fixed year type bug in UnpaywallSource
License
MIT License - See LICENSE file for details
Credits
- Built with FastMCP
- Uses scihub-cli as core download engine
- Metadata from Unpaywall and Crossref
Support
For issues or questions:
- Check the Troubleshooting section above
- Review OpenSpec documentation in
openspec/changes/implement-mcp-server/ - Open an issue on GitHub (include error messages and steps to reproduce)
Disclaimer: This tool is provided as-is for research and educational purposes. Users assume all responsibility for compliance with applicable laws and regulations.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file paper_download_mcp-0.1.0.tar.gz.
File metadata
- Download URL: paper_download_mcp-0.1.0.tar.gz
- Upload date:
- Size: 114.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.19
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1a522dc04c7ffc0cae985bf8e9ec838d53e2707e9faa85e9200771e518578249
|
|
| MD5 |
0d7af7493b7075151dd1aee910c131cb
|
|
| BLAKE2b-256 |
00478336c8555d719548980e56ab167237a4e71e4895e5414a09107f2062edd2
|
File details
Details for the file paper_download_mcp-0.1.0-py3-none-any.whl.
File metadata
- Download URL: paper_download_mcp-0.1.0-py3-none-any.whl
- Upload date:
- Size: 42.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.19
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0865ef080775f2b8265b8a44d10e84c29e2ecbb64f7bc3a45d2ef3159f7579f0
|
|
| MD5 |
0839544aed704ca3266cbe5474b74eed
|
|
| BLAKE2b-256 |
c1b11fc795c06f86fe05a41d45f52df6037266518abfbdc4dafa8e546e848dd3
|