Skip to content

Commit dcf1eb4

Browse files
committed
refactor(server): Simplify parameter handling in McpServerPromptFactory and enhance prompt argument verification in tests
1 parent 6fd8920 commit dcf1eb4

File tree

3 files changed

+48
-18
lines changed

3 files changed

+48
-18
lines changed

src/main/java/com/github/codeboyzhou/mcp/declarative/server/component/McpServerPromptFactory.java

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
import java.lang.reflect.Method;
1212
import java.lang.reflect.Parameter;
1313
import java.util.ArrayList;
14-
import java.util.LinkedHashMap;
1514
import java.util.List;
1615
import java.util.Map;
1716
import java.util.stream.Stream;
@@ -38,9 +37,8 @@ public McpServerFeatures.SyncPromptSpecification create(Class<?> clazz, Method m
3837
Object result;
3938
try {
4039
Object instance = InjectorProvider.getInstance().getInjector().getInstance(clazz);
41-
Map<String, Object> typedParameters =
42-
asTypedParameters(method, promptArguments, request.arguments());
43-
result = method.invoke(instance, typedParameters.values().toArray());
40+
List<Object> typedValues = asTypedParameterValues(method, request.arguments());
41+
result = method.invoke(instance, typedValues.toArray());
4442
} catch (Exception e) {
4543
log.error("Error invoking prompt method", e);
4644
result = e + ": " + e.getMessage();
@@ -70,20 +68,23 @@ private List<McpSchema.PromptArgument> createPromptArguments(Method method) {
7068
return promptArguments;
7169
}
7270

73-
private Map<String, Object> asTypedParameters(
74-
Method method, List<McpSchema.PromptArgument> arguments, Map<String, Object> parameters) {
75-
Class<?>[] parameterTypes = method.getParameterTypes();
76-
Map<String, Object> typedParameters = new LinkedHashMap<>(parameters.size());
71+
private List<Object> asTypedParameterValues(Method method, Map<String, Object> parameters) {
72+
Parameter[] methodParams = method.getParameters();
73+
List<Object> typedValues = new ArrayList<>(methodParams.length);
7774

78-
for (int i = 0, size = arguments.size(); i < size; i++) {
79-
final String parameterName = arguments.get(i).name();
80-
final Object parameterValue = parameters.get(parameterName);
81-
// Fill in a default value when the parameter is not specified
75+
for (Parameter param : methodParams) {
76+
Object rawValue = null;
77+
if (param.isAnnotationPresent(McpPromptParam.class)) {
78+
McpPromptParam promptParam = param.getAnnotation(McpPromptParam.class);
79+
rawValue = parameters.get(promptParam.name());
80+
}
81+
// Fill in a default value when the parameter is not specified or unannotated
8282
// to ensure that the parameter type is correct when calling method.invoke()
83-
Object typedParameterValue = Types.convert(parameterValue, parameterTypes[i]);
84-
typedParameters.put(parameterName, typedParameterValue);
83+
Class<?> targetType = param.getType();
84+
Object typed = Types.convert(rawValue, targetType);
85+
typedValues.add(typed);
8586
}
8687

87-
return typedParameters;
88+
return typedValues;
8889
}
8990
}

src/test/java/com/github/codeboyzhou/mcp/declarative/McpServersTest.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import com.github.codeboyzhou.mcp.declarative.server.factory.McpSseServerInfo;
1515
import com.github.codeboyzhou.mcp.declarative.server.factory.McpStreamableServerInfo;
1616
import com.github.codeboyzhou.mcp.declarative.test.TestSimpleMcpStdioServer;
17+
import com.github.codeboyzhou.mcp.declarative.util.ObjectMappers;
1718
import io.modelcontextprotocol.client.McpClient;
1819
import io.modelcontextprotocol.client.McpSyncClient;
1920
import io.modelcontextprotocol.client.transport.HttpClientSseClientTransport;
@@ -23,6 +24,7 @@
2324
import io.modelcontextprotocol.spec.McpSchema;
2425
import java.time.Duration;
2526
import java.util.List;
27+
import java.util.Map;
2628
import java.util.Random;
2729
import org.junit.jupiter.api.Test;
2830

@@ -158,6 +160,7 @@ private void verify(McpSyncClient client) {
158160
verifyResourcesRegistered(client);
159161
verifyPromptsRegistered(client);
160162
verifyToolsRegistered(client);
163+
verifyPromptsCalled(client);
161164
}
162165

163166
private void verifyServerInfo(McpSyncClient client) {
@@ -181,11 +184,30 @@ private void verifyResourcesRegistered(McpSyncClient client) {
181184
private void verifyPromptsRegistered(McpSyncClient client) {
182185
List<McpSchema.Prompt> prompts = client.listPrompts().prompts();
183186
assertEquals(1, prompts.size());
187+
184188
McpSchema.Prompt prompt = prompts.get(0);
185189
assertEquals("prompt1_name", prompt.name());
186190
assertEquals("prompt1_title", prompt.title());
187191
assertEquals("prompt1_description", prompt.description());
188-
assertTrue(prompt.arguments().isEmpty());
192+
193+
List<McpSchema.PromptArgument> arguments = prompt.arguments();
194+
assertEquals(2, arguments.size());
195+
assertEquals("param1", arguments.get(0).name());
196+
assertEquals("param1_title", arguments.get(0).title());
197+
assertEquals("param1_description", arguments.get(0).description());
198+
assertEquals("param2", arguments.get(1).name());
199+
assertEquals("param2_title", arguments.get(1).title());
200+
assertEquals("param2_description", arguments.get(1).description());
201+
}
202+
203+
private void verifyPromptsCalled(McpSyncClient client) {
204+
String name1 = "prompt1_name";
205+
Map<String, Object> args1 = Map.of("param1", "value1", "param2", "value2");
206+
McpSchema.GetPromptRequest request1 = new McpSchema.GetPromptRequest(name1, args1);
207+
McpSchema.GetPromptResult result1 = client.getPrompt(request1);
208+
McpSchema.TextContent content = (McpSchema.TextContent) result1.messages().get(0).content();
209+
assertEquals(ObjectMappers.toJson(args1), content.text());
210+
assertEquals("prompt1_description", result1.description());
189211
}
190212

191213
private void verifyToolsRegistered(McpSyncClient client) {
Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
11
package com.github.codeboyzhou.mcp.declarative.test;
22

33
import com.github.codeboyzhou.mcp.declarative.annotation.McpPrompt;
4+
import com.github.codeboyzhou.mcp.declarative.annotation.McpPromptParam;
5+
import com.github.codeboyzhou.mcp.declarative.util.ObjectMappers;
6+
import java.util.Map;
47

58
public class TestMcpPrompts {
69

710
@McpPrompt(name = "prompt1_name", title = "prompt1_title", description = "prompt1_description")
8-
public String prompt1() {
9-
return "prompt1_content";
11+
public String prompt1(
12+
@McpPromptParam(name = "param1", title = "param1_title", description = "param1_description")
13+
String param1,
14+
@McpPromptParam(name = "param2", title = "param2_title", description = "param2_description")
15+
String param2) {
16+
return ObjectMappers.toJson(Map.of("param1", param1, "param2", param2));
1017
}
1118
}

0 commit comments

Comments
 (0)