Command Palette

Search for a command to run...

UnylyUnyly
Весь каталог

GIT CODE REVIEW

БесплатноНе проверен

MCP Server for Multi-Project GitLab Merge Request Review 支持对GITLAB多个项目进行MR Review的MCP

GitHubEmbed

Описание

MCP Server for Multi-Project GitLab Merge Request Review 支持对GITLAB多个项目进行MR Review的MCP

README

中文文档 (Chinese)

An MCP (Model Context Protocol) server written in .NET 10 that exposes your company's internal GitLab merge requests as read-only tools for LLM agents. The server itself has no LLM of its own — it just fetches MR data. The reviewing is done by the agent hosting this MCP server. It works as both:

  • stdio transport — a CLI MCP server for desktop clients / Claude Code
  • HTTP (Streamable HTTP) transport — an ASP.NET Core web server exposing /mcp
┌──────────────────────── Rover ──────────────────────────┐
│  Claude / MCP client (agent)                             │
│  ┌──────────────────────────────────────────────────┐   │
│  │  calls list_mrs → get_mr_files → get_mr_file_diff │  ─┐
│  │  reads the diffs and reviews them itself           │  │
│  └──────────────────────────────────────────────────┘   │ │
└─────────────────────────────────────────────────────────┘ │
        │ stdout/JSON-RPC (stdio)  or  HTTP POST /mcp       │
        ▼                                                     ▼
┌───────────────────────────┐                    ┌───────────────────────────┐
│   GitMrReviewer.Stdio     │                    │   GitMrReviewer.Http      │
│   (Exe, Stdio transport)  │                    │   (ASP.NET Core, /mcp)    │
└───────────────────────────┘                    └───────────────────────────┘
        └───────────────┬──────────────────────────────┘
                        ▼
        ┌───────────────────────────────────────────┐
        │             GitMrReviewer.Core            │  ← shared MCP wiring
        │  MrReviewerTools ([McpServerTool]s)       │
        └───────────────────────────────────────────┘
                        ▼
        ┌───────────────────────────────────────────┐
        │        GitMrReviewer.Infrastructure        │
        │  GitLab.DataSource  ·  Configuration       │
        │  SchemaValidator                          │
        └───────────────────────────────────────────┘
                        ▼
        ┌───────────────────────────────────────────┐
        │       GitMrReviewer.Abstractions           │  ← contracts only
        └───────────────────────────────────────────┘

Table of Contents

  1. Features
  2. Project layout
  3. Prerequisites
  4. Configuration
  5. Build & Run — stdio
  6. Build & Run — HTTP
  7. MCP tools
  8. Client configuration
  9. Design notes
  10. Extending
  11. License

Features

  • Data-only MCP server, no LLM. The server exposes GitLab MR data as simple read tools. It never calls an LLM — the MCP client is assumed to have reasoning capabilities and does the reviewing.
  • Granular toolslist_mrs to find MRs, get_mr / get_mr_files for metadata, get_mr_file_diff to pull a single file's diff on demand, and get_mr_discussions for existing threads. Large MRs stay cheap because only the data you ask for is transferred.
  • Both transports in one solution — share 100% of the domain code; each transport is a thin host.
  • Fully async + concurrent — MR metadata, files, and discussions are fetched in parallel; all I/O is async.
  • Schema-guarded GitLab client — every API field is validated against the expected contract with clear error messages on drift.
  • Extensible toward write/delete — the domain layer already models a repository interface; adding mute/unmute or comment-posting tools is additive.
  • .NET 10, nullable enabled, Directory.Build.props-shared compiler settings.

Project layout

git_mcp/
├─ Directory.Build.props                       # shared LangVersion/nullable/doc settings
├─ GitMrReviewer.slnx                          # .NET 10 solution
├─ src/
│  ├─ GitMrReviewer.Abstractions/              # pure contracts (no MCP/GitLab/LLM deps)
│  │  ├─ Settings/                             # GitLabSettings (Options-bound)
│  │  ├─ Models/                               # MrModels (MR, diff, discussion DTOs)
│  │  └─ Services/                             # IMergeRequestDataSource
│  ├─ GitMrReviewer.Infrastructure/           # GitLab REST client + schema guard
│  │  ├─ Configuration/ConfigurationFactory.cs
│  │  ├─ DI/ServiceCollectionExtensions.cs     # AddMrReviewerCore() — shared composition root
│  │  └─ GitLab/                              # GitLabDataSource, SchemaValidator, JSON DTOs
│  ├─ GitMrReviewer.Core/                     # transport-agnostic MCP hosting
│  │  └─ McpTools/MrReviewerTools.cs          # [McpServerTool] list_mrs / get_* tools
│  ├─ GitMrReviewer.StdioServer/              # Exe — stdio transport host (no ASP.NET)
│  └─ GitMrReviewer.HttpServer/               # Web — Streamable HTTP transport host
└─ tests/
   └─ GitMrReviewer.Tests/                    # xunit.v3 unit tests (parser, schema validator)

Prerequisites

  • .NET SDK 10.0.x (incl. the dotnet CLI on PATH)
  • A GitLab service-account / PAT with read_api (or api) scope over the projects you will review
  • An LLM-capable MCP client (e.g. Claude Code) — this server provides the raw MR data for the agent to reason over

Configuration

All settings live in appsettings.json and can be overridden by environment variables. The same file is used by both hosts.

{
  "GitLab": {
    "BaseUrl": "https://git.xxx.com",
    "Token": "glpat-...",                     // default PAT (used when no Tokens entry matches)
    "RequestTimeout": "00:01:00",
    "MaxConcurrency": 8,
    "Tokens": [                                // optional per-project tokens
      {
        "Name": "your-group/your-project",      // matched against the project path/id from the MR URL
        "Token": "glpat-..."                    // PAT for that specific project
      },
      {
        "Name": "1234",                         // can also use the numeric project id
        "Token": "glpat-..."
      }
    ]
  }
}
Environment variable Meaning
GitLab__BaseUrl GitLab instance base URL
GitLab__Token Default GitLab personal access token (PRIVATE-TOKEN header)
GITLAB_TOKEN Convenience alias for GitLab__Token (used by the ConfigurationFactory override)

How multiple tokens work. Each Tokens[] entry pairs a Name (the project path like bonus/bonus-engine or the numeric project id like 1811) with a Token. When you call an MR tool, you may pass the full merge-request URL in the optional url parameter; the server extracts the project path/id from that URL and picks the matching token automatically. If no entry matches, the default GitLab__Token is used. This lets the same MCP server review MRs across many projects, each authenticated with its own service-account token. Keep the Names in the sample config unique and non-colliding (e.g. your-group/your-project instead of a real path) so a placeholder never shadows a real env-provided token.

Never commit real tokens. Keep placeholders in appsettings.json and provide env vars at deploy time.

Build & Run — stdio

# restore + build the full solution
dotnet build GitMrReviewer.slnx

# publish (single-file win-x64, optional)
dotnet publish src/GitMrReviewer.StdioServer -c Release -r win-x64 -o out/stdio

# run directly (in-process transport; used by MCP clients)
src/GitMrReviewer.StdioServer/bin/Debug/net10.0/win-x64/MrReviewer.Stdio.exe

Quick protocol smoke test (sends initialize + tools/list):

printf '%s\n' \
  '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"probe","version":"1.0"}}}' \
  '{"jsonrpc":"2.0","method":"notifications/initialized","params":{}}' \
  '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}' \
| src/GitMrReviewer.StdioServer/bin/Debug/net10.0/win-x64/MrReviewer.Stdio.exe

You should see two JSON-RPC responses — the initialize result and a tools/list result containing the search_projects, list_mrs, get_mr, get_mr_files, get_mr_file_diff, and get_mr_discussions tools.

Build & Run — HTTP

dotnet build src/GitMrReviewer.HttpServer

# run (defaults to http://localhost:port, set ASPNETCORE_URLS to pin it)
ASPNETCORE_URLS=http://127.0.0.1:5279 \
  src/GitMrReviewer.HttpServer/bin/Debug/net10.0/MrReviewer.Http.exe

The MCP endpoint is POST /mcp (Streamable HTTP, JSON + SSE responses).

# initialize (accepts streaming responses)
curl -s -X POST http://127.0.0.1:5279/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"probe","version":"1.0"}}}'

# list tools
curl -s -X POST http://127.0.0.1:5279/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}'

MCP tools

All tools are read-only. There is no LLM involved: the tools just fetch GitLab data and return it as JSON; the calling agent does the analysis.

search_projects

Search the GitLab projects the token can access by name/path. Use this when a project path is unknown or a target returns 404.

Parameter Type Notes
search string Substring to match against project name or path (e.g. lottery)

Returns a JSON array of matching projects (id, name, path_with_namespace, web_url). The numeric id (or the returned path_with_namespace) can then be used as projectIdOrPath in the other tools.

list_mrs

List the merge requests in a project (newest first), to discover which MR to inspect.

Parameter Type Notes
projectIdOrPath string GitLab project id (number) or path (e.g. bonus/bonus-engine). Ignored when url is given.
url (optional) string Full GitLab project or MR URL. Resolves the project and its per-project token.

Returns a JSON array of lightweight MR items (iid, title, state, source_branch, target_branch, web_url, author).

get_mr

Get the metadata of one merge request.

Parameter Type Notes
projectIdOrPath string GitLab project id (number) or path. Ignored when url is given.
mrIid integer MR internal iid shown in the URL (e.g. 1485)
url (optional) string Full MR URL (e.g. https://git.everymatrix.com/bonus/bonus-engine/-/merge_requests/1419). Resolves the project and its per-project token automatically.

Returns the MR title, description, state, branches, URL, and author.

get_mr_files

List the files a merge request changed, with per-file add/delete counts (no patch text).

Parameter Type Notes
projectIdOrPath string GitLab project id (number) or path. Ignored when url is given.
mrIid integer Merge request internal iid (e.g. 1485)
url (optional) string Full MR URL. Resolves the project and its per-project token automatically.

Returns a JSON array of { old_path, new_path, new_file, renamed_file, deleted_file, additions, deletions }.

get_mr_file_diff

Get the unified diff (patch) of a single file in a merge request. Useful for an agent to pull exactly the code it needs to review, instead of receiving a huge combined diff.

Parameter Type Notes
projectIdOrPath string GitLab project id (number) or path. Ignored when url is given.
mrIid integer Merge request internal iid (e.g. 1485)
filePath string Path of the changed file, as returned by get_mr_files (e.g. src/Example.cs)
url (optional) string Full MR URL. Resolves the project and its per-project token automatically.

Returns a JSON object with the file paths, change stats, and the unified diff text (patch).

get_mr_discussions

Get the discussion threads (comments) on a merge request.

Parameter Type Notes
projectIdOrPath string GitLab project id (number) or path. Ignored when url is given.
mrIid integer Merge request internal iid (e.g. 1485)
url (optional) string Full MR URL. Resolves the project and its per-project token automatically.

Returns a JSON array of discussion threads; each thread contains its notes (body, author, system).

Example flow for an agent reviewing MR 1419 in bonus/bonus-engine. When you have the MR URL, pass it as url — the server resolves the project and picks the right token, so different projects can each use their own token:

# URL-driven (token auto-selected from the URL project path)
get_mr("", url="https://git.everymatrix.com/bonus/bonus-engine/-/merge_requests/1419")
get_mr_files("", url=".../bonus/bonus-engine/-/merge_requests/1419")
get_mr_file_diff("", url=".../merge_requests/1419", filePath="src/Example.cs")
get_mr_discussions("", url=".../merge_requests/1419")

# Or with an explicit project id/path (token matched against that key)
search_projects("bonus-engine")          → confirm project id/path (skip if already known)
list_mrs("bonus/bonus-engine")           → find the MR iid + title
get_mr("bonus/bonus-engine", 1419)       → description, state, branches
get_mr_files("bonus/bonus-engine", 1419)
get_mr_file_diff("bonus/bonus-engine", 1419, "src/Example.cs")
get_mr_discussions("bonus/bonus-engine", 1419)

On failure a tool returns isError: true with a text explanation.

Client configuration

Claude Code (stdio)

{
  "mcpServers": {
    "git-mr-reviewer": {
      "command": "E:\\bs\\code\\others\\git_mcp\\src\\GitMrReviewer.StdioServer\\bin\\Debug\\net10.0\\win-x64\\MrReviewer.Stdio.exe",
      "env": {
        "GitLab__Token": "glpat-..."
      }
    }
  }
}

HTTP client

Point any MCP HTTP client at http://<host>:<port>/mcp.

Design notes

  • No LLM in the server. The MR data layer is the whole server. The agent (Claude Code or any MCP client with reasoning) calls these tools and does the reviewing itself.
  • Tool-per-operation, not one megatool. Instead of a single review_mr that dumps the whole MR into one response, each tool returns one slice of context, so an agent can page through a large MR cheaply (get_mr_files first, get_mr_file_diff per interesting file).
  • Abstractions are transport-free. The MCP layer only talks to IMergeRequestDataSource; the GitLab HTTP client lives under Infrastructure.
  • Shared composition root AddMrReviewerCore(IConfiguration) registers Options, the HTTP client, and the repository — identical for stdio and HTTP hosts.
  • Schema-guarded edge (SchemaValidator) converts GitLab JSON drift into descriptive GitLabSchemaExceptions instead of silent null propagation.
  • Async + bounded concurrency: MR parts are fetched with Task.WhenAll; paging is streaming; every method is async.
  • Tool registration via the SDK. MrReviewerTools is registered with WithTools<MrReviewerTools>() on AddMcpServer; the .NET MCP SDK discovers every [McpServerTool]-attributed method and exposes it as its own tool. Adding a tool is just adding a method.

Extending

  1. New read operation — add a method to IMergeRequestDataSource, implement it in GitLabDataSource, expose it through a new [McpServerTool] method on MrReviewerTools.
  2. Write operations (future) — the repository contract can grow Approvals, Mutes, Note posting without touching the MCP hosts.

License

MIT — see LICENSE.

from github.com/Hopcos/GIT-CODE-REVIEW-MCP

Установка GIT CODE REVIEW

У этого сервера нет опубликованного пакета — он собирается из исходников. Открой репозиторий и следуй инструкции в README.

▸ github.com/Hopcos/GIT-CODE-REVIEW-MCP

FAQ

GIT CODE REVIEW MCP бесплатный?

Да, GIT CODE REVIEW MCP бесплатный — установка в пару кликов через Unyly без оплаты.

Нужен ли API-ключ для GIT CODE REVIEW?

Нет, GIT CODE REVIEW работает без API-ключей и переменных окружения.

GIT CODE REVIEW — hosted или self-hosted?

Self-hosted: сервер запускается локально на твоей машине командой из раздела установки.

Как установить GIT CODE REVIEW в Claude Desktop, Claude Code или Cursor?

Открой GIT CODE REVIEW на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.

Похожие MCP

Compare GIT CODE REVIEW with

Не уверен что выбрать?

Найди свой стек за 60 секунд

Автор?

Embed-бейдж для README

Похожее

Все в категории development