# How to use MCP for automated code review

- Tool: MCP
- Difficulty: Advanced
- Time required: 30-45 min
- Compatibility: MCP TypeScript SDK v1.x, GitHub MCP Server, Filesystem MCP Server, Claude Desktop / Cursor
- Last updated: March 2026

## TL;DR

Automate code reviews using MCP by connecting GitHub and Filesystem servers to an AI assistant. The AI reads pull request diffs via the GitHub MCP server, inspects the actual source files via the Filesystem server, and produces structured review comments with file references and line numbers. This catches bugs, style violations, and security issues that manual review misses.

## AI-Powered Code Review with MCP Servers

Code review is one of the highest-value use cases for MCP. By connecting GitHub and Filesystem MCP servers, an AI assistant can read pull request diffs, access the full repository context, and produce detailed review comments. Unlike simple diff-based tools, MCP gives the AI access to the entire codebase, so it understands how changes affect other files, whether imports exist, and whether the code follows project conventions.

## Before you start

- GitHub MCP server installed or configured
- Filesystem MCP server configured with repository access
- Claude Desktop or Cursor with MCP support
- A GitHub repository with pull requests to review
- GitHub personal access token with repo scope

## Step-by-step guide

### 1. Configure the GitHub MCP server for PR access

Set up the GitHub MCP server in your MCP client configuration. The server provides tools to list PRs, read diffs, get file contents from branches, and post review comments. You need a GitHub personal access token with repo scope. Add the server to your Claude Desktop or Cursor MCP config with the token as an environment variable.

```
// Claude Desktop: ~/Library/Application Support/Claude/claude_desktop_config.json
{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_your_token_here"
      }
    }
  }
}
```

**Expected result:** GitHub MCP server appears in your client's tool list with PR-related tools available.

### 2. Add the Filesystem MCP server for full repository context

The Filesystem server gives the AI direct access to read source files in the repository. This is critical for code review because the AI needs to see not just the diff, but the surrounding code, imported modules, and configuration files. Configure it to allow read-only access to your repository directory.

```
// Add to your mcpServers configuration:
{
  "mcpServers": {
    "github": { /* ... from previous step */ },
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/your/repo"],
      "env": {}
    }
  }
}
```

**Expected result:** Filesystem MCP server provides read_file, list_files, and search_files tools for the repository.

### 3. Build a structured code review prompt

Create a system prompt or instruction set that tells the AI how to perform code reviews. The prompt should specify: which tools to use, what to look for (bugs, security, style, performance), how to format comments, and the project's coding standards. Reference your .cursorrules or project conventions so the AI applies your team's specific standards.

```
// Example review prompt for Claude Desktop / Cursor:
// "Review PR #42 in the repository owner/repo-name.
// 
// Steps:
// 1. Use the GitHub tools to fetch the PR diff and changed files list
// 2. For each changed file, use the filesystem tools to read the full file
// 3. Check for:
//    - Logic bugs and edge cases
//    - Security vulnerabilities (injection, XSS, auth bypass)
//    - TypeScript type safety issues
//    - Missing error handling
//    - Performance concerns
//    - Code style violations per our .cursorrules
// 4. Format each finding as:
//    FILE: path/to/file.ts
//    LINE: 42
//    SEVERITY: critical | warning | suggestion
//    ISSUE: Description of the problem
//    FIX: Suggested code change
// 
// Be specific with line numbers and provide concrete fix suggestions."
```

**Expected result:** A structured prompt that guides the AI to perform thorough, consistent code reviews.

### 4. Build a custom MCP server for automated review pipelines

For CI/CD integration, build a custom MCP server that wraps the GitHub API and adds review-specific tools: get_pr_diff, get_changed_files, post_review_comment. This server handles authentication, pagination, and formatting so the AI gets clean data. The post_review_comment tool writes comments back to the PR with file paths and line numbers.

```
// src/tools/review-tools.ts
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";

export function registerReviewTools(server: McpServer) {
  server.tool(
    "get_pr_diff",
    "Get the diff for a pull request",
    {
      owner: z.string(),
      repo: z.string(),
      prNumber: z.number(),
    },
    async ({ owner, repo, prNumber }) => {
      const response = await fetch(
        `https://api.github.com/repos/${owner}/${repo}/pulls/${prNumber}`,
        {
          headers: {
            Authorization: `Bearer ${process.env.GITHUB_TOKEN}`,
            Accept: "application/vnd.github.v3.diff",
          },
        }
      );
      const diff = await response.text();
      return { content: [{ type: "text", text: diff }] };
    }
  );

  server.tool(
    "post_review_comment",
    "Post a review comment on a specific line of a PR",
    {
      owner: z.string(),
      repo: z.string(),
      prNumber: z.number(),
      body: z.string().describe("Comment text"),
      path: z.string().describe("File path relative to repo root"),
      line: z.number().describe("Line number in the diff"),
    },
    async ({ owner, repo, prNumber, body, path, line }) => {
      const response = await fetch(
        `https://api.github.com/repos/${owner}/${repo}/pulls/${prNumber}/comments`,
        {
          method: "POST",
          headers: {
            Authorization: `Bearer ${process.env.GITHUB_TOKEN}`,
            "Content-Type": "application/json",
          },
          body: JSON.stringify({ body, path, line, side: "RIGHT" }),
        }
      );
      if (!response.ok) {
        const error = await response.text();
        return { content: [{ type: "text", text: `Error: ${error}` }], isError: true };
      }
      return { content: [{ type: "text", text: `Comment posted on ${path}:${line}` }] };
    }
  );
}
```

**Expected result:** Custom MCP tools that fetch PR diffs and post review comments with line-level precision.

### 5. Integrate into GitHub Actions for automated PR reviews

Run the AI code review automatically on every PR by triggering it from GitHub Actions. The workflow checks out the code, starts the MCP server, connects an AI client, and posts review comments. Use a script that calls your MCP server's tools programmatically. For teams needing a turnkey solution, RapidDev offers pre-built AI code review integrations that work out of the box with MCP.

```
# .github/workflows/ai-review.yml
name: AI Code Review
on:
  pull_request:
    types: [opened, synchronize]

jobs:
  review:
    runs-on: ubuntu-latest
    permissions:
      pull-requests: write
      contents: read
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - name: Install MCP review server
        run: cd review-server && npm ci && npx tsc
      - name: Run AI code review
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
          PR_NUMBER: ${{ github.event.pull_request.number }}
          REPO_OWNER: ${{ github.repository_owner }}
          REPO_NAME: ${{ github.event.repository.name }}
        run: node review-server/dist/run-review.js
```

**Expected result:** Every PR automatically receives AI-generated code review comments via GitHub Actions.

## Complete code example

File: `src/review-server.ts`

```typescript
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

const GITHUB_TOKEN = process.env.GITHUB_TOKEN!;

async function ghFetch(path: string, options: RequestInit = {}) {
  const res = await fetch(`https://api.github.com${path}`, {
    ...options,
    headers: {
      Authorization: `Bearer ${GITHUB_TOKEN}`,
      Accept: "application/vnd.github.v3+json",
      ...options.headers,
    },
  });
  return res;
}

const server = new McpServer({ name: "code-review-server", version: "1.0.0" });

server.tool("get_pr_info", "Get PR title, description, and changed files", {
  owner: z.string(), repo: z.string(), pr: z.number(),
}, async ({ owner, repo, pr }) => {
  const res = await ghFetch(`/repos/${owner}/${repo}/pulls/${pr}`);
  const data = await res.json();
  const files = await ghFetch(`/repos/${owner}/${repo}/pulls/${pr}/files`);
  const fileList = await files.json();
  return { content: [{ type: "text", text: JSON.stringify({
    title: data.title, body: data.body, files: fileList.map((f: any) => ({
      filename: f.filename, status: f.status, additions: f.additions, deletions: f.deletions,
    })),
  }, null, 2) }] };
});

server.tool("get_file_diff", "Get diff for a specific file in a PR", {
  owner: z.string(), repo: z.string(), pr: z.number(), filename: z.string(),
}, async ({ owner, repo, pr, filename }) => {
  const res = await ghFetch(`/repos/${owner}/${repo}/pulls/${pr}/files`);
  const files = await res.json();
  const file = files.find((f: any) => f.filename === filename);
  if (!file) return { content: [{ type: "text", text: "File not found in PR" }], isError: true };
  return { content: [{ type: "text", text: file.patch || "(binary file)" }] };
});

server.tool("post_comment", "Post a review comment on the PR", {
  owner: z.string(), repo: z.string(), pr: z.number(),
  body: z.string(), path: z.string(), line: z.number(),
}, async ({ owner, repo, pr, body, path, line }) => {
  const res = await ghFetch(`/repos/${owner}/${repo}/pulls/${pr}/comments`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ body, path, line, side: "RIGHT" }),
  });
  if (!res.ok) return { content: [{ type: "text", text: `Error: ${await res.text()}` }], isError: true };
  return { content: [{ type: "text", text: `Comment posted on ${path}:${line}` }] };
});

async function main() {
  const transport = new StdioServerTransport();
  await server.connect(transport);
  console.error("Code review MCP server running");
}
main().catch(e => { console.error(e); process.exit(1); });
```

## Common mistakes

- **Reviewing only the diff without reading the full files for context** — undefined Fix: Use the Filesystem server to read complete files, not just changed lines. The AI needs surrounding code to spot bugs like missing imports or broken function signatures.
- **Posting review comments with wrong line numbers because of diff format confusion** — undefined Fix: Use the GitHub diff line numbers (from the patch), not the absolute file line numbers. The GitHub API expects diff-relative line numbers for PR comments.
- **Not scoping the GitHub token to specific repositories, creating unnecessary security risk** — undefined Fix: Use fine-grained personal access tokens scoped to only the repositories that need AI review.
- **Running automated reviews without human oversight, creating noisy or incorrect comments** — undefined Fix: Start with the AI drafting reviews for human approval before enabling fully automated posting. Tune the review prompt based on feedback.

## Best practices

- Read full files alongside diffs so the AI understands the complete context
- Include project coding standards in the review prompt for consistent feedback
- Start with human-reviewed AI suggestions before enabling fully automated comments
- Use fine-grained GitHub tokens scoped to specific repositories
- Post comments with specific file paths and line numbers for actionable feedback
- Categorize findings by severity (critical, warning, suggestion) for prioritization
- Rate limit review comments to avoid overwhelming PR authors with noise

## Frequently asked questions

### Can MCP-based code review replace human reviewers?

No. AI code review is best as a first pass that catches common issues (bugs, security, style) before human review. It saves reviewer time but should not be the only review step for production code.

### How many credits does an AI code review cost?

A typical PR review with 5-10 changed files uses 2,000-5,000 tokens of input and 500-1,000 tokens of output per file. With Claude 3.5 Sonnet, this costs roughly $0.05-$0.15 per review.

### Can I customize what the AI checks for?

Yes. Modify the review prompt to focus on specific concerns: security, performance, accessibility, test coverage, or your project's specific conventions.

### Does this work with GitLab or Bitbucket?

The pattern works with any Git platform. Replace the GitHub API calls with GitLab or Bitbucket API equivalents. The MCP server structure remains the same.

### Can RapidDev set up automated AI code review for our team?

Yes. RapidDev offers pre-built code review integrations using MCP that work with GitHub, GitLab, and Bitbucket, including custom review rules and CI/CD pipeline setup.

---

Source: https://www.rapidevelopers.com/mcp-tutorial/how-to-use-mcp-for-code-review-automation
© RapidDev — https://www.rapidevelopers.com/mcp-tutorial/how-to-use-mcp-for-code-review-automation
