
Sonar MCP Server
io.github.igorolv由 GitHub 账号 igorolv 发布v0.1.0更新于 Oct 24, 2026
Read-only SonarQube Community Build access for AI agents: issues, hotspots, rules, code snippets
概览
一个本地只读 MCP 服务器,让 AI 编程助手读取自托管 SonarQube Community Build 中的问题、安全热点、规则和源码片段。
- 可以做什么
- 列出项目、浏览组件,读取项目概览、质量门状态、分支和拉取请求分析。列出、查看并汇总问题,包括按模块和规则的分组统计及变更历史。获取问题位置附近的源码片段,包括跨文件流程。查询规则说明,列出并查看安全热点。
- 适用场景
- 适用于让助手在暴露经典 Web API 的自托管 SonarQube Community Build 26.4+ 实例中查找并修复 Sonar 发现的问题,尤其在本地没有代码仓库或需要查看 Sonar 实际分析的文件版本时。
- 运行要求
- 本地运行 JAR 需要 Java 25+,也可使用已发布的 Docker 镜像;仅支持 stdio 传输。需要可访问的 SonarQube 实例地址(SONAR_URL)和用户令牌(SONAR_TOKEN)。可选默认值:SONAR_DEFAULT_PROJECT_KEY、SONAR_DEFAULT_BRANCH、数据目录和分页设置。
安装
在 SourceWeft 中
- 打开 控制台中的 Sonar MCP Server,将其添加到工作区。
- 为需要使用其工具的对话启用该服务。
Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。
其他 MCP 客户端
参照 仓库 中的启动说明。
README
Sonar MCP Server
[CI] [Release] [License] [Java 25] [MCP] [Glama score] [Listed on mcpservers.org]
A local MCP server providing read-only access to a SonarQube Community Build (26.4+) instance via its web-api. It lets AI agents (Claude Code, Cursor, VS Code Copilot, etc.) fetch a project's issue list, the files and locations where they occur, rule descriptions, source-code snippets around issues, and Security Hotspots.
Typical scenario: "find and fix Sonar issues in such-and-such project" — the LLM calls listIssues, optionally getRule and getIssueSnippets, and edits files locally.
Why this server
There is an official SonarSource MCP server, but it targets SonarQube 10+ (and SonarCloud) and assumes a cloud-style deployment. This server is built for self-hosted SonarQube Community Build 26.4+ installations that expose the classic /api/ web-api. It supports both Standard Experience and MQR mode, handling per-software-quality impacts when the instance runs in MQR mode.
It is also intentionally narrower in scope:
- Read-only by design. The server never creates, updates, or deletes anything in SonarQube — no marking issues as false-positive, no editing comments, no admin endpoints. The token's write permissions in SonarQube are irrelevant because the server never calls those endpoints.
- Curated tool set. Instead of mirroring the SonarQube API surface, the server exposes a small, focused set of tools (13 in total) chosen for a single workflow: let an AI agent read Sonar's findings and fix the code based on them. Listing components, issues and hotspots, drilling into a single finding, fetching the rule explanation, and pulling the source-code snippet around the location — and that's it. Anything outside this "diagnose -> fix the code locally" loop is deliberately left out to keep the tool list small and the agent's choices unambiguous.
In short: a focused, read-only bridge from a self-hosted SonarQube Community Build to an AI coding agent.
Quick start
- Install JDK 25+.
- Download
sonar-mcp-server.jarfrom the latest release, or build it yourself:./gradlew bootJar(see Build). A Docker image is published as well. - Get your SonarQube URL and user token (see Configuration).
- Add the JAR to your client's MCP configuration (see Connecting to an AI client).
For Claude Code that is one command:
Architecture
The server only supports the stdio transport.
The AI client spawns the server as a child process; communication uses the MCP protocol over stdin/stdout. The server does not open any HTTP port and accepts no incoming connections.
Tools
The server exports 13 read-only MCP tools.
Projects
Issues
Rules
Security Hotspots
All tools are read-only — no data in SonarQube is modified.
Working with branches and pull requests
Sonar analyses a branch and a pull request as two distinct, mutually exclusive scopes. The Sonar web-api accepts either branch= or pullRequest= on a single request, never both.
branch— long-lived branches (main, develop, feature/...). Resolved as: explicitbranchargument →SONAR_DEFAULT_BRANCH→ none (Sonar uses the project's main branch).pullRequest— the Sonar PR key, usually the PR/MR number. Independent from branch analyses; PR analyses often contain the most relevant findings for in-flight work. Pull request keys never fall back to a server-level default — pass them explicitly.
Passing both branch and pullRequest to the same tool call is an error. Use listProjectBranches / listProjectPullRequests to discover available refs.
Branch scoping is load-bearing. Each Sonar branch is a separate analysis: open-issue counts on
mainand on a feature branch can differ a lot, because the feature branch may have new fixes (or new code) that have not been merged. If the agent silently omitsbranch=, it reads frommain(orSONAR_DEFAULT_BRANCH) and may miss work already done on a feature branch — or worse, fix the same problem twice. When the user's local git is onfeature/..., agents should calllistProjectBranchesfirst, find the matching Sonar branch, and pass it explicitly to every issue / summary / breakdown call.As a server-side safety net,
listIssues,getProjectIssuesSummary, andgetProjectIssuesBreakdownattach abranchAdvisoryfield to their response when (1) neitherbranchnorpullRequestwas passed AND (2) the project has other branches analysed in Sonar. The advisory carries the effective (main) branch name and the list of non-main branches sorted by most recent analysisDate. The field is absent otherwise.
Stack
- Java 25, Spring Boot 4.0.0, Spring AI MCP 2.0.0 (stdio transport)
- Jackson 3 (
tools.jackson) for JSON - Gradle 9.3.1 with version catalog (
gradle/libs.versions.toml)
Build
On Windows: .\gradlew.bat build.
Output: build/libs/sonar-mcp-server.jar
Configuration
The server needs a SonarQube URL and token; the rest is optional.
Tool groups
The MCP tools/list manifest is split into four groups, each gated by an environment flag. All groups are on by default, so the out-of-the-box manifest is unchanged. Turn a group off to shrink the manifest — useful for small-context (local) models that would otherwise be flooded with tool and output schemas at session start.
Set a flag to false (e.g. SONAR_MCP_TOOLS_HOTSPOT=false) to drop that group's tools from the manifest.
Getting the SonarQube URL
Open SonarQube in a browser and copy the address from the location bar without the path — only scheme and host.
If SonarQube is reachable only by IP, use the IP as is. If it's deployed under a subpath (e.g.
/sonar), include that in the URL as well.
Getting a SonarQube token
- Sign in to SonarQube with your account.
- Open My Account -> Security.
- In Generate Tokens, enter a token name and pick type User Token.
- Click Generate — the token is shown only once. Copy it immediately.
- Use the token value as
SONAR_TOKEN.
If a token is lost, you have to regenerate it — SonarQube doesn't display existing tokens again.
The server uses HTTP Bearer auth, passing the token in the Authorization header — this is the standard SonarQube Community Build scheme for user tokens.
Running
The server runs over stdio. After a successful start it opens no HTTP port and waits for MCP requests over stdin/stdout.
Logs are written to ${SONAR_MCP_DATA_DIR:-~/.sonar-mcp-server}/logs/sonar-mcp-server.log.
The file rotates by date and size: 10MB, retention 30 days, total cap 512MB.
Docker
The image is published to GHCR with every release:
The same command is what an MCP client should launch (-i keeps stdin open for the stdio
transport). Mount a host directory at /data to keep logs between runs. If SonarQube runs on the
same machine, use its host name rather than localhost, or add --network host on Linux.
To build the image locally: docker build -t sonar-mcp-server .
Connecting to an AI client
Where exactly:
For CLI clients there are also commands to view and remove the registration: claude mcp list / claude mcp remove --scope user sonar (similarly for qwen).
After adding, restart the client.
Example AI-agent prompts
Operations and security
This MCP server is meant to run locally next to the AI client. It opens no HTTP port and accepts no incoming network connections: the client starts the JAR as a child process and talks to it over stdin/stdout.
Access model
- The server acts with the rights of the SonarQube user whose token is in
SONAR_TOKEN. - All MCP tools are read-only: the server does not create, modify, or delete issues, hotspots, rules, or projects.
- Available projects and issues are determined by the user's permissions in SonarQube. If the user can't see a project in SonarQube, the server shouldn't be able to access it either.
- Treat the token as a secret. Don't commit it to the repository, shell scripts,
.vscode/mcp.json,.cursor/mcp.json, or any other shared project files.
What data is sent to the AI client
The AI client receives exactly the data it requests through the MCP tools:
- the list of issues with rule, severity, type, file path, line number, message, tags, SCM author;
- issue change history;
- Sonar rule descriptions (including HTML/markdown);
- source-code snippets around issue locations (via
getIssueSnippets); - Security Hotspots and their details.
Before connecting to an external or cloud-based AI client, check your company's internal policies: source code may contain trade secrets.
Diagnostics
Environment check:
SonarQube web-api access check (HTTP Bearer auth with the token):
The expected response is a JSON list of projects. 401 Unauthorized means the token is invalid or expired; 403 means the user lacks permission for the API.
Build check:
Integration tests against a live SonarQube:
Integration tests require a reachable SonarQube and real data. Unit tests exclude the integration tag by default.
Known operational limitations
- HTTP timeouts and retry policy aren't separately configurable yet.
- The Sonar API uses page-based pagination (
p/ps); the tools acceptoffset/limit, and an offset that is not a multiple oflimitis rounded down to the nearest page boundary. Sonar also capspsat 500. componentPathPrefixis a client-side filter: the server pages through the project's issues / hotspots and keeps those whosecomponentPathstarts with the prefix (directory-boundary safe). The scan is capped (SONAR_MCP_PATH_FILTER_MAX_SCANNED_ISSUES, default 10000); when the cap is hit, the response setspathPrefixTruncated=trueand the caller should tighten the prefix.- The
authorfield onIssueis the SCM author of the line where the issue occurred (populated by Sonar when an SCM provider is configured). Sonar doesn't return separatescmAuthor/scmDatefields inissues/search; for line-level SCM usegetIssueSnippets.
Project layout
Troubleshooting
- "Gradle requires JVM 17 or later" — set
JAVA_HOMEto a JDK 25+. - Connection refused / 401 — check URL and token. Test:
curl -H "Authorization: Bearer $SONAR_TOKEN" "$SONAR_URL/api/components/search?qualifiers=TRK&p=1&ps=1". - 403 Forbidden — the token user has no rights on the project or on the web-api. Check the role in SonarQube.
- Package/module scope returns 0 issues — pass the path-style prefix as
componentPathPrefix(e.g.bc-doc/src/main/java/ru/foo), not a Sonar component key. Convert Java/Kotlin package dots to slashes. The filter is directory-boundary safe, sobc-doc/srcwill not matchbc-doc/srcExtra. pathPrefixTruncated=truein the response — the client-side scan hitSONAR_MCP_PATH_FILTER_MAX_SCANNED_ISSUESbefore reaching the end. Tighten the prefix to reduce the scan, or raise the cap if 10k is genuinely not enough for your project.
来源:README.md,提交 29f381f
工具
0版本历史
1- v0.1.0最新Sep 18, 2026
评分
已满足适用检查项的 50%
该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。
- 近 30 天内可连通25 分
请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。
- 已声明认证方式10 分
请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。
- 已列出工具15 分
请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。
- 描述必需15 分
- 图标10 分
- 文档15 分
- 许可证10 分
