Skip to main content
Glama
fegizii

Semantic Scholar MCP Server

by fegizii

get_paper_pdf_info

Check PDF availability for academic papers using Semantic Scholar IDs, DOIs, or ArXiv IDs to determine if full-text documents are accessible.

Instructions

Get PDF availability information for a paper.

Args:
    paper_id: Paper ID (Semantic Scholar ID, DOI, ArXiv ID, etc.)

Returns:
    PDF availability information

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
paper_idYes

Implementation Reference

  • Implementation of the get_paper_pdf_info tool handler. Fetches paper details from Semantic Scholar API focusing on openAccessPdf field, formats availability info including direct URL if available, and lists alternative sources like ArXiv, DOI, PubMed.
    @mcp.tool()
    async def get_paper_pdf_info(paper_id: str) -> str:
        """
        Get PDF availability information for a paper.
    
        Args:
            paper_id: Paper ID (Semantic Scholar ID, DOI, ArXiv ID, etc.)
    
        Returns:
            PDF availability information
        """
        encoded_id = quote(paper_id, safe="")
        result = await make_api_request(
            f"paper/{encoded_id}", {"fields": "paperId,title,openAccessPdf,externalIds"}
        )
    
        if result is None:
            return "Error: Failed to fetch paper information"
    
        if "error" in result:
            return f"Error: {result['error']}"
    
        title = result.get("title", "Unknown Title")
        open_access = result.get("openAccessPdf")
        external_ids = result.get("externalIds", {})
    
        result_text = f"PDF Information for: {title}\n\n"
    
        if open_access and open_access.get("url"):
            pdf_url = open_access["url"]
            result_text += "✅ Open Access PDF Available\n"
            result_text += f"URL: {pdf_url}\n"
            result_text += "Status: Ready for download\n\n"
        else:
            result_text += "❌ No Open Access PDF Available\n\n"
    
        # Check for potential alternative sources
        result_text += "Alternative sources to check:\n"
        if external_ids.get("ArXiv"):
            result_text += f"- ArXiv: https://arxiv.org/abs/{external_ids['ArXiv']}\n"
        if external_ids.get("DOI"):
            result_text += f"- Publisher (DOI): https://doi.org/{external_ids['DOI']}\n"
        if external_ids.get("PubMed"):
            result_text += (
                f"- PubMed: https://pubmed.ncbi.nlm.nih.gov/{external_ids['PubMed']}/\n"
            )
    
        return result_text
  • The @mcp.tool() decorator registers the get_paper_pdf_info function as an MCP tool.
    @mcp.tool()
  • Helper function used by get_paper_pdf_info to make API requests to Semantic Scholar, handling errors and API keys.
    async def make_api_request(
        endpoint: str, params: Optional[Dict[str, Any]] = None, method: str = "GET"
    ) -> Optional[Dict[str, Any]]:
        """Make a request to the Semantic Scholar API."""
        url = f"{BASE_URL}/{endpoint.lstrip('/')}"
    
        headers = {
            "Accept": "application/json",
            "User-Agent": f"semantic-scholar-mcp/{USER_AGENT_VERSION}",
        }
    
        if API_KEY:
            headers["x-api-key"] = API_KEY
    
        try:
            async with httpx.AsyncClient(timeout=API_TIMEOUT) as client:
                if method == "GET":
                    response = await client.get(url, headers=headers, params=params)
                elif method == "POST":
                    response = await client.post(url, headers=headers, json=params)
                else:
                    raise ValueError(f"Unsupported HTTP method: {method}")
    
                response.raise_for_status()
                return response.json()
    
        except httpx.HTTPStatusError as e:
            if e.response.status_code == 403:
                if not API_KEY:
                    return {
                        "error": "Rate limit exceeded. The shared public rate limit (1000 req/sec) may be exceeded. Get a free API key from https://www.semanticscholar.org/product/api for dedicated limits."
                    }
                else:
                    return {
                        "error": f"API key may be invalid or rate limit exceeded: {str(e)}"
                    }
            elif e.response.status_code == 429:
                return {
                    "error": "Rate limit exceeded. Please wait a moment and try again, or get an API key for dedicated higher limits."
                }
            else:
                return {"error": f"HTTP error: {str(e)}"}
        except httpx.HTTPError as e:
            return {"error": f"HTTP error: {str(e)}"}
        except Exception as e:
            return {"error": f"Request failed: {str(e)}"}

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/fegizii/SemanticScholarMCP'

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