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)));
+ }
}