@@ -47,6 +47,34 @@ pub trait RequestParamsMeta {
4747 }
4848 }
4949 }
50+ /// Get the W3C `traceparent` value from meta, if present (SEP-414)
51+ fn traceparent ( & self ) -> Option < & str > {
52+ self . meta ( ) . and_then ( |m| m. get_traceparent ( ) )
53+ }
54+ /// Set the W3C `traceparent` value in meta (SEP-414)
55+ fn set_traceparent ( & mut self , value : & str ) {
56+ self . meta_or_default ( ) . set_traceparent ( value) ;
57+ }
58+ /// Get the W3C `tracestate` value from meta, if present (SEP-414)
59+ fn tracestate ( & self ) -> Option < & str > {
60+ self . meta ( ) . and_then ( |m| m. get_tracestate ( ) )
61+ }
62+ /// Set the W3C `tracestate` value in meta (SEP-414)
63+ fn set_tracestate ( & mut self , value : & str ) {
64+ self . meta_or_default ( ) . set_tracestate ( value) ;
65+ }
66+ /// Get the W3C `baggage` value from meta, if present (SEP-414)
67+ fn baggage ( & self ) -> Option < & str > {
68+ self . meta ( ) . and_then ( |m| m. get_baggage ( ) )
69+ }
70+ /// Set the W3C `baggage` value in meta (SEP-414)
71+ fn set_baggage ( & mut self , value : & str ) {
72+ self . meta_or_default ( ) . set_baggage ( value) ;
73+ }
74+ /// Get a mutable reference to meta, inserting an empty one if absent.
75+ fn meta_or_default ( & mut self ) -> & mut Meta {
76+ self . meta_mut ( ) . get_or_insert_with ( Meta :: new)
77+ }
5078}
5179
5280/// Trait for task-augmented request params that contain both `_meta` and `task` fields.
@@ -207,6 +235,12 @@ impl Meta {
207235 const META_KEY_CLIENT_INFO : & str = "io.modelcontextprotocol/clientInfo" ;
208236 const META_KEY_CLIENT_CAPABILITIES : & str = "io.modelcontextprotocol/clientCapabilities" ;
209237 const META_KEY_LOG_LEVEL : & str = "io.modelcontextprotocol/logLevel" ;
238+ /// Reserved `_meta` key for the W3C Trace Context `traceparent` value (SEP-414).
239+ const TRACEPARENT_FIELD : & str = "traceparent" ;
240+ /// Reserved `_meta` key for the W3C Trace Context `tracestate` value (SEP-414).
241+ const TRACESTATE_FIELD : & str = "tracestate" ;
242+ /// Reserved `_meta` key for the W3C Baggage value (SEP-414).
243+ const BAGGAGE_FIELD : & str = "baggage" ;
210244
211245 pub fn new ( ) -> Self {
212246 Self ( JsonObject :: new ( ) )
@@ -304,6 +338,58 @@ impl Meta {
304338 self . insert_serialized ( Self :: META_KEY_LOG_LEVEL , log_level) ;
305339 }
306340
341+ /// Read a string-valued `_meta` field, or `None` if absent or not a string.
342+ fn get_str ( & self , field : & str ) -> Option < & str > {
343+ self . 0 . get ( field) . and_then ( Value :: as_str)
344+ }
345+
346+ /// Write a string-valued `_meta` field.
347+ fn set_str ( & mut self , field : & str , value : impl Into < String > ) {
348+ self . 0
349+ . insert ( field. to_string ( ) , Value :: String ( value. into ( ) ) ) ;
350+ }
351+
352+ /// Get the W3C `traceparent` value (SEP-414), if present.
353+ pub fn get_traceparent ( & self ) -> Option < & str > {
354+ self . get_str ( Self :: TRACEPARENT_FIELD )
355+ }
356+
357+ /// Set the W3C `traceparent` value (SEP-414).
358+ ///
359+ /// ```
360+ /// use rmcp::model::Meta;
361+ ///
362+ /// let mut meta = Meta::new();
363+ /// meta.set_traceparent("00-0af7651916cd43dd8448eb211c80319c-00f067aa0ba902b7-01");
364+ /// assert_eq!(
365+ /// meta.get_traceparent(),
366+ /// Some("00-0af7651916cd43dd8448eb211c80319c-00f067aa0ba902b7-01"),
367+ /// );
368+ /// ```
369+ pub fn set_traceparent ( & mut self , value : impl Into < String > ) {
370+ self . set_str ( Self :: TRACEPARENT_FIELD , value) ;
371+ }
372+
373+ /// Get the W3C `tracestate` value (SEP-414), if present.
374+ pub fn get_tracestate ( & self ) -> Option < & str > {
375+ self . get_str ( Self :: TRACESTATE_FIELD )
376+ }
377+
378+ /// Set the W3C `tracestate` value (SEP-414).
379+ pub fn set_tracestate ( & mut self , value : impl Into < String > ) {
380+ self . set_str ( Self :: TRACESTATE_FIELD , value) ;
381+ }
382+
383+ /// Get the W3C `baggage` value (SEP-414), if present.
384+ pub fn get_baggage ( & self ) -> Option < & str > {
385+ self . get_str ( Self :: BAGGAGE_FIELD )
386+ }
387+
388+ /// Set the W3C `baggage` value (SEP-414).
389+ pub fn set_baggage ( & mut self , value : impl Into < String > ) {
390+ self . set_str ( Self :: BAGGAGE_FIELD , value) ;
391+ }
392+
307393 pub fn extend ( & mut self , other : Meta ) {
308394 for ( k, v) in other. 0 . into_iter ( ) {
309395 self . 0 . insert ( k, v) ;
@@ -361,3 +447,59 @@ where
361447 }
362448 }
363449}
450+
451+ #[ cfg( test) ]
452+ mod tests {
453+ use super :: * ;
454+
455+ #[ derive( Default ) ]
456+ struct Params {
457+ meta : Option < Meta > ,
458+ }
459+
460+ impl RequestParamsMeta for Params {
461+ fn meta ( & self ) -> Option < & Meta > {
462+ self . meta . as_ref ( )
463+ }
464+ fn meta_mut ( & mut self ) -> & mut Option < Meta > {
465+ & mut self . meta
466+ }
467+ }
468+
469+ const TRACEPARENT : & str = "00-0af7651916cd43dd8448eb211c80319c-00f067aa0ba902b7-01" ;
470+
471+ #[ test]
472+ fn trace_context_round_trip ( ) {
473+ let mut meta = Meta :: new ( ) ;
474+ meta. set_traceparent ( TRACEPARENT ) ;
475+ meta. set_tracestate ( "vendor1=value1,vendor2=value2" ) ;
476+ meta. set_baggage ( "userId=alice,region=us-east-1" ) ;
477+ assert_eq ! ( meta. get_traceparent( ) , Some ( TRACEPARENT ) ) ;
478+ assert_eq ! ( meta. get_tracestate( ) , Some ( "vendor1=value1,vendor2=value2" ) ) ;
479+ assert_eq ! ( meta. get_baggage( ) , Some ( "userId=alice,region=us-east-1" ) ) ;
480+ }
481+
482+ #[ test]
483+ fn absent_field_is_none ( ) {
484+ let meta = Meta :: new ( ) ;
485+ assert_eq ! ( meta. get_traceparent( ) , None ) ;
486+ assert_eq ! ( meta. get_tracestate( ) , None ) ;
487+ assert_eq ! ( meta. get_baggage( ) , None ) ;
488+ }
489+
490+ #[ test]
491+ fn non_string_value_is_none ( ) {
492+ let mut meta = Meta :: new ( ) ;
493+ meta. 0
494+ . insert ( Meta :: TRACEPARENT_FIELD . to_string ( ) , Value :: from ( 42 ) ) ;
495+ assert_eq ! ( meta. get_traceparent( ) , None ) ;
496+ }
497+
498+ #[ test]
499+ fn trait_setter_inserts_meta_when_absent ( ) {
500+ let mut params = Params :: default ( ) ;
501+ assert_eq ! ( params. traceparent( ) , None ) ;
502+ params. set_traceparent ( TRACEPARENT ) ;
503+ assert_eq ! ( params. traceparent( ) , Some ( TRACEPARENT ) ) ;
504+ }
505+ }
0 commit comments