Skip to content

Commit a3fc7cf

Browse files
committed
Fixed PR comments
1 parent 776f97f commit a3fc7cf

File tree

3 files changed

+46
-24
lines changed

3 files changed

+46
-24
lines changed

api/src/main/java/io/kafbat/ui/config/McpConfig.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,6 @@ public McpAsyncServer mcpServer(WebFluxSseServerTransportProvider transport) {
5858
.build();
5959
}
6060

61-
private List<AsyncPromptSpecification> prompts() {
62-
return List.of();
63-
}
64-
6561
private List<AsyncToolSpecification> tools() {
6662
List<AsyncToolSpecification> tools = new ArrayList<>();
6763
for (McpTool mcpTool : mcpTools) {

api/src/main/java/io/kafbat/ui/service/mcp/McpSpecificationGenerator.java

Lines changed: 45 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.kafbat.ui.service.mcp;
22

3+
import com.fasterxml.jackson.core.JsonProcessingException;
34
import com.fasterxml.jackson.databind.ObjectMapper;
45
import com.github.victools.jsonschema.generator.SchemaGenerator;
56
import io.modelcontextprotocol.server.McpAsyncServerExchange;
@@ -19,19 +20,22 @@
1920
import java.util.Map;
2021
import java.util.function.BiFunction;
2122
import lombok.RequiredArgsConstructor;
23+
import lombok.extern.slf4j.Slf4j;
2224
import org.springframework.aop.support.AopUtils;
2325
import org.springframework.core.annotation.AnnotationUtils;
26+
import org.springframework.http.HttpStatusCode;
2427
import org.springframework.http.ResponseEntity;
2528
import org.springframework.stereotype.Component;
2629
import org.springframework.web.server.ServerWebExchange;
2730
import reactor.core.publisher.Flux;
2831
import reactor.core.publisher.Mono;
2932

33+
@Slf4j
3034
@Component
3135
@RequiredArgsConstructor
3236
public class McpSpecificationGenerator {
3337
private final SchemaGenerator schemaGenerator;
34-
private final ObjectMapper objectMapper;
38+
private final ObjectMapper objectMapper = new ObjectMapper();
3539

3640
public List<AsyncToolSpecification> convertTool(McpTool controller) {
3741
List<AsyncToolSpecification> result = new ArrayList<>();
@@ -48,7 +52,7 @@ public List<AsyncToolSpecification> convertTool(McpTool controller) {
4852
return result;
4953
}
5054

51-
public AsyncToolSpecification convertOperation(Method method, Operation annotation, McpTool instance) {
55+
private AsyncToolSpecification convertOperation(Method method, Operation annotation, McpTool instance) {
5256
String name = annotation.operationId();
5357
String description = annotation.description().isEmpty() ? name : annotation.description();
5458
return new AsyncToolSpecification(
@@ -61,17 +65,18 @@ public AsyncToolSpecification convertOperation(Method method, Operation annotati
6165
private BiFunction<McpAsyncServerExchange, Map<String, Object>, Mono<CallToolResult>>
6266
methodCall(Method method, Object instance) {
6367

64-
return (ex, v) -> Mono.deferContextual(ctx -> {
68+
return (ex, args) -> Mono.deferContextual(ctx -> {
6569
try {
6670
ServerWebExchange serverWebExchange = ctx.get(ServerWebExchange.class);
6771
Mono<Object> result = (Mono<Object>) method.invoke(
6872
instance,
69-
toParams(v, method.getParameters(), ex, serverWebExchange)
73+
toParams(args, method.getParameters(), ex, serverWebExchange)
7074
);
7175
return result.flatMap(this::toCallResult)
72-
.onErrorResume((e) -> Mono.just(this.toError(e)));
76+
.onErrorResume((e) -> Mono.just(this.toErrorResult(e)));
7377
} catch (IllegalAccessException | InvocationTargetException e) {
74-
return Mono.just(this.toError(e));
78+
log.warn("Error invoking method {}: {}", method.getName(), e.getMessage(), e);
79+
return Mono.just(this.toErrorResult(e));
7580
}
7681
});
7782
}
@@ -80,31 +85,52 @@ private Mono<CallToolResult> toCallResult(Object result) {
8085
return switch (result) {
8186
case Mono<?> mono -> mono.map(this::callToolResult);
8287
case Flux<?> flux -> flux.collectList().map(this::callToolResult);
83-
case ResponseEntity<?> response -> toCallResult(response.getBody());
88+
case ResponseEntity<?> response -> reponseToCallResult(response);
8489
case null, default -> Mono.just(this.callToolResult(result));
8590
};
8691
}
8792

93+
private Mono<CallToolResult> reponseToCallResult(ResponseEntity<?> response) {
94+
HttpStatusCode statusCode = response.getStatusCode();
95+
if (statusCode.is2xxSuccessful() || statusCode.is1xxInformational()) {
96+
return Mono.just(this.callToolResult(response.getBody()));
97+
} else {
98+
try {
99+
return Mono.just(toErrorResult(objectMapper.writeValueAsString(response.getBody())));
100+
} catch (JsonProcessingException e) {
101+
return Mono.just(toErrorResult(e));
102+
}
103+
}
104+
}
105+
88106
private CallToolResult callToolResult(Object result) {
89107
try {
90108
return new CallToolResult(
91109
List.of(new McpSchema.TextContent(objectMapper.writeValueAsString(result))),
92110
false
93111
);
94112
} catch (Exception e) {
95-
return toError(e);
113+
return toErrorResult(e);
96114
}
97115
}
98116

99-
protected CallToolResult toError(Throwable e) {
117+
protected CallToolResult toErrorResult(String body) {
118+
return new CallToolResult(
119+
List.of(new McpSchema.TextContent(body)),
120+
true
121+
);
122+
}
123+
124+
protected CallToolResult toErrorResult(Throwable e) {
125+
log.warn("Error responded to MCP Client: {}", e.getMessage(), e);
100126
return new CallToolResult(
101127
List.of(new McpSchema.TextContent(e.getMessage())),
102128
true
103129
);
104130
}
105131

106132
private Object[] toParams(
107-
Map<String, Object> v,
133+
Map<String, Object> mcpArgs,
108134
Parameter[] parameters,
109135
McpAsyncServerExchange ex,
110136
ServerWebExchange serverWebExchange
@@ -117,8 +143,8 @@ private Object[] toParams(
117143
} else if (parameter.getType().equals(McpAsyncServerExchange.class)) {
118144
values[i] = ex;
119145
} else {
120-
Object o = v.get(parameter.getName());
121-
if (o != null) {
146+
Object arg = mcpArgs.get(parameter.getName());
147+
if (arg != null) {
122148
Class<?> parameterType = parameter.getType();
123149
boolean mono = false;
124150

@@ -129,11 +155,11 @@ private Object[] toParams(
129155
mono = true;
130156
}
131157

132-
if (parameterType.isAssignableFrom(o.getClass())) {
133-
values[i] = mono ? Mono.just(o) : o;
134-
} else if (Map.class.isAssignableFrom(o.getClass())) {
158+
if (parameterType.isAssignableFrom(arg.getClass())) {
159+
values[i] = mono ? Mono.just(arg) : arg;
160+
} else if (Map.class.isAssignableFrom(arg.getClass())) {
135161
try {
136-
Object obj = objectMapper.convertValue(o, parameterType);
162+
Object obj = objectMapper.convertValue(arg, parameterType);
137163
values[i] = mono ? Mono.just(obj) : obj;
138164
} catch (Exception e) {
139165
throw new RuntimeException(e);
@@ -149,7 +175,7 @@ private Object[] toParams(
149175
private JsonSchema operationSchema(Method method, McpTool instance) {
150176
Method annotatedMethod = findAnnotatedMethod(method, instance);
151177

152-
Map<String, Object> parameters = new HashMap<>();
178+
Map<String, Object> parametersSchemas = new HashMap<>();
153179
List<String> required = new ArrayList<>();
154180
Parameter[] annotatedParameters = annotatedMethod.getParameters();
155181
Parameter[] methodParameters = method.getParameters();
@@ -163,14 +189,14 @@ private JsonSchema operationSchema(Method method, McpTool instance) {
163189
if (parameterAnnotation.required()) {
164190
required.add(methodParameter.getName());
165191
}
166-
parameters.put(
192+
parametersSchemas.put(
167193
methodParameter.getName(),
168194
getTypeSchema(methodParameter)
169195
);
170196
}
171197
}
172198
return new JsonSchema(
173-
"object", parameters, required,
199+
"object", parametersSchemas, required,
174200
false,
175201
null, null
176202
);

api/src/test/java/io/kafbat/ui/service/mcp/McpSpecificationGeneratorTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
class McpSpecificationGeneratorTest {
2525
private static final SchemaGenerator SCHEMA_GENERATOR = schemaGenerator();
2626
private static final McpSpecificationGenerator MCP_SPECIFICATION_GENERATOR =
27-
new McpSpecificationGenerator(SCHEMA_GENERATOR, new ObjectMapper());
27+
new McpSpecificationGenerator(SCHEMA_GENERATOR);
2828

2929
private static SchemaGenerator schemaGenerator() {
3030
SchemaGeneratorConfigBuilder configBuilder =

0 commit comments

Comments
 (0)