You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by zh...@apache.org on 2026/07/29 03:29:03 UTC

(shardingsphere) branch master updated: Refactor MCP E2E test suite naming (#39264)

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 33b18fe1c69 Refactor MCP E2E test suite naming (#39264)
33b18fe1c69 is described below

commit 33b18fe1c692706064ed5915fcbcc015fe1f9544
Author: Liang Zhang <zh...@apache.org>
AuthorDate: Wed Jul 29 11:28:56 2026 +0800

    Refactor MCP E2E test suite naming (#39264)
---
 .github/workflows/e2e-mcp.yml                      | 34 +++++++--------
 .../content/test-manual/mcp-e2e-test/_index.cn.md  | 42 +++++++------------
 .../content/test-manual/mcp-e2e-test/_index.en.md  | 42 +++++++------------
 test/e2e/mcp/pom.xml                               |  2 +-
 .../AbstractFunctionalityE2ETest.java}             |  4 +-
 .../AbstractHttpProxyWorkflowE2ETest.java}         |  4 +-
 .../AbstractMySQLRuntimeE2ETest.java}              | 45 +++++++++++++-------
 .../AbstractPostgreSQLRuntimeE2ETest.java}         | 10 ++---
 .../AbstractTransportParameterizedE2ETest.java}    |  6 +--
 .../FunctionalityTransportCases.java}              | 24 +++++------
 .../HttpProxyEncryptWorkflowE2ETest.java}          | 18 ++++----
 .../HttpProxyFeatureWorkflowContractE2ETest.java}  | 12 +++---
 .../HttpProxyMaskWorkflowE2ETest.java}             | 16 ++++----
 .../HttpProxySecretReferenceWorkflowE2ETest.java}  |  6 +--
 .../MCPClientTransportFactory.java}                | 40 ++----------------
 .../MCPClientTransportFactoryTest.java}            |  8 ++--
 .../MySQLMetadataE2ETest.java}                     | 48 +++++++++++-----------
 .../MySQLReadOnlySQLE2ETest.java}                  | 32 +++++++--------
 .../MySQLSQLExecutionE2ETest.java}                 | 40 +++++++++---------
 .../PackagedDistributionE2ETest.java               |  2 +-
 .../PostgreSQLDatabaseGatewayE2ETest.java}         |  8 ++--
 .../e2e/mcp/llm/{suite => }/LLMHttpE2ETest.java    |  2 +-
 ...oTransportE2ETest.java => LLMStdioE2ETest.java} | 16 ++++----
 .../resources/docker/llm-runtime/build-local.sh    |  4 +-
 24 files changed, 212 insertions(+), 253 deletions(-)

diff --git a/.github/workflows/e2e-mcp.yml b/.github/workflows/e2e-mcp.yml
index 6439142ba7b..d031645ac81 100644
--- a/.github/workflows/e2e-mcp.yml
+++ b/.github/workflows/e2e-mcp.yml
@@ -134,8 +134,8 @@ jobs:
           docker-images: |
             ${{ steps.mcp-llm-runtime-image.outputs.image_tag }}=mcp-llm-runtime-image.tar
 
-  e2e-mcp-core:
-    name: E2E - MCP Core
+  e2e-mcp-functionality:
+    name: E2E - MCP Functionality
     if: github.repository == 'apache/shardingsphere'
     needs: e2e-mcp-build-images
     runs-on: ubuntu-latest
@@ -160,13 +160,13 @@ jobs:
           set -euo pipefail
           mkdir -p distribution/mcp/target
           tar -xzf "${RUNNER_TEMP}/mcp-e2e-build-artifacts/mcp-distribution-home.tar.gz" -C distribution/mcp/target
-      - name: Run MCP Core E2E
-        run: ./mvnw -pl test/e2e/mcp test -Pe2e.mcp -Dmcp.e2e.container.image=${{ env.MCP_DISTRIBUTION_IMAGE }} -DskipITs -Dspotless.skip=true -B -ntp
-      - name: Upload MCP Core E2E Artifacts
+      - name: Run MCP Functionality E2E
+        run: ./mvnw -pl test/e2e/mcp test -Pe2e.mcp.functionality -Dmcp.e2e.container.image=${{ env.MCP_DISTRIBUTION_IMAGE }} -DskipITs -Dspotless.skip=true -B -ntp
+      - name: Upload MCP Functionality E2E Artifacts
         if: always()
         uses: actions/upload-artifact@v6
         with:
-          name: e2e-mcp-core-${{ github.run_id }}-${{ github.run_attempt }}
+          name: e2e-mcp-functionality-${{ github.run_id }}-${{ github.run_attempt }}
           path: test/e2e/mcp/target/surefire-reports
           if-no-files-found: warn
 
@@ -185,7 +185,7 @@ jobs:
           artifact-dir: ${{ runner.temp }}/mcp-e2e-build-artifacts
           restore-maven-repository: 'false'
           docker-image-archives: mcp-distribution-image.tar
-      - name: Checkout Fixed MCP Conformance Source
+      - name: Checkout Pinned MCP Conformance Runner
         uses: actions/checkout@v6.0.1
         with:
           repository: modelcontextprotocol/conformance
@@ -196,12 +196,12 @@ jobs:
           node-version: '22'
           cache: npm
           cache-dependency-path: .mcp-conformance/package-lock.json
-      - name: Build Fixed MCP Conformance Runner
+      - name: Build MCP Conformance Runner
         working-directory: .mcp-conformance
         run: |
           npm ci
           npm run build
-      - name: Run Applicable MCP 2025-11-25 Server Scenarios
+      - name: Run MCP 2025-11-25 Conformance Scenarios
         shell: bash
         run: |
           set -euo pipefail
@@ -271,19 +271,19 @@ jobs:
       max-parallel: 3
       matrix:
         include:
-          - id: stdio-transport
-            test: LLMStdioTransportE2ETest#assertStdioTransport
-          - id: autonomous-read-only-query
+          - id: stdio-autonomous-read-only-query
+            test: LLMStdioE2ETest#assertAutonomousReadOnlyQuery
+          - id: http-autonomous-read-only-query
             test: LLMHttpE2ETest#assertAutonomousReadOnlyQuery
-          - id: autonomous-metadata-discovery
+          - id: http-autonomous-metadata-discovery
             test: LLMHttpE2ETest#assertAutonomousMetadataDiscovery
-          - id: side-effect-preview
+          - id: http-side-effect-preview
             test: LLMHttpE2ETest#assertSideEffectPreview
-          - id: runtime-resource-navigation
+          - id: http-runtime-resource-navigation
             test: LLMHttpE2ETest#assertRuntimeResourceNavigation
-          - id: missing-database-scope-discovery
+          - id: http-missing-database-scope-discovery
             test: LLMHttpE2ETest#assertMissingDatabaseScopeDiscovery
-          - id: invalid-resource-recovery
+          - id: http-invalid-resource-recovery
             test: LLMHttpE2ETest#assertInvalidResourceRecovery
     steps:
       - uses: actions/checkout@v6.0.1
diff --git a/docs/document/content/test-manual/mcp-e2e-test/_index.cn.md b/docs/document/content/test-manual/mcp-e2e-test/_index.cn.md
index 4cfa3572bce..b6f174ae485 100644
--- a/docs/document/content/test-manual/mcp-e2e-test/_index.cn.md
+++ b/docs/document/content/test-manual/mcp-e2e-test/_index.cn.md
@@ -5,19 +5,15 @@ weight = 5
 chapter = true
 +++
 
-本章说明 ShardingSphere-MCP 的端到端契约验证和 LLM usability 验证。
+本章说明 ShardingSphere-MCP 的 Functionality、Conformance 和 LLM 三类端到端测试。
 
 ## 范围
 
-`test/e2e/mcp` 覆盖:
+MCP E2E workflow 包含三个相互独立的测试套件:
 
-- 发行包启动和配置。
-- 基于真实 MySQL、PostgreSQL 和 Proxy 的 HTTP、STDIO runtime。
-- Tool、resource、prompt 和 completion 的跨进程发现与执行。
-- 适用于当前 server capability 的官方 MCP conformance 场景。
-- 真实模型驱动的 MCP usability。
-- 基于实时元数据和数据的 10 题自主 MCP Builder 评测。
-- Encrypt、Mask、Broadcast、Readwrite-Splitting、Shadow 和 Sharding workflow 验收。
+- MCP Functionality E2E 验证发行包启动和配置、基于真实 MySQL、PostgreSQL 和 Proxy 的 HTTP 与 STDIO runtime、Tool、resource、prompt 和 completion 的跨进程发现与执行,以及 Encrypt、Mask、Broadcast、Readwrite-Splitting、Shadow 和 Sharding workflow。
+- MCP Conformance E2E 使用官方 runner 验证适用于当前 server capability 的 MCP 协议场景。
+- MCP LLM E2E 验证真实模型通过 HTTP 或 STDIO 使用 MCP 完成只读查询、元数据发现、资源导航、带副作用操作的 preview 和错误恢复。
 
 不需要 Docker 的 HTTP 协议、会话和安全边界由 `mcp/bootstrap` 的 `StreamableHttpMCPServerIT` 覆盖,不属于 E2E。
 
@@ -74,13 +70,13 @@ sh test/e2e/mcp/src/test/resources/docker/llm-runtime/build-local.sh --dry-run
 sh test/e2e/mcp/src/test/resources/docker/llm-runtime/build-local.sh
 ```
 
-## 运行 MCP Runtime E2E
+## 运行 MCP Functionality E2E
 
 MCP E2E 运行配置集中在 `test/e2e/mcp/src/test/resources/env/e2e-env.properties`。
 本地运行时可以直接修改该文件,也可以使用同名 `-D` 系统参数覆盖。
 
 ```bash
-./mvnw -pl test/e2e/mcp test -Pe2e.mcp
+./mvnw -pl test/e2e/mcp test -Pe2e.mcp.functionality
 ```
 
 ## 运行 MCP HTTP IT
@@ -91,23 +87,15 @@ MCP E2E 运行配置集中在 `test/e2e/mcp/src/test/resources/env/e2e-env.prope
 ./mvnw -pl mcp/bootstrap verify
 ```
 
-## 运行 LLM Usability Suite
+## 运行 MCP LLM E2E
 
 ```bash
-./mvnw -pl test/e2e/mcp test -Pe2e.mcp.llm -Dtest=LLMUsabilitySuiteE2ETest
+./mvnw -pl test/e2e/mcp test -Pe2e.mcp.llm
 ```
 
-## 运行自主 MCP Builder 评测
+`LLMHttpE2ETest` 覆盖 HTTP 场景,`LLMStdioE2ETest` 覆盖 STDIO 自主只读查询。每个场景都使用实时 `tools/list` response,并保留模型 response、MCP structured response、interaction trace 和断言报告。选中 `llm-e2e` lane 后,如果 Docker、模型、数据库或 MCP 基础设施缺失,测试直接失败,不把失败转换成 skip。
 
-评测从 `llm/evaluation/mcp-builder-evaluation.xml` 加载 10 个相互独立的只读问题。
-每个问题都创建新的 MCP session,从实时 `tools/list` response 派生模型 function definitions,保留模型原始 response 和 MCP structured response,并且不注入纠错提示或期望答案,只对最终答案做精确比较。
-用于闭合评分的运行显式使用 32768 token context window。选中 `llm-e2e` lane 后,如果 Docker、模型、数据库或 MCP 基础设施缺失,测试直接失败,不把评分失败转换成 skip。
-
-```bash
-./mvnw -pl test/e2e/mcp test -Pe2e.mcp.llm -Dtest=MCPBuilderEvaluationE2ETest
-```
-
-## 官方 MCP Conformance
+## MCP Conformance E2E
 
 CI conformance lane 将 `modelcontextprotocol/conformance` 固定在 commit `21a9a2febd7100d7c17ac1021ee7f2ed9f66a1e0`,传入 protocol version `2025-11-25`,并且只运行 workflow 中声明的适用通用 server 场景。
 上游固定使用 `test_*` tool/resource 的产品无关调用、未声明的可选能力和固定 HTTP 传输面以外的场景不适用于本项目,产品能力继续由确定性 E2E 覆盖;不会为了上游 fixture 添加生产测试钩子。
@@ -118,24 +106,24 @@ CI conformance lane 将 `modelcontextprotocol/conformance` 固定在 commit `21a
 仅本地调试时,可以连接已经运行的 OpenAI-compatible endpoint:
 
 ```bash
-./mvnw -pl test/e2e/mcp test -Pe2e.mcp.llm -Dtest=LLMUsabilitySuiteE2ETest -Dmcp.llm.runtime-mode=external-debug -Dmcp.llm.base-url=http://127.0.0.1:8080/v1
+./mvnw -pl test/e2e/mcp test -Pe2e.mcp.llm -Dtest=LLMHttpE2ETest -Dmcp.llm.runtime-mode=external-debug -Dmcp.llm.base-url=http://127.0.0.1:8080/v1
 ```
 
 External debug endpoint 不能作为 score-closing evidence。
 
 ## 产物
 
-LLM usability 和 MCP Builder evaluation artifact 写入:
+MCP LLM E2E artifact 写入:
 
 ```text
 test/e2e/mcp/target/llm-e2e/
 ```
 
-每个自主评测 case 都记录问题、期望与实际答案、原始模型 response、MCP interaction trace、实时 tool definitions、runtime evidence 和 assertion report。Artifact 写入会脱敏 secret-shaped 值;如果发现未脱敏 secret pattern 或已知模型 API key,评分运行直接失败。
+每个场景都记录问题、期望与实际答案、原始模型 response、MCP interaction trace、实时 tool definitions、runtime evidence 和 assertion report。Artifact 写入会脱敏 secret-shaped 值;如果发现未脱敏 secret pattern 或已知模型 API key,测试直接失败。
 
 GitHub Actions 入口:
 
 - `.github/workflows/e2e-mcp.yml`
 
-这条 workflow 是 MCP runtime E2E 的必跑入口。
+这条 workflow 是三类 MCP E2E 的统一入口。
 如果超大 PR 因 path filter 限制漏触发,可以使用 `workflow_dispatch` 手动补充 evidence。
diff --git a/docs/document/content/test-manual/mcp-e2e-test/_index.en.md b/docs/document/content/test-manual/mcp-e2e-test/_index.en.md
index fc7b062cf61..8b47c4555ac 100644
--- a/docs/document/content/test-manual/mcp-e2e-test/_index.en.md
+++ b/docs/document/content/test-manual/mcp-e2e-test/_index.en.md
@@ -5,19 +5,15 @@ weight = 5
 chapter = true
 +++
 
-This chapter describes ShardingSphere-MCP end-to-end contract validation and LLM usability validation.
+This chapter describes the ShardingSphere-MCP Functionality, Conformance, and LLM end-to-end test suites.
 
 ## Scope
 
-`test/e2e/mcp` covers:
+The MCP E2E workflow contains three independent test suites:
 
-- Distribution startup and configuration.
-- HTTP and STDIO runtimes backed by real MySQL, PostgreSQL, and Proxy processes.
-- Cross-process discovery and execution of tools, resources, prompts, and completions.
-- Official MCP conformance scenarios applicable to the published server capabilities.
-- Real-model MCP usability.
-- Autonomous 10-question MCP Builder evaluation against live metadata and data.
-- Encrypt, Mask, Broadcast, Readwrite-Splitting, Shadow, and Sharding workflow validation.
+- MCP Functionality E2E validates distribution startup and configuration, HTTP and STDIO runtimes backed by real MySQL, PostgreSQL, and Proxy processes, cross-process discovery and execution of tools, resources, prompts, and completions, and the Encrypt, Mask, Broadcast, Readwrite-Splitting, Shadow, and Sharding workflows.
+- MCP Conformance E2E uses the official runner to validate MCP protocol scenarios applicable to the published server capabilities.
+- MCP LLM E2E validates that a real model can use MCP over HTTP or STDIO for read-only queries, metadata discovery, resource navigation, side-effect previews, and error recovery.
 
 The `StreamableHttpMCPServerIT` in `mcp/bootstrap` covers HTTP protocol, session, and security boundaries that require neither Docker nor an external service.
 
@@ -74,13 +70,13 @@ Build the local runtime image:
 sh test/e2e/mcp/src/test/resources/docker/llm-runtime/build-local.sh
 ```
 
-## Run MCP Runtime E2E
+## Run MCP Functionality E2E
 
 MCP E2E runtime configuration is centralized in `test/e2e/mcp/src/test/resources/env/e2e-env.properties`.
 For local runs, edit that file or override the same keys with `-D` system properties.
 
 ```bash
-./mvnw -pl test/e2e/mcp test -Pe2e.mcp
+./mvnw -pl test/e2e/mcp test -Pe2e.mcp.functionality
 ```
 
 ## Run MCP HTTP IT
@@ -91,23 +87,15 @@ This test starts the real HTTP server without connecting to Docker, a database,
 ./mvnw -pl mcp/bootstrap verify
 ```
 
-## Run LLM Usability Suite
+## Run MCP LLM E2E
 
 ```bash
-./mvnw -pl test/e2e/mcp test -Pe2e.mcp.llm -Dtest=LLMUsabilitySuiteE2ETest
+./mvnw -pl test/e2e/mcp test -Pe2e.mcp.llm
 ```
 
-## Run Autonomous MCP Builder Evaluation
+`LLMHttpE2ETest` covers the HTTP scenarios, and `LLMStdioE2ETest` covers an autonomous read-only query over STDIO. Each scenario uses the live `tools/list` response and preserves the model response, structured MCP response, interaction trace, and assertion report. Missing Docker, model, database, or MCP infrastructure fails the selected `llm-e2e` lane instead of converting the failure into a skipped case.
 
-The evaluation loads ten independent read-only questions from `llm/evaluation/mcp-builder-evaluation.xml`.
-Each question starts a fresh MCP session, derives model function definitions from the live `tools/list` response, preserves raw model responses and structured MCP responses, and compares the final answer exactly without correction prompts or expected-answer injection.
-Score-closing runs use an explicit 32768-token context window. Missing Docker, model, database, or MCP infrastructure fails the selected `llm-e2e` lane instead of converting a score failure into a skipped case.
-
-```bash
-./mvnw -pl test/e2e/mcp test -Pe2e.mcp.llm -Dtest=MCPBuilderEvaluationE2ETest
-```
-
-## Official MCP Conformance
+## MCP Conformance E2E
 
 The CI conformance lane pins `modelcontextprotocol/conformance` to commit `21a9a2febd7100d7c17ac1021ee7f2ed9f66a1e0`, passes protocol version `2025-11-25`, and executes only the applicable generic server scenarios declared in the workflow.
 Upstream calls tied to fixed `test_*` tools or resources, unadvertised optional capabilities, and scenarios outside the fixed HTTP transport surface do not apply to this project. Product capabilities remain covered by deterministic E2E tests, and no production test hooks are added for upstream fixtures.
@@ -118,24 +106,24 @@ The packaged server runs with its loopback HTTP configuration so the DNS rebindi
 For local debugging only, connect to an already running OpenAI-compatible endpoint:
 
 ```bash
-./mvnw -pl test/e2e/mcp test -Pe2e.mcp.llm -Dtest=LLMUsabilitySuiteE2ETest -Dmcp.llm.runtime-mode=external-debug -Dmcp.llm.base-url=http://127.0.0.1:8080/v1
+./mvnw -pl test/e2e/mcp test -Pe2e.mcp.llm -Dtest=LLMHttpE2ETest -Dmcp.llm.runtime-mode=external-debug -Dmcp.llm.base-url=http://127.0.0.1:8080/v1
 ```
 
 External debug endpoints cannot be used as score-closing evidence.
 
 ## Artifacts
 
-LLM usability and MCP Builder evaluation artifacts are written under:
+MCP LLM E2E artifacts are written under:
 
 ```text
 test/e2e/mcp/target/llm-e2e/
 ```
 
-Each autonomous evaluation case records the question, expected and actual answer, raw model response, MCP interaction trace, live tool definitions, runtime evidence, and assertion report. Artifact writing redacts secret-shaped values, and scoring runs fail if an unredacted secret pattern or the known model API key is present.
+Each scenario records the question, expected and actual answer, raw model response, MCP interaction trace, live tool definitions, runtime evidence, and assertion report. Artifact writing redacts secret-shaped values, and the test fails if an unredacted secret pattern or the known model API key is present.
 
 GitHub Actions entry points:
 
 - `.github/workflows/e2e-mcp.yml`
 
-This workflow is the mandatory MCP runtime E2E entry point.
+This workflow is the shared entry point for all three MCP E2E suites.
 If a very large PR misses a path-filter match, use `workflow_dispatch` to add manual evidence.
diff --git a/test/e2e/mcp/pom.xml b/test/e2e/mcp/pom.xml
index 236eaa82db3..aae273c7e83 100644
--- a/test/e2e/mcp/pom.xml
+++ b/test/e2e/mcp/pom.xml
@@ -138,7 +138,7 @@
     
     <profiles>
         <profile>
-            <id>e2e.mcp</id>
+            <id>e2e.mcp.functionality</id>
             <properties>
                 <e2e.run.type>DOCKER</e2e.run.type>
                 <mcp.e2e.container.image>apache/shardingsphere-mcp-e2e:local</mcp.e2e.container.image>
diff --git a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/AbstractProductionRuntimeE2ETest.java b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/AbstractFunctionalityE2ETest.java
similarity index 92%
rename from test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/AbstractProductionRuntimeE2ETest.java
rename to test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/AbstractFunctionalityE2ETest.java
index 8a912eaef93..c32ae7ec6ad 100644
--- a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/AbstractProductionRuntimeE2ETest.java
+++ b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/AbstractFunctionalityE2ETest.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.test.e2e.mcp.runtime.production;
+package org.apache.shardingsphere.test.e2e.mcp.functionality;
 
 import org.apache.shardingsphere.test.e2e.mcp.support.runtime.AbstractConfigBackedRuntimeE2ETest;
 import org.apache.shardingsphere.test.e2e.mcp.support.transport.MCPInteractionPayloads;
@@ -23,7 +23,7 @@ import org.apache.shardingsphere.test.e2e.mcp.support.transport.MCPInteractionPa
 import java.util.List;
 import java.util.Map;
 
-abstract class AbstractProductionRuntimeE2ETest extends AbstractConfigBackedRuntimeE2ETest {
+abstract class AbstractFunctionalityE2ETest extends AbstractConfigBackedRuntimeE2ETest {
     
     protected final List<Map<String, Object>> getPayloadItems(final Map<String, Object> payload) {
         return MCPInteractionPayloads.getRequiredObjectList(payload, "items");
diff --git a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/AbstractProductionProxyWorkflowE2ETest.java b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/AbstractHttpProxyWorkflowE2ETest.java
similarity index 98%
rename from test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/AbstractProductionProxyWorkflowE2ETest.java
rename to test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/AbstractHttpProxyWorkflowE2ETest.java
index 55d4dbfa81a..37161c7ceda 100644
--- a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/AbstractProductionProxyWorkflowE2ETest.java
+++ b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/AbstractHttpProxyWorkflowE2ETest.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.test.e2e.mcp.runtime.production;
+package org.apache.shardingsphere.test.e2e.mcp.functionality;
 
 import org.apache.shardingsphere.mcp.support.database.metadata.jdbc.RuntimeDatabaseConfiguration;
 import org.apache.shardingsphere.mcp.support.workflow.descriptor.WorkflowToolDescriptors;
@@ -39,7 +39,7 @@ import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
 
 @TestInstance(TestInstance.Lifecycle.PER_CLASS)
-abstract class AbstractProductionProxyWorkflowE2ETest extends AbstractProductionRuntimeE2ETest {
+abstract class AbstractHttpProxyWorkflowE2ETest extends AbstractFunctionalityE2ETest {
     
     private ProxyWorkflowRuntimeFixture runtimeFixture;
     
diff --git a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/AbstractProductionMySQLRuntimeE2ETest.java b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/AbstractMySQLRuntimeE2ETest.java
similarity index 84%
rename from test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/AbstractProductionMySQLRuntimeE2ETest.java
rename to test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/AbstractMySQLRuntimeE2ETest.java
index 09c57d7af9d..b7c5ba16261 100644
--- a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/AbstractProductionMySQLRuntimeE2ETest.java
+++ b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/AbstractMySQLRuntimeE2ETest.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.test.e2e.mcp.runtime.production;
+package org.apache.shardingsphere.test.e2e.mcp.functionality;
 
 import io.modelcontextprotocol.client.McpSyncClient;
 import io.modelcontextprotocol.spec.McpClientTransport;
@@ -24,6 +24,7 @@ import lombok.AccessLevel;
 import lombok.AllArgsConstructor;
 import lombok.Getter;
 import org.apache.shardingsphere.mcp.support.database.metadata.jdbc.RuntimeDatabaseConfiguration;
+import org.apache.shardingsphere.mcp.support.descriptor.MCPShardingSphereMetadataKeys;
 import org.apache.shardingsphere.test.e2e.mcp.support.runtime.MySQLRuntimeTestSupport;
 import org.apache.shardingsphere.test.e2e.mcp.support.runtime.RuntimeTransport;
 import org.apache.shardingsphere.test.e2e.mcp.support.transport.MCPInteractionPayloads;
@@ -42,13 +43,14 @@ import java.util.Map;
 import java.util.stream.Stream;
 
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.hasItems;
 import static org.hamcrest.Matchers.is;
 import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 @TestInstance(TestInstance.Lifecycle.PER_CLASS)
 @EnabledIf("org.apache.shardingsphere.test.e2e.mcp.env.MCPE2ECondition#isDockerEnabled")
-abstract class AbstractProductionMySQLRuntimeE2ETest extends AbstractTransportParameterizedProductionRuntimeE2ETest {
+abstract class AbstractMySQLRuntimeE2ETest extends AbstractTransportParameterizedE2ETest {
     
     protected static final String LOGICAL_DATABASE_NAME = "logic_db";
     
@@ -90,7 +92,7 @@ abstract class AbstractProductionMySQLRuntimeE2ETest extends AbstractTransportPa
     protected void prepareRuntimeFixture() throws IOException {
         if (!MySQLRuntimeTestSupport.isDockerAvailable()) {
             throw new IllegalStateException(MySQLRuntimeTestSupport.createDockerRequiredMessage(
-                    "Docker is required for the MySQL-backed production runtime E2E test."));
+                    "Docker is required for the MySQL-backed MCP Functionality E2E test."));
         }
         if (useSharedRuntimeFixture()) {
             prepareSharedRuntimeFixture();
@@ -146,20 +148,20 @@ abstract class AbstractProductionMySQLRuntimeE2ETest extends AbstractTransportPa
         return Map.of("database", databaseName, "schema", databaseName, "sql", sql, "execution_mode", "execute");
     }
     
-    protected static Stream<Arguments> dualTransports() {
-        return ProductionRuntimeTransportCases.transports();
+    protected static Stream<Arguments> allTransportCases() {
+        return FunctionalityTransportCases.allTransportCases();
     }
     
-    protected static Stream<Arguments> semanticPrimaryTransport() {
-        return ProductionRuntimeTransportCases.semanticPrimaryTransport();
+    protected static Stream<Arguments> httpTransportCase() {
+        return FunctionalityTransportCases.httpTransportCase();
     }
     
-    protected static Stream<Arguments> assertReadSingleMetadataResourceCases() {
-        return ProductionRuntimeTransportCases.assertReadSingleMetadataResourceCases(LOGICAL_DATABASE_NAME);
+    protected static Stream<Arguments> singleMetadataResourceCases() {
+        return FunctionalityTransportCases.singleMetadataResourceCases(LOGICAL_DATABASE_NAME);
     }
     
-    protected static Stream<Arguments> assertReadCollectionMetadataResourceCases() {
-        return ProductionRuntimeTransportCases.assertReadCollectionMetadataResourceCases(LOGICAL_DATABASE_NAME);
+    protected static Stream<Arguments> collectionMetadataResourceCases() {
+        return FunctionalityTransportCases.collectionMetadataResourceCases(LOGICAL_DATABASE_NAME);
     }
     
     protected Map<String, RuntimeDatabaseConfiguration> createPreparedProgrammaticRuntimeDatabases() throws IOException {
@@ -252,13 +254,13 @@ abstract class AbstractProductionMySQLRuntimeE2ETest extends AbstractTransportPa
     }
     
     protected McpSyncClient createElicitationClient(final RuntimeTransport transport, final List<McpSchema.ElicitRequest> elicitationRequests) throws IOException {
-        return ProductionMCPClientTransportFactory.createElicitationClient(createClientTransport(transport), elicitationRequests, this::createElicitationResult);
+        return MCPClientTransportFactory.createElicitationClient(createClientTransport(transport), elicitationRequests, this::createElicitationResult);
     }
     
     private McpClientTransport createClientTransport(final RuntimeTransport transport) throws IOException {
         return RuntimeTransport.HTTP == transport
-                ? ProductionMCPClientTransportFactory.createHttpClientTransport(getHttpEndpointUri())
-                : ProductionMCPClientTransportFactory.createStdioClientTransport(getConfigFile());
+                ? MCPClientTransportFactory.createHttpClientTransport(getHttpEndpointUri())
+                : MCPClientTransportFactory.createStdioClientTransport(getConfigFile());
     }
     
     private McpSchema.ElicitResult createElicitationResult(final List<McpSchema.ElicitRequest> elicitationRequests,
@@ -271,7 +273,20 @@ abstract class AbstractProductionMySQLRuntimeE2ETest extends AbstractTransportPa
     }
     
     protected void assertElicitationRequest(final List<McpSchema.ElicitRequest> actualRequests) {
-        ProductionMCPClientTransportFactory.assertElicitationRequest(actualRequests);
+        assertThat(actualRequests.size(), is(1));
+        McpSchema.ElicitRequest actual = actualRequests.getFirst();
+        assertThat(actual.meta().get(MCPShardingSphereMetadataKeys.TOOL), is(MASK_PLAN_TOOL_NAME));
+        assertFalse(String.valueOf(actual.meta().get(MCPShardingSphereMetadataKeys.PLAN_ID)).isBlank());
+        Map<String, Object> actualRequestedSchema = actual.requestedSchema();
+        assertThat(actualRequestedSchema.get("type"), is("object"));
+        assertFalse((Boolean) actualRequestedSchema.get("additionalProperties"));
+        Map<String, Object> actualProperties = MCPInteractionPayloads.getRequiredObject(actualRequestedSchema, "properties");
+        assertTrue(actualProperties.containsKey("field_1"));
+        assertTrue(actualProperties.containsKey("field_2"));
+        assertThat(String.valueOf(MCPInteractionPayloads.getRequiredObject(actualProperties, "field_1").get("description")), is("Please provide property `from-x`."));
+        assertThat(String.valueOf(MCPInteractionPayloads.getRequiredObject(actualProperties, "field_2").get("description")), is("Please provide property `to-y`."));
+        assertFalse(actualProperties.keySet().stream().map(String::valueOf).anyMatch(each -> each.contains("secret") || each.contains("password") || each.contains("token")));
+        assertThat(getRequiredStringList(actualRequestedSchema.get("required")), hasItems("field_1", "field_2"));
     }
     
     protected Map<String, Object> getObjectOrEmpty(final Object value) {
diff --git a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/AbstractProductionPostgreSQLRuntimeE2ETest.java b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/AbstractPostgreSQLRuntimeE2ETest.java
similarity index 88%
rename from test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/AbstractProductionPostgreSQLRuntimeE2ETest.java
rename to test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/AbstractPostgreSQLRuntimeE2ETest.java
index f3e1251a430..bdfa81fbee0 100644
--- a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/AbstractProductionPostgreSQLRuntimeE2ETest.java
+++ b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/AbstractPostgreSQLRuntimeE2ETest.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.test.e2e.mcp.runtime.production;
+package org.apache.shardingsphere.test.e2e.mcp.functionality;
 
 import org.apache.shardingsphere.mcp.support.database.metadata.jdbc.RuntimeDatabaseConfiguration;
 import org.apache.shardingsphere.test.e2e.mcp.support.runtime.PostgreSQLRuntimeTestSupport;
@@ -30,7 +30,7 @@ import java.util.Map;
 import java.util.stream.Stream;
 
 @TestInstance(TestInstance.Lifecycle.PER_CLASS)
-abstract class AbstractProductionPostgreSQLRuntimeE2ETest extends AbstractTransportParameterizedProductionRuntimeE2ETest {
+abstract class AbstractPostgreSQLRuntimeE2ETest extends AbstractTransportParameterizedE2ETest {
     
     protected static final String LOGICAL_DATABASE_NAME = "postgres_db";
     
@@ -47,7 +47,7 @@ abstract class AbstractProductionPostgreSQLRuntimeE2ETest extends AbstractTransp
     @Override
     protected void prepareRuntimeFixture() throws IOException {
         if (!PostgreSQLRuntimeTestSupport.isDockerAvailable()) {
-            throw new IllegalStateException("Docker is required for the PostgreSQL-backed production runtime E2E test.");
+            throw new IllegalStateException("Docker is required for the PostgreSQL-backed MCP Functionality E2E test.");
         }
         if (null != container) {
             return;
@@ -77,7 +77,7 @@ abstract class AbstractProductionPostgreSQLRuntimeE2ETest extends AbstractTransp
         return Map.of("database", LOGICAL_DATABASE_NAME, "schema", schema, "sql", sql, "execution_mode", "execute");
     }
     
-    protected static Stream<Arguments> semanticPrimaryTransport() {
-        return ProductionRuntimeTransportCases.semanticPrimaryTransport();
+    protected static Stream<Arguments> httpTransportCase() {
+        return FunctionalityTransportCases.httpTransportCase();
     }
 }
diff --git a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/AbstractTransportParameterizedProductionRuntimeE2ETest.java b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/AbstractTransportParameterizedE2ETest.java
similarity index 85%
rename from test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/AbstractTransportParameterizedProductionRuntimeE2ETest.java
rename to test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/AbstractTransportParameterizedE2ETest.java
index 09c4245c98d..7b69bae0e91 100644
--- a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/AbstractTransportParameterizedProductionRuntimeE2ETest.java
+++ b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/AbstractTransportParameterizedE2ETest.java
@@ -15,12 +15,12 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.test.e2e.mcp.runtime.production;
+package org.apache.shardingsphere.test.e2e.mcp.functionality;
 
 import org.apache.shardingsphere.test.e2e.mcp.support.runtime.RuntimeTransport;
 import org.junit.jupiter.api.AfterEach;
 
-abstract class AbstractTransportParameterizedProductionRuntimeE2ETest extends AbstractProductionRuntimeE2ETest {
+abstract class AbstractTransportParameterizedE2ETest extends AbstractFunctionalityE2ETest {
     
     private RuntimeTransport transport;
     
@@ -36,7 +36,7 @@ abstract class AbstractTransportParameterizedProductionRuntimeE2ETest extends Ab
     @Override
     protected final RuntimeTransport getTransport() {
         if (null == transport) {
-            throw new IllegalStateException("Runtime transport is not selected for current production E2E test.");
+            throw new IllegalStateException("Runtime transport is not selected for current MCP Functionality E2E test.");
         }
         return transport;
     }
diff --git a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/ProductionRuntimeTransportCases.java b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/FunctionalityTransportCases.java
similarity index 80%
rename from test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/ProductionRuntimeTransportCases.java
rename to test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/FunctionalityTransportCases.java
index efe125ef1d6..f3a1fd8410d 100644
--- a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/ProductionRuntimeTransportCases.java
+++ b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/FunctionalityTransportCases.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.test.e2e.mcp.runtime.production;
+package org.apache.shardingsphere.test.e2e.mcp.functionality;
 
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
@@ -26,22 +26,22 @@ import java.util.List;
 import java.util.stream.Stream;
 
 @NoArgsConstructor(access = AccessLevel.PRIVATE)
-final class ProductionRuntimeTransportCases {
+final class FunctionalityTransportCases {
     
-    static Stream<Arguments> transports() {
-        return runtimeTransports().map(each -> Arguments.of(getTransportName(each), each));
+    static Stream<Arguments> allTransportCases() {
+        return allTransports().map(each -> Arguments.of(getTransportName(each), each));
     }
     
-    static Stream<Arguments> semanticPrimaryTransport() {
-        return semanticPrimaryRuntimeTransports().map(each -> Arguments.of(getTransportName(each), each));
+    static Stream<Arguments> httpTransportCase() {
+        return httpTransports().map(each -> Arguments.of(getTransportName(each), each));
     }
     
-    static Stream<Arguments> assertReadSingleMetadataResourceCases(final String logicalDatabaseName) {
-        return semanticPrimaryRuntimeTransports().flatMap(each -> createSingleMetadataResourceCases(logicalDatabaseName, each));
+    static Stream<Arguments> singleMetadataResourceCases(final String logicalDatabaseName) {
+        return httpTransports().flatMap(each -> createSingleMetadataResourceCases(logicalDatabaseName, each));
     }
     
-    static Stream<Arguments> assertReadCollectionMetadataResourceCases(final String logicalDatabaseName) {
-        return semanticPrimaryRuntimeTransports().flatMap(each -> Stream.of(
+    static Stream<Arguments> collectionMetadataResourceCases(final String logicalDatabaseName) {
+        return httpTransports().flatMap(each -> Stream.of(
                 Arguments.of(getTransportName(each) + " schemas list", each, "shardingsphere://databases/" + logicalDatabaseName + "/schemas", "schema", List.of(logicalDatabaseName)),
                 Arguments.of(getTransportName(each) + " tables list", each,
                         "shardingsphere://databases/" + logicalDatabaseName + "/schemas/" + logicalDatabaseName + "/tables", "table", List.of("order_items", "orders")),
@@ -51,7 +51,7 @@ final class ProductionRuntimeTransportCases {
                         "shardingsphere://databases/" + logicalDatabaseName + "/schemas/" + logicalDatabaseName + "/views/active_orders/columns", "column", List.of("order_id", "status"))));
     }
     
-    static Stream<RuntimeTransport> runtimeTransports() {
+    static Stream<RuntimeTransport> allTransports() {
         return Stream.of(RuntimeTransport.HTTP, RuntimeTransport.STDIO);
     }
     
@@ -59,7 +59,7 @@ final class ProductionRuntimeTransportCases {
         return RuntimeTransport.HTTP == transport ? "http" : "stdio";
     }
     
-    private static Stream<RuntimeTransport> semanticPrimaryRuntimeTransports() {
+    private static Stream<RuntimeTransport> httpTransports() {
         return Stream.of(RuntimeTransport.HTTP);
     }
     
diff --git a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/HttpProductionProxyEncryptWorkflowE2ETest.java b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/HttpProxyEncryptWorkflowE2ETest.java
similarity index 95%
rename from test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/HttpProductionProxyEncryptWorkflowE2ETest.java
rename to test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/HttpProxyEncryptWorkflowE2ETest.java
index 3aa237873a3..ff4e87ba422 100644
--- a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/HttpProductionProxyEncryptWorkflowE2ETest.java
+++ b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/HttpProxyEncryptWorkflowE2ETest.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.test.e2e.mcp.runtime.production;
+package org.apache.shardingsphere.test.e2e.mcp.functionality;
 
 import org.apache.shardingsphere.mcp.support.workflow.descriptor.WorkflowToolDescriptors;
 import org.apache.shardingsphere.mcp.support.workflow.model.WorkflowIssueCode;
@@ -36,7 +36,7 @@ import static org.hamcrest.Matchers.hasItem;
 import static org.hamcrest.Matchers.is;
 
 @EnabledIf("org.apache.shardingsphere.test.e2e.mcp.env.MCPE2ECondition#isDockerEnabled")
-class HttpProductionProxyEncryptWorkflowE2ETest extends AbstractProductionProxyWorkflowE2ETest {
+class HttpProxyEncryptWorkflowE2ETest extends AbstractHttpProxyWorkflowE2ETest {
     
     private static final String PLAN_TOOL_NAME = "database_gateway_plan_encrypt_rule";
     
@@ -57,7 +57,7 @@ class HttpProductionProxyEncryptWorkflowE2ETest extends AbstractProductionProxyW
     private static final String TEMPLATE_SECRET_VALUE = "mcp-template-secret-6f2d4a8b";
     
     @Test
-    void assertCompleteEncryptAlgorithmThroughProxy() throws IOException, InterruptedException {
+    void assertCompleteEncryptAlgorithm() throws IOException, InterruptedException {
         useSharedReadOnlyRuntimeFixture();
         try (MCPInteractionClient interactionClient = createOpenedInteractionClient()) {
             Map<String, Object> actual = interactionClient.complete(Map.of("type", "ref/prompt", "name", PLAN_PROMPT_NAME), "algorithm_type", "AE", Map.of());
@@ -66,7 +66,7 @@ class HttpProductionProxyEncryptWorkflowE2ETest extends AbstractProductionProxyW
     }
     
     @Test
-    void assertPlanApplyAndValidateEncryptWorkflowThroughProxy() throws IOException, InterruptedException {
+    void assertPlanApplyAndValidateEncryptWorkflow() throws IOException, InterruptedException {
         try (MCPInteractionClient interactionClient = createOpenedInteractionClient()) {
             Map<String, Object> clarifyingResponse = interactionClient.call(PLAN_TOOL_NAME,
                     Map.of("table", "orders", "column", "status", "natural_language_intent", "encrypt status with reversible encryption, no equality, no like"));
@@ -107,7 +107,7 @@ class HttpProductionProxyEncryptWorkflowE2ETest extends AbstractProductionProxyW
     }
     
     @Test
-    void assertPlanRecommendsAssistedQueryEncryptWorkflowThroughProxy() throws IOException, InterruptedException {
+    void assertPlanRecommendsAssistedQueryEncryptWorkflow() throws IOException, InterruptedException {
         try (MCPInteractionClient interactionClient = createOpenedInteractionClient()) {
             Map<String, Object> actualClarifyingResponse = interactionClient.call(PLAN_TOOL_NAME,
                     Map.of("database", getLogicalDatabaseName(), "table", "orders", "column", "status",
@@ -145,7 +145,7 @@ class HttpProductionProxyEncryptWorkflowE2ETest extends AbstractProductionProxyW
     }
     
     @Test
-    void assertPlanRejectsUnsupportedSecondEncryptColumnThroughProxy() throws IOException, InterruptedException {
+    void assertPlanRejectsUnsupportedSecondEncryptColumn() throws IOException, InterruptedException {
         try (MCPInteractionClient interactionClient = createOpenedInteractionClient()) {
             Map<String, Object> actualFirstPlanResponse = interactionClient.call(PLAN_TOOL_NAME,
                     Map.of("database", getLogicalDatabaseName(), "table", "orders", "column", "status",
@@ -171,7 +171,7 @@ class HttpProductionProxyEncryptWorkflowE2ETest extends AbstractProductionProxyW
     }
     
     @Test
-    void assertApplySupportsManualOnlyExecutionModeThroughProxy() throws IOException, InterruptedException {
+    void assertApplySupportsManualOnlyExecutionMode() throws IOException, InterruptedException {
         try (MCPInteractionClient interactionClient = createOpenedInteractionClient()) {
             Map<String, Object> actualPlannedResponse = interactionClient.call(PLAN_TOOL_NAME,
                     Map.of("database", getLogicalDatabaseName(), "table", "orders", "column", "status",
@@ -191,7 +191,7 @@ class HttpProductionProxyEncryptWorkflowE2ETest extends AbstractProductionProxyW
     }
     
     @Test
-    void assertPlanApplyAndValidateEncryptDropWorkflowThroughProxy() throws IOException, InterruptedException {
+    void assertPlanApplyAndValidateEncryptDropWorkflow() throws IOException, InterruptedException {
         try (MCPInteractionClient interactionClient = createOpenedInteractionClient()) {
             createEncryptRuleWithoutEquality(interactionClient);
             Map<String, Object> actualDropPlanResponse = interactionClient.call(PLAN_TOOL_NAME,
@@ -211,7 +211,7 @@ class HttpProductionProxyEncryptWorkflowE2ETest extends AbstractProductionProxyW
     }
     
     @Test
-    void assertPlanApplyValidateAndReadEncryptResourcesWithCustomAlgorithmThroughProxy() throws IOException, InterruptedException {
+    void assertPlanApplyValidateAndReadEncryptResourcesWithCustomAlgorithm() throws IOException, InterruptedException {
         try (MCPInteractionClient interactionClient = createOpenedInteractionClient()) {
             Map<String, Object> actualPlanResponse = interactionClient.call(PLAN_TOOL_NAME,
                     Map.of("database", getLogicalDatabaseName(), "table", "orders", "column", "status",
diff --git a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/HttpProductionProxyFeatureWorkflowContractE2ETest.java b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/HttpProxyFeatureWorkflowContractE2ETest.java
similarity index 98%
rename from test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/HttpProductionProxyFeatureWorkflowContractE2ETest.java
rename to test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/HttpProxyFeatureWorkflowContractE2ETest.java
index 8d16757b881..1fe48f80d7a 100644
--- a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/HttpProductionProxyFeatureWorkflowContractE2ETest.java
+++ b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/HttpProxyFeatureWorkflowContractE2ETest.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.test.e2e.mcp.runtime.production;
+package org.apache.shardingsphere.test.e2e.mcp.functionality;
 
 import org.apache.shardingsphere.mcp.support.workflow.descriptor.WorkflowToolDescriptors;
 import org.apache.shardingsphere.mcp.support.workflow.model.WorkflowIssueCode;
@@ -38,7 +38,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 @EnabledIf("org.apache.shardingsphere.test.e2e.mcp.env.MCPE2ECondition#isDockerEnabled")
-class HttpProductionProxyFeatureWorkflowContractE2ETest extends AbstractProductionProxyWorkflowE2ETest {
+class HttpProxyFeatureWorkflowContractE2ETest extends AbstractHttpProxyWorkflowE2ETest {
     
     private static final String APPLY_TOOL_NAME = WorkflowToolDescriptors.APPLY_TOOL_NAME;
     
@@ -83,7 +83,7 @@ class HttpProductionProxyFeatureWorkflowContractE2ETest extends AbstractProducti
             "register storage unit", "alter storage unit", "unregister storage unit");
     
     @Test
-    void assertBroadcastWorkflowCanBeAppliedAndValidatedThroughProxy() throws IOException, InterruptedException {
+    void assertBroadcastWorkflowCanBeAppliedAndValidated() throws IOException, InterruptedException {
         try (MCPInteractionClient interactionClient = createOpenedInteractionClient()) {
             Map<String, Object> arguments = Map.of("database", getLogicalDatabaseName(), "operation_type", "create", "tables", "orders");
             Map<String, Object> actualPlanResponse = interactionClient.call(BROADCAST_PLAN_TOOL_NAME, arguments);
@@ -105,7 +105,7 @@ class HttpProductionProxyFeatureWorkflowContractE2ETest extends AbstractProducti
     }
     
     @Test
-    void assertReadwriteSplittingWorkflowCanBeAppliedAndValidatedThroughProxy() throws IOException, InterruptedException {
+    void assertReadwriteSplittingWorkflowCanBeAppliedAndValidated() throws IOException, InterruptedException {
         try (MCPInteractionClient interactionClient = createOpenedInteractionClient()) {
             assertStorageUnitsExposeWorkflowTopology(interactionClient);
             planApplyAndValidateWorkflow(interactionClient, READWRITE_SPLITTING_PLAN_TOOL_NAME,
@@ -201,7 +201,7 @@ class HttpProductionProxyFeatureWorkflowContractE2ETest extends AbstractProducti
     }
     
     @Test
-    void assertShardingAutoTableAndAuditorCleanupThroughProxy() throws IOException, InterruptedException {
+    void assertShardingAutoTableAndAuditorCleanup() throws IOException, InterruptedException {
         try (MCPInteractionClient interactionClient = createOpenedInteractionClient()) {
             String unusedAuditorName = "fixture_unused_auditor";
             assertThat(findItemByField(getPayloadItems(interactionClient.readResource(String.format(
@@ -244,7 +244,7 @@ class HttpProductionProxyFeatureWorkflowContractE2ETest extends AbstractProducti
     }
     
     @Test
-    void assertShardingWorkflowCanBeAppliedAndValidatedThroughProxy() throws IOException, InterruptedException {
+    void assertShardingWorkflowCanBeAppliedAndValidated() throws IOException, InterruptedException {
         try (MCPInteractionClient interactionClient = createOpenedInteractionClient()) {
             applyAndValidateWorkflow(interactionClient, SHARDING_KEY_GENERATOR_PLAN_TOOL_NAME,
                     Map.of("database", getLogicalDatabaseName(), "operation_type", "create", "key_generator", "snowflake_generator",
diff --git a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/HttpProductionProxyMaskWorkflowE2ETest.java b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/HttpProxyMaskWorkflowE2ETest.java
similarity index 93%
rename from test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/HttpProductionProxyMaskWorkflowE2ETest.java
rename to test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/HttpProxyMaskWorkflowE2ETest.java
index 7dd64625a2a..14c69ebf3c9 100644
--- a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/HttpProductionProxyMaskWorkflowE2ETest.java
+++ b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/HttpProxyMaskWorkflowE2ETest.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.test.e2e.mcp.runtime.production;
+package org.apache.shardingsphere.test.e2e.mcp.functionality;
 
 import org.apache.shardingsphere.mcp.support.workflow.descriptor.WorkflowToolDescriptors;
 import org.apache.shardingsphere.mcp.support.workflow.model.WorkflowIssueCode;
@@ -34,7 +34,7 @@ import static org.hamcrest.Matchers.hasItem;
 import static org.hamcrest.Matchers.is;
 
 @EnabledIf("org.apache.shardingsphere.test.e2e.mcp.env.MCPE2ECondition#isDockerEnabled")
-class HttpProductionProxyMaskWorkflowE2ETest extends AbstractProductionProxyWorkflowE2ETest {
+class HttpProxyMaskWorkflowE2ETest extends AbstractHttpProxyWorkflowE2ETest {
     
     private static final String PLAN_TOOL_NAME = "database_gateway_plan_mask_rule";
     
@@ -49,7 +49,7 @@ class HttpProductionProxyMaskWorkflowE2ETest extends AbstractProductionProxyWork
     private static final String TABLE_RULES_RESOURCE_URI = "shardingsphere://features/mask/databases/%s/tables/%s/rules";
     
     @Test
-    void assertCompleteMaskAlgorithmThroughProxy() throws IOException, InterruptedException {
+    void assertCompleteMaskAlgorithm() throws IOException, InterruptedException {
         useSharedReadOnlyRuntimeFixture();
         try (MCPInteractionClient interactionClient = createOpenedInteractionClient()) {
             Map<String, Object> actual = interactionClient.complete(Map.of("type", "ref/prompt", "name", PLAN_PROMPT_NAME), "algorithm_type", "KEEP", Map.of());
@@ -58,7 +58,7 @@ class HttpProductionProxyMaskWorkflowE2ETest extends AbstractProductionProxyWork
     }
     
     @Test
-    void assertPlanApplyAndValidateMaskWorkflowThroughProxy() throws IOException, InterruptedException {
+    void assertPlanApplyAndValidateMaskWorkflow() throws IOException, InterruptedException {
         try (MCPInteractionClient interactionClient = createOpenedInteractionClient()) {
             Map<String, Object> actualCreatePlanResponse = interactionClient.call(PLAN_TOOL_NAME,
                     Map.of("database", getLogicalDatabaseName(), "table", "orders", "column", "status",
@@ -78,7 +78,7 @@ class HttpProductionProxyMaskWorkflowE2ETest extends AbstractProductionProxyWork
     }
     
     @Test
-    void assertPlanApplyAndValidateMaskDropWorkflowThroughProxy() throws IOException, InterruptedException {
+    void assertPlanApplyAndValidateMaskDropWorkflow() throws IOException, InterruptedException {
         try (MCPInteractionClient interactionClient = createOpenedInteractionClient()) {
             createMaskRule(interactionClient);
             Map<String, Object> actualDropPlanResponse = interactionClient.call(PLAN_TOOL_NAME,
@@ -94,7 +94,7 @@ class HttpProductionProxyMaskWorkflowE2ETest extends AbstractProductionProxyWork
     }
     
     @Test
-    void assertPlanRejectsSecondMaskColumnThroughProxy() throws IOException, InterruptedException {
+    void assertPlanRejectsSecondMaskColumn() throws IOException, InterruptedException {
         try (MCPInteractionClient interactionClient = createOpenedInteractionClient()) {
             createMaskRule(interactionClient);
             Map<String, Object> actualSecondCreatePlanResponse = interactionClient.call(PLAN_TOOL_NAME,
@@ -108,7 +108,7 @@ class HttpProductionProxyMaskWorkflowE2ETest extends AbstractProductionProxyWork
     }
     
     @Test
-    void assertPlanRecommendApplyAndValidateMaskWorkflowFromNaturalLanguageThroughProxy() throws IOException, InterruptedException {
+    void assertPlanRecommendsApplyAndValidateMaskWorkflowFromNaturalLanguage() throws IOException, InterruptedException {
         try (MCPInteractionClient interactionClient = createOpenedInteractionClient()) {
             Map<String, Object> actualClarifyingResponse = interactionClient.call(PLAN_TOOL_NAME,
                     Map.of("database", getLogicalDatabaseName(), "table", "orders", "column", "status",
@@ -134,7 +134,7 @@ class HttpProductionProxyMaskWorkflowE2ETest extends AbstractProductionProxyWork
     }
     
     @Test
-    void assertPlanApplyValidateAndReadMaskResourcesWithCustomAlgorithmThroughProxy() throws IOException, InterruptedException {
+    void assertPlanApplyValidateAndReadMaskResourcesWithCustomAlgorithm() throws IOException, InterruptedException {
         try (MCPInteractionClient interactionClient = createOpenedInteractionClient()) {
             Map<String, Object> actualPlanResponse = interactionClient.call(PLAN_TOOL_NAME,
                     Map.of("database", getLogicalDatabaseName(), "table", "orders", "column", "status",
diff --git a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/HttpProductionProxySecretReferenceWorkflowE2ETest.java b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/HttpProxySecretReferenceWorkflowE2ETest.java
similarity index 95%
rename from test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/HttpProductionProxySecretReferenceWorkflowE2ETest.java
rename to test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/HttpProxySecretReferenceWorkflowE2ETest.java
index db27892e9b3..a4a23652c91 100644
--- a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/HttpProductionProxySecretReferenceWorkflowE2ETest.java
+++ b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/HttpProxySecretReferenceWorkflowE2ETest.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.test.e2e.mcp.runtime.production;
+package org.apache.shardingsphere.test.e2e.mcp.functionality;
 
 import org.apache.shardingsphere.mcp.support.diagnostic.MCPDiagnosticCategory;
 import org.apache.shardingsphere.mcp.support.workflow.descriptor.WorkflowToolDescriptors;
@@ -35,7 +35,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 @EnabledIf("org.apache.shardingsphere.test.e2e.mcp.env.MCPE2ECondition#isDockerEnabled")
-class HttpProductionProxySecretReferenceWorkflowE2ETest extends AbstractProductionProxyWorkflowE2ETest {
+class HttpProxySecretReferenceWorkflowE2ETest extends AbstractHttpProxyWorkflowE2ETest {
     
     private static final String PLAN_TOOL_NAME = "database_gateway_plan_encrypt_rule";
     
@@ -44,7 +44,7 @@ class HttpProductionProxySecretReferenceWorkflowE2ETest extends AbstractProducti
     private static final String RULES_RESOURCE_URI = "shardingsphere://features/encrypt/databases/%s/rules";
     
     @Test
-    void assertSecretReferenceApplyRequiresManualExecutionThroughProxy() throws IOException, InterruptedException {
+    void assertSecretReferenceApplyRequiresManualExecution() throws IOException, InterruptedException {
         try (MCPInteractionClient interactionClient = createOpenedInteractionClient()) {
             Map<String, Object> planResponse = planSecretReferencedEncryptRule(interactionClient);
             String planId = String.valueOf(planResponse.get("plan_id"));
diff --git a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/ProductionMCPClientTransportFactory.java b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/MCPClientTransportFactory.java
similarity index 61%
rename from test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/ProductionMCPClientTransportFactory.java
rename to test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/MCPClientTransportFactory.java
index 724050f1ba8..252b4dc8b39 100644
--- a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/ProductionMCPClientTransportFactory.java
+++ b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/MCPClientTransportFactory.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.test.e2e.mcp.runtime.production;
+package org.apache.shardingsphere.test.e2e.mcp.functionality;
 
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
@@ -29,8 +29,6 @@ import io.modelcontextprotocol.spec.McpSchema;
 import io.modelcontextprotocol.spec.ProtocolVersions;
 import org.apache.shardingsphere.mcp.bootstrap.MCPBootstrap;
 import org.apache.shardingsphere.mcp.bootstrap.transport.MCPTransportJsonMapperFactory;
-import org.apache.shardingsphere.mcp.support.descriptor.MCPShardingSphereMetadataKeys;
-import org.apache.shardingsphere.test.e2e.mcp.support.transport.MCPInteractionPayloads;
 import org.apache.shardingsphere.test.e2e.mcp.support.transport.client.MCPStdioLogbackConfiguration;
 
 import java.io.IOException;
@@ -39,28 +37,19 @@ import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.time.Duration;
 import java.util.List;
-import java.util.Map;
 import java.util.function.BiFunction;
 
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.hasItems;
-import static org.hamcrest.Matchers.is;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
 @NoArgsConstructor(access = AccessLevel.PRIVATE)
-final class ProductionMCPClientTransportFactory {
-    
-    private static final String STDIO_LOGBACK_CONFIG_FILE_NAME = "mcp-e2e-sdk-stdio-logback.xml";
+final class MCPClientTransportFactory {
     
-    private static final String MASK_PLAN_TOOL_NAME = "database_gateway_plan_mask_rule";
+    private static final String STDIO_LOGBACK_CONFIG_FILE_NAME = "mcp-functionality-e2e-sdk-stdio-logback.xml";
     
     private static final List<String> SUPPORTED_PROTOCOL_VERSIONS = List.of(ProtocolVersions.MCP_2025_11_25);
     
     static McpSyncClient createElicitationClient(final McpClientTransport clientTransport, final List<McpSchema.ElicitRequest> elicitationRequests,
                                                  final BiFunction<List<McpSchema.ElicitRequest>, McpSchema.ElicitRequest, McpSchema.ElicitResult> elicitationHandler) {
         return McpClient.sync(clientTransport)
-                .clientInfo(new McpSchema.Implementation("mcp-e2e-elicitation", "MCP E2E Elicitation", "1.0.0"))
+                .clientInfo(new McpSchema.Implementation("mcp-functionality-e2e-elicitation", "MCP Functionality E2E Elicitation", "1.0.0"))
                 .capabilities(McpSchema.ClientCapabilities.builder().elicitation().build())
                 .requestTimeout(Duration.ofSeconds(30L))
                 .initializationTimeout(Duration.ofSeconds(30L))
@@ -80,27 +69,6 @@ final class ProductionMCPClientTransportFactory {
                 .build());
     }
     
-    static void assertElicitationRequest(final List<McpSchema.ElicitRequest> actualRequests) {
-        assertThat(actualRequests.size(), is(1));
-        McpSchema.ElicitRequest actual = actualRequests.getFirst();
-        assertThat(actual.meta().get(MCPShardingSphereMetadataKeys.TOOL), is(MASK_PLAN_TOOL_NAME));
-        assertFalse(String.valueOf(actual.meta().get(MCPShardingSphereMetadataKeys.PLAN_ID)).isBlank());
-        Map<String, Object> actualRequestedSchema = actual.requestedSchema();
-        assertThat(actualRequestedSchema.get("type"), is("object"));
-        assertFalse((Boolean) actualRequestedSchema.get("additionalProperties"));
-        Map<String, Object> actualProperties = MCPInteractionPayloads.getRequiredObject(actualRequestedSchema, "properties");
-        assertTrue(actualProperties.containsKey("field_1"));
-        assertTrue(actualProperties.containsKey("field_2"));
-        assertThat(String.valueOf(MCPInteractionPayloads.getRequiredObject(actualProperties, "field_1").get("description")), is("Please provide property `from-x`."));
-        assertThat(String.valueOf(MCPInteractionPayloads.getRequiredObject(actualProperties, "field_2").get("description")), is("Please provide property `to-y`."));
-        assertFalse(actualProperties.keySet().stream().map(String::valueOf).anyMatch(each -> each.contains("secret") || each.contains("password") || each.contains("token")));
-        assertThat(getRequiredStringList(actualRequestedSchema.get("required")), hasItems("field_1", "field_2"));
-    }
-    
-    private static List<String> getRequiredStringList(final Object value) {
-        return ((List<?>) value).stream().map(String::valueOf).toList();
-    }
-    
     private static final class ProtocolAwareStdioClientTransport extends StdioClientTransport {
         
         private ProtocolAwareStdioClientTransport(final ServerParameters params) {
diff --git a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/ProductionMCPClientTransportFactoryTest.java b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/MCPClientTransportFactoryTest.java
similarity index 82%
rename from test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/ProductionMCPClientTransportFactoryTest.java
rename to test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/MCPClientTransportFactoryTest.java
index 2560f39006a..507c6115fb1 100644
--- a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/ProductionMCPClientTransportFactoryTest.java
+++ b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/MCPClientTransportFactoryTest.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.test.e2e.mcp.runtime.production;
+package org.apache.shardingsphere.test.e2e.mcp.functionality;
 
 import io.modelcontextprotocol.client.transport.StdioClientTransport;
 import io.modelcontextprotocol.spec.McpClientTransport;
@@ -31,11 +31,11 @@ import java.util.List;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
 
-class ProductionMCPClientTransportFactoryTest {
+class MCPClientTransportFactoryTest {
     
     @Test
     void assertCreateHttpClientTransport() {
-        McpClientTransport actual = ProductionMCPClientTransportFactory.createHttpClientTransport(URI.create("http://127.0.0.1:8080/mcp"));
+        McpClientTransport actual = MCPClientTransportFactory.createHttpClientTransport(URI.create("http://127.0.0.1:8080/mcp"));
         try {
             assertThat(actual.protocolVersions(), is(List.of(ProtocolVersions.MCP_2025_11_25)));
         } finally {
@@ -45,7 +45,7 @@ class ProductionMCPClientTransportFactoryTest {
     
     @Test
     void assertCreateStdioClientTransport(@TempDir final Path tempDir) throws IOException {
-        StdioClientTransport actual = ProductionMCPClientTransportFactory.createStdioClientTransport(tempDir.resolve("mcp.yaml"));
+        StdioClientTransport actual = MCPClientTransportFactory.createStdioClientTransport(tempDir.resolve("mcp.yaml"));
         try {
             assertThat(actual.protocolVersions(), is(List.of(ProtocolVersions.MCP_2025_11_25)));
         } finally {
diff --git a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/ProductionMySQLRuntimeE2ETest.java b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/MySQLMetadataE2ETest.java
similarity index 76%
rename from test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/ProductionMySQLRuntimeE2ETest.java
rename to test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/MySQLMetadataE2ETest.java
index e7d38238591..d11c7df9607 100644
--- a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/ProductionMySQLRuntimeE2ETest.java
+++ b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/MySQLMetadataE2ETest.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.test.e2e.mcp.runtime.production;
+package org.apache.shardingsphere.test.e2e.mcp.functionality;
 
 import org.apache.shardingsphere.test.e2e.mcp.support.runtime.RuntimeTransport;
 import org.apache.shardingsphere.test.e2e.mcp.support.transport.MCPPayloadAssertions;
@@ -36,7 +36,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 @EnabledIf("org.apache.shardingsphere.test.e2e.mcp.env.MCPE2ECondition#isDockerEnabled")
-class ProductionMySQLRuntimeE2ETest extends AbstractProductionMySQLRuntimeE2ETest {
+class MySQLMetadataE2ETest extends AbstractMySQLRuntimeE2ETest {
     
     @Override
     protected boolean useSharedRuntimeFixture() {
@@ -44,8 +44,8 @@ class ProductionMySQLRuntimeE2ETest extends AbstractProductionMySQLRuntimeE2ETes
     }
     
     @ParameterizedTest(name = "{0}")
-    @MethodSource("semanticPrimaryTransport")
-    void assertReadCapabilitiesWithActualMySQLBackend(final String name, final RuntimeTransport transport) throws IOException, InterruptedException {
+    @MethodSource("httpTransportCase")
+    void assertReadCapabilities(final String name, final RuntimeTransport transport) throws IOException, InterruptedException {
         useTransport(transport);
         try (MCPInteractionClient interactionClient = createOpenedInteractionClient()) {
             Map<String, Object> actual = interactionClient.readResource("shardingsphere://databases/logic_db/capabilities");
@@ -55,8 +55,8 @@ class ProductionMySQLRuntimeE2ETest extends AbstractProductionMySQLRuntimeE2ETes
     }
     
     @ParameterizedTest(name = "{0}")
-    @MethodSource("semanticPrimaryTransport")
-    void assertReadDatabasesResourceWithActualMySQLBackend(final String name, final RuntimeTransport transport) throws IOException, InterruptedException {
+    @MethodSource("httpTransportCase")
+    void assertReadDatabasesResource(final String name, final RuntimeTransport transport) throws IOException, InterruptedException {
         useTransport(transport);
         try (MCPInteractionClient interactionClient = createOpenedInteractionClient()) {
             MCPPayloadAssertions.assertSingleItemValue(interactionClient.readResource("shardingsphere://databases"), "database", LOGICAL_DATABASE_NAME);
@@ -64,9 +64,9 @@ class ProductionMySQLRuntimeE2ETest extends AbstractProductionMySQLRuntimeE2ETes
     }
     
     @ParameterizedTest(name = "{0}")
-    @MethodSource("assertReadSingleMetadataResourceCases")
-    void assertReadSingleMetadataResourceWithActualMySQLBackend(final String name, final RuntimeTransport transport,
-                                                                final String resourceUri, final String key, final String expectedValue) throws IOException, InterruptedException {
+    @MethodSource("singleMetadataResourceCases")
+    void assertReadSingleMetadataResource(final String name, final RuntimeTransport transport,
+                                          final String resourceUri, final String key, final String expectedValue) throws IOException, InterruptedException {
         useTransport(transport);
         try (MCPInteractionClient interactionClient = createOpenedInteractionClient()) {
             MCPPayloadAssertions.assertSingleItemValue(interactionClient.readResource(resourceUri), key, expectedValue);
@@ -74,9 +74,9 @@ class ProductionMySQLRuntimeE2ETest extends AbstractProductionMySQLRuntimeE2ETes
     }
     
     @ParameterizedTest(name = "{0}")
-    @MethodSource("assertReadCollectionMetadataResourceCases")
-    void assertReadCollectionMetadataResourceWithActualMySQLBackend(final String name, final RuntimeTransport transport,
-                                                                    final String resourceUri, final String key, final List<String> expectedNames) throws IOException, InterruptedException {
+    @MethodSource("collectionMetadataResourceCases")
+    void assertReadCollectionMetadataResource(final String name, final RuntimeTransport transport,
+                                              final String resourceUri, final String key, final List<String> expectedNames) throws IOException, InterruptedException {
         useTransport(transport);
         try (MCPInteractionClient interactionClient = createOpenedInteractionClient()) {
             MCPPayloadAssertions.assertItemValues(interactionClient.readResource(resourceUri), key, expectedNames);
@@ -84,8 +84,8 @@ class ProductionMySQLRuntimeE2ETest extends AbstractProductionMySQLRuntimeE2ETes
     }
     
     @ParameterizedTest(name = "{0}")
-    @MethodSource("semanticPrimaryTransport")
-    void assertReadTableDetailWithActualMySQLBackend(final String name, final RuntimeTransport transport) throws IOException, InterruptedException {
+    @MethodSource("httpTransportCase")
+    void assertReadTableDetail(final String name, final RuntimeTransport transport) throws IOException, InterruptedException {
         useTransport(transport);
         try (MCPInteractionClient interactionClient = createOpenedInteractionClient()) {
             List<Map<String, Object>> items = getPayloadItems(interactionClient.readResource(
@@ -99,8 +99,8 @@ class ProductionMySQLRuntimeE2ETest extends AbstractProductionMySQLRuntimeE2ETes
     }
     
     @ParameterizedTest(name = "{0}")
-    @MethodSource("semanticPrimaryTransport")
-    void assertSearchMetadataTablesAndViewsWithActualMySQLBackend(final String name, final RuntimeTransport transport) throws IOException, InterruptedException {
+    @MethodSource("httpTransportCase")
+    void assertSearchMetadataTablesAndViews(final String name, final RuntimeTransport transport) throws IOException, InterruptedException {
         useTransport(transport);
         try (MCPInteractionClient interactionClient = createOpenedInteractionClient()) {
             List<Map<String, Object>> items = getPayloadItems(interactionClient.call("database_gateway_search_metadata",
@@ -110,8 +110,8 @@ class ProductionMySQLRuntimeE2ETest extends AbstractProductionMySQLRuntimeE2ETes
     }
     
     @ParameterizedTest(name = "{0}")
-    @MethodSource("semanticPrimaryTransport")
-    void assertValidateRuntimeDatabaseWithActualMySQLBackend(final String name, final RuntimeTransport transport) throws IOException, InterruptedException {
+    @MethodSource("httpTransportCase")
+    void assertValidateRuntimeDatabase(final String name, final RuntimeTransport transport) throws IOException, InterruptedException {
         useTransport(transport);
         try (MCPInteractionClient interactionClient = createOpenedInteractionClient()) {
             Map<String, Object> actual = interactionClient.call(
@@ -126,8 +126,8 @@ class ProductionMySQLRuntimeE2ETest extends AbstractProductionMySQLRuntimeE2ETes
     }
     
     @ParameterizedTest(name = "{0}")
-    @MethodSource("semanticPrimaryTransport")
-    void assertSearchMetadataPaginationWithActualMySQLBackend(final String name, final RuntimeTransport transport) throws IOException, InterruptedException {
+    @MethodSource("httpTransportCase")
+    void assertSearchMetadataPagination(final String name, final RuntimeTransport transport) throws IOException, InterruptedException {
         useTransport(transport);
         try (MCPInteractionClient interactionClient = createOpenedInteractionClient()) {
             Map<String, Object> firstPage = interactionClient.call("database_gateway_search_metadata",
@@ -146,8 +146,8 @@ class ProductionMySQLRuntimeE2ETest extends AbstractProductionMySQLRuntimeE2ETes
     }
     
     @ParameterizedTest(name = "{0}")
-    @MethodSource("semanticPrimaryTransport")
-    void assertReadViewsWithActualMySQLBackend(final String name, final RuntimeTransport transport) throws IOException, InterruptedException {
+    @MethodSource("httpTransportCase")
+    void assertReadViews(final String name, final RuntimeTransport transport) throws IOException, InterruptedException {
         useTransport(transport);
         try (MCPInteractionClient interactionClient = createOpenedInteractionClient()) {
             List<Map<String, Object>> items = getPayloadItems(interactionClient.readResource(
@@ -158,8 +158,8 @@ class ProductionMySQLRuntimeE2ETest extends AbstractProductionMySQLRuntimeE2ETes
     }
     
     @ParameterizedTest(name = "{0}")
-    @MethodSource("semanticPrimaryTransport")
-    void assertReadIndexesWithActualMySQLBackend(final String name, final RuntimeTransport transport) throws IOException, InterruptedException {
+    @MethodSource("httpTransportCase")
+    void assertReadIndexes(final String name, final RuntimeTransport transport) throws IOException, InterruptedException {
         useTransport(transport);
         try (MCPInteractionClient interactionClient = createOpenedInteractionClient()) {
             List<String> actualIndexNames = getPayloadItems(interactionClient.readResource(
diff --git a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/ProductionMySQLReadOnlySQLRuntimeE2ETest.java b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/MySQLReadOnlySQLE2ETest.java
similarity index 84%
rename from test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/ProductionMySQLReadOnlySQLRuntimeE2ETest.java
rename to test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/MySQLReadOnlySQLE2ETest.java
index fb099222a58..e631abd8775 100644
--- a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/ProductionMySQLReadOnlySQLRuntimeE2ETest.java
+++ b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/MySQLReadOnlySQLE2ETest.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.test.e2e.mcp.runtime.production;
+package org.apache.shardingsphere.test.e2e.mcp.functionality;
 
 import io.modelcontextprotocol.client.McpSyncClient;
 import io.modelcontextprotocol.spec.McpSchema;
@@ -38,7 +38,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 @EnabledIf("org.apache.shardingsphere.test.e2e.mcp.env.MCPE2ECondition#isDockerEnabled")
-class ProductionMySQLReadOnlySQLRuntimeE2ETest extends AbstractProductionMySQLRuntimeE2ETest {
+class MySQLReadOnlySQLE2ETest extends AbstractMySQLRuntimeE2ETest {
     
     @Override
     protected boolean useSharedRuntimeFixture() {
@@ -46,8 +46,8 @@ class ProductionMySQLReadOnlySQLRuntimeE2ETest extends AbstractProductionMySQLRu
     }
     
     @ParameterizedTest(name = "{0}")
-    @MethodSource("semanticPrimaryTransport")
-    void assertExecuteSelectWithActualMySQLBackend(final String name, final RuntimeTransport transport) throws IOException, InterruptedException {
+    @MethodSource("httpTransportCase")
+    void assertExecuteSelect(final String name, final RuntimeTransport transport) throws IOException, InterruptedException {
         useTransport(transport);
         try (MCPInteractionClient interactionClient = createOpenedInteractionClient()) {
             Map<String, Object> actual = interactionClient.call("database_gateway_execute_query",
@@ -57,8 +57,8 @@ class ProductionMySQLReadOnlySQLRuntimeE2ETest extends AbstractProductionMySQLRu
     }
     
     @ParameterizedTest(name = "{0}")
-    @MethodSource("semanticPrimaryTransport")
-    void assertExecuteSelectWithTruncationWithActualMySQLBackend(final String name, final RuntimeTransport transport) throws IOException, InterruptedException {
+    @MethodSource("httpTransportCase")
+    void assertExecuteSelectWithTruncation(final String name, final RuntimeTransport transport) throws IOException, InterruptedException {
         useTransport(transport);
         try (MCPInteractionClient interactionClient = createOpenedInteractionClient()) {
             Map<String, Object> actual = interactionClient.call("database_gateway_execute_query",
@@ -70,8 +70,8 @@ class ProductionMySQLReadOnlySQLRuntimeE2ETest extends AbstractProductionMySQLRu
     }
     
     @ParameterizedTest(name = "{0}")
-    @MethodSource("semanticPrimaryTransport")
-    void assertExecuteExplainSelectWithActualMySQLBackend(final String name, final RuntimeTransport transport) throws IOException, InterruptedException {
+    @MethodSource("httpTransportCase")
+    void assertExecuteExplainSelect(final String name, final RuntimeTransport transport) throws IOException, InterruptedException {
         useTransport(transport);
         try (MCPInteractionClient interactionClient = createOpenedInteractionClient()) {
             Map<String, Object> actual = interactionClient.call("database_gateway_execute_explain_query",
@@ -84,8 +84,8 @@ class ProductionMySQLReadOnlySQLRuntimeE2ETest extends AbstractProductionMySQLRu
     }
     
     @ParameterizedTest(name = "{0}")
-    @MethodSource("semanticPrimaryTransport")
-    void assertExecuteQueryTimeoutWithActualMySQLBackend(final String name, final RuntimeTransport transport) throws IOException, InterruptedException {
+    @MethodSource("httpTransportCase")
+    void assertExecuteQueryTimeout(final String name, final RuntimeTransport transport) throws IOException, InterruptedException {
         useTransport(transport);
         try (MCPInteractionClient interactionClient = createOpenedInteractionClient()) {
             Map<String, Object> actual = interactionClient.call("database_gateway_execute_query",
@@ -95,8 +95,8 @@ class ProductionMySQLReadOnlySQLRuntimeE2ETest extends AbstractProductionMySQLRu
     }
     
     @ParameterizedTest(name = "{0}")
-    @MethodSource("dualTransports")
-    void assertElicitMaskPlanningWithActualMySQLBackend(final String name, final RuntimeTransport transport) throws IOException {
+    @MethodSource("allTransportCases")
+    void assertElicitMaskPlanning(final String name, final RuntimeTransport transport) throws IOException {
         useTransport(transport);
         List<McpSchema.ElicitRequest> actualElicitationRequests = new CopyOnWriteArrayList<>();
         try (McpSyncClient client = createElicitationClient(transport, actualElicitationRequests)) {
@@ -126,8 +126,8 @@ class ProductionMySQLReadOnlySQLRuntimeE2ETest extends AbstractProductionMySQLRu
     }
     
     @ParameterizedTest(name = "{0}")
-    @MethodSource("semanticPrimaryTransport")
-    void assertRejectSequenceResourceWithActualMySQLBackend(final String name, final RuntimeTransport transport) throws IOException, InterruptedException {
+    @MethodSource("httpTransportCase")
+    void assertRejectSequenceResource(final String name, final RuntimeTransport transport) throws IOException, InterruptedException {
         useTransport(transport);
         try (MCPInteractionClient interactionClient = createOpenedInteractionClient()) {
             Map<String, Object> actual = interactionClient.readResource(
@@ -138,8 +138,8 @@ class ProductionMySQLReadOnlySQLRuntimeE2ETest extends AbstractProductionMySQLRu
     }
     
     @ParameterizedTest(name = "{0}")
-    @MethodSource("semanticPrimaryTransport")
-    void assertAiNativeDeterministicInteractionLoopWithActualMySQLBackend(final String name, final RuntimeTransport transport) throws IOException, InterruptedException {
+    @MethodSource("httpTransportCase")
+    void assertAiNativeDeterministicInteractionLoop(final String name, final RuntimeTransport transport) throws IOException, InterruptedException {
         useTransport(transport);
         try (MCPInteractionClient interactionClient = createOpenedInteractionClient()) {
             assertAiNativeGuidance(interactionClient.readResource("shardingsphere://guidance"));
diff --git a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/ProductionMySQLSQLRuntimeE2ETest.java b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/MySQLSQLExecutionE2ETest.java
similarity index 83%
rename from test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/ProductionMySQLSQLRuntimeE2ETest.java
rename to test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/MySQLSQLExecutionE2ETest.java
index 1e784c097be..e50beeb2fdb 100644
--- a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/ProductionMySQLSQLRuntimeE2ETest.java
+++ b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/MySQLSQLExecutionE2ETest.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.test.e2e.mcp.runtime.production;
+package org.apache.shardingsphere.test.e2e.mcp.functionality;
 
 import org.apache.shardingsphere.test.e2e.mcp.support.runtime.MySQLRuntimeTestSupport;
 import org.apache.shardingsphere.test.e2e.mcp.support.runtime.RuntimeTransport;
@@ -37,11 +37,11 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 @EnabledIf("org.apache.shardingsphere.test.e2e.mcp.env.MCPE2ECondition#isDockerEnabled")
-class ProductionMySQLSQLRuntimeE2ETest extends AbstractProductionMySQLRuntimeE2ETest {
+class MySQLSQLExecutionE2ETest extends AbstractMySQLRuntimeE2ETest {
     
     @ParameterizedTest(name = "{0}")
-    @MethodSource("semanticPrimaryTransport")
-    void assertExecuteUpdateWithActualMySQLBackend(final String name, final RuntimeTransport transport) throws SQLException, IOException, InterruptedException {
+    @MethodSource("httpTransportCase")
+    void assertExecuteUpdate(final String name, final RuntimeTransport transport) throws SQLException, IOException, InterruptedException {
         useTransport(transport);
         try (MCPInteractionClient interactionClient = createOpenedInteractionClient()) {
             Map<String, Object> actual = interactionClient.call("database_gateway_execute_update",
@@ -53,8 +53,8 @@ class ProductionMySQLSQLRuntimeE2ETest extends AbstractProductionMySQLRuntimeE2E
     }
     
     @ParameterizedTest(name = "{0}")
-    @MethodSource("semanticPrimaryTransport")
-    void assertExecuteRollbackWithActualMySQLBackend(final String name, final RuntimeTransport transport) throws SQLException, IOException, InterruptedException {
+    @MethodSource("httpTransportCase")
+    void assertExecuteRollback(final String name, final RuntimeTransport transport) throws SQLException, IOException, InterruptedException {
         useTransport(transport);
         try (MCPInteractionClient interactionClient = createOpenedInteractionClient()) {
             Map<String, Object> beginResponse = interactionClient.call("database_gateway_execute_update", createExecuteUpdateArguments("BEGIN"));
@@ -68,8 +68,8 @@ class ProductionMySQLSQLRuntimeE2ETest extends AbstractProductionMySQLRuntimeE2E
     }
     
     @ParameterizedTest(name = "{0}")
-    @MethodSource("semanticPrimaryTransport")
-    void assertExecuteSavepointFlowWithActualMySQLBackend(final String name, final RuntimeTransport transport) throws SQLException, IOException, InterruptedException {
+    @MethodSource("httpTransportCase")
+    void assertExecuteSavepointFlow(final String name, final RuntimeTransport transport) throws SQLException, IOException, InterruptedException {
         useTransport(transport);
         try (MCPInteractionClient interactionClient = createOpenedInteractionClient()) {
             interactionClient.call("database_gateway_execute_update", createExecuteUpdateArguments("BEGIN"));
@@ -88,8 +88,8 @@ class ProductionMySQLSQLRuntimeE2ETest extends AbstractProductionMySQLRuntimeE2E
     }
     
     @ParameterizedTest(name = "{0}")
-    @MethodSource("semanticPrimaryTransport")
-    void assertExecuteReleaseSavepointWithActualMySQLBackend(final String name, final RuntimeTransport transport) throws IOException, InterruptedException {
+    @MethodSource("httpTransportCase")
+    void assertExecuteReleaseSavepoint(final String name, final RuntimeTransport transport) throws IOException, InterruptedException {
         useTransport(transport);
         try (MCPInteractionClient interactionClient = createOpenedInteractionClient()) {
             interactionClient.call("database_gateway_execute_update", createExecuteUpdateArguments("BEGIN"));
@@ -103,8 +103,8 @@ class ProductionMySQLSQLRuntimeE2ETest extends AbstractProductionMySQLRuntimeE2E
     }
     
     @ParameterizedTest(name = "{0}")
-    @MethodSource("semanticPrimaryTransport")
-    void assertExecuteDdlRefreshesMetadataWithActualMySQLBackend(final String name, final RuntimeTransport transport) throws IOException, InterruptedException {
+    @MethodSource("httpTransportCase")
+    void assertExecuteDdlRefreshesMetadata(final String name, final RuntimeTransport transport) throws IOException, InterruptedException {
         useTransport(transport);
         try (MCPInteractionClient interactionClient = createOpenedInteractionClient()) {
             Map<String, Object> executeResponse = interactionClient.call("database_gateway_execute_update",
@@ -117,8 +117,8 @@ class ProductionMySQLSQLRuntimeE2ETest extends AbstractProductionMySQLRuntimeE2E
     }
     
     @ParameterizedTest(name = "{0}")
-    @MethodSource("semanticPrimaryTransport")
-    void assertCloseRollsBackPendingTransactionWithActualMySQLBackend(final String name, final RuntimeTransport transport) throws SQLException, IOException, InterruptedException {
+    @MethodSource("httpTransportCase")
+    void assertCloseRollsBackPendingTransaction(final String name, final RuntimeTransport transport) throws SQLException, IOException, InterruptedException {
         useTransport(transport);
         try (MCPInteractionClient interactionClient = createOpenedInteractionClient()) {
             interactionClient.call("database_gateway_execute_update", createExecuteUpdateArguments("BEGIN"));
@@ -130,8 +130,8 @@ class ProductionMySQLSQLRuntimeE2ETest extends AbstractProductionMySQLRuntimeE2E
     }
     
     @ParameterizedTest(name = "{0}")
-    @MethodSource("semanticPrimaryTransport")
-    void assertListDatabasesWithMultipleRuntimeDatabasesWithActualMySQLBackend(final String name, final RuntimeTransport transport) throws IOException, InterruptedException {
+    @MethodSource("httpTransportCase")
+    void assertListDatabasesWithMultipleRuntimeDatabases(final String name, final RuntimeTransport transport) throws IOException, InterruptedException {
         useTransport(transport);
         try (MCPInteractionClient interactionClient = createOpenedInteractionClient(createPreparedProgrammaticRuntimeDatabases())) {
             List<String> actualDatabaseNames = getPayloadItems(interactionClient.readResource("shardingsphere://databases")).stream()
@@ -141,8 +141,8 @@ class ProductionMySQLSQLRuntimeE2ETest extends AbstractProductionMySQLRuntimeE2E
     }
     
     @ParameterizedTest(name = "{0}")
-    @MethodSource("semanticPrimaryTransport")
-    void assertRefreshMetadataVisibleForTargetDatabaseOnlyWithActualMySQLBackend(final String name, final RuntimeTransport transport) throws IOException, InterruptedException {
+    @MethodSource("httpTransportCase")
+    void assertRefreshMetadataVisibleForTargetDatabaseOnly(final String name, final RuntimeTransport transport) throws IOException, InterruptedException {
         useTransport(transport);
         try (MCPInteractionClient firstInteractionClient = createOpenedInteractionClient(createPreparedProgrammaticRuntimeDatabases())) {
             firstInteractionClient.call("database_gateway_execute_update",
@@ -160,8 +160,8 @@ class ProductionMySQLSQLRuntimeE2ETest extends AbstractProductionMySQLRuntimeE2E
     }
     
     @ParameterizedTest(name = "{0}")
-    @MethodSource("semanticPrimaryTransport")
-    void assertRejectCrossDatabaseTransactionSwitchWithActualMySQLBackend(final String name, final RuntimeTransport transport) throws IOException, InterruptedException {
+    @MethodSource("httpTransportCase")
+    void assertRejectCrossDatabaseTransactionSwitch(final String name, final RuntimeTransport transport) throws IOException, InterruptedException {
         useTransport(transport);
         try (MCPInteractionClient interactionClient = createOpenedInteractionClient(createPreparedProgrammaticRuntimeDatabases())) {
             interactionClient.call("database_gateway_execute_update", createExecuteUpdateArguments(LOGICAL_DATABASE_NAME, "BEGIN"));
diff --git a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/PackagedDistributionE2ETest.java b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/PackagedDistributionE2ETest.java
similarity index 99%
rename from test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/PackagedDistributionE2ETest.java
rename to test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/PackagedDistributionE2ETest.java
index 586362dd646..d69b8b50240 100644
--- a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/PackagedDistributionE2ETest.java
+++ b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/PackagedDistributionE2ETest.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.test.e2e.mcp.runtime.production;
+package org.apache.shardingsphere.test.e2e.mcp.functionality;
 
 import org.apache.shardingsphere.test.e2e.env.runtime.EnvironmentPropertiesLoader;
 import org.apache.shardingsphere.test.e2e.mcp.support.OfficialMCPToolNames;
diff --git a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/ProductionPostgreSQLRuntimeE2ETest.java b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/PostgreSQLDatabaseGatewayE2ETest.java
similarity index 95%
rename from test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/ProductionPostgreSQLRuntimeE2ETest.java
rename to test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/PostgreSQLDatabaseGatewayE2ETest.java
index bdaae66514d..7c1c2cc5b7b 100644
--- a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/runtime/production/ProductionPostgreSQLRuntimeE2ETest.java
+++ b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/functionality/PostgreSQLDatabaseGatewayE2ETest.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.test.e2e.mcp.runtime.production;
+package org.apache.shardingsphere.test.e2e.mcp.functionality;
 
 import org.apache.shardingsphere.test.e2e.mcp.support.runtime.RuntimeTransport;
 import org.apache.shardingsphere.test.e2e.mcp.support.transport.MCPInteractionPayloads;
@@ -36,11 +36,11 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 @EnabledIf("org.apache.shardingsphere.test.e2e.mcp.env.MCPE2ECondition#isDockerEnabled")
-class ProductionPostgreSQLRuntimeE2ETest extends AbstractProductionPostgreSQLRuntimeE2ETest {
+class PostgreSQLDatabaseGatewayE2ETest extends AbstractPostgreSQLRuntimeE2ETest {
     
     @ParameterizedTest(name = "{0}")
-    @MethodSource("semanticPrimaryTransport")
-    void assertPostgreSQLRuntimeContract(final String name, final RuntimeTransport transport) throws IOException, InterruptedException {
+    @MethodSource("httpTransportCase")
+    void assertDatabaseGatewayContract(final String name, final RuntimeTransport transport) throws IOException, InterruptedException {
         useTransport(transport);
         try (MCPInteractionClient interactionClient = createOpenedInteractionClient()) {
             assertMetadata(interactionClient);
diff --git a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/llm/suite/LLMHttpE2ETest.java b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/llm/LLMHttpE2ETest.java
similarity index 99%
rename from test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/llm/suite/LLMHttpE2ETest.java
rename to test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/llm/LLMHttpE2ETest.java
index 24b651d59b9..c80767fd0fb 100644
--- a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/llm/suite/LLMHttpE2ETest.java
+++ b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/llm/LLMHttpE2ETest.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.test.e2e.mcp.llm.suite;
+package org.apache.shardingsphere.test.e2e.mcp.llm;
 
 import org.apache.shardingsphere.mcp.support.database.metadata.jdbc.RuntimeDatabaseConfiguration;
 import org.apache.shardingsphere.test.e2e.mcp.llm.config.LLME2EConfiguration;
diff --git a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/llm/suite/transport/LLMStdioTransportE2ETest.java b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/llm/LLMStdioE2ETest.java
similarity index 90%
rename from test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/llm/suite/transport/LLMStdioTransportE2ETest.java
rename to test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/llm/LLMStdioE2ETest.java
index 3f39375e98d..40a1b3b1768 100644
--- a/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/llm/suite/transport/LLMStdioTransportE2ETest.java
+++ b/test/e2e/mcp/src/test/java/org/apache/shardingsphere/test/e2e/mcp/llm/LLMStdioE2ETest.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.test.e2e.mcp.llm.suite.transport;
+package org.apache.shardingsphere.test.e2e.mcp.llm;
 
 import org.apache.shardingsphere.mcp.support.database.metadata.jdbc.RuntimeDatabaseConfiguration;
 import org.apache.shardingsphere.test.e2e.mcp.llm.config.LLME2EConfiguration;
@@ -45,9 +45,9 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
 @Tag("llm-e2e")
 @EnabledIf("org.apache.shardingsphere.test.e2e.mcp.env.MCPE2ECondition#isDockerEnabled")
 @TestInstance(TestInstance.Lifecycle.PER_CLASS)
-class LLMStdioTransportE2ETest extends AbstractConfigBackedRuntimeE2ETest {
+class LLMStdioE2ETest extends AbstractConfigBackedRuntimeE2ETest {
     
-    private static final String SUITE_ID = "llm-stdio-transport";
+    private static final String SUITE_ID = "llm-stdio-autonomous-read-only-query";
     
     private static final String DATABASE_NAME = "logic_db";
     
@@ -92,7 +92,7 @@ class LLMStdioTransportE2ETest extends AbstractConfigBackedRuntimeE2ETest {
     }
     
     @Test
-    void assertStdioTransport() throws IOException {
+    void assertAutonomousReadOnlyQuery() throws IOException {
         LLMConversationExecutor conversationExecutor = new LLMConversationExecutor(getRequiredLLMConfiguration(), getRequiredLLMRuntimeEvidence());
         prepareRuntimeFixture();
         LLMConversationExecutor.ConversationResult actualResult = conversationExecutor.runConversation(SUITE_ID, createScenario(), createInteractionClient());
@@ -111,8 +111,8 @@ class LLMStdioTransportE2ETest extends AbstractConfigBackedRuntimeE2ETest {
     private void assertSuccess(final LLMConversationExecutor.ConversationResult actualResult) {
         LLME2EAssertionReport actualReport = actualResult.artifactBundle().getAssertionReport();
         assertTrue(actualReport.isSuccess(),
-                () -> String.format("LLM stdio transport scenario failed: %s - %s", actualReport.getFailureType(), actualReport.getMessage()));
-        assertFalse(actualResult.artifactBundle().getInteractionTrace().isEmpty(), "LLM stdio transport scenario must record at least one MCP interaction.");
+                () -> String.format("MCP LLM E2E stdio scenario failed: %s - %s", actualReport.getFailureType(), actualReport.getMessage()));
+        assertFalse(actualResult.artifactBundle().getInteractionTrace().isEmpty(), "MCP LLM E2E stdio scenario must record at least one MCP interaction.");
     }
     
     private static LLME2EConfiguration getRequiredLLMConfiguration() {
@@ -145,12 +145,12 @@ class LLMStdioTransportE2ETest extends AbstractConfigBackedRuntimeE2ETest {
         if (null != currentRuntimeFixture) {
             return;
         }
-        currentRuntimeFixture = runtimeFixtureFactory.createMySQLFixture(DATABASE_NAME, "Docker is required for the MySQL-backed LLM stdio transport E2E test.");
+        currentRuntimeFixture = runtimeFixtureFactory.createMySQLFixture(DATABASE_NAME, "Docker is required for the MySQL-backed MCP LLM E2E stdio test.");
     }
     
     private Fixture getRequiredRuntimeFixture() {
         if (null == currentRuntimeFixture) {
-            throw new IllegalStateException("LLM stdio transport runtime fixture was not initialized.");
+            throw new IllegalStateException("MCP LLM E2E stdio runtime fixture was not initialized.");
         }
         return currentRuntimeFixture;
     }
diff --git a/test/e2e/mcp/src/test/resources/docker/llm-runtime/build-local.sh b/test/e2e/mcp/src/test/resources/docker/llm-runtime/build-local.sh
index 83c9d6b8882..5ecc41baafc 100644
--- a/test/e2e/mcp/src/test/resources/docker/llm-runtime/build-local.sh
+++ b/test/e2e/mcp/src/test/resources/docker/llm-runtime/build-local.sh
@@ -49,7 +49,7 @@ DOCKERFILE_PATH="${SCRIPT_DIR}/Dockerfile"
 ENV_FILE="${SCRIPT_DIR}/../../env/e2e-env.properties"
 
 if [ ! -f "${ENV_FILE}" ]; then
-  echo "MCP E2E environment properties file is required: ${ENV_FILE}" >&2
+  echo "MCP LLM E2E environment properties file is required: ${ENV_FILE}" >&2
   exit 1
 fi
 
@@ -60,7 +60,7 @@ read_property() {
 read_required_property() {
   PROPERTY_VALUE="$(read_property "$1" || true)"
   if [ -z "${PROPERTY_VALUE}" ]; then
-    echo "MCP E2E property is required: $1" >&2
+    echo "MCP LLM E2E property is required: $1" >&2
     exit 1
   fi
   echo "${PROPERTY_VALUE}"