This is an automated email from the ASF dual-hosted git repository.
terrymanu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git
The following commit(s) were added to refs/heads/master by this push:
new 12e9129f148 Strengthen MCP next action example validation (#39001)
12e9129f148 is described below
commit 12e9129f148fb30b943dfb671d616f68d991fced
Author: Liang Zhang <[email protected]>
AuthorDate: Sun Jul 5 10:46:15 2026 +0800
Strengthen MCP next action example validation (#39001)
---
.../support/descriptor/MCPToolOutputSchemaValidator.java | 15 +++++++++++++++
.../descriptor/MCPDescriptorCatalogValidatorTest.java | 9 +++++++++
.../mcp-descriptors/mcp-descriptor-test-planning.yaml | 2 ++
3 files changed, 26 insertions(+)
diff --git
a/mcp/support/src/main/java/org/apache/shardingsphere/mcp/support/descriptor/MCPToolOutputSchemaValidator.java
b/mcp/support/src/main/java/org/apache/shardingsphere/mcp/support/descriptor/MCPToolOutputSchemaValidator.java
index f70177f19e6..cdd38749f76 100644
---
a/mcp/support/src/main/java/org/apache/shardingsphere/mcp/support/descriptor/MCPToolOutputSchemaValidator.java
+++
b/mcp/support/src/main/java/org/apache/shardingsphere/mcp/support/descriptor/MCPToolOutputSchemaValidator.java
@@ -40,6 +40,8 @@ public final class MCPToolOutputSchemaValidator {
private static final Map<String, Collection<String>>
NEXT_ACTION_ALLOWED_FIELDS = createNextActionAllowedFields();
+ private static final Map<String, Collection<String>>
NEXT_ACTION_REQUIRED_FIELDS = createNextActionRequiredFields();
+
private static final Collection<String> NEXT_ACTION_SCHEMA_ALLOWED_FIELDS
= createNextActionSchemaAllowedFields();
private static final Collection<String> MODEL_CRITICAL_HINT_FIELDS =
List.of(
@@ -64,6 +66,15 @@ public final class MCPToolOutputSchemaValidator {
"terminal", Set.of("order", "type", "title", "reason",
"depends_on"));
}
+ private static Map<String, Collection<String>>
createNextActionRequiredFields() {
+ return Map.of(
+ "resource_read", Set.of("order", "type", "title",
"resource_uri"),
+ "tool_call", Set.of("order", "type", "title", "tool_name",
"arguments"),
+ "completion", Set.of("order", "type", "title", "ref",
"argument"),
+ "ask_user", Set.of("order", "type", "title", "question"),
+ "terminal", Set.of("order", "type", "title"));
+ }
+
private static Collection<String> createNextActionSchemaAllowedFields() {
Set<String> result = new HashSet<>();
for (Collection<String> each : NEXT_ACTION_ALLOWED_FIELDS.values()) {
@@ -199,6 +210,10 @@ public final class MCPToolOutputSchemaValidator {
Collection<String> allowedFields =
NEXT_ACTION_ALLOWED_FIELDS.get(type);
ShardingSpherePreconditions.checkState(null != allowedFields,
() -> new IllegalStateException(String.format("Tool `%s`
next_actions example uses unknown type `%s`.", descriptor.getName(), type)));
+ for (String each : NEXT_ACTION_REQUIRED_FIELDS.get(type)) {
+ ShardingSpherePreconditions.checkState(action.containsKey(each),
+ () -> new IllegalStateException(String.format("Tool `%s`
next_actions example `%s` must contain `%s`.", descriptor.getName(), type,
each)));
+ }
for (Object each : action.keySet()) {
String fieldName = String.valueOf(each);
ShardingSpherePreconditions.checkState(allowedFields.contains(fieldName),
diff --git
a/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/descriptor/MCPDescriptorCatalogValidatorTest.java
b/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/descriptor/MCPDescriptorCatalogValidatorTest.java
index 6d8ee4833af..dccc391cfe2 100644
---
a/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/descriptor/MCPDescriptorCatalogValidatorTest.java
+++
b/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/descriptor/MCPDescriptorCatalogValidatorTest.java
@@ -136,6 +136,15 @@ class MCPDescriptorCatalogValidatorTest {
"Tool `database_gateway_test_tool` next_actions example
`tool_call` contains unsupported field `extra_context`.");
}
+ @Test
+ void assertValidateRejectsMissingNextActionExampleField() {
+ assertValidationError(createCatalog(List.of(),
List.of(createToolDescriptor(
+ "database_gateway_test_tool", new MCPToolAnnotations("Test
Tool", true, false, true, true),
+ createOutputSchema(Map.of("next_actions",
createNextActionsSchema()), List.of(Map.of("next_actions", List.of(
+ Map.of("order", 1, "type", "tool_call", "title",
"Retry", "tool_name", "database_gateway_test_tool")))))))),
+ "Tool `database_gateway_test_tool` next_actions example
`tool_call` must contain `arguments`.");
+ }
+
@Test
void
assertValidateAcceptsFeatureOwnedToolDescriptorWithoutExtensionMarker() {
assertDoesNotThrow(() ->
MCPDescriptorCatalogValidator.validate(createCatalog(List.of(),
List.of(createToolDescriptor(
diff --git
a/mcp/support/src/test/resources/META-INF/shardingsphere-mcp/mcp-descriptors/mcp-descriptor-test-planning.yaml
b/mcp/support/src/test/resources/META-INF/shardingsphere-mcp/mcp-descriptors/mcp-descriptor-test-planning.yaml
index 24cb18c83b3..7a70c2e7334 100644
---
a/mcp/support/src/test/resources/META-INF/shardingsphere-mcp/mcp-descriptors/mcp-descriptor-test-planning.yaml
+++
b/mcp/support/src/test/resources/META-INF/shardingsphere-mcp/mcp-descriptors/mcp-descriptor-test-planning.yaml
@@ -195,6 +195,8 @@ tools:
- order: 1
type: tool_call
title: Call database_gateway_apply_workflow
+ tool_name: database_gateway_apply_workflow
+ arguments: {}
reason: Preview generated workflow artifacts.
annotations:
title: Plan Encrypt Rule