This is an automated email from the ASF dual-hosted git repository.

liuhongyu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shenyu.git


The following commit(s) were added to refs/heads/master by this push:
     new 164ad63538 feat:mcpServer support object and array param. (#6150)
164ad63538 is described below

commit 164ad635386e52f4edc1b2db398b44a9136932d7
Author: Wweiei <[email protected]>
AuthorDate: Mon Sep 15 15:11:40 2025 +0800

    feat:mcpServer support object and array param. (#6150)
    
    Co-authored-by: aias00 <[email protected]>
---
 .../mcp/server/model/McpServerToolParameter.java   |  35 +++++-
 .../plugin/mcp/server/utils/JsonSchemaUtil.java    |  34 +++++-
 .../mcp/server/utils/JsonSchemaUtilTest.java       | 124 +++++++++++++++++++++
 3 files changed, 187 insertions(+), 6 deletions(-)

diff --git 
a/shenyu-plugin/shenyu-plugin-mcp-server/src/main/java/org/apache/shenyu/plugin/mcp/server/model/McpServerToolParameter.java
 
b/shenyu-plugin/shenyu-plugin-mcp-server/src/main/java/org/apache/shenyu/plugin/mcp/server/model/McpServerToolParameter.java
index f6c85a2235..9b2054fe78 100644
--- 
a/shenyu-plugin/shenyu-plugin-mcp-server/src/main/java/org/apache/shenyu/plugin/mcp/server/model/McpServerToolParameter.java
+++ 
b/shenyu-plugin/shenyu-plugin-mcp-server/src/main/java/org/apache/shenyu/plugin/mcp/server/model/McpServerToolParameter.java
@@ -17,6 +17,8 @@
 
 package org.apache.shenyu.plugin.mcp.server.model;
 
+import java.util.List;
+
 /**
  * McpParameter represents a parameter in the context of a tool description.
  * It contains information about the parameter's name, type, description,
@@ -49,6 +51,11 @@ public class McpServerToolParameter {
      */
     private String defaultValue;
 
+    /**
+     * the child parameters.
+     */
+    private List<McpServerToolParameter> parameters;
+
     /**
      * Constructor for McpParameter.
      */
@@ -63,13 +70,15 @@ public class McpServerToolParameter {
      * @param description description
      * @param required    required
      * @param defaultValue defaultValue
+     * @param parameters parameters
      */
-    public McpServerToolParameter(final String name, final String type, final 
String description, final boolean required, final String defaultValue) {
+    public McpServerToolParameter(final String name, final String type, final 
String description, final boolean required, final String defaultValue, final 
List<McpServerToolParameter> parameters) {
         this.name = name;
         this.type = type;
         this.description = description;
         this.required = required;
         this.defaultValue = defaultValue;
+        this.parameters = parameters;
     }
 
     /**
@@ -145,20 +154,38 @@ public class McpServerToolParameter {
     }
 
     /**
-     * Getter for mcpClass.
+     * Getter for defaultValue.
      *
-     * @return mcpClass
+     * @return defaultValue
      */
     public String getDefaultValue() {
         return defaultValue;
     }
 
     /**
-     * Setter for mcpClass.
+     * Setter for defaultValue.
      *
      * @param defaultValue defaultValue
      */
     public void setDefaultValue(final String defaultValue) {
         this.defaultValue = defaultValue;
     }
+
+    /**
+     * Getter for parameters.
+     *
+     * @return parameters
+     */
+    public List<McpServerToolParameter> getParameters() {
+        return parameters;
+    }
+
+    /**
+     * Setter for parameters.
+     *
+     * @param parameters parameters
+     */
+    public void setParameters(final List<McpServerToolParameter> parameters) {
+        this.parameters = parameters;
+    }
 }
diff --git 
a/shenyu-plugin/shenyu-plugin-mcp-server/src/main/java/org/apache/shenyu/plugin/mcp/server/utils/JsonSchemaUtil.java
 
b/shenyu-plugin/shenyu-plugin-mcp-server/src/main/java/org/apache/shenyu/plugin/mcp/server/utils/JsonSchemaUtil.java
index fee135e937..e15dc76209 100644
--- 
a/shenyu-plugin/shenyu-plugin-mcp-server/src/main/java/org/apache/shenyu/plugin/mcp/server/utils/JsonSchemaUtil.java
+++ 
b/shenyu-plugin/shenyu-plugin-mcp-server/src/main/java/org/apache/shenyu/plugin/mcp/server/utils/JsonSchemaUtil.java
@@ -20,6 +20,7 @@ package org.apache.shenyu.plugin.mcp.server.utils;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import com.github.victools.jsonschema.generator.SchemaVersion;
+import io.micrometer.common.util.StringUtils;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.shenyu.plugin.mcp.server.model.McpServerToolParameter;
 import org.springframework.ai.util.json.JsonParser;
@@ -58,14 +59,43 @@ public final class JsonSchemaUtil {
         ObjectNode properties = schema.putObject("properties");
         for (McpServerToolParameter parameter : parameters) {
             ObjectNode property = properties.putObject(parameter.getName());
-            property.put("type", parameter.getType());
-            property.put("description", parameter.getDescription());
+            recursionConstructPropertiesNodes(parameter, property);
         }
 
         processSchemaOptions(schemaOptions, schema);
         return schema.toPrettyString();
     }
 
+    /**
+     * Recursively construct the properties nodes for the parameter.
+     *
+     * @param parameter the parameter
+     * @param property  the property
+     */
+    public static void recursionConstructPropertiesNodes(final 
McpServerToolParameter parameter,
+                                                         final ObjectNode 
property) {
+        property.put("type", parameter.getType());
+        // if the parameter is the item parameter of array, the description is 
null
+        if (StringUtils.isNotBlank(parameter.getDescription())) {
+            property.put("description", parameter.getDescription());
+        }
+        // add the properties schema for the object type parameter
+        List<McpServerToolParameter> parameters = parameter.getParameters();
+        if ("object".equals(parameter.getType()) && 
CollectionUtils.isNotEmpty(parameters)) {
+            ObjectNode properties = property.putObject("properties");
+            for (McpServerToolParameter itemParameter : parameters) {
+                ObjectNode property1 = 
properties.putObject(itemParameter.getName());
+                recursionConstructPropertiesNodes(itemParameter, property1);
+            }
+        }
+        // add the items schema for the array type parameter
+        if ("array".equals(parameter.getType()) && 
CollectionUtils.isNotEmpty(parameters)) {
+            McpServerToolParameter itemParameter = parameters.get(0);
+            ObjectNode items = property.putObject("items");
+            recursionConstructPropertiesNodes(itemParameter, items);
+        }
+    }
+
     private static void processSchemaOptions(final SchemaOption[] 
schemaOptions, final ObjectNode schema) {
         if (Stream.of(schemaOptions)
                 .noneMatch(option -> option == 
SchemaOption.ALLOW_ADDITIONAL_PROPERTIES_BY_DEFAULT)) {
diff --git 
a/shenyu-plugin/shenyu-plugin-mcp-server/src/test/java/org/apache/shenyu/plugin/mcp/server/utils/JsonSchemaUtilTest.java
 
b/shenyu-plugin/shenyu-plugin-mcp-server/src/test/java/org/apache/shenyu/plugin/mcp/server/utils/JsonSchemaUtilTest.java
index bf6efb8275..8eeb22a246 100644
--- 
a/shenyu-plugin/shenyu-plugin-mcp-server/src/test/java/org/apache/shenyu/plugin/mcp/server/utils/JsonSchemaUtilTest.java
+++ 
b/shenyu-plugin/shenyu-plugin-mcp-server/src/test/java/org/apache/shenyu/plugin/mcp/server/utils/JsonSchemaUtilTest.java
@@ -19,6 +19,8 @@ package org.apache.shenyu.plugin.mcp.server.utils;
 
 import org.apache.shenyu.plugin.mcp.server.model.McpServerToolParameter;
 import org.junit.jupiter.api.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import java.util.Arrays;
 import java.util.Collections;
@@ -33,6 +35,8 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
  */
 class JsonSchemaUtilTest {
 
+    private static final Logger log = 
LoggerFactory.getLogger(JsonSchemaUtilTest.class);
+
     @Test
     void testCreateParameterSchemaWithEmptyParameters() {
         String schema = 
JsonSchemaUtil.createParameterSchema(Collections.emptyList());
@@ -175,4 +179,124 @@ class JsonSchemaUtilTest {
         // Verify that special characters are properly escaped
         assertTrue(schema.contains("\\\"quotes\\\""));
     }
+
+    @Test
+    void testCreateParameterSchemaWithObjectType() {
+        McpServerToolParameter param1 = new McpServerToolParameter();
+        param1.setName("username");
+        param1.setType("string");
+        param1.setDescription("The username");
+        param1.setRequired(true);
+
+        McpServerToolParameter param2 = new McpServerToolParameter();
+        param2.setName("age");
+        param2.setType("integer");
+        param2.setDescription("The age");
+        param2.setRequired(false);
+
+        McpServerToolParameter param3 = new McpServerToolParameter();
+        param3.setName("class");
+        param3.setType("object");
+        param3.setDescription("The class info");
+        param3.setRequired(true);
+
+        McpServerToolParameter param31 = new McpServerToolParameter();
+        param31.setName("className");
+        param31.setType("string");
+        param31.setDescription("The class name");
+        param31.setRequired(true);
+
+        McpServerToolParameter param32 = new McpServerToolParameter();
+        param32.setName("course");
+        param32.setType("object");
+        param32.setDescription("The class course");
+        param32.setRequired(true);
+
+        param3.setParameters(Arrays.asList(param31, param32));
+
+        McpServerToolParameter param321 = new McpServerToolParameter();
+        param321.setName("courseName");
+        param321.setType("string");
+        param321.setDescription("The name  of the course");
+        param321.setRequired(true);
+
+        McpServerToolParameter param322 = new McpServerToolParameter();
+        param322.setName("courseTime");
+        param322.setType("string");
+        param322.setDescription("The time  of the course");
+        param322.setRequired(true);
+
+        param32.setParameters(Arrays.asList(param321, param322));
+
+        List<McpServerToolParameter> parameters = Arrays.asList(param1, 
param2, param3);
+        String schema = JsonSchemaUtil.createParameterSchema(parameters);
+        log.info("schema: {}", schema);
+        assertNotNull(schema);
+        assertTrue(schema.contains("\"username\""));
+        assertTrue(schema.contains("\"class\""));
+        assertTrue(schema.contains("\"className\""));
+        assertTrue(schema.contains("\"course\""));
+        assertTrue(schema.contains("\"courseName\""));
+        assertTrue(schema.contains("\"The name  of the course\""));
+        assertTrue(schema.contains("\"courseTime\""));
+        assertTrue(schema.contains("\"The time  of the course\""));
+    }
+
+    @Test
+    void testCreateParameterSchemaWithArrayType() {
+        McpServerToolParameter param1 = new McpServerToolParameter();
+        param1.setName("className");
+        param1.setType("string");
+        param1.setDescription("The class info");
+        param1.setRequired(true);
+
+        McpServerToolParameter param2 = new McpServerToolParameter();
+        param2.setName("studentNames");
+        param2.setType("array");
+        param2.setDescription("The student names");
+        param2.setRequired(true);
+
+        McpServerToolParameter param21 = new McpServerToolParameter();
+        param21.setName("items");
+        param21.setType("string");
+        param21.setRequired(true);
+        param2.setParameters(Arrays.asList(param21));
+
+        McpServerToolParameter param3 = new McpServerToolParameter();
+        param3.setName("studentInfo");
+        param3.setType("array");
+        param3.setDescription("The student infos");
+        param3.setRequired(true);
+
+        McpServerToolParameter param31 = new McpServerToolParameter();
+        param31.setName("items");
+        param31.setType("object");
+        param31.setRequired(true);
+        param3.setParameters(Arrays.asList(param31));
+
+        McpServerToolParameter param331 = new McpServerToolParameter();
+        param331.setName("studentName");
+        param331.setType("String");
+        param331.setDescription("The student name");
+        param331.setRequired(true);
+
+        McpServerToolParameter param332 = new McpServerToolParameter();
+        param332.setName("studentAge");
+        param332.setType("integer");
+        param332.setDescription("The student age");
+        param332.setRequired(true);
+        param31.setParameters(Arrays.asList(param331, param332));
+
+        List<McpServerToolParameter> parameters = Arrays.asList(param1, 
param2, param3);
+        String schema = JsonSchemaUtil.createParameterSchema(parameters);
+        log.info("schema: {}", schema);
+        assertNotNull(schema);
+        assertTrue(schema.contains("\"className\""));
+        assertTrue(schema.contains("\"studentNames\""));
+        assertTrue(schema.contains("\"items\""));
+        assertTrue(schema.contains("\"studentInfo\""));
+        assertTrue(schema.contains("\"studentName\""));
+        assertTrue(schema.contains("\"studentAge\""));
+        assertTrue(schema.contains("The student age"));
+    }
 }

Reply via email to