Add URL elicitation support (SEP-1036) (#993)
Add URL-type elicitation schema support allowing servers to request URL input from users during tool execution. This enables out-of-band interactions like payment processing or API key entry. Breaking changes: - `ElicitRequest` changed from a `record` to an `interface`. - The original `ElicitRequest` record was renamed to `ElicitFormRequest`. - `McpClient` builder `elicitation()` methods now accept `ElicitFormRequest` instead of `ElicitRequest`. New APIs: - `ElicitUrlRequest` record for URL-mode elicitation. - `urlElicitation()` builder methods in `McpClient`. - `elicitationCompleteConsumer()` and `elicitationCompleteConsumers()` builder methods in `McpClient`. - `sendElicitationComplete()` methods in `McpAsyncServer` and `McpSyncServer`. - `McpError.URL_ELICITATION_REQUIRED` and `McpSchema.ErrorCodes.URL_ELICITATION_REQUIRED`. - `ElicitationCompleteNotification` record and `METHOD_NOTIFICATION_ELICITATION_COMPLETE` constant. Co-authored-by: Daniel Garnier-Moiroux <git@garnier.wf> Co-authored-by: Sainath Reddy Bobbala <bsnr@amazon.com>
This commit is contained in:
parent
c49a994463
commit
dbb9bdad51
3 changed files with 1413 additions and 196 deletions
|
|
@ -0,0 +1,182 @@
|
|||
/*
|
||||
* Copyright 2026-2026 the original author or authors.
|
||||
*/
|
||||
|
||||
package io.modelcontextprotocol.client;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import io.modelcontextprotocol.json.schema.JsonSchemaValidator;
|
||||
import io.modelcontextprotocol.spec.McpClientTransport;
|
||||
import io.modelcontextprotocol.spec.McpSchema;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatCode;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* @author Daniel Garnier-Moiroux
|
||||
*/
|
||||
class McpAsyncClientTest {
|
||||
|
||||
@Nested
|
||||
class ClientBuilder {
|
||||
|
||||
@Nested
|
||||
class ElicitationHandlers {
|
||||
|
||||
@Test
|
||||
void formElicitationMissingHandler() {
|
||||
McpClientTransport transport = mock(McpClientTransport.class);
|
||||
var clientBuilder = McpClient.async(transport)
|
||||
.capabilities(McpSchema.ClientCapabilities.builder().elicitation().build())
|
||||
.jsonSchemaValidator(mock(JsonSchemaValidator.class));
|
||||
var clientBuilderExplicitFormElicitation = McpClient.async(transport)
|
||||
.capabilities(McpSchema.ClientCapabilities.builder().elicitation(true, false).build())
|
||||
.jsonSchemaValidator(mock(JsonSchemaValidator.class));
|
||||
var clientBuilderUrlElicitation = McpClient.async(transport)
|
||||
.capabilities(McpSchema.ClientCapabilities.builder().elicitation(true, true).build())
|
||||
.urlElicitation(req -> Mono.empty())
|
||||
.jsonSchemaValidator(mock(JsonSchemaValidator.class));
|
||||
|
||||
assertThatThrownBy(clientBuilder::build).isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage(
|
||||
"Form elicitation handler must not be null when client capabilities include form elicitation");
|
||||
assertThatThrownBy(clientBuilderExplicitFormElicitation::build)
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage(
|
||||
"Form elicitation handler must not be null when client capabilities include form elicitation");
|
||||
assertThatThrownBy(clientBuilderUrlElicitation::build).isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage(
|
||||
"Form elicitation handler must not be null when client capabilities include form elicitation");
|
||||
}
|
||||
|
||||
@Test
|
||||
void formElicitationHandlerPresent() {
|
||||
McpClientTransport transport = mock(McpClientTransport.class);
|
||||
when(transport.protocolVersions()).thenReturn(List.of("2024-11-05"));
|
||||
McpClient.AsyncSpec asyncSpec = McpClient.async(transport)
|
||||
.capabilities(McpSchema.ClientCapabilities.builder().elicitation(true, false).build());
|
||||
var clientBuilder = asyncSpec.elicitation(request -> Mono.empty())
|
||||
.jsonSchemaValidator(mock(JsonSchemaValidator.class));
|
||||
|
||||
assertThatCode(clientBuilder::build).doesNotThrowAnyException();
|
||||
}
|
||||
|
||||
@Test
|
||||
void urlElicitationMissingHandler() {
|
||||
var clientBuilder = McpClient.async(mock(McpClientTransport.class))
|
||||
.capabilities(McpSchema.ClientCapabilities.builder().elicitation(false, true).build())
|
||||
.jsonSchemaValidator(mock(JsonSchemaValidator.class));
|
||||
|
||||
assertThatThrownBy(clientBuilder::build).isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessage(
|
||||
"URL elicitation handler must not be null when client capabilities include URL elicitation");
|
||||
}
|
||||
|
||||
@Test
|
||||
void urlElicitationHandlerPresent() {
|
||||
McpClientTransport transport = mock(McpClientTransport.class);
|
||||
when(transport.protocolVersions()).thenReturn(List.of("2024-11-05"));
|
||||
var clientBuilder = McpClient.async(transport)
|
||||
.capabilities(McpSchema.ClientCapabilities.builder().elicitation(false, true).build())
|
||||
.urlElicitation(request -> Mono.empty())
|
||||
.jsonSchemaValidator(mock(JsonSchemaValidator.class));
|
||||
|
||||
assertThatCode(clientBuilder::build).doesNotThrowAnyException();
|
||||
}
|
||||
|
||||
@Test
|
||||
void bothHandlersPresent() {
|
||||
McpClientTransport transport = mock(McpClientTransport.class);
|
||||
when(transport.protocolVersions()).thenReturn(List.of("2024-11-05"));
|
||||
McpClient.AsyncSpec asyncSpec = McpClient.async(transport)
|
||||
.capabilities(McpSchema.ClientCapabilities.builder().elicitation().build());
|
||||
var clientBuilder = asyncSpec.elicitation(request1 -> Mono.empty())
|
||||
.urlElicitation(request -> Mono.empty())
|
||||
.jsonSchemaValidator(mock(JsonSchemaValidator.class));
|
||||
|
||||
assertThatCode(clientBuilder::build).doesNotThrowAnyException();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Nested
|
||||
class ClientCapabilities {
|
||||
|
||||
@Test
|
||||
void noElicitation() {
|
||||
McpClientTransport transport = mock(McpClientTransport.class);
|
||||
when(transport.protocolVersions()).thenReturn(List.of("2024-11-05"));
|
||||
var client = McpClient.async(transport).jsonSchemaValidator(mock(JsonSchemaValidator.class)).build();
|
||||
|
||||
assertThat(client.getClientCapabilities().elicitation()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void formElicitationFromHandler() {
|
||||
McpClientTransport transport = mock(McpClientTransport.class);
|
||||
when(transport.protocolVersions()).thenReturn(List.of("2024-11-05"));
|
||||
McpClient.AsyncSpec asyncSpec = McpClient.async(transport);
|
||||
var client = asyncSpec.elicitation(req -> Mono.empty())
|
||||
.jsonSchemaValidator(mock(JsonSchemaValidator.class))
|
||||
.build();
|
||||
|
||||
assertThat(client.getClientCapabilities().elicitation()).isNotNull();
|
||||
assertThat(client.getClientCapabilities().elicitation().form()).isNotNull();
|
||||
assertThat(client.getClientCapabilities().elicitation().url()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void urlElicitationFromHandler() {
|
||||
McpClientTransport transport = mock(McpClientTransport.class);
|
||||
when(transport.protocolVersions()).thenReturn(List.of("2024-11-05"));
|
||||
var client = McpClient.async(transport)
|
||||
.urlElicitation(req -> Mono.empty())
|
||||
.jsonSchemaValidator(mock(JsonSchemaValidator.class))
|
||||
.build();
|
||||
|
||||
assertThat(client.getClientCapabilities().elicitation()).isNotNull();
|
||||
assertThat(client.getClientCapabilities().elicitation().form()).isNull();
|
||||
assertThat(client.getClientCapabilities().elicitation().url()).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void elicitationFromHandlers() {
|
||||
McpClientTransport transport = mock(McpClientTransport.class);
|
||||
when(transport.protocolVersions()).thenReturn(List.of("2024-11-05"));
|
||||
McpClient.AsyncSpec asyncSpec = McpClient.async(transport);
|
||||
var client = asyncSpec.elicitation(req -> Mono.empty())
|
||||
.urlElicitation(req -> Mono.empty())
|
||||
.jsonSchemaValidator(mock(JsonSchemaValidator.class))
|
||||
.build();
|
||||
|
||||
assertThat(client.getClientCapabilities().elicitation()).isNotNull();
|
||||
assertThat(client.getClientCapabilities().elicitation().form()).isNotNull();
|
||||
assertThat(client.getClientCapabilities().elicitation().url()).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void noElicitationFromCapabilities() {
|
||||
McpClientTransport transport = mock(McpClientTransport.class);
|
||||
when(transport.protocolVersions()).thenReturn(List.of("2024-11-05"));
|
||||
McpClient.AsyncSpec asyncSpec = McpClient.async(transport)
|
||||
.capabilities(McpSchema.ClientCapabilities.builder().build());
|
||||
var client = asyncSpec.elicitation(req -> Mono.empty())
|
||||
.urlElicitation(req -> Mono.empty())
|
||||
.jsonSchemaValidator(mock(JsonSchemaValidator.class))
|
||||
.build();
|
||||
|
||||
assertThat(client.getClientCapabilities().elicitation()).isNull();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Copyright 2026-2026 the original author or authors.
|
||||
*/
|
||||
|
||||
package io.modelcontextprotocol.client;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import io.modelcontextprotocol.json.schema.JsonSchemaValidator;
|
||||
import io.modelcontextprotocol.spec.McpClientTransport;
|
||||
import io.modelcontextprotocol.spec.McpSchema;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* @author Daniel Garnier-Moiroux
|
||||
*/
|
||||
class McpSyncClientTest {
|
||||
|
||||
@Nested
|
||||
class ClientCapabilities {
|
||||
|
||||
@Test
|
||||
void noElicitation() {
|
||||
McpClientTransport transport = mock(McpClientTransport.class);
|
||||
when(transport.protocolVersions()).thenReturn(List.of("2024-11-05"));
|
||||
var client = McpClient.sync(transport).jsonSchemaValidator(mock(JsonSchemaValidator.class)).build();
|
||||
|
||||
assertThat(client.getClientCapabilities().elicitation()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void formElicitationFromHandler() {
|
||||
McpClientTransport transport = mock(McpClientTransport.class);
|
||||
when(transport.protocolVersions()).thenReturn(List.of("2024-11-05"));
|
||||
var asyncSpec = McpClient.sync(transport);
|
||||
var client = asyncSpec.elicitation(req -> null)
|
||||
.jsonSchemaValidator(mock(JsonSchemaValidator.class))
|
||||
.build();
|
||||
|
||||
assertThat(client.getClientCapabilities().elicitation()).isNotNull();
|
||||
assertThat(client.getClientCapabilities().elicitation().form()).isNotNull();
|
||||
assertThat(client.getClientCapabilities().elicitation().url()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void urlElicitationFromHandler() {
|
||||
McpClientTransport transport = mock(McpClientTransport.class);
|
||||
when(transport.protocolVersions()).thenReturn(List.of("2024-11-05"));
|
||||
var client = McpClient.sync(transport)
|
||||
.urlElicitation(req -> null)
|
||||
.jsonSchemaValidator(mock(JsonSchemaValidator.class))
|
||||
.build();
|
||||
|
||||
assertThat(client.getClientCapabilities().elicitation()).isNotNull();
|
||||
assertThat(client.getClientCapabilities().elicitation().form()).isNull();
|
||||
assertThat(client.getClientCapabilities().elicitation().url()).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void elicitationFromHandlers() {
|
||||
McpClientTransport transport = mock(McpClientTransport.class);
|
||||
when(transport.protocolVersions()).thenReturn(List.of("2024-11-05"));
|
||||
var asyncSpec = McpClient.sync(transport);
|
||||
var client = asyncSpec.elicitation(req -> null)
|
||||
.urlElicitation(req -> null)
|
||||
.jsonSchemaValidator(mock(JsonSchemaValidator.class))
|
||||
.build();
|
||||
|
||||
assertThat(client.getClientCapabilities().elicitation()).isNotNull();
|
||||
assertThat(client.getClientCapabilities().elicitation().form()).isNotNull();
|
||||
assertThat(client.getClientCapabilities().elicitation().url()).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void noElicitationFromCapabilities() {
|
||||
McpClientTransport transport = mock(McpClientTransport.class);
|
||||
when(transport.protocolVersions()).thenReturn(List.of("2024-11-05"));
|
||||
var asyncSpec = McpClient.sync(transport).capabilities(McpSchema.ClientCapabilities.builder().build());
|
||||
var client = asyncSpec.elicitation(req -> null)
|
||||
.urlElicitation(req -> null)
|
||||
.jsonSchemaValidator(mock(JsonSchemaValidator.class))
|
||||
.build();
|
||||
|
||||
assertThat(client.getClientCapabilities().elicitation()).isNull();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -4,17 +4,17 @@
|
|||
|
||||
package io.modelcontextprotocol.server;
|
||||
|
||||
import io.modelcontextprotocol.common.McpTransportContext;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import io.modelcontextprotocol.common.McpTransportContext;
|
||||
import io.modelcontextprotocol.json.TypeRef;
|
||||
import io.modelcontextprotocol.json.schema.JsonSchemaValidator;
|
||||
import io.modelcontextprotocol.spec.McpError;
|
||||
import io.modelcontextprotocol.spec.McpSchema;
|
||||
import io.modelcontextprotocol.spec.McpServerSession;
|
||||
import io.modelcontextprotocol.json.TypeRef;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mock;
|
||||
|
|
@ -531,6 +531,149 @@ class McpAsyncServerExchangeTests {
|
|||
any(TypeRef.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCreateElicitationWithUrlRequest() {
|
||||
McpSchema.ClientCapabilities capabilitiesWithUrlElicitation = McpSchema.ClientCapabilities.builder()
|
||||
.elicitation(false, true)
|
||||
.build();
|
||||
|
||||
McpAsyncServerExchange exchangeWithElicitation = new McpAsyncServerExchange("testSessionId", mockSession,
|
||||
capabilitiesWithUrlElicitation, clientInfo, McpTransportContext.EMPTY);
|
||||
|
||||
McpSchema.ElicitUrlRequest elicitUrlRequest = McpSchema.ElicitUrlRequest
|
||||
.builder("Please authenticate via URL", "https://example.com/auth", "elicit-url-123")
|
||||
.build();
|
||||
|
||||
McpSchema.ElicitResult expectedResult = McpSchema.ElicitResult.builder(McpSchema.ElicitResult.Action.ACCEPT)
|
||||
.build();
|
||||
|
||||
when(mockSession.sendRequest(eq(McpSchema.METHOD_ELICITATION_CREATE), eq(elicitUrlRequest), any(TypeRef.class)))
|
||||
.thenReturn(Mono.just(expectedResult));
|
||||
|
||||
StepVerifier.create(exchangeWithElicitation.createElicitation(elicitUrlRequest)).assertNext(result -> {
|
||||
assertThat(result).isEqualTo(expectedResult);
|
||||
assertThat(result.action()).isEqualTo(McpSchema.ElicitResult.Action.ACCEPT);
|
||||
}).verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCreateElicitationWithUrlRequestBypassesValidator() {
|
||||
McpSchema.ClientCapabilities capabilitiesWithElicitation = McpSchema.ClientCapabilities.builder()
|
||||
.elicitation(false, true)
|
||||
.build();
|
||||
|
||||
JsonSchemaValidator rejectingValidator = new JsonSchemaValidator() {
|
||||
@Override
|
||||
public ValidationResponse validate(Map<String, Object> schema, Object content) {
|
||||
return ValidationResponse.asInvalid("should not be called");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValidationResponse validateSchema(Map<String, Object> schema) {
|
||||
return ValidationResponse.asInvalid("should not be called");
|
||||
}
|
||||
};
|
||||
|
||||
McpAsyncServerExchange exchangeWithValidator = new McpAsyncServerExchange("testSessionId", mockSession,
|
||||
capabilitiesWithElicitation, clientInfo, McpTransportContext.EMPTY, rejectingValidator);
|
||||
|
||||
McpSchema.ElicitUrlRequest elicitUrlRequest = McpSchema.ElicitUrlRequest
|
||||
.builder("Please visit the URL", "https://example.com/oauth", "elicit-oauth-123")
|
||||
.build();
|
||||
|
||||
when(mockSession.sendRequest(eq(McpSchema.METHOD_ELICITATION_CREATE), eq(elicitUrlRequest), any(TypeRef.class)))
|
||||
.thenReturn(Mono.just(McpSchema.ElicitResult.builder(McpSchema.ElicitResult.Action.ACCEPT).build()));
|
||||
|
||||
StepVerifier.create(exchangeWithValidator.createElicitation(elicitUrlRequest)).assertNext(result -> {
|
||||
assertThat(result.action()).isEqualTo(McpSchema.ElicitResult.Action.ACCEPT);
|
||||
}).verifyComplete();
|
||||
|
||||
verify(mockSession, times(1)).sendRequest(eq(McpSchema.METHOD_ELICITATION_CREATE), eq(elicitUrlRequest),
|
||||
any(TypeRef.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testElicitationCapabilitiesEmptyObject() {
|
||||
McpSchema.ClientCapabilities capabilities = McpSchema.ClientCapabilities.builder().elicitation().build();
|
||||
McpAsyncServerExchange exchangeEmpty = new McpAsyncServerExchange("testSessionId", mockSession, capabilities,
|
||||
clientInfo, McpTransportContext.EMPTY);
|
||||
|
||||
McpSchema.ElicitFormRequest formRequest = McpSchema.ElicitRequest.builder("form", Map.of("type", "object"))
|
||||
.build();
|
||||
McpSchema.ElicitUrlRequest urlRequest = McpSchema.ElicitUrlRequest.builder("url", "http", "123").build();
|
||||
|
||||
when(mockSession.sendRequest(eq(McpSchema.METHOD_ELICITATION_CREATE), eq(formRequest), any(TypeRef.class)))
|
||||
.thenReturn(Mono.just(McpSchema.ElicitResult.builder(McpSchema.ElicitResult.Action.ACCEPT).build()));
|
||||
|
||||
StepVerifier.create(exchangeEmpty.createElicitation(formRequest)).expectNextCount(1).verifyComplete();
|
||||
StepVerifier.create(exchangeEmpty.createElicitation(urlRequest))
|
||||
.verifyErrorSatisfies(e -> assertThat(e).isInstanceOf(IllegalStateException.class)
|
||||
.hasMessage("Client must be configured with URL elicitation capabilities"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testElicitationCapabilitiesFormOnly() {
|
||||
McpSchema.ClientCapabilities capabilities = McpSchema.ClientCapabilities.builder()
|
||||
.elicitation(true, false)
|
||||
.build();
|
||||
McpAsyncServerExchange exchangeForm = new McpAsyncServerExchange("testSessionId", mockSession, capabilities,
|
||||
clientInfo, McpTransportContext.EMPTY);
|
||||
|
||||
McpSchema.ElicitFormRequest formRequest = McpSchema.ElicitRequest.builder("form", Map.of("type", "object"))
|
||||
.build();
|
||||
McpSchema.ElicitUrlRequest urlRequest = McpSchema.ElicitUrlRequest.builder("url", "http", "123").build();
|
||||
|
||||
when(mockSession.sendRequest(eq(McpSchema.METHOD_ELICITATION_CREATE), eq(formRequest), any(TypeRef.class)))
|
||||
.thenReturn(Mono.just(McpSchema.ElicitResult.builder(McpSchema.ElicitResult.Action.ACCEPT).build()));
|
||||
|
||||
StepVerifier.create(exchangeForm.createElicitation(formRequest)).expectNextCount(1).verifyComplete();
|
||||
StepVerifier.create(exchangeForm.createElicitation(urlRequest))
|
||||
.verifyErrorSatisfies(e -> assertThat(e).isInstanceOf(IllegalStateException.class)
|
||||
.hasMessage("Client must be configured with URL elicitation capabilities"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testElicitationCapabilitiesUrlOnly() {
|
||||
McpSchema.ClientCapabilities capabilities = McpSchema.ClientCapabilities.builder()
|
||||
.elicitation(false, true)
|
||||
.build();
|
||||
McpAsyncServerExchange exchangeUrl = new McpAsyncServerExchange("testSessionId", mockSession, capabilities,
|
||||
clientInfo, McpTransportContext.EMPTY);
|
||||
|
||||
McpSchema.ElicitFormRequest formRequest = McpSchema.ElicitRequest.builder("form", Map.of("type", "object"))
|
||||
.build();
|
||||
McpSchema.ElicitUrlRequest urlRequest = McpSchema.ElicitUrlRequest.builder("url", "http", "123").build();
|
||||
|
||||
when(mockSession.sendRequest(eq(McpSchema.METHOD_ELICITATION_CREATE), eq(urlRequest), any(TypeRef.class)))
|
||||
.thenReturn(Mono.just(McpSchema.ElicitResult.builder(McpSchema.ElicitResult.Action.ACCEPT).build()));
|
||||
|
||||
StepVerifier.create(exchangeUrl.createElicitation(urlRequest)).expectNextCount(1).verifyComplete();
|
||||
StepVerifier.create(exchangeUrl.createElicitation(formRequest))
|
||||
.verifyErrorSatisfies(e -> assertThat(e).isInstanceOf(IllegalStateException.class)
|
||||
.hasMessage("Client must be configured with form elicitation capabilities"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testElicitationCapabilitiesBoth() {
|
||||
McpSchema.ClientCapabilities capabilities = McpSchema.ClientCapabilities.builder()
|
||||
.elicitation(true, true)
|
||||
.build();
|
||||
McpAsyncServerExchange exchangeBoth = new McpAsyncServerExchange("testSessionId", mockSession, capabilities,
|
||||
clientInfo, McpTransportContext.EMPTY);
|
||||
|
||||
McpSchema.ElicitFormRequest formRequest = McpSchema.ElicitRequest.builder("form", Map.of("type", "object"))
|
||||
.build();
|
||||
McpSchema.ElicitUrlRequest urlRequest = McpSchema.ElicitUrlRequest.builder("url", "http", "123").build();
|
||||
|
||||
when(mockSession.sendRequest(eq(McpSchema.METHOD_ELICITATION_CREATE), eq(formRequest), any(TypeRef.class)))
|
||||
.thenReturn(Mono.just(McpSchema.ElicitResult.builder(McpSchema.ElicitResult.Action.ACCEPT).build()));
|
||||
when(mockSession.sendRequest(eq(McpSchema.METHOD_ELICITATION_CREATE), eq(urlRequest), any(TypeRef.class)))
|
||||
.thenReturn(Mono.just(McpSchema.ElicitResult.builder(McpSchema.ElicitResult.Action.ACCEPT).build()));
|
||||
|
||||
StepVerifier.create(exchangeBoth.createElicitation(formRequest)).expectNextCount(1).verifyComplete();
|
||||
StepVerifier.create(exchangeBoth.createElicitation(urlRequest)).expectNextCount(1).verifyComplete();
|
||||
}
|
||||
|
||||
// ---------------------------------------
|
||||
// Create Message Tests
|
||||
// ---------------------------------------
|
||||
|
|
|
|||
Loading…
Reference in a new issue