download_zenodo
Download PDF files from Zenodo using paper identifiers. Save academic papers to specified directories for research and reference.
Instructions
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.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| paper_id | Yes | ||
| save_path | No | ./downloads |
Implementation Reference
- paper_search_mcp/server.py:1199-1208 (handler)The MCP tool handler function `download_zenodo` in the server.py, which calls the ZenodoSearcher helper.
async def download_zenodo(paper_id: str, save_path: str = "./downloads") -> str: """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. """ return zenodo_searcher.download_pdf(paper_id, save_path) - The actual implementation of `download_pdf` within the `ZenodoSearcher` class, which handles the file downloading logic.
def download_pdf(self, paper_id: str, save_path: str = "./downloads") -> str: """Download an open-access PDF from Zenodo. Args: paper_id: Zenodo record ID (numeric string or full DOI ``10.5281/zenodo.NNNNNN``). save_path: Directory to save the PDF. Returns: Absolute path to the saved PDF, or an error message. """ import re import os record_id = self._extract_record_id(paper_id) if not record_id: return f"Could not determine Zenodo record ID from: {paper_id}" try: response = self.session.get( f"{self.BASE_URL}/records/{record_id}", timeout=20 ) response.raise_for_status() record = response.json() except Exception as exc: return f"Failed to fetch Zenodo record {record_id}: {exc}" pdf_url = self._find_pdf_url(record) if not pdf_url: return ( f"No open-access PDF found for Zenodo record {record_id}. " "The record may be embargoed or restricted." ) os.makedirs(save_path, exist_ok=True) safe_name = re.sub(r"[^a-zA-Z0-9._-]+", "_", record_id) or record_id output_path = os.path.join(save_path, f"zenodo_{safe_name}.pdf") try: dl_response = self.session.get(pdf_url, stream=True, timeout=60) dl_response.raise_for_status() with open(output_path, "wb") as fh: for chunk in dl_response.iter_content(chunk_size=8192): fh.write(chunk) return output_path except Exception as exc: return f"Failed to download PDF from {pdf_url}: {exc}"