Skip to main content
Glama
openags

Paper Search MCP

by openags

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
NameRequiredDescriptionDefault
paper_idYes
save_pathNo./downloads

Implementation Reference

  • 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}"

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/openags/paper-search-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server