Inspiration
Every team using GitHub and Slack together knows the pattern: a PR opens, review stalls, and nobody notices until someone manually checks. The existing tools that flag this only say "PR is 3 days old" — they never say why it's stuck or who needs to act. We wanted an agent that reasons about the actual review data, not just a timestamp.
What it does
Stale PR Nudger connects to GitHub through a real MCP server integration, pulls the live review status and comment history for open pull requests, and uses AI reasoning to determine the specific blocker — a missing reviewer, an unresolved comment thread, requested changes, or an unmerged approval. It posts a digest to a Slack channel and sends a targeted, specific DM to whoever needs to act, using a self-service linking command (link-github ) so any teammate can connect their own accounts without an admin manually maintaining a mapping.
How we built it
Built on Slack's CLI-generated agent scaffold (Bolt for Python + Pydantic AI), using a GitHub MCP server for real tool-calling access to PR data, with a two-stage architecture: one agent gathers raw PR facts via MCP tools, a second reasons over those facts against a strict, grounded rule set to produce structured output (blocker, category, digest line, DM text). Self-service account linking is handled through a lightweight DM command backed by a JSON store. The full pipeline runs on a scheduled task, posting digests and DMs without manual triggering.
Challenges we ran into
Combining Gemini's structured output with GitHub's large MCP tool schema hit a hard "too many states" constraint-serving error — solved by splitting data-gathering and reasoning into separate model calls. We also hit real-world API constraints from two different providers (Gemini's free-tier daily cap, then Groq's daily token budget), which pushed us toward a resilient, provider-agnostic design with per-PR error handling so one failure never kills a full run.
Accomplishments that we're proud of
A fully working, independently-verified pipeline — not a mockup — tested end to end multiple times with real GitHub data, real Slack messages landing, and grounded, specific reasoning rather than generic "PR is old" alerts. The self-service linking replaced what started as a hardcoded single-user mapping, a meaningful step toward something a real team could actually use.
What we learned
Structured output and large tool schemas don't always compose cleanly on every model provider — architecture decisions (like splitting gather/reason into two calls) can matter more than prompt wording. We also learned to treat "the terminal shows success" as the start of verification, not the end of it — several early "working" states turned out to be incomplete until checked directly in Slack.
What's next for Stale PR Nudger
A real OAuth-based install flow (the scaffold already exists in app_oauth.py) for genuine one-click setup and an eventual Slack Marketplace path; native Slack scheduled triggers instead of local Task Scheduler, so the agent runs from the cloud rather than a personal machine; multi-repo support; and verified GitHub OAuth for account linking instead of self-reported usernames.
Log in or sign up for Devpost to join the conversation.