diff --git a/rust/bt-gatt/src/test_utils.rs b/rust/bt-gatt/src/test_utils.rs
index def7f62..ed05af5 100644
--- a/rust/bt-gatt/src/test_utils.rs
+++ b/rust/bt-gatt/src/test_utils.rs
@@ -6,10 +6,11 @@
 use futures::channel::mpsc::{unbounded, UnboundedReceiver, UnboundedSender};
 use futures::future::{ready, Ready};
 use futures::stream::{FusedStream, Stream};
+use futures::StreamExt;
 use parking_lot::Mutex;
 use std::collections::{HashMap, HashSet, VecDeque};
 use std::sync::Arc;
-use std::task::{Poll, Waker};
+use std::task::{Context, Poll, Waker};
 
 use bt_common::{PeerId, Uuid};
 
@@ -802,3 +803,94 @@
             .unwrap();
     }
 }
+
+/// Extension trait providing assertion helpers on a `FakeServerEvent` event
+/// stream.
+pub trait FakeServerEventsExt {
+    /// Polls the receiver and expects a single event to be ready, panicking if
+    /// none is ready.
+    fn expect_event(&mut self) -> FakeServerEvent;
+
+    /// Asserts that no event is currently pending on the receiver.
+    fn expect_no_event(&mut self);
+
+    /// Expects a `FakeServerEvent::Notified` event for `expected_handle`.
+    /// Returns the notification payload and the list of notified peers.
+    fn expect_notification(&mut self, expected_handle: Handle) -> (Vec<u8>, Vec<PeerId>);
+
+    /// Expects a `FakeServerEvent::WriteResponded` event for `expected_handle`.
+    /// Returns the result of the write response.
+    fn expect_write_response(&mut self, expected_handle: Handle) -> Result<()>;
+
+    /// Expects a `FakeServerEvent::ReadResponded` event for `expected_handle`.
+    /// Returns the result of the read response.
+    fn expect_read_response(&mut self, expected_handle: Handle) -> Result<Vec<u8>>;
+}
+
+impl FakeServerEventsExt for UnboundedReceiver<FakeServerEvent> {
+    #[track_caller]
+    fn expect_event(&mut self) -> FakeServerEvent {
+        let mut cx = Context::from_waker(futures::task::noop_waker_ref());
+        match self.poll_next_unpin(&mut cx) {
+            Poll::Ready(Some(event)) => event,
+            x => panic!("Expected fake server event, got {x:?}"),
+        }
+    }
+
+    #[track_caller]
+    fn expect_no_event(&mut self) {
+        let mut cx = Context::from_waker(futures::task::noop_waker_ref());
+        match self.poll_next_unpin(&mut cx) {
+            Poll::Pending => {}
+            Poll::Ready(other) => panic!("Expected no fake server event, got {other:?}"),
+        }
+    }
+
+    #[track_caller]
+    fn expect_notification(&mut self, expected_handle: Handle) -> (Vec<u8>, Vec<PeerId>) {
+        match self.expect_event() {
+            FakeServerEvent::Notified { handle, value, peers, .. } => {
+                assert_eq!(
+                    handle, expected_handle,
+                    "Expected notification for handle {expected_handle:?}, but got notification for handle {handle:?}"
+                );
+                (value, peers)
+            }
+            other => panic!(
+                "Expected FakeServerEvent::Notified for handle {expected_handle:?}, got {other:?}"
+            ),
+        }
+    }
+
+    #[track_caller]
+    fn expect_write_response(&mut self, expected_handle: Handle) -> Result<()> {
+        match self.expect_event() {
+            FakeServerEvent::WriteResponded { handle, value, .. } => {
+                assert_eq!(
+                    handle, expected_handle,
+                    "Expected write response for handle {expected_handle:?}, but got response for handle {handle:?}"
+                );
+                value
+            }
+            other => panic!(
+                "Expected FakeServerEvent::WriteResponded for handle {expected_handle:?}, got {other:?}"
+            ),
+        }
+    }
+
+    #[track_caller]
+    fn expect_read_response(&mut self, expected_handle: Handle) -> Result<Vec<u8>> {
+        match self.expect_event() {
+            FakeServerEvent::ReadResponded { handle, value, .. } => {
+                assert_eq!(
+                    handle, expected_handle,
+                    "Expected read response for handle {expected_handle:?}, but got response for handle {handle:?}"
+                );
+                value
+            }
+            other => panic!(
+                "Expected FakeServerEvent::ReadResponded for handle {expected_handle:?}, got {other:?}"
+            ),
+        }
+    }
+}
diff --git a/rust/bt-gatt/src/tests.rs b/rust/bt-gatt/src/tests.rs
index 9f0bbd7..2a263bd 100644
--- a/rust/bt-gatt/src/tests.rs
+++ b/rust/bt-gatt/src/tests.rs
@@ -433,3 +433,64 @@
     assert_eq!(Handle(1), handle);
     assert_eq!(&[0, 1, 2, 3, 4, 5], value.expect("should be ok").as_slice());
 }
+
+#[test]
+fn fake_server_events_ext_helpers() {
+    use server::{
+        LocalService, NotificationType, ReadResponder, Server, ServiceId, WriteResponder,
+    };
+    let mut noop_cx = futures::task::Context::from_waker(futures::task::noop_waker_ref());
+
+    let (server, mut events) = FakeServer::new();
+    events.expect_no_event();
+
+    let mut local_service_fut = server.prepare(example_service_definition());
+    let Poll::Ready(Ok(local_service)) = local_service_fut.poll_unpin(&mut noop_cx) else {
+        panic!("prepare failed");
+    };
+    let mut service_event_stream = local_service.publish();
+
+    // Published event
+    let FakeServerEvent::Published { id, .. } = events.expect_event() else {
+        panic!("expected published");
+    };
+    assert_eq!(id, ServiceId::new(1));
+    events.expect_no_event();
+
+    // Read response
+    server.incoming_read(PeerId(1), ServiceId::new(1), Handle(1), 0);
+    let Poll::Ready(Some(Ok(ServiceEvent::Read { responder, .. }))) =
+        service_event_stream.poll_next_unpin(&mut noop_cx)
+    else {
+        panic!("expected read");
+    };
+    responder.respond(&[10, 20, 30]);
+    let value = events.expect_read_response(Handle(1)).expect("read response ok");
+    assert_eq!(value, vec![10, 20, 30]);
+    events.expect_no_event();
+
+    // Write response
+    server.incoming_write(PeerId(1), ServiceId::new(1), Handle(2), 0, vec![1, 2]);
+    let Poll::Ready(Some(Ok(ServiceEvent::Write { responder, .. }))) =
+        service_event_stream.poll_next_unpin(&mut noop_cx)
+    else {
+        panic!("expected write");
+    };
+    responder.acknowledge();
+    events.expect_write_response(Handle(2)).expect("write response ok");
+    events.expect_no_event();
+
+    // Notification
+    server.incoming_client_configuration(
+        PeerId(1),
+        ServiceId::new(1),
+        Handle(3),
+        NotificationType::Notify,
+    );
+    let _ = service_event_stream.poll_next_unpin(&mut noop_cx);
+    local_service.notify(&Handle(3), &[42], &[]);
+    let (data, peers) = events.expect_notification(Handle(3));
+    assert_eq!(data, vec![42]);
+    assert_eq!(peers, vec![PeerId(1)]);
+    events.expect_no_event();
+}
diff --git a/rust/bt-mcs/src/error.rs b/rust/bt-mcs/src/error.rs
index d57a6f7..6565d15 100644
--- a/rust/bt-mcs/src/error.rs
+++ b/rust/bt-mcs/src/error.rs
@@ -4,11 +4,19 @@
 
 use thiserror::Error;
 
+use crate::types::PlayingOrder;
+
 #[derive(Debug, Error)]
 pub enum Error {
     #[error("Service is already published")]
     AlreadyPublished,
 
+    #[error("Feature not supported or configured on this server: {0}")]
+    FeatureNotSupported(&'static str),
+
+    #[error("Playing order {0:?} is not supported by this server")]
+    UnsupportedPlayingOrder(PlayingOrder),
+
     #[error("GATT operation error: {0}")]
     Gatt(#[from] bt_gatt::types::Error),
 
diff --git a/rust/bt-mcs/src/server.rs b/rust/bt-mcs/src/server.rs
index 658631c..98e6df0 100644
--- a/rust/bt-mcs/src/server.rs
+++ b/rust/bt-mcs/src/server.rs
@@ -285,18 +285,143 @@
         Ok(())
     }
 
-    #[cfg(test)]
-    pub(crate) fn set_media_state(&mut self, state: MediaState) {
-        self.state.set_media_state(state);
+    fn notify_track_changed(&mut self) {
+        self.local_service.notify(&TRACK_TITLE_HANDLE, self.state.track_title.as_bytes(), &[]);
+        self.local_service.notify(
+            &TRACK_DURATION_HANDLE,
+            &self.state.track_duration.to_notify_value(),
+            &[],
+        );
+        self.local_service.notify(
+            &TRACK_POSITION_HANDLE,
+            &self.state.track_position.to_notify_value(),
+            &[],
+        );
+        // Characteristic updates must precede Track Changed notification (MCS
+        // v1.0.1 Section 3.4.1).
+        self.local_service.notify(&TRACK_CHANGED_HANDLE, &[], &[]);
     }
 
-    #[cfg(test)]
-    pub(crate) fn set_supported_opcodes(&mut self, opcodes: SupportedOpcodes) {
-        self.state.set_supported_opcodes(opcodes);
+    fn notify_current_track_position(&mut self) {
+        let raw_pos = self.state.current_track_position().to_notify_value();
+        self.local_service.notify(&TRACK_POSITION_HANDLE, &raw_pos, &[]);
+    }
+
+    /// Sets the current track metadata and dispatches track update
+    /// notifications.
+    pub fn set_track(
+        &mut self,
+        title: impl Into<String>,
+        duration: TrackDuration,
+        position: TrackPosition,
+    ) {
+        self.state.set_track(title.into(), duration, position);
+        self.notify_track_changed();
+    }
+
+    /// Clears the current track metadata and dispatches track update
+    /// notifications.
+    pub fn clear_track(&mut self) {
+        self.state.clear_track();
+        self.notify_track_changed();
+    }
+
+    /// Sets the current playback state and dispatches state update
+    /// notifications.
+    pub fn set_media_state(&mut self, state: MediaState) {
+        if self.state.media_state == state {
+            return;
+        }
+        let previous_state = self.state.media_state;
+        self.state.set_media_state(state);
+        self.local_service.notify(&MEDIA_STATE_HANDLE, &[state.into()], &[]);
+        // Notify track position when paused from active playback or seeking,
+        // when entering seeking, or when transitioning to inactive (MCS
+        // v1.0.1 Section 3.7.1).
+        if (state == MediaState::Paused
+            && (previous_state == MediaState::Playing || previous_state == MediaState::Seeking))
+            || state == MediaState::Seeking
+            || (state == MediaState::Inactive && previous_state != MediaState::Inactive)
+        {
+            self.notify_current_track_position();
+        }
+    }
+
+    /// Sets the playback position within the current track and dispatches
+    /// position notifications.
+    pub fn set_track_position(&mut self, position: TrackPosition) {
+        self.state.set_track_position(position);
+        self.local_service.notify(
+            &TRACK_POSITION_HANDLE,
+            &self.state.track_position.to_notify_value(),
+            &[],
+        );
+    }
+
+    /// Sets the media player name and dispatches name update notifications.
+    pub fn set_player_name(&mut self, name: impl Into<String>) {
+        let name_str = name.into();
+        self.state.set_player_name(name_str.clone());
+        self.local_service.notify(&MEDIA_PLAYER_NAME_HANDLE, name_str.as_bytes(), &[]);
+    }
+
+    /// Sets the media player icon URL.
+    pub fn set_icon_url(&mut self, url: impl Into<String>) -> Result<(), Error> {
+        self.state.set_icon_url(url.into())
+    }
+
+    /// Sets the playback speed and dispatches speed update notifications.
+    pub fn set_playback_speed(&mut self, speed: PlaybackSpeed) -> Result<(), Error> {
+        self.state.set_playback_speed(speed)?;
+        self.local_service.notify(&PLAYBACK_SPEED_HANDLE, &[speed.into()], &[]);
+        // Notify track position when playback speed changes during active
+        // playback (MCS v1.0.1 Section 3.7.1).
+        if self.state.media_state == MediaState::Playing {
+            self.notify_current_track_position();
+        }
+        Ok(())
+    }
+
+    /// Sets the seeking speed and dispatches seeking speed update
+    /// notifications.
+    pub fn set_seeking_speed(&mut self, speed: SeekingSpeed) -> Result<(), Error> {
+        self.state.set_seeking_speed(speed)?;
+        self.local_service.notify(&SEEKING_SPEED_HANDLE, &[speed.into()], &[]);
+        // Notify track position if seeking speed is updated while seeking (MCS
+        // v1.0.1 Section 3.7.1, 3.9).
+        if self.state.media_state == MediaState::Seeking {
+            self.notify_current_track_position();
+        }
+        Ok(())
+    }
+
+    /// Sets the playing order and dispatches playing order update
+    /// notifications.
+    pub fn set_playing_order(&mut self, order: PlayingOrder) -> Result<(), Error> {
+        self.state.set_playing_order(order)?;
+        self.local_service.notify(&PLAYING_ORDER_HANDLE, &[order.into()], &[]);
+        Ok(())
+    }
+
+    /// Sets the supported media control opcodes and dispatches opcode update
+    /// notifications.
+    pub fn set_supported_opcodes(&mut self, opcodes: SupportedOpcodes) -> Result<(), Error> {
+        self.state.set_supported_opcodes(opcodes)?;
+        self.local_service.notify(
+            &MEDIA_CONTROL_POINT_OPCODES_SUPPORTED_HANDLE,
+            &opcodes.bits().to_le_bytes(),
+            &[],
+        );
+        Ok(())
     }
 }
 
 impl<'a, T: bt_gatt::ServerTypes> McsServerProj<'a, T> {
+    fn notify_current_track_position(&mut self) {
+        let raw_pos = self.state.current_track_position().to_notify_value();
+        self.local_service.notify(&TRACK_POSITION_HANDLE, &raw_pos, &[]);
+    }
+
     fn handle_read<R: ReadResponder>(&self, handle: Handle, offset: usize, responder: R) {
         match self.state.handle_read(handle, offset) {
             Ok(bytes) => responder.respond(&bytes),
@@ -470,17 +595,25 @@
                 self.state.set_track_position(position);
                 self.local_service.notify(
                     &TRACK_POSITION_HANDLE,
-                    &position.raw_10ms().to_le_bytes(),
+                    &self.state.track_position.to_notify_value(),
                     &[],
                 );
             }
             PendingWriteResponse::PlaybackSpeed(speed) => {
-                self.state.set_playback_speed(speed);
-                self.local_service.notify(&PLAYBACK_SPEED_HANDLE, &[speed.into()], &[]);
+                if self.state.set_playback_speed(speed).is_ok() {
+                    self.local_service.notify(&PLAYBACK_SPEED_HANDLE, &[speed.into()], &[]);
+                    // Notify track position when playback speed changes during
+                    // active playback (MCS v1.0.1 Section
+                    // 3.7.1).
+                    if self.state.media_state == MediaState::Playing {
+                        self.notify_current_track_position();
+                    }
+                }
             }
             PendingWriteResponse::PlayingOrder(order) => {
-                self.state.set_playing_order(order);
-                self.local_service.notify(&PLAYING_ORDER_HANDLE, &[order.into()], &[]);
+                if self.state.set_playing_order(order).is_ok() {
+                    self.local_service.notify(&PLAYING_ORDER_HANDLE, &[order.into()], &[]);
+                }
             }
         }
     }
@@ -544,7 +677,7 @@
     use super::*;
 
     use assert_matches::assert_matches;
-    use bt_gatt::test_utils::{FakeServer, FakeServerEvent, FakeTypes};
+    use bt_gatt::test_utils::{FakeServer, FakeServerEvent, FakeServerEventsExt, FakeTypes};
     use bt_gatt::Characteristic;
     use futures::{FutureExt, StreamExt};
 
@@ -808,25 +941,6 @@
         assert_matches!(poll_result, Poll::Ready(None));
     }
 
-    #[track_caller]
-    fn expect_service_event(
-        events: &mut futures::channel::mpsc::UnboundedReceiver<FakeServerEvent>,
-    ) -> FakeServerEvent {
-        let mut cx = Context::from_waker(futures::task::noop_waker_ref());
-        match events.poll_next_unpin(&mut cx) {
-            Poll::Ready(Some(event)) => event,
-            x => panic!("Expected fake server event, got {x:?}"),
-        }
-    }
-
-    #[track_caller]
-    fn expect_no_service_event(
-        events: &mut futures::channel::mpsc::UnboundedReceiver<FakeServerEvent>,
-    ) {
-        let mut cx = Context::from_waker(futures::task::noop_waker_ref());
-        assert_matches!(events.poll_next_unpin(&mut cx), Poll::Pending);
-    }
-
     fn setup_test_server(
         builder: McsServerBuilder,
     ) -> (
@@ -839,10 +953,7 @@
         let mut server: McsServer<FakeTypes> = builder.build().expect("server builds successfully");
         server.publish(fake_gatt_server.clone()).expect("publish succeeds");
         let _ = server.next().poll_unpin(&mut noop_cx);
-        assert!(matches!(
-            expect_service_event(&mut event_receiver),
-            FakeServerEvent::Published { .. }
-        ));
+        assert!(matches!(event_receiver.expect_event(), FakeServerEvent::Published { .. }));
         (server, fake_gatt_server, event_receiver)
     }
 
@@ -866,7 +977,7 @@
             bt_gatt::server::NotificationType::Notify,
         );
         let _ = server.next().poll_unpin(&mut noop_cx);
-        expect_no_service_event(&mut event_receiver);
+        event_receiver.expect_no_event();
         (server, fake_gatt_server, event_receiver, noop_cx)
     }
 
@@ -890,11 +1001,7 @@
             let poll_result = server.next().poll_unpin(&mut noop_cx);
             // Must NOT emit any McsServerEvent.
             assert_matches!(poll_result, Poll::Pending);
-            let bt_gatt::test_utils::FakeServerEvent::WriteResponded { value, .. } =
-                expect_service_event(&mut event_receiver)
-            else {
-                panic!("expected WriteResponded for handle {:?}", handle);
-            };
+            let value = event_receiver.expect_write_response(handle);
             assert_matches!(
                 value.unwrap_err(),
                 bt_gatt::types::Error::Gatt(GattError::InvalidHandle),
@@ -921,7 +1028,7 @@
             bt_gatt::server::NotificationType::Notify,
         );
         let _ = server.next().poll_unpin(&mut noop_cx);
-        expect_no_service_event(&mut event_receiver);
+        event_receiver.expect_no_event();
 
         fake_gatt_server.incoming_write(
             peer,
@@ -943,12 +1050,7 @@
         assert_eq!(peer_id, peer);
         assert_eq!(position, TrackPosition::from_raw_10ms(4200));
 
-        let FakeServerEvent::WriteResponded { value, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected WriteResponded");
-        };
-        assert!(value.is_ok());
+        event_receiver.expect_write_response(TRACK_POSITION_HANDLE).unwrap();
 
         // Upper layer confirms the set track position.
         responder.send(position);
@@ -957,24 +1059,15 @@
         // notification.
         let _ = server.next().poll_unpin(&mut noop_cx);
 
-        let FakeServerEvent::Notified { handle, value, peers, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected Notified");
-        };
-        assert_eq!(handle, TRACK_POSITION_HANDLE);
+        let (value, peers) = event_receiver.expect_notification(TRACK_POSITION_HANDLE);
         assert_eq!(peers, vec![peer]);
         assert_eq!(value, 4200i32.to_le_bytes().to_vec());
 
         // Subsequent read reflects the updated track position
         fake_gatt_server.incoming_read(peer, service_id, TRACK_POSITION_HANDLE, 0);
         let _ = server.next().poll_unpin(&mut noop_cx);
-        let FakeServerEvent::ReadResponded { value, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected ReadResponded");
-        };
-        assert_eq!(value.unwrap(), 4200i32.to_le_bytes());
+        let value = event_receiver.expect_read_response(TRACK_POSITION_HANDLE).unwrap();
+        assert_eq!(value, 4200i32.to_le_bytes());
     }
 
     #[test]
@@ -996,11 +1089,7 @@
         );
         let poll_result = server.next().poll_unpin(&mut noop_cx);
         assert_matches!(poll_result, Poll::Pending);
-        let FakeServerEvent::WriteResponded { value, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected WriteResponded");
-        };
+        let value = event_receiver.expect_write_response(TRACK_POSITION_HANDLE);
         assert_matches!(value.unwrap_err(), bt_gatt::types::Error::Gatt(GattError::InvalidOffset));
 
         // Invalid value length (3 bytes instead of 4)
@@ -1013,11 +1102,7 @@
         );
         let poll_result = server.next().poll_unpin(&mut noop_cx);
         assert_matches!(poll_result, Poll::Pending);
-        let FakeServerEvent::WriteResponded { value, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected WriteResponded");
-        };
+        let value = event_receiver.expect_write_response(TRACK_POSITION_HANDLE);
         assert_matches!(
             value.unwrap_err(),
             bt_gatt::types::Error::Gatt(GattError::InvalidAttributeValueLength)
@@ -1040,7 +1125,7 @@
             bt_gatt::server::NotificationType::Notify,
         );
         let _ = server.next().poll_unpin(&mut noop_cx);
-        expect_no_service_event(&mut event_receiver);
+        event_receiver.expect_no_event();
 
         fake_gatt_server.incoming_write(
             peer,
@@ -1059,35 +1144,21 @@
         assert_eq!(peer_id, peer);
         assert_eq!(speed, PlaybackSpeed::HALF);
 
-        let FakeServerEvent::WriteResponded { value, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected WriteResponded");
-        };
-        assert!(value.is_ok());
+        event_receiver.expect_write_response(PLAYBACK_SPEED_HANDLE).unwrap();
 
         // Upper layer confirms playback speed
         responder.send(speed);
         let _ = server.next().poll_unpin(&mut noop_cx);
 
-        let FakeServerEvent::Notified { handle, value, peers, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected Notified");
-        };
-        assert_eq!(handle, PLAYBACK_SPEED_HANDLE);
+        let (value, peers) = event_receiver.expect_notification(PLAYBACK_SPEED_HANDLE);
         assert_eq!(peers, vec![peer]);
         assert_eq!(value, vec![-64i8 as u8]);
 
         // Subsequent read reflects the updated playback speed
         fake_gatt_server.incoming_read(peer, service_id, PLAYBACK_SPEED_HANDLE, 0);
         let _ = server.next().poll_unpin(&mut noop_cx);
-        let FakeServerEvent::ReadResponded { value, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected ReadResponded");
-        };
-        assert_eq!(value.unwrap(), vec![-64i8 as u8]);
+        let value = event_receiver.expect_read_response(PLAYBACK_SPEED_HANDLE).unwrap();
+        assert_eq!(value, vec![-64i8 as u8]);
     }
 
     #[test]
@@ -1103,11 +1174,7 @@
         fake_gatt_server.incoming_write(peer, service_id, PLAYBACK_SPEED_HANDLE, 1, vec![0x00]);
         let poll_result = server.next().poll_unpin(&mut noop_cx);
         assert_matches!(poll_result, Poll::Pending);
-        let FakeServerEvent::WriteResponded { value, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected WriteResponded");
-        };
+        let value = event_receiver.expect_write_response(PLAYBACK_SPEED_HANDLE);
         assert_matches!(value.unwrap_err(), bt_gatt::types::Error::Gatt(GattError::InvalidOffset));
 
         // Invalid value length (2 bytes instead of 1)
@@ -1120,11 +1187,7 @@
         );
         let poll_result = server.next().poll_unpin(&mut noop_cx);
         assert_matches!(poll_result, Poll::Pending);
-        let FakeServerEvent::WriteResponded { value, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected WriteResponded");
-        };
+        let value = event_receiver.expect_write_response(PLAYBACK_SPEED_HANDLE);
         assert_matches!(
             value.unwrap_err(),
             bt_gatt::types::Error::Gatt(GattError::InvalidAttributeValueLength)
@@ -1149,7 +1212,7 @@
             bt_gatt::server::NotificationType::Notify,
         );
         let _ = server.next().poll_unpin(&mut noop_cx);
-        expect_no_service_event(&mut event_receiver);
+        event_receiver.expect_no_event();
 
         fake_gatt_server.incoming_write(
             peer,
@@ -1168,35 +1231,21 @@
         assert_eq!(peer_id, peer);
         assert_eq!(order, PlayingOrder::ShuffleOnce);
 
-        let FakeServerEvent::WriteResponded { value, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected WriteResponded");
-        };
-        assert!(value.is_ok());
+        event_receiver.expect_write_response(PLAYING_ORDER_HANDLE).unwrap();
 
         // Upper layer confirms playing order
         responder.send(order);
         let _ = server.next().poll_unpin(&mut noop_cx);
 
-        let FakeServerEvent::Notified { handle, value, peers, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected Notified");
-        };
-        assert_eq!(handle, PLAYING_ORDER_HANDLE);
+        let (value, peers) = event_receiver.expect_notification(PLAYING_ORDER_HANDLE);
         assert_eq!(peers, vec![peer]);
         assert_eq!(value, vec![PlayingOrder::ShuffleOnce.into()]);
 
         // Subsequent read reflects the updated playing order
         fake_gatt_server.incoming_read(peer, service_id, PLAYING_ORDER_HANDLE, 0);
         let _ = server.next().poll_unpin(&mut noop_cx);
-        let FakeServerEvent::ReadResponded { value, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected ReadResponded");
-        };
-        assert_eq!(value.unwrap(), vec![PlayingOrder::ShuffleOnce.into()]);
+        let value = event_receiver.expect_read_response(PLAYING_ORDER_HANDLE).unwrap();
+        assert_eq!(value, vec![PlayingOrder::ShuffleOnce.into()]);
     }
 
     #[test]
@@ -1223,22 +1272,13 @@
         let poll_result = server.next().poll_unpin(&mut noop_cx);
         assert_matches!(poll_result, Poll::Pending);
 
-        let FakeServerEvent::WriteResponded { value, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected WriteResponded");
-        };
-        assert!(value.is_ok());
+        event_receiver.expect_write_response(PLAYING_ORDER_HANDLE).unwrap();
 
         // Value remains unchanged (InOrderOnce)
         fake_gatt_server.incoming_read(peer, service_id, PLAYING_ORDER_HANDLE, 0);
         let _ = server.next().poll_unpin(&mut noop_cx);
-        let FakeServerEvent::ReadResponded { value, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected ReadResponded");
-        };
-        assert_eq!(value.unwrap(), vec![PlayingOrder::InOrderOnce.into()]);
+        let value = event_receiver.expect_read_response(PLAYING_ORDER_HANDLE).unwrap();
+        assert_eq!(value, vec![PlayingOrder::InOrderOnce.into()]);
     }
 
     #[test]
@@ -1267,11 +1307,7 @@
             fake_gatt_server.incoming_write(peer, service_id, handle, 0, value);
             let poll_result = server.next().poll_unpin(&mut noop_cx);
             assert_matches!(poll_result, Poll::Pending);
-            let FakeServerEvent::WriteResponded { value, .. } =
-                expect_service_event(&mut event_receiver)
-            else {
-                panic!("expected WriteResponded for handle {:?}", handle);
-            };
+            let value = event_receiver.expect_write_response(handle);
             assert_matches!(
                 value.unwrap_err(),
                 bt_gatt::types::Error::Gatt(GattError::WriteNotPermitted),
@@ -1301,21 +1337,11 @@
         assert_matches!(poll_result, Poll::Pending);
 
         // ATT write is acknowledged
-        let FakeServerEvent::WriteResponded { value, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected WriteResponded");
-        };
-        assert!(value.is_ok());
+        event_receiver.expect_write_response(MEDIA_CONTROL_POINT_HANDLE).unwrap();
 
         // Immediate Media Control Point Notification sent with
         // OPCODE_NOT_SUPPORTED (0x02)
-        let FakeServerEvent::Notified { handle, value, peers, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected Notified");
-        };
-        assert_eq!(handle, MEDIA_CONTROL_POINT_HANDLE);
+        let (value, peers) = event_receiver.expect_notification(MEDIA_CONTROL_POINT_HANDLE);
         assert_eq!(peers, vec![peer]);
         assert_eq!(value, vec![0xEE, ControlPointResultCode::OpcodeNotSupported.into()]);
     }
@@ -1340,21 +1366,11 @@
         assert_matches!(poll_result, Poll::Pending);
 
         // ATT write is acknowledged
-        let FakeServerEvent::WriteResponded { value, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected WriteResponded");
-        };
-        assert!(value.is_ok());
+        event_receiver.expect_write_response(MEDIA_CONTROL_POINT_HANDLE).unwrap();
 
         // Immediate Media Control Point Notification sent with
         // MEDIA_PLAYER_INACTIVE (0x03)
-        let FakeServerEvent::Notified { handle, value, peers, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected Notified");
-        };
-        assert_eq!(handle, MEDIA_CONTROL_POINT_HANDLE);
+        let (value, peers) = event_receiver.expect_notification(MEDIA_CONTROL_POINT_HANDLE);
         assert_eq!(peers, vec![peer]);
         assert_eq!(value, vec![0x01, ControlPointResultCode::MediaPlayerInactive.into()]);
     }
@@ -1366,6 +1382,8 @@
         let (mut server, fake_gatt_server, mut event_receiver, mut noop_cx) =
             setup_test_server_with_control_point(peer);
         server.set_media_state(MediaState::Playing);
+        let (val, _) = event_receiver.expect_notification(MEDIA_STATE_HANDLE);
+        assert_eq!(val, vec![MediaState::Playing.into()]);
 
         // Write Pause opcode (0x02)
         fake_gatt_server.incoming_write(
@@ -1385,12 +1403,7 @@
         assert_eq!(opcode, MediaControlOpcode::Pause);
 
         // ATT write is acknowledged
-        let FakeServerEvent::WriteResponded { value, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected WriteResponded");
-        };
-        assert!(value.is_ok());
+        event_receiver.expect_write_response(MEDIA_CONTROL_POINT_HANDLE).unwrap();
 
         // Upper layer executes command and responds with Success
         responder.send(ControlPointResultCode::Success);
@@ -1398,12 +1411,7 @@
         // Polling the server dispatches the notification
         let _ = server.next().poll_unpin(&mut noop_cx);
 
-        let FakeServerEvent::Notified { handle, value, peers, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected Notified");
-        };
-        assert_eq!(handle, MEDIA_CONTROL_POINT_HANDLE);
+        let (value, peers) = event_receiver.expect_notification(MEDIA_CONTROL_POINT_HANDLE);
         assert_eq!(peers, vec![peer]);
         assert_eq!(value, vec![0x02, ControlPointResultCode::Success.into()]);
     }
@@ -1415,6 +1423,8 @@
         let (mut server, fake_gatt_server, mut event_receiver, mut noop_cx) =
             setup_test_server_with_control_point(peer);
         server.set_media_state(MediaState::Playing);
+        let (val, _) = event_receiver.expect_notification(MEDIA_STATE_HANDLE);
+        assert_eq!(val, vec![MediaState::Playing.into()]);
 
         // MoveRelative opcode with 4-byte offset parameter
         let opcode = MediaControlOpcode::MoveRelative(1500);
@@ -1433,22 +1443,12 @@
         };
         assert_eq!(rx_opcode, opcode);
 
-        let FakeServerEvent::WriteResponded { value, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected WriteResponded");
-        };
-        assert!(value.is_ok());
+        event_receiver.expect_write_response(MEDIA_CONTROL_POINT_HANDLE).unwrap();
 
         responder.send(ControlPointResultCode::Success);
         let _ = server.next().poll_unpin(&mut noop_cx);
 
-        let FakeServerEvent::Notified { handle, value, peers, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected Notified");
-        };
-        assert_eq!(handle, MEDIA_CONTROL_POINT_HANDLE);
+        let (value, peers) = event_receiver.expect_notification(MEDIA_CONTROL_POINT_HANDLE);
         assert_eq!(peers, vec![peer]);
         assert_eq!(value, vec![opcode.raw_opcode(), ControlPointResultCode::Success.into()]);
     }
@@ -1460,6 +1460,8 @@
         let (mut server, fake_gatt_server, mut event_receiver, mut noop_cx) =
             setup_test_server_with_control_point(peer);
         server.set_media_state(MediaState::Playing);
+        let (val, _) = event_receiver.expect_notification(MEDIA_STATE_HANDLE);
+        assert_eq!(val, vec![MediaState::Playing.into()]);
 
         // MoveRelative requires 5 octets; provide only 2 octets
         let raw_op = MediaControlOpcode::MoveRelative(0).raw_opcode();
@@ -1474,19 +1476,9 @@
         let poll_result = server.next().poll_unpin(&mut noop_cx);
         assert_matches!(poll_result, Poll::Pending);
 
-        let FakeServerEvent::WriteResponded { value, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected WriteResponded");
-        };
-        assert!(value.is_ok());
+        event_receiver.expect_write_response(MEDIA_CONTROL_POINT_HANDLE).unwrap();
 
-        let FakeServerEvent::Notified { handle, value, peers, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected Notified");
-        };
-        assert_eq!(handle, MEDIA_CONTROL_POINT_HANDLE);
+        let (value, peers) = event_receiver.expect_notification(MEDIA_CONTROL_POINT_HANDLE);
         assert_eq!(peers, vec![peer]);
         assert_eq!(value, vec![raw_op, ControlPointResultCode::OpcodeNotSupported.into()]);
     }
@@ -1508,22 +1500,14 @@
         );
         let poll_result = server.next().poll_unpin(&mut noop_cx);
         assert_matches!(poll_result, Poll::Pending);
-        let FakeServerEvent::WriteResponded { value, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected WriteResponded");
-        };
+        let value = event_receiver.expect_write_response(MEDIA_CONTROL_POINT_HANDLE);
         assert_matches!(value.unwrap_err(), bt_gatt::types::Error::Gatt(GattError::InvalidOffset));
 
         // Empty value returns InvalidAttributeValueLength
         fake_gatt_server.incoming_write(peer, service_id, MEDIA_CONTROL_POINT_HANDLE, 0, vec![]);
         let poll_result = server.next().poll_unpin(&mut noop_cx);
         assert_matches!(poll_result, Poll::Pending);
-        let FakeServerEvent::WriteResponded { value, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected WriteResponded");
-        };
+        let value = event_receiver.expect_write_response(MEDIA_CONTROL_POINT_HANDLE);
         assert_matches!(
             value.unwrap_err(),
             bt_gatt::types::Error::Gatt(GattError::InvalidAttributeValueLength)
@@ -1537,7 +1521,15 @@
         let (mut server, fake_gatt_server, mut event_receiver, mut noop_cx) =
             setup_test_server_with_control_point(peer);
         server.set_media_state(MediaState::Playing);
-        server.set_supported_opcodes(SupportedOpcodes::PLAY);
+        let (val, _) = event_receiver.expect_notification(MEDIA_STATE_HANDLE);
+        assert_eq!(val, vec![MediaState::Playing.into()]);
+        server
+            .set_supported_opcodes(SupportedOpcodes::PLAY)
+            .expect("set_supported_opcodes succeeds");
+        let (val, peers) =
+            event_receiver.expect_notification(MEDIA_CONTROL_POINT_OPCODES_SUPPORTED_HANDLE);
+        assert_eq!(val, SupportedOpcodes::PLAY.bits().to_le_bytes().to_vec());
+        assert_eq!(peers, vec![peer]);
 
         // Pause is valid in spec, but not in supported_opcodes for this server
         // instance
@@ -1552,19 +1544,9 @@
         let poll_result = server.next().poll_unpin(&mut noop_cx);
         assert_matches!(poll_result, Poll::Pending);
 
-        let FakeServerEvent::WriteResponded { value, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected WriteResponded");
-        };
-        assert!(value.is_ok());
+        event_receiver.expect_write_response(MEDIA_CONTROL_POINT_HANDLE).unwrap();
 
-        let FakeServerEvent::Notified { handle, value, peers, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected Notified");
-        };
-        assert_eq!(handle, MEDIA_CONTROL_POINT_HANDLE);
+        let (value, peers) = event_receiver.expect_notification(MEDIA_CONTROL_POINT_HANDLE);
         assert_eq!(peers, vec![peer]);
         assert_eq!(
             value,
@@ -1582,6 +1564,8 @@
         let (mut server, fake_gatt_server, mut event_receiver, mut noop_cx) =
             setup_test_server_with_control_point(peer);
         server.set_media_state(MediaState::Playing);
+        let (val, _) = event_receiver.expect_notification(MEDIA_STATE_HANDLE);
+        assert_eq!(val, vec![MediaState::Playing.into()]);
 
         // Write Stop opcode (0x05)
         fake_gatt_server.incoming_write(
@@ -1601,12 +1585,7 @@
         assert_eq!(opcode, MediaControlOpcode::Stop);
 
         // ATT write is acknowledged
-        let FakeServerEvent::WriteResponded { value, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected WriteResponded");
-        };
-        assert!(value.is_ok());
+        event_receiver.expect_write_response(MEDIA_CONTROL_POINT_HANDLE).unwrap();
 
         // Responder is dropped without calling send
         drop(responder);
@@ -1614,12 +1593,7 @@
         // Polling the server dispatches the fallback notification
         let _ = server.next().poll_unpin(&mut noop_cx);
 
-        let FakeServerEvent::Notified { handle, value, peers, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected Notified");
-        };
-        assert_eq!(handle, MEDIA_CONTROL_POINT_HANDLE);
+        let (value, peers) = event_receiver.expect_notification(MEDIA_CONTROL_POINT_HANDLE);
         assert_eq!(peers, vec![peer]);
         assert_eq!(value, vec![0x05, ControlPointResultCode::CommandCannotBeCompleted.into()]);
     }
@@ -1632,6 +1606,8 @@
         let (mut server, fake_gatt_server, mut event_receiver, mut noop_cx) =
             setup_test_server_with_control_point(peer1);
         server.set_media_state(MediaState::Playing);
+        let (val, _) = event_receiver.expect_notification(MEDIA_STATE_HANDLE);
+        assert_eq!(val, vec![MediaState::Playing.into()]);
 
         // Also configure notifications for peer2
         fake_gatt_server.incoming_client_configuration(
@@ -1641,7 +1617,7 @@
             bt_gatt::server::NotificationType::Notify,
         );
         let _ = server.next().poll_unpin(&mut noop_cx);
-        expect_no_service_event(&mut event_receiver);
+        event_receiver.expect_no_event();
 
         // Issue 1st command (Play from peer1)
         fake_gatt_server.incoming_write(
@@ -1682,19 +1658,8 @@
         assert_eq!(op2, MediaControlOpcode::NextTrack);
 
         // Drain write acknowledgements
-        let FakeServerEvent::WriteResponded { value: val1, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected 1st WriteResponded");
-        };
-        assert!(val1.is_ok());
-
-        let FakeServerEvent::WriteResponded { value: val2, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected 2nd WriteResponded");
-        };
-        assert!(val2.is_ok());
+        event_receiver.expect_write_response(MEDIA_CONTROL_POINT_HANDLE).unwrap();
+        event_receiver.expect_write_response(MEDIA_CONTROL_POINT_HANDLE).unwrap();
 
         // Respond to both commands in a row before polling the stream
         resp1.send(ControlPointResultCode::Success);
@@ -1706,17 +1671,10 @@
         let poll_result = server.next().poll_unpin(&mut noop_cx);
         assert_matches!(poll_result, Poll::Pending);
 
-        let n1 = expect_service_event(&mut event_receiver);
-        let n2 = expect_service_event(&mut event_receiver);
+        let (val1, peers1) = event_receiver.expect_notification(MEDIA_CONTROL_POINT_HANDLE);
+        let (val2, peers2) = event_receiver.expect_notification(MEDIA_CONTROL_POINT_HANDLE);
 
-        let mut received = Vec::new();
-        for event in [n1, n2] {
-            let FakeServerEvent::Notified { handle, value, peers, .. } = event else {
-                panic!("expected Notified event, got {event:?}");
-            };
-            assert_eq!(handle, MEDIA_CONTROL_POINT_HANDLE);
-            received.push((peers, value));
-        }
+        let received = vec![(peers1, val1), (peers2, val2)];
 
         assert!(received.contains(&(
             vec![peer1],
@@ -1731,7 +1689,7 @@
         )));
 
         // No further events pending
-        expect_no_service_event(&mut event_receiver);
+        event_receiver.expect_no_event();
     }
 
     #[test]
@@ -1741,6 +1699,8 @@
         let (mut server, fake_gatt_server, mut event_receiver, mut noop_cx) =
             setup_test_server_with_control_point(peer);
         server.set_media_state(MediaState::Playing);
+        let (val, _) = event_receiver.expect_notification(MEDIA_STATE_HANDLE);
+        assert_eq!(val, vec![MediaState::Playing.into()]);
 
         // Write Pause opcode (0x02)
         fake_gatt_server.incoming_write(
@@ -1760,12 +1720,7 @@
         assert_eq!(opcode, MediaControlOpcode::Pause);
 
         // ATT write is acknowledged
-        let FakeServerEvent::WriteResponded { value, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected WriteResponded");
-        };
-        assert!(value.is_ok());
+        event_receiver.expect_write_response(MEDIA_CONTROL_POINT_HANDLE).unwrap();
 
         // Replace local_service events stream with a custom channel and close
         // it.
@@ -1792,12 +1747,7 @@
         let poll_result = server.next().poll_unpin(&mut noop_cx);
         assert_matches!(poll_result, Poll::Ready(None));
 
-        let FakeServerEvent::Notified { handle, value, peers, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected Notified");
-        };
-        assert_eq!(handle, MEDIA_CONTROL_POINT_HANDLE);
+        let (value, peers) = event_receiver.expect_notification(MEDIA_CONTROL_POINT_HANDLE);
         assert_eq!(peers, vec![peer]);
         assert_eq!(value, vec![0x02, ControlPointResultCode::Success.into()]);
     }
@@ -1807,6 +1757,7 @@
         let (mut server, fake_gatt_server, mut event_receiver) =
             setup_test_server(McsServerBuilder::generic(0x42, "Test Player"));
         server.state.media_state = MediaState::Paused;
+        server.state.track_duration = TrackDuration::from_raw_10ms(3000); // 30s
         let mut noop_cx = Context::from_waker(futures::task::noop_waker_ref());
 
         let peer = PeerId(1);
@@ -1819,7 +1770,7 @@
             bt_gatt::server::NotificationType::Notify,
         );
         let _ = server.next().poll_unpin(&mut noop_cx);
-        expect_no_service_event(&mut event_receiver);
+        event_receiver.expect_no_event();
 
         // Negative value represents offset from end of track per MCS v1.0.1
         // Section 3.7.1
@@ -1843,35 +1794,26 @@
         assert_eq!(peer_id, peer);
         assert_eq!(position, TrackPosition::from_raw_10ms(-500));
 
-        let FakeServerEvent::WriteResponded { value, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected WriteResponded");
-        };
-        assert!(value.is_ok());
+        assert_matches!(event_receiver.expect_write_response(TRACK_POSITION_HANDLE), Ok(()));
 
         // Upper layer confirms the updated track position
         responder.send(position);
         let _ = server.next().poll_unpin(&mut noop_cx);
 
-        let FakeServerEvent::Notified { handle, value, peers, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected Notified");
-        };
-        assert_eq!(handle, TRACK_POSITION_HANDLE);
+        let (value, peers) = event_receiver.expect_notification(TRACK_POSITION_HANDLE);
         assert_eq!(peers, vec![peer]);
-        assert_eq!(value, (-500i32).to_le_bytes().to_vec());
+        // MCS Section 3.7.1: The characteristic value shall be set to the
+        // offset from the start of the track to the new playing
+        // position (3000 - 500 = 2500).
+        assert_eq!(value, (2500i32).to_le_bytes().to_vec());
 
         // Subsequent read reflects the updated track position
         fake_gatt_server.incoming_read(peer, service_id, TRACK_POSITION_HANDLE, 0);
         let _ = server.next().poll_unpin(&mut noop_cx);
-        let FakeServerEvent::ReadResponded { value, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected ReadResponded");
-        };
-        assert_eq!(value.unwrap(), (-500i32).to_le_bytes());
+        let value = event_receiver
+            .expect_read_response(TRACK_POSITION_HANDLE)
+            .expect("read response succeeds");
+        assert_eq!(value, (2500i32).to_le_bytes());
     }
 
     #[test]
@@ -1894,29 +1836,22 @@
             panic!("expected SetPlaybackSpeed event, got {poll_result:?}");
         };
         // ATT write is acknowledged
-        let FakeServerEvent::WriteResponded { value, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected WriteResponded");
-        };
-        assert!(value.is_ok());
+        assert_matches!(event_receiver.expect_write_response(PLAYBACK_SPEED_HANDLE), Ok(()));
 
         // Drop responder without calling send
         drop(responder);
         let poll_result = server.next().poll_unpin(&mut noop_cx);
         assert_matches!(poll_result, Poll::Pending);
         // No notification should be emitted
-        expect_no_service_event(&mut event_receiver);
+        event_receiver.expect_no_event();
 
         // Playback speed remains unchanged
         fake_gatt_server.incoming_read(peer, service_id, PLAYBACK_SPEED_HANDLE, 0);
         let _ = server.next().poll_unpin(&mut noop_cx);
-        let FakeServerEvent::ReadResponded { value, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected ReadResponded");
-        };
-        assert_eq!(value.unwrap(), vec![PlaybackSpeed::NORMAL.into()]);
+        let value = event_receiver
+            .expect_read_response(PLAYBACK_SPEED_HANDLE)
+            .expect("read response succeeds");
+        assert_eq!(value, vec![PlaybackSpeed::NORMAL.into()]);
 
         // 2. Track position write
         fake_gatt_server.incoming_write(
@@ -1931,27 +1866,20 @@
         else {
             panic!("expected SetTrackPosition event, got {poll_result:?}");
         };
-        let FakeServerEvent::WriteResponded { value, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected WriteResponded");
-        };
-        assert!(value.is_ok());
+        assert_matches!(event_receiver.expect_write_response(TRACK_POSITION_HANDLE), Ok(()));
 
         drop(responder);
         let poll_result = server.next().poll_unpin(&mut noop_cx);
         assert_matches!(poll_result, Poll::Pending);
-        expect_no_service_event(&mut event_receiver);
+        event_receiver.expect_no_event();
 
         // Track position remains unavailable
         fake_gatt_server.incoming_read(peer, service_id, TRACK_POSITION_HANDLE, 0);
         let _ = server.next().poll_unpin(&mut noop_cx);
-        let FakeServerEvent::ReadResponded { value, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected ReadResponded");
-        };
-        assert_eq!(value.unwrap(), TrackPosition::Unavailable.raw_10ms().to_le_bytes());
+        let value = event_receiver
+            .expect_read_response(TRACK_POSITION_HANDLE)
+            .expect("read response succeeds");
+        assert_eq!(value, TrackPosition::Unavailable.raw_10ms().to_le_bytes());
 
         // 3. Playing order write
         fake_gatt_server.incoming_write(
@@ -1966,27 +1894,20 @@
         else {
             panic!("expected SetPlayingOrder event, got {poll_result:?}");
         };
-        let FakeServerEvent::WriteResponded { value, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected WriteResponded");
-        };
-        assert!(value.is_ok());
+        assert_matches!(event_receiver.expect_write_response(PLAYING_ORDER_HANDLE), Ok(()));
 
         drop(responder);
         let poll_result = server.next().poll_unpin(&mut noop_cx);
         assert_matches!(poll_result, Poll::Pending);
-        expect_no_service_event(&mut event_receiver);
+        event_receiver.expect_no_event();
 
         // Playing order remains default InOrderOnce
         fake_gatt_server.incoming_read(peer, service_id, PLAYING_ORDER_HANDLE, 0);
         let _ = server.next().poll_unpin(&mut noop_cx);
-        let FakeServerEvent::ReadResponded { value, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected ReadResponded");
-        };
-        assert_eq!(value.unwrap(), vec![PlayingOrder::InOrderOnce.into()]);
+        let value = event_receiver
+            .expect_read_response(PLAYING_ORDER_HANDLE)
+            .expect("read response succeeds");
+        assert_eq!(value, vec![PlayingOrder::InOrderOnce.into()]);
     }
 
     #[test]
@@ -2006,21 +1927,393 @@
         let poll_result = server.next().poll_unpin(&mut noop_cx);
         assert_matches!(poll_result, Poll::Pending);
 
-        let FakeServerEvent::WriteResponded { value, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected WriteResponded");
-        };
-        assert!(value.is_ok());
+        assert_matches!(event_receiver.expect_write_response(PLAYING_ORDER_HANDLE), Ok(()));
 
         // Value remains unchanged (default InOrderOnce)
         fake_gatt_server.incoming_read(peer, service_id, PLAYING_ORDER_HANDLE, 0);
         let _ = server.next().poll_unpin(&mut noop_cx);
-        let FakeServerEvent::ReadResponded { value, .. } =
-            expect_service_event(&mut event_receiver)
+        let value = event_receiver
+            .expect_read_response(PLAYING_ORDER_HANDLE)
+            .expect("read response succeeds");
+        assert_eq!(value, vec![PlayingOrder::InOrderOnce.into()]);
+    }
+
+    #[test]
+    fn pending_write_response_rejected_by_state_does_not_notify() {
+        let (mut server, fake_gatt_server, mut event_receiver) = setup_test_server(
+            McsServerBuilder::generic(0x42, "Test Player")
+                .with_playing_orders(SupportedPlayingOrders::SINGLE_ONCE),
+        );
+        let mut noop_cx = Context::from_waker(futures::task::noop_waker_ref());
+
+        let peer = PeerId(1);
+        let service_id = ServiceId::new(0x42);
+
+        fake_gatt_server.incoming_client_configuration(
+            peer,
+            service_id,
+            PLAYING_ORDER_HANDLE,
+            bt_gatt::server::NotificationType::Notify,
+        );
+        let _ = server.next().poll_unpin(&mut noop_cx);
+        event_receiver.expect_no_event();
+
+        fake_gatt_server.incoming_write(
+            peer,
+            service_id,
+            PLAYING_ORDER_HANDLE,
+            0,
+            vec![PlayingOrder::SingleOnce.into()],
+        );
+        let poll_result = server.next().poll_unpin(&mut noop_cx);
+        let Poll::Ready(Some(Ok(McsServerEvent::SetPlayingOrder { responder, .. }))) = poll_result
         else {
-            panic!("expected ReadResponded");
+            panic!("expected SetPlayingOrder event, got {poll_result:?}");
         };
-        assert_eq!(value.unwrap(), vec![PlayingOrder::InOrderOnce.into()]);
+        assert_matches!(event_receiver.expect_write_response(PLAYING_ORDER_HANDLE), Ok(()));
+
+        // Upper layer attempts to set an unsupported playing order.
+        responder.send(PlayingOrder::ShuffleOnce);
+        let poll_result = server.next().poll_unpin(&mut noop_cx);
+        assert_matches!(poll_result, Poll::Pending);
+        // State rejected the update, so no notification should be emitted.
+        event_receiver.expect_no_event();
+
+        fake_gatt_server.incoming_read(peer, service_id, PLAYING_ORDER_HANDLE, 0);
+        let _ = server.next().poll_unpin(&mut noop_cx);
+        let value = event_receiver
+            .expect_read_response(PLAYING_ORDER_HANDLE)
+            .expect("read response succeeds");
+        assert_eq!(value, vec![PlayingOrder::InOrderOnce.into()]);
+    }
+
+    #[test]
+    fn public_api_set_and_clear_track() {
+        let (mut server, fake_gatt_server, mut event_receiver) =
+            setup_test_server(McsServerBuilder::generic(0x42, "Test Player"));
+        let mut noop_cx = Context::from_waker(futures::task::noop_waker_ref());
+
+        let peer = PeerId(1);
+        let service_id = ServiceId::new(0x42);
+
+        for handle in
+            [TRACK_CHANGED_HANDLE, TRACK_TITLE_HANDLE, TRACK_DURATION_HANDLE, TRACK_POSITION_HANDLE]
+        {
+            fake_gatt_server.incoming_client_configuration(
+                peer,
+                service_id,
+                handle,
+                bt_gatt::server::NotificationType::Notify,
+            );
+            let _ = server.next().poll_unpin(&mut noop_cx);
+            event_receiver.expect_no_event();
+        }
+
+        // Set track
+        server.set_track(
+            "Song Title",
+            TrackDuration::from_raw_10ms(3000),
+            TrackPosition::from_raw_10ms(0),
+        );
+
+        // Verify notifications per MCS Section 3.4.1 / 3.7.1
+        let (val, _) = event_receiver.expect_notification(TRACK_TITLE_HANDLE);
+        assert_eq!(val, b"Song Title");
+        let (val, _) = event_receiver.expect_notification(TRACK_DURATION_HANDLE);
+        assert_eq!(val, 3000i32.to_le_bytes());
+        let (val, _) = event_receiver.expect_notification(TRACK_POSITION_HANDLE);
+        assert_eq!(val, 0i32.to_le_bytes());
+        let (val, _) = event_receiver.expect_notification(TRACK_CHANGED_HANDLE);
+        assert_eq!(val, vec![]);
+        event_receiver.expect_no_event();
+
+        // Clear track
+        server.clear_track();
+
+        let (val, _) = event_receiver.expect_notification(TRACK_TITLE_HANDLE);
+        assert_eq!(val, vec![]);
+        let (val, _) = event_receiver.expect_notification(TRACK_DURATION_HANDLE);
+        assert_eq!(val, TrackDuration::Unknown.raw_10ms().to_le_bytes());
+        let (val, _) = event_receiver.expect_notification(TRACK_POSITION_HANDLE);
+        assert_eq!(val, TrackPosition::Unavailable.raw_10ms().to_le_bytes());
+        let (val, _) = event_receiver.expect_notification(TRACK_CHANGED_HANDLE);
+        assert_eq!(val, vec![]);
+        event_receiver.expect_no_event();
+    }
+
+    #[test]
+    fn public_api_set_media_state_and_track_position() {
+        let (mut server, fake_gatt_server, mut event_receiver) =
+            setup_test_server(McsServerBuilder::generic(0x42, "Test Player"));
+        let mut noop_cx = Context::from_waker(futures::task::noop_waker_ref());
+
+        let peer = PeerId(1);
+        let service_id = ServiceId::new(0x42);
+
+        for handle in [MEDIA_STATE_HANDLE, TRACK_POSITION_HANDLE] {
+            fake_gatt_server.incoming_client_configuration(
+                peer,
+                service_id,
+                handle,
+                bt_gatt::server::NotificationType::Notify,
+            );
+            let _ = server.next().poll_unpin(&mut noop_cx);
+            event_receiver.expect_no_event();
+        }
+
+        server.set_media_state(MediaState::Playing);
+        let (value, _) = event_receiver.expect_notification(MEDIA_STATE_HANDLE);
+        assert_eq!(value, vec![MediaState::Playing.into()]);
+
+        server.set_track_position(TrackPosition::from_raw_10ms(1500));
+        let (value, _) = event_receiver.expect_notification(TRACK_POSITION_HANDLE);
+        assert_eq!(value, 1500i32.to_le_bytes().to_vec());
+
+        // Pausing from Playing emits both MediaState and TrackPosition
+        // notifications per MCS §3.7.1
+        server.set_media_state(MediaState::Paused);
+        let (value, _) = event_receiver.expect_notification(MEDIA_STATE_HANDLE);
+        assert_eq!(value, vec![MediaState::Paused.into()]);
+
+        let _ = event_receiver.expect_notification(TRACK_POSITION_HANDLE);
+
+        // Setting same MediaState is a no-op and produces no notifications per
+        // MCS v1.0.1 Section 3.17.1.
+        server.set_media_state(MediaState::Paused);
+        event_receiver.expect_no_event();
+
+        // Transitioning to Inactive emits MediaState and
+        // TrackPosition::Unavailable per MCS Section 3.7.1.
+        server.set_media_state(MediaState::Inactive);
+        let (value, _) = event_receiver.expect_notification(MEDIA_STATE_HANDLE);
+        assert_eq!(value, vec![MediaState::Inactive.into()]);
+
+        let (value, _) = event_receiver.expect_notification(TRACK_POSITION_HANDLE);
+        assert_eq!(value, TrackPosition::Unavailable.raw_10ms().to_le_bytes().to_vec());
+
+        // Repeated transition to Inactive produces no notifications.
+        server.set_media_state(MediaState::Inactive);
+        event_receiver.expect_no_event();
+
+        // Transition back to Paused with a track to test FromEnd position
+        // resolving (MCS Section 3.7.1).
+        server.set_media_state(MediaState::Paused);
+        let (value, _) = event_receiver.expect_notification(MEDIA_STATE_HANDLE);
+        assert_eq!(value, vec![MediaState::Paused.into()]);
+
+        server.set_track(
+            "Track",
+            TrackDuration::from_raw_10ms(3000),
+            TrackPosition::from_raw_10ms(0),
+        );
+        let _ = event_receiver.expect_notification(TRACK_TITLE_HANDLE);
+        let _ = event_receiver.expect_notification(TRACK_DURATION_HANDLE);
+        let _ = event_receiver.expect_notification(TRACK_POSITION_HANDLE);
+        let _ = event_receiver.expect_notification(TRACK_CHANGED_HANDLE);
+
+        server.set_track_position(TrackPosition::from_end(std::time::Duration::from_millis(5000)));
+        let (value, _) = event_receiver.expect_notification(TRACK_POSITION_HANDLE);
+        // Duration is 3000 (30.0s), 5.0s from end is 25.0s = 2500 raw units,
+        // not -500.
+        assert_eq!(value, 2500i32.to_le_bytes().to_vec());
+    }
+
+    #[test]
+    fn public_api_media_identity() {
+        let (mut server, fake_gatt_server, mut event_receiver) = setup_test_server(
+            McsServerBuilder::generic(0x42, "Old Name")
+                .with_icon_url("https://example.com/old.png"),
+        );
+        let mut noop_cx = Context::from_waker(futures::task::noop_waker_ref());
+
+        let peer = PeerId(1);
+        let service_id = ServiceId::new(0x42);
+
+        fake_gatt_server.incoming_client_configuration(
+            peer,
+            service_id,
+            MEDIA_PLAYER_NAME_HANDLE,
+            bt_gatt::server::NotificationType::Notify,
+        );
+        let _ = server.next().poll_unpin(&mut noop_cx);
+        event_receiver.expect_no_event();
+
+        server.set_player_name("New Name");
+        let (value, _) = event_receiver.expect_notification(MEDIA_PLAYER_NAME_HANDLE);
+        assert_eq!(value, b"New Name");
+
+        server.set_icon_url("https://example.com/new.png").expect("set_icon_url succeeds");
+        // Icon URL is Read-only, so verify value via GATT read response
+        fake_gatt_server.incoming_read(peer, service_id, MEDIA_PLAYER_ICON_URL_HANDLE, 0);
+        let _ = server.next().poll_unpin(&mut noop_cx);
+        let value = event_receiver
+            .expect_read_response(MEDIA_PLAYER_ICON_URL_HANDLE)
+            .expect("read response succeeds");
+        assert_eq!(value, b"https://example.com/new.png");
+
+        // Test server without icon URL returns FeatureNotSupported
+        let (mut server_no_icon, _, _) =
+            setup_test_server(McsServerBuilder::generic(0x43, "Player"));
+        assert_matches!(
+            server_no_icon.set_icon_url("https://example.com"),
+            Err(Error::FeatureNotSupported("icon_url"))
+        );
+    }
+
+    #[test]
+    fn public_api_playback_speed_and_seeking_speed() {
+        let (mut server, fake_gatt_server, mut event_receiver) =
+            setup_test_server(McsServerBuilder::generic(0x42, "Test Player").with_player_speeds());
+        let mut noop_cx = Context::from_waker(futures::task::noop_waker_ref());
+
+        let peer = PeerId(1);
+        let service_id = ServiceId::new(0x42);
+
+        for handle in
+            [MEDIA_STATE_HANDLE, TRACK_POSITION_HANDLE, PLAYBACK_SPEED_HANDLE, SEEKING_SPEED_HANDLE]
+        {
+            fake_gatt_server.incoming_client_configuration(
+                peer,
+                service_id,
+                handle,
+                bt_gatt::server::NotificationType::Notify,
+            );
+            let _ = server.next().poll_unpin(&mut noop_cx);
+            event_receiver.expect_no_event();
+        }
+
+        server.set_playback_speed(PlaybackSpeed::DOUBLE).expect("set_playback_speed succeeds");
+        let (value, _) = event_receiver.expect_notification(PLAYBACK_SPEED_HANDLE);
+        assert_eq!(value, vec![PlaybackSpeed::DOUBLE.into()]);
+
+        // During active playback, setting playback speed emits both
+        // PlaybackSpeed and TrackPosition notifications (MCS v1.0.1
+        // Section 3.7.1).
+        server.set_media_state(MediaState::Playing);
+        let (value, _) = event_receiver.expect_notification(MEDIA_STATE_HANDLE);
+        assert_eq!(value, vec![MediaState::Playing.into()]);
+        server.set_playback_speed(PlaybackSpeed::HALF).expect("set_playback_speed succeeds");
+        let (value, _) = event_receiver.expect_notification(PLAYBACK_SPEED_HANDLE);
+        assert_eq!(value, vec![PlaybackSpeed::HALF.into()]);
+
+        let _ = event_receiver.expect_notification(TRACK_POSITION_HANDLE);
+
+        // Transition to Seeking emits MediaState and TrackPosition
+        // notifications
+        server.set_media_state(MediaState::Seeking);
+        let (value, _) = event_receiver.expect_notification(MEDIA_STATE_HANDLE);
+        assert_eq!(value, vec![MediaState::Seeking.into()]);
+        let _ = event_receiver.expect_notification(TRACK_POSITION_HANDLE);
+
+        // During seeking, setting seeking speed emits both SeekingSpeed and
+        // TrackPosition
+        server.set_seeking_speed(SeekingSpeed::new(2)).expect("set_seeking_speed succeeds");
+        let (value, _) = event_receiver.expect_notification(SEEKING_SPEED_HANDLE);
+        assert_eq!(value, vec![SeekingSpeed::new(2).into()]);
+
+        let _ = event_receiver.expect_notification(TRACK_POSITION_HANDLE);
+
+        // Pausing from Seeking emits both MediaState and TrackPosition
+        // notifications
+        server.set_media_state(MediaState::Paused);
+        let (value, _) = event_receiver.expect_notification(MEDIA_STATE_HANDLE);
+        assert_eq!(value, vec![MediaState::Paused.into()]);
+        let _ = event_receiver.expect_notification(TRACK_POSITION_HANDLE);
+
+        // Test server without player speeds returns FeatureNotSupported
+        let (mut server_no_speeds, _, _) =
+            setup_test_server(McsServerBuilder::generic(0x43, "Player"));
+        assert_matches!(
+            server_no_speeds.set_playback_speed(PlaybackSpeed::DOUBLE),
+            Err(Error::FeatureNotSupported("playback_speed"))
+        );
+        assert_matches!(
+            server_no_speeds.set_seeking_speed(SeekingSpeed::new(2)),
+            Err(Error::FeatureNotSupported("seeking_speed"))
+        );
+    }
+
+    #[test]
+    fn public_api_playing_order_and_supported_opcodes() {
+        let (mut server, fake_gatt_server, mut event_receiver) = setup_test_server(
+            McsServerBuilder::generic(0x42, "Test Player")
+                .with_playing_orders(
+                    SupportedPlayingOrders::IN_ORDER_ONCE | SupportedPlayingOrders::SHUFFLE_ONCE,
+                )
+                .with_supported_operations(SupportedOpcodes::PLAY),
+        );
+        let mut noop_cx = Context::from_waker(futures::task::noop_waker_ref());
+
+        let peer = PeerId(1);
+        let service_id = ServiceId::new(0x42);
+
+        for handle in [PLAYING_ORDER_HANDLE, MEDIA_CONTROL_POINT_OPCODES_SUPPORTED_HANDLE] {
+            fake_gatt_server.incoming_client_configuration(
+                peer,
+                service_id,
+                handle,
+                bt_gatt::server::NotificationType::Notify,
+            );
+            let _ = server.next().poll_unpin(&mut noop_cx);
+            event_receiver.expect_no_event();
+        }
+
+        // Supported order succeeds and notifies
+        server.set_playing_order(PlayingOrder::ShuffleOnce).expect("set_playing_order succeeds");
+        let (value, _) = event_receiver.expect_notification(PLAYING_ORDER_HANDLE);
+        assert_eq!(value, vec![PlayingOrder::ShuffleOnce.into()]);
+
+        // Unsupported order returns Error and does not notify
+        assert_matches!(
+            server.set_playing_order(PlayingOrder::SingleRepeat),
+            Err(Error::UnsupportedPlayingOrder(PlayingOrder::SingleRepeat))
+        );
+        event_receiver.expect_no_event();
+
+        // Update supported opcodes
+        let new_opcodes = SupportedOpcodes::PLAY | SupportedOpcodes::PAUSE;
+        server.set_supported_opcodes(new_opcodes).expect("set_supported_opcodes succeeds");
+        let (value, _) =
+            event_receiver.expect_notification(MEDIA_CONTROL_POINT_OPCODES_SUPPORTED_HANDLE);
+        assert_eq!(value, new_opcodes.bits().to_le_bytes().to_vec());
+
+        // Test server without playing orders or control point returns
+        // FeatureNotSupported
+        let (mut server_no_optional, _, _) =
+            setup_test_server(McsServerBuilder::generic(0x43, "Player"));
+        assert_matches!(
+            server_no_optional.set_playing_order(PlayingOrder::InOrderOnce),
+            Err(Error::FeatureNotSupported("playing_orders"))
+        );
+        assert_matches!(
+            server_no_optional.set_supported_opcodes(SupportedOpcodes::PLAY),
+            Err(Error::FeatureNotSupported("media_control_point"))
+        );
+    }
+
+    #[test]
+    fn public_api_unpublished_server_updates_state() {
+        let mut server = McsServerBuilder::generic(0x42, "Test Player")
+            .with_icon_url("https://example.com/old.png")
+            .with_player_speeds()
+            .with_playing_orders(SupportedPlayingOrders::all())
+            .with_supported_operations(SupportedOpcodes::all())
+            .build::<FakeTypes>()
+            .unwrap();
+
+        server.set_media_state(MediaState::Playing);
+        server.set_track(
+            "Title",
+            TrackDuration::from_raw_10ms(100),
+            TrackPosition::from_raw_10ms(0),
+        );
+        server.clear_track();
+        server.set_track_position(TrackPosition::from_raw_10ms(0));
+        server.set_player_name("Name");
+        assert_matches!(server.set_icon_url("https://example.com"), Ok(()));
+        assert_matches!(server.set_playback_speed(PlaybackSpeed::NORMAL), Ok(()));
+        assert_matches!(server.set_seeking_speed(SeekingSpeed::NOT_SEEKING), Ok(()));
+        assert_matches!(server.set_playing_order(PlayingOrder::InOrderOnce), Ok(()));
+        assert_matches!(server.set_supported_opcodes(SupportedOpcodes::PLAY), Ok(()));
     }
 }
diff --git a/rust/bt-mcs/src/server/state.rs b/rust/bt-mcs/src/server/state.rs
index f802d19..46d3e2a 100644
--- a/rust/bt-mcs/src/server/state.rs
+++ b/rust/bt-mcs/src/server/state.rs
@@ -10,6 +10,7 @@
 use bt_gatt::Characteristic;
 
 use crate::types::*;
+use crate::Error;
 
 // ============================================================================
 // Characteristic Definitions & Handles (MCS v1.0.1 Section 3)
@@ -170,62 +171,185 @@
             return TrackPosition::Unavailable;
         }
 
-        // Playback timing has not started since the track was initialized or
-        // loaded.
-        let Some(updated_at) = self.position_updated_at else {
-            return self.track_position;
-        };
-
-        // Playback is paused or seeking, so the position remains fixed at the
-        // current offset.
-        if self.media_state != MediaState::Playing {
-            return self.track_position;
-        }
-
         let base = match (self.track_position, self.track_duration) {
             (TrackPosition::FromStart(base), _) => base,
             (TrackPosition::FromEnd(end), TrackDuration::Duration(total)) => {
                 total.saturating_sub(end)
             }
+            (TrackPosition::FromEnd(_), TrackDuration::Unknown) => {
+                return TrackPosition::Unavailable;
+            }
             _ => return self.track_position,
         };
 
-        // TODO(b/540400364): Factor in optional playback speed when supported
-        let mut current = base + updated_at.elapsed();
-        if let TrackDuration::Duration(total) = self.track_duration {
-            current = current.min(total);
+        // Playback is paused, so position remains fixed at current offset.
+        if self.media_state == MediaState::Paused {
+            return TrackPosition::FromStart(base);
         }
-        TrackPosition::FromStart(current)
+
+        // Playback timing has not started since the track was initialized or
+        // loaded.
+        let Some(updated_at) = self.position_updated_at else {
+            return TrackPosition::FromStart(base);
+        };
+
+        let elapsed = updated_at.elapsed();
+        let current = match self.media_state {
+            MediaState::Playing => {
+                let speed_multiplier = self.playback_speed.map_or(1.0, |s| s.as_multiplier());
+                base + elapsed.mul_f64(speed_multiplier)
+            }
+            MediaState::Seeking => {
+                let factor = self.seeking_speed.map_or(0, |s| s.factor());
+                if factor > 0 {
+                    base + elapsed.mul_f64(factor as f64)
+                } else if factor < 0 {
+                    base.saturating_sub(elapsed.mul_f64(factor.unsigned_abs() as f64))
+                } else {
+                    base
+                }
+            }
+            _ => base,
+        };
+
+        let bounded = if let TrackDuration::Duration(total) = self.track_duration {
+            current.min(total)
+        } else {
+            current
+        };
+
+        TrackPosition::FromStart(bounded)
+    }
+
+    /// Updates the track position and synchronizes the timestamp anchor.
+    fn update_track_position(&mut self, position: TrackPosition) {
+        let resolved = match (position, self.track_duration) {
+            (TrackPosition::FromStart(base), _) => TrackPosition::FromStart(base),
+            (TrackPosition::FromEnd(end), TrackDuration::Duration(total)) => {
+                TrackPosition::FromStart(total.saturating_sub(end))
+            }
+            (TrackPosition::FromEnd(_), TrackDuration::Unknown) => TrackPosition::Unavailable,
+            (TrackPosition::Unavailable, _) => TrackPosition::Unavailable,
+        };
+        self.track_position = resolved;
+        self.position_updated_at = match resolved {
+            TrackPosition::Unavailable => None,
+            _ => Some(std::time::Instant::now()),
+        };
+    }
+
+    /// Sets the media playback state and updates the playback position clock
+    /// anchor accordingly.
+    pub(crate) fn set_media_state(&mut self, state: MediaState) {
+        if self.media_state == state {
+            return;
+        }
+
+        match state {
+            MediaState::Playing | MediaState::Paused | MediaState::Seeking => {
+                let position = if self.media_state == MediaState::Playing
+                    || self.media_state == MediaState::Seeking
+                {
+                    self.current_track_position()
+                } else {
+                    self.track_position
+                };
+                self.update_track_position(position);
+            }
+            MediaState::Inactive => {
+                self.update_track_position(TrackPosition::Unavailable);
+            }
+        }
+        self.media_state = state;
     }
 
     /// Sets the track position and records the update timestamp.
     pub(crate) fn set_track_position(&mut self, position: TrackPosition) {
-        self.track_position = position;
-        self.position_updated_at = Some(std::time::Instant::now());
+        self.update_track_position(position);
+    }
+
+    /// Sets the current track title, duration, and position.
+    pub(crate) fn set_track(
+        &mut self,
+        title: String,
+        duration: TrackDuration,
+        position: TrackPosition,
+    ) {
+        self.track_title = title;
+        self.track_duration = duration;
+        self.update_track_position(position);
+    }
+
+    /// Clears the active track metadata and position.
+    pub(crate) fn clear_track(&mut self) {
+        self.track_title.clear();
+        self.track_duration = TrackDuration::Unknown;
+        self.update_track_position(TrackPosition::Unavailable);
+    }
+
+    /// Sets the human-readable media player name.
+    pub(crate) fn set_player_name(&mut self, name: String) {
+        self.player_name = name;
+    }
+
+    /// Sets the media player icon URL if supported.
+    pub(crate) fn set_icon_url(&mut self, url: String) -> Result<(), Error> {
+        if self.icon_url.is_none() {
+            return Err(Error::FeatureNotSupported("icon_url"));
+        }
+        self.icon_url = Some(url);
+        Ok(())
     }
 
     /// Sets the playback speed.
-    pub(crate) fn set_playback_speed(&mut self, speed: PlaybackSpeed) {
-        self.playback_speed = Some(speed);
-    }
-
-    /// Sets the playing order if playing order is supported.
-    pub(crate) fn set_playing_order(&mut self, order: PlayingOrder) {
-        if let Some(ref mut orders) = self.playing_orders {
-            if orders.supported.contains(order.into()) {
-                orders.current = order;
-            }
+    pub(crate) fn set_playback_speed(&mut self, speed: PlaybackSpeed) -> Result<(), Error> {
+        if self.playback_speed.is_none() {
+            return Err(Error::FeatureNotSupported("playback_speed"));
         }
+        // Freeze current track position before adjusting speed so the new
+        // multiplier is not retroactively applied to prior playback
+        // time (MCS v1.0.1 Section 3.7.1).
+        if self.media_state == MediaState::Playing {
+            self.update_track_position(self.current_track_position());
+        }
+        self.playback_speed = Some(speed);
+        Ok(())
     }
 
-    #[cfg(test)]
-    pub(crate) fn set_media_state(&mut self, state: MediaState) {
-        self.media_state = state;
+    /// Sets the seeking speed if supported.
+    pub(crate) fn set_seeking_speed(&mut self, speed: SeekingSpeed) -> Result<(), Error> {
+        if self.seeking_speed.is_none() {
+            return Err(Error::FeatureNotSupported("seeking_speed"));
+        }
+        // Freeze current track position before entering or adjusting seeking
+        // speed so prior elapsed playback is preserved (MCS v1.0.1
+        // Section 3.7.1, 3.9).
+        if self.media_state == MediaState::Playing || self.media_state == MediaState::Seeking {
+            self.update_track_position(self.current_track_position());
+        }
+        self.seeking_speed = Some(speed);
+        Ok(())
     }
 
-    #[cfg(test)]
-    pub(crate) fn set_supported_opcodes(&mut self, opcodes: SupportedOpcodes) {
+    /// Sets the playing order if supported and enabled.
+    pub(crate) fn set_playing_order(&mut self, order: PlayingOrder) -> Result<(), Error> {
+        let Some(ref mut orders) = self.playing_orders else {
+            return Err(Error::FeatureNotSupported("playing_orders"));
+        };
+        if !orders.supported.contains(order.into()) {
+            return Err(Error::UnsupportedPlayingOrder(order));
+        }
+        orders.current = order;
+        Ok(())
+    }
+
+    /// Sets the supported opcodes if supported.
+    pub(crate) fn set_supported_opcodes(&mut self, opcodes: SupportedOpcodes) -> Result<(), Error> {
+        if self.supported_opcodes.is_none() {
+            return Err(Error::FeatureNotSupported("media_control_point"));
+        }
         self.supported_opcodes = Some(opcodes);
+        Ok(())
     }
 
     /// Reads the characteristic bytes for `handle` at `offset`.
@@ -286,11 +410,14 @@
         state.playing_orders = Some(PlayingOrderState::new(SupportedPlayingOrders::SINGLE_ONCE));
         assert_eq!(state.playing_orders.as_ref().unwrap().current, PlayingOrder::InOrderOnce);
 
-        state.set_playing_order(PlayingOrder::SingleOnce);
+        assert_matches!(state.set_playing_order(PlayingOrder::SingleOnce), Ok(()));
         assert_eq!(state.playing_orders.as_ref().unwrap().current, PlayingOrder::SingleOnce);
 
-        // Unsupported playing order is not applied
-        state.set_playing_order(PlayingOrder::ShuffleOnce);
+        // Unsupported playing order returns Err and is not applied
+        assert_matches!(
+            state.set_playing_order(PlayingOrder::ShuffleOnce),
+            Err(Error::UnsupportedPlayingOrder(PlayingOrder::ShuffleOnce))
+        );
         assert_eq!(state.playing_orders.as_ref().unwrap().current, PlayingOrder::SingleOnce);
     }
 
@@ -511,4 +638,204 @@
             assert!(chrc.permissions.update.map_or(true, |s| s.encryption));
         }
     }
+
+    #[test]
+    fn local_state_track_position_calculation_with_playback_speed() {
+        let mut state = McsLocalState::new(0x01, "Player");
+        state.track_duration = TrackDuration::from_raw_10ms(10000);
+        state.media_state = MediaState::Playing;
+        state.track_position = TrackPosition::from_raw_10ms(1000); // 10s base
+
+        // Double speed (2.0x): 2s elapsed should add ~4s -> ~14s
+        state.playback_speed = Some(PlaybackSpeed::DOUBLE);
+        state.position_updated_at = Some(std::time::Instant::now() - Duration::from_secs(2));
+        match state.current_track_position() {
+            TrackPosition::FromStart(dur) => {
+                assert!(dur >= Duration::from_millis(13800) && dur <= Duration::from_millis(14200));
+            }
+            other => panic!("Expected FromStart, got {other:?}"),
+        }
+
+        // Half speed (0.5x): 4s elapsed should add ~2s -> ~12s
+        state.playback_speed = Some(PlaybackSpeed::HALF);
+        state.position_updated_at = Some(std::time::Instant::now() - Duration::from_secs(4));
+        match state.current_track_position() {
+            TrackPosition::FromStart(dur) => {
+                assert!(dur >= Duration::from_millis(11800) && dur <= Duration::from_millis(12200));
+            }
+            other => panic!("Expected FromStart, got {other:?}"),
+        }
+    }
+
+    #[test]
+    fn local_state_track_position_calculation_with_seeking_speed() {
+        let mut state = McsLocalState::new(0x01, "Player");
+        state.track_duration = TrackDuration::from_raw_10ms(10000); // 100s
+        state.media_state = MediaState::Seeking;
+        state.track_position = TrackPosition::from_raw_10ms(2000); // 20s base
+
+        // Fast forward (+4x): 2s elapsed should add ~8s -> ~28s
+        state.seeking_speed = Some(SeekingSpeed::new(4));
+        state.position_updated_at = Some(std::time::Instant::now() - Duration::from_secs(2));
+        match state.current_track_position() {
+            TrackPosition::FromStart(dur) => {
+                assert!(dur >= Duration::from_millis(27800) && dur <= Duration::from_millis(28200));
+            }
+            other => panic!("Expected FromStart, got {other:?}"),
+        }
+
+        // Fast rewind (-4x): 2s elapsed should subtract ~8s -> ~12s
+        state.seeking_speed = Some(SeekingSpeed::new(-4));
+        state.position_updated_at = Some(std::time::Instant::now() - Duration::from_secs(2));
+        match state.current_track_position() {
+            TrackPosition::FromStart(dur) => {
+                assert!(dur >= Duration::from_millis(11800) && dur <= Duration::from_millis(12200));
+            }
+            other => panic!("Expected FromStart, got {other:?}"),
+        }
+
+        // Fast rewind saturated at start of track (0s)
+        state.position_updated_at = Some(std::time::Instant::now() - Duration::from_secs(10));
+        assert_eq!(state.current_track_position(), TrackPosition::from_raw_10ms(0));
+
+        // Fast forward clamped at track duration (100s)
+        state.seeking_speed = Some(SeekingSpeed::new(4));
+        state.position_updated_at = Some(std::time::Instant::now() - Duration::from_secs(50));
+        assert_eq!(state.current_track_position(), TrackPosition::from_raw_10ms(10000));
+    }
+
+    #[test]
+    fn local_state_state_transitions_timeline_capture() {
+        let mut state = McsLocalState::new(0x01, "Player");
+        state.track_duration = TrackDuration::from_raw_10ms(10000);
+        state.set_track(
+            "Test Track".to_string(),
+            TrackDuration::from_raw_10ms(5000),
+            TrackPosition::from_raw_10ms(100),
+        );
+        assert_eq!(state.track_title, "Test Track");
+        assert_eq!(state.track_duration, TrackDuration::from_raw_10ms(5000));
+        assert_eq!(state.track_position, TrackPosition::from_raw_10ms(100));
+
+        // Transition to Playing
+        state.set_media_state(MediaState::Playing);
+        assert_eq!(state.media_state, MediaState::Playing);
+        assert!(state.position_updated_at.is_some());
+
+        // Fast-forward time simulated: 1s elapsed
+        state.position_updated_at = Some(std::time::Instant::now() - Duration::from_secs(1));
+
+        // Transition to Paused: snaps dynamic position
+        state.set_media_state(MediaState::Paused);
+        assert_eq!(state.media_state, MediaState::Paused);
+        match state.track_position {
+            TrackPosition::FromStart(dur) => {
+                assert!(dur >= Duration::from_millis(1900) && dur <= Duration::from_millis(2200));
+            }
+            other => panic!("Expected FromStart, got {other:?}"),
+        }
+
+        // Transition to Inactive: position unavailable
+        state.set_media_state(MediaState::Inactive);
+        assert_eq!(state.media_state, MediaState::Inactive);
+        assert_eq!(state.track_position, TrackPosition::Unavailable);
+        assert!(state.position_updated_at.is_none());
+
+        // Clear track
+        state.clear_track();
+        assert_eq!(state.track_title, "");
+        assert_eq!(state.track_duration, TrackDuration::Unknown);
+        assert_eq!(state.track_position, TrackPosition::Unavailable);
+    }
+
+    #[test]
+    fn local_state_optional_setters_feature_validation() {
+        let mut state = McsLocalState::new(0x01, "Player");
+
+        // Unconfigured features return FeatureNotSupported
+        assert_matches!(
+            state.set_icon_url("https://example.com".to_string()),
+            Err(Error::FeatureNotSupported("icon_url"))
+        );
+        assert_matches!(
+            state.set_playback_speed(PlaybackSpeed::NORMAL),
+            Err(Error::FeatureNotSupported("playback_speed"))
+        );
+        assert_matches!(
+            state.set_seeking_speed(SeekingSpeed::new(1)),
+            Err(Error::FeatureNotSupported("seeking_speed"))
+        );
+        assert_matches!(
+            state.set_playing_order(PlayingOrder::SingleOnce),
+            Err(Error::FeatureNotSupported("playing_orders"))
+        );
+        assert_matches!(
+            state.set_supported_opcodes(SupportedOpcodes::all()),
+            Err(Error::FeatureNotSupported("media_control_point"))
+        );
+
+        // When configured, setters succeed and validate
+        state.icon_url = Some(String::new());
+        state.playback_speed = Some(PlaybackSpeed::NORMAL);
+        state.seeking_speed = Some(SeekingSpeed::NOT_SEEKING);
+        state.playing_orders = Some(PlayingOrderState::new(SupportedPlayingOrders::SINGLE_ONCE));
+        state.supported_opcodes = Some(SupportedOpcodes::PLAY);
+
+        assert_matches!(state.set_icon_url("https://example.com/icon.png".to_string()), Ok(()));
+        assert_eq!(state.icon_url.as_deref(), Some("https://example.com/icon.png"));
+
+        assert_matches!(state.set_playback_speed(PlaybackSpeed::DOUBLE), Ok(()));
+        assert_eq!(state.playback_speed, Some(PlaybackSpeed::DOUBLE));
+
+        assert_matches!(state.set_seeking_speed(SeekingSpeed::new(5)), Ok(()));
+        assert_eq!(state.seeking_speed, Some(SeekingSpeed::new(5)));
+
+        assert_matches!(state.set_playing_order(PlayingOrder::SingleOnce), Ok(()));
+        assert_matches!(
+            state.set_playing_order(PlayingOrder::ShuffleOnce),
+            Err(Error::UnsupportedPlayingOrder(PlayingOrder::ShuffleOnce))
+        );
+
+        assert_matches!(state.set_supported_opcodes(SupportedOpcodes::all()), Ok(()));
+    }
+
+    #[test]
+    fn seeking_speed_min_boundary_calculation() {
+        let mut state = McsLocalState::new(0x01, "Player");
+        state.set_track(
+            "Song".to_string(),
+            TrackDuration::from_raw_10ms(10000),
+            TrackPosition::from_raw_10ms(5000),
+        );
+        state.seeking_speed = Some(SeekingSpeed::new(-128));
+        state.set_media_state(MediaState::Seeking);
+
+        // Verify seeking with minimum factor (-128) does not overflow or panic.
+        let pos = state.current_track_position();
+        match pos {
+            TrackPosition::FromStart(dur) => {
+                assert!(dur <= Duration::from_millis(50000));
+            }
+            other => panic!("Expected FromStart, got {other:?}"),
+        }
+
+        // Verify FromEnd with Unknown duration resolves to Unavailable per MCS
+        // v1.0.1 Section 3.7.1.
+        state.set_track(
+            "Live Stream".to_string(),
+            TrackDuration::Unknown,
+            TrackPosition::from_end(Duration::from_secs(10)),
+        );
+        assert_eq!(state.current_track_position(), TrackPosition::Unavailable);
+
+        // Verify FromEnd with known duration resolves to FromStart(total -
+        // end).
+        state.set_media_state(MediaState::Paused);
+        state.set_track(
+            "Track".to_string(),
+            TrackDuration::from_raw_10ms(5000), // 50s
+            TrackPosition::from_end(Duration::from_secs(10)),
+        );
+        assert_eq!(state.current_track_position(), TrackPosition::from_raw_10ms(4000));
+    }
 }
diff --git a/rust/bt-mcs/src/types.rs b/rust/bt-mcs/src/types.rs
index 35594c4..76fec63 100644
--- a/rust/bt-mcs/src/types.rs
+++ b/rust/bt-mcs/src/types.rs
@@ -598,6 +598,11 @@
             Self::Duration(d) => (d.as_millis() / 10).min(i32::MAX as u128) as i32,
         }
     }
+
+    /// Returns the 4-byte little-endian notification payload for this duration.
+    pub fn to_notify_value(&self) -> [u8; 4] {
+        self.raw_10ms().to_le_bytes()
+    }
 }
 
 impl Encodable for TrackDuration {
@@ -676,6 +681,11 @@
             Self::FromEnd(d) => -((d.as_millis() / 10).min(i32::MAX as u128) as i32),
         }
     }
+
+    /// Returns the 4-byte little-endian notification payload for this position.
+    pub fn to_notify_value(&self) -> [u8; 4] {
+        self.raw_10ms().to_le_bytes()
+    }
 }
 
 impl Encodable for TrackPosition {
@@ -1301,6 +1311,8 @@
 
         let dur = TrackDuration::from_duration(Duration::from_secs(180));
         assert_eq!(dur.raw_10ms(), 18000);
+        assert_eq!(dur.to_notify_value(), 18000i32.to_le_bytes());
+        assert_eq!(TrackDuration::Unknown.to_notify_value(), (-1i32).to_le_bytes());
         assert_eq!(TrackDuration::from_raw_10ms(18000), dur);
 
         let mut buf = [0u8; 4];
@@ -1321,14 +1333,17 @@
     #[test]
     fn track_position_encode_decode() {
         assert_eq!(TrackPosition::Unavailable.raw_10ms(), -1);
+        assert_eq!(TrackPosition::Unavailable.to_notify_value(), (-1i32).to_le_bytes());
         assert_eq!(TrackPosition::from_raw_10ms(-1), TrackPosition::Unavailable);
 
         let start_pos = TrackPosition::from_start(Duration::from_millis(1500));
         assert_eq!(start_pos.raw_10ms(), 150);
+        assert_eq!(start_pos.to_notify_value(), 150i32.to_le_bytes());
         assert_eq!(TrackPosition::from_raw_10ms(150), start_pos);
 
         let end_pos = TrackPosition::from_end(Duration::from_millis(2000));
         assert_eq!(end_pos.raw_10ms(), -200);
+        assert_eq!(end_pos.to_notify_value(), (-200i32).to_le_bytes());
         assert_eq!(TrackPosition::from_raw_10ms(-200), end_pos);
 
         let mut buf = [0u8; 4];
