search_papers
Find academic papers on OpenAlex by entering research topics or keywords, with options to filter by year and limit results for focused literature review.
Instructions
Search for academic papers on OpenAlex based on a query.
Args: query: The research topic or keywords to search for max_results: Maximum number of papers to return (default: 5) year_from: Only include papers from this year onwards (optional)
Returns: A formatted string with paper details including titles, authors, citations, and URLs
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | ||
| max_results | No | ||
| year_from | No |
Implementation Reference
- src/server.py:9-44 (handler)The main MCP tool handler for 'search_papers', registered via @mcp.tool(). Handles input parameters, calls the PaperFetcher helper to search OpenAlex API, formats results into a markdown string with paper details.@mcp.tool() def search_papers(query: str, max_results: int = 5, year_from: Optional[int] = None) -> str: """ Search for academic papers on OpenAlex based on a query. Args: query: The research topic or keywords to search for max_results: Maximum number of papers to return (default: 5) year_from: Only include papers from this year onwards (optional) Returns: A formatted string with paper details including titles, authors, citations, and URLs """ papers = fetcher.search_papers( query=query, max_results=max_results, year_from=year_from ) if papers and "error" in papers[0]: return papers[0]["error"] if not papers: return f"No papers found for query: {query}" result = f"Found {len(papers)} papers for '{query}':\n\n" for i, paper in enumerate(papers, 1): result += f"{i}. **{paper['title']}**\n" result += f" Authors: {paper['authors']}\n" result += f" Year: {paper['publication_year']}\n" result += f" Citations: {paper['cited_by_count']}\n" result += f" URL: {paper['url']}\n" result += f" ID: {paper['id']}\n\n" return result
- src/tools/paper_fetcher.py:13-57 (helper)Supporting utility method in PaperFetcher class that implements the core logic: constructs OpenAlex API request for paper search, handles HTTP calls, parses responses into standardized paper dictionaries using _parse_paper.def search_papers( self, query: str, max_results: int = 5, sort_by: str = "cited_by_count", year_from: Optional[int] = None ) -> List[Dict]: """ Search for papers on OpenAlex. Args: query: Search keywords max_results: Maximum number of results sort_by: Sort by 'cited_by_count', 'publication_date', or 'relevance' year_from: Only papers from this year onwards Returns: List of paper dictionaries with title, authors, abstract, etc. """ url = f"{self.BASE_URL}/works" params = { "search": query, "per_page": max_results, "sort": sort_by + ":desc" } if year_from: params["filter"] = f"publication_year:>{year_from-1}" try: response = self.client.get(url, params=params) response.raise_for_status() data = response.json() papers = [] for work in data.get("results", []): paper = self._parse_paper(work) papers.append(paper) return papers except httpx.HTTPError as e: return [{"error": f"Failed to fetch papers: {str(e)}"}]