feat: Add title field support to MCP schema classes (#372)
- Add BaseMetadata interface with name() and title() methods for consistent metadata handling - The Prompt, PromptArgument, Resource, ResourceTemplate, ResuorceLink, PromptReference, Tool, and Implementation classes implement the BaseMetadata interface, adding a new, optional title field - Update constructors to support backward compatibility while allowing title specification - Modify ResourceContent interface to extend BaseMetadata - Update all test cases to accommodate new title parameter The title field provides human-readable display names optimized for UI contexts, while name remains for programmatic/logical use. This change maintains backward compatibility. Signed-off-by: Christian Tzolov <christian.tzolov@broadcom.com> Co-authored-by: Christian Tzolov <christian.tzolov@broadcom.com>
This commit is contained in:
parent
b5a1e3b8f4
commit
9977a064d5
11 changed files with 1053 additions and 929 deletions
|
|
@ -996,11 +996,11 @@ class WebFluxSseIntegrationTests {
|
||||||
var mcpServer = McpServer.sync(mcpServerTransportProvider)
|
var mcpServer = McpServer.sync(mcpServerTransportProvider)
|
||||||
.capabilities(ServerCapabilities.builder().completions().build())
|
.capabilities(ServerCapabilities.builder().completions().build())
|
||||||
.prompts(new McpServerFeatures.SyncPromptSpecification(
|
.prompts(new McpServerFeatures.SyncPromptSpecification(
|
||||||
new Prompt("code_review", "this is code review prompt",
|
new Prompt("code_review", "Code review", "this is code review prompt",
|
||||||
List.of(new PromptArgument("language", "string", false))),
|
List.of(new PromptArgument("language", "Language", "string", false))),
|
||||||
(mcpSyncServerExchange, getPromptRequest) -> null))
|
(mcpSyncServerExchange, getPromptRequest) -> null))
|
||||||
.completions(new McpServerFeatures.SyncCompletionSpecification(
|
.completions(new McpServerFeatures.SyncCompletionSpecification(
|
||||||
new McpSchema.PromptReference("ref/prompt", "code_review"), completionHandler))
|
new McpSchema.PromptReference("ref/prompt", "code_review", "Code review"), completionHandler))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
try (var mcpClient = clientBuilder.build()) {
|
try (var mcpClient = clientBuilder.build()) {
|
||||||
|
|
@ -1008,7 +1008,8 @@ class WebFluxSseIntegrationTests {
|
||||||
InitializeResult initResult = mcpClient.initialize();
|
InitializeResult initResult = mcpClient.initialize();
|
||||||
assertThat(initResult).isNotNull();
|
assertThat(initResult).isNotNull();
|
||||||
|
|
||||||
CompleteRequest request = new CompleteRequest(new PromptReference("ref/prompt", "code_review"),
|
CompleteRequest request = new CompleteRequest(
|
||||||
|
new PromptReference("ref/prompt", "code_review", "Code review"),
|
||||||
new CompleteRequest.CompleteArgument("language", "py"));
|
new CompleteRequest.CompleteArgument("language", "py"));
|
||||||
|
|
||||||
CompleteResult result = mcpClient.completeCompletion(request);
|
CompleteResult result = mcpClient.completeCompletion(request);
|
||||||
|
|
|
||||||
|
|
@ -420,7 +420,7 @@ public abstract class AbstractMcpAsyncClientTests {
|
||||||
.consumeNextWith(result -> {
|
.consumeNextWith(result -> {
|
||||||
assertThat(result.prompts()).isNotNull();
|
assertThat(result.prompts()).isNotNull();
|
||||||
// Verify that the returned list is immutable
|
// Verify that the returned list is immutable
|
||||||
assertThatThrownBy(() -> result.prompts().add(new Prompt("test", "test", null)))
|
assertThatThrownBy(() -> result.prompts().add(new Prompt("test", "Test", "test", null)))
|
||||||
.isInstanceOf(UnsupportedOperationException.class);
|
.isInstanceOf(UnsupportedOperationException.class);
|
||||||
})
|
})
|
||||||
.verifyComplete();
|
.verifyComplete();
|
||||||
|
|
@ -604,7 +604,7 @@ public abstract class AbstractMcpAsyncClientTests {
|
||||||
assertThat(result.resourceTemplates()).isNotNull();
|
assertThat(result.resourceTemplates()).isNotNull();
|
||||||
// Verify that the returned list is immutable
|
// Verify that the returned list is immutable
|
||||||
assertThatThrownBy(() -> result.resourceTemplates()
|
assertThatThrownBy(() -> result.resourceTemplates()
|
||||||
.add(new McpSchema.ResourceTemplate("test://template", "test", null, null, null)))
|
.add(new McpSchema.ResourceTemplate("test://template", "test", "test", null, null, null)))
|
||||||
.isInstanceOf(UnsupportedOperationException.class);
|
.isInstanceOf(UnsupportedOperationException.class);
|
||||||
})
|
})
|
||||||
.verifyComplete();
|
.verifyComplete();
|
||||||
|
|
|
||||||
|
|
@ -302,7 +302,7 @@ public abstract class AbstractMcpAsyncServerTests {
|
||||||
.serverInfo("test-server", "1.0.0")
|
.serverInfo("test-server", "1.0.0")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
Prompt prompt = new Prompt(TEST_PROMPT_NAME, "Test Prompt", List.of());
|
Prompt prompt = new Prompt(TEST_PROMPT_NAME, "Test Prompt", "Test Prompt", List.of());
|
||||||
McpServerFeatures.AsyncPromptSpecification specification = new McpServerFeatures.AsyncPromptSpecification(
|
McpServerFeatures.AsyncPromptSpecification specification = new McpServerFeatures.AsyncPromptSpecification(
|
||||||
prompt, (exchange, req) -> Mono.just(new GetPromptResult("Test prompt description", List
|
prompt, (exchange, req) -> Mono.just(new GetPromptResult("Test prompt description", List
|
||||||
.of(new PromptMessage(McpSchema.Role.ASSISTANT, new McpSchema.TextContent("Test content"))))));
|
.of(new PromptMessage(McpSchema.Role.ASSISTANT, new McpSchema.TextContent("Test content"))))));
|
||||||
|
|
@ -330,7 +330,7 @@ public abstract class AbstractMcpAsyncServerTests {
|
||||||
void testRemovePrompt() {
|
void testRemovePrompt() {
|
||||||
String TEST_PROMPT_NAME_TO_REMOVE = "TEST_PROMPT_NAME678";
|
String TEST_PROMPT_NAME_TO_REMOVE = "TEST_PROMPT_NAME678";
|
||||||
|
|
||||||
Prompt prompt = new Prompt(TEST_PROMPT_NAME_TO_REMOVE, "Test Prompt", List.of());
|
Prompt prompt = new Prompt(TEST_PROMPT_NAME_TO_REMOVE, "Test Prompt", "Test Prompt", List.of());
|
||||||
McpServerFeatures.AsyncPromptSpecification specification = new McpServerFeatures.AsyncPromptSpecification(
|
McpServerFeatures.AsyncPromptSpecification specification = new McpServerFeatures.AsyncPromptSpecification(
|
||||||
prompt, (exchange, req) -> Mono.just(new GetPromptResult("Test prompt description", List
|
prompt, (exchange, req) -> Mono.just(new GetPromptResult("Test prompt description", List
|
||||||
.of(new PromptMessage(McpSchema.Role.ASSISTANT, new McpSchema.TextContent("Test content"))))));
|
.of(new PromptMessage(McpSchema.Role.ASSISTANT, new McpSchema.TextContent("Test content"))))));
|
||||||
|
|
|
||||||
|
|
@ -289,7 +289,7 @@ public abstract class AbstractMcpSyncServerTests {
|
||||||
.serverInfo("test-server", "1.0.0")
|
.serverInfo("test-server", "1.0.0")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
Prompt prompt = new Prompt(TEST_PROMPT_NAME, "Test Prompt", List.of());
|
Prompt prompt = new Prompt(TEST_PROMPT_NAME, "Test Prompt", "Test Prompt", List.of());
|
||||||
McpServerFeatures.SyncPromptSpecification specification = new McpServerFeatures.SyncPromptSpecification(prompt,
|
McpServerFeatures.SyncPromptSpecification specification = new McpServerFeatures.SyncPromptSpecification(prompt,
|
||||||
(exchange, req) -> new GetPromptResult("Test prompt description", List
|
(exchange, req) -> new GetPromptResult("Test prompt description", List
|
||||||
.of(new PromptMessage(McpSchema.Role.ASSISTANT, new McpSchema.TextContent("Test content")))));
|
.of(new PromptMessage(McpSchema.Role.ASSISTANT, new McpSchema.TextContent("Test content")))));
|
||||||
|
|
@ -310,7 +310,7 @@ public abstract class AbstractMcpSyncServerTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testRemovePrompt() {
|
void testRemovePrompt() {
|
||||||
Prompt prompt = new Prompt(TEST_PROMPT_NAME, "Test Prompt", List.of());
|
Prompt prompt = new Prompt(TEST_PROMPT_NAME, "Test Prompt", "Test Prompt", List.of());
|
||||||
McpServerFeatures.SyncPromptSpecification specification = new McpServerFeatures.SyncPromptSpecification(prompt,
|
McpServerFeatures.SyncPromptSpecification specification = new McpServerFeatures.SyncPromptSpecification(prompt,
|
||||||
(exchange, req) -> new GetPromptResult("Test prompt description", List
|
(exchange, req) -> new GetPromptResult("Test prompt description", List
|
||||||
.of(new PromptMessage(McpSchema.Role.ASSISTANT, new McpSchema.TextContent("Test content")))));
|
.of(new PromptMessage(McpSchema.Role.ASSISTANT, new McpSchema.TextContent("Test content")))));
|
||||||
|
|
|
||||||
|
|
@ -462,8 +462,8 @@ public class McpAsyncServer {
|
||||||
.filter(uri -> uri.contains("{"))
|
.filter(uri -> uri.contains("{"))
|
||||||
.map(uri -> {
|
.map(uri -> {
|
||||||
var resource = this.resources.get(uri).resource();
|
var resource = this.resources.get(uri).resource();
|
||||||
var template = new McpSchema.ResourceTemplate(resource.uri(), resource.name(), resource.description(),
|
var template = new McpSchema.ResourceTemplate(resource.uri(), resource.name(), resource.title(),
|
||||||
resource.mimeType(), resource.annotations());
|
resource.description(), resource.mimeType(), resource.annotations());
|
||||||
return template;
|
return template;
|
||||||
})
|
})
|
||||||
.toList();
|
.toList();
|
||||||
|
|
@ -725,7 +725,8 @@ public class McpAsyncServer {
|
||||||
String refType = (String) refMap.get("type");
|
String refType = (String) refMap.get("type");
|
||||||
|
|
||||||
McpSchema.CompleteReference ref = switch (refType) {
|
McpSchema.CompleteReference ref = switch (refType) {
|
||||||
case "ref/prompt" -> new McpSchema.PromptReference(refType, (String) refMap.get("name"));
|
case "ref/prompt" -> new McpSchema.PromptReference(refType, (String) refMap.get("name"),
|
||||||
|
refMap.get("title") != null ? (String) refMap.get("title") : null);
|
||||||
case "ref/resource" -> new McpSchema.ResourceReference(refType, (String) refMap.get("uri"));
|
case "ref/resource" -> new McpSchema.ResourceReference(refType, (String) refMap.get("uri"));
|
||||||
default -> throw new IllegalArgumentException("Invalid ref type: " + refType);
|
default -> throw new IllegalArgumentException("Invalid ref type: " + refType);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ import org.slf4j.LoggerFactory;
|
||||||
*
|
*
|
||||||
* @author Christian Tzolov
|
* @author Christian Tzolov
|
||||||
* @author Luca Chang
|
* @author Luca Chang
|
||||||
|
* @author Surbhi Bansal
|
||||||
*/
|
*/
|
||||||
public final class McpSchema {
|
public final class McpSchema {
|
||||||
|
|
||||||
|
|
@ -447,12 +448,26 @@ public final class McpSchema {
|
||||||
}
|
}
|
||||||
} // @formatter:on
|
} // @formatter:on
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Describes the name and version of an MCP implementation, with an optional title for
|
||||||
|
* UI representation.
|
||||||
|
*
|
||||||
|
* @param name Intended for programmatic or logical use, but used as a display name in
|
||||||
|
* past specs or fallback (if title isn't present).
|
||||||
|
* @param title Intended for UI and end-user contexts
|
||||||
|
* @param version The version of the implementation.
|
||||||
|
*/
|
||||||
@JsonInclude(JsonInclude.Include.NON_ABSENT)
|
@JsonInclude(JsonInclude.Include.NON_ABSENT)
|
||||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
public record Implementation(// @formatter:off
|
public record Implementation(// @formatter:off
|
||||||
@JsonProperty("name") String name,
|
@JsonProperty("name") String name,
|
||||||
@JsonProperty("version") String version) {
|
@JsonProperty("title") String title,
|
||||||
} // @formatter:on
|
@JsonProperty("version") String version) implements BaseMetadata {// @formatter:on
|
||||||
|
|
||||||
|
public Implementation(String name, String version) {
|
||||||
|
this(name, null, version);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Existing Enums and Base Types (from previous implementation)
|
// Existing Enums and Base Types (from previous implementation)
|
||||||
public enum Role {// @formatter:off
|
public enum Role {// @formatter:off
|
||||||
|
|
@ -499,12 +514,10 @@ public final class McpSchema {
|
||||||
* interface is implemented by both {@link Resource} and {@link ResourceLink} to
|
* interface is implemented by both {@link Resource} and {@link ResourceLink} to
|
||||||
* provide a consistent way to access resource metadata.
|
* provide a consistent way to access resource metadata.
|
||||||
*/
|
*/
|
||||||
public interface ResourceContent {
|
public interface ResourceContent extends BaseMetadata {
|
||||||
|
|
||||||
String uri();
|
String uri();
|
||||||
|
|
||||||
String name();
|
|
||||||
|
|
||||||
String description();
|
String description();
|
||||||
|
|
||||||
String mimeType();
|
String mimeType();
|
||||||
|
|
@ -515,12 +528,35 @@ public final class McpSchema {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base interface for metadata with name (identifier) and title (display name)
|
||||||
|
* properties.
|
||||||
|
*/
|
||||||
|
public interface BaseMetadata {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Intended for programmatic or logical use, but used as a display name in past
|
||||||
|
* specs or fallback (if title isn't present).
|
||||||
|
*/
|
||||||
|
String name();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Intended for UI and end-user contexts — optimized to be human-readable and
|
||||||
|
* easily understood, even by those unfamiliar with domain-specific terminology.
|
||||||
|
*
|
||||||
|
* If not provided, the name should be used for display.
|
||||||
|
*/
|
||||||
|
String title();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A known resource that the server is capable of reading.
|
* A known resource that the server is capable of reading.
|
||||||
*
|
*
|
||||||
* @param uri the URI of the resource.
|
* @param uri the URI of the resource.
|
||||||
* @param name A human-readable name for this resource. This can be used by clients to
|
* @param name A human-readable name for this resource. This can be used by clients to
|
||||||
* populate UI elements.
|
* populate UI elements.
|
||||||
|
* @param title An optional title for this resource.
|
||||||
* @param description A description of what this resource represents. This can be used
|
* @param description A description of what this resource represents. This can be used
|
||||||
* by clients to improve the LLM's understanding of available resources. It can be
|
* by clients to improve the LLM's understanding of available resources. It can be
|
||||||
* thought of like a "hint" to the model.
|
* thought of like a "hint" to the model.
|
||||||
|
|
@ -536,10 +572,11 @@ public final class McpSchema {
|
||||||
public record Resource( // @formatter:off
|
public record Resource( // @formatter:off
|
||||||
@JsonProperty("uri") String uri,
|
@JsonProperty("uri") String uri,
|
||||||
@JsonProperty("name") String name,
|
@JsonProperty("name") String name,
|
||||||
|
@JsonProperty("title") String title,
|
||||||
@JsonProperty("description") String description,
|
@JsonProperty("description") String description,
|
||||||
@JsonProperty("mimeType") String mimeType,
|
@JsonProperty("mimeType") String mimeType,
|
||||||
@JsonProperty("size") Long size,
|
@JsonProperty("size") Long size,
|
||||||
@JsonProperty("annotations") Annotations annotations) implements Annotated, ResourceContent {
|
@JsonProperty("annotations") Annotations annotations) implements Annotated, ResourceContent {// @formatter:on
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated Only exists for backwards-compatibility purposes. Use
|
* @deprecated Only exists for backwards-compatibility purposes. Use
|
||||||
|
|
@ -547,7 +584,7 @@ public final class McpSchema {
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public Resource(String uri, String name, String description, String mimeType, Annotations annotations) {
|
public Resource(String uri, String name, String description, String mimeType, Annotations annotations) {
|
||||||
this(uri, name, description, mimeType, null, annotations);
|
this(uri, name, null, description, mimeType, null, annotations);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Builder builder() {
|
public static Builder builder() {
|
||||||
|
|
@ -555,11 +592,19 @@ public final class McpSchema {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
|
|
||||||
private String uri;
|
private String uri;
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
|
private String title;
|
||||||
|
|
||||||
private String description;
|
private String description;
|
||||||
|
|
||||||
private String mimeType;
|
private String mimeType;
|
||||||
|
|
||||||
private Long size;
|
private Long size;
|
||||||
|
|
||||||
private Annotations annotations;
|
private Annotations annotations;
|
||||||
|
|
||||||
public Builder uri(String uri) {
|
public Builder uri(String uri) {
|
||||||
|
|
@ -572,6 +617,11 @@ public final class McpSchema {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Builder title(String title) {
|
||||||
|
this.title = title;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public Builder description(String description) {
|
public Builder description(String description) {
|
||||||
this.description = description;
|
this.description = description;
|
||||||
return this;
|
return this;
|
||||||
|
|
@ -596,10 +646,11 @@ public final class McpSchema {
|
||||||
Assert.hasText(uri, "uri must not be empty");
|
Assert.hasText(uri, "uri must not be empty");
|
||||||
Assert.hasText(name, "name must not be empty");
|
Assert.hasText(name, "name must not be empty");
|
||||||
|
|
||||||
return new Resource(uri, name, description, mimeType, size, annotations);
|
return new Resource(uri, name, title, description, mimeType, size, annotations);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // @formatter:on
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resource templates allow servers to expose parameterized resources using URI
|
* Resource templates allow servers to expose parameterized resources using URI
|
||||||
|
|
@ -609,6 +660,7 @@ public final class McpSchema {
|
||||||
* resource.
|
* resource.
|
||||||
* @param name A human-readable name for this resource. This can be used by clients to
|
* @param name A human-readable name for this resource. This can be used by clients to
|
||||||
* populate UI elements.
|
* populate UI elements.
|
||||||
|
* @param title An optional title for this resource.
|
||||||
* @param description A description of what this resource represents. This can be used
|
* @param description A description of what this resource represents. This can be used
|
||||||
* by clients to improve the LLM's understanding of available resources. It can be
|
* by clients to improve the LLM's understanding of available resources. It can be
|
||||||
* thought of like a "hint" to the model.
|
* thought of like a "hint" to the model.
|
||||||
|
|
@ -622,9 +674,10 @@ public final class McpSchema {
|
||||||
public record ResourceTemplate( // @formatter:off
|
public record ResourceTemplate( // @formatter:off
|
||||||
@JsonProperty("uriTemplate") String uriTemplate,
|
@JsonProperty("uriTemplate") String uriTemplate,
|
||||||
@JsonProperty("name") String name,
|
@JsonProperty("name") String name,
|
||||||
|
@JsonProperty("title") String title,
|
||||||
@JsonProperty("description") String description,
|
@JsonProperty("description") String description,
|
||||||
@JsonProperty("mimeType") String mimeType,
|
@JsonProperty("mimeType") String mimeType,
|
||||||
@JsonProperty("annotations") Annotations annotations) implements Annotated {
|
@JsonProperty("annotations") Annotations annotations) implements Annotated, BaseMetadata {
|
||||||
} // @formatter:on
|
} // @formatter:on
|
||||||
|
|
||||||
@JsonInclude(JsonInclude.Include.NON_ABSENT)
|
@JsonInclude(JsonInclude.Include.NON_ABSENT)
|
||||||
|
|
@ -645,12 +698,12 @@ public final class McpSchema {
|
||||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
public record ReadResourceRequest( // @formatter:off
|
public record ReadResourceRequest( // @formatter:off
|
||||||
@JsonProperty("uri") String uri,
|
@JsonProperty("uri") String uri,
|
||||||
@JsonProperty("_meta") Map<String, Object> meta) implements Request {
|
@JsonProperty("_meta") Map<String, Object> meta) implements Request {// @formatter:on
|
||||||
|
|
||||||
public ReadResourceRequest(String uri) {
|
public ReadResourceRequest(String uri) {
|
||||||
this(uri, null);
|
this(uri, null);
|
||||||
}
|
}
|
||||||
} // @formatter:on
|
}
|
||||||
|
|
||||||
@JsonInclude(JsonInclude.Include.NON_ABSENT)
|
@JsonInclude(JsonInclude.Include.NON_ABSENT)
|
||||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
|
@ -739,6 +792,7 @@ public final class McpSchema {
|
||||||
* A prompt or prompt template that the server offers.
|
* A prompt or prompt template that the server offers.
|
||||||
*
|
*
|
||||||
* @param name The name of the prompt or prompt template.
|
* @param name The name of the prompt or prompt template.
|
||||||
|
* @param title An optional title for the prompt.
|
||||||
* @param description An optional description of what this prompt provides.
|
* @param description An optional description of what this prompt provides.
|
||||||
* @param arguments A list of arguments to use for templating the prompt.
|
* @param arguments A list of arguments to use for templating the prompt.
|
||||||
*/
|
*/
|
||||||
|
|
@ -746,14 +800,16 @@ public final class McpSchema {
|
||||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
public record Prompt( // @formatter:off
|
public record Prompt( // @formatter:off
|
||||||
@JsonProperty("name") String name,
|
@JsonProperty("name") String name,
|
||||||
|
@JsonProperty("title") String title,
|
||||||
@JsonProperty("description") String description,
|
@JsonProperty("description") String description,
|
||||||
@JsonProperty("arguments") List<PromptArgument> arguments) {
|
@JsonProperty("arguments") List<PromptArgument> arguments) implements BaseMetadata {
|
||||||
} // @formatter:on
|
} // @formatter:on
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describes an argument that a prompt can accept.
|
* Describes an argument that a prompt can accept.
|
||||||
*
|
*
|
||||||
* @param name The name of the argument.
|
* @param name The name of the argument.
|
||||||
|
* @param title An optional title for the argument, which can be used in UI
|
||||||
* @param description A human-readable description of the argument.
|
* @param description A human-readable description of the argument.
|
||||||
* @param required Whether this argument must be provided.
|
* @param required Whether this argument must be provided.
|
||||||
*/
|
*/
|
||||||
|
|
@ -761,8 +817,9 @@ public final class McpSchema {
|
||||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
public record PromptArgument( // @formatter:off
|
public record PromptArgument( // @formatter:off
|
||||||
@JsonProperty("name") String name,
|
@JsonProperty("name") String name,
|
||||||
|
@JsonProperty("title") String title,
|
||||||
@JsonProperty("description") String description,
|
@JsonProperty("description") String description,
|
||||||
@JsonProperty("required") Boolean required) {
|
@JsonProperty("required") Boolean required) implements BaseMetadata {
|
||||||
}// @formatter:on
|
}// @formatter:on
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -872,6 +929,7 @@ public final class McpSchema {
|
||||||
*
|
*
|
||||||
* @param name A unique identifier for the tool. This name is used when calling the
|
* @param name A unique identifier for the tool. This name is used when calling the
|
||||||
* tool.
|
* tool.
|
||||||
|
* @param title A human-readable title for the tool.
|
||||||
* @param description A human-readable description of what the tool does. This can be
|
* @param description A human-readable description of what the tool does. This can be
|
||||||
* used by clients to improve the LLM's understanding of available tools.
|
* used by clients to improve the LLM's understanding of available tools.
|
||||||
* @param inputSchema A JSON Schema object that describes the expected structure of
|
* @param inputSchema A JSON Schema object that describes the expected structure of
|
||||||
|
|
@ -883,19 +941,69 @@ public final class McpSchema {
|
||||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
public record Tool( // @formatter:off
|
public record Tool( // @formatter:off
|
||||||
@JsonProperty("name") String name,
|
@JsonProperty("name") String name,
|
||||||
|
@JsonProperty("title") String title,
|
||||||
@JsonProperty("description") String description,
|
@JsonProperty("description") String description,
|
||||||
@JsonProperty("inputSchema") JsonSchema inputSchema,
|
@JsonProperty("inputSchema") JsonSchema inputSchema,
|
||||||
@JsonProperty("annotations") ToolAnnotations annotations) {
|
@JsonProperty("annotations") ToolAnnotations annotations) implements BaseMetadata { // @formatter:on
|
||||||
|
|
||||||
public Tool(String name, String description, String schema) {
|
public Tool(String name, String description, String schema) {
|
||||||
this(name, description, parseSchema(schema), null);
|
this(name, null, description, parseSchema(schema), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Tool(String name, String description, String schema, ToolAnnotations annotations) {
|
public Tool(String name, String description, String schema, ToolAnnotations annotations) {
|
||||||
this(name, description, parseSchema(schema), annotations);
|
this(name, null, description, parseSchema(schema), annotations);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // @formatter:on
|
public static Builder builder() {
|
||||||
|
return new Builder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder {
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
private JsonSchema inputSchema;
|
||||||
|
|
||||||
|
private ToolAnnotations annotations;
|
||||||
|
|
||||||
|
public Builder name(String name) {
|
||||||
|
this.name = name;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder title(String title) {
|
||||||
|
this.title = title;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder description(String description) {
|
||||||
|
this.description = description;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder inputSchema(JsonSchema inputSchema) {
|
||||||
|
this.inputSchema = inputSchema;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder annotations(ToolAnnotations annotations) {
|
||||||
|
this.annotations = annotations;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Tool build() {
|
||||||
|
Assert.hasText(name, "name must not be empty");
|
||||||
|
|
||||||
|
return new Tool(name, title, description, inputSchema, annotations);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private static JsonSchema parseSchema(String schema) {
|
private static JsonSchema parseSchema(String schema) {
|
||||||
try {
|
try {
|
||||||
|
|
@ -1579,10 +1687,11 @@ public final class McpSchema {
|
||||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
public record PromptReference(// @formatter:off
|
public record PromptReference(// @formatter:off
|
||||||
@JsonProperty("type") String type,
|
@JsonProperty("type") String type,
|
||||||
@JsonProperty("name") String name) implements McpSchema.CompleteReference {
|
@JsonProperty("name") String name,
|
||||||
|
@JsonProperty("title") String title ) implements McpSchema.CompleteReference, BaseMetadata {
|
||||||
|
|
||||||
public PromptReference(String name) {
|
public PromptReference(String name) {
|
||||||
this("ref/prompt", name);
|
this("ref/prompt", name, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -1780,6 +1889,7 @@ public final class McpSchema {
|
||||||
* @param uri the URI of the resource.
|
* @param uri the URI of the resource.
|
||||||
* @param name A human-readable name for this resource. This can be used by clients to
|
* @param name A human-readable name for this resource. This can be used by clients to
|
||||||
* populate UI elements.
|
* populate UI elements.
|
||||||
|
* @param title A human-readable title for this resource.
|
||||||
* @param description A description of what this resource represents. This can be used
|
* @param description A description of what this resource represents. This can be used
|
||||||
* by clients to improve the LLM's understanding of available resources. It can be
|
* by clients to improve the LLM's understanding of available resources. It can be
|
||||||
* thought of like a "hint" to the model.
|
* thought of like a "hint" to the model.
|
||||||
|
|
@ -1794,6 +1904,7 @@ public final class McpSchema {
|
||||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
public record ResourceLink( // @formatter:off
|
public record ResourceLink( // @formatter:off
|
||||||
@JsonProperty("name") String name,
|
@JsonProperty("name") String name,
|
||||||
|
@JsonProperty("title") String title,
|
||||||
@JsonProperty("uri") String uri,
|
@JsonProperty("uri") String uri,
|
||||||
@JsonProperty("description") String description,
|
@JsonProperty("description") String description,
|
||||||
@JsonProperty("mimeType") String mimeType,
|
@JsonProperty("mimeType") String mimeType,
|
||||||
|
|
@ -1808,6 +1919,8 @@ public final class McpSchema {
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
|
private String title;
|
||||||
|
|
||||||
private String uri;
|
private String uri;
|
||||||
|
|
||||||
private String description;
|
private String description;
|
||||||
|
|
@ -1823,6 +1936,11 @@ public final class McpSchema {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Builder title(String title) {
|
||||||
|
this.title = title;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public Builder uri(String uri) {
|
public Builder uri(String uri) {
|
||||||
this.uri = uri;
|
this.uri = uri;
|
||||||
return this;
|
return this;
|
||||||
|
|
@ -1852,7 +1970,7 @@ public final class McpSchema {
|
||||||
Assert.hasText(uri, "uri must not be empty");
|
Assert.hasText(uri, "uri must not be empty");
|
||||||
Assert.hasText(name, "name must not be empty");
|
Assert.hasText(name, "name must not be empty");
|
||||||
|
|
||||||
return new ResourceLink(name, uri, description, mimeType, size, annotations);
|
return new ResourceLink(name, title, uri, description, mimeType, size, annotations);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -421,7 +421,7 @@ public abstract class AbstractMcpAsyncClientTests {
|
||||||
.consumeNextWith(result -> {
|
.consumeNextWith(result -> {
|
||||||
assertThat(result.prompts()).isNotNull();
|
assertThat(result.prompts()).isNotNull();
|
||||||
// Verify that the returned list is immutable
|
// Verify that the returned list is immutable
|
||||||
assertThatThrownBy(() -> result.prompts().add(new Prompt("test", "test", null)))
|
assertThatThrownBy(() -> result.prompts().add(new Prompt("test", "test", "test", null)))
|
||||||
.isInstanceOf(UnsupportedOperationException.class);
|
.isInstanceOf(UnsupportedOperationException.class);
|
||||||
})
|
})
|
||||||
.verifyComplete();
|
.verifyComplete();
|
||||||
|
|
@ -605,7 +605,7 @@ public abstract class AbstractMcpAsyncClientTests {
|
||||||
assertThat(result.resourceTemplates()).isNotNull();
|
assertThat(result.resourceTemplates()).isNotNull();
|
||||||
// Verify that the returned list is immutable
|
// Verify that the returned list is immutable
|
||||||
assertThatThrownBy(() -> result.resourceTemplates()
|
assertThatThrownBy(() -> result.resourceTemplates()
|
||||||
.add(new McpSchema.ResourceTemplate("test://template", "test", null, null, null)))
|
.add(new McpSchema.ResourceTemplate("test://template", "test", "test", null, null, null)))
|
||||||
.isInstanceOf(UnsupportedOperationException.class);
|
.isInstanceOf(UnsupportedOperationException.class);
|
||||||
})
|
})
|
||||||
.verifyComplete();
|
.verifyComplete();
|
||||||
|
|
|
||||||
|
|
@ -251,8 +251,8 @@ class McpAsyncClientResponseHandlerTests {
|
||||||
assertThat(asyncMcpClient.initialize().block()).isNotNull();
|
assertThat(asyncMcpClient.initialize().block()).isNotNull();
|
||||||
|
|
||||||
// Create a mock prompts list that the server will return
|
// Create a mock prompts list that the server will return
|
||||||
McpSchema.Prompt mockPrompt = new McpSchema.Prompt("test-prompt", "Test Prompt Description",
|
McpSchema.Prompt mockPrompt = new McpSchema.Prompt("test-prompt", "Test Prompt", "Test Prompt Description",
|
||||||
List.of(new McpSchema.PromptArgument("arg1", "Test argument", true)));
|
List.of(new McpSchema.PromptArgument("arg1", "Test argument", "Test argument", true)));
|
||||||
McpSchema.ListPromptsResult mockPromptsResult = new McpSchema.ListPromptsResult(List.of(mockPrompt), null);
|
McpSchema.ListPromptsResult mockPromptsResult = new McpSchema.ListPromptsResult(List.of(mockPrompt), null);
|
||||||
|
|
||||||
// Simulate server sending prompts/list_changed notification
|
// Simulate server sending prompts/list_changed notification
|
||||||
|
|
|
||||||
|
|
@ -301,7 +301,7 @@ public abstract class AbstractMcpAsyncServerTests {
|
||||||
.serverInfo("test-server", "1.0.0")
|
.serverInfo("test-server", "1.0.0")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
Prompt prompt = new Prompt(TEST_PROMPT_NAME, "Test Prompt", List.of());
|
Prompt prompt = new Prompt(TEST_PROMPT_NAME, "Test Prompt", "Test Prompt", List.of());
|
||||||
McpServerFeatures.AsyncPromptSpecification specification = new McpServerFeatures.AsyncPromptSpecification(
|
McpServerFeatures.AsyncPromptSpecification specification = new McpServerFeatures.AsyncPromptSpecification(
|
||||||
prompt, (exchange, req) -> Mono.just(new GetPromptResult("Test prompt description", List
|
prompt, (exchange, req) -> Mono.just(new GetPromptResult("Test prompt description", List
|
||||||
.of(new PromptMessage(McpSchema.Role.ASSISTANT, new McpSchema.TextContent("Test content"))))));
|
.of(new PromptMessage(McpSchema.Role.ASSISTANT, new McpSchema.TextContent("Test content"))))));
|
||||||
|
|
@ -329,7 +329,7 @@ public abstract class AbstractMcpAsyncServerTests {
|
||||||
void testRemovePrompt() {
|
void testRemovePrompt() {
|
||||||
String TEST_PROMPT_NAME_TO_REMOVE = "TEST_PROMPT_NAME678";
|
String TEST_PROMPT_NAME_TO_REMOVE = "TEST_PROMPT_NAME678";
|
||||||
|
|
||||||
Prompt prompt = new Prompt(TEST_PROMPT_NAME_TO_REMOVE, "Test Prompt", List.of());
|
Prompt prompt = new Prompt(TEST_PROMPT_NAME_TO_REMOVE, "Test Prompt", "Test Prompt", List.of());
|
||||||
McpServerFeatures.AsyncPromptSpecification specification = new McpServerFeatures.AsyncPromptSpecification(
|
McpServerFeatures.AsyncPromptSpecification specification = new McpServerFeatures.AsyncPromptSpecification(
|
||||||
prompt, (exchange, req) -> Mono.just(new GetPromptResult("Test prompt description", List
|
prompt, (exchange, req) -> Mono.just(new GetPromptResult("Test prompt description", List
|
||||||
.of(new PromptMessage(McpSchema.Role.ASSISTANT, new McpSchema.TextContent("Test content"))))));
|
.of(new PromptMessage(McpSchema.Role.ASSISTANT, new McpSchema.TextContent("Test content"))))));
|
||||||
|
|
|
||||||
|
|
@ -288,7 +288,7 @@ public abstract class AbstractMcpSyncServerTests {
|
||||||
.serverInfo("test-server", "1.0.0")
|
.serverInfo("test-server", "1.0.0")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
Prompt prompt = new Prompt(TEST_PROMPT_NAME, "Test Prompt", List.of());
|
Prompt prompt = new Prompt(TEST_PROMPT_NAME, "Test Prompt", "Test Prompt", List.of());
|
||||||
McpServerFeatures.SyncPromptSpecification specification = new McpServerFeatures.SyncPromptSpecification(prompt,
|
McpServerFeatures.SyncPromptSpecification specification = new McpServerFeatures.SyncPromptSpecification(prompt,
|
||||||
(exchange, req) -> new GetPromptResult("Test prompt description", List
|
(exchange, req) -> new GetPromptResult("Test prompt description", List
|
||||||
.of(new PromptMessage(McpSchema.Role.ASSISTANT, new McpSchema.TextContent("Test content")))));
|
.of(new PromptMessage(McpSchema.Role.ASSISTANT, new McpSchema.TextContent("Test content")))));
|
||||||
|
|
@ -309,7 +309,7 @@ public abstract class AbstractMcpSyncServerTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testRemovePrompt() {
|
void testRemovePrompt() {
|
||||||
Prompt prompt = new Prompt(TEST_PROMPT_NAME, "Test Prompt", List.of());
|
Prompt prompt = new Prompt(TEST_PROMPT_NAME, "Test Prompt", "Test Prompt", List.of());
|
||||||
McpServerFeatures.SyncPromptSpecification specification = new McpServerFeatures.SyncPromptSpecification(prompt,
|
McpServerFeatures.SyncPromptSpecification specification = new McpServerFeatures.SyncPromptSpecification(prompt,
|
||||||
(exchange, req) -> new GetPromptResult("Test prompt description", List
|
(exchange, req) -> new GetPromptResult("Test prompt description", List
|
||||||
.of(new PromptMessage(McpSchema.Role.ASSISTANT, new McpSchema.TextContent("Test content")))));
|
.of(new PromptMessage(McpSchema.Role.ASSISTANT, new McpSchema.TextContent("Test content")))));
|
||||||
|
|
|
||||||
|
|
@ -207,8 +207,8 @@ public class McpSchemaTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testResourceLink() throws Exception {
|
void testResourceLink() throws Exception {
|
||||||
McpSchema.ResourceLink resourceLink = new McpSchema.ResourceLink("main.rs", "file:///project/src/main.rs",
|
McpSchema.ResourceLink resourceLink = new McpSchema.ResourceLink("main.rs", "Main file",
|
||||||
"Primary application entry point", "text/x-rust", null, null);
|
"file:///project/src/main.rs", "Primary application entry point", "text/x-rust", null, null);
|
||||||
String value = mapper.writeValueAsString(resourceLink);
|
String value = mapper.writeValueAsString(resourceLink);
|
||||||
|
|
||||||
assertThatJson(value).when(Option.IGNORING_ARRAY_ORDER)
|
assertThatJson(value).when(Option.IGNORING_ARRAY_ORDER)
|
||||||
|
|
@ -216,7 +216,7 @@ public class McpSchemaTests {
|
||||||
.isObject()
|
.isObject()
|
||||||
.isEqualTo(
|
.isEqualTo(
|
||||||
json("""
|
json("""
|
||||||
{"type":"resource_link","name":"main.rs","uri":"file:///project/src/main.rs","description":"Primary application entry point","mimeType":"text/x-rust"}"""));
|
{"type":"resource_link","name":"main.rs","title":"Main file","uri":"file:///project/src/main.rs","description":"Primary application entry point","mimeType":"text/x-rust"}"""));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -419,7 +419,7 @@ public class McpSchemaTests {
|
||||||
McpSchema.Annotations annotations = new McpSchema.Annotations(Arrays.asList(McpSchema.Role.USER), 0.5);
|
McpSchema.Annotations annotations = new McpSchema.Annotations(Arrays.asList(McpSchema.Role.USER), 0.5);
|
||||||
|
|
||||||
McpSchema.ResourceTemplate template = new McpSchema.ResourceTemplate("resource://{param}/test", "Test Template",
|
McpSchema.ResourceTemplate template = new McpSchema.ResourceTemplate("resource://{param}/test", "Test Template",
|
||||||
"A test resource template", "text/plain", annotations);
|
"Test Template", "A test resource template", "text/plain", annotations);
|
||||||
|
|
||||||
String value = mapper.writeValueAsString(template);
|
String value = mapper.writeValueAsString(template);
|
||||||
assertThatJson(value).when(Option.IGNORING_ARRAY_ORDER)
|
assertThatJson(value).when(Option.IGNORING_ARRAY_ORDER)
|
||||||
|
|
@ -427,7 +427,7 @@ public class McpSchemaTests {
|
||||||
.isObject()
|
.isObject()
|
||||||
.isEqualTo(
|
.isEqualTo(
|
||||||
json("""
|
json("""
|
||||||
{"uriTemplate":"resource://{param}/test","name":"Test Template","description":"A test resource template","mimeType":"text/plain","annotations":{"audience":["user"],"priority":0.5}}"""));
|
{"uriTemplate":"resource://{param}/test","name":"Test Template","title":"Test Template","description":"A test resource template","mimeType":"text/plain","annotations":{"audience":["user"],"priority":0.5}}"""));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -453,10 +453,10 @@ public class McpSchemaTests {
|
||||||
@Test
|
@Test
|
||||||
void testListResourceTemplatesResult() throws Exception {
|
void testListResourceTemplatesResult() throws Exception {
|
||||||
McpSchema.ResourceTemplate template1 = new McpSchema.ResourceTemplate("resource://{param}/test1",
|
McpSchema.ResourceTemplate template1 = new McpSchema.ResourceTemplate("resource://{param}/test1",
|
||||||
"Test Template 1", "First test template", "text/plain", null);
|
"Test Template 1", "Test Template 1", "First test template", "text/plain", null);
|
||||||
|
|
||||||
McpSchema.ResourceTemplate template2 = new McpSchema.ResourceTemplate("resource://{param}/test2",
|
McpSchema.ResourceTemplate template2 = new McpSchema.ResourceTemplate("resource://{param}/test2",
|
||||||
"Test Template 2", "Second test template", "application/json", null);
|
"Test Template 2", "Test Template 2", "Second test template", "application/json", null);
|
||||||
|
|
||||||
McpSchema.ListResourceTemplatesResult result = new McpSchema.ListResourceTemplatesResult(
|
McpSchema.ListResourceTemplatesResult result = new McpSchema.ListResourceTemplatesResult(
|
||||||
Arrays.asList(template1, template2), "next-cursor");
|
Arrays.asList(template1, template2), "next-cursor");
|
||||||
|
|
@ -467,7 +467,7 @@ public class McpSchemaTests {
|
||||||
.isObject()
|
.isObject()
|
||||||
.isEqualTo(
|
.isEqualTo(
|
||||||
json("""
|
json("""
|
||||||
{"resourceTemplates":[{"uriTemplate":"resource://{param}/test1","name":"Test Template 1","description":"First test template","mimeType":"text/plain"},{"uriTemplate":"resource://{param}/test2","name":"Test Template 2","description":"Second test template","mimeType":"application/json"}],"nextCursor":"next-cursor"}"""));
|
{"resourceTemplates":[{"uriTemplate":"resource://{param}/test1","name":"Test Template 1","title":"Test Template 1","description":"First test template","mimeType":"text/plain"},{"uriTemplate":"resource://{param}/test2","name":"Test Template 2","title":"Test Template 2","description":"Second test template","mimeType":"application/json"}],"nextCursor":"next-cursor"}"""));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -535,11 +535,13 @@ public class McpSchemaTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testPrompt() throws Exception {
|
void testPrompt() throws Exception {
|
||||||
McpSchema.PromptArgument arg1 = new McpSchema.PromptArgument("arg1", "First argument", true);
|
McpSchema.PromptArgument arg1 = new McpSchema.PromptArgument("arg1", "First argument", "First argument", true);
|
||||||
|
|
||||||
McpSchema.PromptArgument arg2 = new McpSchema.PromptArgument("arg2", "Second argument", false);
|
McpSchema.PromptArgument arg2 = new McpSchema.PromptArgument("arg2", "Second argument", "Second argument",
|
||||||
|
false);
|
||||||
|
|
||||||
McpSchema.Prompt prompt = new McpSchema.Prompt("test-prompt", "A test prompt", Arrays.asList(arg1, arg2));
|
McpSchema.Prompt prompt = new McpSchema.Prompt("test-prompt", "Test Prompt", "A test prompt",
|
||||||
|
Arrays.asList(arg1, arg2));
|
||||||
|
|
||||||
String value = mapper.writeValueAsString(prompt);
|
String value = mapper.writeValueAsString(prompt);
|
||||||
assertThatJson(value).when(Option.IGNORING_ARRAY_ORDER)
|
assertThatJson(value).when(Option.IGNORING_ARRAY_ORDER)
|
||||||
|
|
@ -547,7 +549,7 @@ public class McpSchemaTests {
|
||||||
.isObject()
|
.isObject()
|
||||||
.isEqualTo(
|
.isEqualTo(
|
||||||
json("""
|
json("""
|
||||||
{"name":"test-prompt","description":"A test prompt","arguments":[{"name":"arg1","description":"First argument","required":true},{"name":"arg2","description":"Second argument","required":false}]}"""));
|
{"name":"test-prompt","title":"Test Prompt","description":"A test prompt","arguments":[{"name":"arg1","title":"First argument","description":"First argument","required":true},{"name":"arg2","title":"Second argument","description":"Second argument","required":false}]}"""));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -566,11 +568,13 @@ public class McpSchemaTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testListPromptsResult() throws Exception {
|
void testListPromptsResult() throws Exception {
|
||||||
McpSchema.PromptArgument arg = new McpSchema.PromptArgument("arg", "An argument", true);
|
McpSchema.PromptArgument arg = new McpSchema.PromptArgument("arg", "Argument", "An argument", true);
|
||||||
|
|
||||||
McpSchema.Prompt prompt1 = new McpSchema.Prompt("prompt1", "First prompt", Collections.singletonList(arg));
|
McpSchema.Prompt prompt1 = new McpSchema.Prompt("prompt1", "First prompt", "First prompt",
|
||||||
|
Collections.singletonList(arg));
|
||||||
|
|
||||||
McpSchema.Prompt prompt2 = new McpSchema.Prompt("prompt2", "Second prompt", Collections.emptyList());
|
McpSchema.Prompt prompt2 = new McpSchema.Prompt("prompt2", "Second prompt", "Second prompt",
|
||||||
|
Collections.emptyList());
|
||||||
|
|
||||||
McpSchema.ListPromptsResult result = new McpSchema.ListPromptsResult(Arrays.asList(prompt1, prompt2),
|
McpSchema.ListPromptsResult result = new McpSchema.ListPromptsResult(Arrays.asList(prompt1, prompt2),
|
||||||
"next-cursor");
|
"next-cursor");
|
||||||
|
|
@ -581,7 +585,7 @@ public class McpSchemaTests {
|
||||||
.isObject()
|
.isObject()
|
||||||
.isEqualTo(
|
.isEqualTo(
|
||||||
json("""
|
json("""
|
||||||
{"prompts":[{"name":"prompt1","description":"First prompt","arguments":[{"name":"arg","description":"An argument","required":true}]},{"name":"prompt2","description":"Second prompt","arguments":[]}],"nextCursor":"next-cursor"}"""));
|
{"prompts":[{"name":"prompt1","title":"First prompt","description":"First prompt","arguments":[{"name":"arg","title":"Argument","description":"An argument","required":true}]},{"name":"prompt2","title":"Second prompt","description":"Second prompt","arguments":[]}],"nextCursor":"next-cursor"}"""));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue