Przejdź do głównej zawartości

Wyszukiwanie i scraping przez MCP: Firecrawl, Exa, Tavily, Brave i MarkItDown

Serwery MCP do researchu w sieci dają agentowi kodującemu aktualne informacje spoza repozytorium: Exa, Brave Search i Tavily przeszukują sieć, Firecrawl i referencyjny serwer Fetch zamieniają strony w Markdown, a MarkItDown konwertuje pliki PDF i dokumenty Office. Wszystko, co zwracają, jest niezaufanym wejściem, więc wnioski wymagają cytatów, które sprawdzi skrypt.

Masz zdecydować, czy przenieść serwis z Express 4 na Express 5, a agent odpowiada z danych treningowych, które kończą się przed interesującym cię wydaniem. Albo szuka, czyta sześć stron i pisze pewne siebie podsumowanie, w którym jedna „zmiana łamiąca” nie występuje w żadnym źródle. Pierwszy problem to brak kontekstu. Drugi to kontekst, którego nie da się sprawdzić, i to on trafia na produkcję.

Ta strona jest dla programistów, którzy chcą, żeby agent badał temat na żywych źródłach, i dla tech leadów, którzy potrzebują, żeby spike badawczy (research spike) kończył się rekordem decyzji architektonicznej (ADR), który recenzent sprawdzi bez ponownego czytania każdej strony przeczytanej przez agenta.

  • Tabelę decyzyjną dla Firecrawl, Exa, Tavily, Brave Search, Fetch i MarkItDown: co robi każdy z nich, ile kosztuje start i gdzie trafia klucz.
  • Polecenia instalacji dla Claude Code, Codex i Cursora, które trzymają klucze API poza adresami URL i poza commitowanymi plikami.
  • Działający przykład: pobranie changeloga przez scraper i lista zmian łamiących od v4.
  • Workflow spike’a badawczego zakończony szkicem ADR, w którym każdy cytat sprawdza krótki skrypt.
  • Typowe awarie i pułapki nazewnicze wraz ze sposobem wyjścia z każdej.

Sześć serwerów dzieli się na trzy zadania: znaleźć źródła, przeczytać znany URL i przekonwertować plik. Większość zespołów potrzebuje jednego serwera wyszukiwania i jednego do czytania, a nie wszystkich sześciu. Wersje i nazwy pakietów sprawdzono w npm i PyPI 2026-09-26.

SerwerZadaniePołączenieDarmowy startUwierzytelnianiePakiet / endpoint
FirecrawlScraping, wyszukiwanie, crawl, mapa witryny, parsowanie plikówZdalny HTTP albo lokalny stdioTak: hostowany endpoint ma darmowy poziom bez klucza, z limitami, dla scrape, search i parse; crawl, map i agent wymagają kluczaEndpoint OAuth albo nagłówek Authorization: Bearerhttps://mcp.firecrawl.dev/v2/mcp; npm firecrawl-mcp 3.25.5
ExaWyszukiwanie semantyczne i pobieranie stronZdalny HTTPTak: działa anonimowo z limitamiZalecany OAuth; klucz w nagłówkuhttps://mcp.exa.ai/mcp; npm exa-mcp-server 3.4.1
TavilyWyszukiwanie, ekstrakcja, mapa, crawlZdalny HTTP albo lokalny stdioWymaga konta; Tavily oferuje darmowe kontoOAuth albo nagłówek Authorization: Bearerhttps://mcp.tavily.com/mcp; npm tavily-mcp 0.2.22
Brave SearchWyszukiwanie w sieci, newsach, obrazach, wideo i lokalne, plus narzędzie kontekstu dla LLMLokalny stdio (domyślny od 2.x) albo HTTPWymaga klucza Brave Search APIZmienna środowiskowa BRAVE_API_KEYnpm @brave/brave-search-mcp-server 2.1.4
Fetch (serwer referencyjny)Czytanie jednego URL-a jako Markdown, w porcjachLokalny stdioTak: darmowy, bez kontaBrakPyPI mcp-server-fetch 2026.8.18
MarkItDownKonwersja PDF, Word, Excel, PowerPoint, HTML, EPUB i innych do MarkdownLokalny stdio (albo HTTP na localhost)Tak: darmowy, bez kontaBrakPyPI markitdown-mcp 0.0.1a7 (alfa)

Jak wybrać:

  • Zacznij od endpointu Firecrawl bez klucza, jeśli chcesz jednego serwera, który i szuka, i scrapuje. Klucz dodaj, gdy potrzebujesz crawl albo map.
  • Wybierz Exa, gdy pytanie jest pojęciowe („zgłoszenia tego błędu i znane obejścia”), a wyszukiwanie po słowach kluczowych zwraca szum. Domyślne narzędzia to web_search_exa i web_fetch_exa.
  • Wybierz Brave Search, gdy chcesz niezależnego indeksu i lokalnego procesu, którego listę narzędzi kontrolujesz przez BRAVE_MCP_ENABLED_TOOLS.
  • Wybierz Tavily, gdy zespół ma już konto Tavily; zestaw narzędzi pokrywa się z Firecrawl.
  • Dodaj Fetch do pojedynczych stron, gdy nie chcesz w pętli żadnej usługi zewnętrznej. Respektuje robots.txt dla żądań inicjowanych przez model.
  • Dodaj MarkItDown tylko do plików: PDF od dostawcy, zapytanie ofertowe w Wordzie, cennik w Excelu.

Czy do researchu w sieci w ogóle potrzebujesz serwera MCP?

Dział zatytułowany „Czy do researchu w sieci w ogóle potrzebujesz serwera MCP?”

Nie zawsze. Zanim dodasz serwer, sprawdź, co agent już ma.

  • Claude Code ma wbudowane narzędzia WebFetch i WebSearch. WebSearch nie działa w Amazon Bedrock ani we wdrożeniach Microsoft Foundry hostowanych na Azure (sprawdzone w dokumentacji narzędzi Claude Code, v2.1.283; zob. konfiguracja bramki LLM).
  • Codex włącza wyszukiwanie na żywo przez codex --search, co udostępnia natywne narzędzie web_search bez zatwierdzania każdego wywołania. codex exec --help w codex-cli 0.157.1 nie wymienia flagi --search.
  • MarkItDown ma CLI, więc agent z dostępem do powłoki skonwertuje plik bez serwera MCP: uvx --from 'markitdown[all]' markitdown spec.pdf -o spec.md.

Serwer dodaj wtedy, gdy wbudowane narzędzia nie wystarczają: potrzebujesz crawla przez wiele stron, indeksu wyszukiwania wspólnego dla całego zespołu, ekstrakcji do ustrukturyzowanego JSON-a albo tego samego setupu we wszystkich trzech narzędziach.

Instalacja serwerów do researchu w Claude Code, Codex i Cursorze

Dział zatytułowany „Instalacja serwerów do researchu w Claude Code, Codex i Cursorze”

Polecana para to Firecrawl (scraping i wyszukiwanie) plus Exa (wyszukiwanie). Oba są zdalne, więc lokalnie nic nie instalujesz. Pozostałe cztery są niżej. Każdy klucz jest czytany ze środowiska i nigdy nie trafia do URL-a: README Firecrawl mówi wprost „Never put an API key in the server URL”, a formy ?tavilyApiKey= i ?exaApiKey= z dokumentacji Tavily i Exa lądują w historii powłoki, plikach konfiguracyjnych i logach proxy.

Uruchom w terminalu w katalogu głównym repozytorium. --scope project zapisuje współdzielony .mcp.json; pojedyncze cudzysłowy zostawiają ${FIRECRAWL_API_KEY} jako referencję, którą Claude Code rozwija przy łączeniu (przetestowane na Claude Code 2.1.283):

Okno terminala
# Firecrawl z kluczem (pełny zestaw narzędzi)
claude mcp add --scope project --transport http firecrawl https://mcp.firecrawl.dev/v2/mcp \
--header 'Authorization: Bearer ${FIRECRAWL_API_KEY}'
# Albo Firecrawl bez klucza: tylko scrape, search i parse, z limitami
claude mcp add --scope project --transport http firecrawl https://mcp.firecrawl.dev/v2/mcp
# Exa, tylko domyślne narzędzia; zaloguj się przez /mcp, żeby podnieść limity
claude mcp add --scope project --transport http exa 'https://mcp.exa.ai/mcp?tools=web_search_exa,web_fetch_exa'

Pozostałe:

Okno terminala
claude mcp add --scope project --transport http tavily https://mcp.tavily.com/mcp # OAuth przez /mcp
claude mcp add --scope project brave-search -e 'BRAVE_API_KEY=${BRAVE_API_KEY}' -- npx -y @brave/brave-search-mcp-server
claude mcp add --scope project fetch -- uvx mcp-server-fetch
claude mcp add --scope project markitdown -- uvx markitdown-mcp

Są też pluginy: claude plugin install exa@claude-plugins-official (z README Exa) oraz plugin firecrawl w tym samym marketplace. Wpis tavily w claude-plugins-official wskazuje na repozytorium skilli Tavily, a nie na serwer MCP.

Dla serwerów logujących się przez OAuth (Exa, Tavily, https://mcp.firecrawl.dev/v2/mcp-oauth od Firecrawl) uruchom /mcp w sesji albo claude mcp login <nazwa>.

Fetch i MarkItDown to pakiety Pythona: potrzebują uv (dla uvx) i Pythona 3.10 lub nowszego, i żaden z nich nie jest opublikowany w npm (w npm pod nazwą mcp-server-fetch jest tylko zaślepka 0.0.1-security, sprawdzone 2026-09-26). npx jest właściwy tylko dla Firecrawl, Tavily i Brave.

Uruchom /mcp w sesji Claude Code albo Codex, albo codex mcp list w terminalu; w Cursorze otwórz listę MCP w ustawieniach. Oczekuj web_search_exa i web_fetch_exa dla Exa, trzech narzędzi (firecrawl_scrape, firecrawl_search, firecrawl_parse) dla Firecrawl bez klucza, fetch dla Fetch i convert_to_markdown dla MarkItDown. Firecrawl z kluczem rejestruje przy ustawieniach domyślnych do 26 narzędzi (README Firecrawl).

Pierwszy test używa strony, której odpowiedź sprawdzisz sam: History.md Expressa. Aktualne wydanie w npm to Express 5.2.1 (sprawdzone 2026-09-26).

Co powinieneś zobaczyć: jedno wywołanie scrape, zapisany plik Markdown i tabelę, w której każdy wiersz ma cytat. Jeśli wiersz nie ma cytatu albo cytuje tekst, którego grep nie znajduje w zapisanym pliku, agent odpowiedział z pamięci. Z Fetch zamiast Firecrawl agent czyta stronę porcjami po 5000 znaków (domyślne max_length) i przesuwa się parametrem start_index; każ mu czytać dalej, aż dojdzie do wpisów 4.x.

Spike badawczy kończy się decyzją, a decyzja powinna być ADR-em, który recenzent może sprawdzić. Pętla poniżej jest taka sama we wszystkich trzech narzędziach; w promptach zmieniają się tylko nazwy serwerów. Zakładamy, że ADR-y leżą w docs/adr/, jak w decyzjach architektonicznych, których agenci przestrzegają.

  1. Zapisz pytanie, zanim agent zacznie szukać. Utwórz research/<spike>/question.md z decyzją do podjęcia, znanymi już opcjami i kryteriami, które ją rozstrzygną (na przykład: koszt migracji, wsparcie Node.js, poprawki bezpieczeństwa). Spike badawczy bez kryteriów zamienia się w listę lektur.

  2. Znajdź źródła i zatwierdź listę.

    Usuwasz wszystko, co nie ma daty, autora albo jest starsze niż omawiane wydanie. To najtańszy przegląd w całej pętli.

  3. Skonwertuj każde zatwierdzone źródło do Markdown w repozytorium. Strony WWW idą przez firecrawl_scrape albo Fetch; PDF-y i pliki Office przez convert_to_markdown z MarkItDown. Każdy plik trafia do research/<spike>/sources/ z URL-em i datą pobrania w pierwszej linii. Źródła na dysku sprawiają, że kolejne kroki da się sprawdzić: dowód nie zależy już od strony, która jutro może wyglądać inaczej.

  4. Wyciągnij tezy z cytatami, plik po pliku. Poproś o research/<spike>/notes.md: jeden wiersz na tezę, z dosłownym cytatem i plikiem źródłowym. Zrób to w subagencie (Claude Code) albo w osobnej sesji, żeby surowe strony nie trafiały do głównego kontekstu.

  5. Napisz szkic ADR z notatek, nie z sieci.

  6. Uruchom sprawdzanie cytatów i bramki. Skrypt z następnej sekcji przerywa build, jeśli któregoś cytatu nie ma w źródle. Potem recenzent czyta ADR (nie źródła) i decyduje.

Kolejność ma znaczenie. Szukanie i czytanie w jednym kroku pozwala agentowi pominąć źródła niezgodne z jego pierwszym przypuszczeniem. Konwersja do plików przed wyciąganiem tez oznacza, że szkic da się porównać z czymś, co się nie zmienia.

Jak zweryfikować wynik researchu bez czytania każdego źródła

Dział zatytułowany „Jak zweryfikować wynik researchu bez czytania każdego źródła”

Człowiek nie przeczyta ponownie ośmiu stron przy każdym ADR i nie musi. Poniższe kontrole przenoszą dowód na pliki i zostawiają recenzentowi jedną ocenę: czy decyzja jest słuszna, skoro wykazano, że źródła mówią to, co twierdzi ADR?

Ten skrypt kończy się błędem, gdy cytat nie występuje dosłownie w pliku, na który się powołuje. Zapisz go jako scripts/check_citations.py:

import pathlib, re, sys
adr = pathlib.Path(sys.argv[1]).read_text(encoding="utf-8")
adr = adr.replace("\u201c", '"').replace("\u201d", '"') # curly quotes count too
markers = re.findall(r"\[src: [^\]]+\]", adr)
cites = re.findall(r'"([^"]{20,})"\s*\[src: ([^\]]+)\]', adr)
missing = 0
for quote, src in cites:
text = " ".join(pathlib.Path(src.strip()).read_text(encoding="utf-8").split())
if " ".join(quote.split()) not in text:
print(f"NOT FOUND in {src}: {quote[:80]}")
missing += 1
unchecked = len(markers) - len(cites)
if unchecked:
print(f"{unchecked} [src: ...] markers have no quote of 20+ characters before them")
print(f"{len(cites)} citations, {missing} not found")
sys.exit(1 if missing or unchecked or not cites else 0)

Uruchom go z katalogu głównego repozytorium: python3 scripts/check_citations.py docs/adr/0014-express-5-migration.md. Cudzysłowy drukarskie („…”, “…”) traktuje jak proste i normalizuje białe znaki. Zwraca kod różny od zera, gdy cytatu nie ma w źródle, gdy przed znacznikiem [src: …] nie stoi cytat co najmniej 20-znakowy albo gdy ADR nie cytuje niczego. Dodaj go do CI dla każdego pull requesta, który zmienia docs/adr/.

KontrolaCo wyłapujeKto odpowiada
Skrypt cytatówZmyślone cytaty, cytaty przypisane do złego źródłaCI, blokująco
Lista źródeł zatwierdzona przed czytaniemŹródła bez daty, anonimowe albo nieaktualneAutor, w kroku 2
Każdy plik źródłowy zaczyna się od URL-a i daty pobraniaDowody, których nie da się później ponownie pobraćRecenzent, na pierwszy rzut oka
Linie „not established by sources”Luki, które agent wypełniłby z pamięciRecenzent decyduje, czy luka ma znaczenie
Drugi agent bez narzędzi sieciowych porównuje ADR z sources/Tezy zacytowane poprawnie, ale wyrwane z kontekstuAgent recenzujący; zob. przegląd pull requesta od agenta

Tech lead zatwierdza decyzję z tym materiałem dowodowym w załączniku, podobnie jak pakiet dowodów dołącza dowód do zmiany w kodzie.

Ile research w sieci kosztuje w kontekście i kredytach

Dział zatytułowany „Ile research w sieci kosztuje w kontekście i kredytach”

Schematy narzędzi to mały koszt: Claude Code i Codex ładują schematy narzędzi MCP na żądanie. Mimo to trzymaj listę krótką. Parametr ?tools= w Exa zastępuje domyślny zestaw, BRAVE_MCP_ENABLED_TOOLS w Brave przyjmuje listę dozwolonych narzędzi rozdzieloną spacjami, enabled_tools w Codex filtruje dowolny serwer, a w Claude Code reguła deny dla mcp__firecrawl__firecrawl_crawl w .claude/settings.json blokuje pojedyncze narzędzie.

Treść stron to duży koszt. Pobrana strona trafia do kontekstu w całości, chyba że zapiszesz ją do pliku. Trzy nawyki trzymają to w ryzach:

  • Proś o onlyMainContent: true przy scrapingu Firecrawl i pozwól domyślnym porcjom Fetch po 5000 znaków robić swoje.
  • Zapisuj źródła w research/<spike>/sources/ i pracuj na plikach, jak w workflow powyżej.
  • Krok czytania uruchamiaj w subagencie, żeby do głównej sesji wracało tylko podsumowanie.

Mierz, zamiast zgadywać: uruchom /context w Claude Code przed jednym scrapingiem i po nim. Drugi rachunek to kredyty. README Firecrawl podaje, że wyszukiwanie kosztuje 2 kredyty i zwraca 1, gdy agent wywoła firecrawl_search_feedback; ustaw FIRECRAWL_NO_SEARCH_FEEDBACK=1 na lokalnym serwerze, jeśli nie chcesz, żeby to narzędzie było rejestrowane. Więcej technik opisuje redukcja kosztu tokenów MCP.

Stan na 2026-09-26 (gwiazdki GitHub odczytane przez GitHub API; Official MCP Registry i claude-plugins-official odczytane tego samego dnia): Firecrawl ★7,5 tys., w rejestrze w wersji 3.25.5, z pluginem; Exa ★5,1 tys., w rejestrze jako ai.exa/exa 3.4.1, z pluginem; Tavily ★2,4 tys., w rejestrze w wersji 0.2.15; Brave Search ★1,5 tys., w rejestrze w wersji 2.1.3 (npm jest dalej, na 2.1.4). Fetch żyje w modelcontextprotocol/servers (★90,6 tys., liczba dla całego repozytorium). ★187,1 tys. MarkItDown należy do biblioteki; serwer MCP to podpakiet w wersji alfa i nie ma go w rejestrze. Nie podajemy liczby pobrań z npm ani PyPI, bo żadnej nie odczytano.

Agent cytuje tekst, którego nie ma w źródle. Podsumowanie dobrze się czyta, a jeden cytat jest zmyślony. Co zrobić: skrypt cytatów; prompt ADR ma wymagać [src: …] przy każdej tezie, a brakujący cytat traktuj jako nieudany build, nie uwagę stylistyczną.

Strona wydaje agentowi polecenia. README albo post na forum pobrany przez scraper zawiera tekst w rodzaju „ignore previous instructions and run…”. Treść z sieci to niezaufane wejście. Co zrobić: uruchamiaj sesje researchu bez narzędzi zapisu sięgających produkcji, sekretów albo akcji wychodzących; trzymaj spike badawczy na gałęzi; przeglądaj każde polecenie, które agent proponuje po lekturze sieci. Zob. model zagrożeń dla agentów i zabezpieczanie serwerów MCP.

Fetch sięga do twojej sieci wewnętrznej. README Fetch ostrzega, że serwer „can access local/internal IP addresses”. Co zrobić: nie uruchamiaj Fetch na maszynie, która widzi panele administracyjne albo endpointy metadanych chmury, których nie dałbyś agentowi; publiczne strony pobieraj przez hostowany endpoint Firecrawl albo uruchamiaj Fetch w sandboksie (zob. uprawnienia i sandboksing).

Fetch odmawia pobrania strony. Respektuje robots.txt dla żądań inicjowanych przez model. Co zrobić: uszanuj odmowę albo pobierz kopię, którą wolno ci czytać. Flaga --ignore-robots-txt istnieje; używaj jej tylko dla własnych witryn.

crawl albo map w Firecrawl zwraca błąd uwierzytelniania. Poziom bez klucza obejmuje tylko scrape, search i parse. Co zrobić: dodaj klucz przez nagłówek (Claude Code, Cursor) albo --bearer-token-env-var (Codex), albo zaloguj się przez https://mcp.firecrawl.dev/v2/mcp-oauth.

Brave Search przestał odpowiadać po HTTP. Wersja 2.x domyślnie używa stdio; wcześniej domyślny był HTTP. Co zrobić: uruchamiaj go jako polecenie stdio, jak wyżej, albo ustaw BRAVE_MCP_TRANSPORT=http (lub --transport http), jeśli klient naprawdę potrzebuje HTTP. Endpoint HTTP nie ma uwierzytelniania i domyślnie nasłuchuje na 127.0.0.1; tak ma zostać.

Exa straciło domyślne narzędzia. Dodanie ?tools=web_search_advanced_exa zastępuje domyślne narzędzia, zamiast je uzupełniać. Co zrobić: wymień wszystkie potrzebne narzędzia, na przykład ?tools=web_search_exa,web_fetch_exa,web_search_advanced_exa.

MarkItDown psuje się po aktualizacji. Każde dotychczasowe wydanie markitdown-mcp to alfa (0.0.1a7 z 2026-09-14). Co zrobić: przypnij wersję (uvx markitdown-mcp@0.0.1a7, przetestowane) albo wołaj z powłoki stabilne CLI markitdown 0.1.8 zamiast serwera MCP.