Skip to content

Commit 3ed6076

Browse files
authored
MCP-193 Support tool annotations (#133)
1 parent 48fd7a7 commit 3ed6076

File tree

48 files changed

+221
-29
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+221
-29
lines changed

src/main/java/org/sonarsource/sonarqube/mcp/tools/SchemaToolBuilder.java

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ public class SchemaToolBuilder {
3434
private String name;
3535
private String title;
3636
private String description;
37+
private boolean isReadOnly;
3738

3839
public SchemaToolBuilder(Map<String, Object> outputSchemaFromClass) {
3940
this.properties = new HashMap<>();
@@ -106,6 +107,14 @@ public SchemaToolBuilder addRequiredEnumProperty(String propertyName, String[] i
106107
return this;
107108
}
108109

110+
/**
111+
* Marks this tool as read-only, indicating it only reads data and doesn't modify any state.
112+
*/
113+
public SchemaToolBuilder setReadOnlyHint() {
114+
this.isReadOnly = true;
115+
return this;
116+
}
117+
109118
public McpSchema.Tool build() {
110119
if (name == null || description == null) {
111120
throw new IllegalStateException("Name and description must be set before building the tool.");
@@ -115,8 +124,18 @@ public McpSchema.Tool build() {
115124
throw new IllegalStateException("Cannot set a required property that does not exist.");
116125
}
117126

118-
var jsonSchema = new McpSchema.JsonSchema("object", properties, requiredProperties, false, Collections.emptyMap(), Collections.emptyMap());
119-
120-
return new McpSchema.Tool(name, title, description, jsonSchema, outputSchemaFromClass, null, Map.of());
127+
var jsonSchema = new McpSchema.JsonSchema("object", properties, requiredProperties, false, Collections.emptyMap(),
128+
Collections.emptyMap());
129+
130+
var toolAnnotations = new McpSchema.ToolAnnotations(
131+
null,
132+
isReadOnly,
133+
false,
134+
false,
135+
true,
136+
null
137+
);
138+
139+
return new McpSchema.Tool(name, title, description, jsonSchema, outputSchemaFromClass, toolAnnotations, null);
121140
}
122141
}

src/main/java/org/sonarsource/sonarqube/mcp/tools/analysis/AnalysisTool.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ public AnalysisTool(BackendService backendService, ServerApiProvider serverApiPr
5858
.addRequiredStringProperty(PROJECT_KEY_PROPERTY, "The SonarQube project key")
5959
.addRequiredStringProperty(SNIPPET_PROPERTY, "Code snippet or full file content")
6060
.addStringProperty(LANGUAGE_PROPERTY, "Language of the code snippet")
61+
.setReadOnlyHint()
6162
.build());
6263
this.backendService = backendService;
6364
this.serverApiProvider = serverApiProvider;

src/main/java/org/sonarsource/sonarqube/mcp/tools/analysis/AnalyzeFileListTool.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public AnalyzeFileListTool(SonarQubeIdeBridgeClient bridgeClient) {
3636
.setDescription("Analyze files in the current working directory using SonarQube for IDE. " +
3737
"This tool connects to a running SonarQube for IDE instance to perform code quality analysis on a list of files.")
3838
.addArrayProperty(FILE_ABSOLUTE_PATHS_PROPERTY, "string", "List of absolute file paths to analyze")
39+
.setReadOnlyHint()
3940
.build());
4041
this.bridgeClient = bridgeClient;
4142
}

src/main/java/org/sonarsource/sonarqube/mcp/tools/dependencyrisks/SearchDependencyRisksTool.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ public SearchDependencyRisksTool(ServerApiProvider serverApiProvider, SonarQubeV
4242
.addRequiredStringProperty(PROJECT_KEY_PROPERTY, "The project key")
4343
.addStringProperty(BRANCH_KEY_PROPERTY, "The branch key")
4444
.addStringProperty(PULL_REQUEST_KEY_PROPERTY, "The pull request key")
45+
.setReadOnlyHint()
4546
.build());
4647
this.serverApiProvider = serverApiProvider;
4748
this.sonarQubeVersionChecker = sonarQubeVersionChecker;

src/main/java/org/sonarsource/sonarqube/mcp/tools/enterprises/ListEnterprisesTool.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ private static McpSchema.Tool createToolDefinition() {
4141
.setDescription("List the enterprises available in SonarQube Cloud that you have access to. " +
4242
"Use this tool to discover enterprise IDs that can be used with other tools.")
4343
.addStringProperty(ENTERPRISE_KEY_PROPERTY, "Optional enterprise key to filter results")
44+
.setReadOnlyHint()
4445
.build();
4546
}
4647

src/main/java/org/sonarsource/sonarqube/mcp/tools/issues/SearchIssuesTool.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ public SearchIssuesTool(ServerApiProvider serverApiProvider) {
4242
.addArrayProperty(SEVERITIES_PROPERTY, "string", "An optional list of severities to filter by, separated by a comma. Possible values: INFO, LOW, MEDIUM, HIGH, BLOCKER")
4343
.addNumberProperty(PAGE_PROPERTY, "An optional page number. Defaults to 1.")
4444
.addNumberProperty(PAGE_SIZE_PROPERTY, "An optional page size. Must be greater than 0 and less than or equal to 500. Defaults to 100.")
45+
.setReadOnlyHint()
4546
.build());
4647
this.serverApiProvider = serverApiProvider;
4748
}

src/main/java/org/sonarsource/sonarqube/mcp/tools/languages/ListLanguagesTool.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ public ListLanguagesTool(ServerApiProvider serverApiProvider) {
3434
.setTitle("List Supported Languages in SonarQube")
3535
.setDescription("List all programming languages supported in this SonarQube instance")
3636
.addStringProperty(QUERY_PROPERTY, "Optional pattern to match language keys/names against")
37+
.setReadOnlyHint()
3738
.build());
3839
this.serverApiProvider = serverApiProvider;
3940
}

src/main/java/org/sonarsource/sonarqube/mcp/tools/measures/GetComponentMeasuresTool.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public GetComponentMeasuresTool(ServerApiProvider serverApiProvider) {
4141
.addStringProperty(BRANCH_PROPERTY, "The branch to analyze for measures")
4242
.addArrayProperty(METRIC_KEYS_PROPERTY, "string", "The metric keys to retrieve (e.g. ncloc, complexity, violations, coverage)")
4343
.addStringProperty(PULL_REQUEST_PROPERTY, "The pull request identifier to analyze for measures")
44+
.setReadOnlyHint()
4445
.build());
4546
this.serverApiProvider = serverApiProvider;
4647
}

src/main/java/org/sonarsource/sonarqube/mcp/tools/metrics/SearchMetricsTool.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public SearchMetricsTool(ServerApiProvider serverApiProvider) {
3636
.setDescription("Search for SonarQube metrics")
3737
.addNumberProperty(PAGE_PROPERTY, "1-based page number (default: 1)")
3838
.addNumberProperty(PAGE_SIZE_PROPERTY, "Page size. Must be greater than 0 and less than or equal to 500 (default: 100)")
39+
.setReadOnlyHint()
3940
.build());
4041
this.serverApiProvider = serverApiProvider;
4142
}

src/main/java/org/sonarsource/sonarqube/mcp/tools/portfolios/ListPortfoliosTool.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,9 @@ private static McpSchema.Tool createToolDefinition(boolean isSonarCloud) {
6565
.addNumberProperty(PAGE_SIZE_PROPERTY, "Page size, max 500 (default: 100)");
6666
}
6767

68-
return builder.build();
68+
return builder
69+
.setReadOnlyHint()
70+
.build();
6971
}
7072

7173
@Override

0 commit comments

Comments
 (0)