diff --git a/rust/Cargo.toml b/rust/Cargo.toml
index 4ce19aa..650f02c 100644
--- a/rust/Cargo.toml
+++ b/rust/Cargo.toml
@@ -31,3 +31,4 @@
 pretty_assertions = "1.2.1"
 thiserror = "2.0.12"
 uuid = { version = "1.1.2", features = ["serde", "v4"] }
+pin-project = "1.0.11"
diff --git a/rust/bt-common/src/core.rs b/rust/bt-common/src/core.rs
index d2e2ce5..f7d94e5 100644
--- a/rust/bt-common/src/core.rs
+++ b/rust/bt-common/src/core.rs
@@ -177,6 +177,32 @@
     }
 }
 
+impl Encodable for CodecId {
+    type Error = PacketError;
+
+    fn encoded_len(&self) -> core::primitive::usize {
+        Self::BYTE_SIZE
+    }
+
+    fn encode(&self, buf: &mut [u8]) -> core::result::Result<(), Self::Error> {
+        if buf.len() < Self::BYTE_SIZE {
+            return Err(Self::Error::BufferTooSmall);
+        }
+        match self {
+            CodecId::Assigned(format) => {
+                buf[0] = (*format).into();
+                buf[1..5].fill(0);
+            }
+            CodecId::VendorSpecific { company_id, vendor_specific_codec_id } => {
+                buf[0] = 0xFF;
+                [buf[1], buf[2]] = u16::from(*company_id).to_le_bytes();
+                [buf[3], buf[4]] = vendor_specific_codec_id.to_le_bytes();
+            }
+        }
+        Ok(())
+    }
+}
+
 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
 pub enum Phy {
     /// LE 1M PHY
@@ -226,4 +252,21 @@
             }
         );
     }
+
+    #[test]
+    fn encode_codec_id() {
+        let assigned = [0x01, 0x00, 0x00, 0x00, 0x00];
+        let (codec_id, _) = CodecId::decode(&assigned[..]).expect("should succeed");
+        assert_eq!(codec_id, CodecId::Assigned(CodingFormat::ALawLog));
+
+        let vendor_specific = [0xFF, 0x36, 0xFD, 0x11, 0x22];
+        let (codec_id, _) = CodecId::decode(&vendor_specific[..]).expect("should succeed");
+        assert_eq!(
+            codec_id,
+            CodecId::VendorSpecific {
+                company_id: (0xFD36 as u16).into(),
+                vendor_specific_codec_id: 0x2211
+            }
+        );
+    }
 }
diff --git a/rust/bt-gatt/src/test_utils.rs b/rust/bt-gatt/src/test_utils.rs
index c72b395..873689f 100644
--- a/rust/bt-gatt/src/test_utils.rs
+++ b/rust/bt-gatt/src/test_utils.rs
@@ -403,7 +403,7 @@
     sender: UnboundedSender<FakeServerEvent>,
 }
 
-#[derive(Debug)]
+#[derive(Clone, Debug)]
 pub struct FakeServer {
     inner: Arc<Mutex<FakeServerInner>>,
 }
diff --git a/rust/bt-gatt/src/types.rs b/rust/bt-gatt/src/types.rs
index 5644c31..aefbb78 100644
--- a/rust/bt-gatt/src/types.rs
+++ b/rust/bt-gatt/src/types.rs
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+use std::collections::HashSet;
+
 use bt_common::{PeerId, Uuid};
 use thiserror::Error;
 
@@ -260,6 +262,18 @@
     }
 }
 
+impl CharacteristicProperties {
+    pub fn is_disjoint(&self, other: &Self) -> bool {
+        let this_properties: HashSet<_> = HashSet::from_iter(self.0.iter());
+        let other_properties: HashSet<_> = HashSet::from_iter(other.0.iter());
+        this_properties.is_disjoint(&other_properties)
+    }
+
+    pub fn contains(&self, property: CharacteristicProperty) -> bool {
+        self.0.contains(&property)
+    }
+}
+
 #[derive(Debug, Clone, Copy, Default)]
 pub struct SecurityLevels {
     /// Encryption is required / provided
@@ -276,6 +290,10 @@
             && (!self.authentication || provided.authentication)
             && (!self.authorization || provided.encryption)
     }
+
+    pub const fn encryption_required() -> Self {
+        Self { encryption: true, authentication: false, authorization: false }
+    }
 }
 
 #[derive(Debug, Clone, Copy, Default)]
@@ -291,6 +309,17 @@
     pub update: Option<SecurityLevels>,
 }
 
+impl AttributePermissions {
+    pub fn with_levels(properties: &CharacteristicProperties, levels: &SecurityLevels) -> Self {
+        let notify_properties = CharacteristicProperty::Notify | CharacteristicProperty::Indicate;
+        Self {
+            read: properties.contains(CharacteristicProperty::Read).then_some(levels.clone()),
+            write: properties.contains(CharacteristicProperty::Write).then_some(levels.clone()),
+            update: (!properties.is_disjoint(&notify_properties)).then_some(levels.clone()),
+        }
+    }
+}
+
 /// The different types of well-known Descriptors are defined here and should be
 /// automatically read during service characteristic discovery by Stack
 /// Implementations and included. Other Descriptor attribute values can be read
diff --git a/rust/bt-pacs/Cargo.toml b/rust/bt-pacs/Cargo.toml
index 52d4737..dd975d8 100644
--- a/rust/bt-pacs/Cargo.toml
+++ b/rust/bt-pacs/Cargo.toml
@@ -12,6 +12,9 @@
 
 ### Others
 futures.workspace = true
+pin-project.workspace = true
+thiserror.workspace = true
 
 [dev-dependencies]
+bt-gatt = { workspace = true, features = ["test-utils"] }
 pretty_assertions.workspace = true
diff --git a/rust/bt-pacs/src/lib.rs b/rust/bt-pacs/src/lib.rs
index e926716..b77a577 100644
--- a/rust/bt-pacs/src/lib.rs
+++ b/rust/bt-pacs/src/lib.rs
@@ -7,11 +7,14 @@
 use bt_common::generic_audio::codec_capabilities::CodecCapability;
 use bt_common::generic_audio::metadata_ltv::Metadata;
 use bt_common::generic_audio::{AudioLocation, ContextType};
-use bt_common::packet_encoding::Decodable;
+use bt_common::packet_encoding::{Decodable, Encodable};
 use bt_common::Uuid;
 use bt_gatt::{client::FromCharacteristic, Characteristic};
 
+use std::collections::HashSet;
+
 pub mod debug;
+pub mod server;
 
 /// UUID from Assigned Numbers section 3.4.
 pub const PACS_UUID: Uuid = Uuid::from_u16(0x1850);
@@ -26,11 +29,10 @@
 pub struct PacRecord {
     pub codec_id: CodecId,
     pub codec_specific_capabilities: Vec<CodecCapability>,
-    // TODO: Actually parse the metadata once Metadata
     pub metadata: Vec<Metadata>,
 }
 
-impl bt_common::packet_encoding::Decodable for PacRecord {
+impl Decodable for PacRecord {
     type Error = bt_common::packet_encoding::Error;
 
     fn decode(buf: &[u8]) -> core::result::Result<(Self, usize), Self::Error> {
@@ -66,14 +68,48 @@
     }
 }
 
-/// One Sink Published Audio Capability Characteristic, or Sink PAC, exposed on
-/// a service. More than one Sink PAC can exist on a given PACS service.  If
-/// multiple are exposed, they are returned separately and can be notified by
-/// the server separately.
-#[derive(Debug, PartialEq, Clone)]
-pub struct SinkPac {
-    pub handle: bt_gatt::types::Handle,
-    pub capabilities: Vec<PacRecord>,
+impl Encodable for PacRecord {
+    type Error = bt_common::packet_encoding::Error;
+
+    fn encoded_len(&self) -> core::primitive::usize {
+        5usize
+            + self.codec_specific_capabilities.iter().fold(0, |a, x| a + x.encoded_len())
+            + self.metadata.iter().fold(0, |a, x| a + x.encoded_len())
+            + 2
+    }
+
+    fn encode(&self, buf: &mut [u8]) -> core::result::Result<(), Self::Error> {
+        if buf.len() < self.encoded_len() {
+            return Err(Self::Error::BufferTooSmall);
+        }
+        self.codec_id.encode(&mut buf[0..]).unwrap();
+        let codec_capabilities_len =
+            self.codec_specific_capabilities.iter().fold(0, |a, x| a + x.encoded_len());
+        buf[5] = codec_capabilities_len as u8;
+        LtValue::encode_all(self.codec_specific_capabilities.clone().into_iter(), &mut buf[6..])?;
+        let metadata_len = self.metadata.iter().fold(0, |a, x| a + x.encoded_len());
+        buf[6 + codec_capabilities_len] = metadata_len as u8;
+        if metadata_len != 0 {
+            LtValue::encode_all(
+                self.metadata.clone().into_iter(),
+                &mut buf[6 + codec_capabilities_len + 1..],
+            )?;
+        }
+        Ok(())
+    }
+}
+
+fn pac_records_into_char_value(records: &Vec<PacRecord>) -> Vec<u8> {
+    let mut val = Vec::new();
+    val.push(records.len() as u8);
+    let mut idx = 1;
+    for record in records {
+        let record_len = record.encoded_len();
+        val.resize(val.len() + record_len, 0);
+        record.encode(&mut val[idx..]).unwrap();
+        idx += record_len;
+    }
+    val
 }
 
 fn pac_records_from_bytes(
@@ -93,6 +129,16 @@
     Ok(capabilities)
 }
 
+/// One Sink Published Audio Capability Characteristic, or Sink PAC, exposed on
+/// a service. More than one Sink PAC can exist on a given PACS service.  If
+/// multiple are exposed, they are returned separately and can be notified by
+/// the server separately.
+#[derive(Debug, PartialEq, Clone)]
+pub struct SinkPac {
+    pub handle: bt_gatt::types::Handle,
+    pub capabilities: Vec<PacRecord>,
+}
+
 impl FromCharacteristic for SinkPac {
     /// UUID from Assigned Numbers section 3.8.
     const UUID: Uuid = Uuid::from_u16(0x2BC9);
@@ -141,12 +187,12 @@
     }
 }
 
-#[derive(Debug, PartialEq, Clone)]
+#[derive(Debug, PartialEq, Clone, Default)]
 pub struct AudioLocations {
-    pub locations: std::collections::HashSet<AudioLocation>,
+    pub locations: HashSet<AudioLocation>,
 }
 
-impl bt_common::packet_encoding::Decodable for AudioLocations {
+impl Decodable for AudioLocations {
     type Error = bt_common::packet_encoding::Error;
 
     fn decode(buf: &[u8]) -> core::result::Result<(Self, usize), Self::Error> {
@@ -160,16 +206,36 @@
     }
 }
 
+impl Encodable for AudioLocations {
+    type Error = bt_common::packet_encoding::Error;
+
+    fn encoded_len(&self) -> core::primitive::usize {
+        4
+    }
+
+    fn encode(&self, buf: &mut [u8]) -> core::result::Result<(), Self::Error> {
+        if buf.len() < 4 {
+            return Err(Self::Error::BufferTooSmall);
+        }
+        [buf[0], buf[1], buf[2], buf[3]] =
+            AudioLocation::to_bits(self.locations.iter()).to_le_bytes();
+        Ok(())
+    }
+}
+
 #[derive(Debug, PartialEq, Clone)]
 pub struct SourceAudioLocations {
     pub handle: bt_gatt::types::Handle,
     pub locations: AudioLocations,
 }
 
-#[derive(Debug, PartialEq, Clone)]
-pub struct SinkAudioLocations {
-    pub handle: bt_gatt::types::Handle,
-    pub locations: AudioLocations,
+impl SourceAudioLocations {
+    fn into_char_value(&self) -> Vec<u8> {
+        let mut val = Vec::with_capacity(self.locations.encoded_len());
+        val.resize(self.locations.encoded_len(), 0);
+        self.locations.encode(&mut val[..]).unwrap();
+        val
+    }
 }
 
 impl FromCharacteristic for SourceAudioLocations {
@@ -191,6 +257,21 @@
     }
 }
 
+#[derive(Debug, PartialEq, Clone)]
+pub struct SinkAudioLocations {
+    pub handle: bt_gatt::types::Handle,
+    pub locations: AudioLocations,
+}
+
+impl SinkAudioLocations {
+    fn into_char_value(&self) -> Vec<u8> {
+        let mut val = Vec::with_capacity(self.locations.encoded_len());
+        val.resize(self.locations.encoded_len(), 0);
+        self.locations.encode(&mut val[..]).unwrap();
+        val
+    }
+}
+
 impl FromCharacteristic for SinkAudioLocations {
     const UUID: Uuid = Uuid::from_u16(0x2BCA);
 
@@ -212,10 +293,10 @@
 #[derive(Debug, PartialEq, Clone)]
 pub enum AvailableContexts {
     NotAvailable,
-    Available(std::collections::HashSet<ContextType>),
+    Available(HashSet<ContextType>),
 }
 
-impl bt_common::packet_encoding::Decodable for AvailableContexts {
+impl Decodable for AvailableContexts {
     type Error = bt_common::packet_encoding::Error;
 
     fn decode(buf: &[u8]) -> core::result::Result<(Self, usize), Self::Error> {
@@ -231,6 +312,36 @@
     }
 }
 
+impl Encodable for AvailableContexts {
+    type Error = bt_common::packet_encoding::Error;
+
+    fn encoded_len(&self) -> core::primitive::usize {
+        2
+    }
+
+    fn encode(&self, buf: &mut [u8]) -> core::result::Result<(), Self::Error> {
+        if buf.len() < 2 {
+            return Err(Self::Error::BufferTooSmall);
+        }
+        match self {
+            AvailableContexts::NotAvailable => [buf[0], buf[1]] = [0x00, 0x00],
+            AvailableContexts::Available(set) => {
+                [buf[0], buf[1]] = ContextType::to_bits(set.iter()).to_le_bytes()
+            }
+        }
+        Ok(())
+    }
+}
+
+impl From<&HashSet<ContextType>> for AvailableContexts {
+    fn from(value: &HashSet<ContextType>) -> Self {
+        if value.is_empty() {
+            return AvailableContexts::NotAvailable;
+        }
+        AvailableContexts::Available(value.clone())
+    }
+}
+
 #[derive(Debug, Clone)]
 pub struct AvailableAudioContexts {
     pub handle: bt_gatt::types::Handle,
@@ -238,6 +349,16 @@
     pub source: AvailableContexts,
 }
 
+impl AvailableAudioContexts {
+    fn into_char_value(&self) -> Vec<u8> {
+        let mut val = Vec::with_capacity(self.sink.encoded_len() + self.source.encoded_len());
+        val.resize(self.sink.encoded_len() + self.source.encoded_len(), 0);
+        self.sink.encode(&mut val[0..]).unwrap();
+        self.source.encode(&mut val[2..]).unwrap();
+        val
+    }
+}
+
 impl FromCharacteristic for AvailableAudioContexts {
     /// UUID from Assigned Numbers section 3.8.
     const UUID: Uuid = Uuid::from_u16(0x2BCD);
@@ -273,8 +394,34 @@
 #[derive(Debug, Clone)]
 pub struct SupportedAudioContexts {
     pub handle: bt_gatt::types::Handle,
-    pub sink: std::collections::HashSet<ContextType>,
-    pub source: std::collections::HashSet<ContextType>,
+    pub sink: HashSet<ContextType>,
+    pub source: HashSet<ContextType>,
+}
+
+impl SupportedAudioContexts {
+    fn into_char_value(&self) -> Vec<u8> {
+        let mut val = Vec::with_capacity(self.encoded_len());
+        val.resize(self.encoded_len(), 0);
+        self.encode(&mut val[0..]).unwrap();
+        val
+    }
+}
+
+impl Encodable for SupportedAudioContexts {
+    type Error = bt_common::packet_encoding::Error;
+
+    fn encoded_len(&self) -> core::primitive::usize {
+        4
+    }
+
+    fn encode(&self, buf: &mut [u8]) -> core::result::Result<(), Self::Error> {
+        if buf.len() < 4 {
+            return Err(Self::Error::BufferTooSmall);
+        }
+        [buf[0], buf[1]] = ContextType::to_bits(self.sink.iter()).to_le_bytes();
+        [buf[2], buf[3]] = ContextType::to_bits(self.source.iter()).to_le_bytes();
+        Ok(())
+    }
 }
 
 impl FromCharacteristic for SupportedAudioContexts {
diff --git a/rust/bt-pacs/src/server.rs b/rust/bt-pacs/src/server.rs
new file mode 100644
index 0000000..5531187
--- /dev/null
+++ b/rust/bt-pacs/src/server.rs
@@ -0,0 +1,640 @@
+// Copyright 2024 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 Published Audio Capabilities Service server role.
+//!
+//! Use the `ServerBuilder` to define a new `Server` instance with the specified
+//! characteristics. The server isn't published to GATT until
+//! `Server::publish` method is called.
+//! Once the `Server` is published, poll on it to receive events from the
+//! `Server`, which are created as it processes incoming client requests.
+//!
+//! For example:
+//!
+//! // Set up a GATT Server which implements `bt_gatt::ServerTypes::Server`.
+//! let gatt_server = ...;
+//! // Define supported and available audio contexts for this PACS.
+//! let supported = AudioContexts::new(...);
+//! let available = AudioContexts::new(...);
+//! let pacs_server = ServerBuilder::new(supported,
+//! available).with_sources(...).with_sinks(...).build()?;
+//!
+//! // Publish the server.
+//! pacs_server.publish(gatt_server).expect("publishes fine");
+//! // Process events from the PACS server.
+//! while let Some(event) = pacs_server.next().await {
+//!     // Do something with `event`
+//! }
+
+use bt_common::generic_audio::ContextType;
+use bt_gatt::server::LocalService;
+use bt_gatt::server::{ReadResponder, ServiceDefinition, WriteResponder};
+use bt_gatt::types::{GattError, Handle};
+use bt_gatt::Server as _;
+use futures::task::{Poll, Waker};
+use futures::{Future, Stream};
+use pin_project::pin_project;
+use std::collections::HashMap;
+use thiserror::Error;
+
+use crate::{
+    AudioLocations, AvailableAudioContexts, PacRecord, SinkAudioLocations, SourceAudioLocations,
+    SupportedAudioContexts,
+};
+
+mod types;
+use crate::server::types::*;
+
+#[pin_project(project = LocalServiceProj)]
+enum LocalServiceState<T: bt_gatt::ServerTypes> {
+    NotPublished {
+        waker: Option<Waker>,
+    },
+    Preparing {
+        #[pin]
+        fut: T::LocalServiceFut,
+    },
+    Published {
+        service: T::LocalService,
+        #[pin]
+        events: T::ServiceEventStream,
+    },
+    Terminated,
+}
+
+impl<T: bt_gatt::ServerTypes> Default for LocalServiceState<T> {
+    fn default() -> Self {
+        Self::NotPublished { waker: None }
+    }
+}
+
+#[derive(Debug, Error)]
+pub enum Error {
+    #[error("Service is already published")]
+    AlreadyPublished,
+    #[error("Issue publishing service: {0}")]
+    PublishError(#[from] bt_gatt::types::Error),
+    #[error("Service should support at least one of Sink or Source PAC characteristics")]
+    MissingPac,
+    #[error("Available audio contexts are not supported: {0:?}")]
+    UnsupportedAudioContexts(Vec<ContextType>),
+}
+
+impl<T: bt_gatt::ServerTypes> Stream for LocalServiceState<T> {
+    type Item = Result<bt_gatt::server::ServiceEvent<T>, Error>;
+
+    fn poll_next(
+        mut self: std::pin::Pin<&mut Self>,
+        cx: &mut std::task::Context<'_>,
+    ) -> Poll<Option<Self::Item>> {
+        // SAFETY:
+        //  - Wakers are Unpin
+        //  - We re-pin the structurally pinned futures in Preparing and Published
+        //    (service is untouched)
+        //  - Terminated is empty
+        loop {
+            match self.as_mut().project() {
+                LocalServiceProj::Terminated => return Poll::Ready(None),
+                LocalServiceProj::NotPublished { .. } => {
+                    self.as_mut()
+                        .set(LocalServiceState::NotPublished { waker: Some(cx.waker().clone()) });
+                    return Poll::Pending;
+                }
+                LocalServiceProj::Preparing { fut } => {
+                    let service_result = futures::ready!(fut.poll(cx));
+                    let Ok(service) = service_result else {
+                        return Poll::Ready(Some(Err(Error::PublishError(
+                            service_result.err().unwrap(),
+                        ))));
+                    };
+                    let events = service.publish();
+                    self.as_mut().set(LocalServiceState::Published { service, events });
+                    continue;
+                }
+                LocalServiceProj::Published { service: _, events } => {
+                    let item = futures::ready!(events.poll_next(cx));
+                    let Some(gatt_result) = item else {
+                        self.as_mut().set(LocalServiceState::Terminated);
+                        return Poll::Ready(None);
+                    };
+                    let Ok(event) = gatt_result else {
+                        self.as_mut().set(LocalServiceState::Terminated);
+                        return Poll::Ready(Some(Err(Error::PublishError(
+                            gatt_result.err().unwrap(),
+                        ))));
+                    };
+                    return Poll::Ready(Some(Ok(event)));
+                }
+            }
+        }
+    }
+}
+
+impl<T: bt_gatt::ServerTypes> LocalServiceState<T> {
+    fn is_published(&self) -> bool {
+        if let LocalServiceState::NotPublished { .. } = self { false } else { true }
+    }
+}
+
+#[derive(Default)]
+pub struct ServerBuilder {
+    source_pacs: Vec<Vec<PacRecord>>,
+    source_audio_locations: Option<AudioLocations>,
+    sink_pacs: Vec<Vec<PacRecord>>,
+    sink_audio_locations: Option<AudioLocations>,
+}
+
+impl ServerBuilder {
+    pub fn new() -> ServerBuilder {
+        ServerBuilder::default()
+    }
+
+    /// Adds a source PAC characteristic to the builder.
+    /// Each call adds a new characteristic.
+    /// `capabilities` represents the records for a single PAC characteristic.
+    /// If `capabilities` is empty, it will be ignored.
+    pub fn add_source(mut self, capabilities: Vec<PacRecord>) -> Self {
+        if !capabilities.is_empty() {
+            self.source_pacs.push(capabilities);
+        }
+        self
+    }
+
+    /// Sets the audio locations for the source.
+    /// This corresponds to a single Source Audio Locations characteristic.
+    pub fn set_source_locations(mut self, audio_locations: AudioLocations) -> Self {
+        self.source_audio_locations = Some(audio_locations);
+        self
+    }
+
+    /// Adds a sink PAC characteristic to the builder.
+    /// Each call adds a new characteristic.
+    /// `capabilities` represents the records for a single PAC characteristic.
+    /// If `capabilities` is empty, it will be ignored.
+    pub fn add_sink(mut self, capabilities: Vec<PacRecord>) -> Self {
+        if !capabilities.is_empty() {
+            self.sink_pacs.push(capabilities);
+        }
+        self
+    }
+
+    /// Sets the audio locations for the sink.
+    /// This corresponds to a single Sink Audio Locations characteristic.
+    pub fn set_sink_locations(mut self, audio_locations: AudioLocations) -> Self {
+        self.sink_audio_locations = Some(audio_locations);
+        self
+    }
+
+    fn verify_characteristics(
+        &self,
+        supported: &AudioContexts,
+        available: &AudioContexts,
+    ) -> Result<(), Error> {
+        // If the corresponding bit in the supported audio contexts is
+        // not set to 0b1, we shall not set a bit to 0b1 in the
+        // available audio contexts. See PACS v1.0.1 section 3.5.1.
+        let diff: Vec<ContextType> = available.sink.difference(&supported.sink).cloned().collect();
+        if diff.len() != 0 {
+            return Err(Error::UnsupportedAudioContexts(diff));
+        }
+        let diff: Vec<ContextType> =
+            available.source.difference(&supported.source).cloned().collect();
+        if diff.len() != 0 {
+            return Err(Error::UnsupportedAudioContexts(diff));
+        }
+
+        // PACS server must have at least one Sink or Source PACS record.
+        if self.source_pacs.len() == 0 && self.sink_pacs.len() == 0 {
+            return Err(Error::MissingPac);
+        }
+        Ok(())
+    }
+
+    /// Builds a server after verifying all the defined characteristics
+    /// for this server (see PACS v1.0.1 section 3 for details).
+    pub fn build<T>(
+        mut self,
+        mut supported: AudioContexts,
+        available: AudioContexts,
+    ) -> Result<Server<T>, Error>
+    where
+        T: bt_gatt::ServerTypes,
+    {
+        let _ = self.verify_characteristics(&supported, &available)?;
+
+        let mut service_def = ServiceDefinition::new(
+            bt_gatt::server::ServiceId::new(1),
+            crate::PACS_UUID,
+            bt_gatt::types::ServiceKind::Primary,
+        );
+
+        let supported = SupportedAudioContexts {
+            handle: SUPPORTED_AUDIO_CONTEXTS_HANDLE,
+            sink: supported.sink.drain().collect(),
+            source: supported.source.drain().collect(),
+        };
+        let _ = service_def.add_characteristic((&supported).into());
+
+        let available = AvailableAudioContexts {
+            handle: AVAILABLE_AUDIO_CONTEXTS_HANDLE,
+            sink: (&available.sink).into(),
+            source: (&available.source).into(),
+        };
+        let _ = service_def.add_characteristic((&available).into());
+
+        let mut next_handle_iter = (HANDLE_OFFSET..).map(|x| Handle(x));
+        let mut audio_capabilities = HashMap::new();
+
+        // Sink audio locations characteristic may exist iff it's defined
+        // and there are valid sink PAC characteristics.
+        let sink_audio_locations = match self.sink_audio_locations.take() {
+            Some(locations) if self.sink_pacs.len() > 0 => {
+                let sink =
+                    SinkAudioLocations { handle: next_handle_iter.next().unwrap(), locations };
+                let _ = service_def.add_characteristic((&sink).into());
+                Some(sink)
+            }
+            _ => None,
+        };
+        for capabilities in self.sink_pacs.drain(..) {
+            let handle = next_handle_iter.next().unwrap();
+            let pac = PublishedAudioCapability::new_sink(handle, capabilities);
+            let _ = service_def.add_characteristic((&pac).into());
+            audio_capabilities.insert(handle, pac);
+        }
+
+        // Source audio locations characteristic may exist iff it's defined
+        // and there are valid source PAC characteristics.
+        let source_audio_locations = match self.source_audio_locations.take() {
+            Some(locations) if self.source_pacs.len() > 0 => {
+                let source =
+                    SourceAudioLocations { handle: next_handle_iter.next().unwrap(), locations };
+                let _ = service_def.add_characteristic((&source).into());
+                Some(source)
+            }
+            _ => None,
+        };
+        for capabilities in self.source_pacs.drain(..) {
+            let handle = next_handle_iter.next().unwrap();
+            let pac = PublishedAudioCapability::new_source(handle, capabilities);
+            let _ = service_def.add_characteristic((&pac).into());
+            audio_capabilities.insert(handle, pac);
+        }
+
+        let server = Server {
+            service_def,
+            local_service: Default::default(),
+            published_audio_capabilities: audio_capabilities,
+            source_audio_locations,
+            sink_audio_locations,
+            available_audio_contexts: available,
+            supported_audio_contexts: supported,
+        };
+        Ok(server)
+    }
+}
+
+#[pin_project]
+pub struct Server<T: bt_gatt::ServerTypes> {
+    service_def: ServiceDefinition,
+    #[pin]
+    local_service: LocalServiceState<T>,
+    published_audio_capabilities: HashMap<Handle, PublishedAudioCapability>,
+    source_audio_locations: Option<SourceAudioLocations>,
+    sink_audio_locations: Option<SinkAudioLocations>,
+    available_audio_contexts: AvailableAudioContexts,
+    supported_audio_contexts: SupportedAudioContexts,
+}
+
+impl<T: bt_gatt::ServerTypes> Server<T> {
+    pub fn publish(&mut self, server: T::Server) -> Result<(), Error> {
+        if self.local_service.is_published() {
+            return Err(Error::AlreadyPublished);
+        }
+
+        let LocalServiceState::NotPublished { waker } = std::mem::replace(
+            &mut self.local_service,
+            LocalServiceState::Preparing { fut: server.prepare(self.service_def.clone()) },
+        ) else {
+            unreachable!();
+        };
+        waker.map(Waker::wake);
+        Ok(())
+    }
+
+    fn is_source_locations_handle(&self, handle: Handle) -> bool {
+        self.source_audio_locations.as_ref().map_or(false, |locations| locations.handle == handle)
+    }
+
+    fn is_sink_locations_handle(&self, handle: Handle) -> bool {
+        self.sink_audio_locations.as_ref().map_or(false, |locations| locations.handle == handle)
+    }
+}
+
+impl<T: bt_gatt::ServerTypes> Stream for Server<T> {
+    type Item = Result<(), Error>;
+
+    fn poll_next(
+        mut self: std::pin::Pin<&mut Self>,
+        cx: &mut std::task::Context<'_>,
+    ) -> std::task::Poll<Option<Self::Item>> {
+        loop {
+            let mut this = self.as_mut().project();
+            let gatt_event = match futures::ready!(this.local_service.as_mut().poll_next(cx)) {
+                None => return Poll::Ready(None),
+                Some(Err(e)) => return Poll::Ready(Some(Err(e))),
+                Some(Ok(event)) => event,
+            };
+            use bt_gatt::server::ServiceEvent::*;
+            match gatt_event {
+                Read { handle, offset, responder, .. } => {
+                    let offset = offset as usize;
+                    let value = match handle {
+                        x if x == AVAILABLE_AUDIO_CONTEXTS_HANDLE => {
+                            self.available_audio_contexts.into_char_value()
+                        }
+                        x if x == SUPPORTED_AUDIO_CONTEXTS_HANDLE => {
+                            self.supported_audio_contexts.into_char_value()
+                        }
+                        x if self.is_source_locations_handle(x) => {
+                            self.source_audio_locations.as_ref().unwrap().into_char_value()
+                        }
+                        x if self.is_sink_locations_handle(x) => {
+                            self.sink_audio_locations.as_ref().unwrap().into_char_value()
+                        }
+                        pac_handle => {
+                            let Some(ref pac) = self.published_audio_capabilities.get(&pac_handle)
+                            else {
+                                responder.error(GattError::InvalidHandle);
+                                continue;
+                            };
+                            pac.encode()
+                        }
+                    };
+                    responder.respond(&value[offset..]);
+                    continue;
+                }
+                // TODO(b/309015071): support optional writes.
+                Write { responder, .. } => {
+                    responder.error(GattError::WriteNotPermitted);
+                    continue;
+                }
+                // TODO(b/309015071): implement notify since it's mandatory.
+                ClientConfiguration { .. } => {
+                    unimplemented!();
+                }
+                _ => continue,
+            }
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    use bt_common::core::{CodecId, CodingFormat};
+    use bt_common::generic_audio::codec_capabilities::*;
+    use bt_common::generic_audio::AudioLocation;
+    use bt_common::PeerId;
+    use bt_gatt::server;
+    use bt_gatt::test_utils::{FakeServer, FakeServerEvent, FakeTypes};
+    use bt_gatt::types::ServiceKind;
+    use futures::{FutureExt, StreamExt};
+
+    use std::collections::HashSet;
+
+    use crate::AvailableContexts;
+
+    // Builder for a server with:
+    // - 1 sink and 1 source PAC characteristics
+    // - sink audio locations
+    fn default_server_builder() -> ServerBuilder {
+        let builder = ServerBuilder::new()
+            .add_sink(vec![PacRecord {
+                codec_id: CodecId::Assigned(CodingFormat::ALawLog),
+                codec_specific_capabilities: vec![CodecCapability::SupportedFrameDurations(
+                    FrameDurationSupport::BothNoPreference,
+                )],
+                metadata: vec![],
+            }])
+            .set_sink_locations(AudioLocations {
+                locations: HashSet::from([AudioLocation::FrontLeft, AudioLocation::FrontRight]),
+            })
+            .add_source(vec![
+                PacRecord {
+                    codec_id: CodecId::Assigned(CodingFormat::ALawLog),
+                    codec_specific_capabilities: vec![CodecCapability::SupportedFrameDurations(
+                        FrameDurationSupport::BothNoPreference,
+                    )],
+                    metadata: vec![],
+                },
+                PacRecord {
+                    codec_id: CodecId::Assigned(CodingFormat::MuLawLog),
+                    codec_specific_capabilities: vec![CodecCapability::SupportedFrameDurations(
+                        FrameDurationSupport::BothNoPreference,
+                    )],
+                    metadata: vec![],
+                },
+            ])
+            .add_source(vec![]);
+        builder
+    }
+
+    #[test]
+    fn build_server() {
+        let server = default_server_builder()
+            .build::<FakeTypes>(
+                AudioContexts::new(
+                    HashSet::from([ContextType::Conversational, ContextType::Media]),
+                    HashSet::from([ContextType::Media]),
+                ),
+                AudioContexts::new(HashSet::from([ContextType::Media]), HashSet::new()),
+            )
+            .expect("should succeed");
+        assert_eq!(server.published_audio_capabilities.len(), 2);
+
+        assert_eq!(server.supported_audio_contexts.handle.0, 1);
+        assert_eq!(
+            server.supported_audio_contexts.sink,
+            HashSet::from([ContextType::Conversational, ContextType::Media])
+        );
+        assert_eq!(server.supported_audio_contexts.source, HashSet::from([ContextType::Media]));
+
+        assert_eq!(server.available_audio_contexts.handle.0, 2);
+        assert_eq!(
+            server.available_audio_contexts.sink,
+            AvailableContexts::Available(HashSet::from([ContextType::Media]))
+        );
+        assert_eq!(server.available_audio_contexts.source, AvailableContexts::NotAvailable);
+
+        // Should have 1 sink PAC characteristic with audio locations.
+        let location_char = server.sink_audio_locations.as_ref().expect("should exist");
+        assert_eq!(location_char.handle.0, 3);
+        assert_eq!(
+            location_char.locations.locations,
+            HashSet::from([AudioLocation::FrontLeft, AudioLocation::FrontRight])
+        );
+
+        let mut sink_iter =
+            server.published_audio_capabilities.iter().filter(|(_handle, pac)| pac.is_sink());
+        let sink_char = sink_iter.next().expect("should exist");
+        assert_eq!(sink_char.0, &Handle(4));
+        assert_eq!(sink_char.1.pac_records().len(), 1);
+        assert!(sink_iter.next().is_none());
+
+        // Should have 1 source PAC characteristic w/o audio locations.
+        assert!(server.source_audio_locations.is_none());
+        let mut source_iter =
+            server.published_audio_capabilities.iter().filter(|(_handle, pac)| pac.is_source());
+        let source_char = source_iter.next().expect("should exist");
+        assert_eq!(source_char.0, &Handle(5));
+        assert_eq!(source_char.1.pac_records().len(), 2);
+        assert_eq!(source_iter.next(), None);
+    }
+
+    #[test]
+    fn build_server_error() {
+        // No sink or source PACs.
+        assert!(
+            ServerBuilder::new()
+                .build::<FakeTypes>(
+                    AudioContexts::new(
+                        HashSet::from([ContextType::Conversational, ContextType::Media]),
+                        HashSet::from([ContextType::Media]),
+                    ),
+                    AudioContexts::new(HashSet::from([ContextType::Media]), HashSet::new()),
+                )
+                .is_err()
+        );
+
+        // Sink audio context in available not in supported.
+        assert!(
+            default_server_builder()
+                .build::<FakeTypes>(
+                    AudioContexts::new(
+                        HashSet::from([ContextType::Conversational, ContextType::Media]),
+                        HashSet::from([ContextType::Media]),
+                    ),
+                    AudioContexts::new(HashSet::from([ContextType::Alerts]), HashSet::new()),
+                )
+                .is_err()
+        );
+
+        // Sink audio context in available not in supported.
+        assert!(
+            default_server_builder()
+                .build::<FakeTypes>(
+                    AudioContexts::new(
+                        HashSet::from([ContextType::Conversational, ContextType::Media]),
+                        HashSet::from([ContextType::Media]),
+                    ),
+                    AudioContexts::new(
+                        HashSet::from([]),
+                        HashSet::from([ContextType::EmergencyAlarm])
+                    ),
+                )
+                .is_err()
+        );
+    }
+
+    #[test]
+    fn publish_server() {
+        let mut noop_cx = futures::task::Context::from_waker(futures::task::noop_waker_ref());
+
+        let mut server = default_server_builder()
+            .build::<FakeTypes>(
+                AudioContexts::new(
+                    HashSet::from([ContextType::Media]),
+                    HashSet::from([ContextType::Media]),
+                ),
+                AudioContexts::new(HashSet::new(), HashSet::new()),
+            )
+            .unwrap();
+
+        // Server should be pending still since GATT server not establihsed.
+        let Poll::Pending = server.next().poll_unpin(&mut noop_cx) else {
+            panic!("Should be pending");
+        };
+
+        let (fake_gatt_server, mut event_receiver) = FakeServer::new();
+
+        // Event stream should be pending still since service not published.
+        let mut event_stream = event_receiver.next();
+        let Poll::Pending = event_stream.poll_unpin(&mut noop_cx) else {
+            panic!("Should be pending");
+        };
+
+        let _ = server.publish(fake_gatt_server).expect("should succeed");
+
+        // Server should poll on local server state.
+        let Poll::Pending = server.next().poll_unpin(&mut noop_cx) else {
+            panic!("Should be pending");
+        };
+
+        // Should receive event that GATT service was published.
+        let Poll::Ready(Some(FakeServerEvent::Published { id, definition })) =
+            event_stream.poll_unpin(&mut noop_cx)
+        else {
+            panic!("Should be published");
+        };
+        assert_eq!(id, server::ServiceId::new(1));
+        assert_eq!(definition.characteristics().collect::<Vec<_>>().len(), 5);
+        assert_eq!(definition.kind(), ServiceKind::Primary);
+        assert_eq!(definition.uuid(), crate::PACS_UUID);
+
+        // Server can only be published once.
+        let (fake_gatt_server, _) = FakeServer::new();
+        assert!(server.publish(fake_gatt_server).is_err());
+    }
+
+    #[test]
+    fn read_from_server() {
+        let mut noop_cx = futures::task::Context::from_waker(futures::task::noop_waker_ref());
+
+        let mut server = default_server_builder()
+            .build::<FakeTypes>(
+                AudioContexts::new(
+                    HashSet::from([ContextType::Media]),
+                    HashSet::from([ContextType::Media]),
+                ),
+                AudioContexts::new(HashSet::from([ContextType::Media]), HashSet::new()),
+            )
+            .unwrap();
+
+        let (fake_gatt_server, mut event_receiver) = FakeServer::new();
+        let _ = server.publish(fake_gatt_server.clone()).expect("should succeed");
+
+        // Server should poll on local server state.
+        let Poll::Pending = server.next().poll_unpin(&mut noop_cx) else {
+            panic!("Should be pending");
+        };
+
+        // Should receive event that GATT service was published.
+        let mut event_stream = event_receiver.next();
+        let Poll::Ready(Some(FakeServerEvent::Published { id, .. })) =
+            event_stream.poll_unpin(&mut noop_cx)
+        else {
+            panic!("Should be published");
+        };
+
+        // Fake an incoming read from a remote peer.
+        let available_char_handle = server.available_audio_contexts.handle;
+        fake_gatt_server.incoming_read(PeerId(0x01), id, available_char_handle, 0);
+
+        // Server should still be pending.
+        let Poll::Pending = server.next().poll_unpin(&mut noop_cx) else {
+            panic!("Should be pending");
+        };
+
+        // We should received read response.
+        let Poll::Ready(Some(FakeServerEvent::ReadResponded { handle, value, .. })) =
+            event_stream.poll_unpin(&mut noop_cx)
+        else {
+            panic!("Should be published");
+        };
+        assert_eq!(handle, available_char_handle);
+        assert_eq!(value.expect("should be ok"), vec![0x04, 0x00, 0x00, 0x00]);
+    }
+}
diff --git a/rust/bt-pacs/src/server/types.rs b/rust/bt-pacs/src/server/types.rs
new file mode 100644
index 0000000..db45e52
--- /dev/null
+++ b/rust/bt-pacs/src/server/types.rs
@@ -0,0 +1,200 @@
+// Copyright 2024 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.
+
+//! Define types and trait implementations specific to the PACS server.
+
+use bt_gatt::client::FromCharacteristic;
+use bt_gatt::types::{
+    AttributePermissions, CharacteristicProperties, CharacteristicProperty, Handle, SecurityLevels,
+};
+use bt_gatt::Characteristic;
+
+use std::collections::HashSet;
+
+use crate::*;
+
+pub(crate) const SUPPORTED_AUDIO_CONTEXTS_HANDLE: Handle = Handle(1);
+pub(crate) const AVAILABLE_AUDIO_CONTEXTS_HANDLE: Handle = Handle(2);
+pub(crate) const HANDLE_OFFSET: u64 = 3;
+
+impl From<&SupportedAudioContexts> for Characteristic {
+    fn from(_value: &SupportedAudioContexts) -> Self {
+        // TODO(b/309015071): implement optional properties.
+        let properties: CharacteristicProperties = CharacteristicProperty::Read.into();
+
+        Characteristic {
+            handle: SUPPORTED_AUDIO_CONTEXTS_HANDLE,
+            uuid: <SupportedAudioContexts as FromCharacteristic>::UUID,
+            properties: properties.clone(),
+            permissions: AttributePermissions::with_levels(
+                &properties,
+                &SecurityLevels::encryption_required(),
+            ),
+            descriptors: Vec::new(),
+        }
+    }
+}
+
+impl From<&AvailableAudioContexts> for Characteristic {
+    fn from(_value: &AvailableAudioContexts) -> Self {
+        let properties = CharacteristicProperty::Read | CharacteristicProperty::Notify;
+
+        Characteristic {
+            handle: AVAILABLE_AUDIO_CONTEXTS_HANDLE,
+            uuid: <AvailableAudioContexts as FromCharacteristic>::UUID,
+            properties: properties.clone(),
+            permissions: AttributePermissions::with_levels(
+                &properties,
+                &SecurityLevels::encryption_required(),
+            ),
+            descriptors: Vec::new(),
+        }
+    }
+}
+
+impl From<&SourcePac> for Characteristic {
+    fn from(value: &SourcePac) -> Self {
+        // TODO(b/309015071): implement optional properties.
+        let properties: CharacteristicProperties = CharacteristicProperty::Read.into();
+
+        Characteristic {
+            handle: value.handle,
+            uuid: <SourcePac as FromCharacteristic>::UUID,
+            properties: properties.clone(),
+            permissions: AttributePermissions::with_levels(
+                &properties,
+                &SecurityLevels::encryption_required(),
+            ),
+            descriptors: Vec::new(),
+        }
+    }
+}
+
+impl From<&SinkPac> for Characteristic {
+    fn from(value: &SinkPac) -> Self {
+        // TODO(b/309015071): implement optional properties.
+        let properties: CharacteristicProperties = CharacteristicProperty::Read.into();
+
+        Characteristic {
+            handle: value.handle,
+            uuid: <SinkPac as FromCharacteristic>::UUID,
+            properties: properties.clone(),
+            permissions: AttributePermissions::with_levels(
+                &properties,
+                &SecurityLevels::encryption_required(),
+            ),
+            descriptors: Vec::new(),
+        }
+    }
+}
+
+impl From<&SourceAudioLocations> for Characteristic {
+    fn from(value: &SourceAudioLocations) -> Self {
+        // TODO(b/309015071): implement optional properties.
+        let properties: CharacteristicProperties = CharacteristicProperty::Read.into();
+
+        Characteristic {
+            handle: value.handle,
+            uuid: <SourceAudioLocations as FromCharacteristic>::UUID,
+            properties: properties.clone(),
+            permissions: AttributePermissions::with_levels(
+                &properties,
+                &SecurityLevels::encryption_required(),
+            ),
+            descriptors: Vec::new(),
+        }
+    }
+}
+
+impl From<&SinkAudioLocations> for Characteristic {
+    fn from(value: &SinkAudioLocations) -> Self {
+        // TODO(b/309015071): implement optional properties.
+        let properties: CharacteristicProperties = CharacteristicProperty::Read.into();
+
+        Characteristic {
+            handle: value.handle,
+            uuid: <SinkAudioLocations as FromCharacteristic>::UUID,
+            properties: properties.clone(),
+            permissions: AttributePermissions::with_levels(
+                &properties,
+                &SecurityLevels::encryption_required(),
+            ),
+            descriptors: Vec::new(),
+        }
+    }
+}
+
+#[derive(Default)]
+pub struct AudioContexts {
+    pub(crate) sink: HashSet<ContextType>,
+    pub(crate) source: HashSet<ContextType>,
+}
+
+impl AudioContexts {
+    #[cfg(test)]
+    pub fn new(sink: HashSet<ContextType>, source: HashSet<ContextType>) -> Self {
+        AudioContexts { sink, source }
+    }
+}
+
+/// A single PAC characteristic consists of 1 or more PAC records.
+pub type PacRecords = Vec<PacRecord>;
+
+#[derive(Debug, PartialEq)]
+pub(crate) enum PublishedAudioCapability {
+    Sink(SinkPac),
+    Source(SourcePac),
+}
+
+impl PublishedAudioCapability {
+    pub fn new_sink(handle: Handle, records: PacRecords) -> Self {
+        Self::Sink(SinkPac { handle: handle, capabilities: records })
+    }
+
+    pub fn new_source(handle: Handle, records: PacRecords) -> Self {
+        Self::Source(SourcePac { handle: handle, capabilities: records })
+    }
+
+    #[cfg(test)]
+    pub fn is_sink(&self) -> bool {
+        match self {
+            PublishedAudioCapability::Sink(_) => true,
+            PublishedAudioCapability::Source(_) => false,
+        }
+    }
+
+    #[cfg(test)]
+    pub fn is_source(&self) -> bool {
+        match self {
+            PublishedAudioCapability::Sink(_) => false,
+            PublishedAudioCapability::Source(_) => true,
+        }
+    }
+
+    #[cfg(test)]
+    pub fn pac_records(&self) -> &Vec<PacRecord> {
+        match self {
+            PublishedAudioCapability::Sink(pac) => &pac.capabilities,
+            PublishedAudioCapability::Source(pac) => &pac.capabilities,
+        }
+    }
+
+    /// Encode into PAC characteristic format as defined in PACS v1.0.1
+    /// Table 3.2/3.4.
+    pub(crate) fn encode(&self) -> Vec<u8> {
+        match self {
+            PublishedAudioCapability::Sink(pac) => pac_records_into_char_value(&pac.capabilities),
+            PublishedAudioCapability::Source(pac) => pac_records_into_char_value(&pac.capabilities),
+        }
+    }
+}
+
+impl From<&PublishedAudioCapability> for Characteristic {
+    fn from(value: &PublishedAudioCapability) -> Self {
+        match value {
+            PublishedAudioCapability::Sink(pac) => pac.into(),
+            PublishedAudioCapability::Source(pac) => pac.into(),
+        }
+    }
+}
