Claude Academy
advanced16 min

Building a PR Review Skill

Learning Objectives

  • Build a complete PR review skill from scratch
  • Combine MCP tools with skill instructions
  • Create structured review output
  • Handle multiple review categories (security, quality, performance)

The Complete PR Review Skill

We're going to build a production-quality PR review skill that:

1. Fetches the PR diff via GitHub MCP

2. Scans for security vulnerabilities

3. Checks code quality

4. Identifies performance issues

5. Outputs a structured markdown review

This is the kind of skill that saves hours per week for teams doing regular code review.

The Skill Structure

.claude/skills/pr-review/

├── SKILL.md

└── references/

└── security-patterns.md

SKILL.md

---

name: PR Review

description: Comprehensive pull request review covering security, quality, and performance

disableAutoInvocation: true


Overview

This skill performs a comprehensive PR review. It must be invoked

explicitly with /pr-review <pr-number>.

Prerequisites

  • GitHub MCP server must be connected
  • The repository must be a git repo with a remote

Workflow

Step 1: Gather PR Data

1. Use mcp__github to fetch the PR details:

- Title, description, author

- Changed files list

- Full diff

- Existing review comments

2. Read each changed file in full (not just the diff) to understand context

Step 2: Security Scan

Check every changed file for these patterns:

#### SQL Injection

  • Raw string concatenation in SQL queries
  • Template literals in database queries
  • Missing parameterized queries
  • Dynamic table/column names from user input

#### Cross-Site Scripting (XSS)

  • innerHTML or dangerouslySetInnerHTML with user data
  • Unsanitized output in templates
  • Missing Content-Security-Policy headers

#### Authentication/Authorization Bypass

  • Endpoints missing auth middleware
  • Role checks that can be bypassed
  • Token validation gaps
  • Session management issues

#### Data Exposure

  • PII in log statements (emails, names, addresses)
  • Verbose error messages exposing internals
  • Sensitive data in API responses
  • Hardcoded secrets or credentials

#### Input Validation

  • Missing Zod/validation on request bodies
  • Incomplete validation (checking type but not bounds)
  • Missing sanitization on output

Step 3: Code Quality Review

Check for:

  • Duplicated logic: Same code in multiple places
  • Single responsibility violations: Functions doing too many things
  • Error handling gaps: Uncaught promises, missing try/catch, generic catches
  • Type safety: Any types, type assertions, missing return types
  • Naming: Unclear variable/function names
  • Dead code: Unused imports, unreachable code, commented-out code

Step 4: Performance Review

Check for:

  • N+1 queries: Database queries inside loops
  • Missing indexes: Queries on unindexed columns
  • Unnecessary computation: Repeated calculations, missing memoization
  • Large payloads: Responses returning more data than needed
  • Missing pagination: List endpoints without limits
  • Synchronous bottlenecks: Blocking operations in async contexts

Step 5: Generate Report

Output the review in this exact format:

Output Format

markdown

# PR Review: #{pr_number} — {pr_title}

Author: {author}

Files Changed: {count}

Review Date: {date}

Summary

{1-2 sentence summary of the PR and overall assessment}

Critical Findings

| # | Severity | Category | File:Line | Finding |

|---|----------|----------|-----------|---------|

| 1 | CRITICAL | Security | src/api/users.ts:47 | SQL injection via unsanitized query parameter |

| 2 | HIGH | Security | src/auth/middleware.ts:12 | Missing auth check on admin endpoint |

Details

#### Finding 1: SQL injection via unsanitized query parameter

File: src/api/users.ts:47

Severity: CRITICAL

Category: Security

Description: User input from req.query.search is concatenated

directly into the SQL query without parameterization.

Current Code:

const users = await db.query(SELECT * FROM users WHERE name LIKE '%${search}%');

Recommended Fix:

const users = await db.query('SELECT * FROM users WHERE name LIKE $1', [%${search}%]);

Warnings

{Same format as Critical Findings}

Suggestions

{Same format but lighter tone — improvements, not requirements}

Approval Recommendation

  • [ ] Approve: No critical or high-severity findings
  • [ ] Request Changes: Critical or high-severity findings present
  • [ ] Comment: Only suggestions, no blocking issues
## Severity Definitions

  • CRITICAL: Must fix before merge. Security vulnerability, data loss risk, or production-breaking.
  • HIGH: Should fix before merge. Significant quality or performance issue.
  • MEDIUM: Fix in follow-up. Code quality concern that doesn't block merge.
  • LOW: Optional. Style suggestion or minor improvement.

Rules

  • Read the FULL file for context, not just the diff lines
  • Reference specific line numbers for every finding
  • Provide a concrete fix for every finding (not just "fix this")
  • Don't report style issues if the project has a formatter
  • Check CLAUDE.md for project-specific conventions before flagging violations
  • If no issues found, explicitly say "No issues found" — don't invent findings

Using the Skill

Setup

Ensure the GitHub MCP server is connected:

claude mcp add github -e GITHUB_TOKEN=ghp_xxx --transport stdio npx -y @modelcontextprotocol/server-github

Invocation

# In a Claude Code session

/pr-review 42

Or with natural language:

"Use the PR review skill to review PR #42"

Example Output

Claude produces a structured review like:

# PR Review: #42 — Add order cancellation endpoint

Author: @engineer

Files Changed: 7

Review Date: 2026-04-04

Summary

This PR adds order cancellation with refund processing. The implementation

follows the service pattern but has two security concerns and one

performance issue that should be addressed before merge.

Critical Findings

| # | Severity | Category | File:Line | Finding |

|---|----------|----------|-----------|---------|

| 1 | HIGH | Security | src/services/order.ts:89 | Missing idempotency check on refund |

| 2 | MEDIUM | Performance | src/repos/order-repo.ts:34 | N+1 query in cancellation batch |

...

Extending the Skill

Add Custom Security Patterns

Create .claude/skills/pr-review/references/security-patterns.md:

# Project-Specific Security Patterns

HMAC Verification

All webhook handlers MUST call verifyHmac() before processing.

Check that new webhook handlers include this.

Multi-Tenancy

All database queries MUST include merchantId filter.

Check that new queries don't accidentally expose cross-tenant data.

Rate Limiting

All public endpoints MUST have rate limiting applied.

Check that new routes include @fastify/rate-limit.

The skill can reference these project-specific patterns during reviews.

Key Takeaway

A PR review skill combines GitHub MCP (data fetching) with structured review instructions (what to check and how to report). The skill checks security (injection, XSS, auth bypass), quality (duplication, error handling, types), and performance (N+1 queries, missing indexes). Structured markdown output with severity tags and file:line references makes findings actionable and directly postable as GitHub PR comments. Build the skill once, use it for every PR.