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 515df2adbf7 Improve MCP workflow continuation payloads (#39016)
515df2adbf7 is described below

commit 515df2adbf78bd72c6531617bb2bf153d68576b4
Author: Liang Zhang <[email protected]>
AuthorDate: Mon Jul 6 09:26:45 2026 +0800

    Improve MCP workflow continuation payloads (#39016)
    
    - Add model-facing summary fields to workflow planning, apply and 
validation responses
    - Return structured validation recovery next actions
    - Align MCP guidance, descriptors, docs and descriptor validators with the 
workflow contract
---
 .../content/reference/mcp/protocol-surface.cn.md   |  4 ++++
 .../content/reference/mcp/protocol-surface.en.md   |  4 ++++
 .../shardingsphere-mcp/developer-appendix.cn.md    |  5 +++++
 .../shardingsphere-mcp/developer-appendix.en.md    |  5 +++++
 .../features/plugin-workflow.cn.md                 |  4 ++++
 .../features/plugin-workflow.en.md                 |  4 ++++
 .../workflow/WorkflowApplyResponseBuilder.java     | 24 ++++++++++++++++++++--
 .../workflow/WorkflowApplyResponseBuilderTest.java |  3 +++
 .../mcp-descriptors/mcp-descriptor-broadcast.yaml  |  4 ++++
 .../mcp-descriptors/mcp-descriptor-encrypt.yaml    |  4 ++++
 .../encrypt/EncryptDescriptorContractTest.java     |  8 ++++++++
 .../mcp-descriptors/mcp-descriptor-mask.yaml       |  4 ++++
 .../mcp-descriptor-readwrite-splitting.yaml        |  5 +++++
 .../mcp-descriptors/mcp-descriptor-shadow.yaml     |  6 ++++++
 .../mcp-descriptors/mcp-descriptor-sharding.yaml   |  2 ++
 .../descriptor/MCPGuidancePayloadBuilder.java      |  7 +++++++
 .../MCPToolDescriptorCatalogValidator.java         |  6 +++---
 .../MCPToolDescriptorValidationUtils.java          |  2 +-
 .../service/WorkflowPlanPayloadBuilder.java        | 18 +++++++++++++++-
 .../service/WorkflowValidationSupport.java         | 22 ++++++++++++++++++--
 .../mcp-descriptors/mcp-descriptor-support.yaml    |  8 ++++++++
 .../descriptor/MCPDescriptorCatalogLoaderTest.java |  4 ++--
 .../MCPDescriptorCatalogValidatorTest.java         |  7 ++++---
 .../descriptor/MCPGuidancePayloadBuilderTest.java  | 10 ++++++++-
 .../MCPToolDescriptorValidationUtilsTest.java      |  2 +-
 .../service/WorkflowPlanPayloadBuilderTest.java    |  3 +++
 .../service/WorkflowValidationSupportTest.java     |  5 +++++
 .../mcp-descriptor-test-planning.yaml              |  4 ++++
 28 files changed, 168 insertions(+), 16 deletions(-)

diff --git a/docs/document/content/reference/mcp/protocol-surface.cn.md 
b/docs/document/content/reference/mcp/protocol-surface.cn.md
index 30e5413332d..f2a3ff34f64 100644
--- a/docs/document/content/reference/mcp/protocol-surface.cn.md
+++ b/docs/document/content/reference/mcp/protocol-surface.cn.md
@@ -201,6 +201,8 @@ Feature resources:
 
 Completions 用于补全运行时名称、metadata identifier、算法和当前 session 中的 workflow `plan_id`。
 Client 应在选择不确定的 database、schema、table、column、algorithm 或 `plan_id` 前调用 
`completion/complete`,或读取最近的 MCP resource。
+当 completion 响应包含 meta `next_actions` 时,client 应先遵循这些动作,再猜测取值或切换到其他 tool。
+重试 completion 前,可通过 `resources/templates/list` 发现最近 resource 所需的 URI 变量,并补齐上下文。
 
 ## 响应与恢复
 
@@ -220,5 +222,7 @@ Client 应在选择不确定的 database、schema、table、column、algorithm 
 
 可恢复错误 payload 保留 `message`,并增加 `recovery` 提示。
 常见恢复场景包括缺失参数、不支持的 tool/resource、非法枚举、workflow 状态错误和 SQL tool 选错。
+需要继续操作的模型可见业务 payload 会包含顶层 `summary` 和结构化 `next_actions`。
+Workflow 规划、执行、人工执行包导出和校验响应使用这些字段,引导下一次 tool call、用户补问、resource 
read、completion call 或终止。
 
 JSON-RPC 数字错误码属于 MCP 协议错误契约。
diff --git a/docs/document/content/reference/mcp/protocol-surface.en.md 
b/docs/document/content/reference/mcp/protocol-surface.en.md
index d1b5371eb8f..5a581e75b31 100644
--- a/docs/document/content/reference/mcp/protocol-surface.en.md
+++ b/docs/document/content/reference/mcp/protocol-surface.en.md
@@ -201,6 +201,8 @@ Feature resources:
 
 Completions suggest runtime names, metadata identifiers, algorithms, and 
workflow `plan_id` values in the current session.
 Before choosing uncertain database, schema, table, column, algorithm, or 
`plan_id` values, clients should call `completion/complete` or read the nearest 
MCP resource.
+When a completion response includes meta `next_actions`, clients should follow 
those actions before guessing a value or switching to another tool.
+Use `resources/templates/list` to discover URI variables for the nearest 
resource before retrying completion with additional context.
 
 ## Responses and recovery
 
@@ -220,5 +222,7 @@ Large-result payloads use:
 
 Recoverable error payloads keep `message` and add `recovery` hints.
 Common recovery cases include missing arguments, unsupported tools or 
resources, invalid enum values, workflow state errors, and unsafe SQL tool 
selection.
+Model-facing business payloads that require continuation include a top-level 
`summary` and structured `next_actions`.
+Workflow planning, apply, manual-only export, and validation responses use 
these fields to guide the next tool call, user question, resource read, 
completion call, or terminal stop.
 
 JSON-RPC numeric error codes are the MCP protocol error contract.
diff --git 
a/docs/document/content/user-manual/shardingsphere-mcp/developer-appendix.cn.md 
b/docs/document/content/user-manual/shardingsphere-mcp/developer-appendix.cn.md
index 4e7b370531b..70e94741cd9 100644
--- 
a/docs/document/content/user-manual/shardingsphere-mcp/developer-appendix.cn.md
+++ 
b/docs/document/content/user-manual/shardingsphere-mcp/developer-appendix.cn.md
@@ -49,6 +49,9 @@ STDIO 示例:
 | `shardingsphere://capabilities`                      | 
运行时数据库、连接目标、功能插件和副作用边界。      | 判断当前 MCP Server 可用于哪些数据库任务。 |
 | `shardingsphere://databases/{database}/capabilities` | 指定运行时数据库的 
SQL、事务、模式和元数据对象能力。 | 判断某个数据库的可用操作和限制。            |
 
+当 client 无法确定 database、schema、table、column、algorithm、storage unit 或 workflow 
`plan_id` 时,应一次只针对一个参数调用 `completion/complete`。
+如果 completion 返回缺少上下文或没有候选值,应遵循返回 meta 中的 `next_actions`;这些动作通常会指向重试补全前需要读取的最近 
resource 或 resource template。
+
 ## 资源
 
 | 资源 URI 或模板                                                                   
            | 用途                                                           |
@@ -74,6 +77,8 @@ STDIO 示例:
 | 
`shardingsphere://databases/{database}/schemas/{schema}/views/{view}/columns/{column}`
   | 读取一个视图列的详情。                                                  |
 | `shardingsphere://workflows/{plan_id}`                                       
            | 查看当前治理变更计划、补问信息、变更产物和下一步动作。                                  |
 
+Workflow resources 和 workflow tools 会包含简短的 `summary` 以及结构化 `next_actions`,让 
client 不必先读取所有嵌套字段,也能继续预览、执行、人工执行、校验或恢复。
+
 ## 工具
 
 | 工具                                             | 用途                          
               | 副作用                                          |
diff --git 
a/docs/document/content/user-manual/shardingsphere-mcp/developer-appendix.en.md 
b/docs/document/content/user-manual/shardingsphere-mcp/developer-appendix.en.md
index 50d5dbb1b6f..8bb1ad9960b 100644
--- 
a/docs/document/content/user-manual/shardingsphere-mcp/developer-appendix.en.md
+++ 
b/docs/document/content/user-manual/shardingsphere-mcp/developer-appendix.en.md
@@ -49,6 +49,9 @@ Replace `/path/to/apache-shardingsphere-mcp` with the actual 
distribution direct
 | `shardingsphere://capabilities`                      | Runtime databases, 
connection targets, feature plugins, and side-effect boundaries.           | 
Determine which database tasks the current MCP Server supports.          |
 | `shardingsphere://databases/{database}/capabilities` | SQL, transaction, 
schema, and metadata-object capabilities of the specified runtime database. | 
Determine available operations and limits for one database.              |
 
+When a client cannot choose a database, schema, table, column, algorithm, 
storage unit, or workflow `plan_id`, call `completion/complete` for one 
argument at a time.
+If completion reports missing context or no candidates, follow the returned 
meta `next_actions`; those actions usually point to the nearest resource or 
resource template to read before retrying completion.
+
 ## Resources
 
 | Resource URI or template                                                     
            | Purpose                                                           
                                                                         |
@@ -74,6 +77,8 @@ Replace `/path/to/apache-shardingsphere-mcp` with the actual 
distribution direct
 | 
`shardingsphere://databases/{database}/schemas/{schema}/views/{view}/columns/{column}`
   | Reads one view column.                                                     
                                                                |
 | `shardingsphere://workflows/{plan_id}`                                       
            | Reads the current governance change plan, clarification 
questions, artifacts, and next actions.                                         
   |
 
+Workflow resources and workflow tools include a short `summary` plus 
structured `next_actions` so clients can continue preview, apply, manual 
execution, validation, or recovery without reading every nested field first.
+
 ## Tools
 
 | Tool                                           | Purpose                     
                                                                                
             | Side effect                                                      
                          |
diff --git 
a/docs/document/content/user-manual/shardingsphere-mcp/features/plugin-workflow.cn.md
 
b/docs/document/content/user-manual/shardingsphere-mcp/features/plugin-workflow.cn.md
index 9a143fae23e..5eff0046ac3 100644
--- 
a/docs/document/content/user-manual/shardingsphere-mcp/features/plugin-workflow.cn.md
+++ 
b/docs/document/content/user-manual/shardingsphere-mcp/features/plugin-workflow.cn.md
@@ -32,11 +32,15 @@ weight = 1
 
 面向模型的规划响应可能包含:
 
+- `summary`:简短的模型可读状态摘要,说明计划需要补充信息、可以预览,或已经失败。
 - `algorithm_recommendations`:根据 Proxy 可见插件目录或用户显式输入选择的候选算法。
 - `property_requirements`:所选算法的必填或可选属性;缺少必填属性时,workflow 会保持在澄清状态,而不是生成不安全产物。
 - `resources_to_read` 和 `next_actions`:继续 workflow 所需的资源和工具导航提示。
 - `distsql_artifacts`:在当前功能插件边界内生成的可审查规则 DistSQL。
 
+预览、执行、人工执行包导出和校验响应也会返回 `summary` 和 `next_actions`。
+Client 应优先遵循这些字段,而不是自行猜测替代调用,或向用户询问 payload 中已经包含的信息。
+
 ## 变更执行选择
 
 | 用户说法         | 用户会得到什么           | 关注点                    |
diff --git 
a/docs/document/content/user-manual/shardingsphere-mcp/features/plugin-workflow.en.md
 
b/docs/document/content/user-manual/shardingsphere-mcp/features/plugin-workflow.en.md
index 649c635c04c..67649b6dc65 100644
--- 
a/docs/document/content/user-manual/shardingsphere-mcp/features/plugin-workflow.en.md
+++ 
b/docs/document/content/user-manual/shardingsphere-mcp/features/plugin-workflow.en.md
@@ -32,11 +32,15 @@ Use preview before execution when the user needs one more 
confirmation step.
 
 Model-facing planning responses may include:
 
+- `summary`: a short model-facing status line that tells whether the plan 
needs clarification, is ready for preview, or failed.
 - `algorithm_recommendations`: candidate algorithms selected from 
Proxy-visible plugin catalogs or explicit user input.
 - `property_requirements`: required or optional properties for the selected 
algorithms. Missing required properties keep the workflow in clarification 
instead of generating unsafe artifacts.
 - `resources_to_read` and `next_actions`: resource and tool navigation hints 
for continuing the workflow.
 - `distsql_artifacts`: reviewable rule DistSQL generated inside the current 
feature plugin boundary.
 
+Preview, apply, manual-only export, and validation responses also return 
`summary` and `next_actions`.
+Clients should follow these fields before inventing a replacement call or 
asking the user for information already present in the payload.
+
 ## Change Execution Choices
 
 | User wording                             | What users receive                
                         | Focus                                                
                                       |
diff --git 
a/mcp/core/src/main/java/org/apache/shardingsphere/mcp/core/workflow/WorkflowApplyResponseBuilder.java
 
b/mcp/core/src/main/java/org/apache/shardingsphere/mcp/core/workflow/WorkflowApplyResponseBuilder.java
index 1b896b37860..9132b122e1a 100644
--- 
a/mcp/core/src/main/java/org/apache/shardingsphere/mcp/core/workflow/WorkflowApplyResponseBuilder.java
+++ 
b/mcp/core/src/main/java/org/apache/shardingsphere/mcp/core/workflow/WorkflowApplyResponseBuilder.java
@@ -62,8 +62,9 @@ public final class WorkflowApplyResponseBuilder {
                                      final Collection<String> executedDdl, 
final Collection<String> executedDistSql, final Collection<String> 
skippedArtifacts,
                                      final Map<String, Object> 
manualArtifactPackage) {
         String planId = snapshot.getPlanId();
-        Map<String, Object> result = new LinkedHashMap<>(16, 1F);
+        Map<String, Object> result = new LinkedHashMap<>(24, 1F);
         result.put("response_mode", resolveResponseMode(status, 
executionMode));
+        result.put(MCPPayloadFieldNames.SUMMARY, createSummary(planId, status, 
executionMode, issues, executedDdl, executedDistSql));
         result.put(WorkflowFieldNames.PLAN_ID, planId);
         result.put("status", status);
         result.put(WorkflowFieldNames.EXECUTION_MODE, executionMode);
@@ -103,7 +104,9 @@ public final class WorkflowApplyResponseBuilder {
         result.put("would_apply", false);
         result.put("preview_artifacts", previewArtifacts);
         result.put("review_focus", 
createPreviewReviewFocus(applyExecutionMode, previewArtifacts));
-        result.put("review_summary", createReviewSummary(previewArtifacts));
+        String reviewSummary = createReviewSummary(previewArtifacts);
+        result.put(MCPPayloadFieldNames.SUMMARY, reviewSummary);
+        result.put("review_summary", reviewSummary);
         result.put("argument_provenance", createPreviewArgumentProvenance());
         result.put(MCPPayloadFieldNames.NEXT_ACTIONS, 
createPreviewNextActions(snapshot, applyExecutionMode, previewArtifacts));
         return result;
@@ -119,6 +122,23 @@ public final class WorkflowApplyResponseBuilder {
         return WorkflowLifecycle.STATUS_COMPLETED.equals(status) ? 
MCPResponseMode.EXECUTED : MCPResponseMode.TERMINAL;
     }
     
+    private String createSummary(final String planId, final String status, 
final String executionMode, final Collection<Map<String, Object>> issues,
+                                 final Collection<String> executedDdl, final 
Collection<String> executedDistSql) {
+        if (EXECUTION_MODE_PREVIEW.equals(executionMode)) {
+            return String.format("Workflow apply preview is ready for plan 
`%s`.", planId);
+        }
+        if (WorkflowLifecycle.STATUS_COMPLETED.equals(status)) {
+            return String.format("Workflow apply completed for plan `%s` with 
%d applied artifact(s).", planId, executedDdl.size() + executedDistSql.size());
+        }
+        if (WorkflowLifecycle.STATUS_AWAITING_MANUAL_EXECUTION.equals(status)) 
{
+            return String.format("Workflow apply exported manual artifacts for 
plan `%s`; external execution is required before validation.", planId);
+        }
+        if (WorkflowLifecycle.STATUS_FAILED.equals(status)) {
+            return String.format("Workflow apply failed for plan `%s` with %d 
issue(s).", planId, issues.size());
+        }
+        return String.format("Workflow apply returned status `%s` for plan 
`%s`.", status, planId);
+    }
+    
     private List<Map<String, Object>> createPreviewArtifacts(final 
Collection<WorkflowArtifactBundle.ExecutableWorkflowArtifact> 
executableArtifacts) {
         return 
executableArtifacts.stream().map(this::createPreviewArtifact).toList();
     }
diff --git 
a/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/workflow/WorkflowApplyResponseBuilderTest.java
 
b/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/workflow/WorkflowApplyResponseBuilderTest.java
index 0baff20ba74..db294d199ad 100644
--- 
a/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/workflow/WorkflowApplyResponseBuilderTest.java
+++ 
b/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/workflow/WorkflowApplyResponseBuilderTest.java
@@ -42,6 +42,7 @@ class WorkflowApplyResponseBuilderTest {
                         "CREATE MASK RULE orders", true));
         Map<String, Object> actual = new 
WorkflowApplyResponseBuilder().buildPreviewResponse(createSnapshot("encrypt.table"),
 executableArtifacts, "review-then-execute", Map.of());
         assertThat(actual.get("response_mode"), is("preview"));
+        assertThat(actual.get("summary"), is("Previewed 2 workflow artifacts 
with side-effect scope physical-structure, rule-metadata. Nothing has been 
applied."));
         assertThat(actual.get("plan_id"), is("plan-1"));
         assertThat(actual.get("status"), is("preview"));
         assertThat(actual.get("execution_mode"), is("preview"));
@@ -60,6 +61,7 @@ class WorkflowApplyResponseBuilderTest {
         Map<String, Object> actual = new 
WorkflowApplyResponseBuilder().build(createSnapshot("encrypt.table"), 
WorkflowLifecycle.STATUS_COMPLETED, "review-then-execute",
                 List.of(), List.of(), List.of("ALTER TABLE orders ADD COLUMN 
phone_mask VARCHAR(64)"), List.of("CREATE ENCRYPT RULE orders"), List.of(), 
Map.of());
         assertThat(actual.get("response_mode"), is("executed"));
+        assertThat(actual.get("summary"), is("Workflow apply completed for 
plan `plan-1` with 2 applied artifact(s)."));
         assertThat(actual.get("executed_ddl"), is(List.of("ALTER TABLE orders 
ADD COLUMN phone_mask VARCHAR(64)")));
         assertThat(actual.get("executed_distsql"), is(List.of("CREATE ENCRYPT 
RULE orders")));
         assertThat(actual.get("applied_artifacts"), is(List.of("ALTER TABLE 
orders ADD COLUMN phone_mask VARCHAR(64)", "CREATE ENCRYPT RULE orders")));
@@ -75,6 +77,7 @@ class WorkflowApplyResponseBuilderTest {
         Map<String, Object> actual = new 
WorkflowApplyResponseBuilder().build(createSnapshot("encrypt.table"), 
WorkflowLifecycle.STATUS_AWAITING_MANUAL_EXECUTION, "manual-only",
                 List.of(), List.of(), List.of(), List.of(), List.of(), 
manualArtifactPackage);
         assertThat(actual.get("response_mode"), is("manual_only"));
+        assertThat(actual.get("summary"), is("Workflow apply exported manual 
artifacts for plan `plan-1`; external execution is required before 
validation."));
         assertThat(actual.get("manual_artifacts"), 
is(List.of(manualArtifactPackage)));
         Map<?, ?> actualSummary = (Map<?, ?>) 
actual.get("manual_artifact_summary");
         assertThat(actualSummary.get("ddl_artifact_count"), is(1));
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 4ef0313b9d1..e923bf444d1 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
@@ -221,6 +221,9 @@ tools:
           enum:
             - planning
             - terminal
+        summary:
+          type: string
+          description: "Short model-facing workflow planning summary."
         plan_id:
           type: string
           description: "Workflow plan identifier for 
database_gateway_apply_workflow and database_gateway_validate_workflow."
@@ -318,6 +321,7 @@ tools:
       additionalProperties: true
       examples:
         - response_mode: planning
+          summary: Workflow plan `broadcast-rule-20260606-001` for 
broadcast.rule is ready for preview.
           plan_id: broadcast-rule-20260606-001
           status: planned
           workflow_kind: broadcast.rule
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 36338f2b9ea..f54de39df40 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
@@ -274,6 +274,9 @@ tools:
           enum:
             - planning
             - terminal
+        summary:
+          type: string
+          description: "Short model-facing workflow planning summary."
         plan_id:
           type: string
           description: "Workflow plan identifier for 
database_gateway_apply_workflow and database_gateway_validate_workflow."
@@ -410,6 +413,7 @@ tools:
           description: "Typed resources the model should read when more rule 
or algorithm context is useful."
       examples:
         - response_mode: planning
+          summary: Workflow plan `encrypt-rule-20260505-001` for encrypt.rule 
is ready for preview.
           plan_id: encrypt-rule-20260505-001
           status: planned
           workflow_kind: encrypt.rule
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 0bbec63b449..8e84be13a2f 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
@@ -27,6 +27,7 @@ import java.util.Locale;
 import java.util.Map;
 
 import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 class EncryptDescriptorContractTest {
     
@@ -35,6 +36,13 @@ class EncryptDescriptorContractTest {
         
assertEncryptDistSQLExampleValue(findToolDescriptor().getOutputSchema().get("examples"));
     }
     
+    @Test
+    void assertPlanningOutputDeclaresSummary() {
+        Map<?, ?> actualOutputSchema = findToolDescriptor().getOutputSchema();
+        Map<?, ?> actualProperties = (Map<?, ?>) 
actualOutputSchema.get("properties");
+        assertTrue(actualProperties.containsKey("summary"));
+    }
+    
     private MCPToolDescriptor findToolDescriptor() {
         MCPDescriptorCatalog catalog = MCPDescriptorCatalogLoader.load();
         return catalog.getProtocolDescriptors().getToolDescriptors().stream()
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 e082b3571f8..82b4d10f8b5 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
@@ -232,6 +232,9 @@ tools:
           enum:
             - planning
             - terminal
+        summary:
+          type: string
+          description: "Short model-facing workflow planning summary."
         plan_id:
           type: string
           description: "Workflow plan identifier for 
database_gateway_apply_workflow and database_gateway_validate_workflow."
@@ -356,6 +359,7 @@ tools:
           description: "Typed resources the model should read when more rule 
or algorithm context is useful."
       examples:
         - response_mode: planning
+          summary: Workflow plan `mask-rule-20260505-001` for mask.rule is 
ready for preview.
           plan_id: mask-rule-20260505-001
           status: planned
           workflow_kind: mask.rule
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 1cbee790e3b..fe8e45a8db7 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
@@ -389,6 +389,9 @@ tools:
           enum:
             - planning
             - terminal
+        summary:
+          type: string
+          description: "Short model-facing workflow planning summary."
         plan_id:
           type: string
           description: "Workflow plan identifier for 
database_gateway_apply_workflow and database_gateway_validate_workflow."
@@ -493,6 +496,7 @@ tools:
       additionalProperties: true
       examples:
         - response_mode: planning
+          summary: Workflow plan `readwrite-rule-20260606-001` for 
readwrite.rule is ready for preview.
           plan_id: readwrite-rule-20260606-001
           status: planned
           workflow_kind: readwrite.rule
@@ -609,6 +613,7 @@ tools:
       <<: *workflowPlanOutputSchema
       examples:
         - response_mode: planning
+          summary: Workflow plan `readwrite-status-20260606-001` for 
readwrite.status is ready for preview.
           plan_id: readwrite-status-20260606-001
           status: planned
           workflow_kind: readwrite.status
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 8b2c102f9e8..90631af4d88 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
@@ -468,6 +468,9 @@ tools:
           enum:
             - planning
             - terminal
+        summary:
+          type: string
+          description: "Short model-facing workflow planning summary."
         plan_id:
           type: string
           description: "Workflow plan identifier for 
database_gateway_apply_workflow and database_gateway_validate_workflow."
@@ -577,6 +580,7 @@ tools:
       additionalProperties: true
       examples:
         - response_mode: planning
+          summary: Workflow plan `shadow-rule-20260606-001` for shadow.rule is 
ready for preview.
           plan_id: shadow-rule-20260606-001
           workflow_kind: shadow.rule
           status: planned
@@ -657,6 +661,7 @@ tools:
       <<: *workflowPlanOutputSchema
       examples:
         - response_mode: planning
+          summary: Workflow plan `default-shadow-algorithm-20260606-001` for 
shadow.default is ready for preview.
           plan_id: default-shadow-algorithm-20260606-001
           workflow_kind: shadow.default
           status: planned
@@ -726,6 +731,7 @@ tools:
       <<: *workflowPlanOutputSchema
       examples:
         - response_mode: planning
+          summary: Workflow plan `shadow-algorithm-cleanup-20260606-001` for 
shadow.cleanup is ready for preview.
           plan_id: shadow-algorithm-cleanup-20260606-001
           workflow_kind: shadow.cleanup
           status: planned
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 221edec6c8e..28a0612319f 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
@@ -803,6 +803,7 @@ tools:
       type: object
       properties:
         response_mode: {type: string, description: "Stable response mode 
marker for workflow planning, or terminal when planning cannot continue.", 
enum: [planning, terminal]}
+        summary: {type: string, description: "Short model-facing workflow 
planning summary."}
         plan_id: {type: string, description: "Workflow plan identifier for 
database_gateway_apply_workflow and database_gateway_validate_workflow."}
         workflow_kind: {type: string, description: "Workflow kind resolved by 
the planner."}
         status: {type: string, description: "Stable workflow status, such as 
clarifying, planned, or failed."}
@@ -842,6 +843,7 @@ tools:
       additionalProperties: true
       examples:
         - response_mode: planning
+          summary: Workflow plan `sharding-table-rule-20260606-001` for 
sharding.table.rule is ready for preview.
           plan_id: sharding-table-rule-20260606-001
           workflow_kind: sharding.table.rule
           status: planned
diff --git 
a/mcp/support/src/main/java/org/apache/shardingsphere/mcp/support/descriptor/MCPGuidancePayloadBuilder.java
 
b/mcp/support/src/main/java/org/apache/shardingsphere/mcp/support/descriptor/MCPGuidancePayloadBuilder.java
index 8f013b469a7..1261b405d28 100644
--- 
a/mcp/support/src/main/java/org/apache/shardingsphere/mcp/support/descriptor/MCPGuidancePayloadBuilder.java
+++ 
b/mcp/support/src/main/java/org/apache/shardingsphere/mcp/support/descriptor/MCPGuidancePayloadBuilder.java
@@ -92,6 +92,8 @@ final class MCPGuidancePayloadBuilder {
                         "Stop after reporting the result rows."),
                 createFirstCallRoute("side_effect_sql", "call_tool 
database_gateway_execute_update execution_mode=preview", "call_tool 
database_gateway_execute_update execution_mode=execute",
                         "Execute only after preview review confirms the 
intended side effect."),
+                createFirstCallRoute("complete_uncertain_argument", "call 
completion/complete for one uncertain argument",
+                        "follow completion meta.next_actions when context is 
missing or no candidates match", "Stop after the argument is selected or the 
nearest resource proves it is unavailable."),
                 createFirstCallRoute("recover_error", "follow top-level 
next_actions", "fallback to recovery.next_actions when top-level actions are 
absent",
                         "Ask the user only when no deterministic resource, 
completion, or tool action is available."));
     }
@@ -119,6 +121,8 @@ final class MCPGuidancePayloadBuilder {
         result.put("sql_tool_selection", sqlToolSelection);
         result.put("workflow_session_rule", "Reuse the current-session plan_id 
returned by a planning tool; re-plan when the plan is unavailable.");
         result.put("side_effect_rule", "Preview before side effects and 
continue only when the requested side effect is still intended.");
+        result.put("completion_rule", "Use completion/complete for one 
uncertain argument at a time; when completion reports missing context, follow 
meta.next_actions before guessing.");
+        result.put("resource_template_rule", "Use resources/templates/list to 
discover URI variables, then read the nearest concrete resource before filling 
dependent completion context.");
         result.put("next_action_rule", "Use canonical next_actions fields: 
type, tool_name, resource_uri, and arguments.");
         result.put("detail_resource_rule", "Use resource descriptors, 
outputSchema, and returned payload keys before assuming detail fields.");
         result.put("recovery_rule", "When a call fails with 
recovery.next_actions, follow those structured actions before inventing a new 
call.");
@@ -183,6 +187,9 @@ final class MCPGuidancePayloadBuilder {
                 createCommonFlow("side_effecting_sql", List.of("call_tool 
database_gateway_execute_update execution_mode=preview",
                         "call_tool database_gateway_execute_update 
execution_mode=execute"),
                         "Execute only after reviewing the previewed SQL and 
side-effect scope.", List.of("database_gateway_execute_update"), List.of()),
+                createCommonFlow("complete_uncertain_argument", 
List.of("resources/templates/list", "call completion/complete for one argument",
+                        "follow completion meta.next_actions when diagnostic 
is missing_context, prefix_filtered_all_candidates, or no_candidates"),
+                        "Stop when a completion value is selected or the 
nearest resource proves the argument is unavailable.", List.of(), List.of()),
                 createCommonFlow("workflow_plan_apply_validate", 
List.of("call_tool descriptor-backed feature planning tool", "call_tool 
database_gateway_apply_workflow execution_mode=preview",
                         "call_tool database_gateway_apply_workflow 
execution_mode=review-then-execute 
approved_steps=<preview_artifacts.approval_step>",
                         "call_tool database_gateway_validate_workflow"),
diff --git 
a/mcp/support/src/main/java/org/apache/shardingsphere/mcp/support/descriptor/MCPToolDescriptorCatalogValidator.java
 
b/mcp/support/src/main/java/org/apache/shardingsphere/mcp/support/descriptor/MCPToolDescriptorCatalogValidator.java
index 71cfe22ba95..51c21f2addc 100644
--- 
a/mcp/support/src/main/java/org/apache/shardingsphere/mcp/support/descriptor/MCPToolDescriptorCatalogValidator.java
+++ 
b/mcp/support/src/main/java/org/apache/shardingsphere/mcp/support/descriptor/MCPToolDescriptorCatalogValidator.java
@@ -206,13 +206,13 @@ public final class MCPToolDescriptorCatalogValidator {
     
     private static void validateApplyWorkflowDescriptor(final 
MCPToolDescriptor descriptor) {
         
MCPToolDescriptorValidationUtils.validateRequiredOutputFields(descriptor,
-                List.of("response_mode", WorkflowFieldNames.PLAN_ID, "status", 
WorkflowFieldNames.EXECUTION_MODE, MCPPayloadFieldNames.NEXT_ACTIONS, 
"manual_artifact_summary",
-                        "category", "message", "secret_reference_summary"));
+                List.of("response_mode", MCPPayloadFieldNames.SUMMARY, 
WorkflowFieldNames.PLAN_ID, "status", WorkflowFieldNames.EXECUTION_MODE, 
MCPPayloadFieldNames.NEXT_ACTIONS,
+                        "manual_artifact_summary", "category", "message", 
"secret_reference_summary"));
     }
     
     private static void validateValidateWorkflowDescriptor(final 
MCPToolDescriptor descriptor) {
         
MCPToolDescriptorValidationUtils.validateRequiredOutputFields(descriptor,
-                List.of("response_mode", WorkflowFieldNames.PLAN_ID, "status", 
"overall_status", "issues", MCPPayloadFieldNames.NEXT_ACTIONS));
+                List.of("response_mode", MCPPayloadFieldNames.SUMMARY, 
WorkflowFieldNames.PLAN_ID, "status", "overall_status", "issues", 
MCPPayloadFieldNames.NEXT_ACTIONS));
     }
     
     private static void validatePlanningWorkflowDescriptor(final 
MCPToolDescriptor descriptor) {
diff --git 
a/mcp/support/src/main/java/org/apache/shardingsphere/mcp/support/descriptor/MCPToolDescriptorValidationUtils.java
 
b/mcp/support/src/main/java/org/apache/shardingsphere/mcp/support/descriptor/MCPToolDescriptorValidationUtils.java
index 1a6c5f3b49f..6ada8bc4060 100644
--- 
a/mcp/support/src/main/java/org/apache/shardingsphere/mcp/support/descriptor/MCPToolDescriptorValidationUtils.java
+++ 
b/mcp/support/src/main/java/org/apache/shardingsphere/mcp/support/descriptor/MCPToolDescriptorValidationUtils.java
@@ -34,7 +34,7 @@ import java.util.Optional;
 public final class MCPToolDescriptorValidationUtils {
     
     private static final Collection<String> 
REQUIRED_WORKFLOW_PLAN_OUTPUT_FIELDS = List.of(
-            "response_mode", WorkflowFieldNames.PLAN_ID, "workflow_kind", 
"status", "missing_required_inputs", "clarification_questions",
+            "response_mode", MCPPayloadFieldNames.SUMMARY, 
WorkflowFieldNames.PLAN_ID, "workflow_kind", "status", 
"missing_required_inputs", "clarification_questions",
             "elicitation_support", "fallback_reason", "issues", 
"global_steps", "current_step", "algorithm_recommendations", 
"property_requirements",
             "validation_strategy", "delivery_mode", "execution_mode", 
"intent_inference", "argument_provenance", "review_focus", 
"proxy_topology_hint",
             "distsql_artifacts", MCPPayloadFieldNames.RESOURCES_TO_READ, 
MCPPayloadFieldNames.NEXT_ACTIONS);
diff --git 
a/mcp/support/src/main/java/org/apache/shardingsphere/mcp/support/workflow/service/WorkflowPlanPayloadBuilder.java
 
b/mcp/support/src/main/java/org/apache/shardingsphere/mcp/support/workflow/service/WorkflowPlanPayloadBuilder.java
index 92499df4c35..3cdf25d406e 100644
--- 
a/mcp/support/src/main/java/org/apache/shardingsphere/mcp/support/workflow/service/WorkflowPlanPayloadBuilder.java
+++ 
b/mcp/support/src/main/java/org/apache/shardingsphere/mcp/support/workflow/service/WorkflowPlanPayloadBuilder.java
@@ -19,6 +19,7 @@ package 
org.apache.shardingsphere.mcp.support.workflow.service;
 
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
+import org.apache.shardingsphere.mcp.support.protocol.MCPPayloadFieldNames;
 import org.apache.shardingsphere.mcp.support.workflow.WorkflowPropertySource;
 import 
org.apache.shardingsphere.mcp.support.workflow.descriptor.WorkflowToolDescriptors;
 import org.apache.shardingsphere.mcp.support.workflow.model.AlgorithmCandidate;
@@ -54,8 +55,9 @@ public final class WorkflowPlanPayloadBuilder {
      * @return workflow-plan payload
      */
     public static Map<String, Object> build(final WorkflowContextSnapshot 
snapshot) {
-        Map<String, Object> result = new LinkedHashMap<>(16, 1F);
+        Map<String, Object> result = new LinkedHashMap<>(24, 1F);
         result.put("response_mode", resolveResponseMode(snapshot));
+        result.put(MCPPayloadFieldNames.SUMMARY, createSummary(snapshot));
         result.put(WorkflowFieldNames.PLAN_ID, snapshot.getPlanId());
         result.put("workflow_kind", snapshot.getWorkflowKind().getValue());
         result.put("status", snapshot.getStatus());
@@ -75,6 +77,20 @@ public final class WorkflowPlanPayloadBuilder {
         return result;
     }
     
+    private static String createSummary(final WorkflowContextSnapshot 
snapshot) {
+        String workflowKind = snapshot.getWorkflowKind().getValue();
+        if (WorkflowLifecycle.STATUS_CLARIFYING.equals(snapshot.getStatus())) {
+            return String.format("Workflow plan `%s` for %s requires 
clarification before preview.", snapshot.getPlanId(), workflowKind);
+        }
+        if (WorkflowLifecycle.STATUS_PLANNED.equals(snapshot.getStatus())) {
+            return String.format("Workflow plan `%s` for %s is ready for 
preview.", snapshot.getPlanId(), workflowKind);
+        }
+        if (WorkflowLifecycle.STATUS_FAILED.equals(snapshot.getStatus())) {
+            return String.format("Workflow plan `%s` for %s failed with %d 
issue(s).", snapshot.getPlanId(), workflowKind, snapshot.getIssues().size());
+        }
+        return String.format("Workflow plan `%s` for %s is `%s`.", 
snapshot.getPlanId(), workflowKind, snapshot.getStatus());
+    }
+    
     /**
      * Build one rule DistSQL-only workflow-plan payload map.
      *
diff --git 
a/mcp/support/src/main/java/org/apache/shardingsphere/mcp/support/workflow/service/WorkflowValidationSupport.java
 
b/mcp/support/src/main/java/org/apache/shardingsphere/mcp/support/workflow/service/WorkflowValidationSupport.java
index 1b46bed5434..93130497533 100644
--- 
a/mcp/support/src/main/java/org/apache/shardingsphere/mcp/support/workflow/service/WorkflowValidationSupport.java
+++ 
b/mcp/support/src/main/java/org/apache/shardingsphere/mcp/support/workflow/service/WorkflowValidationSupport.java
@@ -17,6 +17,7 @@
 
 package org.apache.shardingsphere.mcp.support.workflow.service;
 
+import org.apache.shardingsphere.mcp.support.protocol.MCPNextActionUtils;
 import org.apache.shardingsphere.mcp.support.protocol.MCPPayloadFieldNames;
 import org.apache.shardingsphere.mcp.support.workflow.WorkflowSessionContext;
 import org.apache.shardingsphere.mcp.support.workflow.model.ValidationReport;
@@ -131,6 +132,7 @@ public final class WorkflowValidationSupport {
         workflowSessionContext.persist(snapshot, 
WorkflowLifecycle.STEP_VALIDATED, validationStatus);
         Map<String, Object> result = new LinkedHashMap<>(16, 1F);
         result.put("response_mode", "validation");
+        result.put(MCPPayloadFieldNames.SUMMARY, 
createValidationSummary(snapshot, validationReport));
         result.put(WorkflowFieldNames.PLAN_ID, snapshot.getPlanId());
         result.put("status", validationStatus);
         result.put("issues", createValidationIssues(validationReport));
@@ -194,6 +196,13 @@ public final class WorkflowValidationSupport {
         return 
WorkflowLifecycle.STATUS_FAILED.equals(validationReport.getOverallStatus()) ? 
WorkflowLifecycle.STATUS_FAILED : WorkflowLifecycle.STATUS_VALIDATED;
     }
     
+    private String createValidationSummary(final WorkflowContextSnapshot 
snapshot, final ValidationReport validationReport) {
+        if 
(WorkflowLifecycle.STATUS_FAILED.equals(validationReport.getOverallStatus())) {
+            return String.format("Workflow validation failed for plan `%s` 
with %d mismatch(es).", snapshot.getPlanId(), 
validationReport.getMismatches().size());
+        }
+        return String.format("Workflow validation passed for plan `%s`.", 
snapshot.getPlanId());
+    }
+    
     private boolean isValidatableStatus(final WorkflowContextSnapshot 
snapshot) {
         String actualStatus = null == snapshot.getStatus() ? "" : 
snapshot.getStatus();
         if (WorkflowLifecycle.STATUS_VALIDATED.equalsIgnoreCase(actualStatus)
@@ -211,18 +220,27 @@ public final class WorkflowValidationSupport {
     }
     
     private Map<String, Object> createRejectedResponse(final 
WorkflowContextSnapshot snapshot, final String issueCode, final String message, 
final String userAction) {
-        Map<String, Object> result = new LinkedHashMap<>(9, 1F);
+        Map<String, Object> result = new LinkedHashMap<>(10, 1F);
         result.put("response_mode", "terminal");
+        result.put(MCPPayloadFieldNames.SUMMARY, String.format("Workflow 
validation cannot run for plan `%s`.", snapshot.getPlanId()));
         result.put(WorkflowFieldNames.PLAN_ID, snapshot.getPlanId());
         result.put("status", WorkflowLifecycle.STATUS_FAILED);
         result.put("issues", List.of(new WorkflowIssue(issueCode, "error", 
"validating", message, userAction, false, Map.of()).toMap()));
         result.put("overall_status", WorkflowLifecycle.STATUS_FAILED);
         result.put("mismatches", List.of());
         result.put("recovery_guidance", userAction);
-        result.put(MCPPayloadFieldNames.NEXT_ACTIONS, List.of());
+        result.put(MCPPayloadFieldNames.NEXT_ACTIONS, 
createRejectedNextActions(issueCode, userAction));
         return result;
     }
     
+    private List<Map<String, Object>> createRejectedNextActions(final String 
issueCode, final String userAction) {
+        return 
MCPNextActionUtils.ordered(MCPNextActionUtils.askUser(userAction, 
List.of(resolveRejectedRequiredInput(issueCode))));
+    }
+    
+    private String resolveRejectedRequiredInput(final String issueCode) {
+        return WorkflowIssueCode.SESSION_OWNERSHIP_MISMATCH.equals(issueCode) 
? "same_mcp_session" : "validatable_workflow_state";
+    }
+    
     /**
      * Resolve validation issue code from mismatches.
      *
diff --git 
a/mcp/support/src/main/resources/META-INF/shardingsphere-mcp/mcp-descriptors/mcp-descriptor-support.yaml
 
b/mcp/support/src/main/resources/META-INF/shardingsphere-mcp/mcp-descriptors/mcp-descriptor-support.yaml
index 845d91d86c6..fee54f5217f 100644
--- 
a/mcp/support/src/main/resources/META-INF/shardingsphere-mcp/mcp-descriptors/mcp-descriptor-support.yaml
+++ 
b/mcp/support/src/main/resources/META-INF/shardingsphere-mcp/mcp-descriptors/mcp-descriptor-support.yaml
@@ -225,6 +225,9 @@ tools:
             - manual_only
             - recovery
             - terminal
+        summary:
+          type: string
+          description: "Short model-facing workflow apply summary."
         plan_id:
           type: string
           description: "Workflow plan identifier that was applied."
@@ -378,6 +381,7 @@ tools:
                 description: "Action order values that must complete before 
this action."
       examples:
         - response_mode: preview
+          summary: Previewed 0 workflow artifacts. Nothing has been applied.
           plan_id: encrypt-rule-20260505-001
           execution_mode: preview
           applied_artifacts: []
@@ -429,6 +433,9 @@ tools:
           enum:
             - validation
             - terminal
+        summary:
+          type: string
+          description: "Short model-facing workflow validation summary."
         plan_id:
           type: string
           description: "Workflow plan identifier that was validated."
@@ -540,6 +547,7 @@ tools:
                 description: "Action order values that must complete before 
this action."
       examples:
         - response_mode: validation
+          summary: Workflow validation passed for plan 
`encrypt-rule-20260505-001`.
           plan_id: encrypt-rule-20260505-001
           status: passed
           sections: []
diff --git 
a/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/descriptor/MCPDescriptorCatalogLoaderTest.java
 
b/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/descriptor/MCPDescriptorCatalogLoaderTest.java
index 89a4c989bf7..8b5ee4211a5 100644
--- 
a/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/descriptor/MCPDescriptorCatalogLoaderTest.java
+++ 
b/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/descriptor/MCPDescriptorCatalogLoaderTest.java
@@ -45,9 +45,9 @@ class MCPDescriptorCatalogLoaderTest {
         Set<String> actualToolNames = 
actual.getProtocolDescriptors().getToolDescriptors().stream().map(MCPToolDescriptor::getName).collect(Collectors.toSet());
         assertToolNames(actualToolNames);
         assertOutputProperties(actual, "database_gateway_apply_workflow", 
Set.of(
-                "response_mode", "plan_id", "execution_mode", "next_actions", 
"manual_artifact_package", "manual_artifact_summary", "manual_follow_up", 
"argument_provenance",
+                "response_mode", "summary", "plan_id", "execution_mode", 
"next_actions", "manual_artifact_package", "manual_artifact_summary", 
"manual_follow_up", "argument_provenance",
                 "review_summary", "review_focus", "category", "message", 
"secret_reference_summary"));
-        assertOutputProperties(actual, "database_gateway_validate_workflow", 
Set.of("response_mode", "plan_id", "status", "recovery_guidance", 
"next_actions", "sections", "mismatches"));
+        assertOutputProperties(actual, "database_gateway_validate_workflow", 
Set.of("response_mode", "summary", "plan_id", "status", "recovery_guidance", 
"next_actions", "sections", "mismatches"));
         assertPublicToolAnnotations(actual);
         assertPlanningToolAnnotations(actual);
         assertResourceDescriptor(actual);
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 dccc391cfe2..d7d97a39f31 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
@@ -301,9 +301,10 @@ class MCPDescriptorCatalogValidatorTest {
     private Map<String, Object> createWorkflowPlanOutputSchema() {
         Map<String, Object> properties = new LinkedHashMap<>();
         for (String each : List.of(
-                "response_mode", WorkflowFieldNames.PLAN_ID, "workflow_kind", 
"status", "missing_required_inputs", "clarification_questions", 
"elicitation_support",
-                "fallback_reason", "issues", "global_steps", "current_step", 
"algorithm_recommendations", "property_requirements", "validation_strategy", 
"delivery_mode",
-                "execution_mode", "intent_inference", "argument_provenance", 
"review_focus", "proxy_topology_hint", "distsql_artifacts", 
MCPPayloadFieldNames.RESOURCES_TO_READ)) {
+                "response_mode", MCPPayloadFieldNames.SUMMARY, 
WorkflowFieldNames.PLAN_ID, "workflow_kind", "status", 
"missing_required_inputs", "clarification_questions",
+                "elicitation_support", "fallback_reason", "issues", 
"global_steps", "current_step", "algorithm_recommendations", 
"property_requirements", "validation_strategy",
+                "delivery_mode", "execution_mode", "intent_inference", 
"argument_provenance", "review_focus", "proxy_topology_hint", 
"distsql_artifacts",
+                MCPPayloadFieldNames.RESOURCES_TO_READ)) {
             properties.put(each, Map.of("type", "object", "description", 
"Workflow plan field."));
         }
         properties.put(MCPPayloadFieldNames.NEXT_ACTIONS, 
createNextActionsSchema());
diff --git 
a/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/descriptor/MCPGuidancePayloadBuilderTest.java
 
b/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/descriptor/MCPGuidancePayloadBuilderTest.java
index be5ee710d52..bbf10e2a823 100644
--- 
a/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/descriptor/MCPGuidancePayloadBuilderTest.java
+++ 
b/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/descriptor/MCPGuidancePayloadBuilderTest.java
@@ -53,6 +53,8 @@ class MCPGuidancePayloadBuilderTest {
         assertFalse(actual.containsKey("safe_first_resource"));
         Map<?, ?> actualMetadataRoute = 
findByKey(castToRouteList(actual.get("first_call_routes")), "intent", 
"inspect_metadata");
         assertThat(actualMetadataRoute.get("first_action"), is("read_resource 
shardingsphere://databases"));
+        Map<?, ?> actualCompletionRoute = 
findByKey(castToRouteList(actual.get("first_call_routes")), "intent", 
"complete_uncertain_argument");
+        assertThat(actualCompletionRoute.get("first_action"), is("call 
completion/complete for one uncertain argument"));
         Map<?, ?> actualRecoveryRoute = 
findByKey(castToRouteList(actual.get("first_call_routes")), "intent", 
"recover_error");
         assertThat(actualRecoveryRoute.get("first_action"), is("follow 
top-level next_actions"));
         assertThat(((Map<?, ?>) actual.get("preflight_rule")).get("tool"), 
is("database_gateway_validate_runtime_database"));
@@ -76,6 +78,10 @@ class MCPGuidancePayloadBuilderTest {
         
assertTrue(String.valueOf(actual.get("preflight_rule")).contains("database_gateway_validate_runtime_database"));
         
assertThat(castToMap(actual.get("sql_tool_selection")).keySet().stream().toList(),
 is(List.of("read_only", "side_effecting")));
         assertThat(actual.get("side_effect_rule"), is("Preview before side 
effects and continue only when the requested side effect is still intended."));
+        assertThat(actual.get("completion_rule"),
+                is("Use completion/complete for one uncertain argument at a 
time; when completion reports missing context, follow meta.next_actions before 
guessing."));
+        assertThat(actual.get("resource_template_rule"),
+                is("Use resources/templates/list to discover URI variables, 
then read the nearest concrete resource before filling dependent completion 
context."));
         assertThat(actual.get("detail_resource_rule"), is("Use resource 
descriptors, outputSchema, and returned payload keys before assuming detail 
fields."));
     }
     
@@ -97,10 +103,12 @@ class MCPGuidancePayloadBuilderTest {
         List<Map<String, Object>> actual = builder.createCommonFlows();
         Map<?, ?> actualInspectMetadata = findByKey(actual, "flow_id", 
"inspect_metadata");
         assertTrue(((Collection<?>) 
actualInspectMetadata.get("steps")).contains("resources/list"));
-        Map<?, ?> actualSideEffectingSql = findByKey(actual, "flow_id", 
"side_effecting_sql");
         Map<?, ?> actualValidateRuntimeDatabase = findByKey(actual, "flow_id", 
"validate_runtime_database");
         assertTrue(((Collection<?>) 
actualValidateRuntimeDatabase.get("steps")).contains("call_tool 
database_gateway_validate_runtime_database"));
         assertThat(actualValidateRuntimeDatabase.get("referenced_tools"), 
is(List.of("database_gateway_validate_runtime_database")));
+        Map<?, ?> actualCompleteArgument = findByKey(actual, "flow_id", 
"complete_uncertain_argument");
+        assertTrue(((Collection<?>) 
actualCompleteArgument.get("steps")).contains("call completion/complete for one 
argument"));
+        Map<?, ?> actualSideEffectingSql = findByKey(actual, "flow_id", 
"side_effecting_sql");
         assertThat(actualSideEffectingSql.get("referenced_tools"), 
is(List.of("database_gateway_execute_update")));
         assertTrue(((Collection<?>) 
actualSideEffectingSql.get("steps")).contains("call_tool 
database_gateway_execute_update execution_mode=preview"));
         Map<?, ?> actualWorkflow = findByKey(actual, "flow_id", 
"workflow_plan_apply_validate");
diff --git 
a/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/descriptor/MCPToolDescriptorValidationUtilsTest.java
 
b/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/descriptor/MCPToolDescriptorValidationUtilsTest.java
index 1af04338ea6..fd87ac5e663 100644
--- 
a/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/descriptor/MCPToolDescriptorValidationUtilsTest.java
+++ 
b/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/descriptor/MCPToolDescriptorValidationUtilsTest.java
@@ -38,7 +38,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
 class MCPToolDescriptorValidationUtilsTest {
     
     private static final Collection<String> WORKFLOW_PLAN_OUTPUT_FIELDS = 
List.of(
-            "response_mode", WorkflowFieldNames.PLAN_ID, "workflow_kind", 
"status", "missing_required_inputs", "clarification_questions",
+            "response_mode", MCPPayloadFieldNames.SUMMARY, 
WorkflowFieldNames.PLAN_ID, "workflow_kind", "status", 
"missing_required_inputs", "clarification_questions",
             "elicitation_support", "fallback_reason", "issues", 
"global_steps", "current_step", "algorithm_recommendations", 
"property_requirements",
             "validation_strategy", "delivery_mode", "execution_mode", 
"intent_inference", "argument_provenance", "review_focus", 
"proxy_topology_hint",
             "distsql_artifacts", MCPPayloadFieldNames.RESOURCES_TO_READ, 
MCPPayloadFieldNames.NEXT_ACTIONS);
diff --git 
a/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/workflow/service/WorkflowPlanPayloadBuilderTest.java
 
b/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/workflow/service/WorkflowPlanPayloadBuilderTest.java
index 2a3cdc0d63b..508c91dca9c 100644
--- 
a/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/workflow/service/WorkflowPlanPayloadBuilderTest.java
+++ 
b/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/workflow/service/WorkflowPlanPayloadBuilderTest.java
@@ -73,6 +73,7 @@ class WorkflowPlanPayloadBuilderTest {
         snapshot.setInteractionPlan(interactionPlan);
         Map<String, Object> actual = 
WorkflowPlanPayloadBuilder.build(snapshot);
         assertThat(actual.get("response_mode"), is("planning"));
+        assertThat(actual.get("summary"), is("Workflow plan `plan-1` for 
encrypt.rule requires clarification before preview."));
         assertThat(actual.get("plan_id"), is("plan-1"));
         assertThat(actual.get("workflow_kind"), is("encrypt.rule"));
         assertThat(((Map<?, ?>) 
actual.get("intent_inference")).get("operation_type"), is("create"));
@@ -157,6 +158,7 @@ class WorkflowPlanPayloadBuilderTest {
         snapshot.setRequest(request);
         snapshot.setInteractionPlan(InteractionPlan.create("plan-1", request, 
"Mask workflow plan.", List.of("Review"), List.of("rules")));
         Map<String, Object> actual = 
WorkflowPlanPayloadBuilder.build(snapshot);
+        assertThat(actual.get("summary"), is("Workflow plan `plan-1` for 
mask.rule is ready for preview."));
         List<?> actualResourcesToRead = (List<?>) 
actual.get("resources_to_read");
         List<String> actualResourceUris = 
extractResourceUris(actualResourcesToRead);
         
assertTrue(actualResourceUris.contains("shardingsphere://features/mask/algorithms"));
@@ -335,6 +337,7 @@ class WorkflowPlanPayloadBuilderTest {
         Map<String, Object> actual = 
WorkflowPlanPayloadBuilder.build(snapshot);
         Map<?, ?> actualNextAction = (Map<?, ?>) ((List<?>) 
actual.get("next_actions")).getFirst();
         assertThat(actual.get("response_mode"), is("terminal"));
+        assertThat(actual.get("summary"), is("Workflow plan `plan-1` for 
encrypt.rule failed with 0 issue(s)."));
         assertThat(actualNextAction.get("type"), is("tool_call"));
         assertThat(actualNextAction.get("tool_name"), 
is("database_gateway_plan_encrypt_rule"));
     }
diff --git 
a/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/workflow/service/WorkflowValidationSupportTest.java
 
b/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/workflow/service/WorkflowValidationSupportTest.java
index 2aeee3790bc..341fcfc7737 100644
--- 
a/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/workflow/service/WorkflowValidationSupportTest.java
+++ 
b/mcp/support/src/test/java/org/apache/shardingsphere/mcp/support/workflow/service/WorkflowValidationSupportTest.java
@@ -49,9 +49,11 @@ class WorkflowValidationSupportTest {
         snapshot.setStatus("executed");
         Map<String, Object> actualResult = 
validationSupport.checkValidatePreconditions("session-2", snapshot);
         assertThat(actualResult.get("status"), is("failed"));
+        assertThat(actualResult.get("summary"), is("Workflow validation cannot 
run for plan `plan-1`."));
         assertThat(actualResult.get("plan_id"), is("plan-1"));
         assertThat(actualResult.get("recovery_guidance"), is("Continue the 
workflow from the same session that created the plan."));
         assertThat(((Map<?, ?>) ((List<?>) 
actualResult.get("issues")).get(0)).get("code"), 
is(WorkflowIssueCode.SESSION_OWNERSHIP_MISMATCH));
+        assertThat(((Map<?, ?>) ((List<?>) 
actualResult.get("next_actions")).getFirst()).get("required_inputs"), 
is(List.of("same_mcp_session")));
     }
     
     @Test
@@ -65,6 +67,7 @@ class WorkflowValidationSupportTest {
         assertThat(actualResult.get("plan_id"), is("plan-1"));
         assertThat(actualResult.get("recovery_guidance"), is("Execute the 
workflow first or continue from a validatable status."));
         assertThat(((Map<?, ?>) ((List<?>) 
actualResult.get("issues")).get(0)).get("code"), 
is(WorkflowIssueCode.WORKFLOW_STATUS_INVALID));
+        assertThat(((Map<?, ?>) ((List<?>) 
actualResult.get("next_actions")).getFirst()).get("required_inputs"), 
is(List.of("validatable_workflow_state")));
     }
     
     @Test
@@ -153,6 +156,7 @@ class WorkflowValidationSupportTest {
         workflowSessionContext.save(snapshot);
         Map<String, Object> actualResult = 
validationSupport.finalizeValidation(workflowSessionContext, snapshot, 
validationReport);
         assertThat(actualResult.get("response_mode"), is("validation"));
+        assertThat(actualResult.get("summary"), is("Workflow validation passed 
for plan `plan-1`."));
         assertThat(actualResult.get("status"), is("validated"));
         assertThat(actualResult.get("plan_id"), is("plan-1"));
         assertThat(actualResult.get("recovery_guidance"), is(""));
@@ -175,6 +179,7 @@ class WorkflowValidationSupportTest {
         workflowSessionContext.save(snapshot);
         Map<String, Object> actualResult = 
validationSupport.finalizeValidation(workflowSessionContext, snapshot, 
validationReport);
         assertThat(actualResult.get("response_mode"), is("validation"));
+        assertThat(actualResult.get("summary"), is("Workflow validation failed 
for plan `plan-1` with 1 mismatch(es)."));
         assertThat(((Map<?, ?>) ((List<?>) 
actualResult.get("issues")).get(0)).get("code"), 
is(WorkflowIssueCode.SQL_EXECUTABILITY_FAILED));
         assertThat(actualResult.get("status"), is("failed"));
         assertThat(actualResult.get("recovery_guidance"), is("Inspect 
mismatches, adjust the plan or runtime state, then run 
database_gateway_validate_workflow again."));
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 7a70c2e7334..fb162f71163 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
@@ -87,6 +87,9 @@ tools:
         response_mode:
           type: string
           description: "Machine-readable response mode for planning or 
terminal workflow states."
+        summary:
+          type: string
+          description: "Short model-facing workflow planning summary."
         plan_id:
           type: string
           description: "Workflow plan identifier for 
database_gateway_apply_workflow and database_gateway_validate_workflow."
@@ -170,6 +173,7 @@ tools:
                 description: "Why the model should take this action."
       examples:
         - response_mode: planning
+          summary: Workflow plan `encrypt-rule-20260505-001` for encrypt.rule 
is ready for preview.
           plan_id: encrypt-rule-20260505-001
           workflow_kind: encrypt.rule
           status: planned

Reply via email to