# GitHub Trending Scraper - Repos, Stars & Developers (`viralanalyzer/github-trending-scraper`) Actor

Scrape GitHub trending repositories, stars, forks, languages, and developer profiles. Track open source trends daily/weekly/monthly.

- **URL**: https://apify.com/viralanalyzer/github-trending-scraper.md
- **Developed by:** [viralanalyzer](https://apify.com/viralanalyzer) (community)
- **Categories:** Developer tools, Social media
- **Features:** Limited permissions
- **Stats:** 56 total users, 6 monthly users, 98.9% runs succeeded, 0 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $15.75 / 1,000 repository scrapeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## 🔥 GitHub Trending Scraper — Repos, Stars & Languages

> 🔗 [View on Apify Store](https://apify.com/viralanalyzer/github-trending-scraper) | 🇺🇸 English | [🇧🇷 Português](#português)

Scrape **GitHub trending repositories** with full metadata — stars, forks, descriptions, programming language, and **daily/weekly/monthly star growth**. Filter by programming language or spoken language. Pure HTML scraping with got-scraping + cheerio, no API key needed.

### ✨ Features

- 📈 **3 time periods** — Daily, weekly, and monthly trending repos
- 🌐 **Language filters** — Filter by programming language (Python, JavaScript, Rust, etc.)
- 🗣️ **Spoken language filter** — Filter by spoken language code (en, pt, es, zh, etc.)
- ⭐ **Star metrics** — Total stars + stars gained in the selected period
- 🍴 **Fork count** — Total forks per repository
- 🏆 **Ranking** — Position in GitHub's trending list
- 🛡️ **Anti-placeholder guardrails** — Every result validated as real data
- ⚡ **Fast & lightweight** — Pure HTTP with got-scraping + cheerio

### 📥 Input

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `since` | String | No | `daily` | Trending period: `daily`, `weekly`, or `monthly` |
| `languages` | Array | No | `[]` | Programming languages to filter (e.g., `python`, `javascript`, `rust`). Empty = all |
| `spokenLanguage` | String | No | `""` | Spoken language code (e.g., `en`, `pt`, `es`, `zh`). Empty = all |

#### Input Example

```json
{
    "since": "weekly",
    "languages": ["python", "rust", "typescript"],
    "spokenLanguage": "en"
}
```

### 📤 Output

| Field | Type | Description |
|-------|------|-------------|
| `rank` | Integer | Position in the trending list |
| `owner` | String | Repository owner (user or org) |
| `repo` | String | Repository name |
| `fullName` | String | Full name (owner/repo) |
| `description` | String | Repository description |
| `language` | String | Primary programming language |
| `totalStars` | Integer | Total star count |
| `totalForks` | Integer | Total fork count |
| `starsToday` | Integer | Stars gained in the selected period |
| `repoUrl` | String | GitHub repository URL |
| `since` | String | Time period (daily, weekly, monthly) |
| `filterLanguage` | String | Language filter applied (if any) |
| `platform` | String | Always `github` |
| `scrapedAt` | String | Timestamp of data extraction (ISO 8601) |

#### Output Example

```json
{
    "rank": 1,
    "owner": "microsoft",
    "repo": "autogen",
    "fullName": "microsoft/autogen",
    "description": "A programming framework for agentic AI",
    "language": "Python",
    "totalStars": 41283,
    "totalForks": 5847,
    "starsToday": 1253,
    "repoUrl": "https://github.com/microsoft/autogen",
    "since": "weekly",
    "filterLanguage": "python",
    "platform": "github",
    "scrapedAt": "2026-03-06T14:22:05.371Z"
}
```

### 📋 Use Cases

- 📈 **Tech trend detection** — Identify emerging technologies and frameworks before they go mainstream
- 🔍 **Competitive intelligence** — Monitor competitors' open-source projects and their traction
- 🎯 **Developer marketing** — Find popular repos in your stack to target for integrations
- 💰 **Investment research** — Track which open-source projects are gaining momentum
- 👥 **Hiring intelligence** — Discover trending languages and tools developers are adopting
- ✍️ **Content creation** — Write about the hottest repos and technologies each week

### ✅ Capabilities & Limits

Stated up front, so you do not pay a run to find out.

**Built here:** each language in `languages` is its own HTTP request. A language that fails every retry - bad slug, 404, rate-limit page - is logged and skipped, and the run finishes on the rest. A partial dataset looks exactly like a complete one in the output; only the run log names what was dropped. When *every* language ends with zero repos, the run status tells you which cause it was - see the table below.

| Input / feature | Supported | Notes |
|---|---|---|
| `since` | ✅ | Trending period to scrape. |
| `languages` | ✅ | Filter by language (e.g., python, javascript, rust). Leave empty for all languages. |
| `spokenLanguage` | ✅ | Filter by spoken language (e.g., en, pt, es, zh). Leave empty for all. |

### 🚦 What a run with zero repos does

The ending is decided by what GitHub put on the wire: the HTTP status of `github.com/trending`, and how many `article.Box-row` repo containers a 200 body carried. Page copy is never read to guess a reason.

| What GitHub did | Run status | Dataset | Charged |
|---|---|---|---|
| Blocked every request (`HTTP 403`, `HTTP 429`, timeout) — no page ever arrived | SUCCEEDED | 1 diagnostic row with `_blockReason` | **No PPE** |
| Served the page with repo containers, and the parser extracted none | **FAILED**, exit code 1 | empty | **No PPE** |
| Served the page with no repo container, and you had set `languages` / `spokenLanguage` | **FAILED**, exit code 1, message names your filter | empty | **No PPE** |
| Served the unfiltered page with no repo container | **FAILED**, exit code 1 — the container class changed | empty | **No PPE** |
| Answered `HTTP 404` (language slug does not exist) or `5xx` | **FAILED**, exit code 1, message names the slug | empty | **No PPE** |

A blocked run is the only zero-repo ending that finishes SUCCEEDED, because a 403/429/timeout on the wire is the one cause GitHub confirms by itself. Everything else fails. The trending page exposes no marker that says "this list is legitimately empty", so treating an empty page as good news would mean guessing — and a stale selector would then be sold to you as "nothing was trending in Rust today".

A blocked run leaves this row in the dataset:

```json
{
  "setup_status": "DIAGNOSTIC_GUIDE",
  "_dataQuality": "diagnostic",
  "_blockReason": "HTTP 429 (rate limit)",
  "message": "[DIAGNÓSTICO] Zero repos (since=daily) — GitHub blocked every request to the trending page (HTTP 429 (rate limit)).",
  "potential_causes": [
    "GitHub returned HTTP 429 (rate limit) on every attempt, so no trending page ever reached the parser",
    "HTTP 429 rate-limit on the Apify datacenter exit IP",
    "The exit IP is temporarily throttled by GitHub"
  ],
  "remediations": [
    "Retry in a few minutes — GitHub rate limits on /trending recover quickly",
    "Scrape fewer languages per run (each language is its own request)",
    "Run through a residential proxy if the datacenter IP keeps getting 429"
  ],
  "since": "daily",
  "languagesRequested": ["rust"],
  "spokenLanguage": null,
  "containersSeen": 0,
  "reposParsed": 0,
  "sawHttp200": false,
  "dataSource": "github.com/trending (HTML)",
  "scrapedAt": "2026-08-27T14:22:05.371Z"
}
```

Filter on `_dataQuality != "diagnostic"` and diagnostic rows never reach your pipeline.

### ❓ FAQ

**Q: How many repos are returned per run?**
A: GitHub's trending page shows approximately 25 repos per language/period combination. If you specify multiple languages, each language is scraped separately, so you get up to 25 repos per language.

**Q: What does "starsToday" mean for weekly and monthly periods?**
A: Despite the field name, `starsToday` reflects the stars gained in the selected period. For "weekly" it shows stars gained this week, for "monthly" it shows stars gained this month.

**Q: Can I scrape trending repos for multiple languages at once?**
A: Yes. Add up to 10 languages in the `languages` array. The actor will fetch the trending page for each language separately, with a 2-second delay between requests to avoid rate limiting.

**Q: Does this actor use the GitHub API?**
A: No. It scrapes the GitHub trending HTML page directly using got-scraping + cheerio. No API key or GitHub token is needed. This means it is not subject to GitHub API rate limits.

**Q: What happens if GitHub changes their HTML structure?**
A: The run fails with exit code 1 and a message that names what broke — either "the page carried N article.Box-row containers and the parser extracted none", or "the unfiltered trending page carried no container at all". Both are drift, both fail, neither charges PPE.

**Q: And if my language filter simply has nothing trending?**
A: That also fails with exit code 1, and the message names the filter you set: `languages=[...]` plus `spokenLanguage` when present. GitHub gives no observable "this list is empty" marker, so the actor refuses to bill a start on a guess. Clear the filter, or widen `since`, and run again.

**Q: When does a zero-repo run end SUCCEEDED?**
A: Only when GitHub blocked every request — 403, 429 or a timeout observed on the wire. You get one diagnostic row carrying `_blockReason`, and no PPE charge.

### 💰 Pricing

This actor uses **Pay Per Event (PPE)** pricing:

| Metric | Cost |
|--------|------|
| Per repository scraped | $0.03 |

### 🔗 Related Actors

- [Hacker News Intelligence](https://apify.com/viralanalyzer/hackernews-intelligence) — HN stories & comments
- [Stack Overflow Intelligence](https://apify.com/viralanalyzer/stackoverflow-intelligence) — SO questions & answers
- [Craigslist Scraper](https://apify.com/viralanalyzer/craigslist-scraper) — Classifieds & listings
- [YouTube Fast Scraper](https://apify.com/viralanalyzer/youtube-fast-scraper) — YouTube video metrics

### 📝 Changelog

#### v1.0 (Current)

- ✅ Scrape trending repos for daily, weekly, and monthly periods
- ✅ Filter by programming language (up to 10 languages per run)
- ✅ Filter by spoken language code
- ✅ Full metadata: stars, forks, description, language, ranking
- ✅ Stars gained in selected period (starsToday)
- ✅ Anti-placeholder guardrails
- ✅ Retry logic with rate limit handling
- ✅ PPE billing via Actor.charge()
- ✅ Zero-repo runs classified from the HTTP status and the article.Box-row count: a confirmed block ends SUCCEEDED with a diagnostic row, while selector drift, a 404 slug and user-emptied filters fail with exit code 1

***

<a name="português"></a>

## 🔥 GitHub Trending Scraper — Repositórios, Stars & Linguagens

> [🇺🇸 English](#-github-trending-scraper--repos-stars--languages) | 🇧🇷 Português

Extraia **repositórios em alta no GitHub** com metadados completos — stars, forks, descrições, linguagem de programação e **crescimento diário/semanal/mensal de stars**. Filtre por linguagem de programação ou idioma falado. Scraping HTML puro com got-scraping + cheerio, sem API key.

### ✨ Funcionalidades

- 📈 **3 períodos** — Trending diário, semanal e mensal
- 🌐 **Filtro por linguagem** — Filtre por linguagem de programação (Python, JavaScript, Rust, etc.)
- 🗣️ **Filtro por idioma** — Filtre por código de idioma falado (en, pt, es, zh, etc.)
- ⭐ **Métricas de stars** — Total de stars + stars ganhas no período selecionado
- 🍴 **Contagem de forks** — Total de forks por repositório
- 🏆 **Ranking** — Posição na lista de trending do GitHub
- 🛡️ **Guardrails anti-placeholder** — Todo resultado validado como dado real
- ⚡ **Rápido e leve** — HTTP puro com got-scraping + cheerio

### 📥 Entrada

| Parâmetro | Tipo | Obrigatório | Padrão | Descrição |
|-----------|------|-------------|--------|-----------|
| `since` | String | Não | `daily` | Período de trending: `daily`, `weekly` ou `monthly` |
| `languages` | Array | Não | `[]` | Linguagens de programação para filtrar (ex.: `python`, `javascript`, `rust`). Vazio = todas |
| `spokenLanguage` | String | Não | `""` | Código do idioma falado (ex.: `en`, `pt`, `es`, `zh`). Vazio = todos |

#### Exemplo de Entrada

```json
{
    "since": "weekly",
    "languages": ["python", "rust", "typescript"],
    "spokenLanguage": "en"
}
```

### 📤 Saída

| Campo | Tipo | Descrição |
|-------|------|-----------|
| `rank` | Integer | Posição na lista de trending |
| `owner` | String | Dono do repositório (usuário ou organização) |
| `repo` | String | Nome do repositório |
| `fullName` | String | Nome completo (owner/repo) |
| `description` | String | Descrição do repositório |
| `language` | String | Linguagem de programação principal |
| `totalStars` | Integer | Total de stars |
| `totalForks` | Integer | Total de forks |
| `starsToday` | Integer | Stars ganhas no período selecionado |
| `repoUrl` | String | URL do repositório no GitHub |
| `since` | String | Período (daily, weekly, monthly) |
| `filterLanguage` | String | Filtro de linguagem aplicado (se houver) |
| `platform` | String | Sempre `github` |
| `scrapedAt` | String | Timestamp da extração dos dados (ISO 8601) |

#### Exemplo de Saída

```json
{
    "rank": 1,
    "owner": "microsoft",
    "repo": "autogen",
    "fullName": "microsoft/autogen",
    "description": "A programming framework for agentic AI",
    "language": "Python",
    "totalStars": 41283,
    "totalForks": 5847,
    "starsToday": 1253,
    "repoUrl": "https://github.com/microsoft/autogen",
    "since": "weekly",
    "filterLanguage": "python",
    "platform": "github",
    "scrapedAt": "2026-03-06T14:22:05.371Z"
}
```

### 📋 Casos de Uso

- 📈 **Detecção de tendências tech** — Identifique tecnologias e frameworks emergentes antes de se tornarem mainstream
- 🔍 **Inteligência competitiva** — Monitore projetos open-source de concorrentes e sua tração
- 🎯 **Marketing para desenvolvedores** — Encontre repos populares no seu stack para integrações
- 💰 **Pesquisa de investimento** — Acompanhe quais projetos open-source estão ganhando momentum
- 👥 **Inteligência de contratação** — Descubra linguagens e ferramentas em alta entre desenvolvedores
- ✍️ **Criação de conteúdo** — Escreva sobre os repos e tecnologias mais quentes da semana

### 🚦 O que acontece quando a execução não encontra nenhum repositório

O desfecho vem do que o GitHub colocou na resposta: o status HTTP de `github.com/trending` e quantos contêineres `article.Box-row` um corpo 200 trouxe. O texto da página nunca é lido para adivinhar motivo.

| O que o GitHub fez | Status da execução | Dataset | Cobrança |
|---|---|---|---|
| Bloqueou todas as requisições (`HTTP 403`, `HTTP 429`, timeout) — nenhuma página chegou | SUCCEEDED | 1 linha de diagnóstico com `_blockReason` | **Sem PPE** |
| Serviu a página com contêineres de repo e o parser não extraiu nenhum | **FAILED**, exit code 1 | vazio | **Sem PPE** |
| Serviu a página sem contêiner nenhum, e você tinha definido `languages` / `spokenLanguage` | **FAILED**, exit code 1, a mensagem cita o seu filtro | vazio | **Sem PPE** |
| Serviu a página sem filtro e sem contêiner nenhum | **FAILED**, exit code 1 — a classe do contêiner mudou | vazio | **Sem PPE** |
| Respondeu `HTTP 404` (slug de linguagem inexistente) ou `5xx` | **FAILED**, exit code 1, a mensagem cita o slug | vazio | **Sem PPE** |

Execução bloqueada é o único desfecho com zero repos que termina SUCCEEDED, porque 403/429/timeout na resposta é a única causa que o GitHub confirma sozinho. Todo o resto falha. A página de trending não expõe marcador que diga "esta lista está legitimamente vazia", então tratar página vazia como boa notícia seria adivinhação — e um seletor desatualizado passaria a ser vendido para você como "nada esteve em alta em Rust hoje".

Uma execução bloqueada deixa esta linha no dataset:

```json
{
  "setup_status": "DIAGNOSTIC_GUIDE",
  "_dataQuality": "diagnostic",
  "_blockReason": "HTTP 429 (rate limit)",
  "message": "[DIAGNÓSTICO] Zero repos (since=daily) — GitHub blocked every request to the trending page (HTTP 429 (rate limit)).",
  "potential_causes": [
    "GitHub returned HTTP 429 (rate limit) on every attempt, so no trending page ever reached the parser",
    "HTTP 429 rate-limit on the Apify datacenter exit IP",
    "The exit IP is temporarily throttled by GitHub"
  ],
  "remediations": [
    "Retry in a few minutes — GitHub rate limits on /trending recover quickly",
    "Scrape fewer languages per run (each language is its own request)",
    "Run through a residential proxy if the datacenter IP keeps getting 429"
  ],
  "since": "daily",
  "languagesRequested": ["rust"],
  "spokenLanguage": null,
  "containersSeen": 0,
  "reposParsed": 0,
  "sawHttp200": false,
  "dataSource": "github.com/trending (HTML)",
  "scrapedAt": "2026-08-27T14:22:05.371Z"
}
```

Filtre por `_dataQuality != "diagnostic"` e nenhuma linha de diagnóstico entra no seu pipeline.

### ❓ Perguntas Frequentes

**P: Quantos repos são retornados por execução?**
R: A página de trending do GitHub exibe aproximadamente 25 repos por combinação de linguagem/período. Se você especificar múltiplas linguagens, cada uma é extraída separadamente, então você obtém até 25 repos por linguagem.

**P: O que "starsToday" significa para períodos semanais e mensais?**
R: Apesar do nome do campo, `starsToday` reflete as stars ganhas no período selecionado. Para "weekly" mostra stars ganhas na semana, para "monthly" mostra stars ganhas no mês.

**P: Posso extrair repos em alta para múltiplas linguagens de uma vez?**
R: Sim. Adicione até 10 linguagens no array `languages`. O actor buscará a página de trending para cada linguagem separadamente, com um atraso de 2 segundos entre requisições para evitar rate limiting.

**P: Este actor usa a API do GitHub?**
R: Não. Ele faz scraping da página HTML de trending do GitHub diretamente usando got-scraping + cheerio. Nenhuma API key ou token do GitHub é necessário. Isso significa que ele não está sujeito aos limites de rate da API do GitHub.

**P: O que acontece se o GitHub mudar a estrutura HTML?**
R: A execução falha com exit code 1 e uma mensagem que nomeia o que quebrou — ou "a página trouxe N contêineres article.Box-row e o parser não extraiu nenhum", ou "a página sem filtro não trouxe contêiner algum". Os dois casos são drift, os dois falham, nenhum cobra PPE.

**P: E se o meu filtro de linguagem simplesmente não tiver nada em alta?**
R: Também falha com exit code 1, e a mensagem nomeia o filtro que você definiu: `languages=[...]` mais `spokenLanguage` quando houver. O GitHub não dá marcador observável de "esta lista está vazia", então o actor se recusa a cobrar o start em cima de um palpite. Limpe o filtro, ou amplie o `since`, e rode de novo.

**P: Quando uma execução com zero repos termina SUCCEEDED?**
R: Só quando o GitHub bloqueou todas as requisições — 403, 429 ou timeout observados na resposta. Você recebe uma linha de diagnóstico com `_blockReason` e nenhuma cobrança PPE.

### 💰 Preços

Este actor usa precificação **Pay Per Event (PPE)**:

| Métrica | Custo |
|---------|-------|
| Por repositório extraído | $0.03 |

### 🔗 Actors Relacionados

- [Hacker News Intelligence](https://apify.com/viralanalyzer/hackernews-intelligence) — Stories e comentários do HN
- [Stack Overflow Intelligence](https://apify.com/viralanalyzer/stackoverflow-intelligence) — Perguntas e respostas do SO
- [Craigslist Scraper](https://apify.com/viralanalyzer/craigslist-scraper) — Classificados e anúncios
- [YouTube Fast Scraper](https://apify.com/viralanalyzer/youtube-fast-scraper) — Métricas de vídeos do YouTube

### 📝 Changelog

#### v1.0 (Atual)

- ✅ Scraping de repos em alta para períodos diário, semanal e mensal
- ✅ Filtro por linguagem de programação (até 10 linguagens por execução)
- ✅ Filtro por código de idioma falado
- ✅ Metadados completos: stars, forks, descrição, linguagem, ranking
- ✅ Stars ganhas no período selecionado (starsToday)
- ✅ Guardrails anti-placeholder
- ✅ Lógica de retry com tratamento de rate limit
- ✅ Cobrança PPE via Actor.charge()
- ✅ Execução com zero repos classificada pelo status HTTP e pela contagem de article.Box-row: bloqueio confirmado termina SUCCEEDED com linha de diagnóstico, enquanto drift de seletor, slug 404 e filtro do usuário falham com exit code 1

# Actor input Schema

## `since` (type: `string`):

Trending period to scrape.

## `languages` (type: `array`):

Filter by language (e.g., python, javascript, rust). Leave empty for all languages.

## `spokenLanguage` (type: `string`):

Filter by spoken language (e.g., en, pt, es, zh). Leave empty for all.

## Actor input object example

```json
{
  "since": "daily",
  "languages": [],
  "spokenLanguage": ""
}
```

# Actor output Schema

## `results` (type: `string`):

Dataset containing all scraped results. Each item follows the dataset schema.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "since": "daily",
    "languages": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("viralanalyzer/github-trending-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "since": "daily",
    "languages": [],
}

# Run the Actor and wait for it to finish
run = client.actor("viralanalyzer/github-trending-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "since": "daily",
  "languages": []
}' |
apify call viralanalyzer/github-trending-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,viralanalyzer/github-trending-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/doyjZvyWFPnvAbJxc/builds/QtXIauOptQPw9b6MG/openapi.json
