{
  "markdown": "# sonarqube-mcp\n\n<!-- mcp-name: io.github.mshegolev/sonarqube-mcp -->\n\n[![PyPI](https://img.shields.io/pypi/v/sonarqube-mcp.svg?logo=pypi&logoColor=white)](https://pypi.org/project/sonarqube-mcp/)\n[![Python](https://img.shields.io/pypi/pyversions/sonarqube-mcp.svg?logo=python&logoColor=white)](https://pypi.org/project/sonarqube-mcp/)\n[![License: MIT](https://img.shields.io/pypi/l/sonarqube-mcp.svg)](LICENSE)\n\nMCP server for [SonarQube](https://www.sonarsource.com/products/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.\n\nPython, [FastMCP](https://github.com/modelcontextprotocol/python-sdk), stdio transport.\n\nWorks with any SonarQube 9.x / 10.x instance (self-hosted) and with SonarCloud.\n\n## Why another SonarQube MCP?\n\nA 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).\n\n## Design highlights\n\n- **Tool annotations** — all five tools carry `readOnlyHint: True`, `destructiveHint: False`, `idempotentHint: True`. Nothing can mutate SonarQube from this server.\n- **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.\n- **Structured errors** — 401 / 403 / 404 / 400 / 429 / 5xx mapped to actionable hints (e.g. \"regenerate token\", \"check project key with sonarqube_list_projects\").\n- **Pydantic input validation** for every argument; severity / type filters are checked against the valid SonarQube enum before the request is sent.\n- **Cross-project worst-metric ranking** — batches `/api/measures/search` calls under the hood, sorts ascending or descending based on whether higher is worse for the chosen metric.\n\n## Features (5 tools)\n\n**Discovery**\n- `sonarqube_list_projects` — paginated project search with optional text filter\n\n**Single-project insight**\n- `sonarqube_project_metrics` — measures for one project (default set covers bugs / coverage / smells / ratings / ncloc / tests / alert_status)\n- `sonarqube_quality_gate_status` — Quality Gate status + per-condition failures\n\n**Issue triage**\n- `sonarqube_get_issues` — issue search filtered by severity / type / resolution status\n\n**Cross-project ranking**\n- `sonarqube_worst_metrics` — top-N projects sorted by the worst value of a metric (e.g. worst coverage, most bugs)\n\n## Installation\n\nRequires Python 3.10+.\n\n```bash\n# via uvx (recommended — no install, just run)\nuvx --from sonarqube-mcp sonarqube-mcp\n\n# or via pipx\npipx install sonarqube-mcp\n```\n\n## Configuration\n\n```bash\nclaude mcp add sonarqube -s project \\\n  --env SONARQUBE_URL=https://sonar.example.com \\\n  --env SONARQUBE_TOKEN=squ_your_token \\\n  --env SONARQUBE_SSL_VERIFY=true \\\n  -- uvx --from sonarqube-mcp sonarqube-mcp\n```\n\nOr in `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"sonarqube\": {\n      \"type\": \"stdio\",\n      \"command\": \"uvx\",\n      \"args\": [\"--from\", \"sonarqube-mcp\", \"sonarqube-mcp\"],\n      \"env\": {\n        \"SONARQUBE_URL\": \"https://sonar.example.com\",\n        \"SONARQUBE_TOKEN\": \"${SONARQUBE_TOKEN}\",\n        \"SONARQUBE_SSL_VERIFY\": \"true\"\n      }\n    }\n  }\n}\n```\n\nCheck:\n\n```bash\nclaude mcp list\n# sonarqube: uvx --from sonarqube-mcp sonarqube-mcp - ✓ Connected\n```\n\n## Environment variables\n\n| Variable | Required | Description |\n|---|---|---|\n| `SONARQUBE_URL` | yes | SonarQube URL (no trailing slash) |\n| `SONARQUBE_TOKEN` | yes | Bearer token. Generate in: My Account → Security → Tokens |\n| `SONARQUBE_SSL_VERIFY` | no | `true`/`false`. Default: `true`. |\n\n**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.\n\n## Example usage\n\n- \"List all SonarQube projects matching 'einvy'\"\n- \"What's the Quality Gate status for `einvy:aut_einvy`?\"\n- \"Show me the top 10 projects with the most bugs\"\n- \"Find all BLOCKER / CRITICAL vulnerabilities in `einvy:aut_einvy`\"\n- \"What's the coverage on `einvy:qa_assistant`?\"\n- \"Top 5 worst-coverage projects matching query 'einvy'\"\n\n## Metric directions (used by `sonarqube_worst_metrics`)\n\n**Higher is worse** (sorted descending — more is worse):\n`bugs`, `code_smells`, `vulnerabilities`, `duplicated_lines_density`, `reliability_rating`, `security_rating`, `security_review_rating`, `sqale_rating`, `open_issues`\n\n**Lower is worse** (sorted ascending — less is worse):\n`coverage`, `line_coverage`, `branch_coverage`, `test_success_density`, `tests`\n\nRatings in SonarQube are numeric strings `\"1\"` (A, best) through `\"5\"` (E, worst).\n\n## Safety\n\n- All tools are `readOnlyHint: True` — nothing can mutate SonarQube.\n- No `POST` / `PUT` / `DELETE` is ever called.\n- 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.\n\n## Performance characteristics\n\n- Every tool makes **one HTTP call** to SonarQube except `sonarqube_worst_metrics`, which makes **one search call + ⌈candidate_pool/100⌉ bulk-measures calls**. Default settings land at ≤ 2 calls.\n- Single-tool response time on a healthy SonarQube instance: typically < 500 ms.\n- Pagination is passed through to SonarQube (`p` + `ps` params) — no full-result buffering in the MCP server.\n- `sonarqube_worst_metrics` caps `candidate_pool` at 500 — on instances with thousands of projects, pre-filter with `query=` before ranking (see the tool docstring).\n- SonarQube has no published hard rate limit. If 429 is received the server surfaces an actionable error (\"Wait 30-60 s before retrying; reduce page_size\").\n\n## Development\n\n```bash\ngit clone https://github.com/mshegolev/sonarqube-mcp.git\ncd sonarqube-mcp\npip install -e '.[dev]'\npytest\n```\n\n## License\n\nMIT © Mikhail Shchegolev\n",
  "bytes": 6423,
  "sha": "1a04f7615e32936777f5513f23a772f6b7264a32e33289390fb4f80713fd2683",
  "repo_slug": "mshegolev/sonarqube-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_mshegolev_sonarqube_mcp_5c589c0c/readme"
}