Skip to main content
Glama
h-lu

Paper Search MCP Server

by h-lu

search_repec

Search economics research papers on RePEc/IDEAS to find working papers, journal articles, and books using advanced filters for authors, years, institutions, and JEL classifications.

Instructions

Search economics papers on RePEc/IDEAS - the largest open economics bibliography.

USE THIS TOOL WHEN:
- Searching for ECONOMICS research (macro, micro, finance, econometrics)
- You need working papers from NBER, Federal Reserve, World Bank, etc.
- You want to find papers by JEL classification
- Searching for economic policy analysis

COVERAGE: 4.5M+ items including:
- Working Papers: NBER, Fed banks, ECB, IMF, World Bank
- Journal Articles: AER, JPE, QJE, Econometrica, etc.
- Books and Book Chapters

SEARCH SYNTAX:
- Boolean: + for AND, | for OR, ~ for NOT (e.g., 'money ~liquidity')
- Phrase: use double quotes (e.g., '"monetary policy"')
- Author(Year): e.g., 'Acemoglu (2019)' or 'Kydland Prescott (1977)'
- Synonyms: automatic (labor=labour, USA=United States)
- Word stemming: automatic (find matches finds, finding, findings)

LIMITATION: RePEc provides metadata only, not full PDFs.
PDFs are hosted at original institutions (often freely available).

Args:
    query: Search terms with optional boolean operators.
    max_results: Number of results (default: 10).
    year_from: Optional start year filter (e.g., 2020).
    year_to: Optional end year filter (e.g., 2025).
    search_field: Where to search, one of:
        - 'all': Whole record (default)
        - 'abstract': Abstract only
        - 'keywords': Keywords only
        - 'title': Title only
        - 'author': Author only
    sort_by: How to sort results, one of:
        - 'relevance': Most relevant (default)
        - 'newest': Most recent first
        - 'oldest': Oldest first
        - 'citations': Most cited first
        - 'recent_relevant': Recent and relevant
        - 'relevant_cited': Relevant and cited
    doc_type: Document type filter, one of:
        - 'all': All types (default)
        - 'articles': Journal articles
        - 'papers': Working papers (NBER, Fed, etc.)
        - 'chapters': Book chapters
        - 'books': Books
        - 'software': Software components
    series: Institution/journal series to search within, one of:
        - Institutions: 'nber', 'imf', 'worldbank', 'ecb', 'bis', 'cepr', 'iza'
        - Federal Reserve: 'fed', 'fed_ny', 'fed_chicago', 'fed_stlouis'
        - Top 5 Journals: 'aer', 'jpe', 'qje', 'econometrica', 'restud'
        - Other journals: 'jfe', 'jme', 'aej_macro', 'aej_micro', 'aej_applied'

Returns:
    List of paper dicts with: paper_id (RePEc handle), title, authors,
    abstract, published_date, url, categories (JEL codes).

Example:
    search_repec('inflation', series='nber')  # Search NBER only
    search_repec('causal inference', series='aer', sort_by='newest')
    search_repec('machine learning', series='fed', year_from=2020)

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryYes
max_resultsNo
year_fromNo
year_toNo
search_fieldNoall
sort_byNorelevance
doc_typeNoall
seriesNo

Implementation Reference

  • Primary handler and registration (@mcp.tool()) for the 'search_repec' MCP tool. Defines input schema via type hints and extensive docstring. Delegates execution to _search('repec', ...) which invokes RePECSearcher.search().
    @mcp.tool()
    async def search_repec(
        query: str, 
        max_results: int = 10,
        year_from: Optional[int] = None,
        year_to: Optional[int] = None,
        search_field: str = 'all',
        sort_by: str = 'relevance',
        doc_type: str = 'all',
        series: Optional[str] = None,
    ) -> List[Dict]:
        """Search economics papers on RePEc/IDEAS - the largest open economics bibliography.
        
        USE THIS TOOL WHEN:
        - Searching for ECONOMICS research (macro, micro, finance, econometrics)
        - You need working papers from NBER, Federal Reserve, World Bank, etc.
        - You want to find papers by JEL classification
        - Searching for economic policy analysis
        
        COVERAGE: 4.5M+ items including:
        - Working Papers: NBER, Fed banks, ECB, IMF, World Bank
        - Journal Articles: AER, JPE, QJE, Econometrica, etc.
        - Books and Book Chapters
        
        SEARCH SYNTAX:
        - Boolean: + for AND, | for OR, ~ for NOT (e.g., 'money ~liquidity')
        - Phrase: use double quotes (e.g., '"monetary policy"')
        - Author(Year): e.g., 'Acemoglu (2019)' or 'Kydland Prescott (1977)'
        - Synonyms: automatic (labor=labour, USA=United States)
        - Word stemming: automatic (find matches finds, finding, findings)
        
        LIMITATION: RePEc provides metadata only, not full PDFs.
        PDFs are hosted at original institutions (often freely available).
        
        Args:
            query: Search terms with optional boolean operators.
            max_results: Number of results (default: 10).
            year_from: Optional start year filter (e.g., 2020).
            year_to: Optional end year filter (e.g., 2025).
            search_field: Where to search, one of:
                - 'all': Whole record (default)
                - 'abstract': Abstract only
                - 'keywords': Keywords only
                - 'title': Title only
                - 'author': Author only
            sort_by: How to sort results, one of:
                - 'relevance': Most relevant (default)
                - 'newest': Most recent first
                - 'oldest': Oldest first
                - 'citations': Most cited first
                - 'recent_relevant': Recent and relevant
                - 'relevant_cited': Relevant and cited
            doc_type: Document type filter, one of:
                - 'all': All types (default)
                - 'articles': Journal articles
                - 'papers': Working papers (NBER, Fed, etc.)
                - 'chapters': Book chapters
                - 'books': Books
                - 'software': Software components
            series: Institution/journal series to search within, one of:
                - Institutions: 'nber', 'imf', 'worldbank', 'ecb', 'bis', 'cepr', 'iza'
                - Federal Reserve: 'fed', 'fed_ny', 'fed_chicago', 'fed_stlouis'
                - Top 5 Journals: 'aer', 'jpe', 'qje', 'econometrica', 'restud'
                - Other journals: 'jfe', 'jme', 'aej_macro', 'aej_micro', 'aej_applied'
        
        Returns:
            List of paper dicts with: paper_id (RePEc handle), title, authors,
            abstract, published_date, url, categories (JEL codes).
        
        Example:
            search_repec('inflation', series='nber')  # Search NBER only
            search_repec('causal inference', series='aer', sort_by='newest')
            search_repec('machine learning', series='fed', year_from=2020)
        """
        kwargs = {
            'year_from': year_from,
            'year_to': year_to,
            'search_field': search_field,
            'sort_by': sort_by,
            'doc_type': doc_type,
            'series': series,
        }
        # Remove None values
        kwargs = {k: v for k, v in kwargs.items() if v is not None}
        return await _search('repec', query, max_results, **kwargs)
  • Core implementation of the RePEc search logic in RePECSearcher.search(). Constructs advanced search query for IDEAS/RePEc, scrapes results via POST request and BeautifulSoup parsing, extracts paper metadata including RePEc handles, titles, URLs, and years.
    def search(
        self, 
        query: str, 
        max_results: int = 10,
        year_from: Optional[int] = None,
        year_to: Optional[int] = None,
        search_field: str = 'all',
        sort_by: str = 'relevance',
        doc_type: str = 'all',
        series: Optional[str] = None,
    ) -> List[Paper]:
        """搜索 RePEc/IDEAS 论文
        
        支持 IDEAS 高级搜索的所有选项。
        
        搜索语法提示:
        - 布尔搜索: + 表示 AND, | 表示 OR, ~ 表示 NOT
        - 短语搜索: 使用双引号, 例如 "monetary policy"
        - 作者(年份): 例如 "Acemoglu (2019)"
        - 自动同义词: labor=labour, USA=United States
        - 词干提取: find 匹配 finds, finding, findings
        
        Args:
            query: 搜索关键词 (支持布尔运算符)
            max_results: 最大返回数量 (默认 10)
            year_from: 起始年份 (可选, 如 2020)
            year_to: 结束年份 (可选, 如 2025)
            search_field: 搜索字段, 可选值:
                - 'all': 全部字段 (默认)
                - 'abstract': 仅摘要
                - 'keywords': 仅关键词
                - 'title': 仅标题
                - 'author': 仅作者
            sort_by: 排序方式, 可选值:
                - 'relevance': 相关性 (默认)
                - 'newest': 最新发布
                - 'oldest': 最早发布
                - 'citations': 被引用最多
                - 'recent_relevant': 最新且相关
                - 'relevant_cited': 相关且被引用
            doc_type: 文档类型, 可选值:
                - 'all': 所有类型 (默认)
                - 'articles': 期刊文章
                - 'papers': 工作论文 (NBER, Fed 等)
                - 'chapters': 书籍章节
                - 'books': 书籍
                - 'software': 软件组件
            series: 研究机构/期刊系列, 可选值:
                - 机构: 'nber', 'imf', 'worldbank', 'ecb', 'bis', 'cepr', 'iza'
                - 美联储: 'fed', 'fed_ny', 'fed_chicago', 'fed_stlouis'
                - 期刊: 'aer', 'jpe', 'qje', 'econometrica', 'restud'
                - 其他: 'jfe', 'jme', 'aej_macro', 'aej_micro', 'aej_applied'
            
        Returns:
            List[Paper]: 论文列表
            
        Example:
            >>> papers = searcher.search("artificial intelligence", max_results=5)
            >>> papers = searcher.search('"monetary policy" +inflation', sort_by='newest')
            >>> papers = searcher.search("inflation", series='nber')  # 仅搜索 NBER
            >>> papers = searcher.search("causal", series='aer')  # 仅搜索 AER
        """
        if not query or not query.strip():
            return []
        
        papers = []
        seen_urls = set()  # 避免重复
        
        try:
            # 获取参数值
            wf = self.SEARCH_FIELDS.get(search_field, self.SEARCH_FIELDS['all'])
            s = self.SORT_OPTIONS.get(sort_by, self.SORT_OPTIONS['relevance'])
            
            # 处理 ul 参数: series 优先于 doc_type
            if series:
                ul = self.SERIES.get(series, series)  # 支持直接传入 handle
            else:
                ul = self.DOC_TYPES.get(doc_type, self.DOC_TYPES['all'])
            
            # 构建 POST 数据
            data = {
                'q': query,
                'wf': wf,     # 搜索字段
                's': s,       # 排序方式
                'form': 'extended',
                'wm': 'wrd',
                'dt': 'range',
            }
            
            # 添加 ul 参数 (仅当非空时)
            if ul:
                data['ul'] = ul
            
            # 添加日期范围
            if year_from:
                data['db'] = f'01/01/{year_from}'
            if year_to:
                data['de'] = f'12/31/{year_to}'
            
            # 随机延迟,避免被封
            time.sleep(random.uniform(0.5, 1.5))
            
            # 发送 POST 请求
            response = self.session.post(
                self.SEARCH_URL,
                data=data,
                timeout=self.timeout
            )
            
            if response.status_code != 200:
                logger.error(f"RePEc search failed with status {response.status_code}")
                return []
            
            # 解析 HTML
            soup = BeautifulSoup(response.text, 'html.parser')
            
            # 查找所有论文链接
            for link in soup.find_all('a', href=True):
                if len(papers) >= max_results:
                    break
                
                href = link.get('href', '')
                
                # 检查是否为论文链接
                if not self._is_paper_url(href):
                    continue
                
                # 避免重复
                if href in seen_urls:
                    continue
                seen_urls.add(href)
                
                # 解析论文
                paper = self._parse_paper_link(link, soup)
                if paper:
                    # 应用年份过滤
                    if year_from or year_to:
                        paper_year = paper.published_date.year if paper.published_date else None
                        if paper_year:
                            if year_from and paper_year < year_from:
                                continue
                            if year_to and paper_year > year_to:
                                continue
                    
                    papers.append(paper)
            
            logger.info(f"RePEc search found {len(papers)} papers for query: {query}")
            
        except requests.Timeout:
            logger.error("RePEc search timed out")
        except requests.RequestException as e:
            logger.error(f"RePEc search request failed: {e}")
        except Exception as e:
            logger.error(f"RePEc search error: {e}")
        
        return papers[:max_results]
  • Generic _search helper function used by all platform-specific tools (including search_repec). Retrieves searcher instance from SEARCHERS dict, calls its .search() method, converts Paper objects to dicts for MCP response.
    async def _search(
        searcher_name: str, 
        query: str, 
        max_results: int = 10,
        **kwargs
    ) -> List[Dict]:
        """通用搜索函数"""
        searcher = SEARCHERS.get(searcher_name)
        if not searcher:
            logger.error(f"Unknown searcher: {searcher_name}")
            return []
        
        try:
            papers = searcher.search(query, max_results=max_results, **kwargs)
            return [paper.to_dict() for paper in papers]
        except Exception as e:
            logger.error(f"Search failed for {searcher_name}: {e}")
            return []
  • Global SEARCHERS dictionary instantiation including 'repec': RePECSearcher(), providing the singleton searcher instance used by _search for the search_repec tool.
    SEARCHERS = {
        'arxiv': ArxivSearcher(),
        'pubmed': PubMedSearcher(),
        'biorxiv': BioRxivSearcher(),
        'medrxiv': MedRxivSearcher(),
        'google_scholar': GoogleScholarSearcher(),
        'iacr': IACRSearcher(),
        'semantic': SemanticSearcher(),
        'crossref': CrossRefSearcher(),
        'repec': RePECSearcher(),
    }
  • Input schema defined by function parameters (query required, others optional with defaults) and comprehensive docstring describing usage, examples, and return format (List[Dict] with paper metadata).
    async def search_repec(
        query: str, 
        max_results: int = 10,
        year_from: Optional[int] = None,
        year_to: Optional[int] = None,
        search_field: str = 'all',
        sort_by: str = 'relevance',
        doc_type: str = 'all',
        series: Optional[str] = None,
    ) -> List[Dict]:
        """Search economics papers on RePEc/IDEAS - the largest open economics bibliography.
        
        USE THIS TOOL WHEN:
        - Searching for ECONOMICS research (macro, micro, finance, econometrics)
        - You need working papers from NBER, Federal Reserve, World Bank, etc.
        - You want to find papers by JEL classification
        - Searching for economic policy analysis
        
        COVERAGE: 4.5M+ items including:
        - Working Papers: NBER, Fed banks, ECB, IMF, World Bank
        - Journal Articles: AER, JPE, QJE, Econometrica, etc.
        - Books and Book Chapters
        
        SEARCH SYNTAX:
        - Boolean: + for AND, | for OR, ~ for NOT (e.g., 'money ~liquidity')
        - Phrase: use double quotes (e.g., '"monetary policy"')
        - Author(Year): e.g., 'Acemoglu (2019)' or 'Kydland Prescott (1977)'
        - Synonyms: automatic (labor=labour, USA=United States)
        - Word stemming: automatic (find matches finds, finding, findings)
        
        LIMITATION: RePEc provides metadata only, not full PDFs.
        PDFs are hosted at original institutions (often freely available).
        
        Args:
            query: Search terms with optional boolean operators.
            max_results: Number of results (default: 10).
            year_from: Optional start year filter (e.g., 2020).
            year_to: Optional end year filter (e.g., 2025).
            search_field: Where to search, one of:
                - 'all': Whole record (default)
                - 'abstract': Abstract only
                - 'keywords': Keywords only
                - 'title': Title only
                - 'author': Author only
            sort_by: How to sort results, one of:
                - 'relevance': Most relevant (default)
                - 'newest': Most recent first
                - 'oldest': Oldest first
                - 'citations': Most cited first
                - 'recent_relevant': Recent and relevant
                - 'relevant_cited': Relevant and cited
            doc_type: Document type filter, one of:
                - 'all': All types (default)
                - 'articles': Journal articles
                - 'papers': Working papers (NBER, Fed, etc.)
                - 'chapters': Book chapters
                - 'books': Books
                - 'software': Software components
            series: Institution/journal series to search within, one of:
                - Institutions: 'nber', 'imf', 'worldbank', 'ecb', 'bis', 'cepr', 'iza'
                - Federal Reserve: 'fed', 'fed_ny', 'fed_chicago', 'fed_stlouis'
                - Top 5 Journals: 'aer', 'jpe', 'qje', 'econometrica', 'restud'
                - Other journals: 'jfe', 'jme', 'aej_macro', 'aej_micro', 'aej_applied'
        
        Returns:
            List of paper dicts with: paper_id (RePEc handle), title, authors,
            abstract, published_date, url, categories (JEL codes).
        
        Example:
            search_repec('inflation', series='nber')  # Search NBER only
            search_repec('causal inference', series='aer', sort_by='newest')
            search_repec('machine learning', series='fed', year_from=2020)
        """
        kwargs = {
            'year_from': year_from,
            'year_to': year_to,
            'search_field': search_field,
            'sort_by': sort_by,
            'doc_type': doc_type,
            'series': series,
        }
        # Remove None values
        kwargs = {k: v for k, v in kwargs.items() if v is not None}
        return await _search('repec', query, max_results, **kwargs)

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/h-lu/paper-search-mcp'

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