Skip to main content
Glama

apaper_search_iacr_papers

Search academic papers from the IACR ePrint Archive using keywords, publication year filters, and detailed result options to support cryptography research.

Instructions

Search academic papers from IACR ePrint Archive

Args: query: Search query string (e.g., 'cryptography', 'secret sharing') max_results: Maximum number of papers to return (default: 10) fetch_details: Whether to fetch detailed information for each paper (default: True) year_min: Minimum publication year (revised after) year_max: Maximum publication year (revised before)

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryYes
max_resultsNo
fetch_detailsNo
year_minNo
year_maxNo

Implementation Reference

  • MCP tool handler 'search_iacr_papers' (likely exposed as 'apaper_search_iacr_papers') that orchestrates the search using IACRSearcher and formats the results into a readable string.
    @mcp.tool()
    def search_iacr_papers(
        query: str,
        max_results: int = 10,
        fetch_details: bool = True,
        year_min: int | str | None = None,
        year_max: int | str | None = None,
    ) -> str:
        """
        Search academic papers from IACR ePrint Archive
        
        Args:
            query: Search query string (e.g., 'cryptography', 'secret sharing')
            max_results: Maximum number of papers to return (default: 10)
            fetch_details: Whether to fetch detailed information for each paper (default: True)
            year_min: Minimum publication year (revised after)
            year_max: Maximum publication year (revised before)
        """
        try:
            # Convert string parameters to integers if needed
            year_min_int = None
            year_max_int = None
            
            if year_min is not None:
                year_min_int = int(year_min)
            
            if year_max is not None:
                year_max_int = int(year_max)
            
            papers = iacr_searcher.search(
                query,
                max_results=max_results,
                fetch_details=fetch_details,
                year_min=year_min_int,
                year_max=year_max_int,
            )
    
            if not papers:
                year_filter_msg = ""
                if year_min or year_max:
                    year_range = f" ({year_min or 'earliest'}-{year_max or 'latest'})"
                    year_filter_msg = f" in year range{year_range}"
                return f"No papers found for query: {query}{year_filter_msg}"
    
            # Format the results
            year_filter_msg = ""
            if year_min or year_max:
                year_range = f" ({year_min or 'earliest'}-{year_max or 'latest'})"
                year_filter_msg = f" in year range{year_range}"
            
            result_text = f"Found {len(papers)} IACR papers for query '{query}'{year_filter_msg}:\n\n"
            
            for i, paper in enumerate(papers, 1):
                result_text += f"{i}. **{paper.title}**\n"
                result_text += f"   - Paper ID: {paper.paper_id}\n"
                result_text += f"   - Authors: {', '.join(paper.authors)}\n"
                result_text += f"   - URL: {paper.url}\n"
                result_text += f"   - PDF: {paper.pdf_url}\n"
                if paper.categories:
                    result_text += f"   - Categories: {', '.join(paper.categories)}\n"
                if paper.keywords:
                    result_text += f"   - Keywords: {', '.join(paper.keywords)}\n"
                if paper.abstract:
                    result_text += f"   - Abstract: {paper.abstract}\n"
                result_text += "\n"
    
            return result_text
        except ValueError as e:
            return f"Error: Invalid year format. Please provide valid integers for year_min and year_max."
        except Exception as e:
            return f"Error searching IACR papers: {str(e)}"
  • Core implementation of the IACR ePrint search in IACRSearcher.search(), handling HTTP requests, HTML parsing with BeautifulSoup, and paper extraction.
    def search(
        self,
        query: str,
        max_results: int = 10,
        fetch_details: bool = True,
        year_min: int | None = None,
        year_max: int | None = None,
    ) -> list[Paper]:
        """
        Search IACR ePrint Archive
    
        Args:
            query: Search query string
            max_results: Maximum number of results to return
            fetch_details: Whether to fetch detailed information for each paper (slower but more complete)
            year_min: Minimum publication year (revised after)
            year_max: Maximum publication year (revised before)
    
        Returns:
            List[Paper]: List of paper objects
        """
        papers = []
    
        try:
            # Construct search parameters
            params: dict[str, str | int] = {"q": query}
            if year_min:
                params["revisedafter"] = year_min
            if year_max:
                params["revisedbefore"] = year_max
    
            # Make request
            response = self.session.get(self.IACR_SEARCH_URL, params=params)
    
            if response.status_code != 200:
                logger.error(f"IACR search failed with status {response.status_code}")
                return papers
    
            # Parse results
            soup = BeautifulSoup(response.text, "html.parser")
    
            # Find all paper entries - they are divs with class "mb-4"
            results = soup.find_all("div", class_="mb-4")
    
            if not results:
                logger.info("No results found for the query")
                return papers
    
            # Process each result
            for i, item in enumerate(results):
                if len(papers) >= max_results:
                    break
    
                logger.info(f"Processing paper {i+1}/{min(len(results), max_results)}")
                paper = self._parse_paper(item, fetch_details=fetch_details)
                if paper:
                    papers.append(paper)
    
        except Exception as e:
            logger.error(f"IACR search error: {e}")
    
        return papers[:max_results]
  • Helper method _parse_paper that extracts and parses individual paper details from search result HTML, with option to fetch full details.
    def _parse_paper(self, item, fetch_details: bool = True) -> Paper | None:
        """Parse single paper entry from IACR HTML and optionally fetch detailed info"""
        try:
            # Extract paper ID from the search result
            header_div = item.find("div", class_="d-flex")
            if not header_div:
                return None
    
            # Get paper ID from the link
            paper_link = header_div.find("a", class_="paperlink")
            if not paper_link:
                return None
    
            paper_id = paper_link.get_text(strip=True)  # e.g., "2025/1014"
    
            if fetch_details:
                # Fetch detailed information for this paper
                logger.info(f"Fetching detailed info for paper {paper_id}")
                detailed_paper = self.get_paper_details(paper_id)
                if detailed_paper:
                    return detailed_paper
                else:
                    logger.warning(
                        f"Could not fetch details for {paper_id}, falling back to search result parsing"
                    )
    
            # Fallback: parse from search results if detailed fetch fails or is disabled
            paper_url = self.IACR_BASE_URL + paper_link["href"]
    
            # Get PDF URL
            pdf_link = header_div.find("a", href=True, string="(PDF)")
            pdf_url = self.IACR_BASE_URL + pdf_link["href"] if pdf_link else ""
    
            # Get last updated date
            last_updated_elem = header_div.find("small", class_="ms-auto")
            updated_date = None
            if last_updated_elem:
                date_text = last_updated_elem.get_text(strip=True)
                if "Last updated:" in date_text:
                    date_str = date_text.replace("Last updated:", "").strip()
                    updated_date = self._parse_date(date_str)
    
            # Get content from the second div
            content_div = item.find("div", class_="ms-md-4")
            if not content_div:
                return None
    
            # Extract title
            title_elem = content_div.find("strong")
            title = title_elem.get_text(strip=True) if title_elem else ""
    
            # Extract authors
            authors_elem = content_div.find("span", class_="fst-italic")
            authors = []
            if authors_elem:
                authors_text = authors_elem.get_text(strip=True)
                authors = [author.strip() for author in authors_text.split(",")]
    
            # Extract category
            category_elem = content_div.find("small", class_="badge")
            categories = []
            if category_elem:
                category_text = category_elem.get_text(strip=True)
                categories = [category_text]
    
            # Extract abstract
            abstract_elem = content_div.find("p", class_="search-abstract")
            abstract = abstract_elem.get_text(strip=True) if abstract_elem else ""
    
            # Create paper object with search result data
            published_date = updated_date if updated_date else datetime(1900, 1, 1)
    
            return Paper(
                paper_id=paper_id,
                title=title,
                authors=authors,
                abstract=abstract,
                url=paper_url,
                pdf_url=pdf_url,
                published_date=published_date,
                updated_date=updated_date,
                source="iacr",
                categories=categories,
                keywords=[],
                doi="",
                citations=0,
            )
    
        except Exception as e:
            logger.warning(f"Failed to parse IACR paper: {e}")
            return None
  • Registration of the apaper MCP server in the proxy configuration, enabling the tools including apaper_search_iacr_papers when APAPER=true.
    if _str_to_bool(os.getenv("APAPER", "false")):
        config["mcpServers"]["apaper"] = {
            "type": "stdio",
            "command": "python",
            "args": [str(apaper_server_path)],
        }

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/isomoes/all-in-mcp'

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