search_papers
Search arXiv research papers using queries, filters by date and categories, and retrieves results for academic research.
Instructions
Search for papers on arXiv with advanced filtering
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | ||
| max_results | No | ||
| date_from | No | ||
| date_to | No | ||
| categories | No |
Implementation Reference
- The handler function that executes the search_papers tool. It searches arXiv using the arxiv library, applies filters for dates and categories, processes results, and returns JSON-formatted paper information.
async def handle_search(arguments: Dict[str, Any]) -> List[types.TextContent]: """Handle paper search requests.""" try: client = arxiv.Client() max_results = min(int(arguments.get("max_results", 10)), settings.MAX_RESULTS) # Build search query with category filtering query = arguments["query"] if categories := arguments.get("categories"): category_filter = " OR ".join(f"cat:{cat}" for cat in categories) query = f"({query}) AND ({category_filter})" search = arxiv.Search( query=query, max_results=max_results, sort_by=arxiv.SortCriterion.SubmittedDate, ) # Process results with date filtering results = [] try: date_from = ( parser.parse(arguments["date_from"]).replace(tzinfo=timezone.utc) if "date_from" in arguments else None ) date_to = ( parser.parse(arguments["date_to"]).replace(tzinfo=timezone.utc) if "date_to" in arguments else None ) except (ValueError, TypeError) as e: return [ types.TextContent( type="text", text=f"Error: Invalid date format - {str(e)}" ) ] for paper in client.results(search): if _is_within_date_range(paper.published, date_from, date_to): results.append(_process_paper(paper)) if len(results) >= max_results: break response_data = {"total_results": len(results), "papers": results} return [ types.TextContent(type="text", text=json.dumps(response_data, indent=2)) ] except Exception as e: return [types.TextContent(type="text", text=f"Error: {str(e)}")] - Defines the Tool object for 'search_papers' including name, description, and input schema for parameters like query, max_results, date_from, date_to, categories.
search_tool = types.Tool( name="search_papers", description="Search for papers on arXiv with advanced filtering", inputSchema={ "type": "object", "properties": { "query": {"type": "string"}, "max_results": {"type": "integer"}, "date_from": {"type": "string"}, "date_to": {"type": "string"}, "categories": {"type": "array", "items": {"type": "string"}}, }, "required": ["query"], }, ) - src/arxiv_mcp_server/server.py:41-45 (registration)Registers the search_tool (and others) by returning it in the list_tools() method, making it discoverable by MCP clients.
@server.list_tools() async def list_tools() -> List[types.Tool]: """List available arXiv research tools.""" return [search_tool, download_tool, list_tool, read_tool] - src/arxiv_mcp_server/server.py:47-65 (registration)The call_tool handler dispatches to handle_search when name is 'search_papers', effectively registering the handler implementation.
@server.call_tool() async def call_tool(name: str, arguments: Dict[str, Any]) -> List[types.TextContent]: """Handle tool calls for arXiv research functionality.""" logger.debug(f"Calling tool {name} with arguments {arguments}") try: if name == "search_papers": return await handle_search(arguments) elif name == "download_paper": return await handle_download(arguments) elif name == "list_papers": return await handle_list_papers(arguments) elif name == "read_paper": return await handle_read_paper(arguments) else: return [types.TextContent(type="text", text=f"Error: Unknown tool {name}")] except Exception as e: logger.error(f"Tool error: {str(e)}") return [types.TextContent(type="text", text=f"Error: {str(e)}")] - Helper function to process arXiv paper result into a standardized dictionary with fields like id, title, authors, etc., including resource URI.
def _process_paper(paper: arxiv.Result) -> Dict[str, Any]: """Process paper information with resource URI.""" return { "id": paper.get_short_id(), "title": paper.title, "authors": [author.name for author in paper.authors], "abstract": paper.summary, "categories": paper.categories, "published": paper.published.isoformat(), "url": paper.pdf_url, "resource_uri": f"arxiv://{paper.get_short_id()}", }