Test refinement and services cleanup.

More work refining the services interface and ensuring that interfaces
between the Requester and Responder are normalized. Also further refined
the tests to ensure they serve as demonstrators of how to properly init
the services.

* Changed the constructor for both Requester and Responder to allow better
  control of capabilities and algorithms.
* Added debug-only runtime validation of the capabilities and algorithms.
* Force tests to go through SpdmRequester and SpdmResponder rather than
  bypassing and going to SpdmContext directly.

precommit 1
diff --git a/services/mctp/server/tests/integration.rs b/services/mctp/server/tests/integration.rs
index c929b64..61ab5eb 100644
--- a/services/mctp/server/tests/integration.rs
+++ b/services/mctp/server/tests/integration.rs
@@ -547,4 +547,3 @@
     stack.set_eid(99).expect("set_eid should succeed");
     assert_eq!(stack.get_eid(), 99);
 }
-
diff --git a/services/spdm/common/BUILD.bazel b/services/spdm/common/BUILD.bazel
new file mode 100644
index 0000000..d57e324
--- /dev/null
+++ b/services/spdm/common/BUILD.bazel
@@ -0,0 +1,12 @@
+# Licensed under the Apache-2.0 license
+# SPDX-License-Identifier: Apache-2.0
+
+load("@rules_rust//rust:defs.bzl", "rust_library")
+
+rust_library(
+    name = "spdm_common",
+    srcs = glob(["src/**/*.rs"]),
+    crate_name = "openprot_spdm_common",
+    edition = "2024",
+    visibility = ["//visibility:public"],
+)
diff --git a/services/spdm/common/Cargo.toml b/services/spdm/common/Cargo.toml
new file mode 100644
index 0000000..98e3f49
--- /dev/null
+++ b/services/spdm/common/Cargo.toml
@@ -0,0 +1,11 @@
+# Licensed under the Apache-2.0 license
+# SPDX-License-Identifier: Apache-2.0
+
+[package]
+name = "openprot-spdm-common"
+version = "0.1.0"
+edition = "2021"
+description = "Common constants and types for SPDM requester and responder"
+license = "Apache-2.0"
+
+[dependencies]
diff --git a/services/spdm/common/src/lib.rs b/services/spdm/common/src/lib.rs
new file mode 100644
index 0000000..d65fd15
--- /dev/null
+++ b/services/spdm/common/src/lib.rs
@@ -0,0 +1,19 @@
+// Licensed under the Apache-2.0 license
+// SPDX-License-Identifier: Apache-2.0
+
+//! Common constants and types shared between SPDM requester and responder.
+
+#![no_std]
+#![warn(missing_docs)]
+
+/// Default data transfer size (bytes).
+///
+/// This is the maximum payload size for a single SPDM message fragment.
+/// Value: 0x1200 (4608 bytes)
+pub const DEFAULT_DTS: u32 = 0x1200;
+
+/// Default maximum SPDM message size (bytes).
+///
+/// This is the maximum size of a complete SPDM message (may span multiple fragments).
+/// Value: 0x1200 (4608 bytes)
+pub const DEFAULT_SMS: u32 = 0x1200;
diff --git a/services/spdm/hash/BUILD.bazel b/services/spdm/hash/BUILD.bazel
index 2326de7..edec42c 100644
--- a/services/spdm/hash/BUILD.bazel
+++ b/services/spdm/hash/BUILD.bazel
@@ -1,4 +1,5 @@
 # Licensed under the Apache-2.0 license
+# SPDX-License-Identifier: Apache-2.0
 
 load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
 
@@ -10,7 +11,7 @@
     visibility = ["//visibility:public"],
     deps = [
         # TODO: Replace stub with real //services/crypto/client when imported
-        "//services/crypto/client-stub:crypto_client",
+        "//services/spdm/requester/tests/crypto-client-stub:crypto_client",
         "@rust_crates//:spdm-lib",
     ],
 )
diff --git a/services/spdm/hash/Cargo.toml b/services/spdm/hash/Cargo.toml
index 80b2e8c..c5a2f2f 100644
--- a/services/spdm/hash/Cargo.toml
+++ b/services/spdm/hash/Cargo.toml
@@ -1,4 +1,5 @@
 # Licensed under the Apache-2.0 license
+# SPDX-License-Identifier: Apache-2.0
 
 [package]
 name = "openprot-spdm-hash"
diff --git a/services/spdm/hash/src/lib.rs b/services/spdm/hash/src/lib.rs
index 13dba1d..592a18d 100644
--- a/services/spdm/hash/src/lib.rs
+++ b/services/spdm/hash/src/lib.rs
@@ -1,4 +1,5 @@
 // Licensed under the Apache-2.0 license
+// SPDX-License-Identifier: Apache-2.0
 
 //! SPDM Hash Implementation
 //!
diff --git a/services/spdm/requester/BUILD.bazel b/services/spdm/requester/BUILD.bazel
index 6ed620d..1f4b65d 100644
--- a/services/spdm/requester/BUILD.bazel
+++ b/services/spdm/requester/BUILD.bazel
@@ -1,4 +1,5 @@
 # Licensed under the Apache-2.0 license
+# SPDX-License-Identifier: Apache-2.0
 
 load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
 
@@ -9,6 +10,7 @@
     edition = "2024",
     visibility = ["//visibility:public"],
     deps = [
+        "//services/spdm/common:spdm_common",
         "//services/spdm/transport-mctp:spdm_transport_mctp",
         "@rust_crates//:heapless",
         "@rust_crates//:spdm-lib",
@@ -22,6 +24,7 @@
 
 # Host integration test: SPDM VCA flow with in-memory MCTP transport.
 # Uses the same pattern as //services/mctp/server:mctp_server_echo_test.
+# Demonstrates usage of SpdmRequester and SpdmResponder APIs.
 rust_test(
     name = "spdm_requester_vca_host_test",
     srcs = [
@@ -31,8 +34,10 @@
     crate_root = "tests/vca_host.rs",
     edition = "2024",
     deps = [
+        ":spdm_requester_lib",
         "//services/mctp/api:mctp_api",
         "//services/mctp/server:mctp_server_lib",
+        "//services/spdm/responder:spdm_responder_lib",
         "//services/spdm/transport-mctp:spdm_transport_mctp",
         "@rust_crates//:mctp",
         "@rust_crates//:mctp-lib",
diff --git a/services/spdm/requester/Cargo.toml b/services/spdm/requester/Cargo.toml
index e87282e..e9a4c24 100644
--- a/services/spdm/requester/Cargo.toml
+++ b/services/spdm/requester/Cargo.toml
@@ -1,4 +1,5 @@
 # Licensed under the Apache-2.0 license
+# SPDX-License-Identifier: Apache-2.0
 
 [package]
 name = "openprot-spdm-requester"
diff --git a/services/spdm/requester/src/lib.rs b/services/spdm/requester/src/lib.rs
index 7b6bf73..525ef0f 100644
--- a/services/spdm/requester/src/lib.rs
+++ b/services/spdm/requester/src/lib.rs
@@ -1,4 +1,5 @@
 // Licensed under the Apache-2.0 license
+// SPDX-License-Identifier: Apache-2.0
 
 //! SPDM Requester Service
 //!
@@ -24,7 +25,7 @@
 //!             ▼
 //! ┌─────────────────────────┐
 //! │  SPDM Requester         │◄── This crate
-//! │  (request builder)      │
+//! │  (SpdmContext wrapper)  │
 //! └───────────┬─────────────┘
 //!             │ SPDM messages
 //!             ▼
@@ -36,32 +37,324 @@
 #![no_std]
 #![warn(missing_docs)]
 
-/// SPDM requester state and configuration.
+pub use openprot_spdm_common::{DEFAULT_DTS, DEFAULT_SMS};
+
+use spdm_lib::cert_store::{PeerCertStore, SpdmCertStore};
+use spdm_lib::context::SpdmContext;
+use spdm_lib::error::SpdmError;
+use spdm_lib::platform::evidence::SpdmEvidence;
+use spdm_lib::platform::hash::SpdmHash;
+use spdm_lib::platform::rng::SpdmRng;
+use spdm_lib::platform::transport::SpdmTransport;
+use spdm_lib::protocol::algorithms::{
+    AeadCipherSuite, AlgorithmPriorityTable, BaseAsymAlgo, BaseHashAlgo, DeviceAlgorithms,
+    DheNamedGroup, KeySchedule, LocalDeviceAlgorithms, MeasurementHashAlgo,
+    MeasurementSpecification, MelSpecification, OtherParamSupport, ReqBaseAsymAlg,
+};
+use spdm_lib::protocol::version::SpdmVersion;
+use spdm_lib::protocol::{CapabilityFlags, DeviceCapabilities};
+
+/// Supported SPDM versions (static to avoid lifetime issues)
+static SUPPORTED_VERSIONS: [SpdmVersion; 2] = [SpdmVersion::V12, SpdmVersion::V13];
+
+/// SPDM requester result type
+pub type RequesterResult<T> = Result<T, RequesterError>;
+
+/// SPDM requester errors
 #[derive(Debug)]
-pub struct SpdmRequester {
-    /// Remote endpoint ID for MCTP transport.
-    pub remote_eid: u8,
+pub enum RequesterError {
+    /// SPDM protocol error
+    SpdmError(SpdmError),
 }
 
-impl SpdmRequester {
-    /// Create a new SPDM requester targeting the given endpoint.
-    pub fn new(remote_eid: u8) -> Self {
-        Self { remote_eid }
+impl From<SpdmError> for RequesterError {
+    fn from(e: SpdmError) -> Self {
+        RequesterError::SpdmError(e)
+    }
+}
+
+/// SPDM requester configuration.
+///
+/// Use [`RequesterConfig::default()`] to get defaults, modify as needed,
+/// then pass to [`SpdmRequester::new()`].
+///
+/// # Example
+///
+/// ```rust,no_run
+/// use openprot_spdm_requester::RequesterConfig;
+///
+/// // Get defaults and customize
+/// let mut config = RequesterConfig::default();
+/// let mut caps = RequesterConfig::default_capabilities();
+/// caps.data_transfer_size = 2048;
+/// config.capabilities = Some(caps);
+///
+/// let mut algos = RequesterConfig::default_algorithms();
+/// algos.device_algorithms.base_hash_algo.set_tpm_alg_sha_512(1);
+/// config.algorithms = Some(algos);
+/// ```
+#[derive(Default)]
+pub struct RequesterConfig<'a> {
+    /// Device capabilities. If `None`, default capabilities are used.
+    pub capabilities: Option<DeviceCapabilities>,
+    /// Device algorithms. If `None`, default algorithms are used.
+    pub algorithms: Option<LocalDeviceAlgorithms<'a>>,
+}
+
+impl RequesterConfig<'_> {
+    /// Get the default device capabilities for a requester.
+    ///
+    /// Returns capabilities that can be modified and passed back via
+    /// [`RequesterConfig::capabilities`].
+    pub fn default_capabilities() -> DeviceCapabilities {
+        let mut flags = CapabilityFlags::default();
+        flags.set_cert_cap(1);
+        flags.set_chal_cap(1);
+        flags.set_meas_cap(0); // Requester doesn't provide measurements
+        flags.set_chunk_cap(1);
+
+        DeviceCapabilities {
+            ct_exponent: 0,
+            flags,
+            data_transfer_size: DEFAULT_DTS,
+            max_spdm_msg_size: DEFAULT_SMS,
+            include_supported_algorithms: false,
+        }
     }
 
-    /// Get the remote endpoint ID.
-    pub fn remote_eid(&self) -> u8 {
-        self.remote_eid
+    /// Get the default device algorithms for a requester.
+    ///
+    /// Returns algorithms that can be modified and passed back via
+    /// [`RequesterConfig::algorithms`].
+    ///
+    /// Default configuration:
+    /// - Measurement: DMTF specification with SHA-384
+    /// - Asymmetric: ECDSA with NIST P-384
+    /// - Hash: SHA-384
+    pub fn default_algorithms<'a>() -> LocalDeviceAlgorithms<'a> {
+        let mut measurement_spec = MeasurementSpecification::default();
+        measurement_spec.set_dmtf_measurement_spec(1);
+
+        let mut measurement_hash_algo = MeasurementHashAlgo::default();
+        measurement_hash_algo.set_tpm_alg_sha_384(1);
+
+        let mut base_asym_algo = BaseAsymAlgo::default();
+        base_asym_algo.set_tpm_alg_ecdsa_ecc_nist_p384(1);
+
+        let mut base_hash_algo = BaseHashAlgo::default();
+        base_hash_algo.set_tpm_alg_sha_384(1);
+
+        let device_algorithms = DeviceAlgorithms {
+            measurement_spec,
+            other_param_support: OtherParamSupport::default(),
+            measurement_hash_algo,
+            base_asym_algo,
+            base_hash_algo,
+            mel_specification: MelSpecification::default(),
+            dhe_group: DheNamedGroup::default(),
+            aead_cipher_suite: AeadCipherSuite::default(),
+            req_base_asym_algo: ReqBaseAsymAlg::default(),
+            key_schedule: KeySchedule::default(),
+        };
+
+        let algorithm_priority_table = AlgorithmPriorityTable {
+            measurement_specification: None,
+            opaque_data_format: None,
+            base_asym_algo: None,
+            base_hash_algo: None,
+            mel_specification: None,
+            dhe_group: None,
+            aead_cipher_suite: None,
+            req_base_asym_algo: None,
+            key_schedule: None,
+        };
+
+        LocalDeviceAlgorithms {
+            device_algorithms,
+            algorithm_priority_table,
+        }
     }
 }
 
+/// SPDM requester state and configuration.
+///
+/// This wraps the spdm-lib `SpdmContext` and provides a simplified interface
+/// for initiating SPDM protocol exchanges.
+pub struct SpdmRequester<'a> {
+    context: SpdmContext<'a>,
+}
+
+impl<'a> SpdmRequester<'a> {
+    /// Create a new SPDM requester with platform implementations.
+    ///
+    /// # Arguments
+    ///
+    /// * `transport` - Transport layer implementation (e.g., MCTP)
+    /// * `cert_store` - Certificate store with local certificates
+    /// * `peer_cert_store` - Certificate store for peer (responder) certificates
+    /// * `hash` - Hash implementation for protocol operations
+    /// * `m1_hash` - Hash implementation for M1 transcript
+    /// * `l1_hash` - Hash implementation for L1 transcript
+    /// * `rng` - Random number generator
+    /// * `evidence` - Evidence provider for measurements
+    /// * `config` - Optional configuration (uses defaults if None)
+    ///
+    /// # Returns
+    ///
+    /// A new `SpdmRequester` instance ready to initiate protocol exchanges.
+    #[allow(clippy::too_many_arguments)]
+    pub fn new(
+        transport: &'a mut dyn SpdmTransport,
+        cert_store: &'a mut dyn SpdmCertStore,
+        peer_cert_store: &'a mut dyn PeerCertStore,
+        hash: &'a mut dyn SpdmHash,
+        m1_hash: &'a mut dyn SpdmHash,
+        l1_hash: &'a mut dyn SpdmHash,
+        rng: &'a mut dyn SpdmRng,
+        evidence: &'a dyn SpdmEvidence,
+        config: Option<RequesterConfig<'a>>,
+    ) -> RequesterResult<Self> {
+        let config = config.unwrap_or_default();
+
+        // Use provided capabilities or create defaults
+        let capabilities = match config.capabilities {
+            Some(caps) => {
+                #[cfg(debug_assertions)]
+                validate_device_capabilities(&caps);
+                caps
+            }
+            None => RequesterConfig::default_capabilities(),
+        };
+
+        // Use provided algorithms or create defaults
+        let algorithms = match config.algorithms {
+            Some(algos) => {
+                #[cfg(debug_assertions)]
+                validate_device_algorithms(&algos);
+                algos
+            }
+            None => RequesterConfig::default_algorithms(),
+        };
+
+        // Create SPDM context
+        let context = SpdmContext::new(
+            &SUPPORTED_VERSIONS,
+            transport,
+            capabilities,
+            algorithms,
+            cert_store,
+            Some(peer_cert_store),
+            hash,
+            m1_hash,
+            l1_hash,
+            rng,
+            evidence,
+        )?;
+
+        Ok(Self { context })
+    }
+
+    /// Get reference to the underlying SPDM context.
+    ///
+    /// This allows direct access to context state if needed.
+    pub fn context(&self) -> &SpdmContext<'a> {
+        &self.context
+    }
+
+    /// Get mutable reference to the underlying SPDM context.
+    ///
+    /// This allows direct manipulation of context state if needed.
+    pub fn context_mut(&mut self) -> &mut SpdmContext<'a> {
+        &mut self.context
+    }
+}
+
+/// Validate device capabilities in debug builds.
+#[cfg(debug_assertions)]
+fn validate_device_capabilities(caps: &DeviceCapabilities) {
+    use spdm_lib::protocol::capabilities::MIN_DATA_TRANSFER_SIZE_V12;
+
+    debug_assert!(
+        caps.data_transfer_size >= MIN_DATA_TRANSFER_SIZE_V12,
+        "data_transfer_size ({}) must be >= MIN_DATA_TRANSFER_SIZE_V12 ({})",
+        caps.data_transfer_size,
+        MIN_DATA_TRANSFER_SIZE_V12
+    );
+
+    debug_assert!(
+        caps.max_spdm_msg_size >= caps.data_transfer_size,
+        "max_spdm_msg_size ({}) must be >= data_transfer_size ({})",
+        caps.max_spdm_msg_size,
+        caps.data_transfer_size
+    );
+}
+
+/// Validate device algorithms in debug builds.
+#[cfg(debug_assertions)]
+fn validate_device_algorithms(algos: &LocalDeviceAlgorithms) {
+    let measurement_hash_algo = algos.device_algorithms.measurement_hash_algo;
+    debug_assert!(
+        measurement_hash_algo.0.count_ones() <= 1,
+        "measurement_hash_algo must have at most one bit set"
+    );
+
+    let base_hash_algo = algos.device_algorithms.base_hash_algo;
+    debug_assert!(
+        base_hash_algo.0 != 0,
+        "base_hash_algo must have at least one algorithm enabled"
+    );
+
+    let base_asym_algo = algos.device_algorithms.base_asym_algo;
+    debug_assert!(
+        base_asym_algo.0 != 0,
+        "base_asym_algo must have at least one algorithm enabled"
+    );
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;
 
     #[test]
-    fn test_requester_creation() {
-        let requester = SpdmRequester::new(42);
-        assert_eq!(requester.remote_eid(), 42);
+    fn test_default_config() {
+        let config = RequesterConfig::default();
+        assert!(config.capabilities.is_none());
+        assert!(config.algorithms.is_none());
+    }
+
+    #[test]
+    fn test_default_capabilities() {
+        let caps = RequesterConfig::default_capabilities();
+        assert_eq!(caps.flags.cert_cap(), 1);
+        assert_eq!(caps.flags.chal_cap(), 1);
+        assert_eq!(caps.flags.meas_cap(), 0);
+        assert_eq!(caps.flags.chunk_cap(), 1);
+    }
+
+    #[test]
+    fn test_default_algorithms() {
+        let algos = RequesterConfig::default_algorithms();
+        assert_eq!(
+            algos
+                .device_algorithms
+                .measurement_spec
+                .dmtf_measurement_spec(),
+            1
+        );
+        assert_eq!(
+            algos
+                .device_algorithms
+                .measurement_hash_algo
+                .tpm_alg_sha_384(),
+            1
+        );
+        assert_eq!(
+            algos
+                .device_algorithms
+                .base_asym_algo
+                .tpm_alg_ecdsa_ecc_nist_p384(),
+            1
+        );
+        assert_eq!(algos.device_algorithms.base_hash_algo.tpm_alg_sha_384(), 1);
     }
 }
diff --git a/services/spdm/requester/tests/common/mod.rs b/services/spdm/requester/tests/common/mod.rs
index bc31c3c..4d83579 100644
--- a/services/spdm/requester/tests/common/mod.rs
+++ b/services/spdm/requester/tests/common/mod.rs
@@ -19,9 +19,7 @@
 use mctp::{Eid, Tag};
 use mctp_lib::fragment::{Fragmenter, SendOutput};
 use mctp_lib::Sender;
-use openprot_mctp_api::{
-    Handle, MctpClient, MctpError, RecvMetadata, ResponseCode,
-};
+use openprot_mctp_api::{Handle, MctpClient, MctpError, RecvMetadata, ResponseCode};
 use openprot_mctp_server::Server;
 
 use spdm_lib::cert_store::{CertStoreError, CertStoreResult, PeerCertStore, SpdmCertStore};
@@ -461,8 +459,7 @@
 
 impl DemoPeerCertStore {
     pub fn new() -> Self {
-        let mut slots = Vec::new();
-        slots.push(None);
+        let slots = vec![None];
         Self {
             supported_slots_mask: 0,
             provisioned_slots_mask: 0,
@@ -521,12 +518,11 @@
 
     fn set_supported_slots(&mut self, slot_mask: u8) -> CertStoreResult<()> {
         for b in 0..8 {
-            if slot_mask & (1 << b) != 0 {
-                if let Some(slot) = self.peer_slots.get_mut(b as usize) {
-                    if slot.is_none() {
-                        *slot = Some(PeerSlot::default());
-                    }
-                }
+            if slot_mask & (1 << b) != 0
+                && let Some(slot) = self.peer_slots.get_mut(b as usize)
+                && slot.is_none()
+            {
+                *slot = Some(PeerSlot::default());
             }
         }
         self.supported_slots_mask = slot_mask;
diff --git a/services/crypto/client-stub/BUILD.bazel b/services/spdm/requester/tests/crypto-client-stub/BUILD.bazel
similarity index 93%
rename from services/crypto/client-stub/BUILD.bazel
rename to services/spdm/requester/tests/crypto-client-stub/BUILD.bazel
index cb6683e..4a453c2 100644
--- a/services/crypto/client-stub/BUILD.bazel
+++ b/services/spdm/requester/tests/crypto-client-stub/BUILD.bazel
@@ -1,4 +1,5 @@
 # Licensed under the Apache-2.0 license
+# SPDX-License-Identifier: Apache-2.0
 #
 # STUB LIBRARY — This is a placeholder implementation of the crypto client.
 # It provides the minimal interface required by services/spdm/hash and
diff --git a/services/crypto/client-stub/src/lib.rs b/services/spdm/requester/tests/crypto-client-stub/src/lib.rs
similarity index 98%
rename from services/crypto/client-stub/src/lib.rs
rename to services/spdm/requester/tests/crypto-client-stub/src/lib.rs
index 1640431..8750e09 100644
--- a/services/crypto/client-stub/src/lib.rs
+++ b/services/spdm/requester/tests/crypto-client-stub/src/lib.rs
@@ -1,4 +1,5 @@
 // Licensed under the Apache-2.0 license
+// SPDX-License-Identifier: Apache-2.0
 //
 // STUB LIBRARY — Placeholder crypto client for SPDM hash/rng compilation.
 // All operations return CryptoError::NotImplemented.
diff --git a/services/spdm/requester/tests/vca_host.rs b/services/spdm/requester/tests/vca_host.rs
index 2659060..5bf36c4 100644
--- a/services/spdm/requester/tests/vca_host.rs
+++ b/services/spdm/requester/tests/vca_host.rs
@@ -7,13 +7,16 @@
 //! in-memory transport pattern as the MCTP echo tests. No IPC, no QEMU —
 //! runs entirely on the host.
 //!
+//! This test demonstrates how to use the `SpdmRequester` and `SpdmResponder`
+//! APIs with custom capabilities passed via configuration.
+//!
 //! ## Architecture
 //!
 //! ```text
 //! ┌─ Requester (EID 8) ────────┐      ┌─ Responder (EID 42) ───────┐
 //! │ Stack<DirectClient>        │      │ Stack<DirectClient>        │
 //! │   └→ MctpSpdmTransport     │      │   └→ MctpSpdmTransport     │
-//! │       └→ SpdmContext       │      │       └→ SpdmContext       │
+//! │       └→ SpdmRequester     │      │       └→ SpdmResponder     │
 //! └────────────────────────────┘      └────────────────────────────┘
 //!              │                                   │
 //!              └──── BufferSender ←─ transfer() ───┘
@@ -28,24 +31,19 @@
 #[allow(unused_imports)]
 use openprot_mctp_api::MctpClient;
 use openprot_mctp_server::Server;
+use openprot_spdm_requester::{RequesterConfig, SpdmRequester};
 use openprot_spdm_transport_mctp::MctpSpdmTransport;
 use spdm_lib::codec::MessageBuf;
 use spdm_lib::commands::algorithms::request::generate_negotiate_algorithms_request;
 use spdm_lib::commands::capabilities::request::generate_capabilities_request_local;
-use spdm_lib::commands::version::VersionReqPayload;
 use spdm_lib::commands::version::request::generate_get_version;
-use spdm_lib::context::SpdmContext;
+use spdm_lib::commands::version::VersionReqPayload;
 use spdm_lib::platform::transport::SpdmTransport;
-use spdm_lib::protocol::{
-    AeadCipherSuite, AlgorithmPriorityTable, BaseAsymAlgo, BaseHashAlgo, CapabilityFlags,
-    DeviceAlgorithms, DeviceCapabilities, DheNamedGroup, KeySchedule, LocalDeviceAlgorithms,
-    MeasurementHashAlgo, MeasurementSpecification, MelSpecification, OtherParamSupport,
-    ReqBaseAsymAlg, SpdmVersion,
-};
+use spdm_responder::{ResponderConfig, SpdmResponder};
 
 use common::{
-    transfer, BufferSender, DemoPeerCertStore, DirectClient, MockCertStore, MockEvidence,
-    MockHash, MockRng,
+    transfer, BufferSender, DemoPeerCertStore, DirectClient, MockCertStore, MockEvidence, MockHash,
+    MockRng,
 };
 
 /// Requester EID
@@ -54,93 +52,9 @@
 /// Responder EID
 const RESPONDER_EID: u8 = 42;
 
-/// Supported SPDM versions
-static SUPPORTED_VERSIONS: [SpdmVersion; 2] = [SpdmVersion::V12, SpdmVersion::V13];
-
-/// Create local device algorithms configuration.
-fn create_local_algorithms<'a>() -> LocalDeviceAlgorithms<'a> {
-    let mut measurement_spec = MeasurementSpecification::default();
-    measurement_spec.set_dmtf_measurement_spec(1);
-
-    let mut measurement_hash_algo = MeasurementHashAlgo::default();
-    measurement_hash_algo.set_tpm_alg_sha_384(1);
-
-    let mut base_asym_algo = BaseAsymAlgo::default();
-    base_asym_algo.set_tpm_alg_ecdsa_ecc_nist_p384(1);
-
-    let mut base_hash_algo = BaseHashAlgo::default();
-    base_hash_algo.set_tpm_alg_sha_384(1);
-
-    let device_algorithms = DeviceAlgorithms {
-        measurement_spec,
-        other_param_support: OtherParamSupport::default(),
-        measurement_hash_algo,
-        base_asym_algo,
-        base_hash_algo,
-        mel_specification: MelSpecification::default(),
-        dhe_group: DheNamedGroup::default(),
-        aead_cipher_suite: AeadCipherSuite::default(),
-        req_base_asym_algo: ReqBaseAsymAlg::default(),
-        key_schedule: KeySchedule::default(),
-    };
-
-    let algorithm_priority_table = AlgorithmPriorityTable {
-        measurement_specification: None,
-        opaque_data_format: None,
-        base_asym_algo: None,
-        base_hash_algo: None,
-        mel_specification: None,
-        dhe_group: None,
-        aead_cipher_suite: None,
-        req_base_asym_algo: None,
-        key_schedule: None,
-    };
-
-    LocalDeviceAlgorithms {
-        device_algorithms,
-        algorithm_priority_table,
-    }
-}
-
-/// Create requester capabilities.
-fn create_requester_capabilities() -> DeviceCapabilities {
-    let mut flags = CapabilityFlags::default();
-    flags.set_cert_cap(1);
-    flags.set_chal_cap(1);
-    flags.set_meas_cap(0);
-    flags.set_chunk_cap(1);
-
-    DeviceCapabilities {
-        ct_exponent: 0,
-        flags,
-        data_transfer_size: 1024,
-        max_spdm_msg_size: 4096,
-        include_supported_algorithms: false,
-    }
-}
-
-/// Create responder capabilities.
-fn create_responder_capabilities() -> DeviceCapabilities {
-    let mut flags = CapabilityFlags::default();
-    flags.set_cert_cap(1);
-    flags.set_chal_cap(1);
-    flags.set_meas_cap(2);
-    flags.set_meas_fresh_cap(1);
-    flags.set_chunk_cap(1);
-
-    DeviceCapabilities {
-        ct_exponent: 0,
-        flags,
-        data_transfer_size: 1024,
-        max_spdm_msg_size: 4096,
-        include_supported_algorithms: true,
-    }
-}
-
 /// Sanity check: verify the MCTP layer works before testing SPDM.
 #[test]
 fn mctp_sanity_check() {
-    use mctp::Eid;
     use openprot_mctp_api::{MctpListener, MctpReqChannel};
 
     let buf_a = RefCell::new(Vec::new());
@@ -177,16 +91,25 @@
 ///
 /// This test exercises the full VCA flow between a requester and responder,
 /// using in-memory MCTP transport with no platform dependencies.
+///
+/// Demonstrates usage of `SpdmRequester` and `SpdmResponder` APIs with
+/// custom capabilities passed via `RequesterConfig` and `ResponderConfig`.
 #[test]
 fn spdm_vca_roundtrip() {
     // -- Set up MCTP servers with in-memory transport --
     let buf_req = RefCell::new(Vec::new());
     let buf_resp = RefCell::new(Vec::new());
 
-    let server_req: RefCell<Server<_, 16>> =
-        RefCell::new(Server::new(Eid(REQUESTER_EID), 0, BufferSender { packets: &buf_req }));
-    let server_resp: RefCell<Server<_, 16>> =
-        RefCell::new(Server::new(Eid(RESPONDER_EID), 0, BufferSender { packets: &buf_resp }));
+    let server_req: RefCell<Server<_, 16>> = RefCell::new(Server::new(
+        Eid(REQUESTER_EID),
+        0,
+        BufferSender { packets: &buf_req },
+    ));
+    let server_resp: RefCell<Server<_, 16>> = RefCell::new(Server::new(
+        Eid(RESPONDER_EID),
+        0,
+        BufferSender { packets: &buf_resp },
+    ));
 
     // -- Create Stack facades (same API as production) --
     let stack_req = Stack::new(DirectClient::new(&server_req));
@@ -194,15 +117,21 @@
 
     // Set EIDs on stacks
     stack_req.set_eid(REQUESTER_EID).expect("set requester EID");
-    stack_resp.set_eid(RESPONDER_EID).expect("set responder EID");
+    stack_resp
+        .set_eid(RESPONDER_EID)
+        .expect("set responder EID");
 
     // -- Create SPDM transports --
     let mut transport_req = MctpSpdmTransport::new_requester(&stack_req, RESPONDER_EID);
     let mut transport_resp = MctpSpdmTransport::new_responder(&stack_resp);
 
     // Initialize transports
-    transport_req.init_sequence().expect("requester transport init");
-    transport_resp.init_sequence().expect("responder transport init");
+    transport_req
+        .init_sequence()
+        .expect("requester transport init");
+    transport_resp
+        .init_sequence()
+        .expect("responder transport init");
 
     // -- Create mock platform implementations --
     // Requester side
@@ -222,36 +151,52 @@
     let mut resp_rng = MockRng::new();
     let resp_evidence = MockEvidence::new();
 
-    // -- Create SPDM contexts --
-    let mut ctx_req = SpdmContext::new(
-        &SUPPORTED_VERSIONS,
+    // -- Create SPDM requester and responder using library APIs --
+    // This demonstrates how to use the SpdmRequester/SpdmResponder with
+    // custom capabilities and algorithms passed via configuration.
+    //
+    // Pattern: Get defaults, modify as needed, pass to new()
+    // Here we just use the defaults which apply DEFAULT_DTS and DEFAULT_SMS.
+    let req_caps = RequesterConfig::default_capabilities();
+    let req_algos = RequesterConfig::default_algorithms();
+
+    let requester_config = RequesterConfig {
+        capabilities: Some(req_caps),
+        algorithms: Some(req_algos),
+    };
+
+    let resp_caps = ResponderConfig::default_capabilities();
+    let resp_algos = ResponderConfig::default_algorithms();
+
+    let responder_config = ResponderConfig {
+        capabilities: Some(resp_caps),
+        algorithms: Some(resp_algos),
+    };
+
+    let mut requester = SpdmRequester::new(
         &mut transport_req,
-        create_requester_capabilities(),
-        create_local_algorithms(),
         &mut req_cert_store,
-        Some(&mut req_peer_cert_store),
+        &mut req_peer_cert_store,
         &mut req_hash,
         &mut req_m1_hash,
         &mut req_l1_hash,
         &mut req_rng,
         &req_evidence,
+        Some(requester_config),
     )
-    .expect("requester context creation");
+    .expect("requester creation");
 
-    let mut ctx_resp = SpdmContext::new(
-        &SUPPORTED_VERSIONS,
+    let mut responder = SpdmResponder::new(
         &mut transport_resp,
-        create_responder_capabilities(),
-        create_local_algorithms(),
         &mut resp_cert_store,
-        None,
         &mut resp_hash,
         &mut resp_m1_hash,
         &mut resp_l1_hash,
         &mut resp_rng,
         &resp_evidence,
+        Some(responder_config),
     )
-    .expect("responder context creation");
+    .expect("responder creation");
 
     // -- Message buffers (one per context, reused via reset) --
     let mut req_buf_storage = [0u8; 4096];
@@ -264,10 +209,15 @@
     // ══════════════════════════════════════════════════════════════════════
 
     // Requester: generate and send GET_VERSION
-    generate_get_version(&mut ctx_req, &mut req_buf, VersionReqPayload::new(0, 0))
-        .expect("generate GET_VERSION");
+    generate_get_version(
+        requester.context_mut(),
+        &mut req_buf,
+        VersionReqPayload::new(0, 0),
+    )
+    .expect("generate GET_VERSION");
 
-    ctx_req
+    requester
+        .context_mut()
         .requester_send_request(&mut req_buf, RESPONDER_EID)
         .expect("send GET_VERSION");
 
@@ -276,7 +226,8 @@
     buf_req.borrow_mut().clear();
 
     // Responder: process request and send VERSION response
-    ctx_resp
+    responder
+        .context_mut()
         .responder_process_message(&mut resp_buf)
         .expect("responder process GET_VERSION");
 
@@ -286,7 +237,8 @@
 
     // Requester: process VERSION response
     req_buf.reset();
-    ctx_req
+    requester
+        .context_mut()
         .requester_process_message(&mut req_buf)
         .expect("requester process VERSION");
 
@@ -296,9 +248,10 @@
 
     // Requester: generate and send GET_CAPABILITIES
     req_buf.reset();
-    generate_capabilities_request_local(&mut ctx_req, &mut req_buf)
+    generate_capabilities_request_local(requester.context_mut(), &mut req_buf)
         .expect("generate GET_CAPABILITIES");
-    ctx_req
+    requester
+        .context_mut()
         .requester_send_request(&mut req_buf, RESPONDER_EID)
         .expect("send GET_CAPABILITIES");
 
@@ -308,7 +261,8 @@
 
     // Responder: process request and send CAPABILITIES response
     resp_buf.reset();
-    ctx_resp
+    responder
+        .context_mut()
         .responder_process_message(&mut resp_buf)
         .expect("responder process GET_CAPABILITIES");
 
@@ -318,7 +272,8 @@
 
     // Requester: process CAPABILITIES response
     req_buf.reset();
-    ctx_req
+    requester
+        .context_mut()
         .requester_process_message(&mut req_buf)
         .expect("requester process CAPABILITIES");
 
@@ -328,9 +283,17 @@
 
     // Requester: generate and send NEGOTIATE_ALGORITHMS
     req_buf.reset();
-    generate_negotiate_algorithms_request(&mut ctx_req, &mut req_buf, None, None, None, None)
-        .expect("generate NEGOTIATE_ALGORITHMS");
-    ctx_req
+    generate_negotiate_algorithms_request(
+        requester.context_mut(),
+        &mut req_buf,
+        None,
+        None,
+        None,
+        None,
+    )
+    .expect("generate NEGOTIATE_ALGORITHMS");
+    requester
+        .context_mut()
         .requester_send_request(&mut req_buf, RESPONDER_EID)
         .expect("send NEGOTIATE_ALGORITHMS");
 
@@ -340,7 +303,8 @@
 
     // Responder: process request and send ALGORITHMS response
     resp_buf.reset();
-    ctx_resp
+    responder
+        .context_mut()
         .responder_process_message(&mut resp_buf)
         .expect("responder process NEGOTIATE_ALGORITHMS");
 
@@ -350,7 +314,8 @@
 
     // Requester: process ALGORITHMS response
     req_buf.reset();
-    ctx_req
+    requester
+        .context_mut()
         .requester_process_message(&mut req_buf)
         .expect("requester process ALGORITHMS");
 
diff --git a/services/spdm/responder/BUILD.bazel b/services/spdm/responder/BUILD.bazel
index 8389ed5..b394b37 100644
--- a/services/spdm/responder/BUILD.bazel
+++ b/services/spdm/responder/BUILD.bazel
@@ -1,4 +1,5 @@
 # Licensed under the Apache-2.0 license
+# SPDX-License-Identifier: Apache-2.0
 
 load("@rules_rust//rust:defs.bzl", "rust_library")
 
@@ -9,6 +10,7 @@
     edition = "2024",
     visibility = ["//visibility:public"],
     deps = [
+        "//services/spdm/common:spdm_common",
         "@rust_crates//:spdm-lib",
     ],
 )
diff --git a/services/spdm/responder/Cargo.toml b/services/spdm/responder/Cargo.toml
index 8080708..76dbfd0 100644
--- a/services/spdm/responder/Cargo.toml
+++ b/services/spdm/responder/Cargo.toml
@@ -1,4 +1,5 @@
 # Licensed under the Apache-2.0 license
+# SPDX-License-Identifier: Apache-2.0
 
 [package]
 name = "spdm-responder"
diff --git a/services/spdm/responder/src/lib.rs b/services/spdm/responder/src/lib.rs
index 09f3806..718d634 100644
--- a/services/spdm/responder/src/lib.rs
+++ b/services/spdm/responder/src/lib.rs
@@ -1,4 +1,5 @@
 // Licensed under the Apache-2.0 license
+// SPDX-License-Identifier: Apache-2.0
 
 //! SPDM Responder Service
 //!
@@ -67,6 +68,8 @@
 
 #![no_std]
 
+pub use openprot_spdm_common::{DEFAULT_DTS, DEFAULT_SMS};
+
 use spdm_lib::cert_store::SpdmCertStore;
 use spdm_lib::codec::MessageBuf;
 use spdm_lib::context::SpdmContext;
@@ -86,9 +89,6 @@
 static SUPPORTED_VERSIONS: [SpdmVersion; 2] = [SpdmVersion::V12, SpdmVersion::V11];
 use spdm_lib::protocol::{CapabilityFlags, DeviceCapabilities};
 
-/// Maximum SPDM message size
-const MAX_SPDM_MSG_SIZE: usize = 4096;
-
 /// SPDM responder result type
 pub type ResponderResult<T> = Result<T, ResponderError>;
 
@@ -107,23 +107,106 @@
     }
 }
 
-/// SPDM responder configuration
-#[derive(Debug, Clone, Copy)]
-pub struct ResponderConfig {
-    /// CT exponent for timing
-    pub ct_exponent: u8,
-    /// Data transfer size
-    pub data_transfer_size: u32,
-    /// Maximum SPDM message size
-    pub max_spdm_msg_size: u32,
+/// SPDM responder configuration.
+///
+/// Use [`ResponderConfig::default()`] to get defaults, modify as needed,
+/// then pass to [`SpdmResponder::new()`].
+///
+/// # Example
+///
+/// ```rust,no_run
+/// use spdm_responder::ResponderConfig;
+///
+/// // Get defaults and customize
+/// let mut config = ResponderConfig::default();
+/// let mut caps = ResponderConfig::default_capabilities();
+/// caps.data_transfer_size = 2048;
+/// config.capabilities = Some(caps);
+///
+/// let mut algos = ResponderConfig::default_algorithms();
+/// algos.device_algorithms.base_hash_algo.set_tpm_alg_sha_512(1);
+/// config.algorithms = Some(algos);
+/// ```
+#[derive(Default)]
+pub struct ResponderConfig<'a> {
+    /// Device capabilities. If `None`, default capabilities are used.
+    pub capabilities: Option<DeviceCapabilities>,
+    /// Device algorithms. If `None`, default algorithms are used.
+    pub algorithms: Option<LocalDeviceAlgorithms<'a>>,
 }
 
-impl Default for ResponderConfig {
-    fn default() -> Self {
-        Self {
+impl ResponderConfig<'_> {
+    /// Get the default device capabilities for a responder.
+    ///
+    /// Returns capabilities that can be modified and passed back via
+    /// [`ResponderConfig::capabilities`].
+    pub fn default_capabilities() -> DeviceCapabilities {
+        let mut flags = CapabilityFlags::default();
+        flags.set_cert_cap(1);
+        flags.set_chal_cap(1);
+        flags.set_meas_cap(2); // Measurements with signature
+        flags.set_meas_fresh_cap(1);
+        flags.set_chunk_cap(1);
+
+        DeviceCapabilities {
             ct_exponent: 0,
-            data_transfer_size: 1024,
-            max_spdm_msg_size: MAX_SPDM_MSG_SIZE as u32,
+            flags,
+            data_transfer_size: DEFAULT_DTS,
+            max_spdm_msg_size: DEFAULT_SMS,
+            include_supported_algorithms: true,
+        }
+    }
+
+    /// Get the default device algorithms for a responder.
+    ///
+    /// Returns algorithms that can be modified and passed back via
+    /// [`ResponderConfig::algorithms`].
+    ///
+    /// Default configuration:
+    /// - Measurement: DMTF specification with SHA-384
+    /// - Asymmetric: ECDSA with NIST P-384
+    /// - Hash: SHA-384
+    pub fn default_algorithms<'a>() -> LocalDeviceAlgorithms<'a> {
+        let mut measurement_spec = MeasurementSpecification::default();
+        measurement_spec.set_dmtf_measurement_spec(1);
+
+        let mut measurement_hash_algo = MeasurementHashAlgo::default();
+        measurement_hash_algo.set_tpm_alg_sha_384(1);
+
+        let mut base_asym_algo = BaseAsymAlgo::default();
+        base_asym_algo.set_tpm_alg_ecdsa_ecc_nist_p384(1);
+
+        let mut base_hash_algo = BaseHashAlgo::default();
+        base_hash_algo.set_tpm_alg_sha_384(1);
+
+        let device_algorithms = DeviceAlgorithms {
+            measurement_spec,
+            other_param_support: OtherParamSupport::default(),
+            measurement_hash_algo,
+            base_asym_algo,
+            base_hash_algo,
+            mel_specification: MelSpecification::default(),
+            dhe_group: DheNamedGroup::default(),
+            aead_cipher_suite: AeadCipherSuite::default(),
+            req_base_asym_algo: ReqBaseAsymAlg::default(),
+            key_schedule: KeySchedule::default(),
+        };
+
+        let algorithm_priority_table = AlgorithmPriorityTable {
+            measurement_specification: None,
+            opaque_data_format: None,
+            base_asym_algo: None,
+            base_hash_algo: None,
+            mel_specification: None,
+            dhe_group: None,
+            aead_cipher_suite: None,
+            req_base_asym_algo: None,
+            key_schedule: None,
+        };
+
+        LocalDeviceAlgorithms {
+            device_algorithms,
+            algorithm_priority_table,
         }
     }
 }
@@ -153,6 +236,7 @@
     /// # Returns
     ///
     /// A new `SpdmResponder` instance ready to process messages.
+    #[allow(clippy::too_many_arguments)]
     pub fn new(
         transport: &'a mut dyn SpdmTransport,
         cert_store: &'a mut dyn SpdmCertStore,
@@ -161,15 +245,29 @@
         l1_hash: &'a mut dyn SpdmHash,
         rng: &'a mut dyn SpdmRng,
         evidence: &'a dyn SpdmEvidence,
-        config: Option<ResponderConfig>,
+        config: Option<ResponderConfig<'a>>,
     ) -> ResponderResult<Self> {
         let config = config.unwrap_or_default();
 
-        // Create device capabilities
-        let capabilities = create_device_capabilities(config);
+        // Use provided capabilities or create defaults
+        let capabilities = match config.capabilities {
+            Some(caps) => {
+                #[cfg(debug_assertions)]
+                validate_device_capabilities(&caps);
+                caps
+            }
+            None => ResponderConfig::default_capabilities(),
+        };
 
-        // Create local algorithms
-        let algorithms = create_local_algorithms();
+        // Use provided algorithms or create defaults
+        let algorithms = match config.algorithms {
+            Some(algos) => {
+                #[cfg(debug_assertions)]
+                validate_device_algorithms(&algos);
+                algos
+            }
+            None => ResponderConfig::default_algorithms(),
+        };
 
         // Create SPDM context
         let context = SpdmContext::new(
@@ -230,86 +328,50 @@
     }
 }
 
-/// Create SPDM device capabilities based on configuration.
-fn create_device_capabilities(config: ResponderConfig) -> DeviceCapabilities {
-    let mut flags_value = 0u32;
+/// Validate device capabilities in debug builds.
+#[cfg(debug_assertions)]
+fn validate_device_capabilities(caps: &DeviceCapabilities) {
+    use spdm_lib::protocol::capabilities::MIN_DATA_TRANSFER_SIZE_V12;
 
-    // Certificate capability
-    flags_value |= 1 << 1; // CERT_CAP
+    debug_assert!(
+        caps.data_transfer_size >= MIN_DATA_TRANSFER_SIZE_V12,
+        "data_transfer_size ({}) must be >= MIN_DATA_TRANSFER_SIZE_V12 ({})",
+        caps.data_transfer_size,
+        MIN_DATA_TRANSFER_SIZE_V12
+    );
 
-    // Challenge capability
-    flags_value |= 1 << 2; // CHAL_CAP
+    debug_assert!(
+        caps.max_spdm_msg_size >= caps.data_transfer_size,
+        "max_spdm_msg_size ({}) must be >= data_transfer_size ({})",
+        caps.max_spdm_msg_size,
+        caps.data_transfer_size
+    );
 
-    // Measurements capability (with signature)
-    flags_value |= 2 << 3; // MEAS_CAP (0b10 = measurements with signature)
-
-    // Measurements freshness capability
-    flags_value |= 1 << 5; // MEAS_FRESH_CAP
-
-    // Chunk capability
-    flags_value |= 1 << 17; // CHUNK_CAP
-
-    let flags = CapabilityFlags::new(flags_value);
-
-    DeviceCapabilities {
-        ct_exponent: config.ct_exponent,
-        flags,
-        data_transfer_size: config.data_transfer_size,
-        max_spdm_msg_size: config.max_spdm_msg_size,
-        include_supported_algorithms: true,
-    }
+    // Responder should have at least cert or measurement capability
+    debug_assert!(
+        caps.flags.cert_cap() != 0 || caps.flags.meas_cap() != 0,
+        "responder should have cert_cap or meas_cap enabled"
+    );
 }
 
-/// Create local device algorithms configuration.
-///
-/// Configures supported cryptographic algorithms:
-/// - Measurement: DMTF specification with SHA-384
-/// - Asymmetric: ECDSA with NIST P-384
-/// - Hash: SHA-384
-fn create_local_algorithms<'a>() -> LocalDeviceAlgorithms<'a> {
-    // Measurement specification (DMTF)
-    let mut measurement_spec = MeasurementSpecification::default();
-    measurement_spec.set_dmtf_measurement_spec(1);
+/// Validate device algorithms in debug builds.
+#[cfg(debug_assertions)]
+fn validate_device_algorithms(algos: &LocalDeviceAlgorithms) {
+    let measurement_hash_algo = algos.device_algorithms.measurement_hash_algo;
+    debug_assert!(
+        measurement_hash_algo.0.count_ones() <= 1,
+        "measurement_hash_algo must have at most one bit set"
+    );
 
-    // Measurement hash algorithm (SHA-384)
-    let mut measurement_hash_algo = MeasurementHashAlgo::default();
-    measurement_hash_algo.set_tpm_alg_sha_384(1);
+    let base_hash_algo = algos.device_algorithms.base_hash_algo;
+    debug_assert!(
+        base_hash_algo.0 != 0,
+        "base_hash_algo must have at least one algorithm enabled"
+    );
 
-    // Base asymmetric algorithm (ECDSA P-384)
-    let mut base_asym_algo = BaseAsymAlgo::default();
-    base_asym_algo.set_tpm_alg_ecdsa_ecc_nist_p384(1);
-
-    // Base hash algorithm (SHA-384)
-    let mut base_hash_algo = BaseHashAlgo::default();
-    base_hash_algo.set_tpm_alg_sha_384(1);
-
-    let device_algorithms = DeviceAlgorithms {
-        measurement_spec,
-        other_param_support: OtherParamSupport::default(),
-        measurement_hash_algo,
-        base_asym_algo,
-        base_hash_algo,
-        mel_specification: MelSpecification::default(),
-        dhe_group: DheNamedGroup::default(),
-        aead_cipher_suite: AeadCipherSuite::default(),
-        req_base_asym_algo: ReqBaseAsymAlg::default(),
-        key_schedule: KeySchedule::default(),
-    };
-
-    let algorithm_priority_table = AlgorithmPriorityTable {
-        measurement_specification: None,
-        opaque_data_format: None,
-        base_asym_algo: None,
-        base_hash_algo: None,
-        mel_specification: None,
-        dhe_group: None,
-        aead_cipher_suite: None,
-        req_base_asym_algo: None,
-        key_schedule: None,
-    };
-
-    LocalDeviceAlgorithms {
-        device_algorithms,
-        algorithm_priority_table,
-    }
+    let base_asym_algo = algos.device_algorithms.base_asym_algo;
+    debug_assert!(
+        base_asym_algo.0 != 0,
+        "base_asym_algo must have at least one algorithm enabled"
+    );
 }
diff --git a/services/spdm/rng/BUILD.bazel b/services/spdm/rng/BUILD.bazel
index 9413a5f..cd0298d 100644
--- a/services/spdm/rng/BUILD.bazel
+++ b/services/spdm/rng/BUILD.bazel
@@ -1,4 +1,5 @@
 # Licensed under the Apache-2.0 license
+# SPDX-License-Identifier: Apache-2.0
 
 load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
 
@@ -10,7 +11,7 @@
     visibility = ["//visibility:public"],
     deps = [
         # TODO: Replace stub with real //services/crypto/client when imported
-        "//services/crypto/client-stub:crypto_client",
+        "//services/spdm/requester/tests/crypto-client-stub:crypto_client",
         "@rust_crates//:spdm-lib",
     ],
 )
diff --git a/services/spdm/rng/Cargo.toml b/services/spdm/rng/Cargo.toml
index 8731a23..8127694 100644
--- a/services/spdm/rng/Cargo.toml
+++ b/services/spdm/rng/Cargo.toml
@@ -1,4 +1,5 @@
 # Licensed under the Apache-2.0 license
+# SPDX-License-Identifier: Apache-2.0
 
 [package]
 name = "openprot-spdm-rng"
diff --git a/services/spdm/rng/src/lib.rs b/services/spdm/rng/src/lib.rs
index 6134f69..8b9a021 100644
--- a/services/spdm/rng/src/lib.rs
+++ b/services/spdm/rng/src/lib.rs
@@ -1,4 +1,5 @@
 // Licensed under the Apache-2.0 license
+// SPDX-License-Identifier: Apache-2.0
 
 //! SPDM RNG Implementation
 //!
diff --git a/services/spdm/transport-mctp/BUILD.bazel b/services/spdm/transport-mctp/BUILD.bazel
index 4349c4d..03757ea 100644
--- a/services/spdm/transport-mctp/BUILD.bazel
+++ b/services/spdm/transport-mctp/BUILD.bazel
@@ -1,4 +1,5 @@
 # Licensed under the Apache-2.0 license
+# SPDX-License-Identifier: Apache-2.0
 
 load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
 
@@ -10,8 +11,8 @@
     visibility = ["//visibility:public"],
     deps = [
         "//services/mctp/api:mctp_api",
-        "@rust_crates//:spdm-lib",
         "@pigweed//pw_log/rust:pw_log",
+        "@rust_crates//:spdm-lib",
     ],
 )
 
diff --git a/services/spdm/transport-mctp/Cargo.toml b/services/spdm/transport-mctp/Cargo.toml
index 36a77c0..3c8eaa6 100644
--- a/services/spdm/transport-mctp/Cargo.toml
+++ b/services/spdm/transport-mctp/Cargo.toml
@@ -1,4 +1,5 @@
 # Licensed under the Apache-2.0 license
+# SPDX-License-Identifier: Apache-2.0
 
 [package]
 name = "openprot-spdm-transport-mctp"
diff --git a/services/spdm/transport-mctp/src/lib.rs b/services/spdm/transport-mctp/src/lib.rs
index 3346e95..d5acd50 100644
--- a/services/spdm/transport-mctp/src/lib.rs
+++ b/services/spdm/transport-mctp/src/lib.rs
@@ -1,4 +1,5 @@
 // Licensed under the Apache-2.0 license
+// SPDX-License-Identifier: Apache-2.0
 
 //! MCTP-based SPDM Transport
 //!
@@ -96,18 +97,14 @@
         if let Some(remote_eid) = self.remote_eid {
             // Requester mode: get request channel for remote EID
             pw_log::debug!("MctpSpdmTransport: req(eid={})", remote_eid as u32);
-            self.req_channel = Some(
-                self.stack
-                    .req(remote_eid, 0)
-                    .map_err(|e| {
-                        pw_log::error!(
-                            "MctpSpdmTransport: req(eid={}) failed: ResponseCode={}",
-                            remote_eid as u32,
-                            e.code as u32,
-                        );
-                        TransportError::DriverError
-                    })?,
-            );
+            self.req_channel = Some(self.stack.req(remote_eid, 0).map_err(|e| {
+                pw_log::error!(
+                    "MctpSpdmTransport: req(eid={}) failed: ResponseCode={}",
+                    remote_eid as u32,
+                    e.code as u32,
+                );
+                TransportError::DriverError
+            })?);
             pw_log::debug!("MctpSpdmTransport: req channel allocated");
         } else {
             // Responder mode: register listener for SPDM messages
@@ -115,17 +112,13 @@
                 "MctpSpdmTransport: listener(msg_type=0x{:02x})",
                 MCTP_MSG_TYPE_SPDM as u32
             );
-            self.listener = Some(
-                self.stack
-                    .listener(MCTP_MSG_TYPE_SPDM, 0)
-                    .map_err(|e| {
-                        pw_log::error!(
-                            "MctpSpdmTransport: listener(msg_type=0x05) failed: ResponseCode={}",
-                            e.code as u32,
-                        );
-                        TransportError::DriverError
-                    })?,
-            );
+            self.listener = Some(self.stack.listener(MCTP_MSG_TYPE_SPDM, 0).map_err(|e| {
+                pw_log::error!(
+                    "MctpSpdmTransport: listener(msg_type=0x05) failed: ResponseCode={}",
+                    e.code as u32,
+                );
+                TransportError::DriverError
+            })?);
             pw_log::debug!("MctpSpdmTransport: listener allocated");
         }
 
diff --git a/target/ast10x0/tests/spdm/mctp_server/src/main.rs b/target/ast10x0/tests/spdm/mctp_server/src/main.rs
index e45af07..d1e9340 100644
--- a/target/ast10x0/tests/spdm/mctp_server/src/main.rs
+++ b/target/ast10x0/tests/spdm/mctp_server/src/main.rs
@@ -60,9 +60,8 @@
         let header = match MctpRequestHeader::from_bytes(&req_buf[..len]) {
             Some(h) => h,
             None => {
-                let rlen =
-                    wire::encode_error_response(&mut resp_buf, ResponseCode::BadArgument)
-                        .unwrap_or(0);
+                let rlen = wire::encode_error_response(&mut resp_buf, ResponseCode::BadArgument)
+                    .unwrap_or(0);
                 let _ = syscall::channel_respond(handle::MCTP, &resp_buf[..rlen]);
                 continue;
             }