github_trending
Browse trending repositories on GitHub's public trending feed without specifying a topic.
Instructions
Browse github.com/trending — the public 'what's hot now' feed. USE THIS WHEN: user wants to browse trending repos with no specific topic in mind ('파이썬 트렌딩 보여줘', 'GitHub 핫한 거'). USE github_search INSTEAD WHEN: user has a specific topic/keyword. Note: this is HTML scraping (no official API), so layout changes can break it.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| language | No | ||
| since | No | daily | |
| max_results | No | ||
| response_format | No | markdown |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |
Implementation Reference
- trends_mcp.py:835-894 (handler)The actual async function that executes the github_trending tool logic: scrapes github.com/trending HTML, parses repo names, descriptions, languages, stars, forks, and period stars, then returns formatted markdown.
async def github_trending( language: str | None = None, since: str = "daily", max_results: int = 25, response_format: ResponseFormat = ResponseFormat.MARKDOWN, ) -> str: try: args = GitHubTrendingInput( language=language, since=since, max_results=max_results, response_format=response_format ) url = GITHUB_TRENDING + (f"/{args.language}" if args.language else "") # Trending UI pulses fast — keep TTL short. text = await _http_get_text(url, params={"since": args.since}, ttl=TTL_TRENDING) soup = BeautifulSoup(text, "html.parser") articles = soup.select("article.Box-row") repos: list[dict[str, Any]] = [] for art in articles[: args.max_results]: h2 = art.select_one("h2 a") if not h2: continue href = h2.get("href", "").strip() full_name = re.sub(r"\s+", "", h2.get_text()).strip("/") desc_el = art.select_one("p") desc = desc_el.get_text(strip=True) if desc_el else "" lang_el = art.select_one('[itemprop="programmingLanguage"]') language_v = lang_el.get_text(strip=True) if lang_el else None stars = 0 forks = 0 for a in art.select("a.Link--muted"): ah = a.get("href", "") num_text = a.get_text(strip=True).replace(",", "") m = re.search(r"\d+", num_text) if not m: continue n = int(m.group()) if ah.endswith("/stargazers"): stars = n elif ah.endswith("/forks") or ah.endswith("/network/members"): forks = n period_el = art.select_one("span.d-inline-block.float-sm-right") stars_period = None if period_el: pm = re.search(r"[\d,]+", period_el.get_text()) if pm: stars_period = int(pm.group().replace(",", "")) repos.append( { "full_name": full_name, "url": "https://github.com" + href if href.startswith("/") else href, "description": desc, "language": language_v, "stars": stars, "forks": forks, "stars_period": stars_period, } ) header = f"GitHub Trending — {args.since}" + (f" · {args.language}" if args.language else "") return _format(repos, args.response_format, render_md=lambda x: _render_github_md(x, header)) except Exception as e: return _handle_error(e, "github_trending") - trends_mcp.py:777-782 (schema)Pydantic model GitHubTrendingInput defines the input schema: language (optional), since (daily/weekly/monthly), max_results (1-25), response_format.
class GitHubTrendingInput(BaseModel): model_config = ConfigDict(str_strip_whitespace=True, extra="forbid") language: str | None = Field(None, max_length=40) since: str = Field("daily", pattern=r"^(daily|weekly|monthly)$") max_results: int = Field(25, ge=1, le=25) response_format: ResponseFormat = ResponseFormat.MARKDOWN - trends_mcp.py:818-834 (registration)Registration via @_maybe_tool decorator: source='github', name='github_trending', with MCP annotations. The decorator conditionally registers with FastMCP only if 'github' is in ENABLED_SOURCES.
@_maybe_tool( source="github", name="github_trending", description=( "Browse github.com/trending — the public 'what's hot now' feed. " "USE THIS WHEN: user wants to browse trending repos with no specific " "topic in mind ('파이썬 트렌딩 보여줘', 'GitHub 핫한 거'). " "USE github_search INSTEAD WHEN: user has a specific topic/keyword. " "Note: this is HTML scraping (no official API), so layout changes can break it." ), annotations={ "readOnlyHint": True, "destructiveHint": False, "openWorldHint": True, "idempotentHint": False, }, ) - trends_mcp.py:795-815 (helper)Helper function _render_github_md converts repo data dicts into a markdown-formatted string with headers, stars, forks, and descriptions.
def _render_github_md(items: list[dict[str, Any]], header: str) -> str: if not items: return f"# {header}\n\n_결과 없음_" lines = [f"# {header}", f"_총 {len(items)}건_", ""] for i, r in enumerate(items, 1): bits: list[str] = [] if r.get("language"): bits.append(str(r["language"])) bits.append(f"⭐{r.get('stars', 0):,}") if "forks" in r and r["forks"] is not None: bits.append(f"🍴{r['forks']:,}") if r.get("stars_period"): bits.append(f"📈+{r['stars_period']:,}") meta = " · ".join(bits) desc = _trim(r.get("description"), 200) lines.append( f"## {i}. [{r['full_name']}]({r['url']})\n" f"- {meta}\n" + (f"- {desc}\n" if desc else "") ) return "\n".join(lines)