A daily feed of new GitHub repositories for the topics you follow, new releases of the projects you depend on, and alerts when a repo's stars jump, using the official GitHub REST API.
Written with AI assistance and reviewed by the FedSignals Data team; we maintain these tools.
New open-source projects show up on GitHub every day, and in fast-moving areas like MCP servers, AI agents or RAG, the interesting ones collect hundreds of stars within a week. Release notes for the libraries you depend on matter too: a breaking change in an SDK you use is something you want to hear about the day it ships.
GitHub gives you the pieces, but not a feed:
- GitHub's trending page shows today's popular repos, but you can't filter it by topic and it has no API.
- "Watch → Releases" sends notifications per repo to your GitHub inbox. That's fine for five repos, but you can't send it to Slack, a spreadsheet or an LLM pipeline.
- The GitHub REST API has everything (search, stars, releases), but you have to page through search results, respect rate limits (10 searches a minute without a token) and remember what you already saw.
This tutorial uses the GitHub New Repo, Star-Jump & Release Alerts Actor on Apify, which we maintain. It calls the official GitHub API (no page scraping), searches each topic you choose, adds each repo's latest release, tracks releases of repos you list, and remembers what it has delivered so a daily run returns only new rows.
What you'll build
- A daily list of new repositories for your topics (for example
mcp,llm,ai-agents) with stars, language, license and latest release. - Release alerts for the repos you depend on, with cleaned-up release notes.
- A
star_jumpalert when a repo you already have gains 100+ stars between runs. - A Slack message (or webhook) with each day's new rows.
Step 1: Run it once by hand
Open the Actor page and click Try for free. The prefilled input looks like this:
{ "topics": ["mcp"], "minStars": 50, "createdWithinDays": 30, "watchRepos": ["modelcontextprotocol/python-sdk", "ollama/ollama"], "onlyNew": false, "maxItems": 10 } It finds MCP repositories created in the last 30 days with at least 50 stars, most-starred first, and the latest release of two watched repos. It takes a few seconds and costs about a cent. You don't need a GitHub token for a run this size.
Step 2: Look at the output
Each row is one event. eventType is new_repo, new_release or star_jump. Here is a new_repo row from a real run:
{ "eventType": "new_repo", "repo": "tangency-labs/solidcraft", "url": "https://github.com/tangency-labs/solidcraft", "description": "SolidCraft: an open-source parametric 3D CAD application built in pure Rust. Desktop, web, and automation through MCP.", "topics": [ "3d-modeling", "brep", "cad", "egui", "mcp", "parametric-cad", "rust", "step", "wasm" ], "language": "Rust", "stars": 12284, "starsGainedSinceLastRun": null, "forks": 1596, "openIssues": 4404, "createdAt": "2026-10-07T18:57:48Z", "pushedAt": "2026-10-30T16:14:19Z", "homepage": "https://solidcraft.io", "license": "Apache-2.0", "isFork": false, "latestRelease": { "tag": "v0.27.1", "name": "v0.27.1", "publishedAt": "2026-10-30T04:24:22Z", "url": "https://github.com/tangency-labs/solidcraft/releases/tag/v0.27.1", "prerelease": false }, "matchedTopic": "mcp", "releaseNotes": null, "scrapedAt": "2026-10-30T16:15:39Z" } matchedTopic tells you which topic search found the repo. starsGainedSinceLastRun stays null until a scheduled run has seen the repo before. Every row has the same fields. releaseNotes is filled only on new_release rows (up to 1,500 characters, with @mentions and e-mail addresses removed) and is null on new_repo and star_jump rows.
Every run also writes a SUMMARY record to its key-value store, so you can see what was searched, how many results GitHub had and why the run stopped:
{ "authenticated": false, "watchedRepos": 2, "searchQueries": [ { "query": "topic:mcp stars:>=50 created:>=2026-09-30 archived:false fork:false", "totalCount": 213, "scanned": 8 } ], "searchResultsScanned": 8, "delivered": { "new_repo": 8, "new_release": 2, "star_jump": 0 }, "skippedAlreadySeen": 0, "releaseLookups": 8, "releaseLookupsSkipped": 0, "partialFailures": [], "stopReason": "maxItems", "maxItems": 10, "firstRunForState": false, "requests": { "search": 1, "core": 12 }, "rateLimitRemaining": { "search": 9, "core": 48 }, "finishedAt": "2026-10-30T16:15:43Z" } totalCount: 213 is how many repos matched in total; the run stopped at maxItems. rateLimitRemaining shows how much of GitHub's unauthenticated budget is left.
Step 3: Call it from Python
This runs the Actor synchronously and prints each row. It reads your Apify token from an environment variable (never paste it into code). maxTotalChargeUsd caps the run's charges.
import os import requests ACTOR = "fedsignals~github-repo-release-tracker" URL = f"https://api.apify.com/v2/acts/{ACTOR}/run-sync-get-dataset-items" run_input = { "topics": ["mcp", "ai-agents"], "languages": ["Python", "TypeScript"], # combined with OR "minStars": 100, "createdWithinDays": 30, "watchRepos": ["modelcontextprotocol/python-sdk"], "onlyNew": True, # only rows this stateKey hasn't returned before "stateKey": "mcp-agents-daily", # one key per saved search "fetchLatestRelease": False, # skip per-repo release lookups to save GitHub requests "maxItems": 5, } resp = requests.post( URL, params={"maxTotalChargeUsd": 0.05}, headers={"Authorization": f"Bearer {os.environ['APIFY_TOKEN']}"}, json=run_input, timeout=300, ) resp.raise_for_status() for r in resp.json(): if r["eventType"] == "new_release": rel = r["latestRelease"] print(f"RELEASE {r['repo']} {rel['tag']} ({rel['publishedAt'][:10]}) {rel['url']}") else: gained = r.get("starsGainedSinceLastRun") extra = f" (+{gained})" if gained else "" print(f"{r['eventType'].upper():9} {r['repo']} {r['stars']} stars{extra} {r.get('language') or '-'} {r['url']}") Run it twice. The second run doesn't repeat anything from the first: onlyNew remembers every repo and release delivered for that stateKey, and only brings a repo back as star_jump if it gained at least starJumpThreshold stars (default 100) since the previous run.
Step 4: Schedule it daily
- In the Apify console, click Save as a new task with your topics and watched repos. Keep
onlyNew: trueand set astateKey. - Go to Schedules → Create new, use the cron expression
0 7 * * *(7:00 daily), set your timezone, and attach the task.
If you track many topics or more than a handful of repos, add your own GitHub token in githubToken (a fine-grained token with no extra permissions is enough). Without one, GitHub allows 10 searches a minute and 60 other requests an hour, and the Actor looks up at most 25 latest releases per run. It is stored as a secret input and never logged.
Step 5: Send new rows to Slack or a webhook
Add a webhook for ACTOR.RUN.SUCCEEDED that points at a small function you host. The payload includes resource.defaultDatasetId:
import os import requests def handler(payload: dict) -> None: dataset_id = payload["resource"]["defaultDatasetId"] items = requests.get( f"https://api.apify.com/v2/datasets/{dataset_id}/items", headers={"Authorization": f"Bearer {os.environ['APIFY_TOKEN']}"}, timeout=60, ).json() if not items: return # nothing new today label = {"new_repo": "New", "new_release": "Release", "star_jump": "Rising"} lines = [f"*{len(items)} GitHub updates*"] for r in items[:30]: rel = r.get("latestRelease") or {} if r["eventType"] == "new_release": lines.append(f"• {label['new_release']}: <{rel['url']}|{r['repo']} {rel['tag']}>") else: gained = r.get("starsGainedSinceLastRun") more = f", +{gained} since last run" if gained else "" lines.append(f"• {label[r['eventType']]}: <{r['url']}|{r['repo']}> ({r['stars']} stars{more})") requests.post(os.environ["SLACK_WEBHOOK_URL"], json={"text": "\n".join(lines)}, timeout=30) What it costs
Pay per event: $0.002 per repository row (new_repo or star_jump), $0.002 per release row, plus Apify's $0.00005 run-start fee. That's $2 per 1,000 rows. A daily run that finds 20 new repos and 2 releases costs about $0.044, and a run with nothing new costs only the start fee. Rows skipped as already seen are free, and invalid input (for example a misspelled language) fails before any row is charged (only the run-start fee applies).
FAQ
Do I need a GitHub token?
No, not for small runs. Add your own in githubToken for many topics, many watched repos or frequent runs.
Why one search per topic?
GitHub combines several topic: filters with AND, so mcp plus llm would only find repos tagged with both. The Actor runs one search per topic and removes duplicates. Languages are combined with OR.
Can I get more than 1,000 repos for a topic?
GitHub's search API returns at most 1,000 results per query. Narrow it with a higher minStars, fewer createdWithinDays or a language.
Does it collect personal data?
No profile data: no names, e-mails, followers or contributors. Repository names include the owner's public login, as on GitHub, and release notes have @mentions and e-mails removed.
What if GitHub's rate limit is hit?
The Actor waits up to about a minute, then returns what it has, explains it in the status message and SUMMARY, and you pay only for delivered rows.
Related
- How to Get Daily SAM.gov Contract Opportunity Alerts in Slack: the same daily-alert pattern for federal contracts.
- Documents to Markdown: turn the READMEs and docs you find into AI-ready Markdown.
Last updated: Nov 10, 2026 (tested against Actor build 0.1.6).
FedSignals Data builds small public-data monitors on Apify. FedSignals Data is not affiliated with, or endorsed by, GitHub. Data comes from the GitHub REST API under the GitHub Terms of Service. Questions or feature requests: fedsignals.alerts@gmail.com.

