diff --git a/rust/bt-mcs/src/lib.rs b/rust/bt-mcs/src/lib.rs
index 3d5520d..f08bd71 100644
--- a/rust/bt-mcs/src/lib.rs
+++ b/rust/bt-mcs/src/lib.rs
@@ -7,11 +7,6 @@
 pub mod types;
 
 pub use crate::error::Error;
-pub use crate::server::{
-    ControlPointWriteResponder, McsServer, McsServerBuilder, McsServerEvent,
-    SetPlaybackSpeedResponder, SetPlayingOrderResponder, SetTrackPositionResponder,
-    SetValueResponder,
-};
 pub use crate::types::{
     ControlPointResultCode, MediaControlOpcode, MediaState, PlaybackSpeed, PlayingOrder,
     SeekingSpeed, SupportedOpcodes, SupportedPlayingOrders, TrackDuration, TrackPosition,
diff --git a/rust/bt-mcs/src/server.rs b/rust/bt-mcs/src/server.rs
index 3f49055..ca82faa 100644
--- a/rust/bt-mcs/src/server.rs
+++ b/rust/bt-mcs/src/server.rs
@@ -11,121 +11,26 @@
     WriteResponder,
 };
 use bt_gatt::types::{
-    AttributePermissions, CharacteristicProperties, CharacteristicProperty, GattError, Handle,
-    SecurityLevels, ServiceKind,
+    CharacteristicProperties, CharacteristicProperty, GattError, Handle, ServiceKind,
 };
-use bt_gatt::Characteristic;
-use futures::channel::oneshot;
 use futures::stream::{FuturesUnordered, Stream};
-use futures::FutureExt;
 use pin_project::pin_project;
 use std::future::Future;
-use std::pin::Pin;
 use std::task::{Context, Poll, Waker};
 
+pub mod event;
+use event::*;
+pub use event::{
+    ControlPointWriteResponder, McsServerEvent, SetPlaybackSpeedResponder,
+    SetPlayingOrderResponder, SetTrackPositionResponder, SetValueResponder,
+};
+
+mod state;
+use state::*;
+
 use crate::types::*;
 use crate::Error;
 
-// ============================================================================
-// Mandatory Characteristic Handle Definitions (MCS v1.0.1 Section 3)
-// ============================================================================
-
-/// Handle assigned to the Media Player Name characteristic.
-const MEDIA_PLAYER_NAME_HANDLE: Handle = Handle(1);
-/// Handle assigned to the Track Changed characteristic.
-const TRACK_CHANGED_HANDLE: Handle = Handle(2);
-/// Handle assigned to the Track Title characteristic.
-const TRACK_TITLE_HANDLE: Handle = Handle(3);
-/// Handle assigned to the Track Duration characteristic.
-const TRACK_DURATION_HANDLE: Handle = Handle(4);
-/// Handle assigned to the Track Position characteristic.
-const TRACK_POSITION_HANDLE: Handle = Handle(5);
-/// Handle assigned to the Media State characteristic.
-const MEDIA_STATE_HANDLE: Handle = Handle(6);
-/// Handle assigned to the Content Control ID (CCID) characteristic.
-const CONTENT_CONTROL_ID_HANDLE: Handle = Handle(7);
-
-// ============================================================================
-// Optional Characteristic Handle Definitions (MCS v1.0.1 Section 3)
-// ============================================================================
-
-/// Handle assigned to the Media Player Icon URL characteristic.
-const MEDIA_PLAYER_ICON_URL_HANDLE: Handle = Handle(8);
-/// Handle assigned to the Playback Speed characteristic.
-const PLAYBACK_SPEED_HANDLE: Handle = Handle(9);
-/// Handle assigned to the Seeking Speed characteristic.
-const SEEKING_SPEED_HANDLE: Handle = Handle(10);
-/// Handle assigned to the Playing Order characteristic.
-const PLAYING_ORDER_HANDLE: Handle = Handle(11);
-/// Handle assigned to the Playing Orders Supported characteristic.
-const PLAYING_ORDERS_SUPPORTED_HANDLE: Handle = Handle(12);
-/// Handle assigned to the Media Control Point characteristic.
-const MEDIA_CONTROL_POINT_HANDLE: Handle = Handle(13);
-/// Handle assigned to the Media Control Point Opcodes Supported characteristic.
-const MEDIA_CONTROL_POINT_OPCODES_SUPPORTED_HANDLE: Handle = Handle(14);
-
-/// The mandatory characteristics defined in MCS v1.0.1 Section 3, Table 3.1.
-fn mandatory_characteristics() -> [Characteristic; 7] {
-    [
-        build_characteristic(
-            MEDIA_PLAYER_NAME_HANDLE,
-            MEDIA_PLAYER_NAME_UUID,
-            CharacteristicProperties::READ_NOTIFY,
-        ),
-        build_characteristic(
-            TRACK_CHANGED_HANDLE,
-            TRACK_CHANGED_UUID,
-            CharacteristicProperty::Notify,
-        ),
-        build_characteristic(
-            TRACK_TITLE_HANDLE,
-            TRACK_TITLE_UUID,
-            CharacteristicProperties::READ_NOTIFY,
-        ),
-        build_characteristic(
-            TRACK_DURATION_HANDLE,
-            TRACK_DURATION_UUID,
-            CharacteristicProperties::READ_NOTIFY,
-        ),
-        build_characteristic(
-            TRACK_POSITION_HANDLE,
-            TRACK_POSITION_UUID,
-            CharacteristicProperties::READ_WRITE_NOTIFY,
-        ),
-        build_characteristic(
-            MEDIA_STATE_HANDLE,
-            MEDIA_STATE_UUID,
-            CharacteristicProperties::READ_NOTIFY,
-        ),
-        build_characteristic(
-            CONTENT_CONTROL_ID_HANDLE,
-            CONTENT_CONTROL_ID_UUID,
-            CharacteristicProperty::Read,
-        ),
-    ]
-}
-
-/// Constructs a characteristic definition with the specified handle, UUID,
-/// properties, and encryption-required permissions conforming to MCS v1.0.1
-/// Section 3.
-fn build_characteristic(
-    handle: Handle,
-    uuid: Uuid,
-    properties: impl Into<CharacteristicProperties>,
-) -> Characteristic {
-    let properties = properties.into();
-    Characteristic {
-        handle,
-        uuid,
-        properties,
-        permissions: AttributePermissions::with_levels(
-            &properties,
-            &SecurityLevels::encryption_required(),
-        ),
-        descriptors: Vec::new(),
-    }
-}
-
 /// Internal state for the MCS server.
 #[pin_project(project = LocalServiceProj)]
 enum LocalServiceState<T: bt_gatt::ServerTypes> {
@@ -206,343 +111,6 @@
     }
 }
 
-/// Confirms the updated track position to store in local state and notify to
-/// clients.
-/// It is safe to drop without responding to ignore the update or if the value
-/// has not changed.
-pub type SetTrackPositionResponder = SetValueResponder<TrackPosition>;
-
-/// Confirms the updated playback speed to store in local state and notify to
-/// clients.
-/// It is safe to drop without responding to ignore the update or if the value
-/// has not changed.
-pub type SetPlaybackSpeedResponder = SetValueResponder<PlaybackSpeed>;
-
-/// Confirms the updated playing order to store in local state and notify to
-/// clients.
-/// It is safe to drop without responding to ignore the update or if the value
-/// has not changed.
-pub type SetPlayingOrderResponder = SetValueResponder<PlayingOrder>;
-
-/// Confirms the media control command result code to notify to the client.
-/// A response is expected to confirm the result. If no response is provided,
-/// then it is assumed that the Control Point request has failed and
-/// `ControlPointResultCode::CommandCannotBeCompleted` will be sent to the peer.
-pub type ControlPointWriteResponder = SetValueResponder<ControlPointResultCode>;
-
-/// Responder for an asynchronous characteristic write or control point command.
-///
-/// Calling [`send`](Self::send) confirms the new value or command result to
-/// update local state and notify clients. It is safe to drop the responder
-/// without responding to cancel the update (or report command failure).
-pub struct SetValueResponder<T> {
-    response_tx: oneshot::Sender<T>,
-}
-
-impl<T: std::fmt::Debug> SetValueResponder<T> {
-    /// Confirms the value or result code determined by the media player
-    /// application and dispatches the corresponding GATT notification.
-    pub fn send(self, value: T) {
-        if let Err(result) = self.response_tx.send(value) {
-            log::warn!("Failed to send response: server dropped or closed: {result:?}");
-        }
-    }
-}
-
-impl<T> std::fmt::Debug for SetValueResponder<T> {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        f.debug_struct("SetValueResponder").finish_non_exhaustive()
-    }
-}
-
-/// An in-flight handler for a single-value asynchronous write response.
-struct SetValueResponseFut<T> {
-    rx: oneshot::Receiver<T>,
-}
-
-impl<T> SetValueResponseFut<T> {
-    fn create() -> (Self, SetValueResponder<T>) {
-        let (tx, rx) = oneshot::channel();
-        (Self { rx }, SetValueResponder { response_tx: tx })
-    }
-}
-
-impl<T> Future for SetValueResponseFut<T> {
-    type Output = Option<T>;
-
-    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
-        self.rx.poll_unpin(cx).map(Result::ok)
-    }
-}
-
-/// Responses produced when an in-flight asynchronous write response completes.
-enum PendingWriteResponse {
-    ControlPoint {
-        peer_id: PeerId,
-        opcode: MediaControlOpcode,
-        result_code: ControlPointResultCode,
-    },
-    TrackPosition(TrackPosition),
-    PlaybackSpeed(PlaybackSpeed),
-    PlayingOrder(PlayingOrder),
-}
-
-/// An in-flight asynchronous write response future.
-enum PendingWriteResponseFut {
-    ControlPoint {
-        peer_id: PeerId,
-        opcode: MediaControlOpcode,
-        fut: SetValueResponseFut<ControlPointResultCode>,
-    },
-    TrackPosition(SetValueResponseFut<TrackPosition>),
-    PlaybackSpeed(SetValueResponseFut<PlaybackSpeed>),
-    PlayingOrder(SetValueResponseFut<PlayingOrder>),
-}
-
-impl Future for PendingWriteResponseFut {
-    type Output = Option<PendingWriteResponse>;
-
-    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
-        match self.as_mut().get_mut() {
-            Self::ControlPoint { peer_id, opcode, fut } => fut.poll_unpin(cx).map(|res| {
-                let code = res.unwrap_or(ControlPointResultCode::CommandCannotBeCompleted);
-                Some(PendingWriteResponse::ControlPoint {
-                    peer_id: *peer_id,
-                    opcode: opcode.clone(),
-                    result_code: code,
-                })
-            }),
-            Self::TrackPosition(fut) => {
-                fut.poll_unpin(cx).map(|res| res.map(PendingWriteResponse::TrackPosition))
-            }
-            Self::PlaybackSpeed(fut) => {
-                fut.poll_unpin(cx).map(|res| res.map(PendingWriteResponse::PlaybackSpeed))
-            }
-            Self::PlayingOrder(fut) => {
-                fut.poll_unpin(cx).map(|res| res.map(PendingWriteResponse::PlayingOrder))
-            }
-        }
-    }
-}
-
-/// Events produced by an [`McsServer`] stream representing client actions that
-/// require additional upper-layer application processing.
-#[derive(Debug)]
-pub enum McsServerEvent {
-    /// Request to set the track playback position.
-    SetTrackPosition {
-        peer_id: PeerId,
-        position: TrackPosition,
-        responder: SetValueResponder<TrackPosition>,
-    },
-    /// Request to set the playback speed.
-    SetPlaybackSpeed {
-        peer_id: PeerId,
-        speed: PlaybackSpeed,
-        responder: SetValueResponder<PlaybackSpeed>,
-    },
-    /// Request to set the playing order.
-    SetPlayingOrder {
-        peer_id: PeerId,
-        order: PlayingOrder,
-        responder: SetValueResponder<PlayingOrder>,
-    },
-    /// Request to execute a media control command.
-    ControlPointCommand {
-        opcode: MediaControlOpcode,
-        responder: SetValueResponder<ControlPointResultCode>,
-    },
-}
-
-/// State of the playing order characteristics when enabled on the server.
-#[derive(Debug, Clone, PartialEq, Eq)]
-struct PlayingOrderState {
-    /// Currently selected playing order.
-    current: PlayingOrder,
-    /// Bitmask of supported playing orders.
-    supported: SupportedPlayingOrders,
-}
-
-impl PlayingOrderState {
-    /// Creates a new `PlayingOrderState` with the default current order
-    /// (`PlayingOrder::InOrderOnce`) and the given supported bitmask.
-    fn new(supported: SupportedPlayingOrders) -> Self {
-        Self { current: PlayingOrder::default(), supported }
-    }
-
-    /// Sets the playing order if it is supported.
-    ///
-    /// Returns `true` if `order` was supported and applied, or `false` if
-    /// ignored because it was unsupported (MCS v1.0.1 Section 3.15.1).
-    fn set_order(&mut self, order: PlayingOrder) -> bool {
-        if self.supported.contains(order.into()) {
-            self.current = order;
-            true
-        } else {
-            false
-        }
-    }
-}
-
-/// Local state of the characteristics in this server.
-#[derive(Debug, Clone, PartialEq, Eq)]
-struct McsLocalState {
-    /// Content Control ID (CCID) identifying this media service instance.
-    ccid: u8,
-    /// Human-readable media player application name.
-    player_name: String,
-    /// Title of the currently selected track (empty if no track loaded).
-    track_title: String,
-    /// Total duration of the current track (MCS v1.0.1 Section 3.6).
-    track_duration: TrackDuration,
-    /// Base playback position of the current track (MCS v1.0.1 Section 3.7).
-    track_position: TrackPosition,
-    /// Timestamp when `track_position` was set or updated.
-    position_updated_at: Option<std::time::Instant>,
-    /// Current player activity state.
-    media_state: MediaState,
-    /// URL pointing to media player icon graphic, if supported.
-    icon_url: Option<String>,
-    /// Playback speed multiplier, if supported.
-    playback_speed: Option<PlaybackSpeed>,
-    /// Seeking speed factor, if supported.
-    seeking_speed: Option<SeekingSpeed>,
-    /// Playing order and supported playing orders, if supported.
-    playing_orders: Option<PlayingOrderState>,
-    /// Supported media control point opcodes, if Media Control Point is
-    /// supported.
-    supported_opcodes: Option<SupportedOpcodes>,
-}
-
-impl McsLocalState {
-    /// Creates a new [`McsLocalState`] with default values for an inactive
-    /// player with no track loaded per MCS v1.0.1 Section 3.
-    fn new(ccid: u8, player_name: impl Into<String>) -> Self {
-        Self {
-            ccid,
-            player_name: player_name.into(),
-            track_title: String::new(),
-            track_duration: TrackDuration::Unknown,
-            track_position: TrackPosition::Unavailable,
-            position_updated_at: None,
-            media_state: MediaState::Inactive,
-            icon_url: None,
-            playback_speed: None,
-            seeking_speed: None,
-            playing_orders: None,
-            supported_opcodes: None,
-        }
-    }
-
-    /// Calculates the instantaneous track position based on elapsed playback
-    /// time (MCS v1.0.1 Section 3.7).
-    fn current_track_position(&self) -> TrackPosition {
-        // Per MCS Section 3.17, an inactive player has no current track, so it is
-        // unavailable.
-        if self.media_state == MediaState::Inactive {
-            return TrackPosition::Unavailable;
-        }
-
-        // Playback timing has not started since the track was just initialized.
-        let Some(updated_at) = self.position_updated_at else {
-            return self.track_position;
-        };
-
-        // Playback is paused/seeking, so the position remains fixed.
-        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)
-            }
-            _ => 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);
-        }
-        TrackPosition::FromStart(current)
-    }
-
-    /// Sets the track position and records the update timestamp.
-    fn set_track_position(&mut self, position: TrackPosition) {
-        self.track_position = position;
-        self.position_updated_at = Some(std::time::Instant::now());
-    }
-
-    /// Sets the playback speed.
-    fn set_playback_speed(&mut self, speed: PlaybackSpeed) {
-        self.playback_speed = Some(speed);
-    }
-
-    /// Sets the playing order if playing order is supported.
-    fn set_playing_order(&mut self, order: PlayingOrder) {
-        if let Some(ref mut orders) = self.playing_orders {
-            let _ = orders.set_order(order);
-        }
-    }
-
-    #[cfg(test)]
-    pub(crate) fn set_media_state(&mut self, state: MediaState) {
-        self.media_state = state;
-    }
-
-    #[cfg(test)]
-    pub(crate) fn set_supported_opcodes(&mut self, opcodes: SupportedOpcodes) {
-        self.supported_opcodes = Some(opcodes);
-    }
-
-    /// Reads the characteristic bytes for `handle` at `offset`.
-    fn handle_read(&self, handle: Handle, offset: usize) -> Result<Vec<u8>, GattError> {
-        let read_at_offset =
-            |bytes: &[u8]| bytes.get(offset..).map(Vec::from).ok_or(GattError::InvalidOffset);
-
-        match handle {
-            // Track Changed and Media Control Point are not readable per MCS v1.0.1 Section 3,
-            // Table 3.1.
-            TRACK_CHANGED_HANDLE | MEDIA_CONTROL_POINT_HANDLE => Err(GattError::ReadNotPermitted),
-            MEDIA_PLAYER_NAME_HANDLE => read_at_offset(self.player_name.as_bytes()),
-            TRACK_TITLE_HANDLE => read_at_offset(self.track_title.as_bytes()),
-            TRACK_DURATION_HANDLE => read_at_offset(&self.track_duration.raw_10ms().to_le_bytes()),
-            TRACK_POSITION_HANDLE => {
-                read_at_offset(&self.current_track_position().raw_10ms().to_le_bytes())
-            }
-            MEDIA_STATE_HANDLE => read_at_offset(&[self.media_state.into()]),
-            CONTENT_CONTROL_ID_HANDLE => read_at_offset(&[self.ccid]),
-            MEDIA_PLAYER_ICON_URL_HANDLE => {
-                let url = self.icon_url.as_ref().ok_or(GattError::InvalidHandle)?;
-                read_at_offset(url.as_bytes())
-            }
-            PLAYBACK_SPEED_HANDLE => {
-                let speed = self.playback_speed.ok_or(GattError::InvalidHandle)?;
-                read_at_offset(&[speed.into()])
-            }
-            SEEKING_SPEED_HANDLE => {
-                let speed = self.seeking_speed.ok_or(GattError::InvalidHandle)?;
-                read_at_offset(&[speed.into()])
-            }
-            PLAYING_ORDER_HANDLE => {
-                let orders = self.playing_orders.as_ref().ok_or(GattError::InvalidHandle)?;
-                read_at_offset(&[orders.current.into()])
-            }
-            PLAYING_ORDERS_SUPPORTED_HANDLE => {
-                let orders = self.playing_orders.as_ref().ok_or(GattError::InvalidHandle)?;
-                read_at_offset(&orders.supported.bits().to_le_bytes())
-            }
-            MEDIA_CONTROL_POINT_OPCODES_SUPPORTED_HANDLE => {
-                let opcodes = self.supported_opcodes.ok_or(GattError::InvalidHandle)?;
-                read_at_offset(&opcodes.bits().to_le_bytes())
-            }
-            _ => Err(GattError::InvalidHandle),
-        }
-    }
-}
-
 /// Builder for configuring an MCS or GMCS GATT service.
 // TODO(b/549911651): Add support for OTS (Object Transfer Service) integration.
 #[derive(Debug, Clone, PartialEq)]
@@ -974,7 +542,8 @@
 
     use assert_matches::assert_matches;
     use bt_gatt::test_utils::{FakeServer, FakeServerEvent, FakeTypes};
-    use futures::StreamExt;
+    use bt_gatt::Characteristic;
+    use futures::{FutureExt, StreamExt};
 
     #[test]
     fn builder_generic_service_definition() {
@@ -1298,191 +867,6 @@
         (server, fake_gatt_server, event_receiver, noop_cx)
     }
 
-    fn assert_read_characteristic(
-        server: &mut McsServer<FakeTypes>,
-        fake_gatt_server: &FakeServer,
-        event_receiver: &mut futures::channel::mpsc::UnboundedReceiver<FakeServerEvent>,
-        handle: Handle,
-        expected: &[u8],
-    ) {
-        let mut noop_cx = Context::from_waker(futures::task::noop_waker_ref());
-        let peer = PeerId(1);
-        let service_id = server.service_def.id();
-        fake_gatt_server.incoming_read(peer, service_id, handle, 0);
-        let _ = server.next().poll_unpin(&mut noop_cx);
-        let bt_gatt::test_utils::FakeServerEvent::ReadResponded { value, .. } =
-            expect_service_event(event_receiver)
-        else {
-            panic!("expected ReadResponded");
-        };
-        assert_eq!(value.unwrap(), expected);
-    }
-
-    #[test]
-    fn read_mandatory_characteristics_default_values() {
-        let (mut server, fake_gatt_server, mut event_receiver) =
-            setup_test_server(McsServerBuilder::generic(0x42, "Test Player"));
-
-        // Media Player Name
-        assert_read_characteristic(
-            &mut server,
-            &fake_gatt_server,
-            &mut event_receiver,
-            MEDIA_PLAYER_NAME_HANDLE,
-            b"Test Player",
-        );
-
-        // Track Title
-        assert_read_characteristic(
-            &mut server,
-            &fake_gatt_server,
-            &mut event_receiver,
-            TRACK_TITLE_HANDLE,
-            b"",
-        );
-
-        // Track Duration
-        assert_read_characteristic(
-            &mut server,
-            &fake_gatt_server,
-            &mut event_receiver,
-            TRACK_DURATION_HANDLE,
-            &(-1i32).to_le_bytes(),
-        );
-
-        // Track Position
-        assert_read_characteristic(
-            &mut server,
-            &fake_gatt_server,
-            &mut event_receiver,
-            TRACK_POSITION_HANDLE,
-            &(-1i32).to_le_bytes(),
-        );
-
-        // Media State
-        assert_read_characteristic(
-            &mut server,
-            &fake_gatt_server,
-            &mut event_receiver,
-            MEDIA_STATE_HANDLE,
-            &[MediaState::Inactive.into()],
-        );
-
-        // Content Control ID
-        assert_read_characteristic(
-            &mut server,
-            &fake_gatt_server,
-            &mut event_receiver,
-            CONTENT_CONTROL_ID_HANDLE,
-            &[0x42],
-        );
-    }
-
-    #[test]
-    fn read_optional_characteristics_configured_values() {
-        let (mut server, fake_gatt_server, mut event_receiver) = setup_test_server(
-            McsServerBuilder::generic(0x42, "Test Player")
-                .with_icon_url("https://example.com/icon.png")
-                .with_player_speeds()
-                .with_playing_orders(
-                    SupportedPlayingOrders::IN_ORDER_ONCE | SupportedPlayingOrders::SHUFFLE_ONCE,
-                )
-                .with_supported_operations(SupportedOpcodes::PLAY | SupportedOpcodes::PAUSE),
-        );
-
-        // Media Player Icon URL
-        assert_read_characteristic(
-            &mut server,
-            &fake_gatt_server,
-            &mut event_receiver,
-            MEDIA_PLAYER_ICON_URL_HANDLE,
-            b"https://example.com/icon.png",
-        );
-
-        // Playback Speed
-        assert_read_characteristic(
-            &mut server,
-            &fake_gatt_server,
-            &mut event_receiver,
-            PLAYBACK_SPEED_HANDLE,
-            &[0],
-        );
-
-        // Seeking Speed
-        assert_read_characteristic(
-            &mut server,
-            &fake_gatt_server,
-            &mut event_receiver,
-            SEEKING_SPEED_HANDLE,
-            &[0],
-        );
-
-        // Playing Order
-        assert_read_characteristic(
-            &mut server,
-            &fake_gatt_server,
-            &mut event_receiver,
-            PLAYING_ORDER_HANDLE,
-            &[PlayingOrder::InOrderOnce.into()],
-        );
-
-        // Playing Orders Supported
-        let expected_orders =
-            SupportedPlayingOrders::IN_ORDER_ONCE | SupportedPlayingOrders::SHUFFLE_ONCE;
-        assert_read_characteristic(
-            &mut server,
-            &fake_gatt_server,
-            &mut event_receiver,
-            PLAYING_ORDERS_SUPPORTED_HANDLE,
-            &expected_orders.bits().to_le_bytes(),
-        );
-
-        // Media Control Point Opcodes Supported
-        let expected_opcodes = SupportedOpcodes::PLAY | SupportedOpcodes::PAUSE;
-        assert_read_characteristic(
-            &mut server,
-            &fake_gatt_server,
-            &mut event_receiver,
-            MEDIA_CONTROL_POINT_OPCODES_SUPPORTED_HANDLE,
-            &expected_opcodes.bits().to_le_bytes(),
-        );
-    }
-
-    #[test]
-    fn read_unconfigured_optional_characteristics_returns_invalid_handle() {
-        let (mut server, fake_gatt_server, mut event_receiver) =
-            setup_test_server(McsServerBuilder::generic(0x42, "Mandatory Only Player"));
-
-        let mut noop_cx = Context::from_waker(futures::task::noop_waker_ref());
-        let peer = PeerId(1);
-        let service_id = server.service_def.id();
-
-        let unconfigured_handles = [
-            MEDIA_PLAYER_ICON_URL_HANDLE,
-            PLAYBACK_SPEED_HANDLE,
-            SEEKING_SPEED_HANDLE,
-            PLAYING_ORDER_HANDLE,
-            PLAYING_ORDERS_SUPPORTED_HANDLE,
-            MEDIA_CONTROL_POINT_OPCODES_SUPPORTED_HANDLE,
-        ];
-
-        for handle in unconfigured_handles {
-            fake_gatt_server.incoming_read(peer, service_id, handle, 0);
-            let _ = server.next().poll_unpin(&mut noop_cx);
-            let bt_gatt::test_utils::FakeServerEvent::ReadResponded { value, .. } =
-                expect_service_event(&mut event_receiver)
-            else {
-                panic!("expected ReadResponded for handle {:?}", handle);
-            };
-            assert_matches!(
-                value.unwrap_err(),
-                bt_gatt::types::Error::Gatt(GattError::InvalidHandle),
-                "handle {:?} should return InvalidHandle when unconfigured",
-                handle
-            );
-        }
-    }
-
     #[test]
     fn write_unconfigured_optional_characteristics_returns_invalid_handle() {
         let (mut server, fake_gatt_server, mut event_receiver) =
@@ -1518,121 +902,6 @@
     }
 
     #[test]
-    fn read_string_characteristics_with_offset() {
-        let (mut server, fake_gatt_server, mut event_receiver) = setup_test_server(
-            McsServerBuilder::generic(0x42, "Long Player Name")
-                .with_icon_url("https://example.com/icon.png"),
-        );
-
-        let mut noop_cx = Context::from_waker(futures::task::noop_waker_ref());
-        let peer = PeerId(1);
-        let service_id = server.service_def.id();
-
-        // Valid offset slice for Player Name
-        fake_gatt_server.incoming_read(peer, service_id, MEDIA_PLAYER_NAME_HANDLE, 5);
-        let _ = server.next().poll_unpin(&mut noop_cx);
-        let bt_gatt::test_utils::FakeServerEvent::ReadResponded { value, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected ReadResponded");
-        };
-        assert_eq!(value.unwrap(), b"Player Name");
-
-        // Valid offset slice for Icon URL
-        fake_gatt_server.incoming_read(peer, service_id, MEDIA_PLAYER_ICON_URL_HANDLE, 8);
-        let _ = server.next().poll_unpin(&mut noop_cx);
-        let bt_gatt::test_utils::FakeServerEvent::ReadResponded { value, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected ReadResponded");
-        };
-        assert_eq!(value.unwrap(), b"example.com/icon.png");
-
-        // Exact end offset returns empty slice
-        fake_gatt_server.incoming_read(
-            peer,
-            service_id,
-            MEDIA_PLAYER_NAME_HANDLE,
-            "Long Player Name".len() as u32,
-        );
-        let _ = server.next().poll_unpin(&mut noop_cx);
-        let bt_gatt::test_utils::FakeServerEvent::ReadResponded { value, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected ReadResponded");
-        };
-        assert_eq!(value.unwrap(), b"");
-
-        // Out-of-bounds offset returns InvalidOffset
-        fake_gatt_server.incoming_read(peer, service_id, MEDIA_PLAYER_NAME_HANDLE, 100);
-        let _ = server.next().poll_unpin(&mut noop_cx);
-        let bt_gatt::test_utils::FakeServerEvent::ReadResponded { value, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected ReadResponded");
-        };
-        assert_matches!(value.unwrap_err(), bt_gatt::types::Error::Gatt(GattError::InvalidOffset));
-
-        // Out-of-bounds offset on Icon URL returns InvalidOffset
-        fake_gatt_server.incoming_read(peer, service_id, MEDIA_PLAYER_ICON_URL_HANDLE, 100);
-        let _ = server.next().poll_unpin(&mut noop_cx);
-        let bt_gatt::test_utils::FakeServerEvent::ReadResponded { value, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected ReadResponded");
-        };
-        assert_matches!(value.unwrap_err(), bt_gatt::types::Error::Gatt(GattError::InvalidOffset));
-    }
-
-    #[test]
-    fn read_non_readable_characteristics_returns_error() {
-        let mut noop_cx = Context::from_waker(futures::task::noop_waker_ref());
-        let (mut server, fake_gatt_server, mut event_receiver) = setup_test_server(
-            McsServerBuilder::generic(0x42, "Test Player")
-                .with_supported_operations(SupportedOpcodes::default()),
-        );
-
-        let peer = PeerId(1);
-        let service_id = server.service_def.id();
-
-        // Track Changed is notify-only
-        fake_gatt_server.incoming_read(peer, service_id, TRACK_CHANGED_HANDLE, 0);
-        let _ = server.next().poll_unpin(&mut noop_cx);
-        let bt_gatt::test_utils::FakeServerEvent::ReadResponded { value, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected ReadResponded");
-        };
-        assert_matches!(
-            value.unwrap_err(),
-            bt_gatt::types::Error::Gatt(GattError::ReadNotPermitted)
-        );
-
-        // Media Control Point is write/notify-only
-        fake_gatt_server.incoming_read(peer, service_id, MEDIA_CONTROL_POINT_HANDLE, 0);
-        let _ = server.next().poll_unpin(&mut noop_cx);
-        let bt_gatt::test_utils::FakeServerEvent::ReadResponded { value, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected ReadResponded");
-        };
-        assert_matches!(
-            value.unwrap_err(),
-            bt_gatt::types::Error::Gatt(GattError::ReadNotPermitted)
-        );
-
-        // Unknown handle returns InvalidHandle
-        fake_gatt_server.incoming_read(peer, service_id, Handle(999), 0);
-        let _ = server.next().poll_unpin(&mut noop_cx);
-        let bt_gatt::test_utils::FakeServerEvent::ReadResponded { value, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected ReadResponded");
-        };
-        assert_matches!(value.unwrap_err(), bt_gatt::types::Error::Gatt(GattError::InvalidHandle));
-    }
-
-    #[test]
     fn write_track_position_success() {
         let (mut server, fake_gatt_server, mut event_receiver) =
             setup_test_server(McsServerBuilder::generic(0x42, "Test Player"));
@@ -2747,163 +2016,4 @@
         };
         assert_eq!(value.unwrap(), vec![PlayingOrder::InOrderOnce.into()]);
     }
-
-    #[test]
-    fn local_state_handle_read() {
-        let mut state = McsLocalState::new(0x01, "Player");
-        state.media_state = MediaState::Paused;
-        state.playback_speed = Some(PlaybackSpeed::NORMAL);
-        state.playing_orders = Some(PlayingOrderState::new(SupportedPlayingOrders::all()));
-
-        // Track Position
-        assert_eq!(
-            state.handle_read(TRACK_POSITION_HANDLE, 0),
-            Ok(TrackPosition::Unavailable.raw_10ms().to_le_bytes().to_vec())
-        );
-
-        // Playback Speed
-        assert_eq!(state.handle_read(PLAYBACK_SPEED_HANDLE, 0), Ok(vec![0x00]));
-
-        // Playing Order
-        assert_eq!(
-            state.handle_read(PLAYING_ORDER_HANDLE, 0),
-            Ok(vec![PlayingOrder::InOrderOnce.into()])
-        );
-    }
-
-    #[test]
-    fn playing_order_state_helpers() {
-        let mut state = PlayingOrderState::new(SupportedPlayingOrders::IN_ORDER_ONCE);
-        assert_eq!(state.current, PlayingOrder::InOrderOnce);
-        assert_eq!(state.supported, SupportedPlayingOrders::IN_ORDER_ONCE);
-        assert!(!state.set_order(PlayingOrder::SingleOnce));
-        assert_eq!(state.current, PlayingOrder::InOrderOnce);
-        assert!(state.set_order(PlayingOrder::InOrderOnce));
-
-        let mut all_state = PlayingOrderState::new(SupportedPlayingOrders::all());
-        assert_eq!(all_state.current, PlayingOrder::InOrderOnce);
-        assert_eq!(all_state.supported, SupportedPlayingOrders::all());
-        assert!(all_state.set_order(PlayingOrder::ShuffleRepeat));
-        assert_eq!(all_state.current, PlayingOrder::ShuffleRepeat);
-    }
-
-    #[test]
-    fn local_state_track_position_calculation() {
-        let mut state = McsLocalState::new(0x01, "Test Player");
-
-        // When no track is loaded, position is Unavailable regardless of state.
-        assert_eq!(state.current_track_position(), TrackPosition::Unavailable);
-        state.media_state = MediaState::Playing;
-        assert_eq!(state.current_track_position(), TrackPosition::Unavailable);
-
-        // When paused or seeking with a loaded track, position does not advance with
-        // time.
-        state.media_state = MediaState::Paused;
-        state.track_position = TrackPosition::from_start(std::time::Duration::from_millis(5000));
-        state.position_updated_at =
-            Some(std::time::Instant::now() - std::time::Duration::from_secs(10));
-        assert_eq!(
-            state.current_track_position(),
-            TrackPosition::from_start(std::time::Duration::from_millis(5000))
-        );
-        state.media_state = MediaState::Seeking;
-        assert_eq!(
-            state.current_track_position(),
-            TrackPosition::from_start(std::time::Duration::from_millis(5000))
-        );
-
-        // When playing with a loaded track (FromStart), position advances based on
-        // elapsed time.
-        state.media_state = MediaState::Playing;
-        state.track_duration = TrackDuration::from_duration(std::time::Duration::from_secs(20));
-        state.track_position = TrackPosition::from_start(std::time::Duration::from_millis(5000));
-        state.position_updated_at =
-            Some(std::time::Instant::now() - std::time::Duration::from_millis(500));
-        let computed = state.current_track_position();
-        let TrackPosition::FromStart(dur) = computed else {
-            panic!("expected FromStart");
-        };
-        assert!(
-            dur >= std::time::Duration::from_millis(5450)
-                && dur <= std::time::Duration::from_millis(5650),
-            "unexpected computed position: {dur:?}"
-        );
-
-        // When elapsed time exceeds track duration, position is clamped to duration.
-        state.position_updated_at =
-            Some(std::time::Instant::now() - std::time::Duration::from_secs(100));
-        assert_eq!(
-            state.current_track_position(),
-            TrackPosition::from_start(std::time::Duration::from_secs(20))
-        );
-
-        // When playing with a track position relative to end (FromEnd), base is
-        // duration - offset.
-        state.track_duration = TrackDuration::from_duration(std::time::Duration::from_secs(30));
-        state.track_position = TrackPosition::from_end(std::time::Duration::from_secs(10));
-        state.position_updated_at =
-            Some(std::time::Instant::now() - std::time::Duration::from_millis(500));
-        // Base is 30s - 10s = 20s. Elapsed 500ms -> ~20.5s from start.
-        let computed = state.current_track_position();
-        let TrackPosition::FromStart(dur) = computed else {
-            panic!("expected FromStart");
-        };
-        assert!(
-            dur >= std::time::Duration::from_millis(20450)
-                && dur <= std::time::Duration::from_millis(20650),
-            "unexpected computed position: {dur:?}"
-        );
-
-        // When FromEnd elapsed time exceeds track duration, position is clamped to
-        // duration.
-        state.position_updated_at =
-            Some(std::time::Instant::now() - std::time::Duration::from_secs(100));
-        assert_eq!(
-            state.current_track_position(),
-            TrackPosition::from_start(std::time::Duration::from_secs(30))
-        );
-
-        // When FromEnd is used with unknown duration, it cannot resolve to FromStart
-        // and returns FromEnd.
-        state.track_duration = TrackDuration::Unknown;
-        state.track_position = TrackPosition::from_end(std::time::Duration::from_secs(10));
-        assert_eq!(
-            state.current_track_position(),
-            TrackPosition::from_end(std::time::Duration::from_secs(10))
-        );
-    }
-
-    #[test]
-    fn read_track_position_during_active_playback() {
-        let (mut server, fake_gatt_server, mut event_receiver) =
-            setup_test_server(McsServerBuilder::generic(0x42, "Test Player"));
-
-        // Set server state to Playing with a loaded track at position 500 (5.0
-        // seconds).
-        server.state.media_state = MediaState::Playing;
-        server.state.track_duration =
-            TrackDuration::from_duration(std::time::Duration::from_secs(60));
-        server.state.track_position =
-            TrackPosition::from_start(std::time::Duration::from_millis(5000));
-        server.state.position_updated_at =
-            Some(std::time::Instant::now() - std::time::Duration::from_millis(1000));
-
-        let mut noop_cx = Context::from_waker(futures::task::noop_waker_ref());
-        let peer = PeerId(1);
-        let service_id = server.service_def.id();
-        fake_gatt_server.incoming_read(peer, service_id, TRACK_POSITION_HANDLE, 0);
-        let _ = server.next().poll_unpin(&mut noop_cx);
-        let bt_gatt::test_utils::FakeServerEvent::ReadResponded { value, .. } =
-            expect_service_event(&mut event_receiver)
-        else {
-            panic!("expected ReadResponded");
-        };
-
-        let raw_bytes = value.unwrap();
-        assert_eq!(raw_bytes.len(), 4);
-        let raw_10ms = i32::from_le_bytes(raw_bytes.try_into().unwrap());
-        // 5000ms + 1000ms elapsed = 6000ms = 600 units of 10ms (allow minor jitter +/-
-        // 30 units)
-        assert!(raw_10ms >= 580 && raw_10ms <= 640, "unexpected raw_10ms: {raw_10ms}");
-    }
 }
diff --git a/rust/bt-mcs/src/server/event.rs b/rust/bt-mcs/src/server/event.rs
new file mode 100644
index 0000000..26fed15
--- /dev/null
+++ b/rust/bt-mcs/src/server/event.rs
@@ -0,0 +1,213 @@
+// Copyright 2026 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+use bt_common::PeerId;
+use futures::channel::oneshot;
+use futures::FutureExt;
+use std::future::Future;
+use std::pin::Pin;
+use std::task::{Context, Poll};
+
+use crate::types::*;
+
+/// Confirms the updated track position to store in local state and notify to
+/// clients.
+/// It is safe to drop without responding to ignore the update or if the value
+/// has not changed.
+pub type SetTrackPositionResponder = SetValueResponder<TrackPosition>;
+
+/// Confirms the updated playback speed to store in local state and notify to
+/// clients.
+/// It is safe to drop without responding to ignore the update or if the value
+/// has not changed.
+pub type SetPlaybackSpeedResponder = SetValueResponder<PlaybackSpeed>;
+
+/// Confirms the updated playing order to store in local state and notify to
+/// clients.
+/// It is safe to drop without responding to ignore the update or if the value
+/// has not changed.
+pub type SetPlayingOrderResponder = SetValueResponder<PlayingOrder>;
+
+/// Confirms the media control command result code to notify to the client.
+/// A response is expected to confirm the result. If no response is provided,
+/// then it is assumed that the Control Point request has failed and
+/// `ControlPointResultCode::CommandCannotBeCompleted` will be sent to the peer.
+pub type ControlPointWriteResponder = SetValueResponder<ControlPointResultCode>;
+
+/// Responder for an asynchronous characteristic write or control point command.
+///
+/// Calling [`send`](Self::send) confirms the new value or command result to
+/// update local state and notify clients. It is safe to drop the responder
+/// without responding to cancel the update (or report command failure).
+pub struct SetValueResponder<T> {
+    response_tx: oneshot::Sender<T>,
+}
+
+impl<T: std::fmt::Debug> SetValueResponder<T> {
+    /// Confirms the value or result code determined by the media player
+    /// application and dispatches the corresponding GATT notification.
+    pub fn send(self, value: T) {
+        if let Err(result) = self.response_tx.send(value) {
+            log::warn!("Failed to send response: server dropped or closed: {result:?}");
+        }
+    }
+}
+
+impl<T> std::fmt::Debug for SetValueResponder<T> {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        f.debug_struct("SetValueResponder").finish_non_exhaustive()
+    }
+}
+
+/// An in-flight handler for a single-value asynchronous write response.
+pub(crate) struct SetValueResponseFut<T> {
+    rx: oneshot::Receiver<T>,
+}
+
+impl<T> SetValueResponseFut<T> {
+    pub(crate) fn create() -> (Self, SetValueResponder<T>) {
+        let (tx, rx) = oneshot::channel();
+        (Self { rx }, SetValueResponder { response_tx: tx })
+    }
+}
+
+impl<T> Future for SetValueResponseFut<T> {
+    type Output = Option<T>;
+
+    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        self.rx.poll_unpin(cx).map(Result::ok)
+    }
+}
+
+/// Responses produced when an in-flight asynchronous write response completes.
+#[derive(Debug)]
+pub(crate) enum PendingWriteResponse {
+    ControlPoint {
+        peer_id: PeerId,
+        opcode: MediaControlOpcode,
+        result_code: ControlPointResultCode,
+    },
+    TrackPosition(TrackPosition),
+    PlaybackSpeed(PlaybackSpeed),
+    PlayingOrder(PlayingOrder),
+}
+
+/// An in-flight asynchronous write response future.
+pub(crate) enum PendingWriteResponseFut {
+    ControlPoint {
+        peer_id: PeerId,
+        opcode: MediaControlOpcode,
+        fut: SetValueResponseFut<ControlPointResultCode>,
+    },
+    TrackPosition(SetValueResponseFut<TrackPosition>),
+    PlaybackSpeed(SetValueResponseFut<PlaybackSpeed>),
+    PlayingOrder(SetValueResponseFut<PlayingOrder>),
+}
+
+impl Future for PendingWriteResponseFut {
+    type Output = Option<PendingWriteResponse>;
+
+    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        match self.as_mut().get_mut() {
+            Self::ControlPoint { peer_id, opcode, fut } => fut.poll_unpin(cx).map(|res| {
+                let code = res.unwrap_or(ControlPointResultCode::CommandCannotBeCompleted);
+                Some(PendingWriteResponse::ControlPoint {
+                    peer_id: *peer_id,
+                    opcode: opcode.clone(),
+                    result_code: code,
+                })
+            }),
+            Self::TrackPosition(fut) => {
+                fut.poll_unpin(cx).map(|res| res.map(PendingWriteResponse::TrackPosition))
+            }
+            Self::PlaybackSpeed(fut) => {
+                fut.poll_unpin(cx).map(|res| res.map(PendingWriteResponse::PlaybackSpeed))
+            }
+            Self::PlayingOrder(fut) => {
+                fut.poll_unpin(cx).map(|res| res.map(PendingWriteResponse::PlayingOrder))
+            }
+        }
+    }
+}
+
+/// Events produced by an [`McsServer`] stream representing client actions that
+/// require additional upper-layer application processing.
+#[derive(Debug)]
+pub enum McsServerEvent {
+    /// Request to set the track playback position.
+    SetTrackPosition {
+        peer_id: PeerId,
+        position: TrackPosition,
+        responder: SetValueResponder<TrackPosition>,
+    },
+    /// Request to set the playback speed.
+    SetPlaybackSpeed {
+        peer_id: PeerId,
+        speed: PlaybackSpeed,
+        responder: SetValueResponder<PlaybackSpeed>,
+    },
+    /// Request to set the playing order.
+    SetPlayingOrder {
+        peer_id: PeerId,
+        order: PlayingOrder,
+        responder: SetValueResponder<PlayingOrder>,
+    },
+    /// Request to execute a media control command.
+    ControlPointCommand {
+        opcode: MediaControlOpcode,
+        responder: SetValueResponder<ControlPointResultCode>,
+    },
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use assert_matches::assert_matches;
+
+    #[test]
+    fn set_value_responder_and_fut() {
+        let (mut fut, responder) = SetValueResponseFut::<PlaybackSpeed>::create();
+        let mut cx = Context::from_waker(futures::task::noop_waker_ref());
+
+        assert!(fut.poll_unpin(&mut cx).is_pending());
+
+        responder.send(PlaybackSpeed::DOUBLE);
+        assert_eq!(fut.poll_unpin(&mut cx), Poll::Ready(Some(PlaybackSpeed::DOUBLE)));
+    }
+
+    #[test]
+    fn set_value_responder_dropped_results_in_none() {
+        let (mut fut, responder) = SetValueResponseFut::<TrackPosition>::create();
+        let mut cx = Context::from_waker(futures::task::noop_waker_ref());
+
+        assert!(fut.poll_unpin(&mut cx).is_pending());
+
+        drop(responder);
+        assert_eq!(fut.poll_unpin(&mut cx), Poll::Ready(None));
+    }
+
+    #[test]
+    fn pending_write_response_control_point_dropped_defaults_to_cannot_be_completed() {
+        let (fut, responder) = SetValueResponseFut::<ControlPointResultCode>::create();
+        let peer_id = PeerId(1);
+        let mut pending = PendingWriteResponseFut::ControlPoint {
+            peer_id,
+            opcode: MediaControlOpcode::Play,
+            fut,
+        };
+        let mut cx = Context::from_waker(futures::task::noop_waker_ref());
+
+        assert!(pending.poll_unpin(&mut cx).is_pending());
+
+        drop(responder);
+        assert_matches!(
+            pending.poll_unpin(&mut cx),
+            Poll::Ready(Some(PendingWriteResponse::ControlPoint {
+                peer_id: p,
+                opcode: MediaControlOpcode::Play,
+                result_code: ControlPointResultCode::CommandCannotBeCompleted,
+            })) if p == peer_id
+        );
+    }
+}
diff --git a/rust/bt-mcs/src/server/state.rs b/rust/bt-mcs/src/server/state.rs
new file mode 100644
index 0000000..aafa445
--- /dev/null
+++ b/rust/bt-mcs/src/server/state.rs
@@ -0,0 +1,513 @@
+// Copyright 2026 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+use bt_common::Uuid;
+use bt_gatt::types::{
+    AttributePermissions, CharacteristicProperties, CharacteristicProperty, GattError, Handle,
+    SecurityLevels,
+};
+use bt_gatt::Characteristic;
+
+use crate::types::*;
+
+// ============================================================================
+// Characteristic Definitions & Handles (MCS v1.0.1 Section 3)
+// ============================================================================
+
+/// Handle assigned to the Media Player Name characteristic.
+pub(crate) const MEDIA_PLAYER_NAME_HANDLE: Handle = Handle(1);
+/// Handle assigned to the Track Changed characteristic.
+pub(crate) const TRACK_CHANGED_HANDLE: Handle = Handle(2);
+/// Handle assigned to the Track Title characteristic.
+pub(crate) const TRACK_TITLE_HANDLE: Handle = Handle(3);
+/// Handle assigned to the Track Duration characteristic.
+pub(crate) const TRACK_DURATION_HANDLE: Handle = Handle(4);
+/// Handle assigned to the Track Position characteristic.
+pub(crate) const TRACK_POSITION_HANDLE: Handle = Handle(5);
+/// Handle assigned to the Media State characteristic.
+pub(crate) const MEDIA_STATE_HANDLE: Handle = Handle(6);
+/// Handle assigned to the Content Control ID (CCID) characteristic.
+pub(crate) const CONTENT_CONTROL_ID_HANDLE: Handle = Handle(7);
+
+// ============================================================================
+// Optional Characteristic Handle Definitions (MCS v1.0.1 Section 3)
+// ============================================================================
+
+/// Handle assigned to the Media Player Icon URL characteristic.
+pub(crate) const MEDIA_PLAYER_ICON_URL_HANDLE: Handle = Handle(8);
+/// Handle assigned to the Playback Speed characteristic.
+pub(crate) const PLAYBACK_SPEED_HANDLE: Handle = Handle(9);
+/// Handle assigned to the Seeking Speed characteristic.
+pub(crate) const SEEKING_SPEED_HANDLE: Handle = Handle(10);
+/// Handle assigned to the Playing Order characteristic.
+pub(crate) const PLAYING_ORDER_HANDLE: Handle = Handle(11);
+/// Handle assigned to the Playing Orders Supported characteristic.
+pub(crate) const PLAYING_ORDERS_SUPPORTED_HANDLE: Handle = Handle(12);
+/// Handle assigned to the Media Control Point characteristic.
+pub(crate) const MEDIA_CONTROL_POINT_HANDLE: Handle = Handle(13);
+/// Handle assigned to the Media Control Point Opcodes Supported characteristic.
+pub(crate) const MEDIA_CONTROL_POINT_OPCODES_SUPPORTED_HANDLE: Handle = Handle(14);
+
+/// Constructs a characteristic definition with the specified handle, UUID,
+/// properties, and encryption-required permissions conforming to MCS v1.0.1
+/// Section 3.
+pub(crate) fn build_characteristic(
+    handle: Handle,
+    uuid: Uuid,
+    properties: impl Into<CharacteristicProperties>,
+) -> Characteristic {
+    let properties = properties.into();
+    Characteristic {
+        handle,
+        uuid,
+        properties,
+        permissions: AttributePermissions::with_levels(
+            &properties,
+            &SecurityLevels::encryption_required(),
+        ),
+        descriptors: Vec::new(),
+    }
+}
+
+/// The mandatory characteristics defined in MCS v1.0.1 Section 3, Table 3.1.
+pub(crate) fn mandatory_characteristics() -> [Characteristic; 7] {
+    [
+        build_characteristic(
+            MEDIA_PLAYER_NAME_HANDLE,
+            MEDIA_PLAYER_NAME_UUID,
+            CharacteristicProperties::READ_NOTIFY,
+        ),
+        build_characteristic(
+            TRACK_CHANGED_HANDLE,
+            TRACK_CHANGED_UUID,
+            CharacteristicProperty::Notify,
+        ),
+        build_characteristic(
+            TRACK_TITLE_HANDLE,
+            TRACK_TITLE_UUID,
+            CharacteristicProperties::READ_NOTIFY,
+        ),
+        build_characteristic(
+            TRACK_DURATION_HANDLE,
+            TRACK_DURATION_UUID,
+            CharacteristicProperties::READ_NOTIFY,
+        ),
+        build_characteristic(
+            TRACK_POSITION_HANDLE,
+            TRACK_POSITION_UUID,
+            CharacteristicProperties::READ_WRITE_NOTIFY,
+        ),
+        build_characteristic(
+            MEDIA_STATE_HANDLE,
+            MEDIA_STATE_UUID,
+            CharacteristicProperties::READ_NOTIFY,
+        ),
+        build_characteristic(
+            CONTENT_CONTROL_ID_HANDLE,
+            CONTENT_CONTROL_ID_UUID,
+            CharacteristicProperty::Read,
+        ),
+    ]
+}
+
+/// Local state of the characteristics in this server.
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub(crate) struct McsLocalState {
+    /// Content Control ID (CCID) identifying this media service instance.
+    pub(crate) ccid: u8,
+    /// Human-readable media player application name.
+    pub(crate) player_name: String,
+    /// Title of the currently selected track (empty if no track loaded).
+    pub(crate) track_title: String,
+    /// Total duration of the current track (MCS v1.0.1 Section 3.6).
+    pub(crate) track_duration: TrackDuration,
+    /// Base playback position of the current track (MCS v1.0.1 Section 3.7).
+    pub(crate) track_position: TrackPosition,
+    /// Timestamp when `track_position` was set or updated.
+    pub(crate) position_updated_at: Option<std::time::Instant>,
+    /// Current player activity state.
+    pub(crate) media_state: MediaState,
+    /// URL pointing to media player icon graphic, if supported.
+    pub(crate) icon_url: Option<String>,
+    /// Playback speed multiplier, if supported.
+    pub(crate) playback_speed: Option<PlaybackSpeed>,
+    /// Seeking speed factor, if supported.
+    pub(crate) seeking_speed: Option<SeekingSpeed>,
+    /// Playing order and supported playing orders, if supported.
+    pub(crate) playing_orders: Option<PlayingOrderState>,
+    /// Supported media control point opcodes, if Media Control Point is
+    /// supported.
+    pub(crate) supported_opcodes: Option<SupportedOpcodes>,
+}
+
+impl McsLocalState {
+    /// Creates a new [`McsLocalState`] with default values for an inactive
+    /// player with no track loaded per MCS v1.0.1 Section 3.
+    pub(crate) fn new(ccid: u8, player_name: impl Into<String>) -> Self {
+        Self {
+            ccid,
+            player_name: player_name.into(),
+            track_title: String::new(),
+            track_duration: TrackDuration::Unknown,
+            track_position: TrackPosition::Unavailable,
+            position_updated_at: None,
+            media_state: MediaState::Inactive,
+            icon_url: None,
+            playback_speed: None,
+            seeking_speed: None,
+            playing_orders: None,
+            supported_opcodes: None,
+        }
+    }
+
+    /// Calculates the instantaneous track position based on elapsed playback
+    /// time (MCS v1.0.1 Section 3.7).
+    pub(crate) fn current_track_position(&self) -> TrackPosition {
+        // Per MCS Section 3.17, an inactive player has no current track, so it is
+        // unavailable.
+        if self.media_state == MediaState::Inactive {
+            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)
+            }
+            _ => 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);
+        }
+        TrackPosition::FromStart(current)
+    }
+
+    /// 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());
+    }
+
+    /// 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;
+            }
+        }
+    }
+
+    #[cfg(test)]
+    pub(crate) fn set_media_state(&mut self, state: MediaState) {
+        self.media_state = state;
+    }
+
+    #[cfg(test)]
+    pub(crate) fn set_supported_opcodes(&mut self, opcodes: SupportedOpcodes) {
+        self.supported_opcodes = Some(opcodes);
+    }
+
+    /// Reads the characteristic bytes for `handle` at `offset`.
+    pub(crate) fn handle_read(&self, handle: Handle, offset: usize) -> Result<Vec<u8>, GattError> {
+        let read_at_offset =
+            |bytes: &[u8]| bytes.get(offset..).map(Vec::from).ok_or(GattError::InvalidOffset);
+
+        match handle {
+            // Track Changed and Media Control Point are not readable per MCS v1.0.1 Section 3,
+            // Table 3.1.
+            TRACK_CHANGED_HANDLE | MEDIA_CONTROL_POINT_HANDLE => Err(GattError::ReadNotPermitted),
+            MEDIA_PLAYER_NAME_HANDLE => read_at_offset(self.player_name.as_bytes()),
+            TRACK_TITLE_HANDLE => read_at_offset(self.track_title.as_bytes()),
+            TRACK_DURATION_HANDLE => read_at_offset(&self.track_duration.raw_10ms().to_le_bytes()),
+            TRACK_POSITION_HANDLE => {
+                read_at_offset(&self.current_track_position().raw_10ms().to_le_bytes())
+            }
+            MEDIA_STATE_HANDLE => read_at_offset(&[self.media_state.into()]),
+            CONTENT_CONTROL_ID_HANDLE => read_at_offset(&[self.ccid]),
+            MEDIA_PLAYER_ICON_URL_HANDLE => {
+                let url = self.icon_url.as_ref().ok_or(GattError::InvalidHandle)?;
+                read_at_offset(url.as_bytes())
+            }
+            PLAYBACK_SPEED_HANDLE => {
+                let speed = self.playback_speed.ok_or(GattError::InvalidHandle)?;
+                read_at_offset(&[speed.into()])
+            }
+            SEEKING_SPEED_HANDLE => {
+                let speed = self.seeking_speed.ok_or(GattError::InvalidHandle)?;
+                read_at_offset(&[speed.into()])
+            }
+            PLAYING_ORDER_HANDLE => {
+                let orders = self.playing_orders.as_ref().ok_or(GattError::InvalidHandle)?;
+                read_at_offset(&[orders.current.into()])
+            }
+            PLAYING_ORDERS_SUPPORTED_HANDLE => {
+                let orders = self.playing_orders.as_ref().ok_or(GattError::InvalidHandle)?;
+                read_at_offset(&orders.supported.bits().to_le_bytes())
+            }
+            MEDIA_CONTROL_POINT_OPCODES_SUPPORTED_HANDLE => {
+                let opcodes = self.supported_opcodes.ok_or(GattError::InvalidHandle)?;
+                read_at_offset(&opcodes.bits().to_le_bytes())
+            }
+            _ => Err(GattError::InvalidHandle),
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use assert_matches::assert_matches;
+    use std::time::Duration;
+
+    #[test]
+    fn local_state_set_playing_order() {
+        let mut state = McsLocalState::new(0x01, "Player");
+        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_eq!(state.playing_orders.as_ref().unwrap().current, PlayingOrder::SingleOnce);
+
+        // Unsupported playing order is not applied
+        state.set_playing_order(PlayingOrder::ShuffleOnce);
+        assert_eq!(state.playing_orders.as_ref().unwrap().current, PlayingOrder::SingleOnce);
+    }
+
+    #[test]
+    fn local_state_handle_read() {
+        let mut state = McsLocalState::new(0x01, "Player");
+        state.media_state = MediaState::Paused;
+        state.playback_speed = Some(PlaybackSpeed::NORMAL);
+        state.playing_orders = Some(PlayingOrderState::new(SupportedPlayingOrders::all()));
+
+        // Track Position
+        assert_eq!(
+            state.handle_read(TRACK_POSITION_HANDLE, 0),
+            Ok(TrackPosition::Unavailable.raw_10ms().to_le_bytes().to_vec())
+        );
+
+        // Playback Speed
+        assert_eq!(state.handle_read(PLAYBACK_SPEED_HANDLE, 0), Ok(vec![0x00]));
+
+        // Playing Order
+        assert_eq!(
+            state.handle_read(PLAYING_ORDER_HANDLE, 0),
+            Ok(vec![PlayingOrder::InOrderOnce.into()])
+        );
+    }
+
+    #[test]
+    fn local_state_track_position_calculation() {
+        let mut state = McsLocalState::new(0x01, "Player");
+        state.track_duration = TrackDuration::from_raw_10ms(1000);
+
+        // Inactive player always has unavailable track position
+        state.media_state = MediaState::Inactive;
+        state.track_position = TrackPosition::from_raw_10ms(500);
+        assert_eq!(state.current_track_position(), TrackPosition::Unavailable);
+
+        // Paused player returns base track position
+        state.media_state = MediaState::Paused;
+        assert_eq!(state.current_track_position(), TrackPosition::from_raw_10ms(500));
+
+        // Playing player calculates elapsed time
+        state.media_state = MediaState::Playing;
+        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(6900) && dur <= Duration::from_millis(7200));
+            }
+            other => panic!("Expected FromStart duration, got {other:?}"),
+        }
+
+        // Clamped to total duration
+        state.position_updated_at = Some(std::time::Instant::now() - Duration::from_secs(20));
+        assert_eq!(state.current_track_position(), TrackPosition::from_raw_10ms(1000));
+    }
+
+    #[test]
+    fn read_mandatory_characteristics_default_values() {
+        let state = McsLocalState::new(0x05, "Test Player");
+
+        assert_eq!(state.handle_read(MEDIA_PLAYER_NAME_HANDLE, 0), Ok(b"Test Player".to_vec()));
+        assert_eq!(state.handle_read(TRACK_TITLE_HANDLE, 0), Ok(b"".to_vec()));
+        assert_eq!(
+            state.handle_read(TRACK_DURATION_HANDLE, 0),
+            Ok(TrackDuration::Unknown.raw_10ms().to_le_bytes().to_vec())
+        );
+        assert_eq!(
+            state.handle_read(TRACK_POSITION_HANDLE, 0),
+            Ok(TrackPosition::Unavailable.raw_10ms().to_le_bytes().to_vec())
+        );
+        assert_eq!(state.handle_read(MEDIA_STATE_HANDLE, 0), Ok(vec![MediaState::Inactive.into()]));
+        assert_eq!(state.handle_read(CONTENT_CONTROL_ID_HANDLE, 0), Ok(vec![0x05]));
+    }
+
+    #[test]
+    fn read_optional_characteristics_configured_values() {
+        let mut state = McsLocalState::new(0x01, "Player");
+        state.icon_url = Some("https://example.com/icon.png".to_string());
+        state.playback_speed = Some(PlaybackSpeed::DOUBLE);
+        state.seeking_speed = Some(SeekingSpeed::new(10));
+        state.playing_orders = Some(PlayingOrderState::new(SupportedPlayingOrders::SHUFFLE_ONCE));
+        state.supported_opcodes = Some(SupportedOpcodes::PLAY | SupportedOpcodes::PAUSE);
+
+        assert_eq!(
+            state.handle_read(MEDIA_PLAYER_ICON_URL_HANDLE, 0),
+            Ok(b"https://example.com/icon.png".to_vec())
+        );
+        assert_eq!(
+            state.handle_read(PLAYBACK_SPEED_HANDLE, 0),
+            Ok(vec![PlaybackSpeed::DOUBLE.into()])
+        );
+        assert_eq!(
+            state.handle_read(SEEKING_SPEED_HANDLE, 0),
+            Ok(vec![SeekingSpeed::new(10).into()])
+        );
+        assert_eq!(
+            state.handle_read(PLAYING_ORDER_HANDLE, 0),
+            Ok(vec![PlayingOrder::InOrderOnce.into()])
+        );
+        assert_eq!(
+            state.handle_read(PLAYING_ORDERS_SUPPORTED_HANDLE, 0),
+            Ok(SupportedPlayingOrders::SHUFFLE_ONCE.bits().to_le_bytes().to_vec())
+        );
+        assert_eq!(
+            state.handle_read(MEDIA_CONTROL_POINT_OPCODES_SUPPORTED_HANDLE, 0),
+            Ok((SupportedOpcodes::PLAY | SupportedOpcodes::PAUSE).bits().to_le_bytes().to_vec())
+        );
+    }
+
+    #[test]
+    fn read_string_characteristics_with_offset() {
+        let mut state = McsLocalState::new(0x01, "Long Player Name");
+        state.track_title = "Track Number 1".to_string();
+        state.icon_url = Some("https://example.com".to_string());
+
+        assert_eq!(state.handle_read(MEDIA_PLAYER_NAME_HANDLE, 5), Ok(b"Player Name".to_vec()));
+        assert_eq!(state.handle_read(TRACK_TITLE_HANDLE, 6), Ok(b"Number 1".to_vec()));
+        assert_eq!(state.handle_read(MEDIA_PLAYER_ICON_URL_HANDLE, 8), Ok(b"example.com".to_vec()));
+
+        assert_matches!(
+            state.handle_read(MEDIA_PLAYER_NAME_HANDLE, 100),
+            Err(GattError::InvalidOffset)
+        );
+    }
+
+    #[test]
+    fn read_track_position_during_active_playback() {
+        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(200);
+        state.position_updated_at = Some(std::time::Instant::now() - Duration::from_millis(500));
+
+        let res = state.handle_read(TRACK_POSITION_HANDLE, 0).expect("read should succeed");
+        let raw = i32::from_le_bytes(res.try_into().unwrap());
+        assert!(raw >= 240 && raw <= 260, "Expected track position ~250 (10ms units), got {raw}");
+    }
+
+    #[test]
+    fn read_unconfigured_optional_characteristics_returns_invalid_handle() {
+        let state = McsLocalState::new(0x01, "Player");
+
+        let optional_handles = [
+            MEDIA_PLAYER_ICON_URL_HANDLE,
+            PLAYBACK_SPEED_HANDLE,
+            SEEKING_SPEED_HANDLE,
+            PLAYING_ORDER_HANDLE,
+            PLAYING_ORDERS_SUPPORTED_HANDLE,
+            MEDIA_CONTROL_POINT_OPCODES_SUPPORTED_HANDLE,
+        ];
+
+        for handle in optional_handles {
+            assert_matches!(
+                state.handle_read(handle, 0),
+                Err(GattError::InvalidHandle),
+                "Handle {:?} should return InvalidHandle when not configured",
+                handle
+            );
+        }
+    }
+
+    #[test]
+    fn read_non_readable_characteristics_returns_error() {
+        let mut state = McsLocalState::new(0x01, "Player");
+        state.supported_opcodes = Some(SupportedOpcodes::all());
+
+        assert_matches!(
+            state.handle_read(TRACK_CHANGED_HANDLE, 0),
+            Err(GattError::ReadNotPermitted)
+        );
+        assert_matches!(
+            state.handle_read(MEDIA_CONTROL_POINT_HANDLE, 0),
+            Err(GattError::ReadNotPermitted)
+        );
+    }
+
+    #[test]
+    fn mandatory_characteristics_properties_and_permissions() {
+        let mandatory = mandatory_characteristics();
+        assert_eq!(mandatory.len(), 7);
+
+        assert_eq!(mandatory[0].handle, MEDIA_PLAYER_NAME_HANDLE);
+        assert_eq!(mandatory[0].uuid, MEDIA_PLAYER_NAME_UUID);
+        assert_eq!(mandatory[0].properties, CharacteristicProperties::READ_NOTIFY);
+
+        assert_eq!(mandatory[1].handle, TRACK_CHANGED_HANDLE);
+        assert_eq!(mandatory[1].uuid, TRACK_CHANGED_UUID);
+        assert_eq!(
+            mandatory[1].properties,
+            CharacteristicProperties::from(CharacteristicProperty::Notify)
+        );
+
+        assert_eq!(mandatory[2].handle, TRACK_TITLE_HANDLE);
+        assert_eq!(mandatory[2].uuid, TRACK_TITLE_UUID);
+        assert_eq!(mandatory[2].properties, CharacteristicProperties::READ_NOTIFY);
+
+        assert_eq!(mandatory[3].handle, TRACK_DURATION_HANDLE);
+        assert_eq!(mandatory[3].uuid, TRACK_DURATION_UUID);
+        assert_eq!(mandatory[3].properties, CharacteristicProperties::READ_NOTIFY);
+
+        assert_eq!(mandatory[4].handle, TRACK_POSITION_HANDLE);
+        assert_eq!(mandatory[4].uuid, TRACK_POSITION_UUID);
+        assert_eq!(mandatory[4].properties, CharacteristicProperties::READ_WRITE_NOTIFY);
+
+        assert_eq!(mandatory[5].handle, MEDIA_STATE_HANDLE);
+        assert_eq!(mandatory[5].uuid, MEDIA_STATE_UUID);
+        assert_eq!(mandatory[5].properties, CharacteristicProperties::READ_NOTIFY);
+
+        assert_eq!(mandatory[6].handle, CONTENT_CONTROL_ID_HANDLE);
+        assert_eq!(mandatory[6].uuid, CONTENT_CONTROL_ID_UUID);
+        assert_eq!(
+            mandatory[6].properties,
+            CharacteristicProperties::from(CharacteristicProperty::Read)
+        );
+
+        for chrc in &mandatory {
+            assert!(chrc.permissions.read.map_or(true, |s| s.encryption));
+            assert!(chrc.permissions.write.map_or(true, |s| s.encryption));
+            assert!(chrc.permissions.update.map_or(true, |s| s.encryption));
+        }
+    }
+}
