diff --git a/rust/bt-bass/Cargo.toml b/rust/bt-bass/Cargo.toml
index 51fe888..533e06b 100644
--- a/rust/bt-bass/Cargo.toml
+++ b/rust/bt-bass/Cargo.toml
@@ -14,6 +14,7 @@
 bt-gatt = { workspace = true, features = ["test-utils"] }
 futures.workspace = true
 log.workspace = true
+pin-project.workspace = true
 parking_lot.workspace = true
 thiserror.workspace = true
 
diff --git a/rust/bt-bass/src/lib.rs b/rust/bt-bass/src/lib.rs
index 1f8980b..e32b283 100644
--- a/rust/bt-bass/src/lib.rs
+++ b/rust/bt-bass/src/lib.rs
@@ -3,8 +3,10 @@
 // found in the LICENSE file.
 
 pub mod client;
+pub mod server;
 pub mod types;
-pub use crate::client::error::Error;
+pub use crate::client::error::Error as ClientError;
+pub use crate::server::Error as ServerError;
 
 #[cfg(any(test, feature = "test-utils"))]
 pub mod test_utils;
diff --git a/rust/bt-bass/src/server.rs b/rust/bt-bass/src/server.rs
new file mode 100644
index 0000000..4521795
--- /dev/null
+++ b/rust/bt-bass/src/server.rs
@@ -0,0 +1,475 @@
+// 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.
+
+//! Implements the Broadcast Audio Scan Service (BASS) server role.
+
+use bt_gatt::server::{LocalService, Server as _, ServiceDefinition, ServiceId};
+use bt_gatt::types::{
+    AttributePermissions, CharacteristicProperty, Handle, SecurityLevels, ServiceKind,
+};
+use bt_gatt::Characteristic;
+use futures::Future;
+use pin_project::pin_project;
+use std::collections::HashMap;
+
+use crate::types::{
+    BroadcastReceiveState, SourceId, BROADCAST_AUDIO_SCAN_CONTROL_POINT_UUID,
+    BROADCAST_AUDIO_SCAN_SERVICE_UUID, BROADCAST_RECEIVE_STATE_UUID,
+};
+
+pub mod error;
+pub use error::Error;
+
+/// Service identifier assigned to the published BASS GATT service instance.
+const BASS_SERVICE_ID: ServiceId = ServiceId::new(1);
+
+/// Handle assigned to the Broadcast Audio Scan Control Point characteristic.
+const CONTROL_POINT_HANDLE: Handle = Handle(1);
+
+/// Maximum number of Broadcast Receive State characteristics that can be hosted
+/// by the server. See BASS v1.0 Section 3.2.1.
+const MAX_RECEIVE_STATES: usize = 255;
+
+/// Internal representation of a Broadcast Receive State characteristic slot.
+/// See BASS v1.0 Section 3.2.
+#[derive(Debug)]
+pub(crate) struct PublishedReceiveStateCharacteristic {
+    /// 1-indexed source identifier.
+    /// See BASS v1.0 Section 3.2.1.
+    source_id: SourceId,
+    /// Handle assigned to this GATT characteristic.
+    handle: Handle,
+    /// Current Broadcast Receive State value.
+    state: BroadcastReceiveState,
+}
+
+/// Internal publication state lifecycle of the BASS GATT service.
+#[pin_project(project = LocalServiceProj)]
+enum LocalServiceState<T: bt_gatt::ServerTypes> {
+    /// Service definition has not been registered in the GATT database.
+    NotPublished,
+    /// Service registration is in progress.
+    Preparing {
+        #[pin]
+        fut: T::LocalServiceFut,
+    },
+    /// Service registration is complete and active in the GATT database.
+    Published { service: T::LocalService },
+}
+
+impl<T: bt_gatt::ServerTypes> Default for LocalServiceState<T> {
+    fn default() -> Self {
+        Self::NotPublished
+    }
+}
+
+impl<T: bt_gatt::ServerTypes> LocalServiceState<T> {
+    fn is_published(&self) -> bool {
+        matches!(self, LocalServiceState::Published { .. })
+    }
+
+    fn poll_publish(
+        mut self: std::pin::Pin<&mut Self>,
+        cx: &mut std::task::Context<'_>,
+    ) -> std::task::Poll<Result<(), Error>> {
+        match self.as_mut().project() {
+            LocalServiceProj::NotPublished => std::task::Poll::Pending,
+            LocalServiceProj::Preparing { fut } => {
+                let service_result = futures::ready!(fut.poll(cx));
+                match service_result {
+                    Ok(service) => {
+                        let _ = service.publish();
+                        self.set(LocalServiceState::Published { service });
+                        std::task::Poll::Ready(Ok(()))
+                    }
+                    Err(e) => {
+                        self.set(LocalServiceState::NotPublished);
+                        std::task::Poll::Ready(Err(Error::Gatt(e)))
+                    }
+                }
+            }
+            LocalServiceProj::Published { .. } => std::task::Poll::Ready(Ok(())),
+        }
+    }
+}
+
+/// Builder for constructing a BASS GATT [`Server`].
+#[derive(Default)]
+pub struct ServerBuilder {
+    /// Staged Broadcast Receive State characteristics.
+    /// There must be at least one such staged characteristic.
+    receive_states: Vec<BroadcastReceiveState>,
+}
+
+impl ServerBuilder {
+    pub fn new() -> Self {
+        Self::default()
+    }
+
+    /// Adds a Broadcast Receive State characteristic slot to the builder.
+    pub fn add_receive_state_characteristic(mut self, state: BroadcastReceiveState) -> Self {
+        self.receive_states.push(state);
+        self
+    }
+
+    /// Constructs the Broadcast Audio Scan Control Point characteristic.
+    /// Defined in BASS v1.0 Section 3.1.
+    fn build_control_point() -> Characteristic {
+        let cp_properties =
+            CharacteristicProperty::Write | CharacteristicProperty::WriteWithoutResponse;
+        Characteristic {
+            handle: CONTROL_POINT_HANDLE,
+            uuid: BROADCAST_AUDIO_SCAN_CONTROL_POINT_UUID,
+            properties: cp_properties.clone(),
+            permissions: AttributePermissions::with_levels(
+                &cp_properties,
+                &SecurityLevels::encryption_required(),
+            ),
+            descriptors: Vec::new(),
+        }
+    }
+
+    /// Constructs the Broadcast Receive State characteristic.
+    /// Defined in BASS v1.0 Section 3.2.
+    fn build_receive_state(handle: Handle) -> Characteristic {
+        let properties = CharacteristicProperty::Read | CharacteristicProperty::Notify;
+        Characteristic {
+            handle,
+            uuid: BROADCAST_RECEIVE_STATE_UUID,
+            properties: properties.clone(),
+            permissions: AttributePermissions::with_levels(
+                &properties,
+                &SecurityLevels::encryption_required(),
+            ),
+            descriptors: Vec::new(),
+        }
+    }
+
+    /// Builds a [`Server`] instance after verifying required service
+    /// characteristics.
+    pub fn build<T: bt_gatt::ServerTypes>(self) -> Result<Server<T>, Error> {
+        // Per BASS v1.0 Section 3.2, there must be [1,255] Broadcast Receive State
+        // characteristics.
+        if self.receive_states.is_empty() {
+            return Err(Error::MissingReceiveState);
+        }
+        if self.receive_states.len() > MAX_RECEIVE_STATES {
+            return Err(Error::ExceedsMaxReceiveStates);
+        }
+
+        let mut service_def = ServiceDefinition::new(
+            BASS_SERVICE_ID,
+            BROADCAST_AUDIO_SCAN_SERVICE_UUID,
+            ServiceKind::Primary,
+        );
+
+        let _ = service_def.add_characteristic(Self::build_control_point());
+
+        // Broadcast Receive State characteristics (Read, Notify; Encryption Required)
+        const FIRST_RECEIVE_STATE_HANDLE: Handle = Handle(2);
+        let num_receive_states = self.receive_states.len();
+        let mut receive_state_characteristics = HashMap::with_capacity(num_receive_states);
+        let mut source_id_to_handle = HashMap::with_capacity(num_receive_states);
+        for (i, mut state) in self.receive_states.into_iter().enumerate() {
+            let source_id = (i + 1) as u8;
+            let handle = Handle(FIRST_RECEIVE_STATE_HANDLE.0 + i as u64);
+            let _ = service_def.add_characteristic(Self::build_receive_state(handle));
+
+            // Override Source ID as this is assigned by the server. See BASS v1.0 Section
+            // 3.2.1.
+            if let BroadcastReceiveState::NonEmpty(ref mut receive_state) = state {
+                receive_state.source_id = source_id;
+            }
+
+            receive_state_characteristics
+                .insert(handle, PublishedReceiveStateCharacteristic { source_id, handle, state });
+            source_id_to_handle.insert(source_id, handle);
+        }
+
+        let next_source_id = (num_receive_states + 1) as SourceId;
+
+        Ok(Server {
+            service_def,
+            local_service: Default::default(),
+            control_point_handle: CONTROL_POINT_HANDLE,
+            receive_state_characteristics,
+            source_id_to_handle,
+            next_source_id,
+        })
+    }
+}
+
+/// The BASS GATT Server implementation.
+///
+/// Manages the Control Point characteristic and one or more Broadcast Receive
+/// State characteristics.
+#[pin_project]
+pub struct Server<T: bt_gatt::ServerTypes> {
+    service_def: ServiceDefinition,
+    #[pin]
+    local_service: LocalServiceState<T>,
+    control_point_handle: Handle,
+    /// Broadcast Receive State characteristics mapped by GATT handle.
+    receive_state_characteristics: HashMap<Handle, PublishedReceiveStateCharacteristic>,
+    /// Map from Source ID to characteristic handle.
+    source_id_to_handle: HashMap<SourceId, Handle>,
+    /// Next available Source ID to be assigned to an empty Receive State
+    /// characteristic.
+    next_source_id: SourceId,
+}
+
+impl<T: bt_gatt::ServerTypes> Server<T> {
+    /// Returns true if the server has successfully published the GATT service.
+    pub fn is_published(&self) -> bool {
+        self.local_service.is_published()
+    }
+
+    /// Helper for polling publication to transition from Preparing to Published
+    /// state.
+    // TODO(b/534436439): Remove once the Stream implementation is defined.
+    #[cfg(test)]
+    pub(crate) fn poll_publish(
+        self: std::pin::Pin<&mut Self>,
+        cx: &mut std::task::Context<'_>,
+    ) -> std::task::Poll<Result<(), Error>> {
+        self.project().local_service.poll_publish(cx)
+    }
+
+    /// Publishes the service to the GATT database.
+    pub fn publish(&mut self, server: T::Server) -> Result<(), Error> {
+        if matches!(
+            self.local_service,
+            LocalServiceState::Preparing { .. } | LocalServiceState::Published { .. }
+        ) {
+            return Err(Error::AlreadyPublished);
+        }
+
+        let LocalServiceState::NotPublished = std::mem::replace(
+            &mut self.local_service,
+            LocalServiceState::Preparing { fut: server.prepare(self.service_def.clone()) },
+        ) else {
+            unreachable!();
+        };
+        Ok(())
+    }
+
+    /// Handles a read request for a characteristic on the BASS server.
+    // TODO(b/534436439): Remove once the Stream implementation is defined.
+    #[cfg(test)]
+    fn handle_read(
+        &self,
+        handle: Handle,
+        offset: usize,
+        responder: impl bt_gatt::server::ReadResponder,
+    ) {
+        use bt_common::packet_encoding::Encodable;
+        use bt_gatt::types::GattError;
+
+        if handle == self.control_point_handle {
+            responder.error(GattError::ReadNotPermitted);
+            return;
+        }
+
+        let Some(slot) = self.receive_state_characteristics.get(&handle) else {
+            responder.error(GattError::InvalidHandle);
+            return;
+        };
+
+        let mut buf = vec![0u8; slot.state.encoded_len()];
+        if slot.state.encode(&mut buf).is_ok() {
+            if offset > buf.len() {
+                responder.error(GattError::InvalidOffset);
+            } else {
+                responder.respond(&buf[offset..]);
+            }
+        } else {
+            responder.error(GattError::UnlikelyError);
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use bt_bap::types::BroadcastId;
+    use bt_common::core::AddressType;
+    use bt_gatt::server::ReadResponder;
+    use bt_gatt::test_utils::{FakeServer, FakeServerEvent, FakeTypes};
+    use bt_gatt::types::GattError;
+    use futures::FutureExt;
+    use parking_lot::Mutex;
+    use std::sync::Arc;
+
+    use crate::types::{EncryptionStatus, PaSyncState, ReceiveState};
+
+    struct TestReadResponder {
+        result: Arc<Mutex<Option<Result<Vec<u8>, GattError>>>>,
+    }
+
+    impl ReadResponder for TestReadResponder {
+        fn respond(self, value: &[u8]) {
+            *self.result.lock() = Some(Ok(value.to_vec()));
+        }
+
+        fn error(self, error: GattError) {
+            *self.result.lock() = Some(Err(error));
+        }
+    }
+
+    fn make_test_receive_state(source_id: SourceId) -> BroadcastReceiveState {
+        BroadcastReceiveState::NonEmpty(ReceiveState::new(
+            source_id,
+            AddressType::Public,
+            [0x01, 0x02, 0x03, 0x04, 0x05, 0x06],
+            1,
+            BroadcastId::try_from(0x123456).unwrap(),
+            PaSyncState::NotSynced,
+            EncryptionStatus::NotEncrypted,
+            vec![],
+        ))
+    }
+
+    #[test]
+    fn empty_builder_fails() {
+        let builder = ServerBuilder::new();
+        assert!(matches!(builder.build::<FakeTypes>(), Err(Error::MissingReceiveState)));
+    }
+
+    #[test]
+    fn too_many_receive_states_fails() {
+        let mut builder = ServerBuilder::new();
+        for _ in 0..=MAX_RECEIVE_STATES {
+            builder = builder.add_receive_state_characteristic(BroadcastReceiveState::Empty);
+        }
+        assert!(matches!(builder.build::<FakeTypes>(), Err(Error::ExceedsMaxReceiveStates)));
+    }
+
+    #[test]
+    fn publish_server() {
+        use futures::task::Context;
+        use futures::StreamExt;
+        use std::task::Poll;
+
+        let mut noop_cx = Context::from_waker(futures::task::noop_waker_ref());
+
+        let mut server = ServerBuilder::new()
+            .add_receive_state_characteristic(BroadcastReceiveState::Empty)
+            .add_receive_state_characteristic(make_test_receive_state(2))
+            .build::<FakeTypes>()
+            .expect("building server works");
+
+        assert!(!server.is_published());
+
+        let (fake_gatt_server, mut event_receiver) = FakeServer::new();
+        let mut event_stream = event_receiver.next();
+
+        assert!(server.publish(fake_gatt_server.clone()).is_ok());
+        assert!(server.publish(fake_gatt_server).is_err());
+
+        // Poll publish to complete preparation and transition to Published state
+        assert!(std::pin::Pin::new(&mut server).poll_publish(&mut noop_cx).is_ready());
+        assert!(server.is_published());
+
+        let Poll::Ready(Some(FakeServerEvent::Published { id, definition })) =
+            event_stream.poll_unpin(&mut noop_cx)
+        else {
+            panic!("Expected published event");
+        };
+
+        assert_eq!(id, BASS_SERVICE_ID);
+        assert_eq!(definition.uuid(), BROADCAST_AUDIO_SCAN_SERVICE_UUID);
+        assert_eq!(definition.characteristics().count(), 3);
+    }
+
+    #[test]
+    fn read_receive_state() {
+        let server = ServerBuilder::new()
+            .add_receive_state_characteristic(BroadcastReceiveState::Empty)
+            .add_receive_state_characteristic(make_test_receive_state(2))
+            .build::<FakeTypes>()
+            .expect("building server works");
+
+        // 1. Read empty Receive State slot (Handle 2)
+        let res = Arc::new(Mutex::new(None));
+        server.handle_read(Handle(2), 0, TestReadResponder { result: res.clone() });
+        assert_eq!(res.lock().take().unwrap().expect("ok"), vec![]);
+
+        // 2. Read populated Receive State slot (Handle 3)
+        let res = Arc::new(Mutex::new(None));
+        server.handle_read(Handle(3), 0, TestReadResponder { result: res.clone() });
+        assert!(!res.lock().take().unwrap().expect("ok").is_empty());
+
+        // 3. Read unknown handle (Handle 99)
+        let res = Arc::new(Mutex::new(None));
+        server.handle_read(Handle(99), 0, TestReadResponder { result: res.clone() });
+        assert_eq!(res.lock().take().unwrap().expect_err("err"), GattError::InvalidHandle);
+    }
+
+    #[test]
+    fn read_control_point_fails() {
+        let server = ServerBuilder::new()
+            .add_receive_state_characteristic(BroadcastReceiveState::Empty)
+            .build::<FakeTypes>()
+            .expect("building server works");
+
+        let res = Arc::new(Mutex::new(None));
+        server.handle_read(CONTROL_POINT_HANDLE, 0, TestReadResponder { result: res.clone() });
+        assert_eq!(res.lock().take().unwrap().expect_err("err"), GattError::ReadNotPermitted);
+    }
+
+    #[test]
+    fn read_receive_state_invalid_offset() {
+        let server = ServerBuilder::new()
+            .add_receive_state_characteristic(BroadcastReceiveState::Empty)
+            .build::<FakeTypes>()
+            .expect("building server works");
+
+        let res = Arc::new(Mutex::new(None));
+        server.handle_read(Handle(2), 10, TestReadResponder { result: res.clone() });
+        assert_eq!(res.lock().take().unwrap().expect_err("err"), GattError::InvalidOffset);
+    }
+
+    #[test]
+    fn poll_publish_failure() {
+        use futures::task::Context;
+        use std::task::Poll;
+
+        let mut noop_cx = Context::from_waker(futures::task::noop_waker_ref());
+
+        let mut server = ServerBuilder::new()
+            .add_receive_state_characteristic(BroadcastReceiveState::Empty)
+            .build::<FakeTypes>()
+            .expect("building server works");
+
+        let (fake_gatt_server, _event_receiver) = FakeServer::new();
+        fake_gatt_server
+            .set_next_prepare_result(Err(bt_gatt::types::Error::Gatt(GattError::UnlikelyError)));
+
+        assert!(server.publish(fake_gatt_server.clone()).is_ok());
+
+        assert!(matches!(
+            std::pin::Pin::new(&mut server).poll_publish(&mut noop_cx),
+            Poll::Ready(Err(Error::Gatt(bt_gatt::types::Error::Gatt(GattError::UnlikelyError))))
+        ));
+
+        // Verifying server reset state to NotPublished so it is not published
+        assert!(!server.is_published());
+    }
+
+    #[test]
+    fn builder_normalizes_source_id() {
+        // Create state with an arbitrary source_id = 99
+        let state = make_test_receive_state(99);
+        let server = ServerBuilder::new()
+            .add_receive_state_characteristic(state)
+            .build::<FakeTypes>()
+            .expect("building server works");
+
+        // Verify slot's internal state and encoded read value have source_id = 1
+        let res = Arc::new(Mutex::new(None));
+        server.handle_read(Handle(2), 0, TestReadResponder { result: res.clone() });
+        let buf = res.lock().take().unwrap().expect("ok");
+        assert_eq!(buf[0], 1);
+    }
+}
diff --git a/rust/bt-bass/src/server/error.rs b/rust/bt-bass/src/server/error.rs
new file mode 100644
index 0000000..b5727f3
--- /dev/null
+++ b/rust/bt-bass/src/server/error.rs
@@ -0,0 +1,34 @@
+// 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 thiserror::Error;
+
+use crate::types::SourceId;
+use bt_common::packet_encoding::Error as PacketError;
+use bt_gatt::types::Error as BTGattError;
+
+/// Errors encountered when operating a BASS GATT server.
+#[derive(Debug, Error)]
+pub enum Error {
+    #[error("Service is already published")]
+    AlreadyPublished,
+
+    #[error("Service should support at least one Broadcast Receive State characteristic")]
+    MissingReceiveState,
+
+    #[error("Exceeded maximum number of Broadcast Receive State characteristics (255)")]
+    ExceedsMaxReceiveStates,
+
+    #[error("An unsupported opcode ({0:#x}) used in Control Point operation")]
+    OpCodeNotSupported(u8),
+
+    #[error("Invalid source id ({0}) used in Control Point operation")]
+    InvalidSourceId(SourceId),
+
+    #[error("Packet encoding/decoding error: {0}")]
+    Packet(#[from] PacketError),
+
+    #[error("GATT operation error: {0}")]
+    Gatt(#[from] BTGattError),
+}
diff --git a/rust/bt-bass/src/types.rs b/rust/bt-bass/src/types.rs
index 30a4388..a3d1222 100644
--- a/rust/bt-bass/src/types.rs
+++ b/rust/bt-bass/src/types.rs
@@ -15,8 +15,9 @@
 const PA_SYNC_BYTE_SIZE: usize = 1;
 const SOURCE_ID_BYTE_SIZE: usize = 1;
 
-/// 16-bit UUID value for the characteristics offered by the Broadcast Audio
-/// Scan Service.
+/// 16-bit UUID values for the Broadcast Audio Scan Service and its
+/// characteristics.
+pub const BROADCAST_AUDIO_SCAN_SERVICE_UUID: Uuid = Uuid::from_u16(0x184F);
 pub const BROADCAST_AUDIO_SCAN_CONTROL_POINT_UUID: Uuid = Uuid::from_u16(0x2BC7);
 pub const BROADCAST_RECEIVE_STATE_UUID: Uuid = Uuid::from_u16(0x2BC8);
 
diff --git a/rust/bt-gatt/src/test_utils.rs b/rust/bt-gatt/src/test_utils.rs
index e8e7de9..a5bee21 100644
--- a/rust/bt-gatt/src/test_utils.rs
+++ b/rust/bt-gatt/src/test_utils.rs
@@ -453,6 +453,7 @@
     sender: UnboundedSender<FakeServerEvent>,
     notification_peers: HashSet<PeerId>,
     indication_peers: HashSet<PeerId>,
+    next_prepare_result: Option<Result<()>>,
 }
 
 #[derive(Clone, Debug)]
@@ -465,8 +466,12 @@
         &self,
         service: server::ServiceDefinition,
     ) -> <FakeTypes as ServerTypes>::LocalServiceFut {
+        let mut lock = self.inner.lock();
+        if let Some(Err(e)) = lock.next_prepare_result.take() {
+            return futures::future::ready(Err(e));
+        }
         let id = service.id();
-        self.inner.lock().services.insert(id, service);
+        lock.services.insert(id, service);
         futures::future::ready(Ok(FakeLocalService::new(id, self.inner.clone())))
     }
 }
@@ -482,12 +487,17 @@
                     sender,
                     notification_peers: HashSet::new(),
                     indication_peers: HashSet::new(),
+                    next_prepare_result: None,
                 })),
             },
             receiver,
         )
     }
 
+    pub fn set_next_prepare_result(&self, res: Result<()>) {
+        self.inner.lock().next_prepare_result = Some(res);
+    }
+
     pub fn service(&self, id: server::ServiceId) -> Option<ServiceDefinition> {
         self.inner.lock().services.get(&id).cloned()
     }
