search_pmc
Search academic papers from PubMed Central using queries to find relevant research articles and return paper metadata.
Instructions
Search academic papers from PubMed Central (PMC).
Args: query: Search query string (e.g., 'machine learning'). max_results: Maximum number of papers to return (default: 10). Returns: List of paper metadata in dictionary format.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | ||
| max_results | No |
Implementation Reference
- paper_search_mcp/server.py:877-887 (handler)The `search_pmc` tool handler in the MCP server calls the `async_search` utility using the `pmc_searcher` instance.
async def search_pmc(query: str, max_results: int = 10) -> List[Dict]: """Search academic papers from PubMed Central (PMC). Args: query: Search query string (e.g., 'machine learning'). max_results: Maximum number of papers to return (default: 10). Returns: List of paper metadata in dictionary format. """ papers = await async_search(pmc_searcher, query, max_results) return papers if papers else [] - The actual PMC search logic is implemented within the `PMCSearcher.search` method, which utilizes PubMed's E-utilities API to query and parse paper data.
def search(self, query: str, max_results: int = 10, **kwargs) -> List[Paper]: """ Search PMC open access articles. Args: query: Search query string max_results: Maximum results to return **kwargs: Additional parameters (e.g., from_date, to_date) Returns: List[Paper]: List of found papers with metadata """ papers = [] try: # Step 1: Use E-utilities to search PMC database search_params = { 'db': 'pmc', 'term': query, 'retmax': max_results, 'retmode': 'xml', 'tool': 'paper-search-mcp', 'email': 'openags@example.com' } search_response = self.session.get(self.EUTILS_SEARCH_URL, params=search_params, timeout=30) search_response.raise_for_status() search_root = ET.fromstring(search_response.content) # Get PMC IDs pmcids = [id_elem.text for id_elem in search_root.findall('.//Id') if id_elem.text] if not pmcids: logger.info(f"No PMC results found for query: {query}") return papers # Step 2: Fetch compact summaries (more stable than full-text efetch) summary_params = { 'db': 'pmc', 'id': ','.join(pmcids), 'retmode': 'xml', 'tool': 'paper-search-mcp', 'email': 'openags@example.com' } summary_response = self.session.get(self.EUTILS_SUMMARY_URL, params=summary_params, timeout=30) summary_response.raise_for_status() summary_root = ET.fromstring(summary_response.content) # Step 3: Parse each summary record for docsum in summary_root.findall('.//DocSum'): try: paper = self._parse_docsum(docsum) if paper: papers.append(paper) if len(papers) >= max_results: break except Exception as e: logger.warning(f"Error parsing PMC summary: {e}") continue except requests.RequestException as e: logger.error(f"PMC search request error: {e}") except ET.ParseError as e: logger.error(f"PMC XML parsing error: {e}") except Exception as e: logger.error(f"Unexpected error in PMC search: {e}") return papers