@@ -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,126 @@ 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+ #[ expect( dead_code, reason = "schema-only representation of request metadata" ) ]
1035+ struct DiscoverRequestMetaSchema {
1036+ #[ schemars( rename = "io.modelcontextprotocol/protocolVersion" ) ]
1037+ protocol_version : ProtocolVersion ,
1038+ #[ schemars( rename = "io.modelcontextprotocol/clientInfo" ) ]
1039+ client_info : Implementation ,
1040+ #[ schemars( rename = "io.modelcontextprotocol/clientCapabilities" ) ]
1041+ client_capabilities : ClientCapabilities ,
1042+ #[ schemars( rename = "io.modelcontextprotocol/logLevel" ) ]
1043+ log_level : Option < LoggingLevel > ,
1044+ }
1045+
1046+ #[ cfg( feature = "schemars" ) ]
1047+ #[ derive( schemars:: JsonSchema ) ]
1048+ #[ expect( dead_code, reason = "schema-only representation of request parameters" ) ]
1049+ struct DiscoverRequestParamsSchema {
1050+ #[ schemars( rename = "_meta" ) ]
1051+ meta : DiscoverRequestMetaSchema ,
1052+ }
1053+
1054+ #[ cfg( feature = "schemars" ) ]
1055+ impl schemars:: JsonSchema for DiscoverRequestParams {
1056+ fn schema_name ( ) -> Cow < ' static , str > {
1057+ Cow :: Borrowed ( "DiscoverRequestParams" )
1058+ }
1059+
1060+ fn json_schema ( generator : & mut schemars:: SchemaGenerator ) -> schemars:: Schema {
1061+ DiscoverRequestParamsSchema :: json_schema ( generator)
1062+ }
1063+ }
1064+
1065+ /// A request for the server's supported protocol versions and capabilities.
1066+ pub type DiscoverRequest = Request < DiscoverRequestMethod , DiscoverRequestParams > ;
1067+
1068+ /// The server's response to a [`DiscoverRequest`].
1069+ #[ derive( Debug , Serialize , Deserialize , Clone , PartialEq ) ]
1070+ #[ serde( rename_all = "camelCase" ) ]
1071+ #[ cfg_attr( feature = "schemars" , derive( schemars:: JsonSchema ) ) ]
1072+ #[ non_exhaustive]
1073+ pub struct DiscoverResult {
1074+ /// Identifies how the result should be parsed.
1075+ pub result_type : ResultType ,
1076+ /// Protocol versions implemented by this server.
1077+ pub supported_versions : Vec < ProtocolVersion > ,
1078+ /// Capabilities provided by this server.
1079+ pub capabilities : ServerCapabilities ,
1080+ /// Information about the server implementation.
1081+ pub server_info : Implementation ,
1082+ /// Optional guidance for using the server.
1083+ #[ serde( skip_serializing_if = "Option::is_none" ) ]
1084+ pub instructions : Option < String > ,
1085+ /// How long clients may consider this response fresh, in milliseconds.
1086+ pub ttl_ms : u64 ,
1087+ /// Whether the cached result may be shared across authorization contexts.
1088+ pub cache_scope : CacheScope ,
1089+ /// Protocol-level response metadata.
1090+ #[ serde( rename = "_meta" , skip_serializing_if = "Option::is_none" ) ]
1091+ pub meta : Option < Meta > ,
1092+ }
1093+
1094+ impl DiscoverResult {
1095+ /// Create a non-cacheable private discovery result.
1096+ pub fn new (
1097+ supported_versions : Vec < ProtocolVersion > ,
1098+ capabilities : ServerCapabilities ,
1099+ server_info : Implementation ,
1100+ ) -> Self {
1101+ Self {
1102+ result_type : ResultType :: COMPLETE ,
1103+ supported_versions,
1104+ capabilities,
1105+ server_info,
1106+ instructions : None ,
1107+ ttl_ms : 0 ,
1108+ cache_scope : CacheScope :: Private ,
1109+ meta : None ,
1110+ }
1111+ }
1112+
1113+ /// Create a discovery result from the server's initialization information.
1114+ pub fn from_server_info (
1115+ supported_versions : Vec < ProtocolVersion > ,
1116+ server_info : ServerInfo ,
1117+ ) -> Self {
1118+ let ServerInfo {
1119+ capabilities,
1120+ server_info,
1121+ instructions,
1122+ meta,
1123+ ..
1124+ } = server_info;
1125+ let mut result = Self :: new ( supported_versions, capabilities, server_info) ;
1126+ result. instructions = instructions;
1127+ result. meta = meta;
1128+ result
1129+ }
1130+
1131+ /// Set the cache lifetime hint in milliseconds.
1132+ pub fn with_ttl_ms ( mut self , ttl_ms : u64 ) -> Self {
1133+ self . ttl_ms = ttl_ms;
1134+ self
1135+ }
1136+
1137+ /// Set the cache scope.
1138+ pub fn with_cache_scope ( mut self , cache_scope : CacheScope ) -> Self {
1139+ self . cache_scope = cache_scope;
1140+ self
1141+ }
1142+ }
1143+
9961144#[ allow( clippy:: derivable_impls) ]
9971145impl Default for ServerInfo {
9981146 fn default ( ) -> Self {
@@ -3788,6 +3936,7 @@ ts_union!(
37883936 export type ClientRequest =
37893937 | PingRequest
37903938 | InitializeRequest
3939+ | DiscoverRequest
37913940 | CompleteRequest
37923941 | SetLevelRequest
37933942 | GetPromptRequest
@@ -3811,6 +3960,7 @@ impl ClientRequest {
38113960 match & self {
38123961 ClientRequest :: PingRequest ( r) => r. method . as_str ( ) ,
38133962 ClientRequest :: InitializeRequest ( r) => r. method . as_str ( ) ,
3963+ ClientRequest :: DiscoverRequest ( r) => r. method . as_str ( ) ,
38143964 ClientRequest :: CompleteRequest ( r) => r. method . as_str ( ) ,
38153965 ClientRequest :: SetLevelRequest ( r) => r. method . as_str ( ) ,
38163966 ClientRequest :: GetPromptRequest ( r) => r. method . as_str ( ) ,
@@ -3882,6 +4032,7 @@ ts_union!(
38824032
38834033ts_union ! (
38844034 export type ServerResult =
4035+ | DiscoverResult
38854036 | InitializeResult
38864037 | CompleteResult
38874038 | GetPromptResult
0 commit comments