@@ -519,6 +519,10 @@ pub struct JsonRpcNotification<N = Notification> {
519519pub struct ErrorCode ( pub i32 ) ;
520520
521521impl ErrorCode {
522+ /// The request used a protocol version the server does not support.
523+ pub const UNSUPPORTED_PROTOCOL_VERSION : Self = Self ( -32022 ) ;
524+ /// Processing the request requires a client capability that was not declared.
525+ pub const MISSING_REQUIRED_CLIENT_CAPABILITY : Self = Self ( -32021 ) ;
522526 pub const HEADER_MISMATCH : Self = Self ( -32020 ) ;
523527 pub const RESOURCE_NOT_FOUND : Self = Self ( -32002 ) ;
524528 pub const INVALID_REQUEST : Self = Self ( -32600 ) ;
@@ -568,6 +572,30 @@ impl ErrorData {
568572 pub fn header_mismatch ( message : impl Into < Cow < ' static , str > > , data : Option < Value > ) -> Self {
569573 Self :: new ( ErrorCode :: HEADER_MISMATCH , message, data)
570574 }
575+ /// Create an unsupported-protocol-version error.
576+ pub fn unsupported_protocol_version (
577+ requested : ProtocolVersion ,
578+ supported : & [ ProtocolVersion ] ,
579+ ) -> Self {
580+ Self :: new (
581+ ErrorCode :: UNSUPPORTED_PROTOCOL_VERSION ,
582+ "Unsupported protocol version" ,
583+ Some ( serde_json:: json!( {
584+ "requested" : requested,
585+ "supported" : supported,
586+ } ) ) ,
587+ )
588+ }
589+ /// Create a missing-required-capability error.
590+ pub fn missing_required_client_capability ( required : ClientCapabilities ) -> Self {
591+ Self :: new (
592+ ErrorCode :: MISSING_REQUIRED_CLIENT_CAPABILITY ,
593+ "Missing required client capability" ,
594+ Some ( serde_json:: json!( {
595+ "requiredCapabilities" : required,
596+ } ) ) ,
597+ )
598+ }
571599 pub fn parse_error ( message : impl Into < Cow < ' static , str > > , data : Option < Value > ) -> Self {
572600 Self :: new ( ErrorCode :: PARSE_ERROR , message, data)
573601 }
@@ -993,6 +1021,135 @@ impl InitializeResult {
9931021pub type ServerInfo = InitializeResult ;
9941022pub type ClientInfo = InitializeRequestParams ;
9951023
1024+ const_string ! ( DiscoverRequestMethod = "server/discover" ) ;
1025+
1026+ /// Parameters for [`DiscoverRequest`].
1027+ #[ derive( Debug , Serialize , Deserialize , Clone , Copy , PartialEq , Eq , Default ) ]
1028+ #[ serde( deny_unknown_fields) ]
1029+ #[ expect( clippy:: exhaustive_structs, reason = "intentionally exhaustive" ) ]
1030+ pub struct DiscoverRequestParams { }
1031+
1032+ #[ cfg( feature = "schemars" ) ]
1033+ #[ derive( schemars:: JsonSchema ) ]
1034+ #[ schemars( rename = "RequestMetaObject" ) ]
1035+ #[ expect( dead_code, reason = "schema-only representation of request metadata" ) ]
1036+ struct RequestMetaObjectSchema {
1037+ #[ schemars( default , rename = "progressToken" , with = "ProgressToken" ) ]
1038+ #[ serde( skip_serializing_if = "Option::is_none" ) ]
1039+ progress_token : Option < ProgressToken > ,
1040+ #[ schemars( rename = "io.modelcontextprotocol/protocolVersion" ) ]
1041+ protocol_version : ProtocolVersion ,
1042+ #[ schemars( rename = "io.modelcontextprotocol/clientInfo" ) ]
1043+ client_info : Implementation ,
1044+ #[ schemars( rename = "io.modelcontextprotocol/clientCapabilities" ) ]
1045+ client_capabilities : ClientCapabilities ,
1046+ #[ schemars(
1047+ default ,
1048+ rename = "io.modelcontextprotocol/logLevel" ,
1049+ with = "LoggingLevel"
1050+ ) ]
1051+ #[ serde( skip_serializing_if = "Option::is_none" ) ]
1052+ log_level : Option < LoggingLevel > ,
1053+ }
1054+
1055+ #[ cfg( feature = "schemars" ) ]
1056+ #[ derive( schemars:: JsonSchema ) ]
1057+ #[ expect( dead_code, reason = "schema-only representation of request parameters" ) ]
1058+ struct DiscoverRequestParamsSchema {
1059+ #[ schemars( rename = "_meta" ) ]
1060+ meta : RequestMetaObjectSchema ,
1061+ }
1062+
1063+ #[ cfg( feature = "schemars" ) ]
1064+ impl schemars:: JsonSchema for DiscoverRequestParams {
1065+ fn schema_name ( ) -> Cow < ' static , str > {
1066+ Cow :: Borrowed ( "DiscoverRequestParams" )
1067+ }
1068+
1069+ fn json_schema ( generator : & mut schemars:: SchemaGenerator ) -> schemars:: Schema {
1070+ DiscoverRequestParamsSchema :: json_schema ( generator)
1071+ }
1072+ }
1073+
1074+ /// A request for the server's supported protocol versions and capabilities.
1075+ pub type DiscoverRequest = Request < DiscoverRequestMethod , DiscoverRequestParams > ;
1076+
1077+ /// The server's response to a [`DiscoverRequest`].
1078+ #[ derive( Debug , Serialize , Deserialize , Clone , PartialEq ) ]
1079+ #[ serde( rename_all = "camelCase" ) ]
1080+ #[ cfg_attr( feature = "schemars" , derive( schemars:: JsonSchema ) ) ]
1081+ #[ non_exhaustive]
1082+ pub struct DiscoverResult {
1083+ /// Identifies how the result should be parsed.
1084+ pub result_type : ResultType ,
1085+ /// Protocol versions implemented by this server.
1086+ pub supported_versions : Vec < ProtocolVersion > ,
1087+ /// Capabilities provided by this server.
1088+ pub capabilities : ServerCapabilities ,
1089+ /// Information about the server implementation.
1090+ pub server_info : Implementation ,
1091+ /// Optional guidance for using the server.
1092+ #[ serde( skip_serializing_if = "Option::is_none" ) ]
1093+ pub instructions : Option < String > ,
1094+ /// How long clients may consider this response fresh, in milliseconds.
1095+ pub ttl_ms : u64 ,
1096+ /// Whether the cached result may be shared across authorization contexts.
1097+ pub cache_scope : CacheScope ,
1098+ /// Protocol-level response metadata.
1099+ #[ serde( rename = "_meta" , skip_serializing_if = "Option::is_none" ) ]
1100+ pub meta : Option < Meta > ,
1101+ }
1102+
1103+ impl DiscoverResult {
1104+ /// Create a non-cacheable private discovery result.
1105+ pub fn new (
1106+ supported_versions : Vec < ProtocolVersion > ,
1107+ capabilities : ServerCapabilities ,
1108+ server_info : Implementation ,
1109+ ) -> Self {
1110+ Self {
1111+ result_type : ResultType :: COMPLETE ,
1112+ supported_versions,
1113+ capabilities,
1114+ server_info,
1115+ instructions : None ,
1116+ ttl_ms : 0 ,
1117+ cache_scope : CacheScope :: Private ,
1118+ meta : None ,
1119+ }
1120+ }
1121+
1122+ /// Create a discovery result from the server's initialization information.
1123+ pub fn from_server_info (
1124+ supported_versions : Vec < ProtocolVersion > ,
1125+ server_info : ServerInfo ,
1126+ ) -> Self {
1127+ let ServerInfo {
1128+ capabilities,
1129+ server_info,
1130+ instructions,
1131+ meta,
1132+ ..
1133+ } = server_info;
1134+ let mut result = Self :: new ( supported_versions, capabilities, server_info) ;
1135+ result. instructions = instructions;
1136+ result. meta = meta;
1137+ result
1138+ }
1139+
1140+ /// Set the cache lifetime hint in milliseconds.
1141+ pub fn with_ttl_ms ( mut self , ttl_ms : u64 ) -> Self {
1142+ self . ttl_ms = ttl_ms;
1143+ self
1144+ }
1145+
1146+ /// Set the cache scope.
1147+ pub fn with_cache_scope ( mut self , cache_scope : CacheScope ) -> Self {
1148+ self . cache_scope = cache_scope;
1149+ self
1150+ }
1151+ }
1152+
9961153#[ allow( clippy:: derivable_impls) ]
9971154impl Default for ServerInfo {
9981155 fn default ( ) -> Self {
@@ -3788,6 +3945,7 @@ ts_union!(
37883945 export type ClientRequest =
37893946 | PingRequest
37903947 | InitializeRequest
3948+ | DiscoverRequest
37913949 | CompleteRequest
37923950 | SetLevelRequest
37933951 | GetPromptRequest
@@ -3811,6 +3969,7 @@ impl ClientRequest {
38113969 match & self {
38123970 ClientRequest :: PingRequest ( r) => r. method . as_str ( ) ,
38133971 ClientRequest :: InitializeRequest ( r) => r. method . as_str ( ) ,
3972+ ClientRequest :: DiscoverRequest ( r) => r. method . as_str ( ) ,
38143973 ClientRequest :: CompleteRequest ( r) => r. method . as_str ( ) ,
38153974 ClientRequest :: SetLevelRequest ( r) => r. method . as_str ( ) ,
38163975 ClientRequest :: GetPromptRequest ( r) => r. method . as_str ( ) ,
@@ -3882,6 +4041,7 @@ ts_union!(
38824041
38834042ts_union ! (
38844043 export type ServerResult =
4044+ | DiscoverResult
38854045 | InitializeResult
38864046 | CompleteResult
38874047 | GetPromptResult
0 commit comments