GPT Pesquisador + Scrapeless MCP: Dê ao Seu Agente de Pesquisa uma Camada de Busca Real
Senior Web Scraping Engineer
TL;DR:
- O GPT Researcher lê a web através de recuperadores, e o
mcprecuperador transforma qualquer servidor MCP em uma fonte de pesquisa — assim, o Servidor MCP Scrapeless se torna a camada que realmente busca páginas. - Configurar
RETRIEVER=mcpé obrigatório. Passarmcp_configssem isso deixa o recuperador MCP desligado, e a execução retorna ao que quer que esteja configurado. - O transporte stdio é o caminho que funciona hoje:
npx -y scrapeless-mcp-server@0.4.9comSCRAPELESS_KEYemenvcarrega todas as 21 ferramentas. - O caminho remoto
connection_urlnão autentica no cliente liberado.connection_tokenacessa o transporte como um argumentotokennão suportado, econnection_headersnunca chega até ele. - Fixe suas versões.
gpt-researcher==0.16.0levantaNameErrorna importação, emcpversões a partir de 1.28 desativam o suporte ao MCP dentro delangchain-mcp-adapterssem uma mensagem de erro. scrape_markdownemhttps://quotes.toscrape.com/retorna 4308 caracteres de conteúdo da página através do recuperador, e você pode chamá-lo antes que qualquer modelo esteja envolvido.- Apenas a execução de pesquisa em si precisa de uma chave de provedor de modelo; carregar e chamar ferramentas não precisa de nada além da sua chave Scrapeless.
- Comece no plano gratuito do Scrapeless e dê ao seu agente de pesquisa uma camada de busca real.
O GPT Researcher planeja uma consulta, pesquisa, lê o que encontra e escreve um relatório citado. A parte de pesquisa é bem atendida — ele envia recuperadores para Google, Bing, Brave, arXiv, PubMed e mais. A parte de leitura é onde a pesquisa autônoma quietamente degrada: um recuperador devolve uma lista de URLs, e algo ainda precisa transformar essas URLs em texto. Quando essa busca retorna uma página de desafio ou uma casca vazia, o relatório é escrito de qualquer maneira, a partir de qualquer conteúdo fino que voltar.
O mcp recuperador muda o que fica naquele slot. Aponte o GPT Researcher para um servidor MCP e as ferramentas do servidor se tornam a superfície de pesquisa, então a busca de páginas passa por uma infraestrutura construída para isso, em vez de um simples HTTP get. Este guia conecta o GPT Researcher ao Servidor MCP Scrapeless, lista as ferramentas que ele expõe, chama uma de verdade, e marca exatamente qual etapa é a primeira a precisar de uma chave de provedor de modelo.
O que o Servidor MCP Scrapeless Oferece a um Agente de Pesquisa
O Servidor MCP Scrapeless expõe ferramentas de scraping e navegador através do Protocolo de Contexto de Modelo, então a camada de busca é algo que seu agente chama ao invés de algo que você constrói. Uma conexão serve 21 ferramentas: scrape_markdown e scrape_html para conteúdo de página, google_search e google_trends para dados de pesquisa, scrape_screenshot para capturas, e um conjunto de 16 ferramentas browser_* que opera um navegador em nuvem através de navegação, cliques, digitação, rolagem e esperas.
Para um agente de pesquisa, a importante é scrape_markdown. A qualidade do relatório do GPT Researcher depende do texto que ele coleta, e markdown já é a forma que o contexto deseja. As ferramentas browser_* importam quando uma fonte só renderiza após interação — elas rodam no navegador em nuvem Scrapeless, então um agente pode acessar uma página renderizada sem um navegador na máquina de pesquisa.
A camada de protocolo segue a especificação do Protocolo de Contexto de Modelo, que transporta suas mensagens através de a especificação JSON-RPC 2.0. Se você quiser que o protocolo seja explicado em seus próprios termos primeiro, O que é MCP cobre isso, e LangChain + Scrapeless MCP mostra o mesmo servidor conectado a uma pilha diferente.
Pré-requisitos
- Python 3.10 ou posterior.
- Node.js na máquina que executa a pesquisa, porque o transporte stdio inicia o servidor com
npx. - Uma chave de API Scrapeless do painel, exportada como
SCRAPELESS_KEY. - Uma chave de provedor de modelo como
OPENAI_API_KEY. O GPT Researcher constrói um cliente de embeddings enquanto constrói o objeto pesquisador, então essa variável deve ser configurada antes dessa etapa — tudo até e incluindo a chamada de ferramentas MCP funciona sem ela.
Instalação
A fixação de versões não é opcional aqui, e dois pinos específicos estão fazendo trabalho real.
bash
pip install "gpt-researcher==0.15.1" "langchain-mcp-adapters==0.3.1" "mcp==1.27.2"
gpt-researcher==0.16.0 não pode ser importado. Seu actions/query_processing.py define um helper cuja assinatura anota Any e List várias linhas acima do from typing import Any, List, Dict que as definiria, e como as anotações em um def simples são avaliadas quando o objeto da função é construído — o comportamento da proposta de anotação postergada foi escrito para mudar — a importação levanta NameError: name 'Any' is not defined antes que qualquer outra coisa seja executada. A versão 0.15.1 não tem esse problema de ordenação.
O mcp pin é mais sutil. langchain-mcp-adapters declara seu requisito como mcp>=1.9.2, um piso ilimitado no sentido descrito por a especificação do especificador de dependência Python, portanto uma nova instalação puxa o que quer que mcp seja mais recente. Lançamentos a partir de 1.28 não exportam mais RequestContext de mcp.shared.context, que o adaptador importa na carga do módulo. O GPT Researcher captura esse ImportError e define uma flag interna de disponibilidade como falsa, então o MCP não falha de forma barulhenta — ele simplesmente deixa de existir, e sua pesquisa roda sem nunca tocar o servidor.
Defina sua chave no shell em vez de no código-fonte.
bash
export SCRAPELESS_KEY="your_api_key_here"
Conectar pelo stdio e listar as ferramentas
A camada MCP do GPT Researcher aceita uma lista de dicionários de configuração do servidor. Para um servidor stdio, você fornece um nome, o comando, seus argumentos e qualquer ambiente que o servidor precise. MCPClientManager converte isso na configuração de transporte e executa o handshake.
python
import asyncio
import os
from gpt_researcher.mcp.client import MCPClientManager
SCRAPELESS = {
"name": "scrapeless",
"command": "npx",
"args": ["-y", "scrapeless-mcp-server@0.4.9"],
"env": {"SCRAPELESS_KEY": os.environ["SCRAPELESS_KEY"], "PATH": os.environ["PATH"]},
}
async def main() -> None:
manager = MCPClientManager([SCRAPELESS])
tools = await manager.get_all_tools()
print("tool count:", len(tools))
print("tools:", ", ".join(sorted(tool.name for tool in tools)))
asyncio.run(main())
Inclua PATH em env. O processo do servidor é iniciado exatamente com o ambiente que você fornecer, então deixar PATH de fora significa que npx não pode ser localizado.
O servidor ao vivo retorna 21 ferramentas com apenas a chave Scrapeless definida.
text
tool count: 21
tools: browser_click, browser_close, browser_create, browser_get_html, browser_get_text, browser_go_back, browser_go_forward, browser_goto, browser_press_key, browser_screenshot, browser_scroll, browser_scroll_to, browser_snapshot, browser_type, browser_wait, browser_wait_for, google_search, google_trends, scrape_html, scrape_markdown, scrape_screenshot
Por que o caminho da URL remota não funciona ainda
A tabela de configuração na documentação do GPT Researcher lista connection_url e connection_token para servidores remotos, que parece ser a combinação natural para um ponto final hospedado. No cliente lançado, nenhuma chave lhe dá uma conexão autenticada, e vale a pena ver por que antes de você passar uma tarde nisso.
Ambas as falhas são visíveis sem uma chamada de rede, porque convert_configs_to_langchain_format é a função que decide o que o transporte recebe.
python
from gpt_researcher.mcp.client import MCPClientManager
URL = "https://api.scrapeless.com/mcp"
with_token = MCPClientManager([
{"name": "s", "connection_url": URL, "connection_token": "PLACEHOLDER"},
]).convert_configs_to_langchain_format()["s"]
with_headers = MCPClientManager([
{"name": "s", "connection_url": URL, "connection_headers": {"x-api-token": "PLACEHOLDER"}},
]).convert_configs_to_langchain_format()["s"]
print("connection_token ->", sorted(with_token))
print("connection_headers ->", sorted(with_headers))
text
connection_token -> ['token', 'transport', 'url']
connection_headers -> ['transport', 'url']
connection_token se torna uma chave token, que a fábrica de sessões HTTP streamable não aceita — a tentativa de conexão termina em _create_streamable_http_session() got an unexpected keyword argument 'token', e a lista de ferramentas volta vazia.
connection_headers não sobrevive à conversão de maneira alguma. O ramo que a copiaria testa server_config.get("connection_type"), mas a conversão escreve apenas uma chave transport, então o teste nunca corresponde e os cabeçalhos são descartados. Como o ponto final Scrapeless se autentica em um cabeçalho x-api-token, a requisição chega não autenticada. A lista de ferramentas está vazia por esse motivo também, que é o porquê dos dois sintomas parecerem idênticos do lado de fora.
Use stdio até que uma versão seja lançada que copie cabeçalhos para o transporte. Ele alcança o mesmo servidor e as mesmas 21 ferramentas.
Chame uma ferramenta antes que o agente exista
As ferramentas carregadas através do cliente MCP são chamadas ordinárias, então você pode exercitar a camada de busca por conta própria. Esta é a maneira mais barata de confirmar se sua chave e transporte estão corretos, e não precisa de uma chave de provedor de modelo.
python
import asyncio
import os
from gpt_researcher.mcp.client import MCPClientManager
SCRAPELESS = {
"name": "scrapeless",
"command": "npx",
"args": ["-y", "scrapeless-mcp-server@0.4.9"],
"env": {"SCRAPELESS_KEY": os.environ["SCRAPELESS_KEY"], "PATH": os.environ["PATH"]},
}
def as_text(result) -> str:
if isinstance(result, str):
return result
if isinstance(result, (list, tuple)):
parts = [b["text"] for b in result if isinstance(b, dict) and "text" in b]
if parts:
return "\n".join(parts)
return str(result)
async def main() -> None:
manager = MCPClientManager([SCRAPELESS])
tools = await manager.get_all_tools()
scrape = next(tool for tool in tools if tool.name == "scrape_markdown")
text = as_text(await scrape.ainvoke({"url": "https://quotes.toscrape.com/"}))
print("characters:", len(text))
print("first line:", text.split("\n")[0])
asyncio.run(main())
A chamada retorna a página como markdown, envolta no envelope de bloco de conteúdo que o protocolo define. as_text achata esse envelope, o que importa porque o retorno bruto é uma lista de blocos em vez de uma string.
text
characters: 4308
first line: Response:
Entregue a configuração ao pesquisador
Com o transporte comprovado, o mesmo dicionário vai para GPTResearcher. Duas coisas precisam estar alinhadas: RETRIEVER deve nomear mcp, e mcp_configs deve carregar o servidor. Perder a variável de ambiente e o recuperador MCP nunca é construído, que é a maneira mais comum que essa integração parece não fazer nada.
Nota: este bloco é uma lacuna de pré-requisito.
GPTResearcherconstrói um cliente de embeddings durante__init__, então precisa deOPENAI_API_KEYpresente antes que o objeto exista, econduct_researchgasta créditos reais de modelo. O ambiente de verificação para este artigo não tinha uma chave de provedor de modelo, então a fiação abaixo foi confirmada até e incluindo a resolução do recuperador, e a chamada de pesquisa em si não foi executada.
python
import asyncio
import os
os.environ["RETRIEVER"] = "mcp"
from gpt_researcher import GPTResearcher
SCRAPELESS = {
"name": "scrapeless",
"command": "npx",
"args": ["-y", "scrapeless-mcp-server@0.4.9"],
"env": {"SCRAPELESS_KEY": os.environ["SCRAPELESS_KEY"], "PATH": os.environ["PATH"]},
}
async def main() -> None:
researcher = GPTResearcher(
query="Which quotes and authors appear on quotes.toscrape.com?",
mcp_configs=[SCRAPELESS],
)
await researcher.conduct_research()
report = await researcher.write_report()
print(report)
asyncio.run(main())
A atribuição precisa acontecer antes de GPTResearcher ser construída, porque o pesquisador lê o ambiente enquanto constrói seu objeto de configuração. Colocá-la acima da importação, como aqui, é apenas a ordem que é mais difícil de errar.
RETRIEVER=mcp torna Scrapeless a única fonte de pesquisa, que se adequa a perguntas sobre páginas específicas. RETRIEVER=tavily,mcp e combinações semelhantes mantêm um mecanismo de busca ao lado, para que o agente encontre fontes candidatas de uma maneira e as leia de outra. Também há MCP_STRATEGY, que é configurado por padrão para fast e executa a etapa MCP uma vez contra a consulta principal; deep executa para cada subconsulta gerada e custa proporcionalmente mais.
Pronto para dar ao seu agente de pesquisa uma camada de busca que se sustente em fontes reais? Crie uma conta gratuita no Scrapeless e conecte-a em algumas linhas.
Conclusão
A fiação é curta uma vez que os pinos da versão e a escolha do transporte estão resolvidos: instale gpt-researcher==0.15.1 contra mcp==1.27.2, defina RETRIEVER=mcp e passe uma entrada stdio mcp_configs apontando para scrapeless-mcp-server. Isso resulta em 21 ferramentas, e scrape_markdown retorna o conteúdo real da página antes que um modelo seja envolvido — o que torna a camada de busca testável por conta própria, em vez de ser algo que você depura através de um relatório finalizado.
As duas armadilhas são dignas de nota porque nenhuma se anuncia. Um mcp não fixado desliga o suporte MCP silenciosamente, e o caminho remoto connection_url deixa suas credenciais no chão. Ambos produzem o mesmo sintoma de um agente que pesquisa sem nunca chamar seu servidor. Verifique primeiro a contagem de ferramentas; se não for 21, nada a jusante se comportará.
Compare planos na página de preços do Scrapeless, e a referência completa das ferramentas está na documentação do Scrapeless.
Perguntas Frequentes
P: Preciso de uma chave de provedor de modelo só para testar a conexão MCP?
Não. Carregar ferramentas e chamá-las ocorre inteiramente através do cliente MCP, então uma chave Scrapeless é suficiente para confirmar que o transporte funciona e para chamar scrape_markdown em uma URL real. A chave do modelo se torna necessária no momento em que você constrói GPTResearcher, porque um cliente de embeddings é criado durante a inicialização.
P: Por que minha execução ignora o servidor MCP mesmo que eu tenha passado mcp_configs?
A variável de ambiente RETRIEVER é quase sempre a causa. mcp_configs por si só não ativa o recuperador MCP; RETRIEVER precisa nomear mcp, seja sozinha ou em uma lista como tavily,mcp. Defina isso antes de construir GPTResearcher, uma vez que o valor é lido enquanto o pesquisador constrói sua configuração.
P: Posso me conectar ao endpoint Scrapeless hospedado em vez de rodar o servidor localmente?
Não através de mcp_configs no cliente lançado. connection_token é passado para a sessão HTTP transmitível como um argumento que não é aceito, e connection_headers é descartado durante a conversão de configuração antes de chegar ao transporte. O transporte stdio se conecta ao mesmo servidor e expõe as mesmas 21 ferramentas, portanto, é o caminho funcional hoje.
P: Qual é a diferença entre as estratégias MCP rápida e profunda?
fast, o padrão, executa a etapa MCP uma vez usando a consulta principal. deep a executa para cada subconsulta gerada pelo agente, o que amplia a cobertura e multiplica tanto as chamadas de ferramentas quanto o gasto com modelos. Comece em fast e passe para deep apenas quando um relatório específico estiver retornando magro.
P: Devo usar RETRIEVER=mcp sozinho ou combiná-lo com um recuperador de pesquisa?
Use mcp sozinho quando já souber quais páginas importam, porque o agente ignora a geração de subconsultas e trabalha nas fontes que você aponta. Combine-o, conforme tavily,mcp, quando a descoberta faz parte do trabalho — o recuperador de pesquisa encontra candidatos e as ferramentas MCP os leem.
P: Por que fixar mcp em vez de pegar a versão mais nova?
langchain-mcp-adapters requer mcp>=1.9.2 sem limite superior, então um ambiente fresco instala a versão mais nova. A partir da 1.28, RequestContext não é mais exportado de mcp.shared.context, a importação do adaptador falha, e o GPT Researcher registra o MCP como indisponível em vez de levantar um erro. Fixar mcp==1.27.2 mantém o adaptador importável.
P: A contagem de ferramentas é algo que eu deveria verificar na minha própria configuração?
Sim, e é o diagnóstico mais rápido disponível. Uma contagem de 21 significa que o transporte, a chave e o adaptador estão todos funcionando. Zero significa que a conexão nunca se autenticou, e qualquer exceção durante get_all_tools é registrada em vez de levantada, então uma lista vazia é o que uma conexão falhada parece a partir do seu código.
P: O que scrape_markdown realmente retorna?
Uma lista de blocos de conteúdo de protocolo em vez de uma string simples, com o markdown da página no bloco de texto. Achate-o antes de medir ou armazená-lo - tratar o valor de retorno como uma string produz a representação Python da lista em vez da página.
Na Scorretless, acessamos apenas dados disponíveis ao público, enquanto cumprem estritamente as leis, regulamentos e políticas de privacidade do site aplicáveis. O conteúdo deste blog é apenas para fins de demonstração e não envolve atividades ilegais ou infratoras. Não temos garantias e negamos toda a responsabilidade pelo uso de informações deste blog ou links de terceiros. Antes de se envolver em qualquer atividade de raspagem, consulte seu consultor jurídico e revise os termos de serviço do site de destino ou obtenha as permissões necessárias.



