Add HTTP attribution headers with injection protection

Instrument all curl calls with a User-Agent identifying the server and
MCP SDK, plus X-MCP-Tool / X-MCP-Client / X-MCP-Protocol-Version headers
so Gerrit server-side logs can identify MCP traffic and trace it to a
specific tool invocation and client.

Client-supplied values (clientInfo.name, clientInfo.version, protocol
version) flow directly from the MCP initialize handshake into curl -A
and -H arguments. Without validation, a client embedding \r\n in its
name could inject arbitrary headers or trigger HTTP request splitting
against a proxied Gerrit instance. Each value is now passed through
_reject_if_unsafe(), which substitutes "unparseable" for any string
containing C0 control characters (0x00–0x1F) or DEL (0x7F), keeping
malicious clients identifiable in logs rather than silently dropping
their attribution.

- New http_headers.py module owns all header logic: a ContextVar carries
  per-request state (tool name, client name/version, protocol version)
  through the async call chain without touching any tool signatures.
- GerritFastMCP subclasses FastMCP and overrides call_tool to populate
  the ContextVar from ctx.session.client_params before dispatching.
- run_curl() reads the ContextVar and splices in the headers; extensions
  get them automatically via the same run_curl closure.
- url_utilities.is_public_url() gets the static UA (no MCP context).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Change-Id: I771e401ed8a92766086f2a8126e58d1dfcbe0132
6 files changed
tree: d9b3f24480087355e78591fa2f631dff7973f956
  1. .claude-plugin/
  2. .gemini/
  3. docs/
  4. gerrit_mcp_server/
  5. hooks/
  6. skills/
  7. tests/
  8. .gitignore
  9. .mcp.json
  10. AGENTS.md
  11. build-gerrit.sh
  12. gemini-cli-config.template.json
  13. gemini-extension.json
  14. LICENSE
  15. OWNERS
  16. pyproject.toml
  17. README.md
  18. server.sh
  19. uv.lock
README.md

🐍 Gerrit MCP Server

An MCP (Model Context Protocol) server for interacting with the Gerrit code review system. This server allows a language model like Gemini to query changes, retrieve details, and manage reviews by executing curl commands against the Gerrit REST API.

This server can be run as a persistent HTTP server or on-demand via STDIO.

📚 Documentation

For detailed information, please see the documents in the docs/ directory:

🚀 Getting Started

1. Prerequisites

Before you begin, ensure you have the following tools installed and available in your system's PATH.

  • Python 3.12+: Required by the server.
  • uv: Used for dependency management and running the server. Optional — the build script will install it via pip if absent.
  • curl: The standard command-line tool for transferring data with URLs.

2. Build the Environment

Run the build script from the root of the gerrit-mcp-server project directory. This will create a virtual environment in .venv via uv sync and install all dependencies.

./build-gerrit.sh

3. Configure the Server

You will need to create a gerrit_config.json file inside the gerrit_mcp_server directory. Copy the provided sample file gerrit_mcp_server/gerrit_config.sample.json and customize it for your environment. See the Configuration Guide for details on all available options.

cp gerrit_mcp_server/gerrit_config.sample.json gerrit_mcp_server/gerrit_config.json

Alternatively, if your harness supports skills (tested with Claude Code), the /gerrit:setup skill can create or repair this file for you interactively. See Interactive Setup.

4. Run the Server (HTTP Mode)

To run the server as a persistent background process, use the server.sh script:

  • Start the server:
    ./server.sh start
    
  • Check the status:
    ./server.sh status
    
  • Stop the server:
    ./server.sh stop
    

For on-demand STDIO mode, please see the Gemini CLI Setup Guide or, to use this server as a Claude Code plugin, the Claude Code Setup Guide.

Security

This is not an officially supported Google product. This project is not eligible for the Google Open Source Software Vulnerability Rewards Program.