Skip to main content
Glama
h-lu

Paper Search MCP Server

by h-lu

download_medrxiv

Download PDF files from medRxiv's open-access repository by providing the paper's DOI identifier and specifying a save location.

Instructions

Download PDF from medRxiv (free and open access).

Args:
    paper_id: medRxiv DOI (e.g., '10.1101/2024.01.01.12345678').
    save_path: Directory to save PDF.

Returns:
    Path to downloaded PDF.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
paper_idYes
save_pathNo

Implementation Reference

  • The main handler function for the 'download_medrxiv' tool. It is registered via @mcp.tool() decorator and delegates the download to the generic _download helper using the 'medrxiv' searcher instance.
    @mcp.tool()
    async def download_medrxiv(paper_id: str, save_path: Optional[str] = None) -> str:
        """Download PDF from medRxiv (free and open access).
        
        Args:
            paper_id: medRxiv DOI (e.g., '10.1101/2024.01.01.12345678').
            save_path: Directory to save PDF.
        
        Returns:
            Path to downloaded PDF.
        """
        return await _download('medrxiv', paper_id, save_path)
  • Generic download helper function that retrieves the appropriate searcher from SEARCHERS dict and calls its download_pdf method. This is called by all download_* tool handlers.
    async def _download(
        searcher_name: str, 
        paper_id: str, 
        save_path: Optional[str] = None
    ) -> str:
        """通用下载函数"""
        if save_path is None:
            save_path = get_download_path()
        
        searcher = SEARCHERS.get(searcher_name)
        if not searcher:
            return f"Error: Unknown searcher {searcher_name}"
        
        try:
            return searcher.download_pdf(paper_id, save_path)
        except NotImplementedError as e:
            return str(e)
        except Exception as e:
            logger.error(f"Download failed for {searcher_name}: {e}")
            return f"Error downloading: {str(e)}"
  • The core implementation of PDF download for medRxiv papers in the MedRxivSearcher class. Downloads the PDF from the constructed URL https://www.medrxiv.org/content/{paper_id}v1.full.pdf and saves it to the specified path.
    def download_pdf(self, paper_id: str, save_path: str) -> str:
        """下载 PDF
        
        Args:
            paper_id: medRxiv DOI
            save_path: 保存目录
            
        Returns:
            下载的文件路径或错误信息
        """
        if not paper_id:
            return "Error: paper_id is empty"
        
        pdf_url = f"https://www.medrxiv.org/content/{paper_id}v1.full.pdf"
        
        try:
            response = self.session.get(
                pdf_url, 
                timeout=self.timeout,
                headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'}
            )
            response.raise_for_status()
            
            os.makedirs(save_path, exist_ok=True)
            filename = f"{paper_id.replace('/', '_')}.pdf"
            pdf_path = os.path.join(save_path, filename)
            
            with open(pdf_path, 'wb') as f:
                f.write(response.content)
            
            logger.info(f"PDF downloaded: {pdf_path}")
            return pdf_path
            
        except Exception as e:
            logger.error(f"PDF download failed: {e}")
            return f"Error downloading PDF: {e}"
  • Global SEARCHERS dictionary where the 'medrxiv' key is registered with a MedRxivSearcher instance, which provides the download_pdf method used by the tool.
    SEARCHERS = {
        'arxiv': ArxivSearcher(),
        'pubmed': PubMedSearcher(),
        'biorxiv': BioRxivSearcher(),
        'medrxiv': MedRxivSearcher(),
        'google_scholar': GoogleScholarSearcher(),
        'iacr': IACRSearcher(),
        'semantic': SemanticSearcher(),
        'crossref': CrossRefSearcher(),
        'repec': RePECSearcher(),
    }
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It describes the core action (downloading a PDF) and mentions the source is 'free and open access,' which hints at no authentication requirements. However, it lacks details on error handling, rate limits, file naming conventions, or what happens if the save_path is null, leaving gaps in behavioral understanding.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured and front-loaded with the main purpose, followed by clear sections for Args and Returns. Every sentence adds value: the first sentence states the tool's function and context, and the subsequent lines efficiently document parameters and return value without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's moderate complexity (2 parameters, no output schema, no annotations), the description is mostly complete. It covers the purpose, parameters, and return value adequately. However, it lacks details on behavioral aspects like error cases or default behaviors when save_path is null, which could enhance completeness for a download operation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description adds significant meaning beyond the input schema, which has 0% description coverage. It explains that 'paper_id' is a 'medRxiv DOI' with an example format, and 'save_path' is a 'Directory to save PDF,' clarifying the purpose and format of both parameters that are not covered in the schema properties.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the specific action ('Download PDF') and resource ('from medRxiv'), distinguishing it from sibling tools like 'read_medrxiv_paper' or 'search_medrxiv' by focusing on file retrieval rather than content reading or searching. It also specifies the source is 'free and open access,' which adds useful context about accessibility.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage context by mentioning 'medRxiv (free and open access),' suggesting it's for accessing papers from this specific repository. However, it does not explicitly state when to use this tool versus alternatives like 'download_biorxiv' or 'download_scihub,' nor does it provide exclusions or prerequisites for use.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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/h-lu/paper-search-mcp'

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