sonar-mcp-server
Provides read-only access to a SonarQube instance via its web-api, allowing AI agents to list projects and components, fetch issues and security hotspots, retrieve rule details and source-code snippets, and view project summaries, branches, and pull request analyses.
Sonar MCP Server
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.
Related MCP server: SonarQube MCP Server
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:
claude mcp add --scope user -e SONAR_URL=https://sonar.example.com -e SONAR_TOKEN=your_token -- sonar java -jar /path/to/sonar-mcp-server.jarArchitecture
The server only supports the stdio transport.
┌─────────────┐ stdio ┌──────────────────┐ web-api ┌──────────┐
│ AI agent │ <------------> │ sonar-mcp- │ -------------> │ SonarQube│
│ (Claude Code│ stdin/stdout │ server (Java) │ HTTP + Bearer │ CB 26.4+│
│ Cursor...) │ │ │ auth (token) │ │
└─────────────┘ └──────────────────┘ └──────────┘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
Tool | Description |
| List of SonarQube projects. Parameters: |
| Search/browse components inside a project using Sonar's component tree. Parameters: |
| Project overview: header info (name, qualifier, visibility, description, version, last analysis date), quality gate status with failed conditions, and curated metrics (ncloc, bugs, vulnerabilities, security hotspots, code smells, coverage, duplicated lines density, technical debt in minutes, alert status). Parameters: |
| List of branches analysed for the project. Each entry: |
| List of PR analyses for the project. Each entry: PR |
Issues
Tool | Description |
| Flat list of issues for a project. Parameters: |
| Details of a single issue by key plus its change history ( |
| Source-code snippets around all issue locations (primary plus flows for cross-file rules). For each location: |
| Aggregated summary of open issues in a project: total plus breakdowns by severity, type, status, rule, tag, and SCM author. Parameters mirror |
| Multi-module aggregation of issues by logical module and rule. Module is derived from the first |
Rules
Tool | Description |
| Details of a Sonar rule by key (e.g. |
Security Hotspots
Tool | Description |
| List of Security Hotspots for a project. Hotspots are a separate category from issues, marking spots that require manual security review. By default Sonar returns hotspots in status |
| Security Hotspot details: full rule description (risk, vulnerability, fix recommendations), primary textRange, secondary flows, changelog. Hotspot keys are globally unique, so no |
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 JSONGradle 9.3.1 with version catalog (
gradle/libs.versions.toml)
Build
# Point to a JDK 25+ if it's not the default:
export JAVA_HOME="$HOME/.jdks/jdk-25.0.2"
./gradlew buildOn Windows: .\gradlew.bat build.
Output: build/libs/sonar-mcp-server.jar
Configuration
The server needs a SonarQube URL and token; the rest is optional.
Variable | Description |
| SonarQube base URL (e.g. |
| SonarQube user token |
| Default SonarQube project key. When set, |
| Default Sonar branch. When set, all branch-aware tools ( |
| Local data directory for the server; defaults to |
| Default page limit for list tools; defaults to |
| Default offset for list tools; defaults to |
| Max page limit (Sonar API itself caps at 500); defaults to |
| Reserved for future per-snippet line cap; currently unused (Sonar picks the window itself). Defaults to |
| Hard cap on issues/hotspots scanned client-side when |
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.
Variable | Tools in the group |
|
|
|
|
|
|
|
|
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.
In the browser address bar | URL value |
|
|
|
|
|
|
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
SONAR_URL=http://sonar.example.com SONAR_TOKEN=your_token \
java -jar build/libs/sonar-mcp-server.jarThe 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:
docker run -i --rm -e SONAR_URL=https://sonar.example.com -e SONAR_TOKEN=your_token ghcr.io/igorolv/sonar-mcp-server:latestThe 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
{
"command": "java",
"args": ["-jar", "<absolute-path>/sonar-mcp-server.jar"],
"env": {
"SONAR_URL": "http://sonar.example.com",
"SONAR_TOKEN": "your_token"
}
}Where exactly:
Client | How to connect |
Claude Code |
|
Qwen Code |
|
VS Code |
|
Cursor |
|
Claude Desktop |
|
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
Find and fix Sonar issues in project my-project
Show the top 10 rules by number of open issues in project my-project
Show Sonar issues under src/main/java/com/example/fooOperations 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:
java -version
echo "$SONAR_URL"
test -n "$SONAR_TOKEN" && echo "SONAR_TOKEN is set"SonarQube web-api access check (HTTP Bearer auth with the token):
curl -H "Authorization: Bearer $SONAR_TOKEN" "$SONAR_URL/api/components/search?qualifiers=TRK&p=1&ps=1"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:
./gradlew test
./gradlew buildIntegration tests against a live SonarQube:
SONAR_URL=<url> SONAR_TOKEN=<token> ./gradlew integrationTestIntegration 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
├── src/main/java/ru/it_spectrum/ai/sonar/mcp/
│ ├── SonarMcpServerApplication.java — Spring Boot entry point
│ ├── api/ — stable MCP wire format: records returned by tools/services
│ │ ├── Issue.java, IssuePage.java, IssueDetails.java, IssueLocation.java, IssueFlow.java, IssueImpact.java, IssueSnippets.java
│ │ ├── Project.java, ProjectPage.java, ProjectOverview.java, ProjectMetrics.java, ProjectComponent.java, ProjectComponentPage.java
│ │ ├── RuleDetails.java, RuleSection.java
│ │ ├── Hotspot.java, HotspotDetails.java, HotspotPage.java, HotspotRule.java
│ │ ├── SourceSnippet.java, SnippetLine.java
│ │ ├── ChangelogEntry.java, ChangelogDiff.java
│ │ ├── TextRange.java, FacetCount.java, BranchAdvisory.java
│ │ ├── ProjectIssuesSummary.java, ProjectIssuesBreakdown.java, ModuleIssuesSummary.java
│ │ ├── ProjectBranch.java, ProjectBranches.java, ProjectPullRequest.java, ProjectPullRequests.java
│ │ ├── QualityGateStatus.java, QualityGateCondition.java
│ │ └── Opaque.java
│ ├── client/
│ │ ├── SonarClient.java — SonarQube web-api wrapper
│ │ └── model/ — raw DTOs of the SonarQube web-api, not exposed directly via MCP
│ │ └── Sonar*.java
│ ├── config/
│ │ ├── SonarClientProperties.java — url + token from env
│ │ ├── SonarMcpProperties.java — all sonar-mcp.* runtime settings
│ │ ├── SonarConfig.java — RestClient with Bearer auth
│ │ ├── McpServerConfig.java — stdio MCP customizer with immediateExecution(true)
│ │ └── JsonConfig.java — ObjectMapper for MCP JSON
│ ├── service/
│ │ ├── ProjectService.java
│ │ ├── IssueService.java
│ │ ├── RuleService.java — with in-memory rule cache
│ │ ├── SnippetService.java
│ │ ├── HotspotService.java
│ │ ├── PaginationHelper.java — offset/limit -> p/ps
│ │ └── SonarMappers.java — client.model -> api mapping
│ └── tools/
│ ├── ProjectTools.java — 5 MCP tools
│ ├── IssueTools.java — 5 MCP tools
│ ├── RuleTools.java — 1 MCP tool
│ ├── HotspotTools.java — 2 MCP tools
│ ├── ToolDescriptions.java — shared @McpTool / @McpToolParam description constants
│ ├── SonarPrompts.java — MCP prompts (analyzePath, fixPath, fixFile, investigateIssue, reviewPullRequest)
│ ├── RefResolver.java — branch/pullRequest resolution with default-branch fallback
│ └── ToolLogger.java
└── src/main/resources/
├── application.yml — MCP server configuration (stdio)
└── logback-spring.xml — logging configurationTroubleshooting
"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.
Available Tools
13 toolsgetHotspotgetHotspotARead-onlyIdempotent
Get one Security Hotspot. Returns review details, rule guidance, locations, flows, and changelog.
| Name | Required | Description | Default |
|---|---|---|---|
| hotspotKey | Yes | Hotspot key |
Output Schema
| Name | Required | Description |
|---|---|---|
| rule | No | |
| flows | No | Data-flow paths showing how user input reaches the risky code. |
| hotspot | No | |
| changelog | No | Full change history of the hotspot (reviews, reassignments, etc.). |
| textRange | No | Precise text range in the source file; null when the hotspot spans the whole file. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and non-destructive behavior, so the safety profile is covered. The description adds value by specifying what the response includes, giving the agent expectations about the payload without contradicting the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence that leads with the core action ('Get one Security Hotspot') and then lists the return contents efficiently. No filler or redundant phrasing.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter read tool with an output schema present, the description covers the essential information: what it returns and that it is a single item. It does not mention usage vs. siblings, but that is already accounted for in usage guidance. The low complexity means this is sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The only parameter, hotspotKey, is fully described in the schema ('Hotspot key') with 100% coverage. The description adds no additional meaning beyond the schema, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Get one Security Hotspot' – a specific verb plus resource that clearly distinguishes this from listHotspots (which returns many). It further differentiates by enumerating the returned content: review details, rule guidance, locations, flows, and changelog.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The usage is implied: given a hotspotKey, this tool fetches a single hotspot. However, the description does not explicitly state when to choose this over listHotspots or getIssue, and it names no alternatives. For a simple get-by-key tool, this is adequate but not explicitly guided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getIssuegetIssueARead-onlyIdempotent
Get one issue by key. Returns full issue details and changelog, including status and assignment history. Scope explicitly: omitting both branch and pullRequest uses the configured default (usually main). For non-main or PR work, pass the matching ref explicitly; discover it with listProjectBranches / listProjectPullRequests.
| Name | Required | Description | Default |
|---|---|---|---|
| branch | No | Branch name; mutually exclusive with `pullRequest`. Omission uses the configured default (usually main). For non-main lookup, pass explicitly; use `listProjectBranches` to discover names. | |
| issueKey | Yes | Issue key | |
| pullRequest | No | PR key; mutually exclusive with `branch`; no default. For PR work, pass explicitly; use `listProjectPullRequests`. |
Output Schema
| Name | Required | Description |
|---|---|---|
| issue | No | |
| changelog | No | Full change history of the issue (transitions, assignments, severity changes, etc.). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false. The description adds critical context beyond that: the default branch behavior, the requirement to pass a ref for non-main work, and the mutual exclusion rule. No contradiction; it enriches the behavioral profile.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with zero wasted words. The primary purpose is front-loaded, and the scoping caveat and discovery hints are packed efficiently into the second sentence.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema exists, return format need not be repeated. The description covers purpose, scope, parameter interactions, and discovery methods. For a read-only retrieval tool, this is complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents each parameter. The description adds meaningful semantics by explaining the default branch, the mutual exclusivity, and how to discover valid values—this goes beyond the schema's basic descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states a specific verb ('Get') and resource ('one issue by key'), and describes the return content ('full issue details and changelog'). It distinguishes from sibling listIssues and getIssueSnippets by specifying single-issue retrieval and history inclusion.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly explains when to use the default vs. pass refs, names the alternatives (listProjectBranches / listProjectPullRequests) for discovery, and notes the mutual exclusivity of branch and pullRequest. This is strong when-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getIssueSnippetsgetIssueSnippetsARead-onlyIdempotent
Get Sonar-analysed source snippets for all issue locations, including cross-file flows. Returns component path, language, code lines, and SCM metadata. Use when local source is unavailable or may differ from the analysed ref. Scope explicitly: omitting both branch and pullRequest uses the configured default (usually main). For non-main or PR work, pass the matching ref explicitly; discover it with listProjectBranches / listProjectPullRequests.
| Name | Required | Description | Default |
|---|---|---|---|
| branch | No | Branch name; mutually exclusive with `pullRequest`. Omission uses the configured default (usually main). For non-main lookup, pass explicitly; use `listProjectBranches` to discover names. | |
| issueKey | Yes | Issue key | |
| pullRequest | No | PR key; mutually exclusive with `branch`; no default. For PR work, pass explicitly; use `listProjectPullRequests`. |
Output Schema
| Name | Required | Description |
|---|---|---|
| issueKey | No | Key of the issue these snippets belong to. |
| snippets | No | One or more source code snippets showing the issue location and surrounding lines. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false. The description adds useful behavioral context beyond that: snippets are Sonar-analysed rather than local, cross-file flows are included, and the result exposes component path, language, code lines, and SCM metadata. The default-branch behavior is also disclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences with no filler: purpose, use case, and scoping guidance. Each sentence justifies its presence, and the front-loaded return value description lets an agent quickly recognize the tool's role.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only tool with a full output schema and a required single parameter, the description covers purpose, return contents, when to use, and how to handle branch/PR scoping. Nothing essential is missing for an agent to select and invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description reinforces the branch/pullRequest mutual exclusivity and default-branch behavior, but those semantics are already documented in the schema. The required issueKey is simple and needs no elaboration.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description names a specific verb and resource: 'Get Sonar-analysed source snippets for all issue locations, including cross-file flows.' It distinguishes itself from siblings like getIssue/listIssues by focusing on source snippets across all locations, not issue metadata or summaries.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use it: 'Use when local source is unavailable or may differ from the analysed ref.' It also gives scoping guidance for branches and PRs and points to listProjectBranches/listProjectPullRequests for discovery. It does not explicitly name which sibling to use instead for ordinary local-source cases, but the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getProjectgetProjectARead-onlyIdempotent
Get one project analysis. Returns project metadata, quality gate failures, and metrics for size, findings, coverage, duplication, and technical debt. Scope explicitly: omitting both branch and pullRequest uses the configured default (usually main). For non-main or PR work, pass the matching ref explicitly; discover it with listProjectBranches / listProjectPullRequests.
| Name | Required | Description | Default |
|---|---|---|---|
| branch | No | Branch name; mutually exclusive with `pullRequest`. Omission uses the configured default (usually main). For non-main work, pass explicitly; use `listProjectBranches`. | |
| projectKey | No | Project key; omit only if the server has a default. Discover with `listProjects`. | |
| pullRequest | No | PR key; mutually exclusive with `branch`; no default. For PR work, pass explicitly; use `listProjectPullRequests`. |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | No | Human-readable project name. |
| metrics | No | |
| version | No | Project version string, if configured. |
| qualifier | No | Project qualifier: TRK for a main project, VW for a portfolio, APP for an application. |
| projectKey | No | Unique project key. |
| visibility | No | Visibility setting: 'public' or 'private'. |
| description | No | Optional project description. |
| qualityGate | No | |
| lastAnalysisDate | No | ISO-8601 timestamp of the most recent successful analysis. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish read-only, idempotent, non-destructive behavior, so the bar is lower. The description adds valuable behavioral context: the default-branch scoping rule, mutually exclusive ref parameters, and the categories of returned data. It does not contradict any annotation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences front-load the operational purpose before the scoping rule. Every clause contributes either return semantics or a routing instruction, with no filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With a rich output schema, safety annotations, and fully documented parameters, the description supplies the remaining decision-relevant context: default ref selection and how to discover refs. Nothing needed to select or invoke the tool correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, and each parameter description already covers defaults, mutual exclusivity, and discovery via sibling tools. The description reinforces this guidance but adds no new parameter-level meaning, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Get'), a singular resource ('one project analysis'), and enumerates return content (project metadata, quality gate failures, and metrics for size, findings, coverage, duplication, and technical debt). This clearly distinguishes it from sibling list/issue tools without needing to inspect their schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly instructs when to omit both refs (configured default, usually main) and when to pass the matching ref explicitly for non-main or PR work. It names concrete discovery alternatives (`listProjectBranches` / `listProjectPullRequests`), giving an agent direct routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getProjectIssuesBreakdowngetProjectIssuesBreakdownARead-onlyIdempotent
Count project issues by logical module and rule; intended for multi-module projects. A module is the first componentPath segment. Returns totals, module/rule facets, and per-module severity/type summaries. Scope explicitly: omitting both branch and pullRequest uses the configured default (usually main). For non-main or PR work, pass the matching ref explicitly; discover it with listProjectBranches / listProjectPullRequests. If branchAdvisory is present, choose the branch matching the user's ref and retry explicitly.
| Name | Required | Description | Default |
|---|---|---|---|
| rules | No | Comma-separated rule keys, e.g. `java:S1234`. | |
| types | No | Comma-separated: CODE_SMELL,BUG,VULNERABILITY. | |
| branch | No | Branch name; mutually exclusive with `pullRequest`. Omission uses the configured default (usually main). For non-main work, pass explicitly; use `listProjectBranches`. | |
| resolved | No | Resolved filter; defaults to false only when statuses is also omitted. | |
| statuses | No | Comma-separated: OPEN,CONFIRMED,REOPENED,RESOLVED,CLOSED. With no statuses/resolved, returns open issues. | |
| projectKey | No | Project key; omit only if the server has a default. Discover with `listProjects`. | |
| severities | No | Comma-separated: INFO,MINOR,MAJOR,CRITICAL,BLOCKER. | |
| pullRequest | No | PR key; mutually exclusive with `branch`; no default. For PR work, pass explicitly; use `listProjectPullRequests`. | |
| componentPathPrefix | No | Same Sonar `componentPath` prefix semantics as `listIssues`; use `listComponents` instead of guessing. |
Output Schema
| Name | Required | Description |
|---|---|---|
| total | No | Total number of issues matching the query. |
| byRule | No | Issues grouped by rule key across the selected scope. |
| modules | No | Per-module issue summaries, including rule/severity/type breakdowns. |
| byModule | No | Issues grouped by logical module. |
| projectKey | No | Key of the project being analysed. |
| branchAdvisory | No | |
| pathPrefixTruncated | No | True when componentPathPrefix was supplied and the underlying scan hit the configured maximum issue count before exhausting Sonar. Totals/modules reflect only the scanned slice. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds valuable behavioral context beyond annotations: the default-branch behavior, the mutual exclusivity of branch and pullRequest, the branchAdvisory retry instruction, and the module definition ('first componentPath segment'). It does not describe pagination or response size, but the output schema exists and the added context is substantial.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but well-organized: it front-loads the core purpose and return shape, then covers scoping behavior, then discovery/retry guidance. Every sentence earns its place, though the density of the branch/pullRequest guidance could be slightly streamlined. It is appropriately sized for a 9-parameter tool with complex scoping semantics.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex read-only aggregation tool with 9 optional parameters, an output schema, and rich annotations, the description covers the key decision points: when to use it, how module grouping works, how branch/PR scoping behaves, and how to discover the right refs. The only minor gap is pagination/response-size expectations, but the output schema and the tool's aggregation nature make that less critical. The description is complete enough for an agent to select and invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all 9 parameters. The description adds meaning by explaining the module concept ('first componentPath segment'), clarifying the default-branch behavior, and explicitly naming discovery tools for branch, pullRequest, and componentPathPrefix. It doesn't add syntax details for every parameter, but it compensates well for the most ambiguous ones.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Count'), a resource ('project issues'), and a clear dimension ('by logical module and rule'), and explicitly distinguishes it from the sibling getProjectIssuesSummary by noting it is 'intended for multi-module projects' and returns module/rule facets. This makes the tool's purpose unambiguous and differentiates it from similar tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use guidance: it is for multi-module projects, and it explains when to pass branch/pullRequest explicitly versus relying on the default. It also names sibling tools (listProjectBranches, listProjectPullRequests, listComponents) as discovery alternatives, and even instructs retrying with branchAdvisory. This is exemplary usage guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getProjectIssuesSummarygetProjectIssuesSummaryARead-onlyIdempotent
Count project issues and group them by severity, type, status, rule, tag, and SCM author. Returns the total and facet counts; use before listing details. Scope explicitly: omitting both branch and pullRequest uses the configured default (usually main). For non-main or PR work, pass the matching ref explicitly; discover it with listProjectBranches / listProjectPullRequests. If branchAdvisory is present, choose the branch matching the user's ref and retry explicitly.
| Name | Required | Description | Default |
|---|---|---|---|
| rules | No | Comma-separated rule keys, e.g. `java:S1234`. | |
| types | No | Comma-separated: CODE_SMELL,BUG,VULNERABILITY. | |
| branch | No | Branch name; mutually exclusive with `pullRequest`. Omission uses the configured default (usually main). For non-main work, pass explicitly; use `listProjectBranches`. | |
| resolved | No | Resolved filter; defaults to false only when statuses is also omitted. | |
| statuses | No | Comma-separated: OPEN,CONFIRMED,REOPENED,RESOLVED,CLOSED. With no statuses/resolved, returns open issues. | |
| projectKey | No | Project key; omit only if the server has a default. Discover with `listProjects`. | |
| severities | No | Comma-separated: INFO,MINOR,MAJOR,CRITICAL,BLOCKER. | |
| pullRequest | No | PR key; mutually exclusive with `branch`; no default. For PR work, pass explicitly; use `listProjectPullRequests`. | |
| componentPathPrefix | No | Same Sonar `componentPath` prefix semantics as `listIssues`; use `listComponents` instead of guessing. |
Output Schema
| Name | Required | Description |
|---|---|---|
| byTag | No | Issues grouped by user-defined tag. |
| total | No | Total number of issues matching the query. |
| byRule | No | Issues grouped by rule key (top rules by issue count). |
| byType | No | Issues grouped by type (BUG, VULNERABILITY, CODE_SMELL). |
| byAuthor | No | Issues grouped by SCM author who introduced them (top authors by issue count). |
| byStatus | No | Issues grouped by lifecycle status (OPEN, CONFIRMED, REOPENED, RESOLVED, CLOSED). |
| bySeverity | No | Issues grouped by severity (BLOCKER, CRITICAL, MAJOR, MINOR, INFO). |
| projectKey | No | Key of the project being summarised. |
| branchAdvisory | No | |
| pathPrefixTruncated | No | True when componentPathPrefix was supplied and the underlying scan hit the configured maximum issue count before exhausting Sonar. Totals/facets reflect only the scanned slice. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnlyHint, idempotentHint, and non-destructive behavior. The description adds useful behavioral context beyond annotations: the default-branch scope behavior and the branchAdvisory retry rule. It does not need to restate safety because annotations cover it.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four dense sentences with purpose, timing, scoping rule, and conditional retry guidance in order. No filler or schema duplication; every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With a rich output schema and 100% parameter coverage, the description supplies the missing operational context: when to call, default scope, and how to resolve branch ambiguity. It could briefly distinguish itself from getProjectIssuesBreakdown, but the aggregation description is sufficient for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema covers 100% of parameters, so the baseline is 3. The description adds cross-parameter context about branch/PR omission and grouping dimensions, but most parameter-level meaning is already present in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description starts with a concrete verb and resource: 'Count project issues and group them by severity, type, status, rule, tag, and SCM author.' The phrase 'use before listing details' and the facet list clearly differentiate this aggregation tool from siblings like listIssues.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states when to invoke ('use before listing details'), and gives explicit conditional instructions for branch selection: omit branch/PR for default, pass matching ref for non-main/PR, discover refs with listProjectBranches/listProjectPullRequests, and retry when branchAdvisory is present. This is actionable routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
getRulegetRuleARead-onlyIdempotent
Get a Sonar rule. Returns title, severity, type, language, tags, and structured explanation and fix sections.
| Name | Required | Description | Default |
|---|---|---|---|
| ruleKey | Yes | Rule key, e.g. `java:S1234` |
Output Schema
| Name | Required | Description |
|---|---|---|
| key | No | Unique rule key (e.g. 'java:S1186'). |
| lang | No | Language key (e.g. 'java', 'js', 'py'). |
| name | No | Human-readable rule name. |
| repo | No | Repository key (language or technology identifier, e.g. 'java', 'js', 'py'). |
| tags | No | Tags categorising the rule (e.g. 'performance', 'java8', 'owasp-a1'). |
| type | No | Rule type: BUG, VULNERABILITY, CODE_SMELL, or SECURITY_HOTSPOT. |
| status | No | Rule lifecycle status: READY, DEPRECATED, or REMOVED. |
| langName | No | Human-readable language name (e.g. 'Java', 'JavaScript', 'Python'). |
| severity | No | Default severity. Standard mode: BLOCKER, CRITICAL, MAJOR, MINOR, INFO. MQR mode: BLOCKER, HIGH, MEDIUM, LOW, INFO. |
| htmlDescription | No | Full rule description as raw HTML (including code examples and formatting). |
| descriptionSections | No | Structured description broken into sections (rationale, non-compliant code, compliant code, etc.). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint: false, so the safety profile is covered. The description mentions returned fields, but since an output schema is present, this largely repeats structured data rather than revealing behavior. No additional traits such as authentication needs, rate limits, or error behavior are disclosed. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single compact sentence that front-loads the operation ('Get a Sonar rule') and then lists the return contents. There is no filler, redundancy, or unnecessary detail, making it appropriately concise for a simple lookup tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's low complexity—one fully documented parameter, an output schema, and read-only/idempotent annotations—the description is functionally adequate for correct invocation. The main gap is the absence of any relationship to sibling tools or selection guidance, but this is minor for such a simple and distinct resource.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% for ruleKey, including an example format (`java:S1234`), so the schema fully documents the parameter. The description adds no extra meaning about the parameter itself, matching the baseline score for high schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb 'Get' and a clear resource 'Sonar rule', and it lists the returned content (title, severity, type, language, tags, explanation/fix sections). This makes the tool's purpose unambiguous. The resource is distinct from sibling tools that target projects, issues, hotspots, and components, so an agent can tell it apart.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no guidance about when to use getRule versus alternatives such as getIssue or getHotspot. It does not mention any exclusions, prerequisites, or contexts where this tool is preferred. An agent must rely entirely on the tool name to infer selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listComponentslistComponentsARead-onlyIdempotent
Browse or search a project's analysed component tree. Use returned path values as componentPathPrefix; Sonar paths may differ from repository paths. Returns component key, path, name, qualifier, and language. Use qualifiers=DIR to discover directories. Scope explicitly: omitting both branch and pullRequest uses the configured default (usually main). For non-main or PR work, pass the matching ref explicitly; discover it with listProjectBranches / listProjectPullRequests.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Page size; server default if omitted. | |
| query | No | Component name/path substring | |
| branch | No | Branch name; mutually exclusive with `pullRequest`. Omission uses the configured default (usually main). For non-main work, pass explicitly; use `listProjectBranches`. | |
| offset | No | Offset; default 0. | |
| projectKey | No | Project key; omit only if the server has a default. Discover with `listProjects`. | |
| qualifiers | No | Comma-separated component types, e.g. `DIR,FIL`; use `DIR` for path discovery. | |
| pullRequest | No | PR key; mutually exclusive with `branch`; no default. For PR work, pass explicitly; use `listProjectPullRequests`. |
Output Schema
| Name | Required | Description |
|---|---|---|
| items | No | Components returned by SonarQube. |
| limit | No | Effective page size. |
| total | No | Total matching component count reported by SonarQube. |
| offset | No | Requested offset. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already convey read-only, idempotent, and non-destructive behavior, and the description adds genuinely non-obvious context: Sonar paths may differ from repository paths, returned paths should be reused as `componentPathPrefix`, and omitted branch/pullRequest arguments fall back to the configured default (usually main). It also summarizes the returned fields, which remains useful even with an output schema present.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Six compact sentences are arranged purpose-first, then usage, then branch/PR scoping. Each sentence contributes actionable information, and nothing is repeated unnecessarily.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only list/browse tool with a rich input schema, an output schema, and safety annotations, the description covers the non-obvious aspects an agent needs: path/prefix semantics, directory discovery, and default branch behavior. No critical information is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 100% schema description coverage, the baseline is 3; the description adds meaningful extra semantics for `qualifiers` (use `DIR` for path discovery) and for `branch`/`pullRequest` default behavior. It does not exhaustively enrich every parameter, but it raises the definition above the schema-only baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific action ('Browse or search') and a specific resource ('a project's analysed component tree'), clearly distinguishing this from sibling tools that operate on projects, issues, hotspots, or rules. The additional note about returned path values being usable as `componentPathPrefix` clarifies its role in the wider API workflow.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit usage instructions: use `qualifiers=DIR` to discover directories and pass the matching ref for non-main or PR work. It names `listProjectBranches` and `listProjectPullRequests` as the alternatives for discovering refs, giving concrete when-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listHotspotslistHotspotsARead-onlyIdempotent
List project Security Hotspots that need human review. Defaults to TO_REVIEW; supports path and ref filters. Returns rule/category, vulnerability probability, message, and file location. Scope explicitly: omitting both branch and pullRequest uses the configured default (usually main). For non-main or PR work, pass the matching ref explicitly; discover it with listProjectBranches / listProjectPullRequests.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Page size; server default if omitted. | |
| branch | No | Branch name; mutually exclusive with `pullRequest`. Omission uses the configured default (usually main). For non-main work, pass explicitly; use `listProjectBranches`. | |
| offset | No | Offset; default 0. | |
| status | No | `TO_REVIEW` or `REVIEWED`; default `TO_REVIEW` | |
| projectKey | No | Project key; omit only if the server has a default. Discover with `listProjects`. | |
| pullRequest | No | PR key; mutually exclusive with `branch`; no default. For PR work, pass explicitly; use `listProjectPullRequests`. | |
| componentPathPrefix | No | Sonar `componentPath` prefix relative to the project root; an exact file path is also allowed. Uses directory boundaries, so `src` does not match `srcExtra`. For Java/Kotlin packages use slashes. Sonar paths may differ from repository paths; use `listComponents` instead of guessing. If `pathPrefixTruncated=true`, narrow the prefix. |
Output Schema
| Name | Required | Description |
|---|---|---|
| items | No | Hotspots in this page. |
| limit | No | Maximum number of items per page. |
| total | No | Total number of hotspots matching the query across all pages. |
| offset | No | Zero-based offset of this page within the full result set. |
| pathPrefixTruncated | No | True when componentPathPrefix was supplied and the underlying scan hit the configured maximum hotspot count before exhausting Sonar. Tighten the prefix to see the rest. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds valuable behavioral context by disclosing that omitting both branch and pullRequest uses the configured default (usually main) and by stating what fields are returned. This goes beyond the annotations and helps an agent predict behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded: purpose, default, supported filters, return contents, and ref-scoping guidance all fit into four efficient sentences. Every sentence carries useful information and none of it merely restates the tool name or title.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, the description does not need to detail return structure, and the input schema already documents all seven parameters. The description covers default behavior, filtering, return fields, and the important branch/pullRequest scope pitfall. This is complete enough for an agent to select and invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds meaningful cross-parameter guidance: it ties branch/pullRequest omission to the default ref and explicitly says to pass a ref for non-main or PR work. It also points to the right discovery tools for those refs, which is more than the individual schema descriptions provide.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'List project Security Hotspots that need human review.' It clearly distinguishes from siblings like getHotspot (single item) and listIssues (different resource type) by naming the hotspot domain and the 'TO_REVIEW' default. The scope is precise enough that an agent knows exactly what this tool returns.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context: it defaults to TO_REVIEW and supports path and ref filters, and it explains how to handle non-main branches or PRs by passing the matching ref explicitly and discovering it via listProjectBranches/listProjectPullRequests. It does not explicitly contrast with listIssues or getHotspot, but the resource distinction is strongly implied by the wording.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listIssueslistIssuesARead-onlyIdempotent
List project issues with optional severity, type, status, rule, path, and ref filters. Returns rule, severity, type, status, message, file location/text range, and cross-file flows. Defaults to open issues. Scope explicitly: omitting both branch and pullRequest uses the configured default (usually main). For non-main or PR work, pass the matching ref explicitly; discover it with listProjectBranches / listProjectPullRequests. If branchAdvisory is present, choose the branch matching the user's ref and retry explicitly.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Page size; server default if omitted. | |
| rules | No | Comma-separated rule keys, e.g. `java:S1234`. | |
| types | No | Comma-separated: CODE_SMELL,BUG,VULNERABILITY. | |
| branch | No | Branch name; mutually exclusive with `pullRequest`. Omission uses the configured default (usually main). For non-main work, pass explicitly; use `listProjectBranches`. | |
| offset | No | Offset; default 0. | |
| resolved | No | Resolved filter; defaults to false only when statuses is also omitted. | |
| statuses | No | Comma-separated: OPEN,CONFIRMED,REOPENED,RESOLVED,CLOSED. With no statuses/resolved, returns open issues. | |
| projectKey | No | Project key; omit only if the server has a default. Discover with `listProjects`. | |
| severities | No | Comma-separated: INFO,MINOR,MAJOR,CRITICAL,BLOCKER. | |
| pullRequest | No | PR key; mutually exclusive with `branch`; no default. For PR work, pass explicitly; use `listProjectPullRequests`. | |
| componentPathPrefix | No | Sonar `componentPath` prefix relative to the project root; an exact file path is also allowed. Uses directory boundaries, so `src` does not match `srcExtra`. For Java/Kotlin packages use slashes. Sonar paths may differ from repository paths; use `listComponents` instead of guessing. If `pathPrefixTruncated=true`, narrow the prefix. |
Output Schema
| Name | Required | Description |
|---|---|---|
| items | No | Issues in this page. |
| limit | No | Maximum number of items per page. |
| total | No | Total number of issues matching the query across all pages. |
| offset | No | Zero-based offset of this page within the full result set. |
| branchAdvisory | No | |
| pathPrefixTruncated | No | True when componentPathPrefix was supplied and the underlying scan hit the configured maximum issue count before exhausting Sonar. The returned `total` and `items` reflect only the scanned slice; tighten the prefix to see the rest. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and non-destructive, so the safety profile is covered. The description adds valuable behavior beyond annotations: defaults to open issues, the configured-default branch behavior, and the branchAdvisory retry instruction. It does not discuss pagination, rate limits, or auth, but those are less critical for a read-only list tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose and filters, then returns, then defaults and usage guidance. It is slightly long but every sentence earns its place. The branchAdvisory sentence is cryptic and could be more explicit, which prevents a 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 11 optional parameters and an output schema, the description covers the most important contextual aspects: default behavior, branch/PR scoping, and return contents. It does not mention projectKey default behavior or pagination semantics, but the schema covers those. The branchAdvisory guidance is a unique addition, though its source is unexplained.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds meaning beyond the schema by clarifying the default status filter ('Defaults to open issues') and by explaining how to correctly set branch/pullRequest for non-main work. The branchAdvisory retry note also adds operational guidance not present in the schema, though it is somewhat under-defined.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'List project issues' and enumerates the filter dimensions (severity, type, status, rule, path, ref), making it clear this is a listing tool for project issues. The mention of return fields like 'cross-file flows' further distinguishes it from sibling summary/hotspot/single-issue tools, even without naming them explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit guidance on branch and PR scope: omitting both uses the configured default, non-main or PR work requires an explicit ref, and it points to `listProjectBranches` and `listProjectPullRequests` for discovery. It does not explicitly say when to prefer `getIssue` or `listHotspots` over this tool, but it provides strong contextual instruction for the main ambiguity around scope.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listProjectBrancheslistProjectBranchesARead-onlyIdempotent
List analysed project branches. Returns name, main/type flags, analysis date, quality gate, and issue counts; use the name as branch in other tools.
| Name | Required | Description | Default |
|---|---|---|---|
| projectKey | No | Project key; omit only if the server has a default. Discover with `listProjects`. |
Output Schema
| Name | Required | Description |
|---|---|---|
| branches | No | List of branches with analysis status and issue counts. |
| projectKey | No | Key of the project these branches belong to. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and non-destructive behavior. The description adds value by disclosing the specific returned fields and the 'analysed project branches' selection scope, which are not visible in annotations. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single efficient sentence that leads with the core action, then packs the essential return information and the branch-name usage note. Every clause earns its place with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter, read-only listing tool with a rich output schema and clear annotations, the description covers the main behavioral contract: what is listed, what is returned, and how to use the result. There are no critical missing details for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents the single optional projectKey parameter. The description does not add parameter-level detail, but it does not need to since the input schema fully covers semantics including the default-server caveat and the listProjects discovery hint.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action and resource: 'List analysed project branches' and enumerates what is returned (name, flags, analysis date, quality gate, issue counts). This is more specific than simply restating the tool name and helps distinguish it from sibling tools like listProjects or listProjectPullRequests.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The sentence 'use the name as `branch` in other tools' gives concrete downstream usage context, showing the agent when this tool is useful. It does not explicitly name alternatives or exclusion conditions, but for a straightforward listing tool this is clear enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listProjectPullRequestslistProjectPullRequestsARead-onlyIdempotent
List project PR analyses. Returns key, title, source/base branches, URL, analysis date, quality gate, and issue counts; use the key as pullRequest in other tools. Returns empty when DevOps integration is unavailable.
| Name | Required | Description | Default |
|---|---|---|---|
| projectKey | No | Project key; omit only if the server has a default. Discover with `listProjects`. |
Output Schema
| Name | Required | Description |
|---|---|---|
| projectKey | No | Key of the project these pull requests belong to. |
| pullRequests | No | List of pull requests with analysis status and issue counts. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnly/idempotent/non-destructive behavior. Beyond that, the description adds a genuine behavioral disclosure not available in structured data: 'Returns empty when DevOps integration is unavailable.' It does not contradict any annotation; only the field enumeration is somewhat redundant with the output schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short clauses pack purpose, return shape, downstream chaining guidance, and an edge-case behavior into roughly 40 words, with the core purpose front-loaded. No filler or repetition of annotation facts; every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-optional-parameter, read-only list tool with an output schema and full annotations, the description covers everything an agent needs: what it lists, what fields come back, how to use the key downstream, and the no-integration edge case. Pagination or ordering details are minor given the output schema exists.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the projectKey parameter is already fully documented in the schema, including the default-server nuance and the pointer to listProjects. The description adds no input-parameter semantics beyond the schema; baseline 3 applies because the schema carries the burden.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb-resource pair ('List project PR analyses') and enumerates the returned fields (key, title, branches, URL, analysis date, quality gate, issue counts), making the tool's function unambiguous. It is clearly distinct from siblings like listProjectBranches and listIssues, which operate on different resources.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives actionable usage guidance: it instructs the agent to feed the returned key into other tools as `pullRequest`, and its note about empty results signals when the DevOps integration is absent. It does not explicitly name alternatives or state when not to use this tool, but the resource is distinct enough among siblings that the implied usage is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
listProjectslistProjectsARead-onlyIdempotent
List projects, optionally filtered by name. Returns key, name, and qualifier; use the key as projectKey in other tools.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Page size; server default if omitted. | |
| query | No | Project name substring | |
| offset | No | Offset; default 0. |
Output Schema
| Name | Required | Description |
|---|---|---|
| items | No | Projects in this page. |
| limit | No | Maximum number of items per page. |
| total | No | Total number of projects matching the query across all pages. |
| offset | No | Zero-based offset of this page within the full result set. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnly, idempotent, non-destructive behavior. The description adds value beyond that by disclosing the return payload shape (key, name, qualifier) and the practical contract that the key should be reused as `projectKey` in other tools. It does not contradict annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two compact sentences carry all essential information: what the tool lists, how filtering works, what is returned, and how to use the result. Every clause earns its place with no repetition of schema details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only listing tool with three optional parameters, full schema documentation, rich annotations, and an output schema, the description is complete. It adds the one crucial cross-tool detail—using the returned key as `projectKey`—that structured fields alone would not convey.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so limit, query, and offset are already well documented structurally. The description reinforces the `query` parameter as name-based filtering, but adds little semantic detail beyond what the schema provides, keeping this at the baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action and resource: "List projects, optionally filtered by name." This distinguishes it from sibling tools that target other resources (e.g., listIssues, listComponents), so an agent can identify the right tool without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear usage context: listing projects with optional name filtering, and it explains how the result should be consumed downstream by using the returned key as `projectKey`. It does not explicitly name alternative tools or exclusion conditions, but the context is sufficient for this straightforward list operation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
13 tool updates
v0.1.0- First observed
getHotspot - First observed
getIssue - First observed
getIssueSnippets - First observed
getProject - First observed
getProjectIssuesBreakdown - First observed
getProjectIssuesSummary - First observed
getRule - First observed
listComponents - First observed
listHotspots - First observed
listIssues - First observed
listProjectBranches - First observed
listProjectPullRequests - First observed
listProjects
TDQS
Scored across 13 tools
Each tool targets a distinct resource and action (get/list for project, issue, hotspot, rule, components, branches, PRs). The three issue-related tools are clearly differentiated: listIssues returns details, getProjectIssuesSummary returns aggregate facets, and getProjectIssuesBreakdown groups by module/rule.
All tool names follow a consistent getX/listX pattern in camelCase, with nouns clearly indicating the resource. No mixing of conventions or vague verbs.
13 tools is well within the ideal 3-15 range and each tool covers a specific aspect of SonarQube analysis (projects, issues, hotspots, rules, branches, PRs, components). No redundancy or bloat.
Core read-only analysis workflows are well covered: project metrics, issue list/detail/snippets/aggregations, hotspot handling, and branch/PR scoping. Minor gaps include no listRules (only getRule) and no write actions (e.g., issue assignment or hotspot review), but these are not central to an analysis-focused server.
Maintenance
Related MCP Connectors
Zero-config MCP security scanner for AI-generated apps. 25K+ vulnerability patterns.
The Cortex MCP server provides read-only access to real-time engineering context from the Cortex developer portal, allowing AI coding assistants to answer natural language questions about your organization's catalog (microservices, libraries, domains, teams, infrastructure), scorecards (engineering standards and best practices), initiatives (goals and deadlines), and Engineering Intelligence metrics. It includes tools for querying documentation, tracking personal entities, and accessing AI-assisted insights across the entire Cortex ecosystem.
Security scanner for MCP servers. Detect vulnerabilities, prompt injection, and tool poisoning.
Search your AI chat history (ChatGPT, Claude, Codex) from any MCP client. Remote, private, read-only
Related MCP Servers
- FlicenseAqualityDmaintenanceA read-only MCP server that provides AI assistants with structured access to SonarQube projects, issues, metrics, and rules. It enables safe analysis of code quality and security findings through a set of validated, safety-first tools.6-
- AlicenseNot gradedqualityDmaintenanceServer for SonarQube Give AI assistants direct access to your code quality, security & analysis data2MIT
- AlicenseAqualityBmaintenanceAn MCP server for SonarQube that enables LLM agents to discover projects, analyze code quality metrics, check Quality Gate status, search issues with filters, and rank projects by worst-performing metrics. It provides read-only, safe access to SonarQube instances with structured outputs and error handling.521 PyPIMIT
- AlicenseBqualityDmaintenanceRead-only MCP server that exposes SonarQube Web API tools for issue retrieval, quality gate status, and source context, enabling coding agents to fix code issues.8147 npm1MIT