feat(elicitation): add support URL elicitation. SEP-1036 (#605)

This commit is contained in:
Pavel Bezglasny 2026-02-08 03:39:30 +01:00 • committed by GitHub
commit 187597bf7e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -62,6 +62,10 @@ impl<H: ClientHandler> Service<RoleClient> for H {
ServerNotification::PromptListChangedNotification(_notification_no_param) => {
self.on_prompt_list_changed(context).await
}
ServerNotification::ElicitationCompletionNotification(notification) => {
self.on_url_elicitation_notification_complete(notification.params, context)
.await
}
ServerNotification::CustomNotification(notification) => {
self.on_custom_notification(notification, context).await
}
@ -116,6 +120,44 @@ pub trait ClientHandler: Sized + Send + Sync + 'static {
/// # Default Behavior
/// The default implementation automatically declines all elicitation requests.
/// Real clients should override this to provide user interaction.
///
/// # Example
/// ```rust,ignore
/// use rmcp::model::CreateElicitationRequestParam;
/// use rmcp::{
/// model::ErrorData as McpError,
/// model::*,
/// service::{NotificationContext, RequestContext, RoleClient, Service, ServiceRole},
/// };
/// use rmcp::ClientHandler;
///
/// impl ClientHandler for MyClient {
/// async fn create_elicitation(
/// &self,
/// request: CreateElicitationRequestParam,
/// context: RequestContext<RoleClient>,
/// ) -> Result<CreateElicitationResult, McpError> {
/// match request {
/// CreateElicitationRequestParam::FormElicitationParam {meta, message, requested_schema,} => {
/// // Display message to user and collect input according to requested_schema
/// let user_input = get_user_input(message, requested_schema).await?;
/// Ok(CreateElicitationResult {
/// action: ElicitationAction::Accept,
/// content: Some(user_input),
/// })
/// }
/// CreateElicitationRequestParam::UrlElicitationParam {meta, message, url, elicitation_id,} => {
/// // Open URL in browser for user to complete elicitation
/// open_url_in_browser(url).await?;
/// Ok(CreateElicitationResult {
/// action: ElicitationAction::Accept,
/// content: None,
/// })
/// }
/// }
/// }
/// }
/// ```
fn create_elicitation(
&self,
request: CreateElicitationRequestParams,
@ -189,6 +231,14 @@ pub trait ClientHandler: Sized + Send + Sync + 'static {
) -> impl Future<Output = ()> + Send + '_ {
std::future::ready(())
}
fn on_url_elicitation_notification_complete(
&self,
params: ElicitationResponseNotificationParam,
context: NotificationContext<RoleClient>,
) -> impl Future<Output = ()> + Send + '_ {
std::future::ready(())
}
fn on_custom_notification(
&self,
notification: CustomNotification,