feat: deprecate roots, sampling, and logging (SEP-2577) (#884)

SEP-2577 deprecates the Roots, Sampling, and Logging features. The
deprecation is advisory: the features stay fully functional and there is
no wire-level change. Mark the corresponding Rust APIs as deprecated so
downstream users get compiler warnings and migration guidance.

- Forward attributes through the service `method!` macros and deprecate
  `Peer::create_message`, `Peer::list_roots`, `Peer::set_level`, and
  `Peer::notify_logging_message`.
- Forward per-field attributes through the capability `builder!` macro and
  deprecate the generated `enable_roots`, `enable_sampling`, and
  `enable_logging` builders, plus the hand-written
  `enable_roots_list_changed`, `enable_sampling_tools`, and
  `enable_sampling_context`.
- Document the deprecation on the capability types and fields, and in the
  README feature sections.
- Allow `deprecated` at the crate's own call sites so the build stays
  warning-clean, and refresh the message schema snapshots.
This commit is contained in:
Rohit Ghumare 2026-06-04 13:43:39 +01:00 • committed by GitHub
commit 82b04a31f5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 132 additions and 38 deletions

View file

@ -471,6 +471,8 @@ context.peer.notify_prompt_list_changed().await?;
## Sampling ## Sampling
> **Deprecated (SEP-2577):** Sampling is deprecated and will be removed in a future release. It remains fully functional for now. See [SEP-2577](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2577).
Sampling flips the usual direction: the server asks the client to run an LLM completion. The server sends a `create_message` request, the client processes it through its LLM, and returns the result. Sampling flips the usual direction: the server asks the client to run an LLM completion. The server sends a `create_message` request, the client processes it through its LLM, and returns the result.
**MCP Spec:** [Sampling](https://modelcontextprotocol.io/specification/2025-11-25/client/sampling) **MCP Spec:** [Sampling](https://modelcontextprotocol.io/specification/2025-11-25/client/sampling)
@ -544,6 +546,8 @@ impl ClientHandler for MyClient {
## Roots ## Roots
> **Deprecated (SEP-2577):** Roots is deprecated and will be removed in a future release. It remains fully functional for now. See [SEP-2577](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2577).
Roots tell servers which directories or projects the client is working in. A root is a URI (typically `file://`) pointing to a workspace or repository. Servers can query roots to know where to look for files and how to scope their work. Roots tell servers which directories or projects the client is working in. A root is a URI (typically `file://`) pointing to a workspace or repository. Servers can query roots to know where to look for files and how to scope their work.
**MCP Spec:** [Roots](https://modelcontextprotocol.io/specification/2025-11-25/client/roots) **MCP Spec:** [Roots](https://modelcontextprotocol.io/specification/2025-11-25/client/roots)
@ -612,6 +616,8 @@ client.notify_roots_list_changed().await?;
## Logging ## Logging
> **Deprecated (SEP-2577):** Logging is deprecated and will be removed in a future release. It remains fully functional for now. See [SEP-2577](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2577).
Servers can send structured log messages to clients. The client sets a minimum severity level, and the server sends messages through the peer notification interface. Servers can send structured log messages to clients. The client sets a minimum severity level, and the server sends messages through the peer notification interface.
**MCP Spec:** [Logging](https://modelcontextprotocol.io/specification/2025-11-25/server/utilities/logging) **MCP Spec:** [Logging](https://modelcontextprotocol.io/specification/2025-11-25/server/utilities/logging)

View file

@ -1,3 +1,4 @@
#![allow(deprecated)]
use std::{collections::HashSet, sync::Arc}; use std::{collections::HashSet, sync::Arc};
use rmcp::{ use rmcp::{

View file

@ -60,6 +60,9 @@ pub struct ToolsCapability {
pub list_changed: Option<bool>, pub list_changed: Option<bool>,
} }
/// Roots capability. Deprecated by SEP-2577; remains functional and will be
/// removed in a future release.
/// See <https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2577>.
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Default)] #[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Default)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
@ -97,6 +100,9 @@ pub struct TaskRequestsCapability {
pub tools: Option<ToolsTaskCapability>, pub tools: Option<ToolsTaskCapability>,
} }
/// Sampling task capability. Deprecated by SEP-2577; remains functional and
/// will be removed in a future release.
/// See <https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2577>.
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Default)] #[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Default)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
@ -231,6 +237,10 @@ pub struct ElicitationCapability {
} }
/// Sampling capability with optional sub-capabilities (SEP-1577). /// Sampling capability with optional sub-capabilities (SEP-1577).
///
/// Deprecated by SEP-2577; remains functional and will be removed in a future
/// release.
/// See <https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2577>.
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Default)] #[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Default)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
@ -250,8 +260,6 @@ pub struct SamplingCapability {
/// # use rmcp::model::ClientCapabilities; /// # use rmcp::model::ClientCapabilities;
/// let cap = ClientCapabilities::builder() /// let cap = ClientCapabilities::builder()
/// .enable_experimental() /// .enable_experimental()
/// .enable_roots()
/// .enable_roots_list_changed()
/// .build(); /// .build();
/// ``` /// ```
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Default)] #[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Default)]
@ -266,9 +274,10 @@ pub struct ClientCapabilities {
/// support with no settings. /// support with no settings.
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub extensions: Option<ExtensionCapabilities>, pub extensions: Option<ExtensionCapabilities>,
/// Capability for filesystem roots (deprecated by SEP-2577).
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub roots: Option<RootsCapabilities>, pub roots: Option<RootsCapabilities>,
/// Capability for LLM sampling requests (SEP-1577) /// Capability for LLM sampling requests (SEP-1577, deprecated by SEP-2577).
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub sampling: Option<SamplingCapability>, pub sampling: Option<SamplingCapability>,
/// Capability to handle elicitation requests from servers for interactive user input /// Capability to handle elicitation requests from servers for interactive user input
@ -283,7 +292,6 @@ pub struct ClientCapabilities {
/// ```rust /// ```rust
/// # use rmcp::model::ServerCapabilities; /// # use rmcp::model::ServerCapabilities;
/// let cap = ServerCapabilities::builder() /// let cap = ServerCapabilities::builder()
/// .enable_logging()
/// .enable_experimental() /// .enable_experimental()
/// .enable_prompts() /// .enable_prompts()
/// .enable_resources() /// .enable_resources()
@ -304,6 +312,7 @@ pub struct ServerCapabilities {
/// support with no settings. /// support with no settings.
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub extensions: Option<ExtensionCapabilities>, pub extensions: Option<ExtensionCapabilities>,
/// Capability for server log message notifications (deprecated by SEP-2577).
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub logging: Option<JsonObject>, pub logging: Option<JsonObject>,
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
@ -320,7 +329,7 @@ pub struct ServerCapabilities {
#[cfg(any(feature = "server", feature = "macros"))] #[cfg(any(feature = "server", feature = "macros"))]
macro_rules! builder { macro_rules! builder {
($Target: ident {$($f: ident: $T: ty),* $(,)?}) => { ($Target: ident {$($(#[$fa:meta])* $f: ident: $T: ty),* $(,)?}) => {
paste! { paste! {
#[derive(Default, Clone, Copy, Debug)] #[derive(Default, Clone, Copy, Debug)]
#[expect(clippy::exhaustive_structs, reason = "intentionally exhaustive")] #[expect(clippy::exhaustive_structs, reason = "intentionally exhaustive")]
@ -352,20 +361,20 @@ macro_rules! builder {
} }
} }
} }
builder!($Target @toggle $($f: $T,) *); builder!($Target @toggle $($(#[$fa])* $f: $T,)*);
}; };
($Target: ident @toggle $f0: ident: $T0: ty, $($f: ident: $T: ty,)*) => { ($Target: ident @toggle $(#[$fa0:meta])* $f0: ident: $T0: ty, $($(#[$fa:meta])* $f: ident: $T: ty,)*) => {
builder!($Target @toggle [][$f0: $T0][$($f: $T,)*]); builder!($Target @toggle [][$(#[$fa0])* $f0: $T0][$($(#[$fa])* $f: $T,)*]);
}; };
($Target: ident @toggle [$($ff: ident: $Tf: ty,)*][$fn: ident: $TN: ty][$fn_1: ident: $Tn_1: ty, $($ft: ident: $Tt: ty,)*]) => { ($Target: ident @toggle [$($ff: ident: $Tf: ty,)*][$(#[$fna:meta])* $fn: ident: $TN: ty][$(#[$fn1a:meta])* $fn_1: ident: $Tn_1: ty, $($(#[$fta:meta])* $ft: ident: $Tt: ty,)*]) => {
builder!($Target @impl_toggle [$($ff: $Tf,)*][$fn: $TN][$fn_1: $Tn_1, $($ft:$Tt,)*]); builder!($Target @impl_toggle [$($ff: $Tf,)*][$(#[$fna])* $fn: $TN][$fn_1: $Tn_1, $($ft:$Tt,)*]);
builder!($Target @toggle [$($ff: $Tf,)* $fn: $TN,][$fn_1: $Tn_1][$($ft:$Tt,)*]); builder!($Target @toggle [$($ff: $Tf,)* $fn: $TN,][$(#[$fn1a])* $fn_1: $Tn_1][$($(#[$fta])* $ft: $Tt,)*]);
}; };
($Target: ident @toggle [$($ff: ident: $Tf: ty,)*][$fn: ident: $TN: ty][]) => { ($Target: ident @toggle [$($ff: ident: $Tf: ty,)*][$(#[$fna:meta])* $fn: ident: $TN: ty][]) => {
builder!($Target @impl_toggle [$($ff: $Tf,)*][$fn: $TN][]); builder!($Target @impl_toggle [$($ff: $Tf,)*][$(#[$fna])* $fn: $TN][]);
}; };
($Target: ident @impl_toggle [$($ff: ident: $Tf: ty,)*][$fn: ident: $TN: ty][$($ft: ident: $Tt: ty,)*]) => { ($Target: ident @impl_toggle [$($ff: ident: $Tf: ty,)*][$(#[$fna:meta])* $fn: ident: $TN: ty][$($ft: ident: $Tt: ty,)*]) => {
paste! { paste! {
impl< impl<
$(const [<$ff:upper>]: bool,)* $(const [<$ff:upper>]: bool,)*
@ -375,6 +384,7 @@ macro_rules! builder {
false, false,
$([<$ft:upper>],)* $([<$ft:upper>],)*
>> { >> {
$(#[$fna])*
pub fn [<enable_ $fn>](self) -> [<$Target Builder>]<[<$Target BuilderState>]< pub fn [<enable_ $fn>](self) -> [<$Target Builder>]<[<$Target BuilderState>]<
$([<$ff:upper>],)* $([<$ff:upper>],)*
true, true,
@ -387,6 +397,7 @@ macro_rules! builder {
state: PhantomData state: PhantomData
} }
} }
$(#[$fna])*
pub fn [<enable_ $fn _with>](self, $fn: $TN) -> [<$Target Builder>]<[<$Target BuilderState>]< pub fn [<enable_ $fn _with>](self, $fn: $TN) -> [<$Target Builder>]<[<$Target BuilderState>]<
$([<$ff:upper>],)* $([<$ff:upper>],)*
true, true,
@ -431,6 +442,10 @@ builder! {
ServerCapabilities { ServerCapabilities {
experimental: ExperimentalCapabilities, experimental: ExperimentalCapabilities,
extensions: ExtensionCapabilities, extensions: ExtensionCapabilities,
#[deprecated(
since = "1.8.0",
note = "Logging is deprecated by SEP-2577 and will be removed in a future release. See https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2577"
)]
logging: JsonObject, logging: JsonObject,
completions: JsonObject, completions: JsonObject,
prompts: PromptsCapability, prompts: PromptsCapability,
@ -509,7 +524,15 @@ builder! {
ClientCapabilities{ ClientCapabilities{
experimental: ExperimentalCapabilities, experimental: ExperimentalCapabilities,
extensions: ExtensionCapabilities, extensions: ExtensionCapabilities,
#[deprecated(
since = "1.8.0",
note = "Roots is deprecated by SEP-2577 and will be removed in a future release. See https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2577"
)]
roots: RootsCapabilities, roots: RootsCapabilities,
#[deprecated(
since = "1.8.0",
note = "Sampling is deprecated by SEP-2577 and will be removed in a future release. See https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2577"
)]
sampling: SamplingCapability, sampling: SamplingCapability,
elicitation: ElicitationCapability, elicitation: ElicitationCapability,
tasks: TasksCapability, tasks: TasksCapability,
@ -520,6 +543,10 @@ builder! {
impl<const E: bool, const EXT: bool, const S: bool, const EL: bool, const TASKS: bool> impl<const E: bool, const EXT: bool, const S: bool, const EL: bool, const TASKS: bool>
ClientCapabilitiesBuilder<ClientCapabilitiesBuilderState<E, EXT, true, S, EL, TASKS>> ClientCapabilitiesBuilder<ClientCapabilitiesBuilderState<E, EXT, true, S, EL, TASKS>>
{ {
#[deprecated(
since = "1.8.0",
note = "Roots is deprecated by SEP-2577 and will be removed in a future release. See https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2577"
)]
pub fn enable_roots_list_changed(mut self) -> Self { pub fn enable_roots_list_changed(mut self) -> Self {
if let Some(c) = self.roots.as_mut() { if let Some(c) = self.roots.as_mut() {
c.list_changed = Some(true); c.list_changed = Some(true);
@ -533,6 +560,10 @@ impl<const E: bool, const EXT: bool, const R: bool, const EL: bool, const TASKS:
ClientCapabilitiesBuilder<ClientCapabilitiesBuilderState<E, EXT, R, true, EL, TASKS>> ClientCapabilitiesBuilder<ClientCapabilitiesBuilderState<E, EXT, R, true, EL, TASKS>>
{ {
/// Enable tool calling in sampling requests /// Enable tool calling in sampling requests
#[deprecated(
since = "1.8.0",
note = "Sampling is deprecated by SEP-2577 and will be removed in a future release. See https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2577"
)]
pub fn enable_sampling_tools(mut self) -> Self { pub fn enable_sampling_tools(mut self) -> Self {
if let Some(c) = self.sampling.as_mut() { if let Some(c) = self.sampling.as_mut() {
c.tools = Some(JsonObject::default()); c.tools = Some(JsonObject::default());
@ -541,6 +572,10 @@ impl<const E: bool, const EXT: bool, const R: bool, const EL: bool, const TASKS:
} }
/// Enable context inclusion in sampling (soft-deprecated) /// Enable context inclusion in sampling (soft-deprecated)
#[deprecated(
since = "1.8.0",
note = "Sampling is deprecated by SEP-2577 and will be removed in a future release. See https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2577"
)]
pub fn enable_sampling_context(mut self) -> Self { pub fn enable_sampling_context(mut self) -> Self {
if let Some(c) = self.sampling.as_mut() { if let Some(c) = self.sampling.as_mut() {
c.context = Some(JsonObject::default()); c.context = Some(JsonObject::default());
@ -571,6 +606,7 @@ impl<const E: bool, const EXT: bool, const R: bool, const S: bool, const TASKS:
mod test { mod test {
use super::*; use super::*;
#[test] #[test]
#[allow(deprecated)]
fn test_builder() { fn test_builder() {
let builder = <ServerCapabilitiesBuilder>::default() let builder = <ServerCapabilitiesBuilder>::default()
.enable_logging() .enable_logging()
@ -673,6 +709,7 @@ mod test {
} }
#[test] #[test]
#[allow(deprecated)]
fn test_client_extensions_capability() { fn test_client_extensions_capability() {
// Test building ClientCapabilities with extensions (MCP Apps support) // Test building ClientCapabilities with extensions (MCP Apps support)
let mut extensions = ExtensionCapabilities::new(); let mut extensions = ExtensionCapabilities::new();

View file

@ -270,7 +270,8 @@ where
} }
macro_rules! method { macro_rules! method {
(peer_req $method:ident $Req:ident() => $Resp: ident ) => { ($(#[$meta:meta])* peer_req $method:ident $Req:ident() => $Resp: ident ) => {
$(#[$meta])*
pub async fn $method(&self) -> Result<$Resp, ServiceError> { pub async fn $method(&self) -> Result<$Resp, ServiceError> {
let result = self let result = self
.send_request(ClientRequest::$Req($Req { .send_request(ClientRequest::$Req($Req {
@ -283,7 +284,8 @@ macro_rules! method {
} }
} }
}; };
(peer_req $method:ident $Req:ident($Param: ident) => $Resp: ident ) => { ($(#[$meta:meta])* peer_req $method:ident $Req:ident($Param: ident) => $Resp: ident ) => {
$(#[$meta])*
pub async fn $method(&self, params: $Param) -> Result<$Resp, ServiceError> { pub async fn $method(&self, params: $Param) -> Result<$Resp, ServiceError> {
let result = self let result = self
.send_request(ClientRequest::$Req($Req { .send_request(ClientRequest::$Req($Req {
@ -298,7 +300,8 @@ macro_rules! method {
} }
} }
}; };
(peer_req $method:ident $Req:ident($Param: ident)? => $Resp: ident ) => { ($(#[$meta:meta])* peer_req $method:ident $Req:ident($Param: ident)? => $Resp: ident ) => {
$(#[$meta])*
pub async fn $method(&self, params: Option<$Param>) -> Result<$Resp, ServiceError> { pub async fn $method(&self, params: Option<$Param>) -> Result<$Resp, ServiceError> {
let result = self let result = self
.send_request(ClientRequest::$Req($Req { .send_request(ClientRequest::$Req($Req {
@ -313,7 +316,8 @@ macro_rules! method {
} }
} }
}; };
(peer_req $method:ident $Req:ident($Param: ident)) => { ($(#[$meta:meta])* peer_req $method:ident $Req:ident($Param: ident)) => {
$(#[$meta])*
pub async fn $method(&self, params: $Param) -> Result<(), ServiceError> { pub async fn $method(&self, params: $Param) -> Result<(), ServiceError> {
let result = self let result = self
.send_request(ClientRequest::$Req($Req { .send_request(ClientRequest::$Req($Req {
@ -329,7 +333,8 @@ macro_rules! method {
} }
}; };
(peer_not $method:ident $Not:ident($Param: ident)) => { ($(#[$meta:meta])* peer_not $method:ident $Not:ident($Param: ident)) => {
$(#[$meta])*
pub async fn $method(&self, params: $Param) -> Result<(), ServiceError> { pub async fn $method(&self, params: $Param) -> Result<(), ServiceError> {
self.send_notification(ClientNotification::$Not($Not { self.send_notification(ClientNotification::$Not($Not {
method: Default::default(), method: Default::default(),
@ -340,7 +345,8 @@ macro_rules! method {
Ok(()) Ok(())
} }
}; };
(peer_not $method:ident $Not:ident) => { ($(#[$meta:meta])* peer_not $method:ident $Not:ident) => {
$(#[$meta])*
pub async fn $method(&self) -> Result<(), ServiceError> { pub async fn $method(&self) -> Result<(), ServiceError> {
self.send_notification(ClientNotification::$Not($Not { self.send_notification(ClientNotification::$Not($Not {
method: Default::default(), method: Default::default(),
@ -354,7 +360,13 @@ macro_rules! method {
impl Peer<RoleClient> { impl Peer<RoleClient> {
method!(peer_req complete CompleteRequest(CompleteRequestParams) => CompleteResult); method!(peer_req complete CompleteRequest(CompleteRequestParams) => CompleteResult);
method!(peer_req set_level SetLevelRequest(SetLevelRequestParams)); method!(
#[deprecated(
since = "1.8.0",
note = "Logging is deprecated by SEP-2577 and will be removed in a future release. See https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2577"
)]
peer_req set_level SetLevelRequest(SetLevelRequestParams)
);
method!(peer_req get_prompt GetPromptRequest(GetPromptRequestParams) => GetPromptResult); method!(peer_req get_prompt GetPromptRequest(GetPromptRequestParams) => GetPromptResult);
method!(peer_req list_prompts ListPromptsRequest(PaginatedRequestParams)? => ListPromptsResult); method!(peer_req list_prompts ListPromptsRequest(PaginatedRequestParams)? => ListPromptsResult);
method!(peer_req list_resources ListResourcesRequest(PaginatedRequestParams)? => ListResourcesResult); method!(peer_req list_resources ListResourcesRequest(PaginatedRequestParams)? => ListResourcesResult);

View file

@ -272,7 +272,8 @@ where
} }
macro_rules! method { macro_rules! method {
(peer_req $method:ident $Req:ident() => $Resp: ident ) => { ($(#[$meta:meta])* peer_req $method:ident $Req:ident() => $Resp: ident ) => {
$(#[$meta])*
pub async fn $method(&self) -> Result<$Resp, ServiceError> { pub async fn $method(&self) -> Result<$Resp, ServiceError> {
let result = self let result = self
.send_request(ServerRequest::$Req($Req { .send_request(ServerRequest::$Req($Req {
@ -286,7 +287,8 @@ macro_rules! method {
} }
} }
}; };
(peer_req $method:ident $Req:ident($Param: ident) => $Resp: ident ) => { ($(#[$meta:meta])* peer_req $method:ident $Req:ident($Param: ident) => $Resp: ident ) => {
$(#[$meta])*
pub async fn $method(&self, params: $Param) -> Result<$Resp, ServiceError> { pub async fn $method(&self, params: $Param) -> Result<$Resp, ServiceError> {
let result = self let result = self
.send_request(ServerRequest::$Req($Req { .send_request(ServerRequest::$Req($Req {
@ -301,7 +303,8 @@ macro_rules! method {
} }
} }
}; };
(peer_req $method:ident $Req:ident($Param: ident)) => { ($(#[$meta:meta])* peer_req $method:ident $Req:ident($Param: ident)) => {
$(#[$meta])*
pub fn $method( pub fn $method(
&self, &self,
params: $Param, params: $Param,
@ -321,7 +324,8 @@ macro_rules! method {
} }
}; };
(peer_not $method:ident $Not:ident($Param: ident)) => { ($(#[$meta:meta])* peer_not $method:ident $Not:ident($Param: ident)) => {
$(#[$meta])*
pub async fn $method(&self, params: $Param) -> Result<(), ServiceError> { pub async fn $method(&self, params: $Param) -> Result<(), ServiceError> {
self.send_notification(ServerNotification::$Not($Not { self.send_notification(ServerNotification::$Not($Not {
method: Default::default(), method: Default::default(),
@ -332,7 +336,8 @@ macro_rules! method {
Ok(()) Ok(())
} }
}; };
(peer_not $method:ident $Not:ident) => { ($(#[$meta:meta])* peer_not $method:ident $Not:ident) => {
$(#[$meta])*
pub async fn $method(&self) -> Result<(), ServiceError> { pub async fn $method(&self) -> Result<(), ServiceError> {
self.send_notification(ServerNotification::$Not($Not { self.send_notification(ServerNotification::$Not($Not {
method: Default::default(), method: Default::default(),
@ -344,7 +349,8 @@ macro_rules! method {
}; };
// Timeout-only variants (base method should be created separately with peer_req) // Timeout-only variants (base method should be created separately with peer_req)
(peer_req_with_timeout $method_with_timeout:ident $Req:ident() => $Resp: ident) => { ($(#[$meta:meta])* peer_req_with_timeout $method_with_timeout:ident $Req:ident() => $Resp: ident) => {
$(#[$meta])*
pub async fn $method_with_timeout( pub async fn $method_with_timeout(
&self, &self,
timeout: Option<std::time::Duration>, timeout: Option<std::time::Duration>,
@ -369,7 +375,8 @@ macro_rules! method {
} }
}; };
(peer_req_with_timeout $method_with_timeout:ident $Req:ident($Param: ident) => $Resp: ident) => { ($(#[$meta:meta])* peer_req_with_timeout $method_with_timeout:ident $Req:ident($Param: ident) => $Resp: ident) => {
$(#[$meta])*
pub async fn $method_with_timeout( pub async fn $method_with_timeout(
&self, &self,
params: $Param, params: $Param,
@ -412,6 +419,10 @@ impl Peer<RoleServer> {
} }
} }
#[deprecated(
since = "1.8.0",
note = "Sampling is deprecated by SEP-2577 and will be removed in a future release. See https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2577"
)]
pub async fn create_message( pub async fn create_message(
&self, &self,
params: CreateMessageRequestParams, params: CreateMessageRequestParams,
@ -441,7 +452,13 @@ impl Peer<RoleServer> {
_ => Err(ServiceError::UnexpectedResponse), _ => Err(ServiceError::UnexpectedResponse),
} }
} }
method!(peer_req list_roots ListRootsRequest() => ListRootsResult); method!(
#[deprecated(
since = "1.8.0",
note = "Roots is deprecated by SEP-2577 and will be removed in a future release. See https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2577"
)]
peer_req list_roots ListRootsRequest() => ListRootsResult
);
#[cfg(feature = "elicitation")] #[cfg(feature = "elicitation")]
method!(peer_req create_elicitation CreateElicitationRequest(CreateElicitationRequestParams) => CreateElicitationResult); method!(peer_req create_elicitation CreateElicitationRequest(CreateElicitationRequestParams) => CreateElicitationResult);
#[cfg(feature = "elicitation")] #[cfg(feature = "elicitation")]
@ -451,7 +468,13 @@ impl Peer<RoleServer> {
method!(peer_not notify_cancelled CancelledNotification(CancelledNotificationParam)); method!(peer_not notify_cancelled CancelledNotification(CancelledNotificationParam));
method!(peer_not notify_progress ProgressNotification(ProgressNotificationParam)); method!(peer_not notify_progress ProgressNotification(ProgressNotificationParam));
method!(peer_not notify_logging_message LoggingMessageNotification(LoggingMessageNotificationParam)); method!(
#[deprecated(
since = "1.8.0",
note = "Logging is deprecated by SEP-2577 and will be removed in a future release. See https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2577"
)]
peer_not notify_logging_message LoggingMessageNotification(LoggingMessageNotificationParam)
);
method!(peer_not notify_resource_updated ResourceUpdatedNotification(ResourceUpdatedNotificationParam)); method!(peer_not notify_resource_updated ResourceUpdatedNotification(ResourceUpdatedNotificationParam));
method!(peer_not notify_resource_list_changed ResourceListChangedNotification); method!(peer_not notify_resource_list_changed ResourceListChangedNotification);
method!(peer_not notify_tool_list_changed ToolListChangedNotification); method!(peer_not notify_tool_list_changed ToolListChangedNotification);

View file

@ -112,10 +112,12 @@ impl TestServer {
} }
impl ServerHandler for TestServer { impl ServerHandler for TestServer {
#[allow(deprecated)]
fn get_info(&self) -> ServerInfo { fn get_info(&self) -> ServerInfo {
ServerInfo::new(ServerCapabilities::builder().enable_logging().build()) ServerInfo::new(ServerCapabilities::builder().enable_logging().build())
} }
#[allow(deprecated)]
fn set_level( fn set_level(
&self, &self,
request: SetLevelRequestParams, request: SetLevelRequestParams,

View file

@ -1,5 +1,6 @@
// cargo test --features "server client" --package rmcp test_logging // cargo test --features "server client" --package rmcp test_logging
#![cfg(not(feature = "local"))] #![cfg(not(feature = "local"))]
#![allow(deprecated)]
mod common; mod common;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};

View file

@ -272,7 +272,7 @@
}, },
"ClientCapabilities": { "ClientCapabilities": {
"title": "Builder", "title": "Builder",
"description": "```rust\n# use rmcp::model::ClientCapabilities;\nlet cap = ClientCapabilities::builder()\n .enable_experimental()\n .enable_roots()\n .enable_roots_list_changed()\n .build();\n```", "description": "```rust\n# use rmcp::model::ClientCapabilities;\nlet cap = ClientCapabilities::builder()\n .enable_experimental()\n .build();\n```",
"type": "object", "type": "object",
"properties": { "properties": {
"elicitation": { "elicitation": {
@ -308,6 +308,7 @@
} }
}, },
"roots": { "roots": {
"description": "Capability for filesystem roots (deprecated by SEP-2577).",
"anyOf": [ "anyOf": [
{ {
"$ref": "#/definitions/RootsCapabilities" "$ref": "#/definitions/RootsCapabilities"
@ -318,7 +319,7 @@
] ]
}, },
"sampling": { "sampling": {
"description": "Capability for LLM sampling requests (SEP-1577)", "description": "Capability for LLM sampling requests (SEP-1577, deprecated by SEP-2577).",
"anyOf": [ "anyOf": [
{ {
"$ref": "#/definitions/SamplingCapability" "$ref": "#/definitions/SamplingCapability"
@ -1811,6 +1812,7 @@
] ]
}, },
"RootsCapabilities": { "RootsCapabilities": {
"description": "Roots capability. Deprecated by SEP-2577; remains functional and will be\nremoved in a future release.\nSee <https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2577>.",
"type": "object", "type": "object",
"properties": { "properties": {
"listChanged": { "listChanged": {
@ -1827,7 +1829,7 @@
"const": "notifications/roots/list_changed" "const": "notifications/roots/list_changed"
}, },
"SamplingCapability": { "SamplingCapability": {
"description": "Sampling capability with optional sub-capabilities (SEP-1577).", "description": "Sampling capability with optional sub-capabilities (SEP-1577).\n\nDeprecated by SEP-2577; remains functional and will be removed in a future\nrelease.\nSee <https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2577>.",
"type": "object", "type": "object",
"properties": { "properties": {
"context": { "context": {
@ -1955,6 +1957,7 @@
] ]
}, },
"SamplingTaskCapability": { "SamplingTaskCapability": {
"description": "Sampling task capability. Deprecated by SEP-2577; remains functional and\nwill be removed in a future release.\nSee <https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2577>.",
"type": "object", "type": "object",
"properties": { "properties": {
"createMessage": { "createMessage": {

View file

@ -272,7 +272,7 @@
}, },
"ClientCapabilities": { "ClientCapabilities": {
"title": "Builder", "title": "Builder",
"description": "```rust\n# use rmcp::model::ClientCapabilities;\nlet cap = ClientCapabilities::builder()\n .enable_experimental()\n .enable_roots()\n .enable_roots_list_changed()\n .build();\n```", "description": "```rust\n# use rmcp::model::ClientCapabilities;\nlet cap = ClientCapabilities::builder()\n .enable_experimental()\n .build();\n```",
"type": "object", "type": "object",
"properties": { "properties": {
"elicitation": { "elicitation": {
@ -308,6 +308,7 @@
} }
}, },
"roots": { "roots": {
"description": "Capability for filesystem roots (deprecated by SEP-2577).",
"anyOf": [ "anyOf": [
{ {
"$ref": "#/definitions/RootsCapabilities" "$ref": "#/definitions/RootsCapabilities"
@ -318,7 +319,7 @@
] ]
}, },
"sampling": { "sampling": {
"description": "Capability for LLM sampling requests (SEP-1577)", "description": "Capability for LLM sampling requests (SEP-1577, deprecated by SEP-2577).",
"anyOf": [ "anyOf": [
{ {
"$ref": "#/definitions/SamplingCapability" "$ref": "#/definitions/SamplingCapability"
@ -1811,6 +1812,7 @@
] ]
}, },
"RootsCapabilities": { "RootsCapabilities": {
"description": "Roots capability. Deprecated by SEP-2577; remains functional and will be\nremoved in a future release.\nSee <https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2577>.",
"type": "object", "type": "object",
"properties": { "properties": {
"listChanged": { "listChanged": {
@ -1827,7 +1829,7 @@
"const": "notifications/roots/list_changed" "const": "notifications/roots/list_changed"
}, },
"SamplingCapability": { "SamplingCapability": {
"description": "Sampling capability with optional sub-capabilities (SEP-1577).", "description": "Sampling capability with optional sub-capabilities (SEP-1577).\n\nDeprecated by SEP-2577; remains functional and will be removed in a future\nrelease.\nSee <https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2577>.",
"type": "object", "type": "object",
"properties": { "properties": {
"context": { "context": {
@ -1955,6 +1957,7 @@
] ]
}, },
"SamplingTaskCapability": { "SamplingTaskCapability": {
"description": "Sampling task capability. Deprecated by SEP-2577; remains functional and\nwill be removed in a future release.\nSee <https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2577>.",
"type": "object", "type": "object",
"properties": { "properties": {
"createMessage": { "createMessage": {

View file

@ -2724,6 +2724,7 @@
] ]
}, },
"SamplingTaskCapability": { "SamplingTaskCapability": {
"description": "Sampling task capability. Deprecated by SEP-2577; remains functional and\nwill be removed in a future release.\nSee <https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2577>.",
"type": "object", "type": "object",
"properties": { "properties": {
"createMessage": { "createMessage": {
@ -2737,7 +2738,7 @@
}, },
"ServerCapabilities": { "ServerCapabilities": {
"title": "Builder", "title": "Builder",
"description": "```rust\n# use rmcp::model::ServerCapabilities;\nlet cap = ServerCapabilities::builder()\n .enable_logging()\n .enable_experimental()\n .enable_prompts()\n .enable_resources()\n .enable_tools()\n .enable_tool_list_changed()\n .build();\n```", "description": "```rust\n# use rmcp::model::ServerCapabilities;\nlet cap = ServerCapabilities::builder()\n .enable_experimental()\n .enable_prompts()\n .enable_resources()\n .enable_tools()\n .enable_tool_list_changed()\n .build();\n```",
"type": "object", "type": "object",
"properties": { "properties": {
"completions": { "completions": {
@ -2769,6 +2770,7 @@
} }
}, },
"logging": { "logging": {
"description": "Capability for server log message notifications (deprecated by SEP-2577).",
"type": [ "type": [
"object", "object",
"null" "null"

View file

@ -2724,6 +2724,7 @@
] ]
}, },
"SamplingTaskCapability": { "SamplingTaskCapability": {
"description": "Sampling task capability. Deprecated by SEP-2577; remains functional and\nwill be removed in a future release.\nSee <https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2577>.",
"type": "object", "type": "object",
"properties": { "properties": {
"createMessage": { "createMessage": {
@ -2737,7 +2738,7 @@
}, },
"ServerCapabilities": { "ServerCapabilities": {
"title": "Builder", "title": "Builder",
"description": "```rust\n# use rmcp::model::ServerCapabilities;\nlet cap = ServerCapabilities::builder()\n .enable_logging()\n .enable_experimental()\n .enable_prompts()\n .enable_resources()\n .enable_tools()\n .enable_tool_list_changed()\n .build();\n```", "description": "```rust\n# use rmcp::model::ServerCapabilities;\nlet cap = ServerCapabilities::builder()\n .enable_experimental()\n .enable_prompts()\n .enable_resources()\n .enable_tools()\n .enable_tool_list_changed()\n .build();\n```",
"type": "object", "type": "object",
"properties": { "properties": {
"completions": { "completions": {
@ -2769,6 +2770,7 @@
} }
}, },
"logging": { "logging": {
"description": "Capability for server log message notifications (deprecated by SEP-2577).",
"type": [ "type": [
"object", "object",
"null" "null"

View file

@ -1,4 +1,5 @@
#![cfg(not(feature = "local"))] #![cfg(not(feature = "local"))]
#![allow(deprecated)]
mod common; mod common;
use anyhow::Result; use anyhow::Result;

View file

@ -1,3 +1,4 @@
#![allow(deprecated)]
use std::sync::Arc; use std::sync::Arc;
use anyhow::Result; use anyhow::Result;