Sonar MCP Server について
Sonar MCP Serverは、自社運用のSonarQube Community Build 26.4以降にAIコーディングエージェントから読み取り専用でアクセスするサーバーです。課題、ルール説明、コードスニペット、Security Hotspotsを絞ったツールで取得し、診断とローカルでのコード修正を支援します。
主な機能
- 01プロジェクト、ブランチ、プルリクエストの閲覧
- 02プロジェクト課題の絞り込みと集計
- 03課題の詳細とコードスニペットの取得
- 04ルール説明と修正方法の確認
- 05Security Hotspotsとフローの調査
活用シーン
- 01プロジェクトやファイル配下の課題特定
- 02ブランチやプルリクエストの指摘確認
- 03コード変更前のルール理解
- 04レビューが必要なセキュリティホットスポットの確認
MCP 対応
stdio経由でSonarQubeのweb APIを照会する13種類の読み取り専用MCPツールを提供します。SonarQubeのデータは変更せず、受信用HTTPポートも開きません。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
docker run -i --rm -e SONAR_URL -e SONAR_TOKEN -e SONAR_DEFAULT_PROJECT_KEY ghcr.io/igorolv/sonar-mcp-server:0.1.0SONAR_URLBase URL of the SonarQube instance, e.g. https://sonar.example.comSONAR_TOKENシークレットSonarQube user token (My Account -> Security -> Generate Tokens)SONAR_DEFAULT_PROJECT_KEYシークレットProject key used when a tool call does not name oneローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ghcr.io/igorolv/sonar-mcp-server:0.1.0stdioツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
Sonar MCP Server
SonarQube Community Build(26.4 以降)のインスタンスに、web-api 経由で読み取り専用アクセスを提供するローカル MCP サーバーです。 AI エージェント(Claude Code、Cursor、VS Code Copilot など)が、プロジェクトのイシュー一覧、イシューが発生しているファイルと位置、ルールの説明、イシュー周辺のソースコードスニペット、Security Hotspots を取得できます。
典型的な利用例は、「あのプロジェクトの Sonar のイシューを見つけて修正する」です。LLM は listIssues を呼び出し、必要に応じて getRule と getIssueSnippets を呼び出して、ローカルでファイルを編集します。
このサーバーを選ぶ理由
SonarSource 公式の MCP サーバーもありますが、対象は SonarQube 10+(および SonarCloud)で、クラウド型のデプロイを前提としています。このサーバーは、従来の /api/ web-api を公開するセルフホスト可能な SonarQube Community Build 26.4 以降のインストール環境向けに構築されています。Standard Experience と MQR モードの両方をサポートしており、インスタンスが MQR モードで動作している場合は、ソフトウェア品質ごとの影響を処理します。
また、意図的に対象範囲を絞っています。
- 設計上、読み取り専用です。 このサーバーは SonarQube 上で何かを作成、更新、削除することはありません。誤検知としてイシューにマークすることも、コメントを編集することも、管理者用エンドポイントを呼び出すこともありません。サーバーがそれらのエンドポイントを呼び出すことはないため、SonarQube におけるトークンの書き込み権限は関係ありません。
- 厳選されたツールセットです。 SonarQube API の全機能をそのまま提供するのではなく、単一のワークフロー、つまり「AI エージェントが Sonar の検出結果を読み取り、それに基づいてコードを修正する」ことを目的に選んだ、絞り込まれたツールセット(全 13 個)を提供します。コンポーネント、イシュー、ホットスポットの一覧表示、個別の検出結果の詳細確認、ルールの説明の取得、該当箇所周辺のソースコードスニペットの取得のみを行います。この「診断 → ローカルでコードを修正する」流れに含まれない機能は、ツール一覧を小さく保ち、エージェントが迷わず選択できるよう、意図的に除外しています。
つまり、セルフホスト可能な SonarQube Community Build と AI コーディングエージェントをつなぐ、用途を絞った読み取り専用のブリッジです。
クイックスタート
- JDK 25 以降をインストールします。
- 最新リリースから
sonar-mcp-server.jarをダウンロードするか、自分でビルドします:./gradlew bootJar(ビルドを参照)。Docker イメージも公開されています。 - SonarQube の URL とユーザートークンを取得します(設定を参照)。
- クライアントの MCP 設定に JAR を追加します(AI クライアントへの接続を参照)。
Claude Code の場合は、次の 1 つのコマンドで設定できます。
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.jar
アーキテクチャ
このサーバーがサポートするトランスポートは stdio のみです。
┌─────────────┐ stdio ┌──────────────────┐ web-api ┌──────────┐
│ AI agent │ <------------> │ sonar-mcp- │ -------------> │ SonarQube│
│ (Claude Code│ stdin/stdout │ server (Java) │ HTTP + Bearer │ CB 26.4+│
│ Cursor...) │ │ │ auth (token) │ │
└─────────────┘ └──────────────────┘ └──────────┘
AI クライアントはサーバーを子プロセスとして起動し、stdin/stdout を介して MCP プロトコルで通信します。 サーバーは HTTP ポートを開かず、外部からの接続も受け付けません。
ツール
このサーバーは、読み取り専用の MCP ツールを 13 個提供します。
プロジェクト
| ツール | 説明 |
|---|---|
listProjects | SonarQube プロジェクトの一覧です。パラメーター:query(名前の部分文字列)、limit、offset。key、name、qualifierを返します。 |
listComponents | Sonar のコンポーネントツリーを使用して、プロジェクト内のコンポーネントを検索/参照します。パラメーター:projectKey、query、qualifiers、branch / pullRequest、limit、offset。不透明なコンポーネントのkey値と、path、qualifier、名前、言語、プロジェクトを返します。返されたkey値はlistIssues.componentKeysで変更せずに使用してください。Java パッケージ名をコンポーネントキーとして直接渡さないでください。 |
getProject | プロジェクトの概要:ヘッダー情報(名前、qualifier、公開設定、説明、バージョン、最終分析日)、不合格条件を含む品質ゲートのステータス、厳選されたメトリクス(ncloc、バグ、脆弱性、セキュリティホットスポット、コードスメル、カバレッジ、重複行密度、分単位の技術的負債、アラートステータス)。パラメーター:projectKey、branch(任意)、pullRequest(任意)。 |
listProjectBranches | プロジェクトで分析されたブランチの一覧です。各エントリーには、name、isMain、type(LONG/SHORT/BRANCH)、excludedFromPurge、analysisDate、qualityGateStatusに加えて、バグ/脆弱性/コードスメルの件数が含まれます。ページネーションはありません。Sonar はすべてのブランチを一度に返します。 |
listProjectPullRequests | プロジェクトの PR 分析の一覧です。各エントリーには、PR のkey(他の場所ではpullRequest=として使用)、title、branch(head)、base、url、analysisDate、qualityGateStatusに加えて、バグ/脆弱性/コードスメルの件数が含まれます。Sonar のインストール環境に DevOps 連携がない場合は、空の一覧を返します。 |
イシュー
| ツール | 説明 |
|---|---|
listIssues | プロジェクトのイシュー一覧です。パラメーター:projectKey(デフォルト値が設定されていない場合は必須)、componentPathPrefix(任意) — Sonar プロジェクトルートからの相対パスで指定する、単一のサブツリーまたはファイルのフィルター(例:bc-doc/src/main/java/ru/fooまたはbc-doc/src/main/java/ru/foo/Bar.java)。Java/Kotlin のパッケージ名のドットはスラッシュに変換します。ディレクトリ境界が考慮されます(bc-doc/srcはbc-doc/srcExtraに一致しません)。さらに、severities、types、statuses、rules、branch / pullRequest(相互排他的)、resolved、limit、offsetを指定できます。デフォルトでは、未解決のイシューのみを返します(resolved=false、ステータスは OPEN/CONFIRMED/REOPENED)。各項目には、ルール、重要度、タイプ、ステータス、ファイルパス、行、主要な textRange、およびファイル間ルールのセカンダリフローが含まれます。componentPathPrefixを使用すると、サーバーがプロジェクトをスキャンしてクライアント側でフィルタリングします。スキャンには上限(デフォルトは10000件のイシュー)があり、上限に達するとレスポンスでpathPrefixTruncated=trueになります。 |
getIssue | キーで指定した単一のイシューの詳細と変更履歴(changelog)です。branch / pullRequestは任意で指定できます。 |
getIssueSnippets | すべてのイシューの位置(ファイル間ルールの場合は主要箇所とフロー)の周辺にあるソースコードのスニペットです。各位置には、componentPath、言語、SCM 情報を含むソース行の配列が含まれます。リポジトリをローカルで利用できない場合や、Sonar が分析したファイルのバージョンを正確に確認する必要がある場合に便利です。branch / pullRequestは任意で指定できます。イシューがメインとは異なる ref にあり、そのファイルがメインと異なる場合に重要です。 |
getProjectIssuesSummary | プロジェクト内の未解決イシューの集計サマリーです。合計と、重要度、タイプ、ステータス、ルール、タグ、SCM 作成者別の内訳を返します。パラメーターはページネーションを除き、listIssuesと同じです(componentPathPrefixを含む)。 |
getProjectIssuesBreakdown | 論理モジュールとルール別にイシューを集計した、複数モジュールの内訳です。モジュールは最初のcomponentPathセグメントから導出されます。パラメーターはgetProjectIssuesSummaryと同じです。 |
ルール
| ツール | 説明 |
|---|---|
getRule | キー(例:java:S1234)で指定した Sonar ルールの詳細です。タイトル、重要度、タイプ、言語、タグ、説明セクション(概要、根本原因、修正方法、リソース)が含まれます。インメモリーキャッシュを使用するため、繰り返しの呼び出しは無料です。 |
セキュリティホットスポット
| ツール | 説明 |
|---|---|
listHotspots | プロジェクトのセキュリティホットスポットの一覧です。ホットスポットはイシューとは別のカテゴリであり、手動でのセキュリティレビューが必要な箇所を示します。デフォルトでは、Sonar はステータスが TO_REVIEW のホットスポットを返します。パラメーター:projectKey、componentPathPrefix(任意)— listIssues と同じプレフィックスのセマンティクス、status(任意)、branch / pullRequest(任意、相互排他)、limit、offset。クライアント側のスキャン上限(レスポンス内の pathPrefixTruncated フラグ)の対象です。 |
getHotspot | セキュリティホットスポットの詳細:ルールの完全な説明(リスク、脆弱性、修正の推奨事項)、主テキスト範囲、関連フロー、変更履歴。ホットスポットキーはグローバルに一意であるため、branch / pullRequest パラメーターは不要です。 |
すべてのツールは読み取り専用であり、SonarQube のデータは変更されません。
ブランチとプルリクエストの操作
Sonar は ブランチ と プルリクエスト を、相互排他の別個のスコープとして分析します。Sonar の web-api では、1 回のリクエストにつき branch= または pullRequest= のいずれか一方を指定でき、両方は指定できません。
branch— 長期間使用するブランチ(main、develop、feature/...)。解決順序:明示的なbranch引数 →SONAR_DEFAULT_BRANCH→ なし(Sonar はプロジェクトのメインブランチを使用します)。pullRequest— Sonar の PR キー。通常は PR/MR 番号です。ブランチ分析とは独立しており、進行中の作業では、PR 分析に最も関連性の高い検出結果が含まれることがよくあります。プルリクエストキーはサーバーレベルのデフォルトにフォールバックしないため、明示的に渡してください。
同じツール呼び出しで branch と pullRequest の両方を渡すとエラーになります。利用可能な参照先を確認するには、listProjectBranches / listProjectPullRequests を使用してください。
ブランチのスコープ指定は重要です。 Sonar の各ブランチは個別に分析されます。
mainと機能ブランチでは、未解決イシューの件数が大きく異なる場合があります。機能ブランチには、まだマージされていない新たな修正(または新しいコード)が含まれている可能性があるためです。エージェントがbranch=を暗黙に省略すると、main(またはSONAR_DEFAULT_BRANCH)から結果を読み取るため、機能ブランチですでに完了した作業を見落とす可能性があります。さらに悪い場合、同じ問題を二度修正してしまうこともあります。ユーザーのローカル git がfeature/...にある場合、エージェントは最初にlistProjectBranchesを呼び出して対応する Sonar ブランチを見つけ、すべてのイシュー/サマリー/内訳の呼び出しでそのブランチを明示的に渡す必要があります。サーバー側のセーフティネットとして、
listIssues、getProjectIssuesSummary、getProjectIssuesBreakdownは、(1)branchもpullRequestも渡されておらず、かつ(2)プロジェクトに Sonar で分析済みの他のブランチがある場合、レスポンスにbranchAdvisoryフィールドを付加します。このアドバイザリーには、有効な(メイン)ブランチ名と、最新の analysisDate 順に並べたメイン以外のブランチ一覧が含まれます。それ以外の場合、このフィールドはありません。
技術スタック
- Java 25、Spring Boot 4.0.0、Spring AI MCP 2.0.0(stdio トランスポート)
- JSON 用の Jackson 3(
tools.jackson) - バージョンカタログ(
gradle/libs.versions.toml)を使用する Gradle 9.3.1
ビルド
# Point to a JDK 25+ if it's not the default:
export JAVA_HOME="$HOME/.jdks/jdk-25.0.2"
./gradlew build
Windows の場合:.\gradlew.bat build。
出力:build/libs/sonar-mcp-server.jar
設定
サーバーには SonarQube の URL とトークンが必要です。それ以外はすべて任意です。
| 変数 | 説明 |
|---|---|
SONAR_URL | SonarQube のベース URL(例:http://sonar.example.com) |
SONAR_TOKEN | SonarQube のユーザートークン |
SONAR_DEFAULT_PROJECT_KEY | デフォルトの SonarQube プロジェクトキーです。設定すると、listIssues、getProjectIssuesSummary、listHotspots を projectKey なしで呼び出せます。 |
SONAR_DEFAULT_BRANCH | デフォルトの Sonar ブランチです。設定すると、ブランチに対応するすべてのツール(listIssues、getIssue、getIssueSnippets、getProjectIssuesSummary、listHotspots)で、branch が省略された場合にこのブランチが使用されます。設定しない場合、Sonar はプロジェクトのメインブランチを使用します。 |
SONAR_MCP_DATA_DIR | サーバーのローカルデータディレクトリです。デフォルトは ~/.sonar-mcp-server です。 |
SONAR_MCP_PAGINATION_DEFAULT_LIMIT | リストツールのデフォルトのページ上限です。デフォルトは 50 です。 |
SONAR_MCP_PAGINATION_DEFAULT_OFFSET | リストツールのデフォルトのオフセットです。デフォルトは 0 です。 |
SONAR_MCP_PAGINATION_MAX_LIMIT | 最大ページ上限です(Sonar API 自体の上限は 500 です)。デフォルトは 500 です。 |
SONAR_MCP_SNIPPET_MAX_LINES | スニペットごとの行数上限として将来使用するために予約されています。現在は未使用です(範囲は Sonar が決定します)。デフォルトは 50 です。 |
SONAR_MCP_PATH_FILTER_MAX_SCANNED_ISSUES | componentPathPrefix が設定されている場合に、クライアント側でスキャンするイシュー/ホットスポットの上限です。デフォルトは 10000 です。上限に達すると、レスポンスに pathPrefixTruncated=true が含まれます。 |
ツールグループ
MCP の tools/list マニフェストは、環境変数フラグで制御される 4 つのグループに分かれています。すべてのグループはデフォルトで有効なため、初期状態のマニフェストに変更はありません。グループを無効にするとマニフェストを縮小できます。セッション開始時にツールと出力のスキーマが大量に読み込まれてしまう、小さなコンテキストの(ローカル)モデルで役立ちます。
| 変数 | グループ内のツール |
|---|---|
SONAR_MCP_TOOLS_ISSUE | listIssues、getIssue、getIssueSnippets、getProjectIssuesSummary、getProjectIssuesBreakdown |
SONAR_MCP_TOOLS_PROJECT | listProjects、listComponents、getProject、listProjectBranches、listProjectPullRequests |
SONAR_MCP_TOOLS_HOTSPOT | listHotspots、getHotspot |
SONAR_MCP_TOOLS_RULE | getRule |
フラグを false に設定すると(例:SONAR_MCP_TOOLS_HOTSPOT=false)、そのグループのツールがマニフェストから除外されます。
SonarQube の URL の取得
ブラウザーで SonarQube を開き、アドレスバーからパスを除いてアドレスをコピーします。スキームとホストのみを使用してください。
| ブラウザーのアドレスバー | URL の値 |
|---|---|
https://sonar.example.com/dashboard?id=... | https://sonar.example.com |
http://192.168.1.50:9000/projects | http://192.168.1.50:9000 |
http://10.0.0.5/sonar/projects | http://10.0.0.5/sonar |
SonarQube に IP アドレスでしかアクセスできない場合は、その IP アドレスをそのまま使用してください。サブパス(例:
/sonar)配下にデプロイされている場合は、そのサブパスも URL に含めてください。
SonarQube トークンの取得
- アカウントで SonarQube にサインインします。
- My Account -> Security を開きます。
- Generate Tokens でトークン名を入力し、種類として User Token を選択します。
- Generate をクリックします。トークンが表示されるのは一度だけです。すぐにコピーしてください。
- トークンの値を
SONAR_TOKENとして使用します。
トークンを紛失した場合は再生成する必要があります。SonarQube では既存のトークンは再表示されません。
サーバーは HTTP Bearer 認証を使用し、トークンを Authorization ヘッダーで渡します。これはユーザートークンに対する標準的な SonarQube Community Build の方式です。
実行
SONAR_URL=http://sonar.example.com SONAR_TOKEN=your_token \
java -jar build/libs/sonar-mcp-server.jar
サーバーは stdio で動作します。正常に起動すると HTTP ポートは開かず、stdin/stdout 経由で MCP リクエストを待ち受けます。
ログは ${SONAR_MCP_DATA_DIR:-~/.sonar-mcp-server}/logs/sonar-mcp-server.log に書き込まれます。
ファイルは日付とサイズに基づいてローテーションされます。上限は 10MB、保持期間は 30 日、合計サイズの上限は 512MB です。
Docker
イメージはリリースごとに GHCR に公開されます。
docker run -i --rm -e SONAR_URL=https://sonar.example.com -e SONAR_TOKEN=your_token ghcr.io/igorolv/sonar-mcp-server:latest
同じコマンドを MCP クライアントで起動してください(-i により、stdio トランスポート用に stdin が開いたままになります)。実行間でログを保持するには、ホストのディレクトリを /data にマウントします。SonarQube が同じマシンで実行されている場合は、localhost ではなくホスト名を使用するか、Linux では --network host を追加してください。
イメージをローカルでビルドするには、docker build -t sonar-mcp-server . を実行します。
AI クライアントへの接続
{
"command": "java",
"args": ["-jar", "<absolute-path>/sonar-mcp-server.jar"],
"env": {
"SONAR_URL": "http://sonar.example.com",
"SONAR_TOKEN": "your_token"
}
}
具体的な設定場所:
| クライアント | 接続方法 |
|---|---|
| Claude Code | claude mcp add --scope user -e SONAR_URL=... -e SONAR_TOKEN=... -- sonar java -jar /path/to/sonar-mcp-server.jar |
| Qwen Code | ~/.qwen/settings.json -> "mcpServers" -> "sonar"、または qwen mcp add --scope user -e SONAR_URL=... -e SONAR_TOKEN=... sonar java -jar /path/to/sonar-mcp-server.jar |
| VS Code | .vscode/mcp.json -> "servers" -> "sonar" |
| Cursor | .cursor/mcp.json -> "mcpServers" -> "sonar" |
| Claude Desktop | claude_desktop_config.json -> "mcpServers" -> "sonar" |
CLI クライアントには、登録の確認と削除を行うコマンドもあります:claude mcp list / claude mcp remove --scope user sonar(qwen も同様です)。
追加した後、クライアントを再起動してください。
AI エージェント向けプロンプトの例
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/foo
運用とセキュリティ
この MCP サーバーは、AI クライアントの近くでローカルに実行することを想定しています。HTTP ポートは開かず、受信ネットワーク接続も受け付けません。クライアントが JAR を子プロセスとして起動し、stdin/stdout 経由で通信します。
アクセスモデル
- サーバーは、
SONAR_TOKENにトークンが設定されている SonarQube ユーザーの権限で動作します。 - すべての MCP ツールは読み取り専用です。サーバーがイシュー、ホットスポット、ルール、プロジェクトを作成、変更、削除することはありません。
- 利用可能なプロジェクトとイシューは、SonarQube におけるユーザーの権限によって決まります。SonarQube でユーザーがプロジェクトを閲覧できない場合、サーバーもそのプロジェクトにアクセスできません。
- トークンは秘密情報として扱ってください。リポジトリ、シェルスクリプト、
.vscode/mcp.json、.cursor/mcp.json、その他の共有プロジェクトファイルにコミットしないでください。
AI クライアントに送信されるデータ
AI クライアントが受け取るのは、MCP ツールを通じて要求したデータのみです。
- ルール、重大度、タイプ、ファイルパス、行番号、メッセージ、タグ、SCM 作成者を含むイシューの一覧。
- イシューの変更履歴。
- Sonar ルールの説明(HTML/Markdown を含む)。
- イシューの場所周辺のソースコードスニペット(
getIssueSnippets経由)。 - セキュリティホットスポットとその詳細。
外部またはクラウドベースの AI クライアントに接続する前に、社内ポリシーを確認してください。ソースコードに企業秘密が含まれている可能性があります。
診断
環境の確認:
java -version
echo "$SONAR_URL"
test -n "$SONAR_TOKEN" && echo "SONAR_TOKEN is set"
SonarQube web-api のアクセス確認(トークンを使った HTTP Bearer 認証):
curl -H "Authorization: Bearer $SONAR_TOKEN" "$SONAR_URL/api/components/search?qualifiers=TRK&p=1&ps=1"
期待される応答は、プロジェクトの JSON リストです。401 Unauthorized はトークンが無効または期限切れであることを意味し、403 はユーザーに API の権限がないことを意味します。
ビルドの確認:
./gradlew test
./gradlew build
稼働中の SonarQube に対する統合テスト:
SONAR_URL=<url> SONAR_TOKEN=<token> ./gradlew integrationTest
統合テストには、接続可能な SonarQube と実データが必要です。ユニットテストでは、デフォルトで integration タグが除外されます。
既知の運用上の制限
- HTTP タイムアウトと再試行ポリシーは、まだ個別に設定できません。
- Sonar API はページベースのページネーション(
p/ps)を使用します。ツールではoffset/limitを受け付けますが、limitの倍数でないoffsetは、最も近いページ境界まで切り下げられます。また、Sonar ではpsの上限が 500 に設定されています。 componentPathPrefixはクライアント側のフィルターです。サーバーはプロジェクトのイシュー/ホットスポットをページ単位で取得し、componentPathが指定したプレフィックスで始まるものを保持します(ディレクトリ境界を考慮します)。スキャンには上限(SONAR_MCP_PATH_FILTER_MAX_SCANNED_ISSUES、デフォルトは 10000)があります。上限に達すると、レスポンスにpathPrefixTruncated=trueが設定されます。その場合、呼び出し側はプレフィックスをさらに絞り込んでください。Issueのauthorフィールドは、イシューが発生した行の SCM 作成者を示します(SCM プロバイダーが設定されている場合、Sonar によって値が設定されます)。Sonar はissues/searchでscmAuthor/scmDateを個別のフィールドとして返しません。行レベルの SCM 情報を取得するには、getIssueSnippetsを使用してください。
プロジェクトの構成
├── 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 configuration
トラブルシューティング
- 「Gradle requires JVM 17 or later」 —
JAVA_HOMEに JDK 25 以降を設定してください。 - 接続拒否/401 — URL とトークンを確認してください。テスト:
curl -H "Authorization: Bearer $SONAR_TOKEN" "$SONAR_URL/api/components/search?qualifiers=TRK&p=1&ps=1"。 - 403 Forbidden — トークンのユーザーに、プロジェクトまたは web-api の権限がありません。SonarQube でロールを確認してください。
- パッケージ/モジュールの範囲でイシューが 0 件になる — Sonar コンポーネントキーではなく、パス形式のプレフィックス(例:
bc-doc/src/main/java/ru/foo)をcomponentPathPrefixとして渡してください。Java/Kotlin のパッケージ名のドットはスラッシュに変換してください。このフィルターはディレクトリ境界を考慮するため、bc-doc/srcはbc-doc/srcExtraに一致しません。 - レスポンスに
pathPrefixTruncated=trueが含まれる — クライアント側のスキャンが最後まで到達する前にSONAR_MCP_PATH_FILTER_MAX_SCANNED_ISSUESに達しました。スキャン範囲を減らすためにプレフィックスを絞り込むか、プロジェクトで 10k では本当に足りない場合は上限を引き上げてください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。