Skip to content

Commit 8b80f91

Browse files
committed
polish(server): Improve type handling and parameter processing
1 parent aa242d2 commit 8b80f91

File tree

3 files changed

+49
-24
lines changed

3 files changed

+49
-24
lines changed

src/main/java/com/github/codeboyzhou/mcp/declarative/server/McpSyncServerPromptRegister.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public McpServerFeatures.SyncPromptSpecification createComponentFrom(Class<?> cl
4949
return new McpServerFeatures.SyncPromptSpecification(prompt, (exchange, request) -> {
5050
Object result;
5151
try {
52-
result = ReflectionHelper.invokeMethod(clazz, method, request.arguments());
52+
result = ReflectionHelper.invokeMethod(clazz, method, promptArguments, request.arguments());
5353
} catch (Throwable e) {
5454
logger.error("Error invoking prompt method", e);
5555
result = e + ": " + e.getMessage();

src/main/java/com/github/codeboyzhou/mcp/declarative/server/McpSyncServerToolRegister.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ private McpSchema.JsonSchema createJsonSchema(Method method) {
8080
Map<String, String> property = new HashMap<>();
8181

8282
if (parameterType.getAnnotation(McpJsonSchemaDefinition.class) == null) {
83-
property.put("type", parameterType.getName().toLowerCase());
83+
property.put("type", parameterType.getSimpleName().toLowerCase());
8484
property.put("description", toolParam.description());
8585
} else {
8686
final String parameterTypeSimpleName = parameterType.getSimpleName();
@@ -103,7 +103,7 @@ private Map<String, Object> createJsonSchemaDefinition(Class<?> definitionClass)
103103
Map<String, Object> definitionJsonSchema = new HashMap<>();
104104
definitionJsonSchema.put("type", OBJECT_TYPE_NAME);
105105

106-
Map<String, Object> properties = new HashMap<>();
106+
Map<String, Object> properties = new LinkedHashMap<>();
107107
List<String> required = new ArrayList<>();
108108

109109
ReflectionHelper.doWithFields(definitionClass, field -> {
@@ -113,7 +113,7 @@ private Map<String, Object> createJsonSchemaDefinition(Class<?> definitionClass)
113113
}
114114

115115
Map<String, Object> fieldProperties = new HashMap<>();
116-
fieldProperties.put("type", field.getType().getName().toLowerCase());
116+
fieldProperties.put("type", field.getType().getSimpleName().toLowerCase());
117117
fieldProperties.put("description", property.description());
118118

119119
final String fieldName = property.name().isBlank() ? field.getName() : property.name();

src/main/java/com/github/codeboyzhou/mcp/declarative/util/ReflectionHelper.java

Lines changed: 45 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,10 @@ public static Object invokeMethod(Class<?> clazz, Method method) throws Exceptio
3636
return method.invoke(object);
3737
}
3838

39-
public static Object invokeMethod(Class<?> clazz, Method method, Map<String, Object> parameters) throws Exception {
39+
public static Object invokeMethod(Class<?> clazz, Method method, List<McpSchema.PromptArgument> arguments, Map<String, Object> parameters) throws Exception {
4040
Object object = clazz.getDeclaredConstructor().newInstance();
41-
return method.invoke(object, parameters.values().toArray());
41+
Map<String, Object> typedParameters = asTypedParameters(method, arguments, parameters);
42+
return method.invoke(object, typedParameters.values().toArray());
4243
}
4344

4445
public static Object invokeMethod(Class<?> clazz, Method method, McpSchema.JsonSchema schema, Map<String, Object> parameters) throws Exception {
@@ -47,27 +48,55 @@ public static Object invokeMethod(Class<?> clazz, Method method, McpSchema.JsonS
4748
return method.invoke(object, typedParameters.values().toArray());
4849
}
4950

51+
private static Map<String, Object> asTypedParameters(Method method, List<McpSchema.PromptArgument> arguments, Map<String, Object> parameters) {
52+
Class<?>[] parameterTypes = method.getParameterTypes();
53+
Map<String, Object> typedParameters = new LinkedHashMap<>(parameters.size());
54+
55+
for (int i = 0, size = arguments.size(); i < size; i++) {
56+
final String parameterName = arguments.get(i).name();
57+
final Object parameterValue = parameters.get(parameterName);
58+
// Fill in a default value when the parameter is not specified
59+
// to ensure that the parameter type is correct when calling method.invoke()
60+
Class<?> parameterType = parameterTypes[i];
61+
if (String.class == parameterType) {
62+
typedParameters.put(parameterName, parameterValue == null ? StringHelper.EMPTY : parameterValue.toString());
63+
} else if (int.class == parameterType || Integer.class == parameterType) {
64+
typedParameters.put(parameterName, parameterValue == null ? 0 : Integer.parseInt(parameterValue.toString()));
65+
} else if (long.class == parameterType || Long.class == parameterType) {
66+
typedParameters.put(parameterName, parameterValue == null ? 0 : Long.parseLong(parameterValue.toString()));
67+
} else if (float.class == parameterType || Float.class == parameterType) {
68+
typedParameters.put(parameterName, parameterValue == null ? 0.0 : Float.parseFloat(parameterValue.toString()));
69+
} else if (double.class == parameterType || Double.class == parameterType) {
70+
typedParameters.put(parameterName, parameterValue == null ? 0.0 : Double.parseDouble(parameterValue.toString()));
71+
} else if (boolean.class == parameterType || Boolean.class == parameterType) {
72+
typedParameters.put(parameterName, parameterValue != null && Boolean.parseBoolean(parameterValue.toString()));
73+
} else {
74+
typedParameters.put(parameterName, parameterValue);
75+
}
76+
}
77+
78+
return typedParameters;
79+
}
80+
5081
@SuppressWarnings("unchecked")
5182
private static Map<String, Object> asTypedParameters(McpSchema.JsonSchema schema, Map<String, Object> parameters) {
5283
Map<String, Object> properties = schema.properties();
5384
Map<String, Object> typedParameters = new LinkedHashMap<>(properties.size());
5485

5586
properties.forEach((parameterName, parameterProperties) -> {
5687
Object parameterValue = parameters.get(parameterName);
57-
if (parameterValue == null) {
58-
Map<String, Object> map = (Map<String, Object>) parameterProperties;
59-
final String jsonSchemaType = map.getOrDefault("type", StringHelper.EMPTY).toString();
60-
if (jsonSchemaType.isEmpty()) {
61-
typedParameters.put(parameterName, null);
62-
} else if (isTypeOf(String.class, jsonSchemaType)) {
63-
typedParameters.put(parameterName, StringHelper.EMPTY);
64-
} else if (isTypeOf(Integer.class, jsonSchemaType)) {
65-
typedParameters.put(parameterName, 0);
66-
} else if (isTypeOf(Number.class, jsonSchemaType)) {
67-
typedParameters.put(parameterName, 0.0);
68-
} else if (isTypeOf(Boolean.class, jsonSchemaType)) {
69-
typedParameters.put(parameterName, false);
70-
}
88+
// Fill in a default value when the parameter is not specified
89+
// to ensure that the parameter type is correct when calling method.invoke()
90+
Map<String, Object> map = (Map<String, Object>) parameterProperties;
91+
final String jsonSchemaType = map.getOrDefault("type", StringHelper.EMPTY).toString();
92+
if (String.class.getSimpleName().equalsIgnoreCase(jsonSchemaType)) {
93+
typedParameters.put(parameterName, parameterValue == null ? StringHelper.EMPTY : parameterValue.toString());
94+
} else if (Integer.class.getSimpleName().equalsIgnoreCase(jsonSchemaType)) {
95+
typedParameters.put(parameterName, parameterValue == null ? 0 : Integer.parseInt(parameterValue.toString()));
96+
} else if (Number.class.getSimpleName().equalsIgnoreCase(jsonSchemaType)) {
97+
typedParameters.put(parameterName, parameterValue == null ? 0.0 : Double.parseDouble(parameterValue.toString()));
98+
} else if (Boolean.class.getSimpleName().equalsIgnoreCase(jsonSchemaType)) {
99+
typedParameters.put(parameterName, parameterValue != null && Boolean.parseBoolean(parameterValue.toString()));
71100
} else {
72101
typedParameters.put(parameterName, parameterValue);
73102
}
@@ -76,8 +105,4 @@ private static Map<String, Object> asTypedParameters(McpSchema.JsonSchema schema
76105
return typedParameters;
77106
}
78107

79-
private static boolean isTypeOf(Class<?> clazz, String jsonSchemaType) {
80-
return clazz.getName().equalsIgnoreCase(jsonSchemaType) || clazz.getSimpleName().equalsIgnoreCase(jsonSchemaType);
81-
}
82-
83108
}

0 commit comments

Comments
 (0)