|
| 1 | +package com.github.codeboyzhou.mcp.declarative.server; |
| 2 | + |
| 3 | +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.ReflectionHelper; |
| 6 | +import io.modelcontextprotocol.server.McpServerFeatures; |
| 7 | +import io.modelcontextprotocol.server.McpSyncServer; |
| 8 | +import io.modelcontextprotocol.spec.McpSchema; |
| 9 | +import org.slf4j.Logger; |
| 10 | +import org.slf4j.LoggerFactory; |
| 11 | + |
| 12 | +import java.lang.reflect.Method; |
| 13 | +import java.lang.reflect.Parameter; |
| 14 | +import java.util.ArrayList; |
| 15 | +import java.util.List; |
| 16 | +import java.util.Set; |
| 17 | + |
| 18 | +public class McpSyncServerPromptRegister |
| 19 | + implements McpServerComponentRegister<McpSyncServer, McpServerFeatures.SyncPromptSpecification> { |
| 20 | + |
| 21 | + private static final Logger logger = LoggerFactory.getLogger(McpSyncServerPromptRegister.class); |
| 22 | + |
| 23 | + private final Set<Class<?>> promptClasses; |
| 24 | + |
| 25 | + public McpSyncServerPromptRegister(Set<Class<?>> promptClasses) { |
| 26 | + this.promptClasses = promptClasses; |
| 27 | + } |
| 28 | + |
| 29 | + @Override |
| 30 | + public void registerTo(McpSyncServer server) { |
| 31 | + for (Class<?> promptClass : promptClasses) { |
| 32 | + Set<Method> methods = ReflectionHelper.getMethodsAnnotatedWith(promptClass, McpPrompt.class); |
| 33 | + for (Method method : methods) { |
| 34 | + McpServerFeatures.SyncPromptSpecification prompt = createComponentFrom(promptClass, method); |
| 35 | + server.addPrompt(prompt); |
| 36 | + } |
| 37 | + } |
| 38 | + } |
| 39 | + |
| 40 | + @Override |
| 41 | + public McpServerFeatures.SyncPromptSpecification createComponentFrom(Class<?> clazz, Method method) { |
| 42 | + McpPrompt promptMethod = method.getAnnotation(McpPrompt.class); |
| 43 | + final String name = promptMethod.name().isBlank() ? method.getName() : promptMethod.name(); |
| 44 | + final String description = promptMethod.description(); |
| 45 | + List<McpSchema.PromptArgument> promptArguments = createPromptArguments(method); |
| 46 | + McpSchema.Prompt prompt = new McpSchema.Prompt(name, description, promptArguments); |
| 47 | + return new McpServerFeatures.SyncPromptSpecification(prompt, (exchange, request) -> { |
| 48 | + Object result; |
| 49 | + try { |
| 50 | + result = ReflectionHelper.invokeMethod(clazz, method, request.arguments()); |
| 51 | + } catch (Throwable e) { |
| 52 | + logger.error("Error invoking prompt method", e); |
| 53 | + result = e + ": " + e.getMessage(); |
| 54 | + } |
| 55 | + McpSchema.Content content = new McpSchema.TextContent(result.toString()); |
| 56 | + McpSchema.PromptMessage message = new McpSchema.PromptMessage(McpSchema.Role.USER, content); |
| 57 | + return new McpSchema.GetPromptResult(description, List.of(message)); |
| 58 | + }); |
| 59 | + } |
| 60 | + |
| 61 | + private List<McpSchema.PromptArgument> createPromptArguments(Method method) { |
| 62 | + Set<Parameter> parameters = ReflectionHelper.getParametersAnnotatedWith(method, McpPromptParam.class); |
| 63 | + List<McpSchema.PromptArgument> promptArguments = new ArrayList<>(parameters.size()); |
| 64 | + for (Parameter parameter : parameters) { |
| 65 | + McpPromptParam promptParam = parameter.getAnnotation(McpPromptParam.class); |
| 66 | + final String name = promptParam.name(); |
| 67 | + final String description = promptParam.description(); |
| 68 | + final boolean required = promptParam.required(); |
| 69 | + McpSchema.PromptArgument promptArgument = new McpSchema.PromptArgument(name, description, required); |
| 70 | + promptArguments.add(promptArgument); |
| 71 | + } |
| 72 | + return promptArguments; |
| 73 | + } |
| 74 | + |
| 75 | +} |
0 commit comments