refactor!: remove deprecated v3 APIs (#1066)

This commit is contained in:
Dale Seo 2026-07-28 14:01:56 -04:00 • committed by GitHub
commit 25213a271a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 72 additions and 249 deletions

View file

@ -1,10 +1,6 @@
use std::{borrow::Cow, fmt::Display};
pub use crate::model::ErrorData;
#[deprecated(
note = "Use `rmcp::ErrorData` instead, `rmcp::ErrorData` could become `RmcpError` in the future."
)]
pub type Error = ErrorData;
impl Display for ErrorData {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}: {}", self.code.0, self.message)?;

View file

@ -129,42 +129,51 @@ macro_rules! client_handler_methods {
/// Real clients should override this to provide user interaction.
///
/// # Example
/// ```rust,ignore
/// use rmcp::model::ElicitRequestParams;
/// ```rust,no_run
/// use rmcp::{
/// model::ErrorData as McpError,
/// model::*,
/// service::{NotificationContext, RequestContext, RoleClient, Service, ServiceRole},
/// ClientHandler,
/// model::{
/// ElicitRequestParams, ElicitResult, ElicitationAction, ElicitationSchema,
/// ErrorData as McpError,
/// },
/// service::{RequestContext, RoleClient},
/// };
/// use rmcp::ClientHandler;
///
/// # struct MyClient;
/// #
/// # async fn get_user_input(
/// # _message: String,
/// # _schema: ElicitationSchema,
/// # ) -> Result<serde_json::Value, McpError> {
/// # std::future::pending().await
/// # }
/// #
/// # async fn open_url_in_browser(_url: String) -> Result<(), McpError> {
/// # Ok(())
/// # }
/// #
/// impl ClientHandler for MyClient {
/// async fn create_elicitation(
/// &self,
/// request: ElicitRequestParams,
/// context: RequestContext<RoleClient>,
/// ) -> Result<ElicitResult, McpError> {
/// match request {
/// ElicitRequestParams::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(ElicitResult {
/// action: ElicitationAction::Accept,
/// content: Some(user_input),
/// meta: None,
/// })
/// }
/// ElicitRequestParams::UrlElicitationParam {meta, message, url, elicitation_id,} => {
/// // Open URL in browser for user to complete elicitation
/// open_url_in_browser(url).await?;
/// Ok(ElicitResult {
/// action: ElicitationAction::Accept,
/// content: None,
/// meta: None,
/// })
/// async fn create_elicitation(
/// &self,
/// request: ElicitRequestParams,
/// _context: RequestContext<RoleClient>,
/// ) -> Result<ElicitResult, McpError> {
/// match request {
/// ElicitRequestParams::FormElicitationParams {
/// message,
/// requested_schema,
/// ..
/// } => {
/// let input = get_user_input(message, requested_schema).await?;
/// Ok(ElicitResult::new(ElicitationAction::Accept).with_content(input))
/// }
/// ElicitRequestParams::UrlElicitationParams { url, .. } => {
/// open_url_in_browser(url).await?;
/// Ok(ElicitResult::new(ElicitationAction::Accept))
/// }
/// _ => Ok(ElicitResult::new(ElicitationAction::Decline)),
/// }
/// }
/// }
/// }
/// ```
fn create_elicitation(

View file

@ -3,8 +3,7 @@
#![doc = include_str!("../README.md")]
mod error;
#[allow(deprecated)]
pub use error::{Error, ErrorData, RmcpError};
pub use error::{ErrorData, RmcpError};
/// Basic data types in MCP specification
pub mod model;

View file

@ -1029,10 +1029,6 @@ impl RequestParamsMeta for InitializeRequestParams {
}
}
/// Deprecated: Use [`InitializeRequestParams`] instead (SEP-1319 compliance).
#[deprecated(since = "0.13.0", note = "Use InitializeRequestParams instead")]
pub type InitializeRequestParam = InitializeRequestParams;
/// The server's response to an initialization request.
///
/// Contains the server's protocol version, capabilities, and implementation
@ -1437,9 +1433,6 @@ impl RequestParamsMeta for PaginatedRequestParams {
}
}
/// Deprecated: Use [`PaginatedRequestParams`] instead (SEP-1319 compliance).
#[deprecated(since = "0.13.0", note = "Use PaginatedRequestParams instead")]
pub type PaginatedRequestParam = PaginatedRequestParams;
// =============================================================================
// PROGRESS AND PAGINATION
// =============================================================================
@ -1680,10 +1673,6 @@ impl RequestParamsMeta for ReadResourceRequestParams {
}
}
/// Deprecated: Use [`ReadResourceRequestParams`] instead (SEP-1319 compliance).
#[deprecated(since = "0.13.0", note = "Use ReadResourceRequestParams instead")]
pub type ReadResourceRequestParam = ReadResourceRequestParams;
/// Result containing the contents of a read resource
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
#[serde(rename_all = "camelCase")]
@ -1788,10 +1777,6 @@ impl RequestParamsMeta for SubscribeRequestParams {
}
}
/// Deprecated: Use [`SubscribeRequestParams`] instead (SEP-1319 compliance).
#[deprecated(since = "0.13.0", note = "Use SubscribeRequestParams instead")]
pub type SubscribeRequestParam = SubscribeRequestParams;
/// Request to subscribe to resource updates
#[deprecated(
note = "resources/subscribe is legacy-only; use subscriptions/listen for protocol version 2026-07-28"
@ -1831,10 +1816,6 @@ impl RequestParamsMeta for UnsubscribeRequestParams {
}
}
/// Deprecated: Use [`UnsubscribeRequestParams`] instead (SEP-1319 compliance).
#[deprecated(since = "0.13.0", note = "Use UnsubscribeRequestParams instead")]
pub type UnsubscribeRequestParam = UnsubscribeRequestParams;
/// Request to unsubscribe from resource updates
#[deprecated(
note = "resources/unsubscribe is legacy-only; cancel the subscriptions/listen request for protocol version 2026-07-28"
@ -2333,10 +2314,6 @@ impl RequestParamsMeta for GetPromptRequestParams {
}
}
/// Deprecated: Use [`GetPromptRequestParams`] instead (SEP-1319 compliance).
#[deprecated(since = "0.13.0", note = "Use GetPromptRequestParams instead")]
pub type GetPromptRequestParam = GetPromptRequestParams;
/// Request to get a specific prompt
pub type GetPromptRequest = Request<GetPromptRequestMethod, GetPromptRequestParams>;
@ -2406,10 +2383,6 @@ impl RequestParamsMeta for SetLevelRequestParams {
}
}
/// Deprecated: Use [`SetLevelRequestParams`] instead (SEP-1319 compliance).
#[deprecated(since = "0.13.0", note = "Use SetLevelRequestParams instead")]
pub type SetLevelRequestParam = SetLevelRequestParams;
/// Request to set the logging level
#[deprecated(
since = "2.0.0",
@ -2679,9 +2652,6 @@ pub enum SamplingMessageContentBlock {
ToolResult(ToolResultContent),
}
#[deprecated(since = "2.0.0", note = "Renamed to SamplingMessageContentBlock")]
pub type SamplingMessageContent = SamplingMessageContentBlock;
impl SamplingMessageContentBlock {
/// Create a text content
pub fn text(text: impl Into<String>) -> Self {
@ -3008,10 +2978,6 @@ impl CreateMessageRequestParams {
}
}
/// Deprecated: Use [`CreateMessageRequestParams`] instead (SEP-1319 compliance).
#[deprecated(since = "0.13.0", note = "Use CreateMessageRequestParams instead")]
pub type CreateMessageRequestParam = CreateMessageRequestParams;
/// Preferences for model selection and behavior in sampling requests.
///
/// This allows servers to express their preferences for which model to use
@ -3201,10 +3167,6 @@ impl RequestParamsMeta for CompleteRequestParams {
}
}
/// Deprecated: Use [`CompleteRequestParams`] instead (SEP-1319 compliance).
#[deprecated(since = "0.13.0", note = "Use CompleteRequestParams instead")]
pub type CompleteRequestParam = CompleteRequestParams;
pub type CompleteRequest = Request<CompleteRequestMethod, CompleteRequestParams>;
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Default)]
@ -3391,9 +3353,6 @@ impl ResourceTemplateReference {
}
}
#[deprecated(since = "2.0.0", note = "Renamed to ResourceTemplateReference")]
pub type ResourceReference = ResourceTemplateReference;
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[non_exhaustive]
@ -3545,21 +3504,20 @@ pub enum ElicitationAction {
Cancel,
}
/// Helper enum for deserializing CreateElicitationRequestParam with backward compatibility.
/// When mode is missing, it defaults to FormElicitationParam.
/// Wire representation for tagged elicitation parameters and legacy forms without `mode`.
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
#[serde(tag = "mode")]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
enum CreateElicitationRequestParamDeserializeHelper {
enum ElicitRequestParamsWire {
#[serde(rename = "form", rename_all = "camelCase")]
FormElicitationParam {
Form {
#[serde(rename = "_meta", default, skip_serializing_if = "Option::is_none")]
meta: Option<RequestMetaObject>,
message: String,
requested_schema: ElicitationSchema,
},
#[serde(rename = "url", rename_all = "camelCase")]
UrlElicitationParam {
Url {
#[serde(rename = "_meta", default, skip_serializing_if = "Option::is_none")]
meta: Option<RequestMetaObject>,
message: String,
@ -3567,7 +3525,7 @@ enum CreateElicitationRequestParamDeserializeHelper {
elicitation_id: String,
},
#[serde(untagged, rename_all = "camelCase")]
FormElicitationParamBackwardsCompat {
LegacyForm {
#[serde(rename = "_meta", default, skip_serializing_if = "Option::is_none")]
meta: Option<RequestMetaObject>,
message: String,
@ -3575,19 +3533,17 @@ enum CreateElicitationRequestParamDeserializeHelper {
},
}
impl TryFrom<CreateElicitationRequestParamDeserializeHelper> for ElicitRequestParams {
impl TryFrom<ElicitRequestParamsWire> for ElicitRequestParams {
type Error = serde_json::Error;
fn try_from(
value: CreateElicitationRequestParamDeserializeHelper,
) -> Result<Self, Self::Error> {
fn try_from(value: ElicitRequestParamsWire) -> Result<Self, Self::Error> {
match value {
CreateElicitationRequestParamDeserializeHelper::FormElicitationParam {
ElicitRequestParamsWire::Form {
meta,
message,
requested_schema,
}
| CreateElicitationRequestParamDeserializeHelper::FormElicitationParamBackwardsCompat {
| ElicitRequestParamsWire::LegacyForm {
meta,
message,
requested_schema,
@ -3596,7 +3552,7 @@ impl TryFrom<CreateElicitationRequestParamDeserializeHelper> for ElicitRequestPa
message,
requested_schema,
}),
CreateElicitationRequestParamDeserializeHelper::UrlElicitationParam {
ElicitRequestParamsWire::Url {
meta,
message,
url,
@ -3642,10 +3598,7 @@ impl TryFrom<CreateElicitationRequestParamDeserializeHelper> for ElicitRequestPa
/// };
/// ```
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
#[serde(
tag = "mode",
try_from = "CreateElicitationRequestParamDeserializeHelper"
)]
#[serde(tag = "mode", try_from = "ElicitRequestParamsWire")]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[non_exhaustive]
pub enum ElicitRequestParams {
@ -3697,13 +3650,6 @@ impl RequestParamsMeta for ElicitRequestParams {
}
}
/// Deprecated: Use [`ElicitRequestParams`] instead (SEP-1319 compliance).
#[deprecated(since = "0.13.0", note = "Use ElicitRequestParams instead")]
pub type CreateElicitationRequestParam = ElicitRequestParams;
#[deprecated(since = "2.0.0", note = "Renamed to ElicitRequestParams")]
pub type CreateElicitationRequestParams = ElicitRequestParams;
/// The result returned by a client in response to an elicitation request.
///
/// Contains the user's decision (accept/decline/cancel) and optionally their input data
@ -3750,15 +3696,9 @@ impl ElicitResult {
}
}
#[deprecated(since = "2.0.0", note = "Renamed to ElicitResult")]
pub type CreateElicitationResult = ElicitResult;
/// Request type for creating an elicitation to gather user input
pub type ElicitRequest = Request<ElicitationCreateRequestMethod, ElicitRequestParams>;
#[deprecated(since = "2.0.0", note = "Renamed to ElicitRequest")]
pub type CreateElicitationRequest = ElicitRequest;
// =============================================================================
// TOOL EXECUTION RESULTS
// =============================================================================
@ -4088,10 +4028,6 @@ impl RequestParamsMeta for CallToolRequestParams {
}
}
/// Deprecated: Use [`CallToolRequestParams`] instead (SEP-1319 compliance).
#[deprecated(since = "0.13.0", note = "Use CallToolRequestParams instead")]
pub type CallToolRequestParam = CallToolRequestParams;
/// Request to call a specific tool
pub type CallToolRequest = Request<CallToolRequestMethod, CallToolRequestParams>;
@ -4625,14 +4561,6 @@ mod tests {
use super::*;
#[test]
#[allow(deprecated)]
fn deprecated_aliases_still_resolve() {
// 하위호환: 구 이름이 새 타입으로 여전히 resolve되는지 확인.
let _: CreateElicitationResult = ElicitResult::new(ElicitationAction::Accept);
let _: ResourceReference = ResourceTemplateReference::new("res://x");
}
#[cfg(feature = "transport-streamable-http-client")]
#[test]
fn transport_closed_marker_accepts_only_the_process_local_token() {
@ -4853,12 +4781,11 @@ mod tests {
serde_json::from_value(request.clone()).expect("invalid request");
let (request, id) = request.into_request().expect("should be a request");
assert_eq!(id, RequestId::Number(1));
#[allow(deprecated)]
match request {
ClientRequest::InitializeRequest(Request {
method: _,
params:
InitializeRequestParam {
InitializeRequestParams {
meta: _,
protocol_version: _,
capabilities,
@ -5124,8 +5051,7 @@ mod tests {
}
#[test]
fn test_elicitation_deserialization_untagged() {
// Test deserialization without the "type" field (should default to FormElicitationParam)
fn elicitation_without_mode_deserializes_as_form() {
let json_data_without_tag = json!({
"message": "Please provide more details.",
"requestedSchema": {
@ -5151,7 +5077,7 @@ mod tests {
assert_eq!(requested_schema.title, Some(Cow::from("User Details")));
assert_eq!(requested_schema.type_, ObjectTypeConst);
} else {
panic!("Expected FormElicitationParam");
panic!("Expected FormElicitationParams");
}
}
@ -5189,7 +5115,7 @@ mod tests {
assert_eq!(requested_schema.title, Some(Cow::from("User Details")));
assert_eq!(requested_schema.type_, ObjectTypeConst);
} else {
panic!("Expected FormElicitationParam");
panic!("Expected FormElicitationParams");
}
let json_data_url = json!({
@ -5218,7 +5144,7 @@ mod tests {
assert_eq!(url, "https://example.com/form");
assert_eq!(elicitation_id, "elicitation-123");
} else {
panic!("Expected UrlElicitationParam");
panic!("Expected UrlElicitationParams");
}
}

View file

@ -63,9 +63,6 @@ pub enum PrimitiveSchemaDefinition {
Boolean(BooleanSchema),
}
#[deprecated(since = "2.0.0", note = "Renamed to PrimitiveSchemaDefinition")]
pub type PrimitiveSchema = PrimitiveSchemaDefinition;
// =============================================================================
// STRING SCHEMA
// =============================================================================
@ -1600,44 +1597,6 @@ impl ElicitationSchemaBuilder {
self.property(name, PrimitiveSchemaDefinition::Enum(enum_schema))
}
/// Add a required enum property using values. Creates an untitled single-select enum.
#[deprecated(
since = "0.13.0",
note = "Use ElicitationSchemaBuilder::required_enum_schema with EnumSchema::builder instead"
)]
pub fn required_enum(self, name: impl Into<String>, values: Vec<String>) -> Self {
self.required_property(
name,
PrimitiveSchemaDefinition::Enum(EnumSchema::Legacy(LegacyEnumSchema {
type_: StringTypeConst,
title: None,
description: None,
enum_: values,
enum_names: None,
default: None,
})),
)
}
/// Add an optional enum property using values. Creates an untitled single-select enum.
#[deprecated(
since = "0.13.0",
note = "Use ElicitationSchemaBuilder::optional_enum_schema with EnumSchema::builder instead"
)]
pub fn optional_enum(self, name: impl Into<String>, values: Vec<String>) -> Self {
self.property(
name,
PrimitiveSchemaDefinition::Enum(EnumSchema::Legacy(LegacyEnumSchema {
type_: StringTypeConst,
title: None,
description: None,
enum_: values,
enum_names: None,
default: None,
})),
)
}
/// Mark an existing property as required
pub fn mark_required(mut self, name: impl Into<String>) -> Self {
self.required.push(name.into());

View file

@ -243,15 +243,6 @@ variant_extension! {
#[expect(clippy::exhaustive_structs, reason = "intentionally exhaustive")]
pub struct MetaObject(pub JsonObject);
/// Deprecated alias for [`MetaObject`].
///
/// This is a re-export rather than a type alias so the `Meta(...)` tuple
/// constructor keeps working. Request and notification metadata now have
/// dedicated types; use [`RequestMetaObject`] or [`NotificationMetaObject`]
/// where those are expected.
#[deprecated(note = "Use MetaObject (or RequestMetaObject / NotificationMetaObject)")]
pub use self::MetaObject as Meta;
impl MetaObject {
/// Reserved `_meta` key for the W3C Trace Context `traceparent` value (SEP-414).
const TRACEPARENT_FIELD: &str = "traceparent";

View file

@ -86,9 +86,8 @@ struct ProxyNoParam<M> {
}
/// Combine the message-specific `_meta` map with a legacy [`MetaObject`]
/// extension (inserted through the deprecated `Meta` name), so pre-3.x code
/// does not silently lose metadata on the wire. On key conflicts the
/// message-specific map wins.
/// extension so metadata stored in [`Extensions`] is not lost on the wire.
/// On key conflicts the message-specific map wins.
fn merge_legacy_meta<'a>(
typed: Option<&'a JsonObject>,
extensions: &'a Extensions,
@ -99,7 +98,11 @@ fn merge_legacy_meta<'a>(
(None, Some(legacy)) => Some(Cow::Borrowed(legacy)),
(Some(typed), Some(legacy)) => {
let mut merged = legacy.clone();
merged.extend(typed.clone());
merged.extend(
typed
.iter()
.map(|(key, value)| (key.clone(), value.clone())),
);
Some(Cow::Owned(merged))
}
(None, None) => None,
@ -778,8 +781,6 @@ mod test {
#[test]
fn test_legacy_meta_extension_still_serializes() {
// Pre-3.x code inserts `MetaObject` into extensions through the
// deprecated `Meta` name; its metadata must not be silently dropped.
let mut extensions = Extensions::new();
let mut legacy = crate::model::MetaObject::new();
legacy.insert("traceId".to_string(), json!("legacy"));

View file

@ -85,13 +85,6 @@ pub enum ServerInitializeError {
#[error("expect initialized request, but received: {0:?}")]
ExpectedInitializeRequest(Option<ClientJsonRpcMessage>),
#[deprecated(
since = "1.4.0",
note = "The server no longer gates on the initialized notification. This variant is never constructed and will be removed in a future major release."
)]
#[error("expect initialized notification, but received: {0:?}")]
ExpectedInitializedNotification(Option<ClientJsonRpcMessage>),
#[error("connection closed: {0}")]
ConnectionClosed(String),
@ -101,13 +94,6 @@ pub enum ServerInitializeError {
#[error("initialize failed: {0}")]
InitializeFailed(ErrorData),
#[deprecated(
since = "1.8.0",
note = "Negotiation now falls back to the server-configured version. This variant is never constructed and will be removed in a future major release."
)]
#[error("unsupported protocol version: {0}")]
UnsupportedProtocolVersion(ProtocolVersion),
#[error("Send message error {error}, when {context}")]
TransportError {
error: DynamicTransportError,

View file

@ -2,10 +2,7 @@ use std::process::Stdio;
use futures::future::Future;
use process_wrap::tokio::{ChildWrapper, CommandWrap};
use tokio::{
io::AsyncRead,
process::{ChildStderr, ChildStdin, ChildStdout},
};
use tokio::process::{ChildStderr, ChildStdin, ChildStdout};
use super::{RxJsonRpcMessage, Transport, TxJsonRpcMessage, async_rw::AsyncRwTransport};
use crate::RoleClient;
@ -59,32 +56,6 @@ impl Drop for ChildWithCleanup {
}
}
// we hold the child process with stdout, for it's easier to implement AsyncRead
pin_project_lite::pin_project! {
pub struct TokioChildProcessOut {
child: ChildWithCleanup,
#[pin]
child_stdout: ChildStdout,
}
}
impl TokioChildProcessOut {
/// Get the process ID of the child process.
pub fn id(&self) -> Option<u32> {
self.child.inner.as_ref()?.id()
}
}
impl AsyncRead for TokioChildProcessOut {
fn poll_read(
self: std::pin::Pin<&mut Self>,
cx: &mut std::task::Context<'_>,
buf: &mut tokio::io::ReadBuf<'_>,
) -> std::task::Poll<std::io::Result<()>> {
self.project().child_stdout.poll_read(cx, buf)
}
}
impl TokioChildProcess {
/// Convenience: spawn with default `piped` stdio
pub fn new(command: impl Into<CommandWrap>) -> std::io::Result<Self> {
@ -139,15 +110,6 @@ impl TokioChildProcess {
pub fn into_inner(mut self) -> Option<Box<dyn ChildWrapper>> {
self.child.inner.take()
}
/// Split this helper into a reader (stdout) and writer (stdin).
#[deprecated(
since = "0.5.0",
note = "use the Transport trait implementation instead"
)]
pub fn split(self) -> (TokioChildProcessOut, ChildStdin) {
unimplemented!("This method is deprecated, use the Transport trait implementation instead");
}
}
/// Builder for `TokioChildProcess` allowing custom `Stdio` configuration.

View file

@ -1032,9 +1032,6 @@ pub enum LocalSessionWorkerError {
FailToSendInitializeRequest(SessionError),
#[error("fail to handle message: {0}")]
FailToHandleMessage(SessionError),
#[deprecated(note = "idle timeout now surfaces as WorkerQuitReason::IdleTimeout")]
#[error("keep alive timeout after {}ms", _0.as_millis())]
KeepAliveTimeout(Duration),
#[error("init timeout after {}ms", _0.as_millis())]
InitTimeout(Duration),
#[error("Transport closed")]

View file

@ -90,7 +90,7 @@ async fn test_elicitation_request_param_serialization() {
assert_eq!(msg1, msg2);
assert_eq!(schema1, schema2);
}
_ => panic!("Expected FormElicitationParam variant"),
_ => panic!("Expected FormElicitationParams variant"),
}
}
@ -179,7 +179,7 @@ async fn test_elicitation_json_rpc_protocol() {
ElicitRequestParams::FormElicitationParams { message, .. } => {
assert_eq!(message, "Do you want to continue?");
}
_ => panic!("Expected FormElicitationParam variant"),
_ => panic!("Expected FormElicitationParams variant"),
}
}
@ -496,7 +496,7 @@ async fn test_elicitation_structured_schemas() {
])
);
}
_ => panic!("Expected FormElicitationParam variant"),
_ => panic!("Expected FormElicitationParams variant"),
}
}
@ -738,7 +738,7 @@ async fn test_elicitation_multi_select_enum() {
)
}
}
_ => panic!("Expected FormElicitationParam variant"),
_ => panic!("Expected FormElicitationParams variant"),
}
}
@ -799,7 +799,7 @@ async fn test_elicitation_single_select_enum() {
)
}
}
_ => panic!("Expected FormElicitationParam variant"),
_ => panic!("Expected FormElicitationParams variant"),
}
}
@ -1056,10 +1056,8 @@ async fn test_client_capabilities_with_elicitation() {
assert!(capabilities_without.elicitation.is_none());
}
/// Test InitializeRequestParam with elicitation capability
#[tokio::test]
async fn test_initialize_request_with_elicitation() {
// Test InitializeRequestParam with elicitation capability
let init_param = InitializeRequestParams::new(
ClientCapabilities::builder()
.enable_elicitation_with(
@ -1829,7 +1827,7 @@ async fn test_url_elicitation_request_param_serialization() {
assert_eq!(url, "https://example.com/verify");
assert_eq!(elicitation_id, "elicit-123");
}
_ => panic!("Expected UrlElicitationParam variant"),
_ => panic!("Expected UrlElicitationParams variant"),
}
}
@ -1878,7 +1876,7 @@ async fn test_url_elicitation_json_rpc_protocol() {
assert_eq!(url, "https://auth.example.com/authorize/abc123");
assert_eq!(elicitation_id, "auth-request-456");
}
_ => panic!("Expected UrlElicitationParam variant"),
_ => panic!("Expected UrlElicitationParams variant"),
}
}
@ -1927,7 +1925,6 @@ async fn test_url_elicitation_capability() {
/// Test backward compatibility: ElicitRequestParams without mode tag
#[tokio::test]
async fn test_elicitation_backward_compatibility_no_mode() {
// JSON without "mode" field should deserialize as FormElicitationParam
let json_without_mode = json!({
"message": "Please enter your details",
"requestedSchema": {
@ -1953,7 +1950,7 @@ async fn test_elicitation_backward_compatibility_no_mode() {
assert_eq!(requested_schema.properties.len(), 1);
assert!(requested_schema.properties.contains_key("name"));
}
_ => panic!("Expected FormElicitationParam for backward compatibility"),
_ => panic!("Expected FormElicitationParams for backward compatibility"),
}
}