Skip to content

Commit e45bbb9

Browse files
committed
Review changes
1 parent f46c782 commit e45bbb9

25 files changed

+337
-221
lines changed

codegen/src/main/java/io/helidon/extensions/mcp/codegen/McpCodegenProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
import static io.helidon.extensions.mcp.codegen.McpTypes.MCP_SERVER;
2727

2828
/**
29-
* Mcp code generator provider.
29+
* MCP code generator provider.
3030
*/
3131
public class McpCodegenProvider implements CodegenExtensionProvider {
3232
/**

server/src/main/java/io/helidon/extensions/mcp/server/Mcp.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public final class Mcp {
3939
* <ul>
4040
* <li>
4141
* {@link io.helidon.extensions.mcp.server.Mcp.Tool} -
42-
* Tool is a function that computes a set of inputs and return a result. Mcp server uses tools to
42+
* Tool is a function that computes a set of inputs and return a result. MCP server uses tools to
4343
* interact with the outside world to reach real time data through API calls, access to databases
4444
* or performing any kind of computation.
4545
* </li>

server/src/main/java/io/helidon/extensions/mcp/server/McpAudioContent.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,5 @@
1919
/**
2020
* Audio content.
2121
*/
22-
sealed interface McpAudioContent extends McpMediaContent permits McpAudioContentImpl,
23-
McpSamplingAudioContent {
22+
sealed interface McpAudioContent extends McpMediaContent permits McpAudioContentImpl {
2423
}

server/src/main/java/io/helidon/extensions/mcp/server/McpDecorators.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public void decorate(McpServerConfig.BuilderBase<?, ?> builder, Integer pageSize
5050
static class IntelligencePriorityDecorator implements Prototype.OptionDecorator<McpSamplingRequest.BuilderBase<?, ?>, Optional<Double>> {
5151
@Override
5252
public void decorate(McpSamplingRequest.BuilderBase<?, ?> builder, Optional<Double> value) {
53-
value.filter(McpDecorators::isPositiveAndInferiorToOne)
53+
value.filter(McpDecorators::isPositiveAndLessThanOne)
5454
.orElseThrow(() -> new IllegalArgumentException("Intelligence priority must be in range [0, 1]"));
5555
}
5656
}
@@ -63,7 +63,7 @@ public void decorate(McpSamplingRequest.BuilderBase<?, ?> builder, Optional<Doub
6363
static class SpeedPriorityDecorator implements Prototype.OptionDecorator<McpSamplingRequest.BuilderBase<?, ?>, Optional<Double>> {
6464
@Override
6565
public void decorate(McpSamplingRequest.BuilderBase<?, ?> builder, Optional<Double> value) {
66-
value.filter(McpDecorators::isPositiveAndInferiorToOne)
66+
value.filter(McpDecorators::isPositiveAndLessThanOne)
6767
.orElseThrow(() -> new IllegalArgumentException("Speed priority must be in range [0, 1]"));
6868
}
6969
}
@@ -76,12 +76,12 @@ public void decorate(McpSamplingRequest.BuilderBase<?, ?> builder, Optional<Doub
7676
static class CostPriorityDecorator implements Prototype.OptionDecorator<McpSamplingRequest.BuilderBase<?, ?>, Optional<Double>> {
7777
@Override
7878
public void decorate(McpSamplingRequest.BuilderBase<?, ?> builder, Optional<Double> value) {
79-
value.filter(McpDecorators::isPositiveAndInferiorToOne)
79+
value.filter(McpDecorators::isPositiveAndLessThanOne)
8080
.orElseThrow(() -> new IllegalArgumentException("Cost priority must be in range [0, 1]"));
8181
}
8282
}
8383

84-
static boolean isPositiveAndInferiorToOne(Double value) {
84+
static boolean isPositiveAndLessThanOne(Double value) {
8585
return 0 <= value && value <= 1.0;
8686
}
8787
}

server/src/main/java/io/helidon/extensions/mcp/server/McpImageContent.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,5 @@
1919
/**
2020
* Image content.
2121
*/
22-
sealed interface McpImageContent extends McpMediaContent permits McpImageContentImpl, McpSamplingImageContent {
22+
sealed interface McpImageContent extends McpMediaContent permits McpImageContentImpl {
2323
}

server/src/main/java/io/helidon/extensions/mcp/server/McpJsonRpc.java

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -378,13 +378,13 @@ static JsonObjectBuilder toJson(McpContent content) {
378378
}
379379

380380
static JsonObjectBuilder toJson(McpSamplingMessage message) {
381-
if (message instanceof McpSamplingTextContent text) {
381+
if (message instanceof McpSamplingTextContentImpl text) {
382382
return toJson(text);
383383
}
384-
if (message instanceof McpSamplingImageContent image) {
384+
if (message instanceof McpSamplingImageContentImpl image) {
385385
return toJson(image);
386386
}
387-
if (message instanceof McpSamplingAudioContent resource) {
387+
if (message instanceof McpSamplingAudioContentImpl resource) {
388388
return toJson(resource);
389389
}
390390
throw new IllegalArgumentException("Unsupported content type: " + message.getClass().getName());
@@ -430,19 +430,27 @@ static JsonObjectBuilder toJson(McpPromptAudioContent audio) {
430430
static JsonObjectBuilder toJson(McpSamplingImageContent image) {
431431
return JSON_BUILDER_FACTORY.createObjectBuilder()
432432
.add("role", image.role().text())
433-
.add("content", toJson((McpImageContent) image));
433+
.add("content", JSON_BUILDER_FACTORY.createObjectBuilder()
434+
.add("type", image.type().text())
435+
.add("data", image.encodeBase64Data())
436+
.add("mimeType", image.mediaType().text()));
434437
}
435438

436439
static JsonObjectBuilder toJson(McpSamplingTextContent text) {
437440
return JSON_BUILDER_FACTORY.createObjectBuilder()
438441
.add("role", text.role().text())
439-
.add("content", toJson((McpTextContent) text));
442+
.add("content", JSON_BUILDER_FACTORY.createObjectBuilder()
443+
.add("type", text.type().text())
444+
.add("text", text.text()));
440445
}
441446

442447
static JsonObjectBuilder toJson(McpSamplingAudioContent audio) {
443448
return JSON_BUILDER_FACTORY.createObjectBuilder()
444449
.add("role", audio.role().text())
445-
.add("content", toJson((McpAudioContent) audio));
450+
.add("content", JSON_BUILDER_FACTORY.createObjectBuilder()
451+
.add("type", audio.type().text())
452+
.add("data", audio.encodeBase64Data())
453+
.add("mimeType", audio.mediaType().text()));
446454
}
447455

448456
static JsonObjectBuilder toJson(McpTextContent content) {
@@ -645,16 +653,16 @@ private static McpSamplingMessage parseMessage(McpRole role, JsonObject object)
645653
String type = object.getString("type").toUpperCase();
646654
McpContent.ContentType contentType = McpContent.ContentType.valueOf(type);
647655
return switch (contentType) {
648-
case TEXT -> new McpSamplingTextContent(object.getString("text"), role);
656+
case TEXT -> new McpSamplingTextContentImpl(object.getString("text"), role);
649657
case IMAGE -> {
650658
byte[] data = object.getString("data").getBytes(StandardCharsets.UTF_8);
651659
MediaType mediaType = MediaTypes.create(object.getString("mimeType"));
652-
yield new McpSamplingImageContent(data, mediaType, role);
660+
yield new McpSamplingImageContentImpl(data, mediaType, role);
653661
}
654662
case AUDIO -> {
655663
byte[] data = object.getString("data").getBytes(StandardCharsets.UTF_8);
656664
MediaType mediaType = MediaTypes.create(object.getString("mimeType"));
657-
yield new McpSamplingAudioContent(data, mediaType, role);
665+
yield new McpSamplingAudioContentImpl(data, mediaType, role);
658666
}
659667
default -> throw new IllegalArgumentException("Unknown content type: " + type);
660668
};

server/src/main/java/io/helidon/extensions/mcp/server/McpParameters.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
import jakarta.json.JsonValue;
3636

3737
/**
38-
* Mcp client parameters provided to {@link McpTool} and {@link McpPrompt}.
38+
* MCP client parameters provided to {@link McpTool} and {@link McpPrompt}.
3939
*/
4040
public final class McpParameters {
4141
private static final Mappers MAPPERS = Mappers.create();
@@ -63,7 +63,7 @@ private McpParameters(JsonValue root, String key) {
6363
}
6464

6565
/**
66-
* Get Mcp parameter node.
66+
* Get MCP parameter node.
6767
*
6868
* @param key node key
6969
* @return parameter

server/src/main/java/io/helidon/extensions/mcp/server/McpSampling.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public final class McpSampling extends McpFeature {
4747
* @return {@code true} if the connected client supports sampling feature,
4848
* {@code false} otherwise.
4949
*/
50-
public boolean isEnabled() {
50+
public boolean enabled() {
5151
return session()
5252
.capabilities()
5353
.contains(McpCapability.SAMPLING);
@@ -77,20 +77,19 @@ public McpSamplingResponse request(McpSamplingRequest request) throws McpSamplin
7777
long id = session().jsonRpcId();
7878
JsonObject payload = createSamplingRequest(id, request);
7979

80-
log("Sampling request:\n" + prettyPrint(payload));
80+
if (LOGGER.isLoggable(Level.DEBUG)) {
81+
LOGGER.log(Level.DEBUG, "Sampling request:\n" + prettyPrint(payload));
82+
}
8183
sseSink().ifPresentOrElse(sink -> sink.emit(SseEvent.builder()
8284
.name("message")
8385
.data(payload)
8486
.build()),
8587
() -> session().send(payload));
8688
JsonObject response = session().pollResponse(id, request.timeout());
87-
log("Sampling response:\n" + prettyPrint(response));
88-
return createSamplingResponse(response);
89-
}
90-
91-
private void log(String message) {
9289
if (LOGGER.isLoggable(Level.DEBUG)) {
93-
LOGGER.log(Level.DEBUG, () -> message);
90+
LOGGER.log(Level.DEBUG, "Sampling response:\n" + prettyPrint(response));
9491
}
92+
return createSamplingResponse(response);
9593
}
94+
9695
}

server/src/main/java/io/helidon/extensions/mcp/server/McpSamplingAudioContent.java

Lines changed: 2 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -13,54 +13,11 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
1716
package io.helidon.extensions.mcp.server;
1817

19-
import java.util.Base64;
20-
21-
import io.helidon.common.media.type.MediaType;
22-
2318
/**
2419
* MCP sampling audio content.
2520
*/
26-
public final class McpSamplingAudioContent implements McpSamplingMessage, McpAudioContent {
27-
private final byte[] data;
28-
private final McpRole role;
29-
private final MediaType type;
30-
31-
McpSamplingAudioContent(byte[] data, MediaType type, McpRole role) {
32-
this.data = data;
33-
this.role = role;
34-
this.type = type;
35-
}
36-
37-
@Override
38-
public McpSamplingAudioContent asAudio() {
39-
return this;
40-
}
41-
42-
@Override
43-
public ContentType type() {
44-
return ContentType.AUDIO;
45-
}
46-
47-
@Override
48-
public McpRole role() {
49-
return role;
50-
}
51-
52-
@Override
53-
public byte[] data() {
54-
return data;
55-
}
56-
57-
@Override
58-
public String base64Data() {
59-
return Base64.getEncoder().encodeToString(data);
60-
}
61-
62-
@Override
63-
public MediaType mediaType() {
64-
return type;
65-
}
21+
public sealed interface McpSamplingAudioContent extends McpSamplingMessage,
22+
McpSamplingMediaContent permits McpSamplingAudioContentImpl {
6623
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Copyright (c) 2025 Oracle and/or its affiliates.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.helidon.extensions.mcp.server;
17+
18+
import java.util.Base64;
19+
20+
import io.helidon.common.media.type.MediaType;
21+
22+
/**
23+
* MCP sampling audio content.
24+
*/
25+
final class McpSamplingAudioContentImpl implements McpSamplingAudioContent {
26+
private final byte[] data;
27+
private final McpRole role;
28+
private final MediaType type;
29+
30+
McpSamplingAudioContentImpl(byte[] data, MediaType type, McpRole role) {
31+
this.data = data;
32+
this.role = role;
33+
this.type = type;
34+
}
35+
36+
@Override
37+
public ContentType type() {
38+
return ContentType.AUDIO;
39+
}
40+
41+
@Override
42+
public McpRole role() {
43+
return role;
44+
}
45+
46+
@Override
47+
public MediaType mediaType() {
48+
return type;
49+
}
50+
51+
@Override
52+
public byte[] data() {
53+
return data;
54+
}
55+
56+
@Override
57+
public byte[] decodeBase64Data() {
58+
return Base64.getMimeDecoder().decode(data);
59+
}
60+
61+
@Override
62+
public String encodeBase64Data() {
63+
return Base64.getMimeEncoder().encodeToString(data);
64+
}
65+
}

0 commit comments

Comments
 (0)