Repository navigation
Description
Part of the October Challenge #997.
Why
SonarQube is one of the most widely used code-quality and code-security tools. Teams run it as SonarQube Server (self-hosted, including the free Community Build) or as SonarQube Cloud (formerly SonarCloud). Its Web API exposes projects, quality gate status, issues, measures and analysis history. With an adapter, a user could ask "did the main branch of payments-api pass its quality gate?", "list the open high-severity security issues in project X" or "how has coverage changed since June?". The catalog has GitHub, GitLab and Sentry but no SonarQube (ls packages/backend/src/adapters/*/ | grep -i sonar finds nothing).
Self-hosted vs Cloud
- Self-hosted AnythingMCP: available in Community and Business. Catalog adapters have no edition gating. SonarQube Cloud and any SonarQube Server reachable on the internet work as they are. A SonarQube Server on a private network or private IP needs its host in
SSRF_ALLOWED_HOSTS, because the outbound guard blocks private address space by default (same wording asintl/directus.json:9). - AnythingMCP Cloud (
DEPLOYMENT_MODE=cloud): available, but only for SonarQube Cloud (sonarcloud.io, orsonarqube.usfor the US region) or a SonarQube Server that is publicly reachable. Private-network servers cannot be reached from Cloud. On Cloud trial plans, installs count toward the trial's connector limit (license-guard.service.ts:75-92). - Who can use it: any role except VIEWER can install it (
adapters.controller.ts:306). The connector and its encrypted token belong to the installer's organization. The token sees only the projects its SonarQube user can browse.
What to build
packages/backend/src/adapters/intl/sonarqube.json, one adapter for both SonarQube Server and SonarQube Cloud. Start with npm run adapter:new -- sonarqube --region intl --auth BEARER_TOKEN.
- API docs: Server: https://docs.sonarsource.com/sonarqube-server/latest/extension-guide/web-api/ (the full reference is in the instance under Help → Web API). Cloud: https://docs.sonarsource.com/sonarqube-cloud/advanced-setup/web-api/ and the live reference https://sonarcloud.io/web_api. Use the v1 Web API (
/api/...): it is the same on both products. Web API v2 is gradually replacing it, but v2 runs on a different host on Cloud (api.sonarcloud.io), so it cannot share one base URL. - Base URL:
"baseUrl": "{{SONARQUBE_URL}}/api", asintl/gitlab.json:46andintl/grafana.json:46do.SONARQUBE_URLishttps://sonarcloud.io(Cloud, EU),https://sonarqube.us(Cloud, US), or the Server address including any context path (for examplehttps://sonar.example.comorhttps://example.com/sonarqube). AddenvVarMetawith an address pattern likeintl/gitlab.json:14-32. - Auth:
BEARER_TOKENwithtoken: "{{SONARQUBE_TOKEN}}"(Authorization: Bearer <token>, documented for both products), asintl/directus.json:15-18does. Server: My account → Security, token type User (project and global analysis tokens are for running scans, not the Web API; https://docs.sonarsource.com/sonarqube-server/latest/user-guide/managing-tokens/). Cloud: My account → Access Tokens (https://docs.sonarsource.com/sonarqube-cloud/managing-your-account/managing-tokens/). - Organization (Cloud only): add
optionalEnvVars: ["SONARQUBE_ORGANIZATION"]and pass it as theorganizationquery param where noted below, the wayintl/ebay-sell.json:199passes a connector variable. Cloud requires it for listing projects. A Server 24.12 Community Build ignored the parameter in our test, both when set and when empty. - Category:
infrastructure(like GitHub and GitLab). probe:sonarqube_list_projects. Do not useapi/authentication/validateas the probe: it returns{"valid":true}for anonymous calls too (seen on sonarcloud.io and on a Server instance), so it proves nothing about the token. - Pagination:
p(1-based) andps(max 500 on most endpoints, 1000 onsearch_history).
| Tool | Endpoint | Expected hints |
|---|---|---|
sonarqube_list_projects |
GET /components/search with fixed qualifiers=TRK, organization=$SONARQUBE_ORGANIZATION (q, p, ps) |
read-only |
sonarqube_get_quality_gate_status |
GET /qualitygates/project_status (projectKey, branch, pullRequest) |
read-only |
sonarqube_get_measures |
GET /measures/component (component, metricKeys required, branch, pullRequest) |
read-only |
sonarqube_get_measures_history |
GET /measures/search_history (component, metrics required, from, to, branch, p, ps) |
read-only |
sonarqube_search_issues |
GET /issues/search (componentKeys, organization, issueStatuses, impactSeverities, impactSoftwareQualities, createdAfter, assigned, branch, pullRequest, p, ps) |
read-only |
sonarqube_list_project_analyses |
GET /project_analyses/search (project required, category, from, to, p, ps) |
read-only |
sonarqube_list_branches |
GET /project_branches/list (project) |
read-only |
All tools are GET, so they are derived as readOnlyHint: true, destructiveHint: false (docs/tool-definition.md:782-806). Server and Cloud differences that the JSON must handle (checked against the api/webservices/list output of sonarcloud.io and of a SonarQube Server 24.12 Community Build):
- Listing projects: use
components/search, notprojects/search. On Server,projects/searchrequires Administer System. On Cloud,components/searchrequiresorganization; on Server it requiresqualifiers=TRK. Each product ignores the other's parameter, so one request with both works on both. - Issues by project: use
componentKeys. Cloud only acceptscomponentKeys; on Server it is the deprecated alias ofcomponentsand still works. Use the impact filters (impactSeverities,impactSoftwareQualities,issueStatuses): Cloud has deprecatedtypes,severitiesandstatuses. - Quality gate: on Cloud,
qualitygates/project_statusis marked deprecated since 16 September 2025, with no v2 replacement yet. It still answers.instructionsshould name the fallback:sonarqube_get_measureswithmetricKeys=alert_status,quality_gate_details. Both metrics exist on both products. - Metrics: suggest
software_quality_reliability_issues,software_quality_security_issuesandsoftware_quality_maintainability_issuesin descriptions andinstructions, notbugs,vulnerabilitiesorcode_smells, which Cloud has deprecated (https://docs.sonarsource.com/sonarqube-cloud/deprecations-and-removals/).coverage,duplicated_lines_density,nclocandalert_statusexist on both.
Where to look
packages/backend/src/adapters/intl/gitlab.json— the closest match: one adapter for a SaaS host and self-managed instances, with{{GITLAB_URL}}/api/v4(:46), addressenvVarMeta(:14-32) andverifyHints.packages/backend/src/adapters/intl/directus.json— Bearer auth (:15-18) and the SSRF / private-network wording ininstructions(:9).packages/backend/src/adapters/intl/ebay-sell.json:199— a connector variable sent as a query param.packages/backend/src/adapters/intl/todoist.live.spec.ts— spec template; gate live calls behindRUN_SONARQUBE_LIVE=1asintl/sentry.live.spec.ts:28does.docs/tool-definition.md:18-28—optionalEnvVars;docs/tool-definition.md:343-356— how$paramand connector variables map into the query string..github/CONTRIBUTING.md:137-155— the "Add an adapter" checklist; 🐣 Good first issue: contribute a new MCP adapter #982 — good-first-issue adapter guide.
Acceptance criteria
-
intl/sonarqube.jsonexists with the 7 read-only tools,requiredEnvVars: ["SONARQUBE_URL","SONARQUBE_TOKEN"],optionalEnvVars: ["SONARQUBE_ORGANIZATION"], and adocsUrl. - No tool uses POST/PUT/PATCH/DELETE (asserted in the spec).
-
validate-adapters.mjs --warnis clean (the validator requiresinstructions≥ 800 chars and each tool description ≥ 60 chars,scripts/validate-adapters.mjs:32-33);catalog.tsis regenerated;adapter-count.mjs --checkpasses. -
intl/sonarqube.live.spec.ts: static checks (base URL is{{SONARQUBE_URL}}/api, Bearer auth, read-only methods,sonarqube_list_projectssendsqualifiers=TRKandorganization,sonarqube_search_issuesusescomponentKeys); withRUN_SONARQUBE_LIVE=1it lists projects and reads the quality gate, measures and issues of the first one. Run it against both a SonarQube Server and SonarQube Cloud, and say in the PR which versions you tested.npx jest src/adapters/intl/sonarqubepasses inpackages/backend. - Logo at
packages/frontend/public/logos/connectors/sonarqube.svg. -
instructionscover the three URL cases, which token type to create,SONARQUBE_ORGANIZATIONfor Cloud, the private-network /SSRF_ALLOWED_HOSTSrule, the quality-gate fallback and the 429 rate limit on Cloud ("wait a few minutes", per the Cloud Web API page). - Docs updated: optional
content/guides/en/sonarqube-to-mcp.mdx.
Out of scope
- Any write: issue transitions, assignments and comments, quality gate and quality profile changes, project creation or deletion, token management.
- Security hotspots (
api/hotspots/*): Cloud marks them deprecated since 16 June 2026, replaced by security issues, whichsonarqube_search_issuesalready covers. - Web API v2, portfolios and applications, administration and system endpoints.
- New-code filters on issues: the parameter is
inNewCodePeriodon Server andsinceLeakPeriodon Cloud. It can come in a follow-up.
Free / test account: SonarQube Cloud is free for public projects, and for private projects up to 50k lines of code (https://www.sonarsource.com/plans-and-pricing/sonarcloud/). Import any public GitHub repo to get data. For Server, run the Community Build locally: docker run -d --name sonarqube -e SONAR_ES_BOOTSTRAP_CHECKS_DISABLE=true -p 9000:9000 sonarqube:latest, log in at http://localhost:9000 as admin/admin, and analyze a small project (https://docs.sonarsource.com/sonarqube-community-build/try-out-sonarqube/).
Size
S (a few hours)
How to claim
Comment "I'd like to work on this" and we'll assign you. Rules in #997.
Activity
aj-codespy commentedon Oct 26, 2026
I'd like to work on this
Plan: add
intl/sonarqube.jsonwith the 7 read-only v1 Web API tools ({{SONARQUBE_URL}}/apibase URL, Bearer auth,qualifiers=TRKplus optionalSONARQUBE_ORGANIZATIONoncomponents/search,componentKeysand impact filters on issues, a quality-gate fallback throughalert_status/quality_gate_details). I'll also add the live spec gated onRUN_SONARQUBE_LIVE=1, the logo and the guide. I'll test against a local SonarQube Community Build (Docker) and SonarQube Cloud, and list the versions in the PR.helpcodeai commentedon Oct 27, 2026
Thanks @aj-codespy, it's yours. The plan looks good. Please keep all tools read-only and note in the PR which SonarQube versions you tested against.
feat(adapters): add read-only SonarQube adapter (#1240) (#1317)