De volta ao blog

Como Conectar Scrapeless ao ChatGPT Com uma Ação GPT Personalizada

James Thompson
James Thompson

Scraping and Proxy Management Expert

21-Sep-2026

TL;DR:

  • ChatGPT não pode usar um servidor MCP com chave de API como conector. O MCP em modo desenvolvedor aceita OAuth 2.1 ou nenhuma autenticação, e a documentação da OpenAI afirma que o ChatGPT "não pode apresentar chaves de API personalizadas".
  • A rota que funciona é uma Ação GPT personalizada: um esquema OpenAPI mais autenticação por chave de API em um cabeçalho personalizado.
  • O cabeçalho é x-api-token, não Authorization: Bearer. Defina o tipo de autenticação como Chave de API, depois Personalizado, e então o nome desse cabeçalho.
  • Peça em Markdown, não em HTML. A mesma página tem 8.676 caracteres em Markdown contra 50.403 em HTML — uma redução de 83% no contexto que o modelo gasta com marcação.
  • response_type só funciona ao lado de js_render: true. Deixe js_render de fora e a mesma solicitação retorna 50.368 caracteres de HTML com HTTP 200. outputFormat é aceita e ignorada silenciosamente, retornando os 50.403 caracteres completos de HTML.
  • O esquema abaixo passa openapi-spec-validator contra OpenAPI 3.1.0, e a solicitação que descreve foi executada ao vivo: {code: 200, data: string}.
  • Obtenha uma chave no plano gratuito do Scrapeless antes de começar.

Pergunte ao ChatGPT sobre uma página que ele não viu e você receberá um resumo de seus dados de treinamento ou um resultado de navegação que você não pode controlar. Uma Ação muda a disposição: você entrega ao modelo uma operação HTTP que ele pode chamar, com parâmetros definidos por você, contra uma API que você escolher.

A primeira coisa a resolver é qual mecanismo o ChatGPT realmente aceitará, porque a resposta óbvia está errada.

Por Que Isso É uma Ação e Não um Conector MCP

Todo outro cliente importante trata o servidor MCP do Scrapeless como um conector HTTP remoto com a chave em um cabeçalho. O ChatGPT não faz isso, e vale a pena ver por que antes de construir em torno disso.

O ponto final requer um cabeçalho estático. Chamado sem um:

text Copy
POST https://api.scrapeless.com/mcp   (no auth)
-> HTTP 401
   body: Unauthorized: Missing x-api-token header
   www-authenticate: None

Esse cabeçalho www-authenticate ausente é importante. Sob o quadro de autenticação HTTP, um 401 é onde um servidor anuncia como autenticar, e um cliente em busca de um desafio OAuth não encontra nada a seguir. Também não há metadados OAuth a descobrir:

text Copy
/.well-known/oauth-protected-resource       404
/.well-known/oauth-authorization-server     404
/.well-known/oauth-protected-resource/mcp   404

A especificação do Protocolo de Contexto do Modelo permite qualquer configuração — um token exposto em um cabeçalho é uma implementação MCP perfeitamente normal. A restrição está do lado do ChatGPT: seus conectores em modo desenvolvedor suportam OAuth 2.1 ou nenhuma autenticação, e a documentação da OpenAI afirma claramente que o ChatGPT não pode apresentar chaves de API personalizadas.

Portanto, não há URL para colar. O caminho suportado para uma API HTTP com chave é uma Ação GPT, que suporta autenticação por chave de API com um nome de cabeçalho que você escolher.

Pré-requisitos

  • Um plano ChatGPT que inclua a criação de GPTs.
  • Uma chave de API Scrapeless.
  • Sem hospedagem, sem proxy, sem processo local. A Ação chama api.scrapeless.com diretamente.

Etapa 1: O Esquema OpenAPI

Uma Ação é um documento OpenAPI descrevendo uma ou mais operações. Esta descreve uma única operação: buscar uma página renderizada e retorná-la como Markdown.

yaml Copy
openapi: 3.1.0
info:
  title: Scrapeless Universal Scraping API
  description: Fetch a fully rendered web page and return it as Markdown or HTML.
  version: "1.0.0"
servers:
  - url: https://api.scrapeless.com
paths:
  /api/v2/unlocker/request:
    post:
      operationId: scrapeWebPage
      summary: Fetch a web page with JavaScript rendering and return it as Markdown
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [actor, input]
              properties:
                actor:
                  type: string
                  enum: [unlocker.webunlocker]
                  description: The Scrapeless actor to run.
                input:
                  type: object
                  required: [url, js_render, response_type]
                  properties:
                    url:
                      type: string
                      format: uri
                      description: The page to fetch.
                    js_render:
                      type: boolean
                      enum: [true]
                      default: true
                      description: Must be true. response_type only takes effect when JavaScript rendering is on.
                    response_type:
                      type: string
                      enum: [markdown, html]
                      default: markdown
                      description: Return the page as Markdown or raw HTML.
      responses:
        "200":
          description: The rendered page.
          content:
            application/json:
              schema:
                type: object
                properties:
                  code:
                    type: integer
                  data:
                    type: string
                    description: The rendered page, as Markdown or HTML.
        "401":
          description: Missing or invalid API token.
components:
  securitySchemes:
    scrapelessApiKey:
      type: apiKey
      in: header
      name: x-api-token
security:
  - scrapelessApiKey: []

Três escolhas deliberadas lá.

O actor é um enum com um valor em vez de uma string livre. Um modelo dado um campo de texto livre eventualmente inventará um nome de ator; um enum torna o único valor válido a única opção.

operationId é scrapeWebPage, e esse é o nome que você referencia nas instruções do GPT. Um id vago produz uma seleção de ferramentas vaga.

response_type tem como padrão markdown, pela razão na etapa 3, e tanto ele quanto js_render são listados como obrigatórios. Um padrão de esquema é documentação: não faz o modelo enviar o campo, e o padrão do próprio API para js_render está desativado.

Validar antes de colar vale os trinta segundos — a especificação OpenAPI 3.1.0 é rigorosa sobre a estrutura, e as mensagens de erro do construtor são sucintas:

bash Copy
pip install openapi-spec-validator
bash Copy
python3 -c "
from openapi_spec_validator import validate
from openapi_spec_validator.readers import read_from_filename
spec, _ = read_from_filename('scrapeless-action.yaml')
validate(spec)
print('valid')"
text Copy
valid

Etapa 2: Autenticação

No construtor GPT, abra o painel de autenticação da Ação e defina:

Campo Valor
Tipo de Autenticação Chave de API
Tipo de Autenticação Personalizado
Nome do Cabeçalho Personalizado x-api-token
Chave de API sua chave Scrapeless

O padrão sob Chave de API é Bearer, que envia Authorization: Bearer <key>. O Scrapeless lê x-api-token e nada mais, então deixar o padrão gera um 401 que o construtor só apresenta quando a Ação é chamada pela primeira vez — depois que o esquema já foi validado.

Nota: o builder é uma interface web, portanto, este passo não foi executado como parte da verificação deste artigo. Cada afirmação sobre a API em si — o esquema, o nome do cabeçalho, a forma da resposta e os tamanhos abaixo — vem de chamadas ao vivo contra api.scrapeless.com.

Passo 3: Pergunte por Markdown

Esta configuração decide quanto do contexto do modelo o conector gasta antes de ter lido qualquer coisa, e a diferença é mensurável.

A mesma página de categoria, obtida duas vezes:

text Copy
response_type=markdown      8,676 chars
default (html)             50,403 chars

O Markdown é 83% menor. A resposta de uma Ação GPT vai para o contexto do modelo, então retornar HTML gasta a maior parte desse orçamento em tags, scripts inline e atributos que o modelo ignorará.

Há uma armadilha ao lado disso. outputFormat parece que deveria funcionar e é aceito sem reclamação:

text Copy
input.response_type = "markdown"   ->  8,676 chars  (markdown)
input.outputFormat  = "markdown"   -> 50,403 chars  (HTML)

A segunda chamada teve sucesso, retornou HTTP 200, e silenciosamente devolveu HTML porque outputFormat não é um parâmetro que o ator lê. Uma chave desconhecida que é ignorada em vez de rejeitada é o tipo mais difícil de erro — nada falha, a saída apenas tem uma forma errada e quase seis vezes maior do que você planejou.

A segunda armadilha é mais silenciosa. response_type só entra em efeito quando a renderização JavaScript está ativada, e o padrão da API está desativado. Envie response_type: "markdown" sem js_render: true e a chamada retorna HTTP 200 com 50.368 caracteres de HTML, sem erro e sem aviso. O esquema acima fixa js_render em true e lista como necessário exatamente por esse motivo, e as instruções abaixo nomeiam ambos os campos.

Construindo isso agora? O plano gratuito Scrapeless cobre o suficiente de solicitações para testar a Ação de ponta a ponta.

Passo 4: Instruções Que Chamam

O esquema dá ao modelo uma capacidade; as instruções decidem quando ele a executa. Nomeie a operação explicitamente:

text Copy
When the user gives you a URL, or asks about the current contents of a
specific page, call scrapeWebPage with that URL, js_render true and
response_type "markdown". Do not answer from memory when a URL is present.

Return what the page says, and quote the exact figures it contains rather
than paraphrasing them. If scrapeWebPage reports a 401, tell the user the
API key is missing or misconfigured and stop.

O primeiro parágrafo vincula a ferramenta a um gatilho. Sem isso, um modelo com uma capacidade de navegação própria usará às vezes isso ao invés de produzir resultados dos quais seu esquema não fez parte.

O Que Volta

O envelope de resposta tem dois campos, e o esquema acima declara ambos:

json Copy
{
  "code": 200,
  "data": "-   [Home](https://books.toscrape.com/index.html)\n-   [Books](...)\n..."
}

Verificado contra a API ao vivo com exatamente o corpo que o esquema descreve:

text Copy
HTTP 200
response keys      : ['code', 'data']
code               : 200 (int)
data               : str, 50403 chars
schema match       : code=integer:True  data=string:True

code é o próprio status do Scrapeless, distinto do status HTTP — ambos foram 200 aqui. data é uma única string, razão pela qual o modelo recebe um documento em vez de uma estrutura; se você quiser campos, peça-os nas instruções ou analise-os você mesmo mais adiante.

Conclusão

O conector é uma operação e um cabeçalho. ChatGPT não aceitará um servidor MCP com chave API — esse é um limite da plataforma, confirmado por um 401 sem desafio OAuth, três 404s onde os metadados estariam, e a própria declaração da OpenAI — portanto, o mecanismo é uma Ação, e o mecanismo não é a parte difícil.

As duas escolhas que decidem se funciona bem são ambas pequenas. Defina o cabeçalho personalizado como x-api-token, porque o padrão Bearer falha no momento da chamada em vez de na configuração. E defina response_type para markdown ao lado de js_render: true, porque 8.676 caracteres de Markdown deixam espaço para pensar onde 50.403 caracteres de HTML não deixam — e porque o outputFormat que parece plausível é aceito, ignorado, e devolve o maior.

Para a mesma API acionada a partir do código em vez de um GPT, nosso guia de web scraping com ChatGPT cobre o padrão modelo-plus-fetch, a API Universal Scraping descreve o ator por trás da operação, a documentação carrega a referência completa de parâmetros, e preços lista o custo de cada chamada.

Pronto para dar a ChatGPT um fetch que você controla? Comece com o plano gratuito do Scrapeless e cole o esquema.

FAQ

P: O ChatGPT pode se conectar a um servidor MCP?
Sim, mas apenas um usando OAuth 2.1 ou nenhuma autenticação. Conectores em modo desenvolvedor não podem apresentar uma chave API estática, como a documentação da OpenAI afirma diretamente. Um servidor como o ponto de extremidade Scrapeless MCP, que se autentica em um cabeçalho x-api-token e não publica metadados OAuth, portanto, não pode ser adicionado como um conector ChatGPT — uma Ação GPT é a rota suportada para isso.

Q: Por que minha Ação GPT retorna um 401?

Na maioria das vezes, o nome do cabeçalho. O tipo de autenticação da chave API tem por padrão o tipo Bearer, que envia Authorization: Bearer <key>; Scrapeless lê x-api-token. Defina o tipo de autenticação como Personalizado e o nome do cabeçalho como x-api-token. O esquema valida de qualquer maneira, então isso aparece na primeira chamada, em vez de na configuração.

Q: Qual versão do OpenAPI as Ações GPT precisam?

O esquema acima é OpenAPI 3.1.0 e valida contra essa especificação. Mantenha o documento minimalista — uma URL de servidor, valores operationId explícitos e nenhuma $ref indireção que você não precisa — porque o analisador do construtor é mais rigoroso e seus erros menos específicos do que o de um validador dedicado.

Q: Como faço para impedir que a Ação preencha o contexto do modelo?

Retorne Markdown. Definir response_type como markdown, com js_render: true na mesma solicitação, fez a mesma página passar de 50.403 caracteres para 8.676, e a resposta da Ação é gasta do orçamento de contexto da conversa. Também restringa o esquema: uma operação com um pequeno conjunto de parâmetros dá ao modelo menos espaço para construir uma chamada cara.

Q: Por que meu parâmetro outputFormat não fez nada?

Porque não é um parâmetro que o ator lê. A solicitação ainda retornou HTTP 200 e o HTML completo — 50.403 caracteres em vez de 8.676. A chave correta é response_type, e ela precisa de js_render: true ao lado. Chaves desconhecidas são ignoradas em vez de rejeitadas aqui, então verifique o tamanho do que voltou quando uma configuração de formato parece não ter efeito.

Q: Uma Ação pode expor mais de uma capacidade Scrapeless?

Sim — adicione um caminho e um operationId por operação no mesmo documento. Mantenha cada um estreito e respeite as restrições enum, pois uma única operação com um campo de ator de texto livre convida o modelo a adivinhar. Menor privilégio também torna a Ação mais fácil de revisar depois.

Q: Isso funciona em uma conversa normal do ChatGPT ou apenas em um GPT personalizado?

Ações pertencem a um GPT que você configura, então a capacidade vive nesse GPT em vez de em cada conversa. Qualquer um com quem você compartilhar obtém a operação; se eles fornecerem sua própria chave depende de como você configurar a autenticação.

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.

Artigos mais populares

Catálogo