Skip to content

Commit 7d46851

Browse files
committed
fix: Return empty prompt completion result when prompt has no arguments
Recent changes don't coerce null completion arguments to empty lists so we have to check for null when handling prompt completions. Resolves #932 Signed-off-by: Dariusz Jędrzejczyk <2554306+chemicL@users.noreply.github.com>
1 parent 4c85963 commit 7d46851

3 files changed

Lines changed: 40 additions & 14 deletions

File tree

mcp-core/src/main/java/io/modelcontextprotocol/server/McpAsyncServer.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -999,12 +999,9 @@ private McpRequestHandler<McpSchema.CompleteResult> completionCompleteRequestHan
999999
.message("Prompt not found: " + promptReference.name())
10001000
.build());
10011001
}
1002-
if (!promptSpec.prompt()
1003-
.arguments()
1004-
.stream()
1005-
.filter(arg -> arg.name().equals(argumentName))
1006-
.findFirst()
1007-
.isPresent()) {
1002+
List<McpSchema.PromptArgument> arguments = promptSpec.prompt().arguments();
1003+
if (arguments == null
1004+
|| !arguments.stream().filter(arg -> arg.name().equals(argumentName)).findFirst().isPresent()) {
10081005

10091006
logger.warn("Argument not found: {} in prompt: {}", argumentName, promptReference.name());
10101007

mcp-core/src/main/java/io/modelcontextprotocol/server/McpStatelessAsyncServer.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -744,12 +744,9 @@ private McpStatelessRequestHandler<McpSchema.CompleteResult> completionCompleteR
744744
.message("Prompt not found: " + promptReference.name())
745745
.build());
746746
}
747-
if (!promptSpec.prompt()
748-
.arguments()
749-
.stream()
750-
.filter(arg -> arg.name().equals(argumentName))
751-
.findFirst()
752-
.isPresent()) {
747+
List<McpSchema.PromptArgument> arguments = promptSpec.prompt().arguments();
748+
if (arguments == null
749+
|| arguments.stream().filter(arg -> arg.name().equals(argumentName)).findFirst().isPresent()) {
753750

754751
logger.warn("Argument not found: {} in prompt: {}", argumentName, promptReference.name());
755752

mcp-test/src/test/java/io/modelcontextprotocol/server/McpCompletionTests.java

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,9 @@
1313
import org.apache.catalina.LifecycleState;
1414
import org.apache.catalina.startup.Tomcat;
1515

16-
import static org.assertj.core.api.Assertions.assertThat;
1716
import org.junit.jupiter.api.AfterEach;
1817
import org.junit.jupiter.api.BeforeEach;
1918
import org.junit.jupiter.api.Test;
20-
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
2119

2220
import io.modelcontextprotocol.client.McpClient;
2321
import io.modelcontextprotocol.client.transport.HttpClientSseClientTransport;
@@ -37,6 +35,9 @@
3735
import io.modelcontextprotocol.spec.McpSchema.ServerCapabilities;
3836
import io.modelcontextprotocol.spec.McpError;
3937

38+
import static org.assertj.core.api.Assertions.assertThat;
39+
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
40+
4041
/**
4142
* Tests for completion functionality with context support.
4243
*
@@ -324,4 +325,35 @@ void testCompletionErrorOnMissingContext() {
324325
mcpServer.close();
325326
}
326327

328+
@Test
329+
void testPromptWithoutArgumentsCompletionForArgument() {
330+
BiFunction<McpSyncServerExchange, CompleteRequest, CompleteResult> completionHandler = (exchange,
331+
request) -> new CompleteResult(new CompleteResult.CompleteCompletion(List.of("test"), 1, false));
332+
333+
McpSchema.Prompt prompt = new Prompt("test-prompt", "this is a test prompt", null);
334+
335+
var mcpServer = McpServer.sync(mcpServerTransportProvider)
336+
.capabilities(ServerCapabilities.builder().completions().build())
337+
.prompts(new McpServerFeatures.SyncPromptSpecification(prompt,
338+
(mcpSyncServerExchange, getPromptRequest) -> null))
339+
.completions(new McpServerFeatures.SyncCompletionSpecification(
340+
new PromptReference(PromptReference.TYPE, "test-prompt"), completionHandler))
341+
.build();
342+
343+
try (var mcpClient = clientBuilder.clientInfo(new McpSchema.Implementation("Sample " + "client", "0.0.0"))
344+
.build()) {
345+
InitializeResult initResult = mcpClient.initialize();
346+
assertThat(initResult).isNotNull();
347+
348+
// try completing an argument knowing that the prompt is not parameterized
349+
CompleteRequest request = new CompleteRequest(new PromptReference(PromptReference.TYPE, "test-prompt"),
350+
new CompleteRequest.CompleteArgument("arg", "val"));
351+
352+
CompleteResult completeResult = mcpClient.completeCompletion(request);
353+
assertThat(completeResult.completion().values()).isEmpty();
354+
}
355+
356+
mcpServer.close();
357+
}
358+
327359
}

0 commit comments

Comments
 (0)