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
| Name | Required | Description | Default |
|---|---|---|---|
| paper_id | Yes |
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
- src/semantic_scholar_mcp/server.py:755-755 (registration)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)}"}