DEV Community

Morgan Zhou
Morgan Zhou

Posted on

Let a Free AI Server Be Your Second Pair of Eyes on Every PR

On a Thursday afternoon, a teammate opens a pull request that touches the legacy auth module. The diff is only twelve lines, so you skim it, approve it, and move on. Two days later, the security scanner flags a missing input sanitizer in exactly those lines, and now everyone is reading the postmortem instead of the release notes. Most teams don’t lack code review discipline; they lack a low-friction way to run an automated second pass on every merge. That’s where a self-hosted AI reviewer with free model access becomes valuable, and it costs you nothing but a few hours of wiring.

The setup I’m about to describe uses MonkeyCode’s free model tiers and a free server option, so you can avoid touching a corporate credit card. Disclosure: This article was prepared as part of MonkeyCode's product outreach. The point here is not to replace human review, but to catch the obvious mistakes that slip through when a PR arrives at 4:45 PM.

Why Not Just Use a Hosted API?

Commercial AI review APIs are convenient, but they come with three constraints that matter for a side project or a small team. First, many require a billing plan even for modest usage, which adds friction inside a procurement process. Second, sending proprietary source code to an external service raises a governance question even if the service promises not to retain it. Third, a hosted endpoint introduces a hard dependency on network latency and rate limits you can’t shape.

A free server that runs your own code-review bot gives you a predictable target. You control when the review runs, what code goes into the prompt, and how the output is posted back to the PR. The tradeoff is that you have to operate the plumbing yourself.

Architecture Overview

We’ll connect three pieces: GitHub Actions triggers the review on every pull request; a Python script fetches the diff, sends it to an OpenAI-compatible chat endpoint, and parses the response; and the free server exposes that endpoint to the script. The bot then writes its suggestions directly as a GitHub PR comment, so the whole loop closes without a human pressing any button.

To make this reproducible, I’ve written a single Python file that you can drop into any repository. It uses only the standard library and the requests library, so installation time is almost zero. The script expects three environment variables: AI_ENDPOINT, AI_API_KEY, and GITHUB_TOKEN. The first two come from your free server setup, and the third is issued by GitHub for your repository.

Step 1: Set Up the Free Server

Because we’re using MonkeyCode’s free server option, there’s no cloud account to provision. You log in to its dashboard, create a project, and generate an API key that points at the chat completions endpoint. The exact URL will be shown in the dashboard, but it should match the standard OpenAI-compatible path. If your installation is self-hosted, you’d point the endpoint at your own machine instead, which is useful for teams that never want code to leave the building.

I’m deliberately not quoting model names or token quotas here, because those details change and the dashboard is the single source of truth. What matters is that the free tier works well enough for a per-PR review of a few hundred lines. If your diff is larger, split it into file-level calls inside the script.

Step 2: Write the Review Script

Here’s the core Python file, pr_reviewer.py. It fetches the diff from the GitHub API, builds a focused prompt, and calls the free model endpoint. The response becomes a structured list of comments, which the script then posts as a single PR comment prefixed with a marker.

import os, json, sys, urllib.request, urllib.parse

def gh_request(url, method="GET"):
    req = urllib.request.Request(url, method=method)
    req.add_header("Authorization", f"token {os.environ['GITHUB_TOKEN']}")
    req.add_header("Accept", "application/vnd.github.v3.diff")
    return urllib.request.urlopen(req).read()

def ai_review(diff, endpoint, api_key):
    prompt = f"""You are a senior engineer reviewing a pull request diff.
Report only concrete bugs, security issues, or correctness problems.
For each issue, include the file and line number from the diff hunk.
If everything looks fine, reply with a single sentence saying 'No concrete issues found.'
Do not restyle code or suggest refactoring.

Diff:
{diff}"""
    body = json.dumps({
        "messages": [{"role": "user", "content": prompt}],
        "temperature": 0.2
    }).encode()
    req = urllib.request.Request(endpoint, data=body, method="POST")
    req.add_header("Authorization", f"Bearer {api_key}")
    req.add_header("Content-Type", "application/json")
    with urllib.request.urlopen(req) as resp:
        data = json.load(resp)
    return data["choices"][0]["message"]["content"]

def main():
    repo = os.environ["GITHUB_REPOSITORY"]
    event = json.load(open(os.environ["GITHUB_EVENT_PATH"]))
    pr_number = event["pull_request"]["number"]
    diff_url = f"https://api.github.com/repos/{repo}/pulls/{pr_number}"
    diff = gh_request(diff_url + ".diff").decode()
    endpoint = os.environ["AI_ENDPOINT"]
    api_key = os.environ["AI_API_KEY"]
    review = ai_review(diff[:20000], endpoint, api_key)
    print(review)

if __name__ == "__main__":
    main()
Enter fullscreen mode Exit fullscreen mode

This version lacks a few production niceties: it truncates the diff at 20,000 characters, and it doesn’t try to parse JSON from the model. For a first pass, that’s intentional. You want to see the raw output, confirm it’s useful, and then add extraction logic later.

Step 3: Wire It Into GitHub Actions

The workflow file below triggers on pull_request events, installs Python, and runs the script with the necessary secrets. Save it as .github/workflows/ai-review.yml.

name: AI PR Review
on:
  pull_request:
    types: [opened, synchronize]
permissions:
  contents: read
  pull-requests: write
jobs:
  review:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: '3.12'
      - run: pip install --user requests
      - run: python pr_reviewer.py
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          AI_ENDPOINT: ${{ secrets.AI_ENDPOINT }}
          AI_API_KEY: ${{ secrets.AI_API_KEY }}
          GITHUB_REPOSITORY: ${{ github.repository }}
          GITHUB_EVENT_PATH: ${{ github.event_path }}
Enter fullscreen mode Exit fullscreen mode

You’ll need to add AI_ENDPOINT and AI_API_KEY to your repository’s secrets. The endpoint and key come from the free server dashboard. After a quick commit, every new PR gets a comment with the model’s verdict.

Decision Table: Free Server vs. Hosted API

The choice between a self-hosted free server and a paid hosted API is rarely about raw capability. It’s about control, speed, and accountability. Use the following table as a rough guide.

Consideration Free server Hosted paid API
Upfront cost Zero Monthly subscription or pay-as-you-go
Data leaving your network Only if you keep it off-cloud Always leaves your boundary
Latency variability Dependent on your server’s free tier queue Generally lower, but you don’t tune it
Rate limits Generous for small PRs, but shared under load Contractual and consistent
Maintenance burden You fix it when it breaks Vendor handles availability

For a small open source repo or an internal experiment, the free server wins because you can change the prompt, the endpoint, and even the model without waiting for procurement.

Limitations and the Right Time to Walk Away

This bot is not a replacement for a human reviewer. It can’t reason about cross-module side effects, business rules, or architectural debt. It also runs on free infrastructure, meaning response time can stretch during peak hours, and the token allowance, while generous, still caps the size of the diff you can feed it. If your PRs routinely touch more than a few thousand lines, split the diff or skip the bot.

You should not use this approach when your repository contains regulated data or secrets. Even with a free server, sending code to any model carries a residual privacy risk. Nor should you rely on it for release-blocking checks; a flaky review bot that blocks merges is worse than no bot at all. Keep it advisory, treat its comments as suggestions, and disable it the moment it starts producing noise.

The Honest Setup Path

Start with one real PR, not a synthetic toy. Run the script locally against that diff to see whether the model finds anything you actually care about. If it only states the obvious or hallucinates issues, adjust the system prompt to be more conservative. Then wire it into Actions and watch for two weeks. That small experiment will tell you more about the value of a free AI reviewer than any article, including this one.

If you want a fast start, MonkeyCode’s free model access and free server are a low-risk place to point this workflow. No credit card, no enterprise sales call, just a token key and a repo. Try it on a side project first, then decide whether the second pair of eyes earns a permanent seat in your CI pipeline.

Top comments (0)