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 5c7fc962ee2 Improve ShardingSphere MCP prompt completions (#39019)
5c7fc962ee2 is described below

commit 5c7fc962ee278016886d6c2ea0a961a66f019b3d
Author: Liang Zhang <[email protected]>
AuthorDate: Mon Jul 6 15:32:24 2026 +0800

    Improve ShardingSphere MCP prompt completions (#39019)
    
    - add supported prompt completion targets for planning prompts
    - support storage unit completion aliases used by feature prompts
    - clarify execute_update as preview-or-execute side-effecting SQL
---
 .../provider/MetadataCompletionProvider.java         | 17 ++++++++++++-----
 .../mcp-descriptors/mcp-descriptor-core.yaml         |  6 ++++--
 .../provider/MetadataCompletionProviderTest.java     | 20 ++++++++++++++++++++
 .../capability/ServerCapabilitiesHandlerTest.java    |  4 +++-
 .../metadata/SearchMetadataToolHandlerTest.java      |  4 +++-
 .../mcp-descriptors/mcp-descriptor-broadcast.yaml    |  2 ++
 .../broadcast/BroadcastFeatureDefinitionTest.java    | 12 ++++++++++++
 .../mcp-descriptors/mcp-descriptor-encrypt.yaml      |  5 +++++
 .../encrypt/EncryptDescriptorContractTest.java       | 13 +++++++++++++
 .../mcp-descriptors/mcp-descriptor-mask.yaml         |  5 +++++
 .../mcp/feature/mask/MaskFeatureDefinitionTest.java  | 12 ++++++++++++
 .../mcp-descriptor-readwrite-splitting.yaml          |  4 ++++
 .../ReadwriteSplittingFeatureDefinitionTest.java     | 19 +++++++++++++++++++
 .../mcp-descriptors/mcp-descriptor-shadow.yaml       |  6 ++++++
 .../feature/shadow/ShadowDescriptorContractTest.java | 17 +++++++++++++++++
 .../mcp-descriptors/mcp-descriptor-sharding.yaml     |  6 ++++++
 .../sharding/ShardingDescriptorContractTest.java     | 20 ++++++++++++++++++++
 17 files changed, 163 insertions(+), 9 deletions(-)

diff --git 
a/mcp/core/src/main/java/org/apache/shardingsphere/mcp/core/completion/provider/MetadataCompletionProvider.java
 
b/mcp/core/src/main/java/org/apache/shardingsphere/mcp/core/completion/provider/MetadataCompletionProvider.java
index cd3961d6a5c..8a7a4bcddd5 100644
--- 
a/mcp/core/src/main/java/org/apache/shardingsphere/mcp/core/completion/provider/MetadataCompletionProvider.java
+++ 
b/mcp/core/src/main/java/org/apache/shardingsphere/mcp/core/completion/provider/MetadataCompletionProvider.java
@@ -47,6 +47,8 @@ import java.util.stream.Stream;
  */
 public final class MetadataCompletionProvider implements 
MCPCompletionProvider<MCPDatabaseHandlerContext> {
     
+    private static final Set<String> STORAGE_UNIT_ARGUMENTS = 
Set.of("storageUnit", "storage_unit", "write_storage_unit", 
"source_storage_unit", "shadow_storage_unit");
+    
     private static final Set<String> SUPPORTED_ARGUMENTS = Set.of("database", 
"schema", "table", "column", "index", "sequence", "storageUnit");
     
     private final GovernanceMetadataQueryService 
governanceMetadataQueryService = new GovernanceMetadataQueryService();
@@ -58,18 +60,23 @@ public final class MetadataCompletionProvider implements 
MCPCompletionProvider<M
     
     @Override
     public boolean supports(final MCPCompletionRequestContext requestContext) {
-        return SUPPORTED_ARGUMENTS.contains(requestContext.getArgumentName());
+        return 
SUPPORTED_ARGUMENTS.contains(canonicalizeArgumentName(requestContext.getArgumentName()));
     }
     
     @Override
     public MCPCompletionProviderResult complete(final 
MCPDatabaseHandlerContext handlerContext, final MCPCompletionRequestContext 
requestContext) {
+        String argumentName = 
canonicalizeArgumentName(requestContext.getArgumentName());
         Map<String, String> contextArguments = new 
LinkedHashMap<>(requestContext.getContextArguments());
-        Map<String, Object> inferredContextArguments = 
applyContextDefaults(handlerContext, requestContext.getArgumentName(), 
contextArguments);
-        Collection<String> missingContextArguments = 
createMissingContextArguments(requestContext.getArgumentName(), 
contextArguments);
+        Map<String, Object> inferredContextArguments = 
applyContextDefaults(handlerContext, argumentName, contextArguments);
+        Collection<String> missingContextArguments = 
createMissingContextArguments(argumentName, contextArguments);
         String nearestResourceUri = createNearestResourceUri(
-                missingContextArguments.isEmpty() ? 
requestContext.getArgumentName() : missingContextArguments.iterator().next(), 
contextArguments);
+                missingContextArguments.isEmpty() ? argumentName : 
missingContextArguments.iterator().next(), contextArguments);
         return new MCPCompletionProviderResult(
-                completeMetadata(handlerContext, 
requestContext.getArgumentName(), contextArguments), inferredContextArguments, 
missingContextArguments, nearestResourceUri);
+                completeMetadata(handlerContext, argumentName, 
contextArguments), inferredContextArguments, missingContextArguments, 
nearestResourceUri);
+    }
+    
+    private String canonicalizeArgumentName(final String argumentName) {
+        return STORAGE_UNIT_ARGUMENTS.contains(argumentName) ? "storageUnit" : 
argumentName;
     }
     
     private Map<String, Object> applyContextDefaults(final 
MCPDatabaseHandlerContext handlerContext, final String argumentName, final 
Map<String, String> contextArguments) {
diff --git 
a/mcp/core/src/main/resources/META-INF/shardingsphere-mcp/mcp-descriptors/mcp-descriptor-core.yaml
 
b/mcp/core/src/main/resources/META-INF/shardingsphere-mcp/mcp-descriptors/mcp-descriptor-core.yaml
index 9e71ad67b87..f22ce5313df 100644
--- 
a/mcp/core/src/main/resources/META-INF/shardingsphere-mcp/mcp-descriptors/mcp-descriptor-core.yaml
+++ 
b/mcp/core/src/main/resources/META-INF/shardingsphere-mcp/mcp-descriptors/mcp-descriptor-core.yaml
@@ -1073,6 +1073,8 @@ tools:
           has_more: false
           continuation_mode: none
           total_match_count: 1
+          returned_count: 1
+          truncated: false
           search_context:
             query: orders
             database: logic_db
@@ -1381,7 +1383,7 @@ tools:
         - TRANSACTION_CONTROL
         - SAVEPOINT
   - name: database_gateway_execute_update
-    title: Execute Update SQL
+    title: Preview or Execute Side-Effecting SQL
     description: >-
       Execute or preview exactly one supported SQL statement that may mutate 
data, metadata, rules, or transaction state.
       Use execution_mode=preview first when the side-effect scope has not been 
reviewed. Preview is classification-only,
@@ -1599,7 +1601,7 @@ tools:
                 - 1
               reason: Execute only after reviewing normalized_sql and 
side_effect_scope; preview did not validate runtime executability.
     annotations:
-      title: Execute Update SQL
+      title: Preview or Execute Side-Effecting SQL
       readOnlyHint: false
       destructiveHint: true
       idempotentHint: false
diff --git 
a/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/completion/provider/MetadataCompletionProviderTest.java
 
b/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/completion/provider/MetadataCompletionProviderTest.java
index d1ec00cc8be..fe53850783a 100644
--- 
a/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/completion/provider/MetadataCompletionProviderTest.java
+++ 
b/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/completion/provider/MetadataCompletionProviderTest.java
@@ -66,6 +66,15 @@ class MetadataCompletionProviderTest {
         assertTrue(new 
MetadataCompletionProvider().supports(createRequestContext("storageUnit", 
Map.of())));
     }
     
+    @Test
+    void assertSupportsStorageUnitAliases() {
+        MetadataCompletionProvider provider = new MetadataCompletionProvider();
+        assertTrue(provider.supports(createRequestContext("storage_unit", 
Map.of())));
+        
assertTrue(provider.supports(createRequestContext("write_storage_unit", 
Map.of())));
+        
assertTrue(provider.supports(createRequestContext("source_storage_unit", 
Map.of())));
+        
assertTrue(provider.supports(createRequestContext("shadow_storage_unit", 
Map.of())));
+    }
+    
     @Test
     void assertSupportsWithUnknownArgument() {
         assertFalse(new 
MetadataCompletionProvider().supports(createRequestContext("foo_value", 
Map.of())));
@@ -186,6 +195,17 @@ class MetadataCompletionProviderTest {
         assertThat(actual.getNearestResourceUri(), 
is("shardingsphere://databases/logic_db/storage-units"));
     }
     
+    @Test
+    void assertCompleteStorageUnitAlias() {
+        MCPFeatureQueryFacade queryFacade = mock(MCPFeatureQueryFacade.class);
+        when(queryFacade.query("logic_db", "", "SHOW STORAGE UNITS FROM 
logic_db")).thenReturn(List.of(Map.of("name", "write_ds")));
+        MCPCompletionProviderResult actual = new 
MetadataCompletionProvider().complete(createHandlerContext(mock(MCPMetadataQueryFacade.class),
 queryFacade),
+                createRequestContext("write_storage_unit", Map.of("database", 
"logic_db")));
+        assertCandidate(actual, "write_ds");
+        assertThat(actual.getMissingContextArguments(), is(List.of()));
+        assertThat(actual.getNearestResourceUri(), 
is("shardingsphere://databases/logic_db/storage-units"));
+    }
+    
     @Test
     void assertCompleteStorageUnitWithSingleDatabaseDefaulted() {
         MCPFeatureQueryFacade queryFacade = mock(MCPFeatureQueryFacade.class);
diff --git 
a/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/resource/handler/capability/ServerCapabilitiesHandlerTest.java
 
b/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/resource/handler/capability/ServerCapabilitiesHandlerTest.java
index fb64372c4bf..48d40c8bd39 100644
--- 
a/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/resource/handler/capability/ServerCapabilitiesHandlerTest.java
+++ 
b/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/resource/handler/capability/ServerCapabilitiesHandlerTest.java
@@ -256,8 +256,9 @@ class ServerCapabilitiesHandlerTest {
         
assertTrue(searchMetadataOutputProperties.containsKey("returned_count"));
         assertTrue(searchMetadataOutputProperties.containsKey("truncated"));
         
assertTrue(searchMetadataOutputProperties.containsKey("large_result_guidance"));
+        assertThat(getInputFieldNames(searchMetadataTool), 
is(List.of("database", "schema", "query", "object_types")));
         Map<?, ?> objectTypesSchema = findInputSchema(searchMetadataTool, 
"object_types");
-        assertTrue(((List<?>) ((Map<?, ?>) 
objectTypesSchema.get("items")).get("enum")).containsAll(List.of("database", 
"schema", "table", "view", "column", "index", "sequence")));
+        assertTrue(((List<?>) ((Map<?, ?>) 
objectTypesSchema.get("items")).get("enum")).containsAll(List.of("database", 
"schema", "table", "view", "column", "index", "storage_unit", "sequence")));
         Map<?, ?> validateRuntimeDatabaseTool = findTool(capabilities, 
"database_gateway_validate_runtime_database");
         Map<?, ?> validateRuntimeDatabaseOutputProperties = (Map<?, ?>) 
((Map<?, ?>) validateRuntimeDatabaseTool.get("outputSchema")).get("properties");
         assertThat(getInputFieldNames(validateRuntimeDatabaseTool), 
is(List.of("database")));
@@ -275,6 +276,7 @@ class ServerCapabilitiesHandlerTest {
         
assertTrue(executeUpdateOutputProperties.containsKey("preview_semantics"));
         
assertTrue(executeUpdateOutputProperties.containsKey("review_summary"));
         
assertFalse(executeUpdateOutputProperties.containsKey("approval_summary"));
+        assertThat(executeUpdateTool.get("title"), is("Preview or Execute 
Side-Effecting SQL"));
         assertTrue(((String) 
executeUpdateTool.get("description")).contains("Preview is classification-only, 
not a database dry run."));
         assertThat(findInputSchema(executeUpdateTool, 
"execution_mode").get("description"),
                 is("Required safety gate. Use preview to classify side effects 
without execution; preview is not a database dry run. Use execute only after 
reviewing the preview."));
diff --git 
a/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/tool/handler/metadata/SearchMetadataToolHandlerTest.java
 
b/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/tool/handler/metadata/SearchMetadataToolHandlerTest.java
index f0f645f65cd..78272eb2142 100644
--- 
a/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/tool/handler/metadata/SearchMetadataToolHandlerTest.java
+++ 
b/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/tool/handler/metadata/SearchMetadataToolHandlerTest.java
@@ -56,10 +56,10 @@ class SearchMetadataToolHandlerTest {
         MCPToolDescriptor actual = 
MCPDescriptorCatalogIndex.getRequiredToolDescriptor(new 
SearchMetadataToolHandler().getToolName());
         assertThat(actual.getName(), is("database_gateway_search_metadata"));
         assertThat(((Map<?, ?>) 
actual.getInputSchema().get("properties")).size(), is(4));
-        Map<?, ?> actualProperties = (Map<?, ?>) 
actual.getOutputSchema().get("properties");
         Map<?, ?> actualInputProperties = (Map<?, ?>) 
actual.getInputSchema().get("properties");
         Map<?, ?> actualObjectTypeItems = (Map<?, ?>) ((Map<?, ?>) 
actualInputProperties.get("object_types")).get("items");
         assertTrue(((List<?>) 
actualObjectTypeItems.get("enum")).contains("storage_unit"));
+        Map<?, ?> actualProperties = (Map<?, ?>) 
actual.getOutputSchema().get("properties");
         Map<?, ?> actualItems = (Map<?, ?>) ((Map<?, ?>) 
actualProperties.get("items")).get("items");
         Map<?, ?> actualItemProperties = (Map<?, ?>) 
actualItems.get("properties");
         assertTrue(actualItemProperties.containsKey("resource"));
@@ -170,6 +170,8 @@ class SearchMetadataToolHandlerTest {
             assertThat(actualPayload.get("total_match_count"), is(101));
             assertThat(actualPayload.get("returned_count"), is(100));
             assertTrue((Boolean) actualPayload.get("truncated"));
+            assertFalse((Boolean) actualPayload.get("has_more"));
+            assertThat(actualPayload.get("continuation_mode"), is("none"));
             Map<?, ?> actualLargeResultGuidance = (Map<?, ?>) 
actualPayload.get("large_result_guidance");
             assertThat(actualLargeResultGuidance.get("state"), 
is("metadata_search_result_truncated"));
             assertThat(actualLargeResultGuidance.get("threshold"), is(100));
diff --git 
a/mcp/features/broadcast/src/main/resources/META-INF/shardingsphere-mcp/mcp-descriptors/mcp-descriptor-broadcast.yaml
 
b/mcp/features/broadcast/src/main/resources/META-INF/shardingsphere-mcp/mcp-descriptors/mcp-descriptor-broadcast.yaml
index e923bf444d1..9134e875ab5 100644
--- 
a/mcp/features/broadcast/src/main/resources/META-INF/shardingsphere-mcp/mcp-descriptors/mcp-descriptor-broadcast.yaml
+++ 
b/mcp/features/broadcast/src/main/resources/META-INF/shardingsphere-mcp/mcp-descriptors/mcp-descriptor-broadcast.yaml
@@ -119,6 +119,8 @@ completionTargets:
     reference: plan_broadcast_rule
     arguments:
       - database
+      - table
+      - plan_id
     maxValues: 50
 
 resourceNavigation:
diff --git 
a/mcp/features/broadcast/src/test/java/org/apache/shardingsphere/mcp/feature/broadcast/BroadcastFeatureDefinitionTest.java
 
b/mcp/features/broadcast/src/test/java/org/apache/shardingsphere/mcp/feature/broadcast/BroadcastFeatureDefinitionTest.java
index 6d31440f8d0..a03133c4686 100644
--- 
a/mcp/features/broadcast/src/test/java/org/apache/shardingsphere/mcp/feature/broadcast/BroadcastFeatureDefinitionTest.java
+++ 
b/mcp/features/broadcast/src/test/java/org/apache/shardingsphere/mcp/feature/broadcast/BroadcastFeatureDefinitionTest.java
@@ -17,10 +17,15 @@
 
 package org.apache.shardingsphere.mcp.feature.broadcast;
 
+import 
org.apache.shardingsphere.mcp.support.descriptor.MCPCompletionTargetDescriptor;
+import 
org.apache.shardingsphere.mcp.support.descriptor.MCPDescriptorCatalogLoader;
 import org.junit.jupiter.api.Test;
 
+import java.util.List;
+
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 class BroadcastFeatureDefinitionTest {
     
@@ -33,4 +38,11 @@ class BroadcastFeatureDefinitionTest {
         assertThat(BroadcastFeatureDefinition.RULES_RESOURCE_URI, 
is("shardingsphere://features/broadcast/databases/{database}/rules"));
         assertThat(BroadcastFeatureDefinition.RULE_COUNT_RESOURCE_URI, 
is("shardingsphere://features/broadcast/databases/{database}/rule-count"));
     }
+    
+    @Test
+    void assertPromptCompletionArguments() {
+        MCPCompletionTargetDescriptor actual = 
MCPDescriptorCatalogLoader.load().getShardingSphereDescriptors().getCompletionTargetDescriptors().stream()
+                .filter(each -> "prompt".equals(each.getReferenceType()) && 
BroadcastFeatureDefinition.PLAN_PROMPT_NAME.equals(each.getReference())).findFirst().orElseThrow();
+        assertTrue(actual.getArguments().containsAll(List.of("database", 
"table", "plan_id")));
+    }
 }
diff --git 
a/mcp/features/encrypt/src/main/resources/META-INF/shardingsphere-mcp/mcp-descriptors/mcp-descriptor-encrypt.yaml
 
b/mcp/features/encrypt/src/main/resources/META-INF/shardingsphere-mcp/mcp-descriptors/mcp-descriptor-encrypt.yaml
index f54de39df40..0f6b6da6543 100644
--- 
a/mcp/features/encrypt/src/main/resources/META-INF/shardingsphere-mcp/mcp-descriptors/mcp-descriptor-encrypt.yaml
+++ 
b/mcp/features/encrypt/src/main/resources/META-INF/shardingsphere-mcp/mcp-descriptors/mcp-descriptor-encrypt.yaml
@@ -128,9 +128,14 @@ completionTargets:
   - referenceType: prompt
     reference: plan_encrypt_rule
     arguments:
+      - database
+      - schema
+      - table
+      - column
       - algorithm_type
       - assisted_query_algorithm_type
       - like_query_algorithm_type
+      - plan_id
     maxValues: 50
 resourceNavigation:
   - from: shardingsphere://features/encrypt/algorithms
diff --git 
a/mcp/features/encrypt/src/test/java/org/apache/shardingsphere/mcp/feature/encrypt/EncryptDescriptorContractTest.java
 
b/mcp/features/encrypt/src/test/java/org/apache/shardingsphere/mcp/feature/encrypt/EncryptDescriptorContractTest.java
index 8e84be13a2f..c4884a680cd 100644
--- 
a/mcp/features/encrypt/src/test/java/org/apache/shardingsphere/mcp/feature/encrypt/EncryptDescriptorContractTest.java
+++ 
b/mcp/features/encrypt/src/test/java/org/apache/shardingsphere/mcp/feature/encrypt/EncryptDescriptorContractTest.java
@@ -18,11 +18,13 @@
 package org.apache.shardingsphere.mcp.feature.encrypt;
 
 import org.apache.shardingsphere.mcp.api.tool.descriptor.MCPToolDescriptor;
+import 
org.apache.shardingsphere.mcp.support.descriptor.MCPCompletionTargetDescriptor;
 import org.apache.shardingsphere.mcp.support.descriptor.MCPDescriptorCatalog;
 import 
org.apache.shardingsphere.mcp.support.descriptor.MCPDescriptorCatalogLoader;
 import org.junit.jupiter.api.Test;
 
 import java.util.Collection;
+import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 
@@ -43,12 +45,23 @@ class EncryptDescriptorContractTest {
         assertTrue(actualProperties.containsKey("summary"));
     }
     
+    @Test
+    void assertPromptCompletionArguments() {
+        
assertCompletionTargetArguments(EncryptFeatureDefinition.PLAN_PROMPT_NAME, 
"database", "schema", "table", "column", "plan_id");
+    }
+    
     private MCPToolDescriptor findToolDescriptor() {
         MCPDescriptorCatalog catalog = MCPDescriptorCatalogLoader.load();
         return catalog.getProtocolDescriptors().getToolDescriptors().stream()
                 .filter(each -> 
EncryptFeatureDefinition.PLAN_TOOL_NAME.equals(each.getName())).findFirst().orElseThrow();
     }
     
+    private void assertCompletionTargetArguments(final String promptName, 
final String... expectedArguments) {
+        MCPCompletionTargetDescriptor actual = 
MCPDescriptorCatalogLoader.load().getShardingSphereDescriptors().getCompletionTargetDescriptors().stream()
+                .filter(each -> "prompt".equals(each.getReferenceType()) && 
promptName.equals(each.getReference())).findFirst().orElseThrow();
+        
assertTrue(actual.getArguments().containsAll(List.of(expectedArguments)));
+    }
+    
     private void assertEncryptDistSQLExampleValue(final Object value) {
         if (value instanceof Map) {
             assertEncryptDistSQLExampleMap((Map<?, ?>) value);
diff --git 
a/mcp/features/mask/src/main/resources/META-INF/shardingsphere-mcp/mcp-descriptors/mcp-descriptor-mask.yaml
 
b/mcp/features/mask/src/main/resources/META-INF/shardingsphere-mcp/mcp-descriptors/mcp-descriptor-mask.yaml
index 82b4d10f8b5..14572159980 100644
--- 
a/mcp/features/mask/src/main/resources/META-INF/shardingsphere-mcp/mcp-descriptors/mcp-descriptor-mask.yaml
+++ 
b/mcp/features/mask/src/main/resources/META-INF/shardingsphere-mcp/mcp-descriptors/mcp-descriptor-mask.yaml
@@ -120,7 +120,12 @@ completionTargets:
   - referenceType: prompt
     reference: plan_mask_rule
     arguments:
+      - database
+      - schema
+      - table
+      - column
       - algorithm_type
+      - plan_id
     maxValues: 50
 resourceNavigation:
   - from: shardingsphere://features/mask/algorithms
diff --git 
a/mcp/features/mask/src/test/java/org/apache/shardingsphere/mcp/feature/mask/MaskFeatureDefinitionTest.java
 
b/mcp/features/mask/src/test/java/org/apache/shardingsphere/mcp/feature/mask/MaskFeatureDefinitionTest.java
index b9bcada70ef..bf5a1070fbf 100644
--- 
a/mcp/features/mask/src/test/java/org/apache/shardingsphere/mcp/feature/mask/MaskFeatureDefinitionTest.java
+++ 
b/mcp/features/mask/src/test/java/org/apache/shardingsphere/mcp/feature/mask/MaskFeatureDefinitionTest.java
@@ -17,10 +17,15 @@
 
 package org.apache.shardingsphere.mcp.feature.mask;
 
+import 
org.apache.shardingsphere.mcp.support.descriptor.MCPCompletionTargetDescriptor;
+import 
org.apache.shardingsphere.mcp.support.descriptor.MCPDescriptorCatalogLoader;
 import org.junit.jupiter.api.Test;
 
+import java.util.List;
+
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 class MaskFeatureDefinitionTest {
     
@@ -33,4 +38,11 @@ class MaskFeatureDefinitionTest {
         assertThat(MaskFeatureDefinition.RULES_RESOURCE_URI, 
is("shardingsphere://features/mask/databases/{database}/rules"));
         assertThat(MaskFeatureDefinition.RULE_RESOURCE_URI, 
is("shardingsphere://features/mask/databases/{database}/tables/{table}/rules"));
     }
+    
+    @Test
+    void assertPromptCompletionArguments() {
+        MCPCompletionTargetDescriptor actual = 
MCPDescriptorCatalogLoader.load().getShardingSphereDescriptors().getCompletionTargetDescriptors().stream()
+                .filter(each -> "prompt".equals(each.getReferenceType()) && 
MaskFeatureDefinition.PLAN_PROMPT_NAME.equals(each.getReference())).findFirst().orElseThrow();
+        assertTrue(actual.getArguments().containsAll(List.of("database", 
"schema", "table", "column", "plan_id")));
+    }
 }
diff --git 
a/mcp/features/readwrite-splitting/src/main/resources/META-INF/shardingsphere-mcp/mcp-descriptors/mcp-descriptor-readwrite-splitting.yaml
 
b/mcp/features/readwrite-splitting/src/main/resources/META-INF/shardingsphere-mcp/mcp-descriptors/mcp-descriptor-readwrite-splitting.yaml
index fe8e45a8db7..8cb059e6478 100644
--- 
a/mcp/features/readwrite-splitting/src/main/resources/META-INF/shardingsphere-mcp/mcp-descriptors/mcp-descriptor-readwrite-splitting.yaml
+++ 
b/mcp/features/readwrite-splitting/src/main/resources/META-INF/shardingsphere-mcp/mcp-descriptors/mcp-descriptor-readwrite-splitting.yaml
@@ -221,12 +221,16 @@ completionTargets:
     reference: plan_readwrite_splitting_rule
     arguments:
       - database
+      - write_storage_unit
       - load_balancer_type
+      - plan_id
     maxValues: 50
   - referenceType: prompt
     reference: plan_readwrite_splitting_status
     arguments:
       - database
+      - storage_unit
+      - plan_id
     maxValues: 50
 resourceNavigation:
   - from: 
shardingsphere://features/readwrite-splitting/databases/{database}/rules
diff --git 
a/mcp/features/readwrite-splitting/src/test/java/org/apache/shardingsphere/mcp/feature/readwritesplitting/ReadwriteSplittingFeatureDefinitionTest.java
 
b/mcp/features/readwrite-splitting/src/test/java/org/apache/shardingsphere/mcp/feature/readwritesplitting/ReadwriteSplittingFeatureDefinitionTest.java
index 26bc7d14a21..af9af0f3883 100644
--- 
a/mcp/features/readwrite-splitting/src/test/java/org/apache/shardingsphere/mcp/feature/readwritesplitting/ReadwriteSplittingFeatureDefinitionTest.java
+++ 
b/mcp/features/readwrite-splitting/src/test/java/org/apache/shardingsphere/mcp/feature/readwritesplitting/ReadwriteSplittingFeatureDefinitionTest.java
@@ -17,10 +17,16 @@
 
 package org.apache.shardingsphere.mcp.feature.readwritesplitting;
 
+import 
org.apache.shardingsphere.mcp.support.descriptor.MCPCompletionTargetDescriptor;
+import org.apache.shardingsphere.mcp.support.descriptor.MCPDescriptorCatalog;
+import 
org.apache.shardingsphere.mcp.support.descriptor.MCPDescriptorCatalogLoader;
 import org.junit.jupiter.api.Test;
 
+import java.util.List;
+
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 class ReadwriteSplittingFeatureDefinitionTest {
     
@@ -29,4 +35,17 @@ class ReadwriteSplittingFeatureDefinitionTest {
         
assertThat(ReadwriteSplittingFeatureDefinition.RULE_WORKFLOW_KIND.getValue(), 
is("readwrite.rule"));
         
assertThat(ReadwriteSplittingFeatureDefinition.STATUS_WORKFLOW_KIND.getValue(), 
is("readwrite.status"));
     }
+    
+    @Test
+    void assertPromptCompletionArguments() {
+        MCPDescriptorCatalog catalog = MCPDescriptorCatalogLoader.load();
+        assertCompletionTargetArguments(catalog, 
ReadwriteSplittingFeatureDefinition.PLAN_RULE_PROMPT_NAME, "database", 
"write_storage_unit", "plan_id");
+        assertCompletionTargetArguments(catalog, 
ReadwriteSplittingFeatureDefinition.PLAN_STATUS_PROMPT_NAME, "database", 
"storage_unit", "plan_id");
+    }
+    
+    private void assertCompletionTargetArguments(final MCPDescriptorCatalog 
catalog, final String promptName, final String... expectedArguments) {
+        MCPCompletionTargetDescriptor actual = 
catalog.getShardingSphereDescriptors().getCompletionTargetDescriptors().stream()
+                .filter(each -> "prompt".equals(each.getReferenceType()) && 
promptName.equals(each.getReference())).findFirst().orElseThrow();
+        
assertTrue(actual.getArguments().containsAll(List.of(expectedArguments)));
+    }
 }
diff --git 
a/mcp/features/shadow/src/main/resources/META-INF/shardingsphere-mcp/mcp-descriptors/mcp-descriptor-shadow.yaml
 
b/mcp/features/shadow/src/main/resources/META-INF/shardingsphere-mcp/mcp-descriptors/mcp-descriptor-shadow.yaml
index 1448274f8e5..ec673f023c0 100644
--- 
a/mcp/features/shadow/src/main/resources/META-INF/shardingsphere-mcp/mcp-descriptors/mcp-descriptor-shadow.yaml
+++ 
b/mcp/features/shadow/src/main/resources/META-INF/shardingsphere-mcp/mcp-descriptors/mcp-descriptor-shadow.yaml
@@ -290,18 +290,24 @@ completionTargets:
     reference: plan_shadow_rule
     arguments:
       - database
+      - source_storage_unit
+      - shadow_storage_unit
+      - table
       - algorithm_type
+      - plan_id
     maxValues: 50
   - referenceType: prompt
     reference: plan_default_shadow_algorithm
     arguments:
       - database
       - algorithm_type
+      - plan_id
     maxValues: 50
   - referenceType: prompt
     reference: plan_shadow_algorithm_cleanup
     arguments:
       - database
+      - plan_id
     maxValues: 50
 resourceNavigation:
   - from: shardingsphere://features/shadow/databases/{database}/rules
diff --git 
a/mcp/features/shadow/src/test/java/org/apache/shardingsphere/mcp/feature/shadow/ShadowDescriptorContractTest.java
 
b/mcp/features/shadow/src/test/java/org/apache/shardingsphere/mcp/feature/shadow/ShadowDescriptorContractTest.java
index dfe1bec39d7..60aa42a5bd6 100644
--- 
a/mcp/features/shadow/src/test/java/org/apache/shardingsphere/mcp/feature/shadow/ShadowDescriptorContractTest.java
+++ 
b/mcp/features/shadow/src/test/java/org/apache/shardingsphere/mcp/feature/shadow/ShadowDescriptorContractTest.java
@@ -18,15 +18,18 @@
 package org.apache.shardingsphere.mcp.feature.shadow;
 
 import org.apache.shardingsphere.mcp.api.tool.descriptor.MCPToolDescriptor;
+import 
org.apache.shardingsphere.mcp.support.descriptor.MCPCompletionTargetDescriptor;
 import org.apache.shardingsphere.mcp.support.descriptor.MCPDescriptorCatalog;
 import 
org.apache.shardingsphere.mcp.support.descriptor.MCPDescriptorCatalogLoader;
 import org.junit.jupiter.api.Test;
 
+import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 class ShadowDescriptorContractTest {
     
@@ -41,7 +44,21 @@ class ShadowDescriptorContractTest {
         }
     }
     
+    @Test
+    void assertPromptCompletionArguments() {
+        MCPDescriptorCatalog catalog = MCPDescriptorCatalogLoader.load();
+        assertCompletionTargetArguments(catalog, 
ShadowFeatureDefinition.PLAN_RULE_PROMPT_NAME, "database", 
"source_storage_unit", "shadow_storage_unit", "plan_id");
+        assertCompletionTargetArguments(catalog, 
ShadowFeatureDefinition.PLAN_DEFAULT_ALGORITHM_PROMPT_NAME, "database", 
"algorithm_type", "plan_id");
+        assertCompletionTargetArguments(catalog, 
ShadowFeatureDefinition.PLAN_ALGORITHM_CLEANUP_PROMPT_NAME, "database", 
"plan_id");
+    }
+    
     private MCPToolDescriptor findTool(final MCPDescriptorCatalog catalog, 
final String toolName) {
         return 
catalog.getProtocolDescriptors().getToolDescriptors().stream().filter(each -> 
toolName.equals(each.getName())).findFirst().orElseThrow();
     }
+    
+    private void assertCompletionTargetArguments(final MCPDescriptorCatalog 
catalog, final String promptName, final String... expectedArguments) {
+        MCPCompletionTargetDescriptor actual = 
catalog.getShardingSphereDescriptors().getCompletionTargetDescriptors().stream()
+                .filter(each -> "prompt".equals(each.getReferenceType()) && 
promptName.equals(each.getReference())).findFirst().orElseThrow();
+        
assertTrue(actual.getArguments().containsAll(List.of(expectedArguments)));
+    }
 }
diff --git 
a/mcp/features/sharding/src/main/resources/META-INF/shardingsphere-mcp/mcp-descriptors/mcp-descriptor-sharding.yaml
 
b/mcp/features/sharding/src/main/resources/META-INF/shardingsphere-mcp/mcp-descriptors/mcp-descriptor-sharding.yaml
index 05a98b08685..c0cc64fb2d2 100644
--- 
a/mcp/features/sharding/src/main/resources/META-INF/shardingsphere-mcp/mcp-descriptors/mcp-descriptor-sharding.yaml
+++ 
b/mcp/features/sharding/src/main/resources/META-INF/shardingsphere-mcp/mcp-descriptors/mcp-descriptor-sharding.yaml
@@ -530,34 +530,40 @@ completionTargets:
     arguments:
       - database
       - algorithm_type
+      - plan_id
     maxValues: 50
   - referenceType: prompt
     reference: plan_sharding_table_reference_rule
     arguments:
       - database
+      - plan_id
     maxValues: 50
   - referenceType: prompt
     reference: plan_sharding_default_strategy
     arguments:
       - database
       - algorithm_type
+      - plan_id
     maxValues: 50
   - referenceType: prompt
     reference: plan_sharding_key_generator
     arguments:
       - database
       - key_generator_type
+      - plan_id
     maxValues: 50
   - referenceType: prompt
     reference: plan_sharding_key_generate_strategy
     arguments:
       - database
       - key_generator_type
+      - plan_id
     maxValues: 50
   - referenceType: prompt
     reference: plan_sharding_rule_component_cleanup
     arguments:
       - database
+      - plan_id
     maxValues: 50
 resourceNavigation:
   - from: shardingsphere://features/sharding/algorithm-plugins
diff --git 
a/mcp/features/sharding/src/test/java/org/apache/shardingsphere/mcp/feature/sharding/ShardingDescriptorContractTest.java
 
b/mcp/features/sharding/src/test/java/org/apache/shardingsphere/mcp/feature/sharding/ShardingDescriptorContractTest.java
index 1d3d30da93d..82a11750c2c 100644
--- 
a/mcp/features/sharding/src/test/java/org/apache/shardingsphere/mcp/feature/sharding/ShardingDescriptorContractTest.java
+++ 
b/mcp/features/sharding/src/test/java/org/apache/shardingsphere/mcp/feature/sharding/ShardingDescriptorContractTest.java
@@ -18,15 +18,18 @@
 package org.apache.shardingsphere.mcp.feature.sharding;
 
 import org.apache.shardingsphere.mcp.api.tool.descriptor.MCPToolDescriptor;
+import 
org.apache.shardingsphere.mcp.support.descriptor.MCPCompletionTargetDescriptor;
 import org.apache.shardingsphere.mcp.support.descriptor.MCPDescriptorCatalog;
 import 
org.apache.shardingsphere.mcp.support.descriptor.MCPDescriptorCatalogLoader;
 import org.junit.jupiter.api.Test;
 
+import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 class ShardingDescriptorContractTest {
     
@@ -44,7 +47,24 @@ class ShardingDescriptorContractTest {
         }
     }
     
+    @Test
+    void assertPromptCompletionArguments() {
+        MCPDescriptorCatalog catalog = MCPDescriptorCatalogLoader.load();
+        assertCompletionTargetArguments(catalog, 
ShardingFeatureDefinition.PLAN_TABLE_RULE_PROMPT_NAME, "database", 
"algorithm_type", "plan_id");
+        assertCompletionTargetArguments(catalog, 
ShardingFeatureDefinition.PLAN_TABLE_REFERENCE_PROMPT_NAME, "database", 
"plan_id");
+        assertCompletionTargetArguments(catalog, 
ShardingFeatureDefinition.PLAN_DEFAULT_STRATEGY_PROMPT_NAME, "database", 
"algorithm_type", "plan_id");
+        assertCompletionTargetArguments(catalog, 
ShardingFeatureDefinition.PLAN_KEY_GENERATOR_PROMPT_NAME, "database", 
"key_generator_type", "plan_id");
+        assertCompletionTargetArguments(catalog, 
ShardingFeatureDefinition.PLAN_KEY_GENERATE_STRATEGY_PROMPT_NAME, "database", 
"key_generator_type", "plan_id");
+        assertCompletionTargetArguments(catalog, 
ShardingFeatureDefinition.PLAN_COMPONENT_CLEANUP_PROMPT_NAME, "database", 
"plan_id");
+    }
+    
     private MCPToolDescriptor findTool(final MCPDescriptorCatalog catalog, 
final String toolName) {
         return 
catalog.getProtocolDescriptors().getToolDescriptors().stream().filter(each -> 
toolName.equals(each.getName())).findFirst().orElseThrow();
     }
+    
+    private void assertCompletionTargetArguments(final MCPDescriptorCatalog 
catalog, final String promptName, final String... expectedArguments) {
+        MCPCompletionTargetDescriptor actual = 
catalog.getShardingSphereDescriptors().getCompletionTargetDescriptors().stream()
+                .filter(each -> "prompt".equals(each.getReferenceType()) && 
promptName.equals(each.getReference())).findFirst().orElseThrow();
+        
assertTrue(actual.getArguments().containsAll(List.of(expectedArguments)));
+    }
 }


Reply via email to