Skip to content

Commit e70b31f

Browse files
committed
MCP-26 Expose a tool to list all supported languages
1 parent a14555f commit e70b31f

File tree

10 files changed

+407
-10
lines changed

10 files changed

+407
-10
lines changed

README.md

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,11 @@ Alternatively, you can manually create or update your VS Code MCP configurations
9393

9494
## Tools
9595

96+
### Languages
97+
98+
- **list_languages** - List all programming languages supported in this instance
99+
- `q` - Optional pattern to match language keys/names against - _String_
100+
96101
### Issues
97102

98103
- **change_sonar_issue_status** - Change the status of a Sonar issue to "accept", "falsepositive" or to "reopen" an issue
@@ -107,15 +112,6 @@ Alternatively, you can manually create or update your VS Code MCP configurations
107112
- **search_my_sonarqube_cloud_projects** - Find Sonar projects in my organization
108113
- `page` - Optional page number - _String_
109114

110-
### Quality Gates
111-
112-
- **get_quality_gate_status_for_project** - Get the Quality Gate Status for the project
113-
- `analysisId` - Optional analysis ID - _String_
114-
- `branch` - Optional branch key - _String_
115-
- `projectId` - Optional project ID - _String_
116-
- `projectKey` - Optional project key - _String_
117-
- `pullRequest` - Optional pull request ID - _String_
118-
119115
## Data and telemetry
120116

121117
This server collects anonymous usage data and sends it to SonarSource to help improve the product. No source code or IP address is collected, and SonarSource does not share the data with anyone else. Collection of telemetry can be disabled with the following system property or environment variable: `TELEMETRY_DISABLED=true`. Click [here](telemetry-sample.md) to see a sample of the data that are collected.

src/main/java/org/sonar/mcp/SonarMcpServer.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import org.sonar.mcp.tools.ToolExecutor;
3535
import org.sonar.mcp.tools.issues.ChangeIssueStatusTool;
3636
import org.sonar.mcp.tools.issues.SearchIssuesTool;
37+
import org.sonar.mcp.tools.languages.ListLanguagesTool;
3738
import org.sonar.mcp.tools.projects.SearchMyProjectsTool;
3839
import org.sonar.mcp.tools.qualitygates.ProjectStatusTool;
3940

@@ -60,7 +61,8 @@ public SonarMcpServer(StdioServerTransportProvider transportProvider, Map<String
6061
new ChangeIssueStatusTool(serverApi),
6162
new SearchMyProjectsTool(serverApi),
6263
new SearchIssuesTool(serverApi),
63-
new ProjectStatusTool(serverApi)
64+
new ProjectStatusTool(serverApi),
65+
new ListLanguagesTool(serverApi)
6466
);
6567
}
6668

src/main/java/org/sonar/mcp/serverapi/ServerApi.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import javax.annotation.Nullable;
2020
import org.sonar.mcp.serverapi.components.ComponentsApi;
2121
import org.sonar.mcp.serverapi.issues.IssuesApi;
22+
import org.sonar.mcp.serverapi.languages.LanguagesApi;
2223
import org.sonar.mcp.serverapi.qualitygates.QualityGatesApi;
2324

2425
public class ServerApi {
@@ -43,6 +44,10 @@ public IssuesApi issuesApi() {
4344
return new IssuesApi(helper, helper.getOrganization());
4445
}
4546

47+
public LanguagesApi languagesApi() {
48+
return new LanguagesApi(helper);
49+
}
50+
4651
public boolean isAuthenticationSet() {
4752
return isAuthenticationSet;
4853
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Sonar MCP Server
3+
* Copyright (C) 2025 SonarSource
4+
* mailto:info AT sonarsource DOT com
5+
*
6+
* This program is free software; you can redistribute it and/or
7+
* modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12+
* See the Sonar Source-Available License for more details.
13+
*
14+
* You should have received a copy of the Sonar Source-Available License
15+
* along with this program; if not, see https://sonarsource.com/license/ssal/
16+
*/
17+
package org.sonar.mcp.serverapi.languages;
18+
19+
import com.google.gson.Gson;
20+
import java.util.List;
21+
import javax.annotation.Nullable;
22+
import org.sonar.mcp.serverapi.ServerApiHelper;
23+
import org.sonar.mcp.serverapi.UrlBuilder;
24+
import org.sonar.mcp.serverapi.languages.response.ListResponse;
25+
26+
public class LanguagesApi {
27+
28+
public static final String LIST_PATH = "/api/languages/list";
29+
30+
private final ServerApiHelper helper;
31+
32+
public LanguagesApi(ServerApiHelper helper) {
33+
this.helper = helper;
34+
}
35+
36+
public ListResponse list(@Nullable String query) {
37+
try (var response = helper.get(buildListPath(query))) {
38+
var responseStr = response.bodyAsString();
39+
return new Gson().fromJson(responseStr, ListResponse.class);
40+
}
41+
}
42+
43+
private static String buildListPath(@Nullable String query) {
44+
return new UrlBuilder(LIST_PATH)
45+
.addParam("q", query)
46+
.build();
47+
}
48+
49+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
* Sonar MCP Server
3+
* Copyright (C) 2025 SonarSource
4+
* mailto:info AT sonarsource DOT com
5+
*
6+
* This program is free software; you can redistribute it and/or
7+
* modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12+
* See the Sonar Source-Available License for more details.
13+
*
14+
* You should have received a copy of the Sonar Source-Available License
15+
* along with this program; if not, see https://sonarsource.com/license/ssal/
16+
*/
17+
@ParametersAreNonnullByDefault
18+
package org.sonar.mcp.serverapi.languages;
19+
20+
import javax.annotation.ParametersAreNonnullByDefault;
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Sonar MCP Server
3+
* Copyright (C) 2025 SonarSource
4+
* mailto:info AT sonarsource DOT com
5+
*
6+
* This program is free software; you can redistribute it and/or
7+
* modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12+
* See the Sonar Source-Available License for more details.
13+
*
14+
* You should have received a copy of the Sonar Source-Available License
15+
* along with this program; if not, see https://sonarsource.com/license/ssal/
16+
*/
17+
package org.sonar.mcp.serverapi.languages.response;
18+
19+
import java.util.List;
20+
21+
public record ListResponse(List<Language> languages) {
22+
23+
public record Language(String key, String name) {
24+
}
25+
26+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
* Sonar MCP Server
3+
* Copyright (C) 2025 SonarSource
4+
* mailto:info AT sonarsource DOT com
5+
*
6+
* This program is free software; you can redistribute it and/or
7+
* modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12+
* See the Sonar Source-Available License for more details.
13+
*
14+
* You should have received a copy of the Sonar Source-Available License
15+
* along with this program; if not, see https://sonarsource.com/license/ssal/
16+
*/
17+
@ParametersAreNonnullByDefault
18+
package org.sonar.mcp.serverapi.languages.response;
19+
20+
import javax.annotation.ParametersAreNonnullByDefault;
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* Sonar MCP Server
3+
* Copyright (C) 2025 SonarSource
4+
* mailto:info AT sonarsource DOT com
5+
*
6+
* This program is free software; you can redistribute it and/or
7+
* modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12+
* See the Sonar Source-Available License for more details.
13+
*
14+
* You should have received a copy of the Sonar Source-Available License
15+
* along with this program; if not, see https://sonarsource.com/license/ssal/
16+
*/
17+
package org.sonar.mcp.tools.languages;
18+
19+
import org.sonar.mcp.serverapi.ServerApi;
20+
import org.sonar.mcp.serverapi.languages.response.ListResponse;
21+
import org.sonar.mcp.tools.SchemaToolBuilder;
22+
import org.sonar.mcp.tools.Tool;
23+
24+
public class ListLanguagesTool extends Tool {
25+
26+
public static final String TOOL_NAME = "list_languages";
27+
public static final String QUERY_PROPERTY = "q";
28+
29+
private final ServerApi serverApi;
30+
31+
public ListLanguagesTool(ServerApi serverApi) {
32+
super(new SchemaToolBuilder()
33+
.setName(TOOL_NAME)
34+
.setDescription("List all programming languages supported in this instance")
35+
.addStringProperty(QUERY_PROPERTY, "Optional pattern to match language keys/names against")
36+
.build());
37+
this.serverApi = serverApi;
38+
}
39+
40+
@Override
41+
public Tool.Result execute(Tool.Arguments arguments) {
42+
if (!serverApi.isAuthenticationSet()) {
43+
return Tool.Result.failure("Not connected to SonarQube Cloud, please provide 'SONARQUBE_CLOUD_TOKEN' and 'SONARQUBE_CLOUD_ORG'");
44+
}
45+
46+
var query = arguments.getOptionalString(QUERY_PROPERTY);
47+
var response = serverApi.languagesApi().list(query);
48+
return Tool.Result.success(buildResponseFromList(response));
49+
}
50+
51+
private static String buildResponseFromList(ListResponse response) {
52+
var stringBuilder = new StringBuilder();
53+
stringBuilder.append("Supported Languages:\n\n");
54+
55+
for (var language : response.languages()) {
56+
stringBuilder.append(language.name())
57+
.append(" (").append(language.key()).append(")")
58+
.append("\n");
59+
}
60+
61+
return stringBuilder.toString().trim();
62+
}
63+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
* Sonar MCP Server
3+
* Copyright (C) 2025 SonarSource
4+
* mailto:info AT sonarsource DOT com
5+
*
6+
* This program is free software; you can redistribute it and/or
7+
* modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12+
* See the Sonar Source-Available License for more details.
13+
*
14+
* You should have received a copy of the Sonar Source-Available License
15+
* along with this program; if not, see https://sonarsource.com/license/ssal/
16+
*/
17+
@ParametersAreNonnullByDefault
18+
package org.sonar.mcp.tools.languages;
19+
20+
import javax.annotation.ParametersAreNonnullByDefault;

0 commit comments

Comments
 (0)