Replace gh CLI and curl-based GitHub API interactions with native GitHub MCP tools (mcp_github_*). This modernizes the skill to use the agent's built-in MCP integration for all GitHub operations. Key changes: - Replace gh CLI commands with mcp_github_pull_request_read(), mcp_github_pull_request_review_write(), etc. - Replace curl API calls with mcp_github_add_issue_comment(), mcp_github_add_comment_to_pending_review(), etc. - Add mcp_github_run_secret_scanning() to security checklist - Add mcp_github_request_copilot_review() as optional step - Add quick reference table mapping tasks to MCP tools - Keep git CLI for local diff operations (unchanged) - Bump version to 2.0.0
11 KiB
| name | description | version | author | license | metadata | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| github-code-review | Review code changes by analyzing git diffs, leaving inline comments on PRs, and performing thorough pre-push review. Uses GitHub MCP tools (mcp_github_*) as the primary interface, with git CLI for local diff operations. | 2.0.0 | Hermes Agent | MIT |
|
GitHub Code Review
Perform code reviews on local changes before pushing, or review open PRs on GitHub. This skill uses GitHub MCP tools (mcp_github_*) as the primary interface for all GitHub API interactions, with plain git for local diff operations.
Prerequisites
- GitHub MCP server configured (provides
mcp_github_*tools) - Inside a git repository (for local diff operations)
1. Reviewing Local Changes (Pre-Push)
Local diffs use plain git — no API needed.
Get the Diff
# Staged changes (what would be committed)
git diff --staged
# All changes vs main (what a PR would contain)
git diff main...HEAD
# File names only
git diff main...HEAD --name-only
# Stat summary (insertions/deletions per file)
git diff main...HEAD --stat
Review Strategy
- Get the big picture first:
git diff main...HEAD --stat
git log main..HEAD --oneline
- Review file by file — use
read_fileon changed files for full context, and the diff to see what changed:
git diff main...HEAD -- src/auth/login.py
- Check for common issues:
# Debug statements, TODOs, console.logs left behind
git diff main...HEAD | grep -n "print(\|console\.log\|TODO\|FIXME\|HACK\|XXX\|debugger"
# Large files accidentally staged
git diff main...HEAD --stat | sort -t'|' -k2 -rn | head -10
# Secrets or credential patterns
git diff main...HEAD | grep -in "password\|secret\|api_key\|token.*=\|private_key"
# Merge conflict markers
git diff main...HEAD | grep -n "<<<<<<\|>>>>>>\|======="
- Present structured feedback to the user.
Review Output Format
When reviewing local changes, present findings in this structure:
## Code Review Summary
### Critical
- **src/auth.py:45** — SQL injection: user input passed directly to query.
Suggestion: Use parameterized queries.
### Warnings
- **src/models/user.py:23** — Password stored in plaintext. Use bcrypt or argon2.
- **src/api/routes.py:112** — No rate limiting on login endpoint.
### Suggestions
- **src/utils/helpers.py:8** — Duplicates logic in `src/core/utils.py:34`. Consolidate.
- **tests/test_auth.py** — Missing edge case: expired token test.
### Looks Good
- Clean separation of concerns in the middleware layer
- Good test coverage for the happy path
2. Reviewing a Pull Request on GitHub (MCP Tools)
Step 1: Gather PR Context
Use MCP tools to get PR metadata, description, and changed files:
# Get PR details (title, author, description, branch, status)
mcp_github_pull_request_read(method="get", owner=OWNER, repo=REPO, pullNumber=PR_NUMBER)
# Get the diff
mcp_github_pull_request_read(method="get_diff", owner=OWNER, repo=REPO, pullNumber=PR_NUMBER)
# Get list of changed files with additions/deletions
mcp_github_pull_request_read(method="get_files", owner=OWNER, repo=REPO, pullNumber=PR_NUMBER)
# Get CI/CD status
mcp_github_pull_request_read(method="get_status", owner=OWNER, repo=REPO, pullNumber=PR_NUMBER)
# Get check runs (individual CI jobs)
mcp_github_pull_request_read(method="get_check_runs", owner=OWNER, repo=REPO, pullNumber=PR_NUMBER)
Step 2: Read File Contents for Context
For each changed file, read the full file to understand the surrounding context:
# Read specific files from the PR branch
mcp_github_get_file_contents(owner=OWNER, repo=REPO, path="src/auth/login.py", ref="refs/pull/PR_NUMBER/head")
Step 3: Check Out Locally (Optional — for running tests)
If you need to run tests or linters locally:
git fetch origin pull/PR_NUMBER/head:pr-PR_NUMBER
git checkout pr-PR_NUMBER
# Run tests
python -m pytest 2>&1 | tail -20
# Run linter
ruff check . 2>&1 | head -30
Step 4: Get Existing Review Comments
Check what's already been discussed:
# Get review threads (grouped comments on code locations)
mcp_github_pull_request_read(method="get_review_comments", owner=OWNER, repo=REPO, pullNumber=PR_NUMBER)
# Get general PR comments
mcp_github_pull_request_read(method="get_comments", owner=OWNER, repo=REPO, pullNumber=PR_NUMBER)
# Get formal reviews (approvals, change requests)
mcp_github_pull_request_read(method="get_reviews", owner=OWNER, repo=REPO, pullNumber=PR_NUMBER)
Step 5: Apply the Review Checklist (Section 3)
Go through each category systematically.
Step 6: Submit a Formal Review with Inline Comments
Use the MCP review tools to submit findings:
Create a pending review, add inline comments, then submit:
# Step A: Create a pending review (omit "event" to keep it pending)
mcp_github_pull_request_review_write(
method="create",
owner=OWNER,
repo=REPO,
pullNumber=PR_NUMBER
)
# Step B: Add inline comments to the pending review
mcp_github_add_comment_to_pending_review(
owner=OWNER,
repo=REPO,
pullNumber=PR_NUMBER,
path="src/auth.py",
line=45,
body="🔴 **Critical:** User input passed directly to SQL query — use parameterized queries.",
subjectType="LINE",
side="RIGHT"
)
mcp_github_add_comment_to_pending_review(
owner=OWNER,
repo=REPO,
pullNumber=PR_NUMBER,
path="src/models/user.py",
line=23,
body="⚠️ **Warning:** Password stored without hashing. Use bcrypt or argon2.",
subjectType="LINE",
side="RIGHT"
)
# Step C: Submit the pending review
mcp_github_pull_request_review_write(
method="submit_pending",
owner=OWNER,
repo=REPO,
pullNumber=PR_NUMBER,
event="REQUEST_CHANGES", # or "APPROVE" or "COMMENT"
body="## Hermes Agent Review\n\nFound 2 issues. See inline comments."
)
Or submit a review directly (no pending step):
# Approve
mcp_github_pull_request_review_write(
method="create",
owner=OWNER,
repo=REPO,
pullNumber=PR_NUMBER,
event="APPROVE",
body="LGTM! Code looks clean — good test coverage, no security concerns."
)
# Request changes
mcp_github_pull_request_review_write(
method="create",
owner=OWNER,
repo=REPO,
pullNumber=PR_NUMBER,
event="REQUEST_CHANGES",
body="Found a few issues — see inline comments."
)
Step 7: Post a Summary Comment
Leave a top-level summary so the PR author gets the full picture:
mcp_github_add_issue_comment(
owner=OWNER,
repo=REPO,
issue_number=PR_NUMBER,
body="""## Code Review Summary
**Verdict: Changes Requested** (2 issues, 1 suggestion)
### 🔴 Critical
- **src/auth.py:45** — SQL injection vulnerability
### ⚠️ Warnings
- **src/models.py:23** — Plaintext password storage
### 💡 Suggestions
- **src/utils.py:8** — Duplicated logic, consider consolidating
### ✅ Looks Good
- Clean API design
- Good error handling in the middleware layer
---
*Reviewed by Hermes Agent*"""
)
Step 8: Reply to Existing Comments
If the PR author responds to your review:
# Reply to a specific review comment
mcp_github_add_reply_to_pull_request_comment(
owner=OWNER,
repo=REPO,
pullNumber=PR_NUMBER,
commentId=COMMENT_ID,
body="Good point! That approach works too."
)
Step 9: Request Copilot Review (Optional)
For automated AI feedback before your review:
mcp_github_request_copilot_review(owner=OWNER, repo=REPO, pullNumber=PR_NUMBER)
Step 10: Clean Up (if checked out locally)
git checkout main
git branch -D pr-PR_NUMBER
3. Review Checklist
When performing a code review (local or PR), systematically check:
Correctness
- Does the code do what it claims?
- Edge cases handled (empty inputs, nulls, large data, concurrent access)?
- Error paths handled gracefully?
Security
- No hardcoded secrets, credentials, or API keys
- Input validation on user-facing inputs
- No SQL injection, XSS, or path traversal
- Auth/authz checks where needed
- Use
mcp_github_run_secret_scanningon changed files for automated secret detection
Code Quality
- Clear naming (variables, functions, classes)
- No unnecessary complexity or premature abstraction
- DRY — no duplicated logic that should be extracted
- Functions are focused (single responsibility)
Testing
- New code paths tested?
- Happy path and error cases covered?
- Tests readable and maintainable?
Performance
- No N+1 queries or unnecessary loops
- Appropriate caching where beneficial
- No blocking operations in async code paths
Documentation
- Public APIs documented
- Non-obvious logic has comments explaining "why"
- README updated if behavior changed
4. Pre-Push Review Workflow
When the user asks you to "review the code" or "check before pushing":
git diff main...HEAD --stat— see scope of changesgit diff main...HEAD— read the full diff- For each changed file, use
read_fileif you need more context - Apply the checklist above
- Present findings in the structured format (Critical / Warnings / Suggestions / Looks Good)
- If critical issues found, offer to fix them before the user pushes
5. PR Review Workflow (End-to-End with MCP Tools)
When the user asks you to "review PR #N", "look at this PR", or gives you a PR URL:
Quick Reference
| Task | MCP Tool |
|---|---|
| Get PR details | mcp_github_pull_request_read(method="get") |
| Get PR diff | mcp_github_pull_request_read(method="get_diff") |
| Get changed files | mcp_github_pull_request_read(method="get_files") |
| Get CI status | mcp_github_pull_request_read(method="get_status") |
| Get check runs | mcp_github_pull_request_read(method="get_check_runs") |
| Read file contents | mcp_github_get_file_contents(ref="refs/pull/N/head") |
| Get review threads | mcp_github_pull_request_read(method="get_review_comments") |
| Get PR comments | mcp_github_pull_request_read(method="get_comments") |
| Get reviews | mcp_github_pull_request_read(method="get_reviews") |
| Create pending review | mcp_github_pull_request_review_write(method="create") |
| Add inline comment | mcp_github_add_comment_to_pending_review() |
| Submit review | mcp_github_pull_request_review_write(method="submit_pending") |
| Add PR comment | mcp_github_add_issue_comment() |
| Reply to comment | mcp_github_add_reply_to_pull_request_comment() |
| Scan for secrets | mcp_github_run_secret_scanning() |
| Request Copilot review | mcp_github_request_copilot_review() |
Decision: Approve vs Request Changes vs Comment
- Approve — no critical or warning-level issues, only minor suggestions or all clear
- Request Changes — any critical or warning-level issue that should be fixed before merge
- Comment — observations and suggestions, but nothing blocking (use when you're unsure or the PR is a draft)