Skip to main content
Glama

Web Research MCP

AI 에이전트를 위한 고품질 다중 소스 웹 리서치 MCP 서버입니다. Claude Desktop, Hermes, Cursor 또는 모든 MCP 호환 클라이언트에 연결하면 Wikipedia, arXiv, Hacker News, Stack Exchange, Crossref, Brave, Tavily 및 웹의 모든 URL에 대한 프로덕션급 검색 + 페이지 가져오기를 사용할 수 있습니다.

MCP Python License: MIT GitHub stars CI

# One-line install (anywhere on disk)
git clone https://github.com/infinit3labs/web-research-mcp.git
hermes mcp add web-research --command "$(pwd)/web-research-mcp/bin/web-research-mcp"
# 6 of 7 tools work with zero API keys. Add Brave or Tavily to unlock general web search.

왜 이런 서버가 필요한가

대부분의 "웹 검색" MCP 서버는 무작위 핑거프린트를 사용해 헤드리스 브라우저로 Google을 스크래핑하려고 합니다. 이 접근 방식은 지는 전쟁입니다 — 검색 엔진은 며칠 안에 스크래퍼를 감지하고 차단하며, 설령 작동하더라도 LLM이 정리해야 하는 DOM 스프를 얻게 됩니다.

이 서버는 다른 접근 방식을 취합니다 — 에이전트를 위해 만들어진 API와 통신합니다:

기능

방식

실제 웹 검색

Brave Search API, Tavily API (화이트리스트, 순위 기반, 구조화된 JSON)

모든 URL 읽기

Jina Reader (JS 렌더링 + 안티봇 처리, 깔끔한 마크다운 반환)

백과사전식 조회

Wikipedia MediaWiki API

학술 프리프린트

arXiv API

피어리뷰 논문

Crossref API

기술 동향 신호

Hacker News Algolia API

코드 Q&A

Stack Exchange API (모든 사이트)

7개 소스 모두 API 키 없이 작동합니다. Brave 또는 Tavily 키를 추가하면 실시간 일반 웹 검색이 잠금 해제됩니다. 이것이 최고 품질의 접근 방식입니다 — 실제 웹 인덱스 API는 어떤 스크래퍼도 재현할 수 없는 신호(클릭 모델, 신선도, 링크 분석)를 사용하므로 스크래핑보다 더 나은 결과를 얻을 수 있습니다.


빠른 시작

옵션 A — pip install (배포 시)

pip install deep-web-research-mcp
hermes mcp add web-research --command "$(which web-research-mcp)"

이름에 대한 참고 사항. PyPI 배포 이름은 deep-web-research-mcp입니다(pip install deep-web-research-mcp). 하지만 설치 후 PATH의 바이너리는 web-research-mcp입니다(pyproject.toml[project.scripts]에 정의됨). 의도적인 설계입니다 — 바이너리는 로컬 런처 bin/web-research-mcp 및 MCP 등록 이름 web-research와 일치합니다. 동일한 패키지, 두 개의 이름.

옵션 B — 소스에서 클론

git clone https://github.com/infinit3labs/web-research-mcp.git
hermes mcp add web-research \
  --command "$(pwd)/bin/web-research-mcp"

프롬프트가 표시되면 7개 도구를 모두 수락하세요. 완료입니다.

옵션 C — Claude Desktop으로 설치

~/Library/Application Support/Claude/claude_desktop_config.json을 편집하세요:

{
  "mcpServers": {
    "web-research": {
      "command": "/Users/code/mcp-servers/web-research/bin/web-research-mcp"
    }
  }
}

옵션 D — Cursor / 모든 stdio MCP 클라이언트로 설치

{
  "mcpServers": {
    "web-research": {
      "command": "/absolute/path/to/web-research-mcp/bin/web-research-mcp"
    }
  }
}

런처 스크립트는 첫 실행 시 venv를 자동 생성하고 pyproject.toml에서 종속성을 설치하며, 구성한 API 키를 위해 web-research.env를 소싱합니다.

2. (선택 사항) 실제 웹 검색을 위한 API 키 추가

cp web-research.env.example web-research.env
$EDITOR web-research.env

잠금 해제 기능

무료 티어

BRAVE_API_KEY

search_web 실제 일반 웹 인덱스

월 2,000회 쿼리

TAVILY_API_KEY

search_web + 리서치 최적화 스니펫

월 1,000회 쿼리

JINA_API_KEY

fetch_url 더 높은 가져오기 속도

월 1M 토큰

런처는 매 호출마다 web-research.env에서 키를 읽습니다 — MCP 클라이언트를 재시작할 필요가 없습니다.

3. 사용하기

에이전트에게 다음과 같이 요청하세요:

"Hacker News와 Stack Overflow에서 2026년에 출시된 최고의 MCP 서버를 검색해줘"

"pro_mode를 사용하여 소형 언어 모델의 현재 상태를 리서치해줘"

"https://arxiv.org/abs/2506.06962를 가져와서 방법론을 요약해줘"

"이 주장을 Wikipedia와 arXiv와 교차 검증해줘"


도구

tools/list에 등록된 10개 도구. 도구는 두 계층으로 나뉩니다:

  • 검색 및 가져오기 (7개 도구) — 단발성 조회. 하나의 도구, 하나의 API, 하나의 결과.

  • 딥 리서치 (3개 도구) — 계획, 수집, 구조화된 증거를 만드는 다단계 파이프라인. 단일 검색으로 충분하지 않을 때 사용하세요.

검색 및 가져오기

search_web — 다중 소스 일반 웹 검색

search_web(
    query: str,                  # search query
    max_results: int = 10,       # per source, before dedup (1–30)
    pro_mode: bool = False,      # also fetch top 3 URLs and append excerpts
) -> str

Brave + Tavily 기반으로 URL 정규화 중복 제거 및 교차 소스 점수 부스팅을 제공합니다. BRAVE_API_KEY 및/또는 TAVILY_API_KEY가 필요합니다. 키가 없으면 활성화 방법을 알려주는 명확한 메시지를 반환합니다.

pro_mode: true는 리서치 킬러 기능입니다 — 일반 검색을 실행하고 Jina를 통해 상위 3개 결과를 가져와 콘텐츠를 스니펫으로 추가합니다. 한 번의 호출로 search_web + 3 × fetch_url을 대체합니다.

fetch_url — 모든 페이지의 깔끔한 마크다운

fetch_url(url: str) -> str

Jina Reader를 통해 처리되며, 다음을 수행합니다:

  • JS가 많은 페이지 렌더링 (SPA, React 앱)

  • 대부분의 봇 감지 우회 (Jina는 화이트리스트에 있음)

  • 메타데이터 블록(Title:, URL Source:, Published Time:)이 포함된 깔끔한 마크다운 반환

  • 컨텍스트 창을 보호하기 위해 ~20k자로 잘라냄

search_wikipedia — 백과사전적 근거

search_wikipedia(query: str, max_results: int = 5) -> str

Wikipedia MediaWiki API. 키 없음. 빠름. 정의 및 역사적 맥락에 가장 적합.

search_academic — arXiv 프리프린트

search_academic(query: str, max_results: int = 5) -> str

제목, 저자, 초록 스니펫, 게시 날짜, PDF URL을 반환합니다. 키 없음. CS, 물리학, 수학, 생물학에 가장 적합.

search_news — Hacker News 신호

search_news(query: str, max_results: int = 10) -> str

제목, URL, 포인트, 댓글, 날짜를 반환합니다. 키 없음. 현재 기술 트렌드에 가장 적합.

search_stackexchange — 180개 이상 사이트의 Q&A

search_stackexchange(query: str, max_results: int = 5, site: str = "stackoverflow") -> str

site를 모든 SE 커뮤니티로 설정하세요: serverfault, superuser, askubuntu, math, tex, datascience, ai 등. 키 없음.

search_scholar_meta — Crossref를 통한 피어리뷰 논문

search_scholar_meta(query: str, max_results: int = 5) -> str

제목, DOI, 인용 횟수, 출판사, 출판 날짜, 초록을 반환합니다. arXiv가 다루지 않는 논문(Elsevier, Springer, Wiley, IEEE, ACM)을 포함합니다. 키 없음.

딥 리서치

이 세 도구는 위의 검색/가져오기 기본 요소를 다단계 리서치 워크플로우로 구성합니다. 자체적으로 LLM을 호출하지 않습니다 — 호출 모델이 최종 내러티브 작성의 책임을 유지합니다. 서버의 역할은 검증 가능한 인용과 함께 증거를 계획, 수집, 구조화하는 것입니다.

plan_research — 구조화된 계획만 (가져오기 없음)

plan_research(question: str, depth: str = "standard") -> str  # JSON

JSON 리서치 계획을 반환합니다: 하위 질문, 하위 질문별 권장 소스, 근거, 실행할 쿼리, 예상 검색 및 가져오기 수. 전체 파이프라인을 실행하기 전에 계획을 검토하거나 수정하려는 경우 사용하세요.

  • depth: "quick" (2-3개 하위 질문), "standard" (4-6개), "deep" (6-8개)

extract_evidence — 하나의 URL에서 타겟 인용문 추출

extract_evidence(
    url: str,
    question: str,
    max_passages: int = 5,
) -> str  # JSON

Jina를 통해 URL을 가져오고, 문단으로 분할하고, 질문과의 관련성을 각각 점수화하고, 상위 구절을 반환합니다. 각 구절에는 before / quote / after 컨텍스트, relevance 점수(0-1), offset(소스의 문자 위치)이 포함되어 인용을 독립적으로 검증할 수 있습니다.

이미 특정 소스가 있고 좁은 주장에 대한 증거를 찾으려는 경우 사용하세요.

research — 전체 딥 리서치 파이프라인

research(question: str, depth: str = "standard") -> str  # markdown + JSON

종단 간 리서치 워크플로우:

  1. 계획 — 하위 질문 계획 수립

  2. 팬아웃 — 각 하위 질문에 대해 권장 소스에서 병렬로 검색

  3. 순위 — 전체 계획에서 URL 중복 제거, 소스 인식 복합 점수로 순위 지정 (Wikipedia/arXiv/Crossref 2.0×, Stack Exchange 1.7×, 웹 검색 1.5×, Hacker News 1.0×)

  4. 가져오기 — Jina Reader를 통해 상위 URL 가져오기

  5. 추출 — 품질 기준으로 문단 관련성 점수화 (내비게이션 메뉴, 링크 전용 문단, 푸터 잡음 필터링)

  6. 반환 — 구조화된 ResearchReport 출력:

{
  "question": "What is retrieval augmented generation?",
  "depth": "quick",
  "plan": { "sub_questions": [...], "estimated_searches": 4, ... },
  "citations": [
    { "id": 1, "url": "...", "title": "...", "source": "wikipedia", "quotes": 2 }
  ],
  "evidence": {
    "sq_def": [
      { "citation_id": 1, "relevance": 0.78, "offset": 1234,
        "before": "...", "quote": "...", "after": "..." }
    ]
  },
  "synthesis_template": "# Research Report: ..."
}

synthesis_template은 각 하위 질문당 하나의 섹션과 Sources 테이블이 있는 Markdown 스켈레톤입니다. 모델(당신)이 내러티브를 작성하고 각 [n] 마커를 citations의 해당 항목에 인용합니다. 모든 인용 구절은 문자 offset을 포함하므로 독자가 원본 페이지에서 인용을 검증할 수 있습니다.

depth는 범위를 제어합니다:

  • "quick" — 2-3개 하위 질문, ~6회 가져오기, ~2분

  • "standard" — 4-6개 하위 질문, ~20회 가져오기, ~3분

  • "deep" — 6-8개 하위 질문, ~32회 가져오기, ~5분


아키텍처

┌─────────────────────────────────────────────────────────┐
│                    MCP Client                            │
│  (Claude Desktop, Hermes, Cursor, custom agent)          │
└────────────────────┬────────────────────────────────────┘
                     │ JSON-RPC over stdio
                     ▼
┌─────────────────────────────────────────────────────────┐
│              bin/web-research-mcp                         │
│  • Boots venv (or reuses cached one)                     │
│  • Sources web-research.env for API keys                 │
│  • Execs python -m web_research.server                   │
└────────────────────┬────────────────────────────────────┘
                     ▼
┌─────────────────────────────────────────────────────────┐
│           web_research.server (MCPServer)                 │
│  7 tool functions registered via @app.tool() decorator    │
│  • Pydantic-driven JSON schemas from type hints           │
│  • Single shared httpx.AsyncClient per call              │
│  • Graceful degradation: one bad source ≠ failed call    │
└────────────────────┬────────────────────────────────────┘
                     │ asyncio.gather for parallel fan-out
                     ▼
┌─────────────────────────────────────────────────────────┐
│          web_research.providers (7 backends)              │
│  ┌──────────┐ ┌──────────┐ ┌─────────────┐               │
│  │ brave    │ │ tavily   │ │ jina_fetch  │  ← general web│
│  └──────────┘ └──────────┘ └─────────────┘               │
│  ┌──────────┐ ┌──────────┐ ┌─────────────┐               │
│  │ wikipedia│ │ arxiv    │ │ crossref    │  ← academic   │
│  └──────────┘ └──────────┘ └─────────────┘               │
│  ┌──────────┐ ┌──────────┐                                │
│  │ hn_algolia│ │stackex   │  ← tech signal               │
│  └──────────┘ └──────────┘                                │
│  + merge_results() with URL-canonical dedup               │
└─────────────────────────────────────────────────────────┘

주요 설계 결정

스크래핑 우선이 아닌 API 우선. 이것이 핵심 논지입니다. 모든 소스는 프로그래밍 방식 액세스를 위해 설계된 공식 API입니다. 깨끗한 구조화된 데이터를 얻을 수 있고, IP 차단이 없으며, 사이트 재설계 시 유지 관리 부담이 없습니다.

소스별 오류 격리. 각 공급자는 HTTP 호출을 try/except로 감쌉니다. 한 소스의 429 오류가 전체 검색을 망치지 않습니다 — 부분 결과와 어떤 소스가 실패했는지에 대한 명확한 메시지를 얻을 수 있습니다.

URL 정규화. merge_results()는 중복 제거 전에 추적 파라미터(utm_*, fbclid, gclid, ref)를 제거하고, 호스트의 대소문자를 정규화하며, 프래그먼트를 제거합니다. Brave와 Tavily가 동일한 기사를 반환하면 also_found_in: [brave, tavily]와 부스팅된 점수로 한 번만 표시됩니다.

호출당 공유 HTTP 클라이언트. 연결 풀링(max_connections=20), 적절한 타임아웃(30s 기본, fetch_url45s), 자동 리디렉션 추적이 있는 httpx.AsyncClient. stdio MCP 서버는 한 번에 하나의 요청을 처리하므로 호출당 새 클라이언트를 사용하여 깨끗한 상태를 유지합니다.

헤드리스 브라우저 없음. Playwright, Selenium, Puppeteer 또는 프록시 로테이션 제로. 더 작은 공격 표면, 더 작은 종속성, JVM/Chrome 풋프린트 없음. JS 렌더링이 필요한 소수의 사이트는 Jina가 처리합니다.


대안과의 비교

기능

이 서버

SerpAPI MCP

Google 스크래핑 MCP

로컬 검색 MCP

일반 웹 인덱스

✅ Brave/Tavily

✅ Google

⚠️ 취약함

API 전용 (스크래핑 없음)

JS 렌더링 처리

✅ Jina 경유

⚠️ 다양함

학술 소스

✅ arXiv + Crossref

⚠️

기술/Q&A 소스

✅ HN + StackExchange

백과사전

✅ Wikipedia

⚠️

API 키 없이 동작

✅ (7개 중 6개 도구)

인용 친화적 출력

⚠️

⚠️

MIT 라이선스

⚠️

⚠️

⚠️


테스트

.venv/bin/python tests/e2e_protocol.py

실제 서버를 시작하고 실제 MCP initialize + tools/list 핸드셰이크를 수행한 다음 모든 도구에 대해 실시간 JSON-RPC 호출을 실행하여 다음을 검증합니다:

  • 실제 API가 실제 데이터를 반환 (스텁 아님)

  • 각 도구의 응답이 예상된 형태를 가짐

  • 오류 상태가 정상적으로 처리됨

  • 키 없는 search_web가 명확한 "API 키 설정" 메시지를 반환

마지막 실행: 7/7 도구가 실시간 API에 대해 통과.


문제 해결

서버가 시작되지만 MCP 클라이언트에 도구가 표시되지 않음

hermes mcp list(또는 이에 상응하는 명령)를 확인하세요. 서버는 --command로 등록되어 있으므로 Hermes가 런처를 직접 실행합니다. 런처가 실행 가능한지 확인하세요:

chmod +x bin/web-research-mcp

fetch_url이 잘린 콘텐츠를 반환함

설계상 20k 문자 제한은 컨텍스트 윈도우를 보호합니다. 더 긴 문서를 읽으려면 직접 페이지를 가져와 search_web에 발췌문을 전달해 후속 질문을 하거나, 여러 번 호출로 섹션을 나누세요.

search_web이 "웹 결과가 없습니다. API 키가 구성되지 않았기 때문일 가능성이 높습니다."를 반환합니다

web-research.envBRAVE_API_KEY 또는 TAVILY_API_KEY 중 하나 이상을 설정해야 합니다. 나머지 6개 도구(Wikipedia, arXiv, HN, Stack Exchange, Crossref, fetch_url)는 키 없이 모두 작동합니다.

Stack Exchange가 400 Bad Request를 반환합니다

커스텀 filter 매개변수를 구성한 경우 API가 알 수 없는 필터 ID를 거부합니다. 기본 필터를 사용하세요(매개변수 생략) — 필요한 것보다 더 많은 필드를 반환하지만 모든 것이 작동합니다. 이 서버는 기본값을 사용합니다.

첫 실행 시 서버가 충돌합니다

stderr에서 실제 traceback을 확인하세요. 일반적인 원인: Python <3.10. python3 --version으로 확인하세요.

속도 제한

각 키 없는 API에는 자체 제한이 있습니다. 제한에 도달하면:

  • Wikipedia: 분당 약 200회 요청, 실제 User-Agent로 자신을 식별하세요(이 서버는 하나를 전송합니다)

  • arXiv: 인증되지 않은 경우 약 3초에 1회 요청, 백오프해 주세요

  • Hacker News Algolia: API 키 사용 시 시간당 10k 요청, 키 없이 5k

  • Stack Exchange: 키 없이 하루 300회 요청(연구 세션에 충분함)

  • Crossref: User-Agent에 mailto를 추가해 주세요(이 서버는 추가합니다), 그러면 폴라이트 풀에서 무제한


개발

프로젝트 구조

web-research-mcp/
├── bin/
│   └── web-research-mcp          # Launcher: venv bootstrap + exec
├── src/web_research/
│   ├── __init__.py
│   ├── server.py                  # MCPServer + 7 @app.tool functions
│   └── providers.py               # 7 search backends + Result dataclass
├── tests/
│   └── e2e_protocol.py            # Real subprocess JSON-RPC test
├── web-research.env.example       # API key template
├── pyproject.toml                 # PEP 621, uv-installable
├── README.md
├── CHANGELOG.md
├── LICENSE
└── .gitignore

새 도구 추가

  1. providers.py에 비동기 함수를 추가하세요:

    async def search_my_source(query: str, max_results: int, client: httpx.AsyncClient) -> list[Result]:
        try:
            # ... your HTTP call ...
        except Exception as e:
            print(f"[my_source] error: {e}", flush=True)
            return []
        return [Result(title=..., url=..., snippet=..., source="my_source")]
  2. server.py에 등록하세요:

    @app.tool(name="search_my_source", description="...", annotations=ToolAnnotations(readOnlyHint=True, openWorldHint=True))
    async def search_my_source(query: Annotated[str, Field(description="Search query")], max_results: Annotated[int, Field(ge=1, le=10, default=5)] = 5) -> str:
        async with await _new_client() as client:
            res = await providers.search_my_source(query, max_results, client)
        return _format_results(query, res, "my_source") if res else f"No my_source results for: {query}"
  3. tests/e2e_protocol.py에 라이브 테스트 케이스를 추가하세요.

  4. README의 Tools 섹션을 업데이트하세요.

코딩 스타일

  • Python 3.10+, async 우선

  • 모든 곳에 타입 힌트; Pydantic이 MCP JSON 스키마를 파생하도록 하세요

  • 모든 provider는 네트워크 호출을 try/except로 감싸고 []로 폴백합니다

  • 호출별 HTTP 클라이언트(_new_client()) — stdio 모드에서 호출 간 공유하지 마세요


기여

PR 환영합니다. 열기 전에:

  1. 라이브 설치에 대해 e2e 테스트를 실행하세요: .venv/bin/python tests/e2e_protocol.py

  2. 새 도구에 대한 테스트 케이스를 추가하세요

  3. providers.py를 MCP 특정 타입과 독립적으로 유지하세요 — 일반 Python 모듈로 재사용 가능해야 합니다

  4. 헤드리스 브라우저나 프록시 로테이션에 의존성을 추가하지 마세요 — 이는 프로젝트의 핵심 주제를 위반합니다

주요 변경 사항의 경우 먼저 이슈를 여세요.


라이선스

MIT — LICENSE 참조.

크레딧

-
license - not tested
Not graded
quality - not tested
A
maintenance

Maintenance

Maintainers
Response time
0dRelease cycle
2Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

  • The best web search for your AI Agent

  • Web research for agents: quality-scored Google search, webpage extraction, and deep research.

  • LLM-ready web search + instant answers + URL-to-clean-text fetch for agents and RAG.

View all MCP Connectors

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/infinit3labs/web-research-mcp'

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