MCP server for SonarQube — projects, metrics, quality gate, issues, worst-metric ranking.
Project description
sonarqube-mcp
MCP server for SonarQube. Lets an LLM agent (Claude Code, Cursor, OpenCode, etc.) discover projects, pull headline metrics, check Quality Gate status, search issues with severity/type filters, and rank projects by the worst value of any metric.
Python, FastMCP, stdio transport.
Works with any SonarQube 9.x / 10.x instance (self-hosted) and with SonarCloud.
Why another SonarQube MCP?
A few community SonarQube MCPs exist, but they tend to stop at single-project reads. This one adds cross-project ranking (sonarqube_worst_metrics) — the operation a lead actually runs during a triage session: "show me the top 10 worst-coverage services in the org". All tools are read-only and safely parameterised (Pydantic input validation, severity / type whitelists).
Design highlights
- Tool annotations — all five tools carry
readOnlyHint: True,destructiveHint: False,idempotentHint: True. Nothing can mutate SonarQube from this server. - Structured output — every tool returns a typed payload (TypedDict) + a markdown summary, so clients with and without structured-content support both get a usable response.
- Structured errors — 401 / 403 / 404 / 400 / 429 / 5xx mapped to actionable hints (e.g. "regenerate token", "check project key with sonarqube_list_projects").
- Pydantic input validation for every argument; severity / type filters are checked against the valid SonarQube enum before the request is sent.
- Cross-project worst-metric ranking — batches
/api/measures/searchcalls under the hood, sorts ascending or descending based on whether higher is worse for the chosen metric.
Features (5 tools)
Discovery
sonarqube_list_projects— paginated project search with optional text filter
Single-project insight
sonarqube_project_metrics— measures for one project (default set covers bugs / coverage / smells / ratings / ncloc / tests / alert_status)sonarqube_quality_gate_status— Quality Gate status + per-condition failures
Issue triage
sonarqube_get_issues— issue search filtered by severity / type / resolution status
Cross-project ranking
sonarqube_worst_metrics— top-N projects sorted by the worst value of a metric (e.g. worst coverage, most bugs)
Installation
Requires Python 3.10+.
# via uvx (recommended — no install, just run)
uvx --from sonarqube-mcp sonarqube-mcp
# or via pipx
pipx install sonarqube-mcp
Configuration
claude mcp add sonarqube -s project \
--env SONARQUBE_URL=https://sonar.example.com \
--env SONARQUBE_TOKEN=squ_your_token \
--env SONARQUBE_SSL_VERIFY=true \
-- uvx --from sonarqube-mcp sonarqube-mcp
Or in .mcp.json:
{
"mcpServers": {
"sonarqube": {
"type": "stdio",
"command": "uvx",
"args": ["--from", "sonarqube-mcp", "sonarqube-mcp"],
"env": {
"SONARQUBE_URL": "https://sonar.example.com",
"SONARQUBE_TOKEN": "${SONARQUBE_TOKEN}",
"SONARQUBE_SSL_VERIFY": "true"
}
}
}
}
Check:
claude mcp list
# sonarqube: uvx --from sonarqube-mcp sonarqube-mcp - ✓ Connected
Environment variables
| Variable | Required | Description |
|---|---|---|
SONARQUBE_URL |
yes | SonarQube URL (no trailing slash) |
SONARQUBE_TOKEN |
yes | Bearer token. Generate in: My Account → Security → Tokens |
SONARQUBE_SSL_VERIFY |
no | true/false. Default: true. |
Note on HTTP proxies. The client intentionally disables env-based proxy discovery (trust_env=False) because self-hosted SonarQube is typically reachable only on an internal network. If you connect to SonarCloud or any SonarQube that lives behind a corporate proxy, you'll currently need to drop the proxy variables at the process level — a SONARQUBE_TRUST_ENV_PROXY knob is planned for a follow-up release.
Example usage
- "List all SonarQube projects matching 'einvy'"
- "What's the Quality Gate status for
einvy:aut_einvy?" - "Show me the top 10 projects with the most bugs"
- "Find all BLOCKER / CRITICAL vulnerabilities in
einvy:aut_einvy" - "What's the coverage on
einvy:qa_assistant?" - "Top 5 worst-coverage projects matching query 'einvy'"
Metric directions (used by sonarqube_worst_metrics)
Higher is worse (sorted descending — more is worse):
bugs, code_smells, vulnerabilities, duplicated_lines_density, reliability_rating, security_rating, security_review_rating, sqale_rating, open_issues
Lower is worse (sorted ascending — less is worse):
coverage, line_coverage, branch_coverage, test_success_density, tests
Ratings in SonarQube are numeric strings "1" (A, best) through "5" (E, worst).
Safety
- All tools are
readOnlyHint: True— nothing can mutate SonarQube. - No
POST/PUT/DELETEis ever called. - Severity / type / qualifier inputs are validated against SonarQube enums before the API call, so the tool fails fast on typos rather than hitting the API.
Development
git clone https://github.com/mshegolev/sonarqube-mcp.git
cd sonarqube-mcp
pip install -e '.[dev]'
pytest
License
MIT © Mikhail Shchegolev
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sonarqube_mcp-0.1.0.tar.gz.
File metadata
- Download URL: sonarqube_mcp-0.1.0.tar.gz
- Upload date:
- Size: 26.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8b09cdcf01ba4ea8d75ea4060f9a0bcef41b50d4bfdd644e23d6c9785aabf0c8
|
|
| MD5 |
58e477a8d679650382537029328111e0
|
|
| BLAKE2b-256 |
76220ce5fb88d9eb0a17a277885ae74ed2f59e75ae1a212e2ec2189d07f347e9
|
Provenance
The following attestation bundles were made for sonarqube_mcp-0.1.0.tar.gz:
Publisher:
publish.yml on mshegolev/sonarqube-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sonarqube_mcp-0.1.0.tar.gz -
Subject digest:
8b09cdcf01ba4ea8d75ea4060f9a0bcef41b50d4bfdd644e23d6c9785aabf0c8 - Sigstore transparency entry: 1336642389
- Sigstore integration time:
-
Permalink:
mshegolev/sonarqube-mcp@4e09c3fddd5b31fe244d86a86bfbeec1fe8a4373 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/mshegolev
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@4e09c3fddd5b31fe244d86a86bfbeec1fe8a4373 -
Trigger Event:
push
-
Statement type:
File details
Details for the file sonarqube_mcp-0.1.0-py3-none-any.whl.
File metadata
- Download URL: sonarqube_mcp-0.1.0-py3-none-any.whl
- Upload date:
- Size: 20.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a143e67bc6e1787c164bd6c6c553ecdd2694ca986df04ee5e8eb5dfda51ee98c
|
|
| MD5 |
cbb60a08488c31dcc12310f775f1707b
|
|
| BLAKE2b-256 |
957409e8070d479d5325cf7e0b4fe5b6c612e830e23b7b18c5e4812d63b4cd74
|
Provenance
The following attestation bundles were made for sonarqube_mcp-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on mshegolev/sonarqube-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sonarqube_mcp-0.1.0-py3-none-any.whl -
Subject digest:
a143e67bc6e1787c164bd6c6c553ecdd2694ca986df04ee5e8eb5dfda51ee98c - Sigstore transparency entry: 1336642518
- Sigstore integration time:
-
Permalink:
mshegolev/sonarqube-mcp@4e09c3fddd5b31fe244d86a86bfbeec1fe8a4373 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/mshegolev
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@4e09c3fddd5b31fe244d86a86bfbeec1fe8a4373 -
Trigger Event:
push
-
Statement type: