Skip to main content
Glama
anggakawa

SonarQube MCP Server

by anggakawa
README.md
# SonarQube MCP Server

A read-only [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that gives AI assistants structured access to SonarQube — issues, metrics, rules, and projects.

## Features

- **6 read-only tools** covering the full SonarQube quality workflow
- **Safe by design** — no mutations, every tool returns a consistent `{"ok": ...}` envelope
- **Input validation** before any API call (severities, types, statuses)
- **Structured errors** with machine-readable `error_code` fields
- Works with SonarQube Community, Developer, and Enterprise editions

---

## Requirements

- Python 3.10+
- A running SonarQube instance
- A SonarQube user token (`squ_...`)

---

## Installation

```bash
pip install sonarqube-mcp-server
```

Or install from source:

```bash
git clone <repo>
cd sonarqube-mcp
pip install -e .
```

---

## Quick Start

```bash
SONARQUBE_URL=http://localhost:9000 \
SONARQUBE_TOKEN=squ_xxxxxxxxxxxx \
sonarqube-mcp-server
```

Or with `python -m`:

```bash
python -m sonarqube_mcp
```

---

## Configuration

### Environment Variables

| Variable | Required | Default | Description |
|---|---|---|---|
| `SONARQUBE_URL` | No | `http://localhost:9000` | Base URL of your SonarQube instance |
| `SONARQUBE_TOKEN` | Yes | — | User token for authentication |
| `SONARQUBE_REQUEST_TIMEOUT_SEC` | No | `30` | HTTP request timeout in seconds |

Copy `.env.example` to `.env` and fill in your values:

```bash
cp .env.example .env
```

### Generating a Token

In SonarQube: **My Account → Security → Generate Tokens**. A user token (`squ_...`) with Browse permission on the target projects is sufficient for all read-only operations.

---

## MCP Client Integration

### Claude Code

Add to your Claude Code MCP settings (`~/.claude/claude_code_config.json`):

```json
{
  "mcpServers": {
    "sonarqube": {
      "command": "sonarqube-mcp-server",
      "env": {
        "SONARQUBE_URL": "http://localhost:9000",
        "SONARQUBE_TOKEN": "squ_xxxxxxxxxxxx"
      }
    }
  }
}
```

### Claude Desktop

Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):

```json
{
  "mcpServers": {
    "sonarqube": {
      "command": "sonarqube-mcp-server",
      "env": {
        "SONARQUBE_URL": "http://localhost:9000",
        "SONARQUBE_TOKEN": "squ_xxxxxxxxxxxx"
      }
    }
  }
}
```

---

## Tools

All tools are **read-only** (`readOnlyHint: true`, `destructiveHint: false`).

### `check_status`

Verify connectivity and retrieve server version.

```json
{}
```

**Response:**
```json
{
  "ok": true,
  "server_url": "http://localhost:9000",
  "status": "UP",
  "version": "10.4.1"
}
```

---

### `list_projects`

List or search SonarQube projects with pagination.

| Parameter | Type | Default | Description |
|---|---|---|---|
| `query` | `string` | — | Filter by project name or key |
| `page` | `integer` | `1` | Page number (1-indexed) |
| `page_size` | `integer` | `20` | Results per page (1–500) |

**Response:**
```json
{
  "ok": true,
  "total": 42,
  "page": 1,
  "page_size": 20,
  "projects": [
    {"key": "my-app", "name": "My Application", "qualifier": "TRK"}
  ]
}
```

---

### `search_issues`

Search issues across all projects or scoped to one project, with rich filtering.

| Parameter | Type | Default | Description |
|---|---|---|---|
| `project_key` | `string` | — | Scope to a specific project |
| `severities` | `string` | — | CSV: `INFO`, `MINOR`, `MAJOR`, `CRITICAL`, `BLOCKER` |
| `types` | `string` | — | CSV: `CODE_SMELL`, `BUG`, `VULNERABILITY`, `SECURITY_HOTSPOT` |
| `statuses` | `string` | — | CSV: `OPEN`, `CONFIRMED`, `REOPENED`, `RESOLVED`, `CLOSED` |
| `tags` | `string` | — | CSV of tag names |
| `assigned` | `boolean` | — | `true` = assigned only, `false` = unassigned only |
| `page` | `integer` | `1` | Page number |
| `page_size` | `integer` | `20` | Results per page (1–500) |

**Example — find all open blockers in a project:**
```json
{
  "project_key": "my-app",
  "severities": "BLOCKER,CRITICAL",
  "statuses": "OPEN"
}
```

---

### `get_issue`

Get full detail for a single issue by key, including text range, effort, assignee, comments, and data-flow information.

| Parameter | Type | Description |
|---|---|---|
| `issue_key` | `string` | Issue key (e.g. `AXy1k2m3n4o5p6q7r8`) |

---

### `get_project_metrics`

Retrieve the quality dashboard for a project. Returns a standard set of metrics by default, or a custom selection.

| Parameter | Type | Default | Description |
|---|---|---|---|
| `project_key` | `string` | — | **Required.** Project key |
| `metric_keys` | `string` | *See below* | CSV of metric keys |

**Default metrics:** `bugs`, `vulnerabilities`, `code_smells`, `security_hotspots`, `coverage`, `duplicated_lines_density`, `ncloc`, `sqale_index`, `reliability_rating`, `security_rating`, `sqale_rating`, `alert_status`, `quality_gate_details`

**Response:**
```json
{
  "ok": true,
  "project_key": "my-app",
  "project_name": "My Application",
  "metrics": {
    "bugs": "3",
    "coverage": "78.4",
    "alert_status": "OK"
  }
}
```

---

### `get_rule`

Retrieve the description and metadata for a SonarQube rule.

| Parameter | Type | Description |
|---|---|---|
| `rule_key` | `string` | Rule key (e.g. `python:S1192`, `java:S106`) |

---

## Error Handling

All tools return a consistent envelope. On failure:

```json
{
  "ok": false,
  "error_code": "auth_error",
  "message": "Authentication failed. Check SONARQUBE_TOKEN.",
  "details": {}
}
```

| `error_code` | Cause |
|---|---|
| `auth_error` | Invalid or missing token (HTTP 401) |
| `forbidden` | Token lacks permissions (HTTP 403) |
| `not_found` | Project, issue, or rule does not exist (HTTP 404) |
| `connection_error` | Cannot reach the SonarQube instance |
| `timeout` | Request exceeded `SONARQUBE_REQUEST_TIMEOUT_SEC` |
| `invalid_input` | Bad parameter value (e.g. unknown severity) |
| `api_error` | Other non-2xx SonarQube response |
| `internal_error` | Unexpected server-side error |

---

## Development

### Setup

```bash
pip install -e ".[dev]"
```

### Running Tests

```bash
pytest
```

### Project Layout

```
src/sonarqube_mcp/
├── server.py             # FastMCP server, tool definitions, main()
├── sonarqube_client.py   # httpx.Client wrapper for SonarQube REST API
├── settings.py           # Frozen dataclass + env var loading
├── errors.py             # SonarQubeError + error_response()
├── __main__.py           # python -m sonarqube_mcp entrypoint
└── __init__.py

tests/
├── conftest.py
├── test_server.py
├── test_client.py
├── test_settings.py
└── test_errors.py
```

### Architecture Notes

- `create_server()` is a factory that captures `settings` and `client` in closure scope — makes unit testing straightforward by injecting a pre-built `SonarQubeSettings`.
- `@_safe_tool` wraps every tool so it never raises — exceptions are caught and returned as structured error envelopes.
- `_clamp()` keeps `page_size` within SonarQube's supported API limits (1–500).
- Settings use a `frozen=True` dataclass — immutable after load, safe to share across tool closures.

---

## License

MIT

TDQS

A3.8/5.0

Scored across 6 tools

Disambiguation5/5

Each tool has a clearly distinct purpose with no overlap: connectivity check, single issue retrieval, project metrics, rule details, project listing, and issue searching. The descriptions specify different resources (server, issue, project, rule) and actions (check, get, list, search), making misselection unlikely.

Naming Consistency5/5

All tools follow a consistent verb_noun pattern (e.g., check_status, get_issue, list_projects, search_issues). The verbs are appropriate and predictable, with no deviations in style or convention across the set.

Tool Count5/5

Six tools is well-scoped for a SonarQube server, covering core functionalities like status verification, issue and project management, metrics, and rule lookup. Each tool earns its place without feeling excessive or insufficient for the domain.

Completeness4/5

The toolset provides strong coverage for querying and monitoring in SonarQube, including status, projects, issues, metrics, and rules. A minor gap exists in write operations (e.g., creating or resolving issues), but agents can still perform most read-oriented tasks effectively.

Maintenance

ActivityInactive
ResponsivenessNo issues