|
28 | 28 | import io.modelcontextprotocol.spec.McpSchema.Prompt; |
29 | 29 | import io.modelcontextprotocol.spec.McpSchema.PromptArgument; |
30 | 30 | import io.modelcontextprotocol.spec.McpSchema.PromptReference; |
| 31 | +import io.modelcontextprotocol.spec.McpSchema.ReadResourceResult; |
| 32 | +import io.modelcontextprotocol.spec.McpSchema.ResourceReference; |
| 33 | +import io.modelcontextprotocol.spec.McpSchema.ResourceTemplate; |
31 | 34 | import io.modelcontextprotocol.spec.McpSchema.ServerCapabilities; |
32 | 35 | import io.modelcontextprotocol.spec.McpSchema.TextContent; |
33 | 36 | import io.modelcontextprotocol.spec.McpSchema.Tool; |
@@ -230,6 +233,110 @@ void testCompletionShouldReturnExpectedSuggestions(String clientType) { |
230 | 233 | } |
231 | 234 | } |
232 | 235 |
|
| 236 | + @ParameterizedTest(name = "{0} : Completion call without matching handler") |
| 237 | + @ValueSource(strings = { "httpclient" }) |
| 238 | + void testCompletionWithoutMatchingHandlerReturnsEmptyResult(String clientType) { |
| 239 | + var clientBuilder = clientBuilders.get(clientType); |
| 240 | + |
| 241 | + BiFunction<McpTransportContext, CompleteRequest, CompleteResult> completionHandler = (transportContext, |
| 242 | + request) -> new CompleteResult(new CompleteResult.CompleteCompletion(List.of("java"), 1, false)); |
| 243 | + |
| 244 | + var prompt = Prompt.builder("code_review") |
| 245 | + .title("Code review") |
| 246 | + .description("this is code review prompt") |
| 247 | + .arguments(List |
| 248 | + .of(PromptArgument.builder("language").title("Language").description("string").required(false).build())) |
| 249 | + .build(); |
| 250 | + |
| 251 | + var otherPrompt = Prompt.builder("other_prompt") |
| 252 | + .title("Other prompt") |
| 253 | + .description("this prompt has completions") |
| 254 | + .arguments(List |
| 255 | + .of(PromptArgument.builder("topic").title("Topic").description("string").required(false).build())) |
| 256 | + .build(); |
| 257 | + |
| 258 | + var mcpServer = McpServer.sync(mcpStatelessServerTransport) |
| 259 | + .capabilities(ServerCapabilities.builder().completions().build()) |
| 260 | + .prompts( |
| 261 | + new McpStatelessServerFeatures.SyncPromptSpecification(prompt, |
| 262 | + (transportContext, getPromptRequest) -> null), |
| 263 | + new McpStatelessServerFeatures.SyncPromptSpecification(otherPrompt, |
| 264 | + (transportContext, getPromptRequest) -> null)) |
| 265 | + .completions(new McpStatelessServerFeatures.SyncCompletionSpecification( |
| 266 | + PromptReference.builder("other_prompt").title("Other prompt").build(), completionHandler)) |
| 267 | + .build(); |
| 268 | + |
| 269 | + try (var mcpClient = clientBuilder.build()) { |
| 270 | + InitializeResult initResult = mcpClient.initialize(); |
| 271 | + assertThat(initResult).isNotNull(); |
| 272 | + |
| 273 | + CompleteRequest request = CompleteRequest |
| 274 | + .builder(PromptReference.builder("code_review").title("Code review").build(), |
| 275 | + new CompleteRequest.CompleteArgument("language", "ja")) |
| 276 | + .build(); |
| 277 | + |
| 278 | + CompleteResult result = mcpClient.completeCompletion(request); |
| 279 | + |
| 280 | + assertThat(result.completion().values()).isEmpty(); |
| 281 | + assertThat(result.completion().total()).isZero(); |
| 282 | + assertThat(result.completion().hasMore()).isFalse(); |
| 283 | + } |
| 284 | + finally { |
| 285 | + mcpServer.close(); |
| 286 | + } |
| 287 | + } |
| 288 | + |
| 289 | + @ParameterizedTest(name = "{0} : Resource template completion call without matching handler") |
| 290 | + @ValueSource(strings = { "httpclient" }) |
| 291 | + void testResourceTemplateCompletionWithoutMatchingHandlerReturnsEmptyResult(String clientType) { |
| 292 | + var clientBuilder = clientBuilders.get(clientType); |
| 293 | + |
| 294 | + BiFunction<McpTransportContext, CompleteRequest, CompleteResult> completionHandler = (transportContext, |
| 295 | + request) -> new CompleteResult(new CompleteResult.CompleteCompletion(List.of("java"), 1, false)); |
| 296 | + |
| 297 | + var template = ResourceTemplate.builder("test://resource/{param}", "Test Resource") |
| 298 | + .title("Test resource") |
| 299 | + .description("A resource template for testing") |
| 300 | + .mimeType("text/plain") |
| 301 | + .build(); |
| 302 | + |
| 303 | + var otherTemplate = ResourceTemplate.builder("test://other/{param}", "Other Resource") |
| 304 | + .title("Other resource") |
| 305 | + .description("A resource template with completions") |
| 306 | + .mimeType("text/plain") |
| 307 | + .build(); |
| 308 | + |
| 309 | + var mcpServer = McpServer.sync(mcpStatelessServerTransport) |
| 310 | + .capabilities(ServerCapabilities.builder().completions().build()) |
| 311 | + .resourceTemplates( |
| 312 | + new McpStatelessServerFeatures.SyncResourceTemplateSpecification(template, |
| 313 | + (transportContext, req) -> ReadResourceResult.builder(List.of()).build()), |
| 314 | + new McpStatelessServerFeatures.SyncResourceTemplateSpecification(otherTemplate, |
| 315 | + (transportContext, req) -> ReadResourceResult.builder(List.of()).build())) |
| 316 | + .completions(new McpStatelessServerFeatures.SyncCompletionSpecification( |
| 317 | + new ResourceReference("test://other/{param}"), completionHandler)) |
| 318 | + .build(); |
| 319 | + |
| 320 | + try (var mcpClient = clientBuilder.build()) { |
| 321 | + InitializeResult initResult = mcpClient.initialize(); |
| 322 | + assertThat(initResult).isNotNull(); |
| 323 | + |
| 324 | + CompleteRequest request = CompleteRequest |
| 325 | + .builder(new ResourceReference("test://resource/{param}"), |
| 326 | + new CompleteRequest.CompleteArgument("param", "ja")) |
| 327 | + .build(); |
| 328 | + |
| 329 | + CompleteResult result = mcpClient.completeCompletion(request); |
| 330 | + |
| 331 | + assertThat(result.completion().values()).isEmpty(); |
| 332 | + assertThat(result.completion().total()).isZero(); |
| 333 | + assertThat(result.completion().hasMore()).isFalse(); |
| 334 | + } |
| 335 | + finally { |
| 336 | + mcpServer.close(); |
| 337 | + } |
| 338 | + } |
| 339 | + |
233 | 340 | // --------------------------------------- |
234 | 341 | // Tool Structured Output Schema Tests |
235 | 342 | // --------------------------------------- |
|
0 commit comments