diff --git a/examples/fabric-admin/.gn b/examples/fabric-admin/.gn
new file mode 100644
index 0000000..3b11e2b
--- /dev/null
+++ b/examples/fabric-admin/.gn
@@ -0,0 +1,25 @@
+# Copyright (c) 2024 Project CHIP Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("//build_overrides/build.gni")
+
+# The location of the build configuration file.
+buildconfig = "${build_root}/config/BUILDCONFIG.gn"
+
+# CHIP uses angle bracket includes.
+check_system_includes = true
+
+default_args = {
+  import("//args.gni")
+}
diff --git a/examples/fabric-admin/BUILD.gn b/examples/fabric-admin/BUILD.gn
new file mode 100644
index 0000000..79e175f
--- /dev/null
+++ b/examples/fabric-admin/BUILD.gn
@@ -0,0 +1,120 @@
+# Copyright (c) 2024 Project CHIP Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("//build_overrides/build.gni")
+import("//build_overrides/chip.gni")
+
+import("//build_overrides/editline.gni")
+import("${chip_root}/build/chip/tools.gni")
+import("${chip_root}/examples/fabric-admin/fabric-admin.gni")
+import("${chip_root}/src/lib/core/core.gni")
+
+assert(chip_build_tools)
+
+config("config") {
+  include_dirs = [
+    ".",
+    "${chip_root}/examples/common",
+    "${chip_root}/zzz_generated/app-common/app-common",
+    "${chip_root}/zzz_generated/chip-tool",
+    "${chip_root}/src/lib",
+  ]
+
+  defines = [ "CONFIG_USE_SEPARATE_EVENTLOOP=${config_use_separate_eventloop}" ]
+
+  # Note: CONFIG_USE_LOCAL_STORAGE is tested for via #ifdef, not #if.
+  if (config_use_local_storage) {
+    defines += [ "CONFIG_USE_LOCAL_STORAGE" ]
+  }
+
+  cflags = [ "-Wconversion" ]
+}
+
+static_library("fabric-admin-utils") {
+  sources = [
+    "${chip_root}/src/controller/ExamplePersistentStorage.cpp",
+    "${chip_root}/src/controller/ExamplePersistentStorage.h",
+    "${chip_root}/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.cpp",
+    "${chip_root}/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp",
+    "commands/clusters/ModelCommand.cpp",
+    "commands/clusters/ModelCommand.h",
+    "commands/common/CHIPCommand.cpp",
+    "commands/common/CHIPCommand.h",
+    "commands/common/Command.cpp",
+    "commands/common/Command.h",
+    "commands/common/Commands.cpp",
+    "commands/common/Commands.h",
+    "commands/common/CredentialIssuerCommands.h",
+    "commands/common/HexConversion.h",
+    "commands/common/RemoteDataModelLogger.cpp",
+    "commands/common/RemoteDataModelLogger.h",
+    "commands/pairing/OpenCommissioningWindowCommand.cpp",
+    "commands/pairing/OpenCommissioningWindowCommand.h",
+    "commands/pairing/PairingCommand.cpp",
+    "commands/pairing/ToTLVCert.cpp",
+  ]
+
+  deps = [ "${chip_root}/src/app:events" ]
+
+  sources += [ "commands/interactive/InteractiveCommands.cpp" ]
+  deps += [
+    "${chip_root}/examples/common/websocket-server",
+    "${chip_root}/src/platform/logging:headers",
+    "${editline_root}:editline",
+  ]
+
+  if (chip_device_platform == "darwin") {
+    sources += [ "commands/common/DeviceScanner.cpp" ]
+  }
+
+  public_deps = [
+    "${chip_root}/examples/common/tracing:commandline",
+    "${chip_root}/src/app/icd/client:handler",
+    "${chip_root}/src/app/icd/client:manager",
+    "${chip_root}/src/app/server",
+    "${chip_root}/src/app/tests/suites/commands/interaction_model",
+    "${chip_root}/src/controller/data_model",
+    "${chip_root}/src/credentials:file_attestation_trust_store",
+    "${chip_root}/src/lib",
+    "${chip_root}/src/lib/core:types",
+    "${chip_root}/src/lib/support/jsontlv",
+    "${chip_root}/src/platform",
+    "${chip_root}/third_party/inipp",
+    "${chip_root}/third_party/jsoncpp",
+  ]
+
+  public_configs = [ ":config" ]
+
+  if (chip_enable_transport_trace) {
+    public_deps +=
+        [ "${chip_root}/examples/common/tracing:trace_handlers_decoder" ]
+  }
+
+  output_dir = root_out_dir
+}
+
+executable("fabric-admin") {
+  sources = [ "main.cpp" ]
+
+  deps = [
+    ":fabric-admin-utils",
+    "${chip_root}/src/platform/logging:force_stdio",
+  ]
+
+  output_dir = root_out_dir
+}
+
+group("default") {
+  deps = [ ":fabric-admin" ]
+}
diff --git a/examples/fabric-admin/args.gni b/examples/fabric-admin/args.gni
new file mode 100644
index 0000000..83300d7
--- /dev/null
+++ b/examples/fabric-admin/args.gni
@@ -0,0 +1,34 @@
+# Copyright (c) 2024 Project CHIP Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("//build_overrides/chip.gni")
+
+import("${chip_root}/config/standalone/args.gni")
+
+chip_device_project_config_include = "<CHIPProjectAppConfig.h>"
+chip_project_config_include = "<CHIPProjectAppConfig.h>"
+chip_system_project_config_include = "<SystemProjectConfig.h>"
+
+chip_project_config_include_dirs =
+    [ "${chip_root}/examples/fabric-admin/include" ]
+chip_project_config_include_dirs += [ "${chip_root}/config/standalone" ]
+
+matter_enable_tracing_support = true
+
+matter_log_json_payload_hex = true
+matter_log_json_payload_decode_full = true
+
+# make fabric-admin very strict by default
+chip_tlv_validate_char_string_on_read = true
+chip_tlv_validate_char_string_on_write = true
diff --git a/examples/fabric-admin/build_overrides b/examples/fabric-admin/build_overrides
new file mode 120000
index 0000000..b430cf6
--- /dev/null
+++ b/examples/fabric-admin/build_overrides
@@ -0,0 +1 @@
+../build_overrides
\ No newline at end of file
diff --git a/examples/fabric-admin/commands/clusters/ClusterCommand.h b/examples/fabric-admin/commands/clusters/ClusterCommand.h
new file mode 100644
index 0000000..4865f05
--- /dev/null
+++ b/examples/fabric-admin/commands/clusters/ClusterCommand.h
@@ -0,0 +1,196 @@
+/*
+ *   Copyright (c) 2024 Project CHIP Authors
+ *   All rights reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+#pragma once
+
+#include <app/tests/suites/commands/interaction_model/InteractionModel.h>
+
+#include "DataModelLogger.h"
+#include "ModelCommand.h"
+
+class ClusterCommand : public InteractionModelCommands, public ModelCommand, public chip::app::CommandSender::Callback
+{
+public:
+    ClusterCommand(CredentialIssuerCommands * credsIssuerConfig) :
+        InteractionModelCommands(this), ModelCommand("command-by-id", credsIssuerConfig)
+    {
+        AddArgument("cluster-id", 0, UINT32_MAX, &mClusterId);
+        AddByIdArguments();
+        AddArguments();
+    }
+
+    ClusterCommand(chip::ClusterId clusterId, CredentialIssuerCommands * credsIssuerConfig) :
+        InteractionModelCommands(this), ModelCommand("command-by-id", credsIssuerConfig), mClusterId(clusterId)
+    {
+        AddByIdArguments();
+        AddArguments();
+    }
+
+    ~ClusterCommand() {}
+
+    CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector<chip::EndpointId> endpointIds) override
+    {
+        return InteractionModelCommands::SendCommand(device, endpointIds.at(0), mClusterId, mCommandId, mPayload);
+    }
+
+    template <class T>
+    CHIP_ERROR SendCommand(chip::DeviceProxy * device, chip::EndpointId endpointId, chip::ClusterId clusterId,
+                           chip::CommandId commandId, const T & value)
+    {
+        return InteractionModelCommands::SendCommand(device, endpointId, clusterId, commandId, value);
+    }
+
+    CHIP_ERROR SendGroupCommand(chip::GroupId groupId, chip::FabricIndex fabricIndex) override
+    {
+        return InteractionModelCommands::SendGroupCommand(groupId, fabricIndex, mClusterId, mCommandId, mPayload);
+    }
+
+    template <class T>
+    CHIP_ERROR SendGroupCommand(chip::GroupId groupId, chip::FabricIndex fabricIndex, chip::ClusterId clusterId,
+                                chip::CommandId commandId, const T & value)
+    {
+        return InteractionModelCommands::SendGroupCommand(groupId, fabricIndex, clusterId, commandId, value);
+    }
+
+    /////////// CommandSender Callback Interface /////////
+    virtual void OnResponse(chip::app::CommandSender * client, const chip::app::ConcreteCommandPath & path,
+                            const chip::app::StatusIB & status, chip::TLV::TLVReader * data) override
+    {
+        CHIP_ERROR error = status.ToChipError();
+        if (CHIP_NO_ERROR != error)
+        {
+            LogErrorOnFailure(RemoteDataModelLogger::LogErrorAsJSON(path, status));
+
+            ChipLogError(NotSpecified, "Response Failure: %s", chip::ErrorStr(error));
+            mError = error;
+            return;
+        }
+
+        if (data != nullptr)
+        {
+            LogErrorOnFailure(RemoteDataModelLogger::LogCommandAsJSON(path, data));
+
+            error = DataModelLogger::LogCommand(path, data);
+            if (CHIP_NO_ERROR != error)
+            {
+                ChipLogError(NotSpecified, "Response Failure: Can not decode Data");
+                mError = error;
+                return;
+            }
+        }
+    }
+
+    virtual void OnError(const chip::app::CommandSender * client, CHIP_ERROR error) override
+    {
+        LogErrorOnFailure(RemoteDataModelLogger::LogErrorAsJSON(error));
+
+        ChipLogProgress(NotSpecified, "Error: %s", chip::ErrorStr(error));
+        mError = error;
+    }
+
+    virtual void OnDone(chip::app::CommandSender * client) override
+    {
+        if (mCommandSender.size())
+        {
+            mCommandSender.front().reset();
+            mCommandSender.erase(mCommandSender.begin());
+        }
+
+        // If the command is repeated N times, wait for all the responses to comes in
+        // before exiting.
+        bool shouldStop = true;
+        if (mRepeatCount.HasValue())
+        {
+            mRepeatCount.SetValue(static_cast<uint16_t>(mRepeatCount.Value() - 1));
+            shouldStop = mRepeatCount.Value() == 0;
+        }
+
+        if (shouldStop)
+        {
+            SetCommandExitStatus(mError);
+        }
+    }
+
+    void Shutdown() override
+    {
+        mError = CHIP_NO_ERROR;
+        ModelCommand::Shutdown();
+    }
+
+protected:
+    ClusterCommand(const char * commandName, CredentialIssuerCommands * credsIssuerConfig) :
+        InteractionModelCommands(this), ModelCommand(commandName, credsIssuerConfig)
+    {
+        // Subclasses are responsible for calling AddArguments.
+    }
+
+    void AddByIdArguments()
+    {
+        AddArgument("command-id", 0, UINT32_MAX, &mCommandId);
+        AddArgument("payload", &mPayload,
+                    "The command payload.  This should be a JSON-encoded object, with string representations of field ids as keys. "
+                    " The values for the keys are represented as follows, depending on the type:\n"
+                    "  * struct: a JSON-encoded object, with field ids as keys.\n"
+                    "  * list: a JSON-encoded array of values.\n"
+                    "  * null: A literal null.\n"
+                    "  * boolean: A literal true or false.\n"
+                    "  * unsigned integer: One of:\n"
+                    "      a) The number directly, as decimal.\n"
+                    "      b) A string starting with \"u:\" followed by decimal digits\n"
+                    "  * signed integer: One of:\n"
+                    "      a) The number directly, if it's negative.\n"
+                    "      b) A string starting with \"s:\" followed by decimal digits\n"
+                    "  * single-precision float: A string starting with \"f:\" followed by the number.\n"
+                    "  * double-precision float: One of:\n"
+                    "      a) The number directly, if it's not an integer.\n"
+                    "      b) A string starting with \"d:\" followed by the number.\n"
+                    "  * octet string: A string starting with \"hex:\" followed by the hex encoding of the bytes.\n"
+                    "  * string: A string with the characters.\n"
+                    "\n"
+                    "  An example payload may look like this: '{ \"0x0\": { \"0\": null, \"1\": false }, \"1\": [17, \"u:17\"], "
+                    "\"0x2\": [ -17, \"s:17\", \"s:-17\" ], \"0x3\": \"f:2\", \"0x4\": [ \"d:3\", 4.5 ], \"0x5\": \"hex:ab12\", "
+                    "\"0x6\": \"ab12\" }' and represents:\n"
+                    "    Field 0: a struct with two fields, one with value null and one with value false.\n"
+                    "    Field 1: A list of unsigned integers.\n"
+                    "    Field 2: A list of signed integers.\n"
+                    "    Field 3: A single-precision float.\n"
+                    "    Field 4: A list of double-precision floats.\n"
+                    "    Field 5: A 2-byte octet string.\n"
+                    "    Field 6: A 4-char character string.");
+    }
+
+    void AddArguments()
+    {
+        AddArgument("timedInteractionTimeoutMs", 0, UINT16_MAX, &mTimedInteractionTimeoutMs,
+                    "If provided, do a timed invoke with the given timed interaction timeout. See \"7.6.10. Timed Interaction\" in "
+                    "the Matter specification.");
+        AddArgument("busyWaitForMs", 0, UINT16_MAX, &mBusyWaitForMs,
+                    "If provided, block the main thread processing for the given time right after sending a command.");
+        AddArgument("suppressResponse", 0, 1, &mSuppressResponse);
+        AddArgument("repeat-count", 1, UINT16_MAX, &mRepeatCount);
+        AddArgument("repeat-delay-ms", 0, UINT16_MAX, &mRepeatDelayInMs);
+        ModelCommand::AddArguments();
+    }
+
+private:
+    chip::ClusterId mClusterId;
+    chip::CommandId mCommandId;
+
+    CHIP_ERROR mError = CHIP_NO_ERROR;
+    CustomArgument mPayload;
+};
diff --git a/examples/fabric-admin/commands/clusters/ComplexArgument.h b/examples/fabric-admin/commands/clusters/ComplexArgument.h
new file mode 100644
index 0000000..954ea1d
--- /dev/null
+++ b/examples/fabric-admin/commands/clusters/ComplexArgument.h
@@ -0,0 +1,422 @@
+/*
+ *   Copyright (c) 2024 Project CHIP Authors
+ *   All rights reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+/**
+ * This file allocate/free memory using the chip platform abstractions
+ * (Platform::MemoryCalloc and Platform::MemoryFree) for hosting a subset of the
+ * data model internal types until they are consumed by the DataModel::Encode machinery:
+ *   - chip::app:DataModel::List<T>
+ *   - chip::ByteSpan
+ *   - chip::CharSpan
+ *
+ * Memory allocation happens during the 'Setup' phase, while memory deallocation happens
+ * during the 'Finalize' phase.
+ *
+ * The 'Finalize' phase during the destructor phase, and if needed, 'Finalize' will call
+ * the 'Finalize' phase of its descendant.
+ */
+
+#pragma once
+
+#include <app-common/zap-generated/cluster-objects.h>
+#include <app/data-model/List.h>
+#include <app/data-model/Nullable.h>
+#include <commands/common/HexConversion.h>
+#include <json/json.h>
+#include <lib/core/Optional.h>
+#include <lib/support/BytesToHex.h>
+#include <lib/support/CHIPMemString.h>
+#include <lib/support/SafeInt.h>
+
+#include "JsonParser.h"
+
+inline constexpr uint8_t kMaxLabelLength = UINT8_MAX;
+inline constexpr char kNullString[]      = "null";
+
+class ComplexArgumentParser
+{
+public:
+    ComplexArgumentParser() {}
+
+    template <typename T,
+              typename std::enable_if_t<std::is_integral<T>::value && !std::is_signed<T>::value &&
+                                            !std::is_same<std::remove_cv_t<std::remove_reference_t<T>>, bool>::value,
+                                        int> = 0>
+    static CHIP_ERROR Setup(const char * label, T & request, Json::Value value)
+    {
+        if (value.isNumeric())
+        {
+            if (chip::CanCastTo<T>(value.asLargestUInt()))
+            {
+                request = static_cast<T>(value.asLargestUInt());
+                return CHIP_NO_ERROR;
+            }
+        }
+        else if (value.isString())
+        {
+            // Check for a hex number; JSON does not support those as numbers,
+            // so they have to be done as strings.  And we might as well support
+            // string-encoded unsigned numbers in general if we're doing that.
+            bool isHexNotation = strncmp(value.asCString(), "0x", 2) == 0 || strncmp(value.asCString(), "0X", 2) == 0;
+
+            std::stringstream str;
+            isHexNotation ? str << std::hex << value.asCString() : str << value.asCString();
+            uint64_t val;
+            str >> val;
+            if (!str.fail() && str.eof() && chip::CanCastTo<T>(val))
+            {
+                request = static_cast<T>(val);
+                return CHIP_NO_ERROR;
+            }
+        }
+
+        ChipLogError(NotSpecified, "Error while encoding %s as an unsigned integer.", label);
+        return CHIP_ERROR_INVALID_ARGUMENT;
+    }
+
+    template <typename T, std::enable_if_t<std::is_signed<T>::value, bool> = true>
+    static CHIP_ERROR Setup(const char * label, T & request, Json::Value value)
+    {
+        if (!value.isNumeric() || !chip::CanCastTo<T>(value.asLargestInt()))
+        {
+            ChipLogError(NotSpecified, "Error while encoding %s as an unsigned integer.", label);
+            return CHIP_ERROR_INVALID_ARGUMENT;
+        }
+
+        request = static_cast<T>(value.asLargestInt());
+        return CHIP_NO_ERROR;
+    }
+
+    template <typename T, typename std::enable_if_t<std::is_enum<T>::value, int> = 0>
+    static CHIP_ERROR Setup(const char * label, T & request, Json::Value value)
+    {
+        std::underlying_type_t<T> requestValue;
+        ReturnErrorOnFailure(ComplexArgumentParser::Setup(label, requestValue, value));
+
+        request = static_cast<T>(requestValue);
+        return CHIP_NO_ERROR;
+    }
+
+    template <typename T>
+    static CHIP_ERROR Setup(const char * label, chip::BitFlags<T> & request, Json::Value & value)
+    {
+        T requestValue;
+        ReturnErrorOnFailure(ComplexArgumentParser::Setup(label, requestValue, value));
+
+        request = chip::BitFlags<T>(requestValue);
+        return CHIP_NO_ERROR;
+    }
+
+    template <typename T>
+    static CHIP_ERROR Setup(const char * label, chip::BitMask<T> & request, Json::Value & value)
+    {
+        T requestValue;
+        ReturnErrorOnFailure(ComplexArgumentParser::Setup(label, requestValue, value));
+
+        request = chip::BitMask<T>(requestValue);
+        return CHIP_NO_ERROR;
+    }
+
+    template <typename T>
+    static CHIP_ERROR Setup(const char * label, chip::Optional<T> & request, Json::Value & value)
+    {
+        T requestValue;
+        ReturnErrorOnFailure(ComplexArgumentParser::Setup(label, requestValue, value));
+
+        request = chip::Optional<T>(requestValue);
+        return CHIP_NO_ERROR;
+    }
+
+    template <typename T>
+    static CHIP_ERROR Setup(const char * label, chip::app::DataModel::Nullable<T> & request, Json::Value & value)
+    {
+        if (value.isNull())
+        {
+            request.SetNull();
+            return CHIP_NO_ERROR;
+        }
+
+        T requestValue;
+        ReturnErrorOnFailure(ComplexArgumentParser::Setup(label, requestValue, value));
+
+        request = chip::app::DataModel::Nullable<T>(requestValue);
+        return CHIP_NO_ERROR;
+    }
+
+    template <typename T>
+    static CHIP_ERROR Setup(const char * label, chip::app::DataModel::List<T> & request, Json::Value & value)
+    {
+        if (!value.isArray())
+        {
+            ChipLogError(NotSpecified, "Error while encoding %s as an array.", label);
+            return CHIP_ERROR_INVALID_ARGUMENT;
+        }
+
+        auto content = static_cast<typename std::remove_const<T>::type *>(chip::Platform::MemoryCalloc(value.size(), sizeof(T)));
+        VerifyOrReturnError(content != nullptr, CHIP_ERROR_NO_MEMORY);
+
+        Json::ArrayIndex size = value.size();
+        for (Json::ArrayIndex i = 0; i < size; i++)
+        {
+            char labelWithIndex[kMaxLabelLength];
+            // GCC 7.0.1 has introduced some new warnings for snprintf (-Werror=format-truncation) by default.
+            // This is not particularly useful when using snprintf and especially in this context, so in order
+            // to disable the warning the %s is constrained to be of max length: (254 - 11 - 2) where:
+            //  - 254 is kMaxLabelLength - 1 (for null)
+            //  - 11 is the maximum length of a %d (-2147483648, 2147483647)
+            //  - 2 is the length for the "[" and "]" characters.
+            snprintf(labelWithIndex, sizeof(labelWithIndex), "%.241s[%d]", label, i);
+            ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithIndex, content[i], value[i]));
+        }
+
+        request = chip::app::DataModel::List<T>(content, value.size());
+        return CHIP_NO_ERROR;
+    }
+
+    static CHIP_ERROR Setup(const char * label, chip::ByteSpan & request, Json::Value & value)
+    {
+        if (!value.isString())
+        {
+            ChipLogError(NotSpecified, "Error while encoding %s as an octet string: Not a string.", label);
+            return CHIP_ERROR_INVALID_ARGUMENT;
+        }
+
+        auto str         = value.asString();
+        auto size        = str.size();
+        uint8_t * buffer = nullptr;
+
+        if (IsStrString(str.c_str()))
+        {
+            // Skip the prefix
+            str.erase(0, kStrStringPrefixLen);
+            size = str.size();
+
+            buffer = static_cast<uint8_t *>(chip::Platform::MemoryCalloc(size, sizeof(uint8_t)));
+            VerifyOrReturnError(buffer != nullptr, CHIP_ERROR_NO_MEMORY);
+
+            memcpy(buffer, str.c_str(), size);
+        }
+        else
+        {
+            if (IsHexString(str.c_str()))
+            {
+                // Skip the prefix
+                str.erase(0, kHexStringPrefixLen);
+                size = str.size();
+            }
+
+            CHIP_ERROR err = HexToBytes(
+                chip::CharSpan(str.c_str(), size),
+                [&buffer](size_t allocSize) {
+                    buffer = static_cast<uint8_t *>(chip::Platform::MemoryCalloc(allocSize, sizeof(uint8_t)));
+                    return buffer;
+                },
+                &size);
+
+            if (err != CHIP_NO_ERROR)
+            {
+                if (buffer != nullptr)
+                {
+                    chip::Platform::MemoryFree(buffer);
+                }
+
+                return err;
+            }
+        }
+
+        request = chip::ByteSpan(buffer, size);
+        return CHIP_NO_ERROR;
+    }
+
+    static CHIP_ERROR Setup(const char * label, chip::CharSpan & request, Json::Value & value)
+    {
+        if (!value.isString())
+        {
+            ChipLogError(NotSpecified, "Error while encoding %s as a string: Not a string.", label);
+            return CHIP_ERROR_INVALID_ARGUMENT;
+        }
+
+        size_t size = strlen(value.asCString());
+        auto buffer = static_cast<char *>(chip::Platform::MemoryCalloc(size, sizeof(char)));
+        VerifyOrReturnError(buffer != nullptr, CHIP_ERROR_NO_MEMORY);
+
+        memcpy(buffer, value.asCString(), size);
+
+        request = chip::CharSpan(buffer, size);
+        return CHIP_NO_ERROR;
+    }
+
+    static CHIP_ERROR Setup(const char * label, float & request, Json::Value & value)
+    {
+        if (!value.isNumeric())
+        {
+            ChipLogError(NotSpecified, "Error while encoding %s as a float: Not a number.", label);
+            return CHIP_ERROR_INVALID_ARGUMENT;
+        }
+
+        request = static_cast<float>(value.asFloat());
+        return CHIP_NO_ERROR;
+    }
+
+    static CHIP_ERROR Setup(const char * label, double & request, Json::Value & value)
+    {
+        if (!value.isNumeric())
+        {
+            ChipLogError(NotSpecified, "Error while encoding %s as a double: Not a number.", label);
+            return CHIP_ERROR_INVALID_ARGUMENT;
+        }
+
+        request = static_cast<double>(value.asDouble());
+        return CHIP_NO_ERROR;
+    }
+
+    static CHIP_ERROR Setup(const char * label, bool & request, Json::Value & value)
+    {
+        if (!value.isBool())
+        {
+            ChipLogError(NotSpecified, "Error while encoding %s as a boolean: Not a boolean.", label);
+            return CHIP_ERROR_INVALID_ARGUMENT;
+        }
+
+        request = value.asBool();
+        return CHIP_NO_ERROR;
+    }
+
+    static CHIP_ERROR EnsureMemberExist(const char * label, const char * memberName, bool hasMember)
+    {
+        if (hasMember)
+        {
+            return CHIP_NO_ERROR;
+        }
+
+        ChipLogError(NotSpecified, "%s is required.  Should be provided as {\"%s\": value}", label, memberName);
+        return CHIP_ERROR_INVALID_ARGUMENT;
+    }
+
+    static CHIP_ERROR EnsureNoMembersRemaining(const char * label, const Json::Value & value)
+    {
+        auto remainingFields = value.getMemberNames();
+        if (remainingFields.size() == 0)
+        {
+            return CHIP_NO_ERROR;
+        }
+#if CHIP_ERROR_LOGGING
+        for (auto & field : remainingFields)
+        {
+            ChipLogError(NotSpecified, "Unexpected field name: '%s.%s'", label, field.c_str());
+        }
+#endif // CHIP_ERROR_LOGGING
+        return CHIP_ERROR_INVALID_ARGUMENT;
+    }
+
+    template <typename T>
+    static void Finalize(T & request)
+    {
+        // Nothing to do
+    }
+
+    template <typename T>
+    static void Finalize(chip::Optional<T> & request)
+    {
+        VerifyOrReturn(request.HasValue());
+        ComplexArgumentParser::Finalize(request.Value());
+    }
+
+    template <typename T>
+    static void Finalize(chip::app::DataModel::Nullable<T> & request)
+    {
+        VerifyOrReturn(!request.IsNull());
+        ComplexArgumentParser::Finalize(request.Value());
+    }
+
+    static void Finalize(chip::ByteSpan & request)
+    {
+        VerifyOrReturn(request.data() != nullptr);
+        chip::Platform::MemoryFree(reinterpret_cast<void *>(const_cast<uint8_t *>(request.data())));
+    }
+
+    static void Finalize(chip::CharSpan & request)
+    {
+        VerifyOrReturn(request.data() != nullptr);
+        chip::Platform::MemoryFree(reinterpret_cast<void *>(const_cast<char *>(request.data())));
+    }
+
+    template <typename T>
+    static void Finalize(chip::app::DataModel::List<T> & request)
+    {
+        VerifyOrReturn(request.data() != nullptr);
+
+        size_t size = request.size();
+        auto data   = const_cast<typename std::remove_const<T>::type *>(request.data());
+        for (size_t i = 0; i < size; i++)
+        {
+            Finalize(data[i]);
+        }
+
+        chip::Platform::MemoryFree(reinterpret_cast<void *>(data));
+    }
+
+#include <zap-generated/cluster/ComplexArgumentParser.h>
+};
+
+class ComplexArgument
+{
+public:
+    virtual ~ComplexArgument() {}
+
+    virtual CHIP_ERROR Parse(const char * label, const char * json) = 0;
+
+    virtual void Reset() = 0;
+};
+
+template <typename T>
+class TypedComplexArgument : public ComplexArgument
+{
+public:
+    TypedComplexArgument() {}
+    TypedComplexArgument(T * request) : mRequest(request) {}
+    ~TypedComplexArgument()
+    {
+        if (mRequest != nullptr)
+        {
+            ComplexArgumentParser::Finalize(*mRequest);
+        }
+    }
+
+    void SetArgument(T * request) { mRequest = request; };
+
+    CHIP_ERROR Parse(const char * label, const char * json)
+    {
+        Json::Value value;
+        if (strcmp(kNullString, json) == 0)
+        {
+            value = Json::nullValue;
+        }
+        else if (!JsonParser::ParseComplexArgument(label, json, value))
+        {
+            return CHIP_ERROR_INVALID_ARGUMENT;
+        }
+
+        return ComplexArgumentParser::Setup(label, *mRequest, value);
+    }
+
+    void Reset() { *mRequest = T(); }
+
+private:
+    T * mRequest;
+};
diff --git a/examples/fabric-admin/commands/clusters/CustomArgument.h b/examples/fabric-admin/commands/clusters/CustomArgument.h
new file mode 100644
index 0000000..3769c00
--- /dev/null
+++ b/examples/fabric-admin/commands/clusters/CustomArgument.h
@@ -0,0 +1,297 @@
+/*
+ *   Copyright (c) 2024 Project CHIP Authors
+ *   All rights reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+#pragma once
+
+#include <app-common/zap-generated/cluster-objects.h>
+#include <commands/common/HexConversion.h>
+#include <lib/support/BytesToHex.h>
+#include <lib/support/CHIPMemString.h>
+#include <lib/support/SafeInt.h>
+
+#include <string>
+
+#include "JsonParser.h"
+
+namespace {
+static constexpr char kPayloadHexPrefix[]         = "hex:";
+static constexpr char kPayloadSignedPrefix[]      = "s:";
+static constexpr char kPayloadUnsignedPrefix[]    = "u:";
+static constexpr char kPayloadFloatPrefix[]       = "f:";
+static constexpr char kPayloadDoublePrefix[]      = "d:";
+static constexpr size_t kPayloadHexPrefixLen      = ArraySize(kPayloadHexPrefix) - 1;      // ignore null character
+static constexpr size_t kPayloadSignedPrefixLen   = ArraySize(kPayloadSignedPrefix) - 1;   // ignore null character
+static constexpr size_t kPayloadUnsignedPrefixLen = ArraySize(kPayloadUnsignedPrefix) - 1; // ignore null character
+static constexpr size_t kPayloadFloatPrefixLen    = ArraySize(kPayloadFloatPrefix) - 1;    // ignore null character
+static constexpr size_t kPayloadDoublePrefixLen   = ArraySize(kPayloadDoublePrefix) - 1;   // ignore null character
+} // namespace
+
+class CustomArgumentParser
+{
+public:
+    static CHIP_ERROR Put(chip::TLV::TLVWriter * writer, chip::TLV::Tag tag, Json::Value & value)
+    {
+        if (value.isObject())
+        {
+            return CustomArgumentParser::PutObject(writer, tag, value);
+        }
+
+        if (value.isArray())
+        {
+            return CustomArgumentParser::PutArray(writer, tag, value);
+        }
+
+        if (value.isString())
+        {
+            if (IsOctetString(value))
+            {
+                return CustomArgumentParser::PutOctetString(writer, tag, value);
+            }
+            if (IsUnsignedNumberPrefix(value))
+            {
+                return CustomArgumentParser::PutUnsignedFromString(writer, tag, value);
+            }
+            if (IsSignedNumberPrefix(value))
+            {
+                return CustomArgumentParser::PutSignedFromString(writer, tag, value);
+            }
+            if (IsFloatNumberPrefix(value))
+            {
+                return CustomArgumentParser::PutFloatFromString(writer, tag, value);
+            }
+            if (IsDoubleNumberPrefix(value))
+            {
+                return CustomArgumentParser::PutDoubleFromString(writer, tag, value);
+            }
+
+            return CustomArgumentParser::PutCharString(writer, tag, value);
+        }
+
+        if (value.isNull())
+        {
+            return chip::app::DataModel::Encode(*writer, tag, chip::app::DataModel::Nullable<uint8_t>());
+        }
+
+        if (value.isBool())
+        {
+            return chip::app::DataModel::Encode(*writer, tag, value.asBool());
+        }
+
+        if (value.isUInt())
+        {
+            return chip::app::DataModel::Encode(*writer, tag, value.asLargestUInt());
+        }
+
+        if (value.isInt())
+        {
+            return chip::app::DataModel::Encode(*writer, tag, value.asLargestInt());
+        }
+
+        if (value.isNumeric())
+        {
+            return chip::app::DataModel::Encode(*writer, tag, value.asDouble());
+        }
+
+        return CHIP_ERROR_NOT_IMPLEMENTED;
+    }
+
+private:
+    static CHIP_ERROR PutArray(chip::TLV::TLVWriter * writer, chip::TLV::Tag tag, Json::Value & value)
+    {
+        chip::TLV::TLVType outer;
+        ReturnErrorOnFailure(writer->StartContainer(tag, chip::TLV::kTLVType_Array, outer));
+
+        Json::ArrayIndex size = value.size();
+
+        for (Json::ArrayIndex i = 0; i < size; i++)
+        {
+            ReturnErrorOnFailure(CustomArgumentParser::Put(writer, chip::TLV::AnonymousTag(), value[i]));
+        }
+
+        return writer->EndContainer(outer);
+    }
+
+    static CHIP_ERROR PutObject(chip::TLV::TLVWriter * writer, chip::TLV::Tag tag, Json::Value & value)
+    {
+        chip::TLV::TLVType outer;
+        ReturnErrorOnFailure(writer->StartContainer(tag, chip::TLV::kTLVType_Structure, outer));
+
+        for (auto const & id : value.getMemberNames())
+        {
+            auto index = std::stoul(id, nullptr, 0);
+            VerifyOrReturnError(chip::CanCastTo<uint8_t>(index), CHIP_ERROR_INVALID_ARGUMENT);
+            ReturnErrorOnFailure(CustomArgumentParser::Put(writer, chip::TLV::ContextTag(static_cast<uint8_t>(index)), value[id]));
+        }
+
+        return writer->EndContainer(outer);
+    }
+
+    static CHIP_ERROR PutOctetString(chip::TLV::TLVWriter * writer, chip::TLV::Tag tag, Json::Value & value)
+    {
+        const char * hexData = value.asCString() + kPayloadHexPrefixLen;
+        size_t hexDataLen    = strlen(hexData);
+        chip::Platform::ScopedMemoryBuffer<uint8_t> buffer;
+
+        size_t octetCount;
+        ReturnErrorOnFailure(HexToBytes(
+            chip::CharSpan(hexData, hexDataLen),
+            [&buffer](size_t allocSize) {
+                buffer.Calloc(allocSize);
+                return buffer.Get();
+            },
+            &octetCount));
+
+        return chip::app::DataModel::Encode(*writer, tag, chip::ByteSpan(buffer.Get(), octetCount));
+    }
+
+    static CHIP_ERROR PutCharString(chip::TLV::TLVWriter * writer, chip::TLV::Tag tag, Json::Value & value)
+    {
+        size_t size = strlen(value.asCString());
+        return chip::app::DataModel::Encode(*writer, tag, chip::CharSpan(value.asCString(), size));
+    }
+
+    static CHIP_ERROR PutUnsignedFromString(chip::TLV::TLVWriter * writer, chip::TLV::Tag tag, Json::Value & value)
+    {
+        char numberAsString[21];
+        chip::Platform::CopyString(numberAsString, value.asCString() + kPayloadUnsignedPrefixLen);
+
+        auto number = std::stoull(numberAsString, nullptr, 0);
+        return chip::app::DataModel::Encode(*writer, tag, static_cast<uint64_t>(number));
+    }
+
+    static CHIP_ERROR PutSignedFromString(chip::TLV::TLVWriter * writer, chip::TLV::Tag tag, Json::Value & value)
+    {
+        char numberAsString[21];
+        chip::Platform::CopyString(numberAsString, value.asCString() + kPayloadSignedPrefixLen);
+
+        auto number = std::stoll(numberAsString, nullptr, 0);
+        return chip::app::DataModel::Encode(*writer, tag, static_cast<int64_t>(number));
+    }
+
+    static CHIP_ERROR PutFloatFromString(chip::TLV::TLVWriter * writer, chip::TLV::Tag tag, Json::Value & value)
+    {
+        char numberAsString[21];
+        chip::Platform::CopyString(numberAsString, value.asCString() + kPayloadFloatPrefixLen);
+
+        auto number = std::stof(numberAsString);
+        return chip::app::DataModel::Encode(*writer, tag, number);
+    }
+
+    static CHIP_ERROR PutDoubleFromString(chip::TLV::TLVWriter * writer, chip::TLV::Tag tag, Json::Value & value)
+    {
+        char numberAsString[21];
+        chip::Platform::CopyString(numberAsString, value.asCString() + kPayloadDoublePrefixLen);
+
+        auto number = std::stod(numberAsString);
+        return chip::app::DataModel::Encode(*writer, tag, number);
+    }
+
+    static bool IsOctetString(Json::Value & value)
+    {
+        return (strncmp(value.asCString(), kPayloadHexPrefix, kPayloadHexPrefixLen) == 0);
+    }
+
+    static bool IsUnsignedNumberPrefix(Json::Value & value)
+    {
+        return (strncmp(value.asCString(), kPayloadUnsignedPrefix, kPayloadUnsignedPrefixLen) == 0);
+    }
+
+    static bool IsSignedNumberPrefix(Json::Value & value)
+    {
+        return (strncmp(value.asCString(), kPayloadSignedPrefix, kPayloadSignedPrefixLen) == 0);
+    }
+
+    static bool IsFloatNumberPrefix(Json::Value & value)
+    {
+        return (strncmp(value.asCString(), kPayloadFloatPrefix, kPayloadFloatPrefixLen) == 0);
+    }
+
+    static bool IsDoubleNumberPrefix(Json::Value & value)
+    {
+        return (strncmp(value.asCString(), kPayloadDoublePrefix, kPayloadDoublePrefixLen) == 0);
+    }
+};
+
+class CustomArgument
+{
+public:
+    ~CustomArgument()
+    {
+        if (mData != nullptr)
+        {
+            chip::Platform::MemoryFree(mData);
+        }
+    }
+
+    CHIP_ERROR Parse(const char * label, const char * json)
+    {
+        Json::Value value;
+        static constexpr char kHexNumPrefix[] = "0x";
+        constexpr size_t kHexNumPrefixLen     = ArraySize(kHexNumPrefix) - 1;
+        if (strncmp(json, kPayloadHexPrefix, kPayloadHexPrefixLen) == 0 ||
+            strncmp(json, kPayloadSignedPrefix, kPayloadSignedPrefixLen) == 0 ||
+            strncmp(json, kPayloadUnsignedPrefix, kPayloadUnsignedPrefixLen) == 0 ||
+            strncmp(json, kPayloadFloatPrefix, kPayloadFloatPrefixLen) == 0 ||
+            strncmp(json, kPayloadDoublePrefix, kPayloadDoublePrefixLen) == 0)
+        {
+            value = Json::Value(json);
+        }
+        else if (strncmp(json, kHexNumPrefix, kHexNumPrefixLen) == 0)
+        {
+            // Assume that hex numbers are unsigned.  Prepend
+            // kPayloadUnsignedPrefix and then let the rest of the logic handle
+            // things.
+            std::string str(kPayloadUnsignedPrefix);
+            str += json;
+            value = Json::Value(str);
+        }
+        else if (!JsonParser::ParseCustomArgument(label, json, value))
+        {
+            return CHIP_ERROR_INVALID_ARGUMENT;
+        }
+
+        mData = static_cast<uint8_t *>(chip::Platform::MemoryCalloc(sizeof(uint8_t), mDataMaxLen));
+        VerifyOrReturnError(mData != nullptr, CHIP_ERROR_NO_MEMORY);
+
+        chip::TLV::TLVWriter writer;
+        writer.Init(mData, mDataMaxLen);
+
+        ReturnErrorOnFailure(CustomArgumentParser::Put(&writer, chip::TLV::AnonymousTag(), value));
+
+        mDataLen = writer.GetLengthWritten();
+        return writer.Finalize();
+    }
+
+    CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const
+    {
+        chip::TLV::TLVReader reader;
+        reader.Init(mData, mDataLen);
+        ReturnErrorOnFailure(reader.Next());
+
+        return writer.CopyElement(tag, reader);
+    }
+
+    // We trust our consumers to do the encoding of our data correctly, so don't
+    // need to know whether we are being encoded for a write.
+    static constexpr bool kIsFabricScoped = false;
+
+private:
+    uint8_t * mData                       = nullptr;
+    uint32_t mDataLen                     = 0;
+    static constexpr uint32_t mDataMaxLen = 4096;
+};
diff --git a/examples/fabric-admin/commands/clusters/DataModelLogger.h b/examples/fabric-admin/commands/clusters/DataModelLogger.h
new file mode 100644
index 0000000..ee64975
--- /dev/null
+++ b/examples/fabric-admin/commands/clusters/DataModelLogger.h
@@ -0,0 +1,190 @@
+/*
+ *   Copyright (c) 2024 Project CHIP Authors
+ *   All rights reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+#pragma once
+
+#include <string>
+
+#include <app-common/zap-generated/cluster-objects.h>
+#include <app/ConcreteAttributePath.h>
+#include <app/ConcreteCommandPath.h>
+#include <app/EventHeader.h>
+#include <app/MessageDef/StatusIB.h>
+#include <app/data-model/DecodableList.h>
+#include <commands/common/RemoteDataModelLogger.h>
+#include <lib/support/BytesToHex.h>
+
+class DataModelLogger
+{
+public:
+    static CHIP_ERROR LogAttribute(const chip::app::ConcreteDataAttributePath & path, chip::TLV::TLVReader * data);
+    static CHIP_ERROR LogCommand(const chip::app::ConcreteCommandPath & path, chip::TLV::TLVReader * data);
+    static CHIP_ERROR LogEvent(const chip::app::EventHeader & header, chip::TLV::TLVReader * data);
+
+private:
+    static CHIP_ERROR LogValue(const char * label, size_t indent, bool value)
+    {
+        DataModelLogger::LogString(label, indent, value ? "TRUE" : "FALSE");
+        return CHIP_NO_ERROR;
+    }
+
+    static CHIP_ERROR LogValue(const char * label, size_t indent, chip::CharSpan value)
+    {
+        DataModelLogger::LogString(label, indent, std::string(value.data(), value.size()));
+        return CHIP_NO_ERROR;
+    }
+
+    static CHIP_ERROR LogValue(const char * label, size_t indent, chip::ByteSpan value)
+    {
+        // CHIP_CONFIG_LOG_MESSAGE_MAX_SIZE includes various prefixes we don't
+        // control (timestamps, process ids, etc).  Let's assume (hope?) that
+        // those prefixes use up no more than half the total available space.
+        // Right now it looks like the prefixes are 45 chars out of a 255 char
+        // buffer.
+        char buffer[CHIP_CONFIG_LOG_MESSAGE_MAX_SIZE / 2];
+        size_t prefixSize = ComputePrefixSize(label, indent);
+        if (prefixSize > ArraySize(buffer))
+        {
+            DataModelLogger::LogString("", 0, "Prefix is too long to fit in buffer");
+            return CHIP_ERROR_INTERNAL;
+        }
+
+        const size_t availableSize = ArraySize(buffer) - prefixSize;
+        // Each byte ends up as two hex characters.
+        const size_t bytesPerLogCall = availableSize / 2;
+        std::string labelStr(label);
+        while (value.size() > bytesPerLogCall)
+        {
+            ReturnErrorOnFailure(
+                chip::Encoding::BytesToUppercaseHexString(value.data(), bytesPerLogCall, &buffer[0], ArraySize(buffer)));
+            LogString(labelStr, indent, buffer);
+            value = value.SubSpan(bytesPerLogCall);
+            // For the second and following lines, make it clear that they are
+            // continuation lines by replacing the label with "....".
+            labelStr.replace(labelStr.begin(), labelStr.end(), labelStr.size(), '.');
+        }
+        ReturnErrorOnFailure(chip::Encoding::BytesToUppercaseHexString(value.data(), value.size(), &buffer[0], ArraySize(buffer)));
+        LogString(labelStr, indent, buffer);
+
+        return CHIP_NO_ERROR;
+    }
+
+    template <typename X,
+              typename std::enable_if_t<
+                  std::is_integral<X>::value && !std::is_same<std::remove_cv_t<std::remove_reference_t<X>>, bool>::value, int> = 0>
+    static CHIP_ERROR LogValue(const char * label, size_t indent, X value)
+    {
+        DataModelLogger::LogString(label, indent, std::to_string(value));
+        return CHIP_NO_ERROR;
+    }
+
+    template <typename X, typename std::enable_if_t<std::is_floating_point<X>::value, int> = 0>
+    static CHIP_ERROR LogValue(const char * label, size_t indent, X value)
+    {
+        DataModelLogger::LogString(label, indent, std::to_string(value));
+        return CHIP_NO_ERROR;
+    }
+
+    template <typename X, typename std::enable_if_t<std::is_enum<X>::value, int> = 0>
+    static CHIP_ERROR LogValue(const char * label, size_t indent, X value)
+    {
+        return DataModelLogger::LogValue(label, indent, chip::to_underlying(value));
+    }
+
+    template <typename X>
+    static CHIP_ERROR LogValue(const char * label, size_t indent, chip::BitFlags<X> value)
+    {
+        return DataModelLogger::LogValue(label, indent, value.Raw());
+    }
+
+    template <typename T>
+    static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::DataModel::DecodableList<T> & value)
+    {
+        size_t count = 0;
+        ReturnErrorOnFailure(value.ComputeSize(&count));
+        DataModelLogger::LogString(label, indent, std::to_string(count) + " entries");
+
+        auto iter = value.begin();
+        size_t i  = 0;
+        while (iter.Next())
+        {
+            ++i;
+            std::string itemLabel = std::string("[") + std::to_string(i) + "]";
+            ReturnErrorOnFailure(DataModelLogger::LogValue(itemLabel.c_str(), indent + 1, iter.GetValue()));
+        }
+        if (iter.GetStatus() != CHIP_NO_ERROR)
+        {
+            DataModelLogger::LogString(indent + 1, "List truncated due to invalid value");
+        }
+        return iter.GetStatus();
+    }
+
+    template <typename T>
+    static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::DataModel::Nullable<T> & value)
+    {
+        if (value.IsNull())
+        {
+            DataModelLogger::LogString(label, indent, "null");
+            return CHIP_NO_ERROR;
+        }
+
+        return DataModelLogger::LogValue(label, indent, value.Value());
+    }
+
+    template <typename T>
+    static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::Optional<T> & value)
+    {
+        if (value.HasValue())
+        {
+            return DataModelLogger::LogValue(label, indent, value.Value());
+        }
+
+        return CHIP_NO_ERROR;
+    }
+
+#include <zap-generated/cluster/logging/DataModelLogger.h>
+
+    static void LogString(size_t indent, const std::string string) { LogString("", indent, string); }
+
+    static void LogString(const std::string label, size_t indent, const std::string string)
+    {
+        std::string prefix = ComputePrefix(label, indent);
+
+        ChipLogProgress(NotSpecified, "%s%s", prefix.c_str(), string.c_str());
+    }
+
+private:
+    static std::string ComputePrefix(const std::string label, size_t indent)
+    {
+        std::string prefix;
+        for (size_t i = 0; i < indent; ++i)
+        {
+            prefix.append("  ");
+        }
+        if (label.size() > 0)
+        {
+            prefix.append(label);
+            prefix.append(":");
+        }
+        prefix.append(" ");
+
+        return prefix;
+    }
+
+    static size_t ComputePrefixSize(const std::string label, size_t indent) { return ComputePrefix(label, indent).size(); }
+};
diff --git a/examples/fabric-admin/commands/clusters/JsonParser.h b/examples/fabric-admin/commands/clusters/JsonParser.h
new file mode 100644
index 0000000..0871e76
--- /dev/null
+++ b/examples/fabric-admin/commands/clusters/JsonParser.h
@@ -0,0 +1,166 @@
+/*
+ *   Copyright (c) 2024 Project CHIP Authors
+ *   All rights reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+#pragma once
+
+#include "../common/CustomStringPrefix.h"
+
+#include <json/json.h>
+#include <lib/core/Optional.h>
+
+#include <memory>
+#include <sstream>
+#include <string>
+#include <vector>
+
+class JsonParser
+{
+public:
+    // Returns whether the parse succeeded.
+    static bool ParseComplexArgument(const char * label, const char * json, Json::Value & value)
+    {
+        return Parse(label, json, /* strictRoot = */ true, value);
+    }
+
+    // Returns whether the parse succeeded.
+    static bool ParseCustomArgument(const char * label, const char * json, Json::Value & value)
+    {
+        return Parse(label, json, /* strictRoot = */ false, value);
+    }
+
+private:
+    static bool Parse(const char * label, const char * json, bool strictRoot, Json::Value & value)
+    {
+        Json::CharReaderBuilder readerBuilder;
+        readerBuilder.settings_["strictRoot"]        = strictRoot;
+        readerBuilder.settings_["allowSingleQuotes"] = true;
+        readerBuilder.settings_["failIfExtra"]       = true;
+        readerBuilder.settings_["rejectDupKeys"]     = true;
+
+        auto reader = std::unique_ptr<Json::CharReader>(readerBuilder.newCharReader());
+        std::string errors;
+        if (reader->parse(json, json + strlen(json), &value, &errors))
+        {
+            return true;
+        }
+
+        // The CharReader API allows us to set failIfExtra, unlike Reader, but does
+        // not allow us to get structured errors.  We get to try to manually undo
+        // the work it did to create a string from the structured errors it had.
+        ChipLogError(NotSpecified, "Error parsing JSON for %s:", label);
+
+        // For each error "errors" has the following:
+        //
+        // 1) A line starting with "* " that has line/column info
+        // 2) A line with the error message.
+        // 3) An optional line with some extra info.
+        //
+        // We keep track of the last error column, in case the error message
+        // reporting needs it.
+        std::istringstream stream(errors);
+        std::string error;
+        chip::Optional<unsigned> errorColumn;
+        while (getline(stream, error))
+        {
+            if (error.rfind("* ", 0) == 0)
+            {
+                // Flush out any pending error location.
+                LogErrorLocation(errorColumn, json);
+
+                // The format of this line is:
+                //
+                // * Line N, Column M
+                //
+                // Unfortunately it does not indicate end of error, so we can only
+                // show its start.
+                unsigned errorLine; // ignored in practice
+                if (sscanf(error.c_str(), "* Line %u, Column %u", &errorLine, &errorColumn.Emplace()) != 2)
+                {
+                    ChipLogError(NotSpecified, "Unexpected location string: %s\n", error.c_str());
+                    // We don't know how to make sense of this thing anymore.
+                    break;
+                }
+                if (errorColumn.Value() == 0)
+                {
+                    ChipLogError(NotSpecified, "Expected error column to be at least 1");
+                    // We don't know how to make sense of this thing anymore.
+                    break;
+                }
+                // We are using our column numbers as offsets, so want them to be
+                // 0-based.
+                --errorColumn.Value();
+            }
+            else
+            {
+                ChipLogError(NotSpecified, "  %s", error.c_str());
+                if (error == "  Missing ',' or '}' in object declaration" && errorColumn.HasValue() && errorColumn.Value() > 0 &&
+                    json[errorColumn.Value() - 1] == '0' && (json[errorColumn.Value()] == 'x' || json[errorColumn.Value()] == 'X'))
+                {
+                    // Log the error location marker before showing the NOTE
+                    // message.
+                    LogErrorLocation(errorColumn, json);
+                    ChipLogError(NotSpecified,
+                                 "NOTE: JSON does not allow hex syntax beginning with 0x for numbers.  Try putting the hex number "
+                                 "in quotes (like {\"name\": \"0x100\"}).");
+                }
+            }
+        }
+
+        // Write out the marker for our last error.
+        LogErrorLocation(errorColumn, json);
+
+        return false;
+    }
+
+private:
+    static void LogErrorLocation(chip::Optional<unsigned> & errorColumn, const char * json)
+    {
+#if CHIP_ERROR_LOGGING
+        if (!errorColumn.HasValue())
+        {
+            return;
+        }
+
+        const char * sourceText = json;
+        unsigned error_start    = errorColumn.Value();
+        // The whole JSON string might be too long to fit in our log
+        // messages.  Just include 30 chars before the error.
+        constexpr ptrdiff_t kMaxContext = 30;
+        std::string errorMarker;
+        if (error_start > kMaxContext)
+        {
+            sourceText += (error_start - kMaxContext);
+            error_start = kMaxContext;
+            ChipLogError(NotSpecified, "... %s", sourceText);
+            // Add markers corresponding to the "... " above.
+            errorMarker += "----";
+        }
+        else
+        {
+            ChipLogError(NotSpecified, "%s", sourceText);
+        }
+        for (unsigned i = 0; i < error_start; ++i)
+        {
+            errorMarker += "-";
+        }
+        errorMarker += "^";
+        ChipLogError(NotSpecified, "%s", errorMarker.c_str());
+        errorColumn.ClearValue();
+#endif // CHIP_ERROR_LOGGING
+    }
+};
diff --git a/examples/fabric-admin/commands/clusters/ModelCommand.cpp b/examples/fabric-admin/commands/clusters/ModelCommand.cpp
new file mode 100644
index 0000000..8f379db
--- /dev/null
+++ b/examples/fabric-admin/commands/clusters/ModelCommand.cpp
@@ -0,0 +1,105 @@
+/*
+ *   Copyright (c) 2024 Project CHIP Authors
+ *   All rights reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+#include "ModelCommand.h"
+
+#include <app/InteractionModelEngine.h>
+#include <app/icd/client/DefaultICDClientStorage.h>
+#include <inttypes.h>
+
+using namespace ::chip;
+
+CHIP_ERROR ModelCommand::RunCommand()
+{
+
+    if (IsGroupId(mDestinationId))
+    {
+        FabricIndex fabricIndex = CurrentCommissioner().GetFabricIndex();
+        ChipLogProgress(chipTool, "Sending command to group 0x%x", GroupIdFromNodeId(mDestinationId));
+
+        return SendGroupCommand(GroupIdFromNodeId(mDestinationId), fabricIndex);
+    }
+
+    ChipLogProgress(NotSpecified, "Sending command to node " ChipLogFormatX64, ChipLogValueX64(mDestinationId));
+    CheckPeerICDType();
+
+    CommissioneeDeviceProxy * commissioneeDeviceProxy = nullptr;
+    if (CHIP_NO_ERROR == CurrentCommissioner().GetDeviceBeingCommissioned(mDestinationId, &commissioneeDeviceProxy))
+    {
+        return SendCommand(commissioneeDeviceProxy, mEndPointId);
+    }
+
+    return CurrentCommissioner().GetConnectedDevice(mDestinationId, &mOnDeviceConnectedCallback,
+                                                    &mOnDeviceConnectionFailureCallback);
+}
+
+void ModelCommand::OnDeviceConnectedFn(void * context, chip::Messaging::ExchangeManager & exchangeMgr,
+                                       const chip::SessionHandle & sessionHandle)
+{
+    ModelCommand * command = reinterpret_cast<ModelCommand *>(context);
+    VerifyOrReturn(command != nullptr, ChipLogError(NotSpecified, "OnDeviceConnectedFn: context is null"));
+
+    chip::OperationalDeviceProxy device(&exchangeMgr, sessionHandle);
+    CHIP_ERROR err = command->SendCommand(&device, command->mEndPointId);
+    VerifyOrReturn(CHIP_NO_ERROR == err, command->SetCommandExitStatus(err));
+}
+
+void ModelCommand::OnDeviceConnectionFailureFn(void * context, const chip::ScopedNodeId & peerId, CHIP_ERROR err)
+{
+    LogErrorOnFailure(err);
+
+    ModelCommand * command = reinterpret_cast<ModelCommand *>(context);
+    VerifyOrReturn(command != nullptr, ChipLogError(NotSpecified, "OnDeviceConnectionFailureFn: context is null"));
+    command->SetCommandExitStatus(err);
+}
+
+void ModelCommand::Shutdown()
+{
+    mOnDeviceConnectedCallback.Cancel();
+    mOnDeviceConnectionFailureCallback.Cancel();
+
+    CHIPCommand::Shutdown();
+}
+
+void ModelCommand::CheckPeerICDType()
+{
+    if (mIsPeerLIT.HasValue())
+    {
+        ChipLogProgress(NotSpecified, "Peer ICD type is set to %s", mIsPeerLIT.Value() == 1 ? "LIT-ICD" : "non LIT-ICD");
+        return;
+    }
+
+    app::ICDClientInfo info;
+    auto destinationPeerId = chip::ScopedNodeId(mDestinationId, CurrentCommissioner().GetFabricIndex());
+    auto iter              = CHIPCommand::sICDClientStorage.IterateICDClientInfo();
+    if (iter == nullptr)
+    {
+        return;
+    }
+    app::DefaultICDClientStorage::ICDClientInfoIteratorWrapper clientInfoIteratorWrapper(iter);
+
+    while (iter->Next(info))
+    {
+        if (ScopedNodeId(info.peer_node.GetNodeId(), info.peer_node.GetFabricIndex()) == destinationPeerId)
+        {
+            ChipLogProgress(NotSpecified, "Peer is a registered LIT ICD.");
+            mIsPeerLIT.SetValue(true);
+            return;
+        }
+    }
+}
diff --git a/examples/fabric-admin/commands/clusters/ModelCommand.h b/examples/fabric-admin/commands/clusters/ModelCommand.h
new file mode 100644
index 0000000..c14d3c9
--- /dev/null
+++ b/examples/fabric-admin/commands/clusters/ModelCommand.h
@@ -0,0 +1,91 @@
+/*
+ *   Copyright (c) 2024 Project CHIP Authors
+ *   All rights reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+#pragma once
+
+#ifdef CONFIG_USE_LOCAL_STORAGE
+#include <controller/ExamplePersistentStorage.h>
+#endif // CONFIG_USE_LOCAL_STORAGE
+
+#include "../common/CHIPCommand.h"
+#include <lib/core/CHIPEncoding.h>
+
+class ModelCommand : public CHIPCommand
+{
+public:
+    ModelCommand(const char * commandName, CredentialIssuerCommands * credsIssuerConfig, bool supportsMultipleEndpoints = false) :
+        CHIPCommand(commandName, credsIssuerConfig), mOnDeviceConnectedCallback(OnDeviceConnectedFn, this),
+        mOnDeviceConnectionFailureCallback(OnDeviceConnectionFailureFn, this), mSupportsMultipleEndpoints(supportsMultipleEndpoints)
+    {}
+
+    void AddArguments(bool skipEndpoints = false)
+    {
+        AddArgument(
+            "destination-id", 0, UINT64_MAX, &mDestinationId,
+            "64-bit node or group identifier.\n  Group identifiers are detected by being in the 0xFFFF'FFFF'FFFF'xxxx range.");
+        if (skipEndpoints == false)
+        {
+            if (mSupportsMultipleEndpoints)
+            {
+                AddArgument("endpoint-ids", 0, UINT16_MAX, &mEndPointId,
+                            "Comma-separated list of endpoint ids (e.g. \"1\" or \"1,2,3\").\n  Allowed to be 0xFFFF to indicate a "
+                            "wildcard endpoint.");
+            }
+            else
+            {
+                AddArgument("endpoint-id-ignored-for-group-commands", 0, UINT16_MAX, &mEndPointId,
+                            "Endpoint the command is targeted at.");
+            }
+        }
+        AddArgument(
+            "lit-icd-peer", 0, 1, &mIsPeerLIT,
+            "Whether to treat the peer as a LIT ICD. false: Always no, true: Always yes, (not set): Yes if the peer is registered "
+            "to this controller.");
+        AddArgument("timeout", 0, UINT16_MAX, &mTimeout);
+    }
+
+    /////////// CHIPCommand Interface /////////
+    CHIP_ERROR RunCommand() override;
+    chip::System::Clock::Timeout GetWaitDuration() const override { return chip::System::Clock::Seconds16(mTimeout.ValueOr(20)); }
+
+    virtual CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector<chip::EndpointId> endPointIds) = 0;
+
+    virtual CHIP_ERROR SendGroupCommand(chip::GroupId groupId, chip::FabricIndex fabricIndex) { return CHIP_ERROR_BAD_REQUEST; };
+
+    void Shutdown() override;
+
+protected:
+    bool IsPeerLIT() { return mIsPeerLIT.ValueOr(false); }
+
+    chip::Optional<uint16_t> mTimeout;
+
+private:
+    chip::NodeId mDestinationId;
+    std::vector<chip::EndpointId> mEndPointId;
+    chip::Optional<bool> mIsPeerLIT;
+
+    void CheckPeerICDType();
+
+    static void OnDeviceConnectedFn(void * context, chip::Messaging::ExchangeManager & exchangeMgr,
+                                    const chip::SessionHandle & sessionHandle);
+    static void OnDeviceConnectionFailureFn(void * context, const chip::ScopedNodeId & peerId, CHIP_ERROR error);
+
+    chip::Callback::Callback<chip::OnDeviceConnected> mOnDeviceConnectedCallback;
+    chip::Callback::Callback<chip::OnDeviceConnectionFailure> mOnDeviceConnectionFailureCallback;
+    const bool mSupportsMultipleEndpoints;
+};
diff --git a/examples/fabric-admin/commands/clusters/ReportCommand.h b/examples/fabric-admin/commands/clusters/ReportCommand.h
new file mode 100644
index 0000000..4e9dbd0
--- /dev/null
+++ b/examples/fabric-admin/commands/clusters/ReportCommand.h
@@ -0,0 +1,551 @@
+/*
+ *   Copyright (c) 2024 Project CHIP Authors
+ *   All rights reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+#pragma once
+
+#include <app/tests/suites/commands/interaction_model/InteractionModel.h>
+
+#include "DataModelLogger.h"
+#include "ModelCommand.h"
+
+class ReportCommand : public InteractionModelReports, public ModelCommand, public chip::app::ReadClient::Callback
+{
+public:
+    ReportCommand(const char * commandName, CredentialIssuerCommands * credsIssuerConfig) :
+        InteractionModelReports(this), ModelCommand(commandName, credsIssuerConfig, /* supportsMultipleEndpoints = */ true)
+    {}
+
+    /////////// ReadClient Callback Interface /////////
+    void OnAttributeData(const chip::app::ConcreteDataAttributePath & path, chip::TLV::TLVReader * data,
+                         const chip::app::StatusIB & status) override
+    {
+        CHIP_ERROR error = status.ToChipError();
+        if (CHIP_NO_ERROR != error)
+        {
+            LogErrorOnFailure(RemoteDataModelLogger::LogErrorAsJSON(path, status));
+
+            ChipLogError(NotSpecified, "Response Failure: %s", chip::ErrorStr(error));
+            mError = error;
+            return;
+        }
+
+        if (data == nullptr)
+        {
+            ChipLogError(NotSpecified, "Response Failure: No Data");
+            mError = CHIP_ERROR_INTERNAL;
+            return;
+        }
+
+        LogErrorOnFailure(RemoteDataModelLogger::LogAttributeAsJSON(path, data));
+
+        error = DataModelLogger::LogAttribute(path, data);
+        if (CHIP_NO_ERROR != error)
+        {
+            ChipLogError(NotSpecified, "Response Failure: Can not decode Data");
+            mError = error;
+            return;
+        }
+    }
+
+    void OnEventData(const chip::app::EventHeader & eventHeader, chip::TLV::TLVReader * data,
+                     const chip::app::StatusIB * status) override
+    {
+        if (status != nullptr)
+        {
+            CHIP_ERROR error = status->ToChipError();
+            if (CHIP_NO_ERROR != error)
+            {
+                LogErrorOnFailure(RemoteDataModelLogger::LogErrorAsJSON(eventHeader, *status));
+
+                ChipLogError(NotSpecified, "Response Failure: %s", chip::ErrorStr(error));
+                mError = error;
+                return;
+            }
+        }
+
+        if (data == nullptr)
+        {
+            ChipLogError(NotSpecified, "Response Failure: No Data");
+            mError = CHIP_ERROR_INTERNAL;
+            return;
+        }
+
+        LogErrorOnFailure(RemoteDataModelLogger::LogEventAsJSON(eventHeader, data));
+
+        CHIP_ERROR error = DataModelLogger::LogEvent(eventHeader, data);
+        if (CHIP_NO_ERROR != error)
+        {
+            ChipLogError(NotSpecified, "Response Failure: Can not decode Data");
+            mError = error;
+            return;
+        }
+    }
+
+    void OnError(CHIP_ERROR error) override
+    {
+        LogErrorOnFailure(RemoteDataModelLogger::LogErrorAsJSON(error));
+
+        ChipLogProgress(NotSpecified, "Error: %s", chip::ErrorStr(error));
+        mError = error;
+    }
+
+    void OnDeallocatePaths(chip::app::ReadPrepareParams && aReadPrepareParams) override
+    {
+        InteractionModelReports::OnDeallocatePaths(std::move(aReadPrepareParams));
+    }
+
+    void Shutdown() override
+    {
+        // We don't shut down InteractionModelReports here; we leave it for
+        // Cleanup to handle.
+        mError = CHIP_NO_ERROR;
+        ModelCommand::Shutdown();
+    }
+
+    void Cleanup() override { InteractionModelReports::Shutdown(); }
+
+protected:
+    // Use a 3x-longer-than-default timeout because wildcard reads can take a
+    // while.
+    chip::System::Clock::Timeout GetWaitDuration() const override
+    {
+        return mTimeout.HasValue() ? chip::System::Clock::Seconds16(mTimeout.Value()) : (ModelCommand::GetWaitDuration() * 3);
+    }
+
+    CHIP_ERROR mError = CHIP_NO_ERROR;
+};
+
+class ReadCommand : public ReportCommand
+{
+protected:
+    ReadCommand(const char * commandName, CredentialIssuerCommands * credsIssuerConfig) :
+        ReportCommand(commandName, credsIssuerConfig)
+    {}
+
+    void OnDone(chip::app::ReadClient * aReadClient) override
+    {
+        InteractionModelReports::CleanupReadClient(aReadClient);
+        SetCommandExitStatus(mError);
+    }
+};
+
+class SubscribeCommand : public ReportCommand
+{
+protected:
+    SubscribeCommand(const char * commandName, CredentialIssuerCommands * credsIssuerConfig) :
+        ReportCommand(commandName, credsIssuerConfig)
+    {}
+
+    void OnSubscriptionEstablished(chip::SubscriptionId subscriptionId) override
+    {
+        mSubscriptionEstablished = true;
+        SetCommandExitStatus(CHIP_NO_ERROR);
+    }
+
+    void OnDone(chip::app::ReadClient * aReadClient) override
+    {
+        InteractionModelReports::CleanupReadClient(aReadClient);
+
+        if (!mSubscriptionEstablished)
+        {
+            SetCommandExitStatus(mError);
+        }
+        // else we must be getting here from Cleanup(), which means we have
+        // already done our exit status thing.
+    }
+
+    void Shutdown() override
+    {
+        mSubscriptionEstablished = false;
+        ReportCommand::Shutdown();
+    }
+
+    // For subscriptions we always defer interactive cleanup.  Either our
+    // ReadClients will terminate themselves (in which case they will be removed
+    // from our list anyway), or they should hang around until shutdown.
+    bool DeferInteractiveCleanup() override { return true; }
+
+private:
+    bool mSubscriptionEstablished = false;
+};
+
+class ReadAttribute : public ReadCommand
+{
+public:
+    ReadAttribute(CredentialIssuerCommands * credsIssuerConfig) : ReadCommand("read-by-id", credsIssuerConfig)
+    {
+        AddArgument("cluster-ids", 0, UINT32_MAX, &mClusterIds,
+                    "Comma-separated list of cluster ids to read from (e.g. \"6\" or \"8,0x201\").\n  Allowed to be 0xFFFFFFFF to "
+                    "indicate a wildcard cluster.");
+        AddAttributeIdArgument();
+        AddCommonArguments();
+        ReadCommand::AddArguments();
+    }
+
+    ReadAttribute(chip::ClusterId clusterId, CredentialIssuerCommands * credsIssuerConfig) :
+        ReadCommand("read-by-id", credsIssuerConfig), mClusterIds(1, clusterId)
+    {
+        AddAttributeIdArgument();
+        AddCommonArguments();
+        ReadCommand::AddArguments();
+    }
+
+    ReadAttribute(chip::ClusterId clusterId, const char * attributeName, chip::AttributeId attributeId,
+                  CredentialIssuerCommands * credsIssuerConfig) :
+        ReadCommand("read", credsIssuerConfig),
+        mClusterIds(1, clusterId), mAttributeIds(1, attributeId)
+    {
+        AddArgument("attr-name", attributeName);
+        AddCommonArguments();
+        ReadCommand::AddArguments();
+    }
+
+    ~ReadAttribute() {}
+
+    CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector<chip::EndpointId> endpointIds) override
+    {
+        return ReadCommand::ReadAttribute(device, endpointIds, mClusterIds, mAttributeIds);
+    }
+
+private:
+    void AddAttributeIdArgument()
+    {
+        AddArgument("attribute-ids", 0, UINT32_MAX, &mAttributeIds,
+                    "Comma-separated list of attribute ids to read (e.g. \"0\" or \"1,0xFFFC,0xFFFD\").\n  Allowed to be "
+                    "0xFFFFFFFF to indicate a wildcard attribute.");
+    }
+
+    void AddCommonArguments()
+    {
+        AddArgument("fabric-filtered", 0, 1, &mFabricFiltered,
+                    "Boolean indicating whether to do a fabric-filtered read. Defaults to true.");
+        AddArgument("data-version", 0, UINT32_MAX, &mDataVersions,
+                    "Comma-separated list of data versions for the clusters being read.");
+    }
+
+    std::vector<chip::ClusterId> mClusterIds;
+    std::vector<chip::AttributeId> mAttributeIds;
+};
+
+class SubscribeAttribute : public SubscribeCommand
+{
+public:
+    SubscribeAttribute(CredentialIssuerCommands * credsIssuerConfig) : SubscribeCommand("subscribe-by-id", credsIssuerConfig)
+    {
+        AddArgument("cluster-ids", 0, UINT32_MAX, &mClusterIds,
+                    "Comma-separated list of cluster ids to subscribe to (e.g. \"6\" or \"8,0x201\").\n  Allowed to be 0xFFFFFFFF "
+                    "to indicate a wildcard cluster.");
+        AddAttributeIdArgument();
+        AddCommonArguments();
+        SubscribeCommand::AddArguments();
+    }
+
+    SubscribeAttribute(chip::ClusterId clusterId, CredentialIssuerCommands * credsIssuerConfig) :
+        SubscribeCommand("subscribe-by-id", credsIssuerConfig), mClusterIds(1, clusterId)
+    {
+        AddAttributeIdArgument();
+        AddCommonArguments();
+        SubscribeCommand::AddArguments();
+    }
+
+    SubscribeAttribute(chip::ClusterId clusterId, const char * attributeName, chip::AttributeId attributeId,
+                       CredentialIssuerCommands * credsIssuerConfig) :
+        SubscribeCommand("subscribe", credsIssuerConfig),
+        mClusterIds(1, clusterId), mAttributeIds(1, attributeId)
+    {
+        AddArgument("attr-name", attributeName);
+        AddCommonArguments();
+        SubscribeCommand::AddArguments();
+    }
+
+    ~SubscribeAttribute() {}
+
+    CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector<chip::EndpointId> endpointIds) override
+    {
+        SubscribeCommand::SetPeerLIT(IsPeerLIT());
+        return SubscribeCommand::SubscribeAttribute(device, endpointIds, mClusterIds, mAttributeIds);
+    }
+
+private:
+    void AddAttributeIdArgument()
+    {
+        AddArgument("attribute-ids", 0, UINT32_MAX, &mAttributeIds,
+                    "Comma-separated list of attribute ids to subscribe to (e.g. \"0\" or \"1,0xFFFC,0xFFFD\").\n  Allowed to be "
+                    "0xFFFFFFFF to indicate a wildcard attribute.");
+    }
+
+    void AddCommonArguments()
+    {
+        AddArgument("min-interval", 0, UINT16_MAX, &mMinInterval,
+                    "Server should not send a new report if less than this number of seconds has elapsed since the last report.");
+        AddArgument("max-interval", 0, UINT16_MAX, &mMaxInterval,
+                    "Server must send a report if this number of seconds has elapsed since the last report.");
+        AddArgument("fabric-filtered", 0, 1, &mFabricFiltered,
+                    "Boolean indicating whether to do a fabric-filtered subscription. Defaults to true.");
+        AddArgument("data-version", 0, UINT32_MAX, &mDataVersions,
+                    "Comma-separated list of data versions for the clusters being subscribed to.");
+        AddArgument("keepSubscriptions", 0, 1, &mKeepSubscriptions,
+                    "Boolean indicating whether to keep existing subscriptions when creating the new one. Defaults to false.");
+        AddArgument("auto-resubscribe", 0, 1, &mAutoResubscribe,
+                    "Boolean indicating whether the subscription should auto-resubscribe.  Defaults to false.");
+    }
+
+    std::vector<chip::ClusterId> mClusterIds;
+    std::vector<chip::AttributeId> mAttributeIds;
+};
+
+class ReadEvent : public ReadCommand
+{
+public:
+    ReadEvent(CredentialIssuerCommands * credsIssuerConfig) : ReadCommand("read-event-by-id", credsIssuerConfig)
+    {
+        AddArgument("cluster-id", 0, UINT32_MAX, &mClusterIds);
+        AddArgument("event-id", 0, UINT32_MAX, &mEventIds);
+        AddArgument("fabric-filtered", 0, 1, &mFabricFiltered);
+        AddArgument("event-min", 0, UINT64_MAX, &mEventNumber);
+        ReadCommand::AddArguments();
+    }
+
+    ReadEvent(chip::ClusterId clusterId, CredentialIssuerCommands * credsIssuerConfig) :
+        ReadCommand("read-event-by-id", credsIssuerConfig), mClusterIds(1, clusterId)
+    {
+        AddArgument("event-id", 0, UINT32_MAX, &mEventIds);
+        AddArgument("fabric-filtered", 0, 1, &mFabricFiltered);
+        AddArgument("event-min", 0, UINT64_MAX, &mEventNumber);
+        ReadCommand::AddArguments();
+    }
+
+    ReadEvent(chip::ClusterId clusterId, const char * eventName, chip::EventId eventId,
+              CredentialIssuerCommands * credsIssuerConfig) :
+        ReadCommand("read-event", credsIssuerConfig),
+        mClusterIds(1, clusterId), mEventIds(1, eventId)
+    {
+        AddArgument("event-name", eventName);
+        AddArgument("fabric-filtered", 0, 1, &mFabricFiltered);
+        AddArgument("event-min", 0, UINT64_MAX, &mEventNumber);
+        ReadCommand::AddArguments();
+    }
+
+    ~ReadEvent() {}
+
+    CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector<chip::EndpointId> endpointIds) override
+    {
+        return ReadCommand::ReadEvent(device, endpointIds, mClusterIds, mEventIds);
+    }
+
+private:
+    std::vector<chip::ClusterId> mClusterIds;
+    std::vector<chip::EventId> mEventIds;
+};
+
+class SubscribeEvent : public SubscribeCommand
+{
+public:
+    SubscribeEvent(CredentialIssuerCommands * credsIssuerConfig) : SubscribeCommand("subscribe-event-by-id", credsIssuerConfig)
+    {
+        AddArgument("cluster-id", 0, UINT32_MAX, &mClusterIds);
+        AddArgument("event-id", 0, UINT32_MAX, &mEventIds);
+        AddCommonArguments();
+        SubscribeCommand::AddArguments();
+    }
+
+    SubscribeEvent(chip::ClusterId clusterId, CredentialIssuerCommands * credsIssuerConfig) :
+        SubscribeCommand("subscribe-event-by-id", credsIssuerConfig), mClusterIds(1, clusterId)
+    {
+        AddArgument("event-id", 0, UINT32_MAX, &mEventIds);
+        AddCommonArguments();
+        SubscribeCommand::AddArguments();
+    }
+
+    SubscribeEvent(chip::ClusterId clusterId, const char * eventName, chip::EventId eventId,
+                   CredentialIssuerCommands * credsIssuerConfig) :
+        SubscribeCommand("subscribe-event", credsIssuerConfig),
+        mClusterIds(1, clusterId), mEventIds(1, eventId)
+    {
+        AddArgument("event-name", eventName, "Event name.");
+        AddCommonArguments();
+        SubscribeCommand::AddArguments();
+    }
+
+    void AddCommonArguments()
+    {
+        AddArgument("min-interval", 0, UINT16_MAX, &mMinInterval,
+                    "The requested minimum interval between reports. Sets MinIntervalFloor in the Subscribe Request.");
+        AddArgument("max-interval", 0, UINT16_MAX, &mMaxInterval,
+                    "The requested maximum interval between reports. Sets MaxIntervalCeiling in the Subscribe Request.");
+        AddArgument("fabric-filtered", 0, 1, &mFabricFiltered);
+        AddArgument("event-min", 0, UINT64_MAX, &mEventNumber);
+        AddArgument("keepSubscriptions", 0, 1, &mKeepSubscriptions,
+                    "false - Terminate existing subscriptions from initiator.\n  true - Leave existing subscriptions in place.");
+        AddArgument(
+            "is-urgent", 0, 1, &mIsUrgents,
+            "Sets isUrgent in the Subscribe Request.\n"
+            "  The queueing of any urgent event SHALL force an immediate generation of reports containing all events queued "
+            "leading up to (and including) the urgent event in question.\n"
+            "  This argument takes a comma separated list of true/false values.\n"
+            "  If the number of paths exceeds the number of entries provided to is-urgent, then isUrgent will be false for the "
+            "extra paths.");
+        AddArgument("auto-resubscribe", 0, 1, &mAutoResubscribe,
+                    "Boolean indicating whether the subscription should auto-resubscribe.  Defaults to false.");
+    }
+
+    ~SubscribeEvent() {}
+
+    CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector<chip::EndpointId> endpointIds) override
+    {
+        SubscribeCommand::SetPeerLIT(IsPeerLIT());
+        return SubscribeCommand::SubscribeEvent(device, endpointIds, mClusterIds, mEventIds);
+    }
+
+private:
+    std::vector<chip::ClusterId> mClusterIds;
+    std::vector<chip::EventId> mEventIds;
+};
+
+class ReadNone : public ReadCommand
+{
+public:
+    ReadNone(CredentialIssuerCommands * credsIssuerConfig) : ReadCommand("read-none", credsIssuerConfig)
+    {
+        AddArgument("fabric-filtered", 0, 1, &mFabricFiltered,
+                    "Boolean indicating whether to do a fabric-filtered read. Defaults to true.");
+        AddArgument("data-versions", 0, UINT32_MAX, &mDataVersions,
+                    "Comma-separated list of data versions for the clusters being read.");
+        AddArgument("event-min", 0, UINT64_MAX, &mEventNumber);
+        ReadCommand::AddArguments(true /* skipEndpoints */);
+    }
+
+    ~ReadNone() {}
+
+    void OnDone(chip::app::ReadClient * aReadClient) override
+    {
+        InteractionModelReports::CleanupReadClient(aReadClient);
+        SetCommandExitStatus(mError);
+    }
+
+    CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector<chip::EndpointId> endpointIds) override
+    {
+        return ReadCommand::ReadNone(device);
+    }
+};
+
+class ReadAll : public ReadCommand
+{
+public:
+    ReadAll(CredentialIssuerCommands * credsIssuerConfig) : ReadCommand("read-all", credsIssuerConfig)
+    {
+        AddArgument("cluster-ids", 0, UINT32_MAX, &mClusterIds,
+                    "Comma-separated list of cluster ids to read from (e.g. \"6\" or \"8,0x201\").\n  Allowed to be 0xFFFFFFFF to "
+                    "indicate a wildcard cluster.");
+        AddArgument("attribute-ids", 0, UINT32_MAX, &mAttributeIds,
+                    "Comma-separated list of attribute ids to read (e.g. \"0\" or \"1,0xFFFC,0xFFFD\").\n  Allowed to be "
+                    "0xFFFFFFFF to indicate a wildcard attribute.");
+        AddArgument("event-ids", 0, UINT32_MAX, &mEventIds,
+                    "Comma-separated list of event ids to read (e.g. \"0\" or \"1,2,3\").\n  Allowed to be "
+                    "0xFFFFFFFF to indicate a wildcard event.");
+        AddArgument("fabric-filtered", 0, 1, &mFabricFiltered,
+                    "Boolean indicating whether to do a fabric-filtered read. Defaults to true.");
+        AddArgument("data-versions", 0, UINT32_MAX, &mDataVersions,
+                    "Comma-separated list of data versions for the clusters being read.");
+        AddArgument("event-min", 0, UINT64_MAX, &mEventNumber);
+        ReadCommand::AddArguments();
+    }
+
+    ~ReadAll() {}
+
+    void OnDone(chip::app::ReadClient * aReadClient) override
+    {
+        InteractionModelReports::CleanupReadClient(aReadClient);
+        SetCommandExitStatus(mError);
+    }
+
+    CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector<chip::EndpointId> endpointIds) override
+    {
+        return ReadCommand::ReadAll(device, endpointIds, mClusterIds, mAttributeIds, mEventIds);
+    }
+
+private:
+    std::vector<chip::ClusterId> mClusterIds;
+    std::vector<chip::AttributeId> mAttributeIds;
+    std::vector<chip::EventId> mEventIds;
+};
+
+class SubscribeNone : public SubscribeCommand
+{
+public:
+    SubscribeNone(CredentialIssuerCommands * credsIssuerConfig) : SubscribeCommand("subscribe-none", credsIssuerConfig)
+    {
+        AddArgument("min-interval", 0, UINT16_MAX, &mMinInterval,
+                    "The requested minimum interval between reports. Sets MinIntervalFloor in the Subscribe Request.");
+        AddArgument("max-interval", 0, UINT16_MAX, &mMaxInterval,
+                    "The requested maximum interval between reports. Sets MaxIntervalCeiling in the Subscribe Request.");
+        AddArgument("fabric-filtered", 0, 1, &mFabricFiltered,
+                    "Boolean indicating whether to do a fabric-filtered read. Defaults to true.");
+        AddArgument("event-min", 0, UINT64_MAX, &mEventNumber);
+        AddArgument("keepSubscriptions", 0, 1, &mKeepSubscriptions,
+                    "false - Terminate existing subscriptions from initiator.\n  true - Leave existing subscriptions in place.");
+        SubscribeCommand::AddArguments(true /* skipEndpoints */);
+    }
+
+    ~SubscribeNone() {}
+
+    CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector<chip::EndpointId> endpointIds) override
+    {
+        return SubscribeCommand::SubscribeNone(device);
+    }
+};
+
+class SubscribeAll : public SubscribeCommand
+{
+public:
+    SubscribeAll(CredentialIssuerCommands * credsIssuerConfig) : SubscribeCommand("subscribe-all", credsIssuerConfig)
+    {
+        AddArgument("cluster-ids", 0, UINT32_MAX, &mClusterIds,
+                    "Comma-separated list of cluster ids to read from (e.g. \"6\" or \"8,0x201\").\n  Allowed to be 0xFFFFFFFF to "
+                    "indicate a wildcard cluster.");
+        AddArgument("attribute-ids", 0, UINT32_MAX, &mAttributeIds,
+                    "Comma-separated list of attribute ids to read (e.g. \"0\" or \"1,0xFFFC,0xFFFD\").\n  Allowed to be "
+                    "0xFFFFFFFF to indicate a wildcard attribute.");
+        AddArgument("event-ids", 0, UINT32_MAX, &mEventIds,
+                    "Comma-separated list of event ids to read (e.g. \"0\" or \"1,2,3\").\n  Allowed to be "
+                    "0xFFFFFFFF to indicate a wildcard event.");
+        AddArgument("min-interval", 0, UINT16_MAX, &mMinInterval,
+                    "The requested minimum interval between reports. Sets MinIntervalFloor in the Subscribe Request.");
+        AddArgument("max-interval", 0, UINT16_MAX, &mMaxInterval,
+                    "The requested maximum interval between reports. Sets MaxIntervalCeiling in the Subscribe Request.");
+        AddArgument("fabric-filtered", 0, 1, &mFabricFiltered,
+                    "Boolean indicating whether to do a fabric-filtered read. Defaults to true.");
+        AddArgument("event-min", 0, UINT64_MAX, &mEventNumber);
+        AddArgument("keepSubscriptions", 0, 1, &mKeepSubscriptions,
+                    "false - Terminate existing subscriptions from initiator.\n  true - Leave existing subscriptions in place.");
+        SubscribeCommand::AddArguments();
+    }
+
+    ~SubscribeAll() {}
+
+    CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector<chip::EndpointId> endpointIds) override
+    {
+        SubscribeCommand::SetPeerLIT(IsPeerLIT());
+        return SubscribeCommand::SubscribeAll(device, endpointIds, mClusterIds, mAttributeIds, mEventIds);
+    }
+
+private:
+    std::vector<chip::ClusterId> mClusterIds;
+    std::vector<chip::AttributeId> mAttributeIds;
+    std::vector<chip::EventId> mEventIds;
+};
diff --git a/examples/fabric-admin/commands/clusters/SubscriptionsCommands.h b/examples/fabric-admin/commands/clusters/SubscriptionsCommands.h
new file mode 100644
index 0000000..625e5a7
--- /dev/null
+++ b/examples/fabric-admin/commands/clusters/SubscriptionsCommands.h
@@ -0,0 +1,108 @@
+/*
+ *   Copyright (c) 2024 Project CHIP Authors
+ *   All rights reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+#pragma once
+
+#include <lib/core/CHIPError.h>
+
+#include <commands/common/CHIPCommand.h>
+#include <commands/common/Commands.h>
+
+class ShutdownSubscription : public CHIPCommand
+{
+public:
+    ShutdownSubscription(CredentialIssuerCommands * credsIssuerConfig) :
+        CHIPCommand("shutdown-one", credsIssuerConfig,
+                    "Shut down a single subscription, identified by its subscription id and target node id.")
+    {
+        AddArgument("subscription-id", 0, UINT32_MAX, &mSubscriptionId);
+        AddArgument("node-id", 0, UINT64_MAX, &mNodeId,
+                    "The node id, scoped to the commissioner name the command is running under.");
+    }
+
+    /////////// CHIPCommand Interface /////////
+    CHIP_ERROR RunCommand() override
+    {
+        CHIP_ERROR err = chip::app::InteractionModelEngine::GetInstance()->ShutdownSubscription(
+            chip::ScopedNodeId(mNodeId, CurrentCommissioner().GetFabricIndex()), mSubscriptionId);
+        SetCommandExitStatus(err);
+        return CHIP_NO_ERROR;
+    }
+    chip::System::Clock::Timeout GetWaitDuration() const override { return chip::System::Clock::Seconds16(10); }
+
+private:
+    chip::SubscriptionId mSubscriptionId;
+    chip::NodeId mNodeId;
+};
+
+class ShutdownSubscriptionsForNode : public CHIPCommand
+{
+public:
+    ShutdownSubscriptionsForNode(CredentialIssuerCommands * credsIssuerConfig) :
+        CHIPCommand("shutdown-all-for-node", credsIssuerConfig, "Shut down all subscriptions targeting a given node.")
+    {
+        AddArgument("node-id", 0, UINT64_MAX, &mNodeId,
+                    "The node id, scoped to the commissioner name the command is running under.");
+    }
+
+    /////////// CHIPCommand Interface /////////
+    CHIP_ERROR RunCommand() override
+    {
+        chip::app::InteractionModelEngine::GetInstance()->ShutdownSubscriptions(CurrentCommissioner().GetFabricIndex(), mNodeId);
+
+        SetCommandExitStatus(CHIP_NO_ERROR);
+        return CHIP_NO_ERROR;
+    }
+    chip::System::Clock::Timeout GetWaitDuration() const override { return chip::System::Clock::Seconds16(10); }
+
+private:
+    chip::NodeId mNodeId;
+};
+
+class ShutdownAllSubscriptions : public CHIPCommand
+{
+public:
+    ShutdownAllSubscriptions(CredentialIssuerCommands * credsIssuerConfig) :
+        CHIPCommand("shutdown-all", credsIssuerConfig, "Shut down all subscriptions to all nodes.")
+    {}
+
+    /////////// CHIPCommand Interface /////////
+    CHIP_ERROR RunCommand() override
+    {
+        chip::app::InteractionModelEngine::GetInstance()->ShutdownAllSubscriptions();
+
+        SetCommandExitStatus(CHIP_NO_ERROR);
+        return CHIP_NO_ERROR;
+    }
+    chip::System::Clock::Timeout GetWaitDuration() const override { return chip::System::Clock::Seconds16(10); }
+
+private:
+};
+
+void registerCommandsSubscriptions(Commands & commands, CredentialIssuerCommands * credsIssuerConfig)
+{
+    const char * clusterName = "Subscriptions";
+
+    commands_list clusterCommands = {
+        make_unique<ShutdownSubscription>(credsIssuerConfig),         //
+        make_unique<ShutdownSubscriptionsForNode>(credsIssuerConfig), //
+        make_unique<ShutdownAllSubscriptions>(credsIssuerConfig),     //
+    };
+
+    commands.RegisterCommandSet(clusterName, clusterCommands, "Commands for shutting down subscriptions.");
+}
diff --git a/examples/fabric-admin/commands/clusters/WriteAttributeCommand.h b/examples/fabric-admin/commands/clusters/WriteAttributeCommand.h
new file mode 100644
index 0000000..8424e95
--- /dev/null
+++ b/examples/fabric-admin/commands/clusters/WriteAttributeCommand.h
@@ -0,0 +1,286 @@
+/*
+ *   Copyright (c) 2024 Project CHIP Authors
+ *   All rights reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+#pragma once
+
+#include <app/tests/suites/commands/interaction_model/InteractionModel.h>
+
+#include "DataModelLogger.h"
+#include "ModelCommand.h"
+
+inline constexpr char kWriteCommandKey[]      = "write";
+inline constexpr char kWriteByIdCommandKey[]  = "write-by-id";
+inline constexpr char kForceWriteCommandKey[] = "force-write";
+
+enum class WriteCommandType
+{
+    kWrite,      // regular, writable attributes
+    kForceWrite, // forced writes, send a write command on something expected to fail
+};
+
+template <class T = std::vector<CustomArgument *>>
+class WriteAttribute : public InteractionModelWriter, public ModelCommand, public chip::app::WriteClient::Callback
+{
+public:
+    WriteAttribute(CredentialIssuerCommands * credsIssuerConfig) :
+        InteractionModelWriter(this), ModelCommand(kWriteByIdCommandKey, credsIssuerConfig)
+    {
+        AddArgumentClusterIds();
+        AddArgumentAttributeIds();
+        AddArgumentAttributeValues();
+        AddArguments();
+    }
+
+    WriteAttribute(chip::ClusterId clusterId, CredentialIssuerCommands * credsIssuerConfig) :
+        InteractionModelWriter(this), ModelCommand(kWriteByIdCommandKey, credsIssuerConfig), mClusterIds(1, clusterId)
+    {
+        AddArgumentAttributeIds();
+        AddArgumentAttributeValues();
+        AddArguments();
+    }
+
+    template <typename minType, typename maxType>
+    WriteAttribute(chip::ClusterId clusterId, const char * attributeName, minType minValue, maxType maxValue,
+                   chip::AttributeId attributeId, WriteCommandType commandType, CredentialIssuerCommands * credsIssuerConfig) :
+        WriteAttribute(clusterId, attributeId, commandType, credsIssuerConfig)
+    {
+        AddArgumentAttributeName(attributeName);
+        AddArgumentAttributeValues(static_cast<int64_t>(minValue), static_cast<uint64_t>(maxValue));
+        AddArguments();
+    }
+
+    WriteAttribute(chip::ClusterId clusterId, const char * attributeName, float minValue, float maxValue,
+                   chip::AttributeId attributeId, WriteCommandType commandType, CredentialIssuerCommands * credsIssuerConfig) :
+        WriteAttribute(clusterId, attributeId, commandType, credsIssuerConfig)
+    {
+        AddArgumentAttributeName(attributeName);
+        AddArgumentAttributeValues(minValue, maxValue);
+        AddArguments();
+    }
+
+    WriteAttribute(chip::ClusterId clusterId, const char * attributeName, double minValue, double maxValue,
+                   chip::AttributeId attributeId, WriteCommandType commandType, CredentialIssuerCommands * credsIssuerConfig) :
+        WriteAttribute(clusterId, attributeId, commandType, credsIssuerConfig)
+    {
+        AddArgumentAttributeName(attributeName);
+        AddArgumentAttributeValues(minValue, maxValue);
+        AddArguments();
+    }
+
+    WriteAttribute(chip::ClusterId clusterId, const char * attributeName, chip::AttributeId attributeId,
+                   WriteCommandType commandType, CredentialIssuerCommands * credsIssuerConfig) :
+        WriteAttribute(clusterId, attributeId, commandType, credsIssuerConfig)
+    {
+        AddArgumentAttributeName(attributeName);
+        AddArgumentAttributeValues();
+        AddArguments();
+    }
+
+    WriteAttribute(chip::ClusterId clusterId, const char * attributeName, chip::AttributeId attributeId,
+                   TypedComplexArgument<T> & attributeParser, WriteCommandType commandType,
+                   CredentialIssuerCommands * credsIssuerConfig) :
+        WriteAttribute(clusterId, attributeId, commandType, credsIssuerConfig)
+    {
+        AddArgumentAttributeName(attributeName);
+        AddArgumentAttributeValues(attributeParser);
+        AddArguments();
+    }
+
+    ~WriteAttribute() {}
+
+    CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector<chip::EndpointId> endpointIds) override
+    {
+        return WriteAttribute::SendCommand(device, endpointIds, mClusterIds, mAttributeIds, mAttributeValues);
+    }
+
+    CHIP_ERROR SendGroupCommand(chip::GroupId groupId, chip::FabricIndex fabricIndex) override
+    {
+        return WriteAttribute::SendGroupCommand(groupId, fabricIndex, mClusterIds, mAttributeIds, mAttributeValues);
+    }
+
+    /////////// WriteClient Callback Interface /////////
+    void OnResponse(const chip::app::WriteClient * client, const chip::app::ConcreteDataAttributePath & path,
+                    chip::app::StatusIB status) override
+    {
+        CHIP_ERROR error = status.ToChipError();
+        if (CHIP_NO_ERROR != error)
+        {
+            LogErrorOnFailure(RemoteDataModelLogger::LogErrorAsJSON(path, status));
+
+            ChipLogError(NotSpecified, "Response Failure: %s", chip::ErrorStr(error));
+            mError = error;
+        }
+    }
+
+    void OnError(const chip::app::WriteClient * client, CHIP_ERROR error) override
+    {
+        LogErrorOnFailure(RemoteDataModelLogger::LogErrorAsJSON(error));
+
+        ChipLogProgress(NotSpecified, "Error: %s", chip::ErrorStr(error));
+        mError = error;
+    }
+
+    void OnDone(chip::app::WriteClient * client) override
+    {
+        InteractionModelWriter::Shutdown();
+        SetCommandExitStatus(mError);
+    }
+
+    CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector<chip::EndpointId> endpointIds,
+                           std::vector<chip::ClusterId> clusterIds, std::vector<chip::AttributeId> attributeIds, const T & values)
+    {
+        return InteractionModelWriter::WriteAttribute(device, endpointIds, clusterIds, attributeIds, values);
+    }
+
+    CHIP_ERROR SendGroupCommand(chip::GroupId groupId, chip::FabricIndex fabricIndex, std::vector<chip::ClusterId> clusterIds,
+                                std::vector<chip::AttributeId> attributeIds, const T & value)
+    {
+        ChipLogDetail(NotSpecified, "Sending Write Attribute to Group %u, on Fabric %x, for cluster %u with attributeId %u",
+                      groupId, fabricIndex, clusterIds.at(0), attributeIds.at(0));
+        chip::Optional<chip::DataVersion> dataVersion = chip::NullOptional;
+        if (mDataVersions.HasValue())
+        {
+            dataVersion.SetValue(mDataVersions.Value().at(0));
+        }
+
+        return InteractionModelWriter::WriteGroupAttribute(groupId, fabricIndex, clusterIds.at(0), attributeIds.at(0), value,
+                                                           dataVersion);
+    }
+
+    void Shutdown() override
+    {
+        mError = CHIP_NO_ERROR;
+        ModelCommand::Shutdown();
+    }
+
+protected:
+    WriteAttribute(const char * attributeName, CredentialIssuerCommands * credsIssuerConfig) :
+        InteractionModelWriter(this), ModelCommand(kWriteCommandKey, credsIssuerConfig)
+    {
+        // Subclasses are responsible for calling AddArguments.
+    }
+
+    void AddArgumentClusterIds()
+    {
+        AddArgument("cluster-ids", 0, UINT32_MAX, &mClusterIds,
+                    "Comma-separated list of cluster ids to write to (e.g. \"6\" or \"6,0x201\").");
+    }
+
+    void AddArgumentAttributeIds()
+    {
+        AddArgument("attribute-ids", 0, UINT32_MAX, &mAttributeIds,
+                    "Comma-separated list of attribute ids to write (e.g. \"16385\" or \"16385,0x4002\").");
+    }
+
+    void AddArgumentAttributeName(const char * attributeName)
+    {
+        AddArgument("attribute-name", attributeName, "The attribute name to write.");
+    }
+
+    template <typename U = T, std::enable_if_t<std::is_same<U, std::vector<CustomArgument *>>::value, int> = 0>
+    static const char * GetAttributeValuesDescription()
+    {
+        return "Semicolon-separated list of attribute values to write. Each value is represented as follows, depending on the "
+               "type:\n"
+               "  * struct: a JSON-encoded object, with field ids as keys.\n"
+               "  * list: a JSON-encoded array of values.\n"
+               "  * null: A literal null.\n"
+               "  * boolean: A literal true or false.\n"
+               "  * unsigned integer: One of:\n"
+               "      a) The number directly, as decimal.\n"
+               "      b) The number directly, as 0x followed by hex digits. (Only for the toplevel value, not inside structs or "
+               "lists.)\n"
+               "      c) A string starting with \"u:\" followed by decimal digits\n"
+               "  * signed integer: One of:\n"
+               "      a) The number directly, if it's negative.\n"
+               "      c) A string starting with \"s:\" followed by decimal digits\n"
+               "  * single-precision float: A string starting with \"f:\" followed by the number.\n"
+               "  * double-precision float: One of:\n"
+               "      a) The number directly, if it's not an integer.\n"
+               "      b) A string starting with \"d:\" followed by the number.\n"
+               "  * octet string: A string starting with \"hex:\" followed by the hex encoding of the bytes.\n"
+               "  * string: A string with the characters.\n"
+               "\n"
+               "  Example values: '10;20', '10;\"u:20\"', '\"hex:aabbcc\";\"hello\"'.";
+    }
+
+    static const char * GetTypedAttributeValuesDescription() { return "Comma-separated list of attribute values to write."; }
+
+    template <typename U = T, std::enable_if_t<!std::is_same<U, std::vector<CustomArgument *>>::value, int> = 0>
+    static const char * GetAttributeValuesDescription()
+    {
+        return GetTypedAttributeValuesDescription();
+    }
+
+    template <typename minType, typename maxType>
+    void AddArgumentAttributeValues(minType minValue, maxType maxValue)
+    {
+        AddArgument("attribute-values", minValue, maxValue, &mAttributeValues, GetTypedAttributeValuesDescription());
+    }
+
+    void AddArgumentAttributeValues() { AddArgument("attribute-values", &mAttributeValues, GetAttributeValuesDescription()); }
+
+    void AddArgumentAttributeValues(TypedComplexArgument<T> & attributeParser)
+    {
+        attributeParser.SetArgument(&mAttributeValues);
+        AddArgument("attribute-values", &attributeParser, GetTypedAttributeValuesDescription());
+    }
+
+    void AddArguments()
+    {
+        AddArgument("timedInteractionTimeoutMs", 0, UINT16_MAX, &mTimedInteractionTimeoutMs,
+                    "If provided, do a timed write with the given timed interaction timeout. See \"7.6.10. Timed Interaction\" in "
+                    "the Matter specification.");
+        AddArgument("busyWaitForMs", 0, UINT16_MAX, &mBusyWaitForMs,
+                    "If provided, block the main thread processing for the given time right after sending a command.");
+        AddArgument("data-version", 0, UINT32_MAX, &mDataVersions,
+                    "Comma-separated list of data versions for the clusters being written.");
+        AddArgument("suppressResponse", 0, 1, &mSuppressResponse);
+        AddArgument("repeat-count", 1, UINT16_MAX, &mRepeatCount);
+        AddArgument("repeat-delay-ms", 0, UINT16_MAX, &mRepeatDelayInMs);
+        ModelCommand::AddArguments();
+    }
+
+private:
+    // This constructor is private as it is not intended to be used from outside the class.
+    WriteAttribute(chip::ClusterId clusterId, chip::AttributeId attributeId, WriteCommandType commandType,
+                   CredentialIssuerCommands * credsIssuerConfig) :
+        InteractionModelWriter(this),
+        ModelCommand(commandType == WriteCommandType::kWrite ? kWriteCommandKey : kForceWriteCommandKey, credsIssuerConfig),
+        mClusterIds(1, clusterId), mAttributeIds(1, attributeId)
+    {}
+
+    std::vector<chip::ClusterId> mClusterIds;
+    std::vector<chip::AttributeId> mAttributeIds;
+
+    CHIP_ERROR mError = CHIP_NO_ERROR;
+    T mAttributeValues;
+};
+
+template <class T>
+class WriteAttributeAsComplex : public WriteAttribute<T>
+{
+public:
+    WriteAttributeAsComplex(chip::ClusterId clusterId, const char * attributeName, chip::AttributeId attributeId,
+                            WriteCommandType commandType, CredentialIssuerCommands * credsIssuerConfig) :
+        WriteAttribute<T>(clusterId, attributeName, attributeId, mAttributeParser, commandType, credsIssuerConfig)
+    {}
+
+private:
+    TypedComplexArgument<T> mAttributeParser;
+};
diff --git a/examples/fabric-admin/commands/common/CHIPCommand.cpp b/examples/fabric-admin/commands/common/CHIPCommand.cpp
new file mode 100644
index 0000000..982c857
--- /dev/null
+++ b/examples/fabric-admin/commands/common/CHIPCommand.cpp
@@ -0,0 +1,651 @@
+/*
+ *   Copyright (c) 2024 Project CHIP Authors
+ *   All rights reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+#include "CHIPCommand.h"
+
+#include <controller/CHIPDeviceControllerFactory.h>
+#include <credentials/attestation_verifier/FileAttestationTrustStore.h>
+#include <lib/core/CHIPConfig.h>
+#include <lib/core/CHIPVendorIdentifiers.hpp>
+#include <lib/support/CodeUtils.h>
+#include <lib/support/ScopedBuffer.h>
+#include <lib/support/TestGroupData.h>
+#include <platform/LockTracker.h>
+
+#include <string>
+
+#if CHIP_CONFIG_TRANSPORT_TRACE_ENABLED
+#include "TraceDecoder.h"
+#include "TraceHandlers.h"
+#endif // CHIP_CONFIG_TRANSPORT_TRACE_ENABLED
+
+std::map<CHIPCommand::CommissionerIdentity, std::unique_ptr<chip::Controller::DeviceCommissioner>> CHIPCommand::mCommissioners;
+std::set<CHIPCommand *> CHIPCommand::sDeferredCleanups;
+
+using DeviceControllerFactory = chip::Controller::DeviceControllerFactory;
+
+constexpr chip::FabricId kIdentityNullFabricId  = chip::kUndefinedFabricId;
+constexpr chip::FabricId kIdentityAlphaFabricId = 1;
+constexpr chip::FabricId kIdentityBetaFabricId  = 2;
+constexpr chip::FabricId kIdentityGammaFabricId = 3;
+constexpr chip::FabricId kIdentityOtherFabricId = 4;
+constexpr char kPAATrustStorePathVariable[]     = "FABRICSYNC_PAA_TRUST_STORE_PATH";
+constexpr char kCDTrustStorePathVariable[]      = "FABRICSYNC_CD_TRUST_STORE_PATH";
+
+const chip::Credentials::AttestationTrustStore * CHIPCommand::sTrustStore = nullptr;
+chip::Credentials::GroupDataProviderImpl CHIPCommand::sGroupDataProvider{ kMaxGroupsPerFabric, kMaxGroupKeysPerFabric };
+// All fabrics share the same ICD client storage.
+chip::app::DefaultICDClientStorage CHIPCommand::sICDClientStorage;
+chip::Crypto::RawKeySessionKeystore CHIPCommand::sSessionKeystore;
+chip::app::DefaultCheckInDelegate CHIPCommand::sCheckInDelegate;
+chip::app::CheckInHandler CHIPCommand::sCheckInHandler;
+
+namespace {
+
+CHIP_ERROR GetAttestationTrustStore(const char * paaTrustStorePath, const chip::Credentials::AttestationTrustStore ** trustStore)
+{
+    if (paaTrustStorePath == nullptr)
+    {
+        paaTrustStorePath = getenv(kPAATrustStorePathVariable);
+    }
+
+    if (paaTrustStorePath == nullptr)
+    {
+        *trustStore = chip::Credentials::GetTestAttestationTrustStore();
+        return CHIP_NO_ERROR;
+    }
+
+    static chip::Credentials::FileAttestationTrustStore attestationTrustStore{ paaTrustStorePath };
+
+    if (paaTrustStorePath != nullptr && attestationTrustStore.paaCount() == 0)
+    {
+        ChipLogError(NotSpecified, "No PAAs found in path: %s", paaTrustStorePath);
+        ChipLogError(NotSpecified,
+                     "Please specify a valid path containing trusted PAA certificates using "
+                     "the argument [--paa-trust-store-path paa/file/path] "
+                     "or environment variable [%s=paa/file/path]",
+                     kPAATrustStorePathVariable);
+        return CHIP_ERROR_INVALID_ARGUMENT;
+    }
+
+    *trustStore = &attestationTrustStore;
+    return CHIP_NO_ERROR;
+}
+
+} // namespace
+
+CHIP_ERROR CHIPCommand::MaybeSetUpStack()
+{
+    if (IsInteractive())
+    {
+        return CHIP_NO_ERROR;
+    }
+
+    StartTracing();
+
+#if (CHIP_DEVICE_LAYER_TARGET_LINUX || CHIP_DEVICE_LAYER_TARGET_TIZEN) && CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE
+    // By default, Linux device is configured as a BLE peripheral while the controller needs a BLE central.
+    ReturnLogErrorOnFailure(chip::DeviceLayer::Internal::BLEMgrImpl().ConfigureBle(mBleAdapterId.ValueOr(0), true));
+#endif
+
+    ReturnLogErrorOnFailure(mDefaultStorage.Init(nullptr, GetStorageDirectory().ValueOr(nullptr)));
+    ReturnLogErrorOnFailure(mOperationalKeystore.Init(&mDefaultStorage));
+    ReturnLogErrorOnFailure(mOpCertStore.Init(&mDefaultStorage));
+
+    // fabric-admin uses a non-persistent keystore.
+    // ICD storage lifetime is currently tied to the fabric-admin's lifetime. Since fabric-admin interactive mode is currently used
+    // for ICD commissioning and check-in validation, this temporary storage meets the test requirements.
+    // TODO: Implement persistent ICD storage for the fabric-admin.
+    ReturnLogErrorOnFailure(sICDClientStorage.Init(&mDefaultStorage, &sSessionKeystore));
+
+    chip::Controller::FactoryInitParams factoryInitParams;
+
+    factoryInitParams.fabricIndependentStorage = &mDefaultStorage;
+    factoryInitParams.operationalKeystore      = &mOperationalKeystore;
+    factoryInitParams.opCertStore              = &mOpCertStore;
+    factoryInitParams.enableServerInteractions = NeedsOperationalAdvertising();
+    factoryInitParams.sessionKeystore          = &sSessionKeystore;
+
+    // Init group data provider that will be used for all group keys and IPKs for the
+    // fabric-admin-configured fabrics. This is OK to do once since the fabric tables
+    // and the DeviceControllerFactory all "share" in the same underlying data.
+    // Different commissioner implementations may want to use alternate implementations
+    // of GroupDataProvider for injection through factoryInitParams.
+    sGroupDataProvider.SetStorageDelegate(&mDefaultStorage);
+    sGroupDataProvider.SetSessionKeystore(factoryInitParams.sessionKeystore);
+    ReturnLogErrorOnFailure(sGroupDataProvider.Init());
+    chip::Credentials::SetGroupDataProvider(&sGroupDataProvider);
+    factoryInitParams.groupDataProvider = &sGroupDataProvider;
+
+    uint16_t port = mDefaultStorage.GetListenPort();
+    if (port != 0)
+    {
+        // Make sure different commissioners run on different ports.
+        port = static_cast<uint16_t>(port + CurrentCommissionerId());
+    }
+    factoryInitParams.listenPort = port;
+    ReturnLogErrorOnFailure(DeviceControllerFactory::GetInstance().Init(factoryInitParams));
+
+    auto systemState = chip::Controller::DeviceControllerFactory::GetInstance().GetSystemState();
+    VerifyOrReturnError(nullptr != systemState, CHIP_ERROR_INCORRECT_STATE);
+
+    ReturnErrorOnFailure(GetAttestationTrustStore(mPaaTrustStorePath.ValueOr(nullptr), &sTrustStore));
+
+    auto engine = chip::app::InteractionModelEngine::GetInstance();
+    VerifyOrReturnError(engine != nullptr, CHIP_ERROR_INCORRECT_STATE);
+    ReturnLogErrorOnFailure(sCheckInDelegate.Init(&sICDClientStorage, engine));
+    ReturnLogErrorOnFailure(sCheckInHandler.Init(DeviceControllerFactory::GetInstance().GetSystemState()->ExchangeMgr(),
+                                                 &sICDClientStorage, &sCheckInDelegate, engine));
+
+    CommissionerIdentity nullIdentity{ kIdentityNull, chip::kUndefinedNodeId };
+    ReturnLogErrorOnFailure(InitializeCommissioner(nullIdentity, kIdentityNullFabricId));
+
+    // After initializing first commissioner, add the additional CD certs once
+    {
+        const char * cdTrustStorePath = mCDTrustStorePath.ValueOr(nullptr);
+        if (cdTrustStorePath == nullptr)
+        {
+            cdTrustStorePath = getenv(kCDTrustStorePathVariable);
+        }
+
+        auto additionalCdCerts =
+            chip::Credentials::LoadAllX509DerCerts(cdTrustStorePath, chip::Credentials::CertificateValidationMode::kPublicKeyOnly);
+        if (cdTrustStorePath != nullptr && additionalCdCerts.size() == 0)
+        {
+            ChipLogError(NotSpecified, "Warning: no CD signing certs found in path: %s, only defaults will be used",
+                         cdTrustStorePath);
+            ChipLogError(NotSpecified,
+                         "Please specify a path containing trusted CD verifying key certificates using "
+                         "the argument [--cd-trust-store-path cd/file/path] "
+                         "or environment variable [%s=cd/file/path]",
+                         kCDTrustStorePathVariable);
+        }
+        ReturnErrorOnFailure(mCredIssuerCmds->AddAdditionalCDVerifyingCerts(additionalCdCerts));
+    }
+    bool allowTestCdSigningKey = !mOnlyAllowTrustedCdKeys.ValueOr(false);
+    mCredIssuerCmds->SetCredentialIssuerOption(CredentialIssuerCommands::CredentialIssuerOptions::kAllowTestCdSigningKey,
+                                               allowTestCdSigningKey);
+
+    return CHIP_NO_ERROR;
+}
+
+void CHIPCommand::MaybeTearDownStack()
+{
+    if (IsInteractive())
+    {
+        return;
+    }
+
+    //
+    // We can call DeviceController::Shutdown() safely without grabbing the stack lock
+    // since the CHIP thread and event queue have been stopped, preventing any thread
+    // races.
+    //
+    for (auto & commissioner : mCommissioners)
+    {
+        ShutdownCommissioner(commissioner.first);
+    }
+
+    StopTracing();
+}
+
+CHIP_ERROR CHIPCommand::EnsureCommissionerForIdentity(std::string identity)
+{
+    chip::NodeId nodeId;
+    ReturnErrorOnFailure(GetIdentityNodeId(identity, &nodeId));
+    CommissionerIdentity lookupKey{ identity, nodeId };
+    if (mCommissioners.find(lookupKey) != mCommissioners.end())
+    {
+        return CHIP_NO_ERROR;
+    }
+
+    // Need to initialize the commissioner.
+    chip::FabricId fabricId;
+    if (identity == kIdentityAlpha)
+    {
+        fabricId = kIdentityAlphaFabricId;
+    }
+    else if (identity == kIdentityBeta)
+    {
+        fabricId = kIdentityBetaFabricId;
+    }
+    else if (identity == kIdentityGamma)
+    {
+        fabricId = kIdentityGammaFabricId;
+    }
+    else
+    {
+        fabricId = strtoull(identity.c_str(), nullptr, 0);
+        if (fabricId < kIdentityOtherFabricId)
+        {
+            ChipLogError(NotSpecified, "Invalid identity: %s", identity.c_str());
+            return CHIP_ERROR_INVALID_ARGUMENT;
+        }
+    }
+
+    return InitializeCommissioner(lookupKey, fabricId);
+}
+
+CHIP_ERROR CHIPCommand::Run()
+{
+    ReturnErrorOnFailure(MaybeSetUpStack());
+
+    CHIP_ERROR err = StartWaiting(GetWaitDuration());
+
+    if (IsInteractive())
+    {
+        bool timedOut;
+        // Give it 2 hours to run our cleanup; that should never get hit in practice.
+        CHIP_ERROR cleanupErr = RunOnMatterQueue(RunCommandCleanup, chip::System::Clock::Seconds16(7200), &timedOut);
+        VerifyOrDie(cleanupErr == CHIP_NO_ERROR);
+        VerifyOrDie(!timedOut);
+    }
+    else
+    {
+        CleanupAfterRun();
+    }
+
+    MaybeTearDownStack();
+
+    return err;
+}
+
+void CHIPCommand::StartTracing()
+{
+    if (mTraceTo.HasValue())
+    {
+        for (const auto & destination : mTraceTo.Value())
+        {
+            mTracingSetup.EnableTracingFor(destination.c_str());
+        }
+    }
+
+#if CHIP_CONFIG_TRANSPORT_TRACE_ENABLED
+    chip::trace::InitTrace();
+
+    if (mTraceFile.HasValue())
+    {
+        chip::trace::AddTraceStream(new chip::trace::TraceStreamFile(mTraceFile.Value()));
+    }
+    else if (mTraceLog.HasValue() && mTraceLog.Value())
+    {
+        chip::trace::AddTraceStream(new chip::trace::TraceStreamLog());
+    }
+
+    if (mTraceDecode.HasValue() && mTraceDecode.Value())
+    {
+        chip::trace::TraceDecoderOptions options;
+        // The interaction model protocol is already logged, so just disable logging those.
+        options.mEnableProtocolInteractionModelResponse = false;
+        chip::trace::TraceDecoder * decoder             = new chip::trace::TraceDecoder();
+        decoder->SetOptions(options);
+        chip::trace::AddTraceStream(decoder);
+    }
+#endif // CHIP_CONFIG_TRANSPORT_TRACE_ENABLED
+}
+
+void CHIPCommand::StopTracing()
+{
+    mTracingSetup.StopTracing();
+
+#if CHIP_CONFIG_TRANSPORT_TRACE_ENABLED
+    chip::trace::DeInitTrace();
+#endif // CHIP_CONFIG_TRANSPORT_TRACE_ENABLED
+}
+
+void CHIPCommand::SetIdentity(const char * identity)
+{
+    std::string name = std::string(identity);
+    if (name.compare(kIdentityAlpha) != 0 && name.compare(kIdentityBeta) != 0 && name.compare(kIdentityGamma) != 0 &&
+        name.compare(kIdentityNull) != 0 && strtoull(name.c_str(), nullptr, 0) < kIdentityOtherFabricId)
+    {
+        ChipLogError(NotSpecified, "Unknown commissioner name: %s. Supported names are [%s, %s, %s, 4, 5...]", name.c_str(),
+                     kIdentityAlpha, kIdentityBeta, kIdentityGamma);
+        chipDie();
+    }
+
+    mCommissionerName.SetValue(const_cast<char *>(identity));
+}
+
+std::string CHIPCommand::GetIdentity()
+{
+    std::string name = mCommissionerName.HasValue() ? mCommissionerName.Value() : kIdentityAlpha;
+    if (name.compare(kIdentityAlpha) != 0 && name.compare(kIdentityBeta) != 0 && name.compare(kIdentityGamma) != 0 &&
+        name.compare(kIdentityNull) != 0)
+    {
+        chip::FabricId fabricId = strtoull(name.c_str(), nullptr, 0);
+        if (fabricId >= kIdentityOtherFabricId)
+        {
+            // normalize name since it is used in persistent storage
+
+            char s[24];
+            sprintf(s, "%lx", fabricId);
+
+            name = s;
+        }
+        else
+        {
+            ChipLogError(NotSpecified, "Unknown commissioner name: %s. Supported names are [%s, %s, %s, 4, 5...]", name.c_str(),
+                         kIdentityAlpha, kIdentityBeta, kIdentityGamma);
+            chipDie();
+        }
+    }
+
+    return name;
+}
+
+CHIP_ERROR CHIPCommand::GetIdentityNodeId(std::string identity, chip::NodeId * nodeId)
+{
+    if (mCommissionerNodeId.HasValue())
+    {
+        *nodeId = mCommissionerNodeId.Value();
+        return CHIP_NO_ERROR;
+    }
+
+    if (identity == kIdentityNull)
+    {
+        *nodeId = chip::kUndefinedNodeId;
+        return CHIP_NO_ERROR;
+    }
+
+    ReturnLogErrorOnFailure(mCommissionerStorage.Init(identity.c_str(), GetStorageDirectory().ValueOr(nullptr)));
+
+    *nodeId = mCommissionerStorage.GetLocalNodeId();
+
+    return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR CHIPCommand::GetIdentityRootCertificate(std::string identity, chip::ByteSpan & span)
+{
+    if (identity == kIdentityNull)
+    {
+        return CHIP_ERROR_NOT_FOUND;
+    }
+
+    chip::NodeId nodeId;
+    VerifyOrDie(GetIdentityNodeId(identity, &nodeId) == CHIP_NO_ERROR);
+    CommissionerIdentity lookupKey{ identity, nodeId };
+    auto item = mCommissioners.find(lookupKey);
+
+    span = chip::ByteSpan(item->first.mRCAC, item->first.mRCACLen);
+    return CHIP_NO_ERROR;
+}
+
+chip::FabricId CHIPCommand::CurrentCommissionerId()
+{
+    chip::FabricId id;
+
+    std::string name = GetIdentity();
+    if (name.compare(kIdentityAlpha) == 0)
+    {
+        id = kIdentityAlphaFabricId;
+    }
+    else if (name.compare(kIdentityBeta) == 0)
+    {
+        id = kIdentityBetaFabricId;
+    }
+    else if (name.compare(kIdentityGamma) == 0)
+    {
+        id = kIdentityGammaFabricId;
+    }
+    else if (name.compare(kIdentityNull) == 0)
+    {
+        id = kIdentityNullFabricId;
+    }
+    else if ((id = strtoull(name.c_str(), nullptr, 0)) < kIdentityOtherFabricId)
+    {
+        VerifyOrDieWithMsg(false, NotSpecified, "Unknown commissioner name: %s. Supported names are [%s, %s, %s, 4, 5...]",
+                           name.c_str(), kIdentityAlpha, kIdentityBeta, kIdentityGamma);
+    }
+
+    return id;
+}
+
+chip::Controller::DeviceCommissioner & CHIPCommand::CurrentCommissioner()
+{
+    return GetCommissioner(GetIdentity());
+}
+
+chip::Controller::DeviceCommissioner & CHIPCommand::GetCommissioner(std::string identity)
+{
+    // We don't have a great way to handle commissioner setup failures here.
+    // This only matters for commands (like TestCommand) that involve multiple
+    // identities.
+    VerifyOrDie(EnsureCommissionerForIdentity(identity) == CHIP_NO_ERROR);
+
+    chip::NodeId nodeId;
+    VerifyOrDie(GetIdentityNodeId(identity, &nodeId) == CHIP_NO_ERROR);
+    CommissionerIdentity lookupKey{ identity, nodeId };
+    auto item = mCommissioners.find(lookupKey);
+    VerifyOrDie(item != mCommissioners.end());
+    return *item->second;
+}
+
+void CHIPCommand::ShutdownCommissioner(const CommissionerIdentity & key)
+{
+    mCommissioners[key].get()->Shutdown();
+}
+
+CHIP_ERROR CHIPCommand::InitializeCommissioner(CommissionerIdentity & identity, chip::FabricId fabricId)
+{
+    std::unique_ptr<ChipDeviceCommissioner> commissioner = std::make_unique<ChipDeviceCommissioner>();
+    chip::Controller::SetupParams commissionerParams;
+
+    ReturnLogErrorOnFailure(mCredIssuerCmds->SetupDeviceAttestation(commissionerParams, sTrustStore));
+
+    chip::Crypto::P256Keypair ephemeralKey;
+
+    if (fabricId != chip::kUndefinedFabricId)
+    {
+
+        // TODO - OpCreds should only be generated for pairing command
+        //        store the credentials in persistent storage, and
+        //        generate when not available in the storage.
+        ReturnLogErrorOnFailure(mCommissionerStorage.Init(identity.mName.c_str(), GetStorageDirectory().ValueOr(nullptr)));
+        if (mUseMaxSizedCerts.HasValue())
+        {
+            auto option = CredentialIssuerCommands::CredentialIssuerOptions::kMaximizeCertificateSizes;
+            mCredIssuerCmds->SetCredentialIssuerOption(option, mUseMaxSizedCerts.Value());
+        }
+
+        ReturnLogErrorOnFailure(mCredIssuerCmds->InitializeCredentialsIssuer(mCommissionerStorage));
+
+        chip::MutableByteSpan nocSpan(identity.mNOC);
+        chip::MutableByteSpan icacSpan(identity.mICAC);
+        chip::MutableByteSpan rcacSpan(identity.mRCAC);
+
+        ReturnLogErrorOnFailure(ephemeralKey.Initialize(chip::Crypto::ECPKeyTarget::ECDSA));
+
+        ReturnLogErrorOnFailure(mCredIssuerCmds->GenerateControllerNOCChain(identity.mLocalNodeId, fabricId,
+                                                                            mCommissionerStorage.GetCommissionerCATs(),
+                                                                            ephemeralKey, rcacSpan, icacSpan, nocSpan));
+
+        identity.mRCACLen = rcacSpan.size();
+        identity.mICACLen = icacSpan.size();
+        identity.mNOCLen  = nocSpan.size();
+
+        commissionerParams.operationalKeypair           = &ephemeralKey;
+        commissionerParams.controllerRCAC               = rcacSpan;
+        commissionerParams.controllerICAC               = icacSpan;
+        commissionerParams.controllerNOC                = nocSpan;
+        commissionerParams.permitMultiControllerFabrics = true;
+        commissionerParams.enableServerInteractions     = NeedsOperationalAdvertising();
+    }
+
+    // TODO: Initialize IPK epoch key in ExampleOperationalCredentials issuer rather than relying on DefaultIpkValue
+    commissionerParams.operationalCredentialsDelegate = mCredIssuerCmds->GetCredentialIssuer();
+    commissionerParams.controllerVendorId             = mCommissionerVendorId.ValueOr(chip::VendorId::TestVendor1);
+
+    ReturnLogErrorOnFailure(DeviceControllerFactory::GetInstance().SetupCommissioner(commissionerParams, *(commissioner.get())));
+
+    if (identity.mName != kIdentityNull)
+    {
+        // Initialize Group Data, including IPK
+        chip::FabricIndex fabricIndex = commissioner->GetFabricIndex();
+        uint8_t compressed_fabric_id[sizeof(uint64_t)];
+        chip::MutableByteSpan compressed_fabric_id_span(compressed_fabric_id);
+        ReturnLogErrorOnFailure(commissioner->GetCompressedFabricIdBytes(compressed_fabric_id_span));
+
+        ReturnLogErrorOnFailure(chip::GroupTesting::InitData(&sGroupDataProvider, fabricIndex, compressed_fabric_id_span));
+
+        // Configure the default IPK for all fabrics used by CHIP-tool. The epoch
+        // key is the same, but the derived keys will be different for each fabric.
+        chip::ByteSpan defaultIpk = chip::GroupTesting::DefaultIpkValue::GetDefaultIpk();
+        ReturnLogErrorOnFailure(
+            chip::Credentials::SetSingleIpkEpochKey(&sGroupDataProvider, fabricIndex, defaultIpk, compressed_fabric_id_span));
+    }
+
+    CHIPCommand::sICDClientStorage.UpdateFabricList(commissioner->GetFabricIndex());
+
+    mCommissioners[identity] = std::move(commissioner);
+
+    return CHIP_NO_ERROR;
+}
+
+void CHIPCommand::RunQueuedCommand(intptr_t commandArg)
+{
+    auto * command = reinterpret_cast<CHIPCommand *>(commandArg);
+    CHIP_ERROR err = command->EnsureCommissionerForIdentity(command->GetIdentity());
+    if (err == CHIP_NO_ERROR)
+    {
+        err = command->RunCommand();
+    }
+
+    if (err != CHIP_NO_ERROR)
+    {
+        command->SetCommandExitStatus(err);
+    }
+}
+
+void CHIPCommand::RunCommandCleanup(intptr_t commandArg)
+{
+    auto * command = reinterpret_cast<CHIPCommand *>(commandArg);
+    command->CleanupAfterRun();
+    command->StopWaiting();
+}
+
+void CHIPCommand::CleanupAfterRun()
+{
+    assertChipStackLockedByCurrentThread();
+    bool deferCleanup = (IsInteractive() && DeferInteractiveCleanup());
+
+    Shutdown();
+
+    if (deferCleanup)
+    {
+        sDeferredCleanups.insert(this);
+    }
+    else
+    {
+        Cleanup();
+    }
+}
+
+CHIP_ERROR CHIPCommand::RunOnMatterQueue(MatterWorkCallback callback, chip::System::Clock::Timeout timeout, bool * timedOut)
+{
+    {
+        std::lock_guard<std::mutex> lk(cvWaitingForResponseMutex);
+        mWaitingForResponse = true;
+    }
+
+    auto err = chip::DeviceLayer::PlatformMgr().ScheduleWork(callback, reinterpret_cast<intptr_t>(this));
+    if (CHIP_NO_ERROR != err)
+    {
+        {
+            std::lock_guard<std::mutex> lk(cvWaitingForResponseMutex);
+            mWaitingForResponse = false;
+        }
+        return err;
+    }
+
+    auto waitingUntil = std::chrono::system_clock::now() + std::chrono::duration_cast<std::chrono::seconds>(timeout);
+    {
+        std::unique_lock<std::mutex> lk(cvWaitingForResponseMutex);
+        *timedOut = !cvWaitingForResponse.wait_until(lk, waitingUntil, [this]() { return !this->mWaitingForResponse; });
+    }
+
+    return CHIP_NO_ERROR;
+}
+
+#if !CONFIG_USE_SEPARATE_EVENTLOOP
+static void OnResponseTimeout(chip::System::Layer *, void * appState)
+{
+    (reinterpret_cast<CHIPCommand *>(appState))->SetCommandExitStatus(CHIP_ERROR_TIMEOUT);
+}
+#endif // !CONFIG_USE_SEPARATE_EVENTLOOP
+
+CHIP_ERROR CHIPCommand::StartWaiting(chip::System::Clock::Timeout duration)
+{
+#if CONFIG_USE_SEPARATE_EVENTLOOP
+    // ServiceEvents() calls StartEventLoopTask(), which is paired with the StopEventLoopTask() below.
+    if (!IsInteractive())
+    {
+        ReturnLogErrorOnFailure(DeviceControllerFactory::GetInstance().ServiceEvents());
+    }
+
+    if (duration.count() == 0)
+    {
+        mCommandExitStatus = RunCommand();
+    }
+    else
+    {
+        bool timedOut;
+        CHIP_ERROR err = RunOnMatterQueue(RunQueuedCommand, duration, &timedOut);
+        if (CHIP_NO_ERROR != err)
+        {
+            return err;
+        }
+        if (timedOut)
+        {
+            mCommandExitStatus = CHIP_ERROR_TIMEOUT;
+        }
+    }
+    if (!IsInteractive())
+    {
+        LogErrorOnFailure(chip::DeviceLayer::PlatformMgr().StopEventLoopTask());
+    }
+#else
+    chip::DeviceLayer::PlatformMgr().ScheduleWork(RunQueuedCommand, reinterpret_cast<intptr_t>(this));
+    ReturnLogErrorOnFailure(chip::DeviceLayer::SystemLayer().StartTimer(duration, OnResponseTimeout, this));
+    chip::DeviceLayer::PlatformMgr().RunEventLoop();
+#endif // CONFIG_USE_SEPARATE_EVENTLOOP
+
+    return mCommandExitStatus;
+}
+
+void CHIPCommand::StopWaiting()
+{
+#if CONFIG_USE_SEPARATE_EVENTLOOP
+    {
+        std::lock_guard<std::mutex> lk(cvWaitingForResponseMutex);
+        mWaitingForResponse = false;
+    }
+    cvWaitingForResponse.notify_all();
+#else  // CONFIG_USE_SEPARATE_EVENTLOOP
+    LogErrorOnFailure(chip::DeviceLayer::PlatformMgr().StopEventLoopTask());
+#endif // CONFIG_USE_SEPARATE_EVENTLOOP
+}
+
+void CHIPCommand::ExecuteDeferredCleanups(intptr_t ignored)
+{
+    for (auto * cmd : sDeferredCleanups)
+    {
+        cmd->Cleanup();
+    }
+    sDeferredCleanups.clear();
+}
diff --git a/examples/fabric-admin/commands/common/CHIPCommand.h b/examples/fabric-admin/commands/common/CHIPCommand.h
new file mode 100644
index 0000000..856a4da
--- /dev/null
+++ b/examples/fabric-admin/commands/common/CHIPCommand.h
@@ -0,0 +1,264 @@
+/*
+ *   Copyright (c) 2024 Project CHIP Authors
+ *   All rights reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+#pragma once
+
+#ifdef CONFIG_USE_LOCAL_STORAGE
+#include <controller/ExamplePersistentStorage.h>
+#endif // CONFIG_USE_LOCAL_STORAGE
+
+#include "Command.h"
+
+#include <TracingCommandLineArgument.h>
+#include <app/icd/client/CheckInHandler.h>
+#include <app/icd/client/DefaultCheckInDelegate.h>
+#include <app/icd/client/DefaultICDClientStorage.h>
+#include <commands/common/CredentialIssuerCommands.h>
+#include <commands/example/ExampleCredentialIssuerCommands.h>
+#include <credentials/GroupDataProviderImpl.h>
+#include <credentials/PersistentStorageOpCertStore.h>
+#include <crypto/PersistentStorageOperationalKeystore.h>
+#include <crypto/RawKeySessionKeystore.h>
+
+#include <string>
+
+inline constexpr char kIdentityAlpha[] = "alpha";
+inline constexpr char kIdentityBeta[]  = "beta";
+inline constexpr char kIdentityGamma[] = "gamma";
+// The null fabric commissioner is a commissioner that isn't on a fabric.
+// This is a legal configuration in which the commissioner delegates
+// operational communication and invocation of the commssioning complete
+// command to a separate on-fabric administrator node.
+//
+// The null-fabric-commissioner identity is provided here to demonstrate the
+// commissioner portion of such an architecture.  The null-fabric-commissioner
+// can carry a commissioning flow up until the point of operational channel
+// (CASE) communcation.
+inline constexpr char kIdentityNull[] = "null-fabric-commissioner";
+
+class CHIPCommand : public Command
+{
+public:
+    using ChipDeviceCommissioner = ::chip::Controller::DeviceCommissioner;
+    using ChipDeviceController   = ::chip::Controller::DeviceController;
+    using IPAddress              = ::chip::Inet::IPAddress;
+    using NodeId                 = ::chip::NodeId;
+    using PeerId                 = ::chip::PeerId;
+    using PeerAddress            = ::chip::Transport::PeerAddress;
+
+    static constexpr uint16_t kMaxGroupsPerFabric    = 50;
+    static constexpr uint16_t kMaxGroupKeysPerFabric = 25;
+
+    CHIPCommand(const char * commandName, CredentialIssuerCommands * credIssuerCmds, const char * helpText = nullptr) :
+        Command(commandName, helpText), mCredIssuerCmds(credIssuerCmds)
+    {
+        AddArgument("paa-trust-store-path", &mPaaTrustStorePath,
+                    "Path to directory holding PAA certificate information.  Can be absolute or relative to the current working "
+                    "directory.");
+        AddArgument("cd-trust-store-path", &mCDTrustStorePath,
+                    "Path to directory holding CD certificate information.  Can be absolute or relative to the current working "
+                    "directory.");
+        AddArgument("commissioner-name", &mCommissionerName,
+                    "Name of fabric to use. Valid values are \"alpha\", \"beta\", \"gamma\", and integers greater than or equal to "
+                    "4.  The default if not specified is \"alpha\".");
+        AddArgument("commissioner-nodeid", 0, UINT64_MAX, &mCommissionerNodeId,
+                    "The node id to use for fabric-admin.  If not provided, kTestControllerNodeId (112233, 0x1B669) will be used.");
+        AddArgument("use-max-sized-certs", 0, 1, &mUseMaxSizedCerts,
+                    "Maximize the size of operational certificates. If not provided or 0 (\"false\"), normally sized operational "
+                    "certificates are generated.");
+        AddArgument("only-allow-trusted-cd-keys", 0, 1, &mOnlyAllowTrustedCdKeys,
+                    "Only allow trusted CD verifying keys (disallow test keys). If not provided or 0 (\"false\"), untrusted CD "
+                    "verifying keys are allowed. If 1 (\"true\"), test keys are disallowed.");
+#if CHIP_CONFIG_TRANSPORT_TRACE_ENABLED
+        AddArgument("trace_file", &mTraceFile);
+        AddArgument("trace_log", 0, 1, &mTraceLog);
+        AddArgument("trace_decode", 0, 1, &mTraceDecode);
+#endif // CHIP_CONFIG_TRANSPORT_TRACE_ENABLED
+        AddArgument("trace-to", &mTraceTo, "Trace destinations, comma-separated (" SUPPORTED_COMMAND_LINE_TRACING_TARGETS ")");
+        AddArgument("ble-adapter", 0, UINT16_MAX, &mBleAdapterId);
+        AddArgument("storage-directory", &mStorageDirectory,
+                    "Directory to place fabric-admin's storage files in.  Defaults to $TMPDIR, with fallback to /tmp");
+        AddArgument(
+            "commissioner-vendor-id", 0, UINT16_MAX, &mCommissionerVendorId,
+            "The vendor id to use for fabric-admin. If not provided, chip::VendorId::TestVendor1 (65521, 0xFFF1) will be used.");
+    }
+
+    /////////// Command Interface /////////
+    CHIP_ERROR Run() override;
+
+    void SetCommandExitStatus(CHIP_ERROR status)
+    {
+        mCommandExitStatus = status;
+        // In interactive mode the stack is not shut down once a command is ended.
+        // That means calling `ErrorStr(err)` from the main thread when command
+        // completion is signaled may race since `ErrorStr` uses a static sErrorStr
+        // buffer for computing the error string.  Call it here instead.
+        if (IsInteractive() && CHIP_NO_ERROR != status)
+        {
+            ChipLogError(NotSpecified, "Run command failure: %s", chip::ErrorStr(status));
+        }
+        StopWaiting();
+    }
+
+protected:
+    // Will be called in a setting in which it's safe to touch the CHIP
+    // stack. The rules for Run() are as follows:
+    //
+    // 1) If error is returned, Run() must not call SetCommandExitStatus.
+    // 2) If success is returned Run() must either have called
+    //    SetCommandExitStatus() or scheduled async work that will do that.
+    virtual CHIP_ERROR RunCommand() = 0;
+
+    // Get the wait duration, in seconds, before the command times out.
+    virtual chip::System::Clock::Timeout GetWaitDuration() const = 0;
+
+    // Shut down the command.  After a Shutdown call the command object is ready
+    // to be used for another command invocation.
+    virtual void Shutdown() { ResetArguments(); }
+
+    // Clean up any resources allocated by the command.  Some commands may hold
+    // on to resources after Shutdown(), but Cleanup() will guarantee those are
+    // cleaned up.
+    virtual void Cleanup() {}
+
+    // If true, skip calling Cleanup() when in interactive mode, so the command
+    // can keep doing work as needed.  Cleanup() will be called when quitting
+    // interactive mode.  This method will be called before Shutdown, so it can
+    // use member values that Shutdown will normally reset.
+    virtual bool DeferInteractiveCleanup() { return false; }
+
+    // If true, the controller will be created with server capabilities enabled,
+    // such as advertising operational nodes over DNS-SD and accepting incoming
+    // CASE sessions.
+    virtual bool NeedsOperationalAdvertising() { return mAdvertiseOperational; }
+
+    // Execute any deferred cleanups.  Used when exiting interactive mode.
+    static void ExecuteDeferredCleanups(intptr_t ignored);
+
+#ifdef CONFIG_USE_LOCAL_STORAGE
+    PersistentStorage mDefaultStorage;
+    // TODO: It's pretty weird that we re-init mCommissionerStorage for every
+    // identity without shutting it down or something in between...
+    PersistentStorage mCommissionerStorage;
+#endif // CONFIG_USE_LOCAL_STORAGE
+    chip::PersistentStorageOperationalKeystore mOperationalKeystore;
+    chip::Credentials::PersistentStorageOpCertStore mOpCertStore;
+    static chip::Crypto::RawKeySessionKeystore sSessionKeystore;
+
+    static chip::Credentials::GroupDataProviderImpl sGroupDataProvider;
+    static chip::app::DefaultICDClientStorage sICDClientStorage;
+    static chip::app::DefaultCheckInDelegate sCheckInDelegate;
+    static chip::app::CheckInHandler sCheckInHandler;
+    CredentialIssuerCommands * mCredIssuerCmds;
+
+    std::string GetIdentity();
+    CHIP_ERROR GetIdentityNodeId(std::string identity, chip::NodeId * nodeId);
+    CHIP_ERROR GetIdentityRootCertificate(std::string identity, chip::ByteSpan & span);
+    void SetIdentity(const char * name);
+
+    // This method returns the commissioner instance to be used for running the command.
+    // The default commissioner instance name is "alpha", but it can be overridden by passing
+    // --identity "instance name" when running a command.
+    ChipDeviceCommissioner & CurrentCommissioner();
+
+    ChipDeviceCommissioner & GetCommissioner(std::string identity);
+
+private:
+    CHIP_ERROR MaybeSetUpStack();
+    void MaybeTearDownStack();
+
+    CHIP_ERROR EnsureCommissionerForIdentity(std::string identity);
+
+    // Commissioners are keyed by name and local node id.
+    struct CommissionerIdentity
+    {
+        bool operator<(const CommissionerIdentity & other) const
+        {
+            return mName < other.mName || (mName == other.mName && mLocalNodeId < other.mLocalNodeId);
+        }
+        std::string mName;
+        chip::NodeId mLocalNodeId;
+        uint8_t mRCAC[chip::Controller::kMaxCHIPDERCertLength] = {};
+        uint8_t mICAC[chip::Controller::kMaxCHIPDERCertLength] = {};
+        uint8_t mNOC[chip::Controller::kMaxCHIPDERCertLength]  = {};
+
+        size_t mRCACLen;
+        size_t mICACLen;
+        size_t mNOCLen;
+    };
+
+    // InitializeCommissioner uses various members, so can't be static.  This is
+    // obviously a little odd, since the commissioners are then shared across
+    // multiple commands in interactive mode...
+    CHIP_ERROR InitializeCommissioner(CommissionerIdentity & identity, chip::FabricId fabricId);
+    void ShutdownCommissioner(const CommissionerIdentity & key);
+    chip::FabricId CurrentCommissionerId();
+
+    static std::map<CommissionerIdentity, std::unique_ptr<ChipDeviceCommissioner>> mCommissioners;
+    static std::set<CHIPCommand *> sDeferredCleanups;
+
+    chip::Optional<char *> mCommissionerName;
+    chip::Optional<chip::NodeId> mCommissionerNodeId;
+    chip::Optional<chip::VendorId> mCommissionerVendorId;
+    chip::Optional<uint16_t> mBleAdapterId;
+    chip::Optional<char *> mPaaTrustStorePath;
+    chip::Optional<char *> mCDTrustStorePath;
+    chip::Optional<bool> mUseMaxSizedCerts;
+    chip::Optional<bool> mOnlyAllowTrustedCdKeys;
+
+    // Cached trust store so commands other than the original startup command
+    // can spin up commissioners as needed.
+    static const chip::Credentials::AttestationTrustStore * sTrustStore;
+
+    static void RunQueuedCommand(intptr_t commandArg);
+    typedef decltype(RunQueuedCommand) MatterWorkCallback;
+    static void RunCommandCleanup(intptr_t commandArg);
+
+    // Do cleanup after a commmand is done running.  Must happen with the
+    // Matter stack locked.
+    void CleanupAfterRun();
+
+    // Run the given callback on the Matter thread.  Return whether we managed
+    // to successfully dispatch it to the Matter thread.  If we did, *timedOut
+    // will be set to whether we timed out or whether our mWaitingForResponse
+    // got set to false by the callback itself.
+    CHIP_ERROR RunOnMatterQueue(MatterWorkCallback callback, chip::System::Clock::Timeout timeout, bool * timedOut);
+
+    CHIP_ERROR mCommandExitStatus = CHIP_ERROR_INTERNAL;
+
+    CHIP_ERROR StartWaiting(chip::System::Clock::Timeout seconds);
+    void StopWaiting();
+
+#if CONFIG_USE_SEPARATE_EVENTLOOP
+    std::condition_variable cvWaitingForResponse;
+    std::mutex cvWaitingForResponseMutex;
+    bool mWaitingForResponse{ true };
+#endif // CONFIG_USE_SEPARATE_EVENTLOOP
+
+    void StartTracing();
+    void StopTracing();
+
+#if CHIP_CONFIG_TRANSPORT_TRACE_ENABLED
+    chip::Optional<char *> mTraceFile;
+    chip::Optional<bool> mTraceLog;
+    chip::Optional<bool> mTraceDecode;
+#endif // CHIP_CONFIG_TRANSPORT_TRACE_ENABLED
+
+    chip::CommandLineApp::TracingSetup mTracingSetup;
+    chip::Optional<std::vector<std::string>> mTraceTo;
+};
diff --git a/examples/fabric-admin/commands/common/Command.cpp b/examples/fabric-admin/commands/common/Command.cpp
new file mode 100644
index 0000000..7e56891
--- /dev/null
+++ b/examples/fabric-admin/commands/common/Command.cpp
@@ -0,0 +1,1088 @@
+/*
+ *   Copyright (c) 2024 Project CHIP Authors
+ *   All rights reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+#include "Command.h"
+#include "CustomStringPrefix.h"
+#include "HexConversion.h"
+#include "platform/PlatformManager.h"
+
+#include <functional>
+#include <netdb.h>
+#include <sstream>
+#include <string>
+#include <sys/socket.h>
+#include <sys/types.h>
+
+#include <math.h> // For INFINITY
+
+#include <lib/core/CHIPSafeCasts.h>
+#include <lib/support/BytesToHex.h>
+#include <lib/support/CHIPMem.h>
+#include <lib/support/CodeUtils.h>
+#include <lib/support/SafeInt.h>
+#include <lib/support/ScopedBuffer.h>
+#include <lib/support/StringSplitter.h>
+#include <lib/support/logging/CHIPLogging.h>
+
+constexpr char kOptionalArgumentPrefix[]       = "--";
+constexpr size_t kOptionalArgumentPrefixLength = 2;
+
+bool Command::InitArguments(int argc, char ** argv)
+{
+    bool isValidCommand = false;
+
+    size_t argvExtraArgsCount = (size_t) argc;
+    size_t mandatoryArgsCount = 0;
+    size_t optionalArgsCount  = 0;
+    for (auto & arg : mArgs)
+    {
+        if (arg.isOptional())
+        {
+            optionalArgsCount++;
+        }
+        else
+        {
+            mandatoryArgsCount++;
+            argvExtraArgsCount--;
+        }
+    }
+
+    VerifyOrExit((size_t) (argc) >= mandatoryArgsCount && (argvExtraArgsCount == 0 || (argvExtraArgsCount && optionalArgsCount)),
+                 ChipLogError(NotSpecified, "InitArgs: Wrong arguments number: %d instead of %u", argc,
+                              static_cast<unsigned int>(mandatoryArgsCount)));
+
+    // Initialize mandatory arguments
+    for (size_t i = 0; i < mandatoryArgsCount; i++)
+    {
+        char * arg = argv[i];
+        if (!InitArgument(i, arg))
+        {
+            ExitNow();
+        }
+    }
+
+    // Initialize optional arguments
+    // Optional arguments expect a name and a value, so i is increased by 2 on every step.
+    for (size_t i = mandatoryArgsCount; i < (size_t) argc; i += 2)
+    {
+        bool found = false;
+        for (size_t j = mandatoryArgsCount; j < mandatoryArgsCount + optionalArgsCount; j++)
+        {
+            // optional arguments starts with kOptionalArgumentPrefix
+            if (strlen(argv[i]) <= kOptionalArgumentPrefixLength &&
+                strncmp(argv[i], kOptionalArgumentPrefix, kOptionalArgumentPrefixLength) != 0)
+            {
+                continue;
+            }
+
+            if (strcmp(argv[i] + strlen(kOptionalArgumentPrefix), mArgs[j].name) == 0)
+            {
+                found = true;
+
+                VerifyOrExit((size_t) argc > (i + 1),
+                             ChipLogError(NotSpecified, "InitArgs: Optional argument %s missing value.", argv[i]));
+                if (!InitArgument(j, argv[i + 1]))
+                {
+                    ExitNow();
+                }
+            }
+        }
+        VerifyOrExit(found, ChipLogError(NotSpecified, "InitArgs: Optional argument %s does not exist.", argv[i]));
+    }
+
+    isValidCommand = true;
+
+exit:
+    return isValidCommand;
+}
+
+static bool ParseAddressWithInterface(const char * addressString, Command::AddressWithInterface * address)
+{
+    struct addrinfo hints;
+    struct addrinfo * result;
+    int ret;
+
+    memset(&hints, 0, sizeof(hints));
+    hints.ai_family   = AF_UNSPEC;
+    hints.ai_socktype = SOCK_DGRAM;
+    ret               = getaddrinfo(addressString, nullptr, &hints, &result);
+    if (ret < 0)
+    {
+        ChipLogError(NotSpecified, "Invalid address: %s", addressString);
+        return false;
+    }
+
+    if (result->ai_family == AF_INET6)
+    {
+        struct sockaddr_in6 * addr = reinterpret_cast<struct sockaddr_in6 *>(result->ai_addr);
+        address->address           = ::chip::Inet::IPAddress::FromSockAddr(*addr);
+        address->interfaceId       = ::chip::Inet::InterfaceId(addr->sin6_scope_id);
+    }
+#if INET_CONFIG_ENABLE_IPV4
+    else if (result->ai_family == AF_INET)
+    {
+        address->address     = ::chip::Inet::IPAddress::FromSockAddr(*reinterpret_cast<struct sockaddr_in *>(result->ai_addr));
+        address->interfaceId = chip::Inet::InterfaceId::Null();
+    }
+#endif // INET_CONFIG_ENABLE_IPV4
+    else
+    {
+        ChipLogError(NotSpecified, "Unsupported address: %s", addressString);
+        return false;
+    }
+
+    return true;
+}
+
+// The callback should return whether the argument is valid, for the non-null
+// case.  It can't directly write to isValidArgument (by closing over it)
+// because in the nullable-and-null case we need to do that from this function,
+// via the return value.
+template <typename T>
+bool HandleNullableOptional(Argument & arg, char * argValue, std::function<bool(T * value)> callback)
+{
+    if (arg.isOptional())
+    {
+        if (arg.isNullable())
+        {
+            arg.value = &(reinterpret_cast<chip::Optional<chip::app::DataModel::Nullable<T>> *>(arg.value)->Emplace());
+        }
+        else
+        {
+            arg.value = &(reinterpret_cast<chip::Optional<T> *>(arg.value)->Emplace());
+        }
+    }
+
+    if (arg.isNullable())
+    {
+        auto * nullable = reinterpret_cast<chip::app::DataModel::Nullable<T> *>(arg.value);
+        if (argValue != nullptr && strncmp(argValue, "null", 4) == 0)
+        {
+            nullable->SetNull();
+            return true;
+        }
+
+        arg.value = &(nullable->SetNonNull());
+    }
+
+    return callback(reinterpret_cast<T *>(arg.value));
+}
+
+bool Command::InitArgument(size_t argIndex, char * argValue)
+{
+    bool isValidArgument = false;
+    bool isHexNotation   = strncmp(argValue, "0x", 2) == 0 || strncmp(argValue, "0X", 2) == 0;
+
+    Argument arg = mArgs.at(argIndex);
+
+    // We have two places where we handle uint8_t-typed args (actual int8u and
+    // bool args), so declare the handler function here so it can be reused.
+    auto uint8Handler = [&](uint8_t * value) {
+        // stringstream treats uint8_t as char, which is not what we want here.
+        uint16_t tmpValue;
+        std::stringstream ss;
+        isHexNotation ? (ss << std::hex << argValue) : (ss << argValue);
+        ss >> tmpValue;
+        if (chip::CanCastTo<uint8_t>(tmpValue))
+        {
+            *value = static_cast<uint8_t>(tmpValue);
+
+            uint64_t min = chip::CanCastTo<uint64_t>(arg.min) ? static_cast<uint64_t>(arg.min) : 0;
+            uint64_t max = arg.max;
+            return (!ss.fail() && ss.eof() && *value >= min && *value <= max);
+        }
+
+        return false;
+    };
+
+    switch (arg.type)
+    {
+    case ArgumentType::Complex: {
+        // Complex arguments may be optional, but they are not currently supported via the <chip::Optional> class.
+        // Instead, they must be explicitly specified as optional using the kOptional flag,
+        // and the base TypedComplexArgument<T> class is still referenced.
+        auto complexArgument = static_cast<ComplexArgument *>(arg.value);
+        return CHIP_NO_ERROR == complexArgument->Parse(arg.name, argValue);
+    }
+
+    case ArgumentType::Custom: {
+        auto customArgument = static_cast<CustomArgument *>(arg.value);
+        return CHIP_NO_ERROR == customArgument->Parse(arg.name, argValue);
+    }
+
+    case ArgumentType::VectorString: {
+        std::vector<std::string> vectorArgument;
+
+        chip::StringSplitter splitter(argValue, ',');
+        chip::CharSpan value;
+
+        while (splitter.Next(value))
+        {
+            vectorArgument.push_back(std::string(value.data(), value.size()));
+        }
+
+        if (arg.flags == Argument::kOptional)
+        {
+            auto argument = static_cast<chip::Optional<std::vector<std::string>> *>(arg.value);
+            argument->SetValue(vectorArgument);
+        }
+        else
+        {
+            auto argument = static_cast<std::vector<std::string> *>(arg.value);
+            *argument     = vectorArgument;
+        }
+        return true;
+    }
+    case ArgumentType::VectorBool: {
+        // Currently only chip::Optional<std::vector<bool>> is supported.
+        if (arg.flags != Argument::kOptional)
+        {
+            return false;
+        }
+
+        std::vector<bool> vectorArgument;
+        std::stringstream ss(argValue);
+        while (ss.good())
+        {
+            std::string valueAsString;
+            getline(ss, valueAsString, ',');
+
+            if (strcasecmp(valueAsString.c_str(), "true") == 0)
+            {
+                vectorArgument.push_back(true);
+            }
+            else if (strcasecmp(valueAsString.c_str(), "false") == 0)
+            {
+                vectorArgument.push_back(false);
+            }
+            else
+            {
+                return false;
+            }
+        }
+
+        auto optionalArgument = static_cast<chip::Optional<std::vector<bool>> *>(arg.value);
+        optionalArgument->SetValue(vectorArgument);
+        return true;
+    }
+
+    case ArgumentType::Vector16:
+    case ArgumentType::Vector32: {
+        std::vector<uint64_t> values;
+        uint64_t min = chip::CanCastTo<uint64_t>(arg.min) ? static_cast<uint64_t>(arg.min) : 0;
+        uint64_t max = arg.max;
+
+        std::stringstream ss(argValue);
+        while (ss.good())
+        {
+            std::string valueAsString;
+            getline(ss, valueAsString, ',');
+            isHexNotation = strncmp(valueAsString.c_str(), "0x", 2) == 0 || strncmp(valueAsString.c_str(), "0X", 2) == 0;
+
+            std::stringstream subss;
+            isHexNotation ? subss << std::hex << valueAsString : subss << valueAsString;
+
+            uint64_t value;
+            subss >> value;
+            VerifyOrReturnError(!subss.fail() && subss.eof() && value >= min && value <= max, false);
+            values.push_back(value);
+        }
+
+        if (arg.type == ArgumentType::Vector16)
+        {
+            auto vectorArgument = static_cast<std::vector<uint16_t> *>(arg.value);
+            for (uint64_t v : values)
+            {
+                vectorArgument->push_back(static_cast<uint16_t>(v));
+            }
+        }
+        else if (arg.type == ArgumentType::Vector32 && arg.flags != Argument::kOptional)
+        {
+            auto vectorArgument = static_cast<std::vector<uint32_t> *>(arg.value);
+            for (uint64_t v : values)
+            {
+                vectorArgument->push_back(static_cast<uint32_t>(v));
+            }
+        }
+        else if (arg.type == ArgumentType::Vector32 && arg.flags == Argument::kOptional)
+        {
+            std::vector<uint32_t> vectorArgument;
+            for (uint64_t v : values)
+            {
+                vectorArgument.push_back(static_cast<uint32_t>(v));
+            }
+
+            auto optionalArgument = static_cast<chip::Optional<std::vector<uint32_t>> *>(arg.value);
+            optionalArgument->SetValue(vectorArgument);
+        }
+        else
+        {
+            return false;
+        }
+
+        return true;
+    }
+
+    case ArgumentType::VectorCustom: {
+        auto vectorArgument = static_cast<std::vector<CustomArgument *> *>(arg.value);
+
+        std::stringstream ss(argValue);
+        while (ss.good())
+        {
+            std::string valueAsString;
+            // By default the parameter separator is ";" in order to not collapse with the argument itself if it contains commas
+            // (e.g a struct argument with multiple fields). In case one needs to use ";" it can be overriden with the following
+            // environment variable.
+            static constexpr char kSeparatorVariable[] = "NotSpecified,_CUSTOM_ARGUMENTS_SEPARATOR";
+            char * getenvSeparatorVariableResult       = getenv(kSeparatorVariable);
+            getline(ss, valueAsString, getenvSeparatorVariableResult ? getenvSeparatorVariableResult[0] : ';');
+
+            CustomArgument * customArgument = new CustomArgument();
+            vectorArgument->push_back(customArgument);
+            VerifyOrReturnError(CHIP_NO_ERROR == vectorArgument->back()->Parse(arg.name, valueAsString.c_str()), false);
+        }
+
+        return true;
+    }
+
+    case ArgumentType::String: {
+        isValidArgument = HandleNullableOptional<char *>(arg, argValue, [&](auto * value) {
+            *value = argValue;
+            return true;
+        });
+        break;
+    }
+
+    case ArgumentType::CharString: {
+        isValidArgument = HandleNullableOptional<chip::CharSpan>(arg, argValue, [&](auto * value) {
+            *value = chip::Span<const char>(argValue, strlen(argValue));
+            return true;
+        });
+        break;
+    }
+
+    case ArgumentType::OctetString: {
+        isValidArgument = HandleNullableOptional<chip::ByteSpan>(arg, argValue, [&](auto * value) {
+            // We support two ways to pass an octet string argument.  If it happens
+            // to be all-ASCII, you can just pass it in.  Otherwise you can pass in
+            // "hex:" followed by the hex-encoded bytes.
+            size_t argLen = strlen(argValue);
+
+            if (IsHexString(argValue))
+            {
+                // Hex-encoded.  Decode it into a temporary buffer first, so if we
+                // run into errors we can do correct "argument is not valid" logging
+                // that actually shows the value that was passed in.  After we
+                // determine it's valid, modify the passed-in value to hold the
+                // right bytes, so we don't need to worry about allocating storage
+                // for this somewhere else.  This works because the hex
+                // representation is always longer than the octet string it encodes,
+                // so we have enough space in argValue for the decoded version.
+                chip::Platform::ScopedMemoryBuffer<uint8_t> buffer;
+
+                size_t octetCount;
+                CHIP_ERROR err = HexToBytes(
+                    chip::CharSpan(argValue + kHexStringPrefixLen, argLen - kHexStringPrefixLen),
+                    [&buffer](size_t allocSize) {
+                        buffer.Calloc(allocSize);
+                        return buffer.Get();
+                    },
+                    &octetCount);
+                if (err != CHIP_NO_ERROR)
+                {
+                    return false;
+                }
+
+                memcpy(argValue, buffer.Get(), octetCount);
+                *value = chip::ByteSpan(chip::Uint8::from_char(argValue), octetCount);
+                return true;
+            }
+
+            // Just ASCII.  Check for the "str:" prefix.
+            if (IsStrString(argValue))
+            {
+                // Skip the prefix
+                argValue += kStrStringPrefixLen;
+                argLen -= kStrStringPrefixLen;
+            }
+            *value = chip::ByteSpan(chip::Uint8::from_char(argValue), argLen);
+            return true;
+        });
+        break;
+    }
+
+    case ArgumentType::Bool: {
+        isValidArgument = HandleNullableOptional<bool>(arg, argValue, [&](auto * value) {
+            // Start with checking for actual boolean values.
+            if (strcasecmp(argValue, "true") == 0)
+            {
+                *value = true;
+                return true;
+            }
+
+            if (strcasecmp(argValue, "false") == 0)
+            {
+                *value = false;
+                return true;
+            }
+
+            // For backwards compat, keep accepting 0 and 1 for now as synonyms
+            // for false and true.  Since we set our min to 0 and max to 1 for
+            // booleans, calling uint8Handler does the right thing in terms of
+            // only allowing those two values.
+            uint8_t temp = 0;
+            if (!uint8Handler(&temp))
+            {
+                return false;
+            }
+            *value = (temp == 1);
+            return true;
+        });
+        break;
+    }
+
+    case ArgumentType::Number_uint8: {
+        isValidArgument = HandleNullableOptional<uint8_t>(arg, argValue, uint8Handler);
+        break;
+    }
+
+    case ArgumentType::Number_uint16: {
+        isValidArgument = HandleNullableOptional<uint16_t>(arg, argValue, [&](auto * value) {
+            std::stringstream ss;
+            isHexNotation ? ss << std::hex << argValue : ss << argValue;
+            ss >> *value;
+
+            uint64_t min = chip::CanCastTo<uint64_t>(arg.min) ? static_cast<uint64_t>(arg.min) : 0;
+            uint64_t max = arg.max;
+            return (!ss.fail() && ss.eof() && *value >= min && *value <= max);
+        });
+        break;
+    }
+
+    case ArgumentType::Number_uint32: {
+        isValidArgument = HandleNullableOptional<uint32_t>(arg, argValue, [&](auto * value) {
+            std::stringstream ss;
+            isHexNotation ? ss << std::hex << argValue : ss << argValue;
+            ss >> *value;
+
+            uint64_t min = chip::CanCastTo<uint64_t>(arg.min) ? static_cast<uint64_t>(arg.min) : 0;
+            uint64_t max = arg.max;
+            return (!ss.fail() && ss.eof() && *value >= min && *value <= max);
+        });
+        break;
+    }
+
+    case ArgumentType::Number_uint64: {
+        isValidArgument = HandleNullableOptional<uint64_t>(arg, argValue, [&](auto * value) {
+            std::stringstream ss;
+            isHexNotation ? ss << std::hex << argValue : ss << argValue;
+            ss >> *value;
+
+            uint64_t min = chip::CanCastTo<uint64_t>(arg.min) ? static_cast<uint64_t>(arg.min) : 0;
+            uint64_t max = arg.max;
+            return (!ss.fail() && ss.eof() && *value >= min && *value <= max);
+        });
+        break;
+    }
+
+    case ArgumentType::Number_int8: {
+        isValidArgument = HandleNullableOptional<int8_t>(arg, argValue, [&](auto * value) {
+            // stringstream treats int8_t as char, which is not what we want here.
+            int16_t tmpValue;
+            std::stringstream ss;
+            isHexNotation ? ss << std::hex << argValue : ss << argValue;
+            ss >> tmpValue;
+            if (chip::CanCastTo<int8_t>(tmpValue))
+            {
+                *value = static_cast<int8_t>(tmpValue);
+
+                int64_t min = arg.min;
+                int64_t max = chip::CanCastTo<int64_t>(arg.max) ? static_cast<int64_t>(arg.max) : INT64_MAX;
+                return (!ss.fail() && ss.eof() && *value >= min && *value <= max);
+            }
+
+            return false;
+        });
+        break;
+    }
+
+    case ArgumentType::Number_int16: {
+        isValidArgument = HandleNullableOptional<int16_t>(arg, argValue, [&](auto * value) {
+            std::stringstream ss;
+            isHexNotation ? ss << std::hex << argValue : ss << argValue;
+            ss >> *value;
+
+            int64_t min = arg.min;
+            int64_t max = chip::CanCastTo<int64_t>(arg.max) ? static_cast<int64_t>(arg.max) : INT64_MAX;
+            return (!ss.fail() && ss.eof() && *value >= min && *value <= max);
+        });
+        break;
+    }
+
+    case ArgumentType::Number_int32: {
+        isValidArgument = HandleNullableOptional<int32_t>(arg, argValue, [&](auto * value) {
+            std::stringstream ss;
+            isHexNotation ? ss << std::hex << argValue : ss << argValue;
+            ss >> *value;
+
+            int64_t min = arg.min;
+            int64_t max = chip::CanCastTo<int64_t>(arg.max) ? static_cast<int64_t>(arg.max) : INT64_MAX;
+            return (!ss.fail() && ss.eof() && *value >= min && *value <= max);
+        });
+        break;
+    }
+
+    case ArgumentType::Number_int64: {
+        isValidArgument = HandleNullableOptional<int64_t>(arg, argValue, [&](auto * value) {
+            std::stringstream ss;
+            isHexNotation ? ss << std::hex << argValue : ss << argValue;
+            ss >> *value;
+
+            int64_t min = arg.min;
+            int64_t max = chip::CanCastTo<int64_t>(arg.max) ? static_cast<int64_t>(arg.max) : INT64_MAX;
+            return (!ss.fail() && ss.eof() && *value >= min && *value <= max);
+        });
+        break;
+    }
+
+    case ArgumentType::Float: {
+        isValidArgument = HandleNullableOptional<float>(arg, argValue, [&](auto * value) {
+            if (strcmp(argValue, "Infinity") == 0)
+            {
+                *value = INFINITY;
+                return true;
+            }
+
+            if (strcmp(argValue, "-Infinity") == 0)
+            {
+                *value = -INFINITY;
+                return true;
+            }
+
+            std::stringstream ss;
+            ss << argValue;
+            ss >> *value;
+            return (!ss.fail() && ss.eof());
+        });
+        break;
+    }
+
+    case ArgumentType::Double: {
+        isValidArgument = HandleNullableOptional<double>(arg, argValue, [&](auto * value) {
+            if (strcmp(argValue, "Infinity") == 0)
+            {
+                *value = INFINITY;
+                return true;
+            }
+
+            if (strcmp(argValue, "-Infinity") == 0)
+            {
+                *value = -INFINITY;
+                return true;
+            }
+
+            std::stringstream ss;
+            ss << argValue;
+            ss >> *value;
+            return (!ss.fail() && ss.eof());
+        });
+        break;
+    }
+
+    case ArgumentType::Address: {
+        isValidArgument = HandleNullableOptional<AddressWithInterface>(
+            arg, argValue, [&](auto * value) { return ParseAddressWithInterface(argValue, value); });
+        break;
+    }
+    }
+
+    if (!isValidArgument)
+    {
+        ChipLogError(NotSpecified, "InitArgs: Invalid argument %s: %s", arg.name, argValue);
+    }
+
+    return isValidArgument;
+}
+
+void Command::AddArgument(const char * name, const char * value, const char * desc)
+{
+    ReadOnlyGlobalCommandArgument arg;
+    arg.name  = name;
+    arg.value = value;
+    arg.desc  = desc;
+
+    mReadOnlyGlobalCommandArgument.SetValue(arg);
+}
+
+size_t Command::AddArgument(const char * name, char ** value, const char * desc, uint8_t flags)
+{
+    Argument arg;
+    arg.type  = ArgumentType::String;
+    arg.name  = name;
+    arg.value = reinterpret_cast<void *>(value);
+    arg.flags = flags;
+    arg.desc  = desc;
+
+    return AddArgumentToList(std::move(arg));
+}
+
+size_t Command::AddArgument(const char * name, chip::CharSpan * value, const char * desc, uint8_t flags)
+{
+    Argument arg;
+    arg.type  = ArgumentType::CharString;
+    arg.name  = name;
+    arg.value = reinterpret_cast<void *>(value);
+    arg.flags = flags;
+    arg.desc  = desc;
+
+    return AddArgumentToList(std::move(arg));
+}
+
+size_t Command::AddArgument(const char * name, chip::ByteSpan * value, const char * desc, uint8_t flags)
+{
+    Argument arg;
+    arg.type  = ArgumentType::OctetString;
+    arg.name  = name;
+    arg.value = reinterpret_cast<void *>(value);
+    arg.flags = flags;
+    arg.desc  = desc;
+
+    return AddArgumentToList(std::move(arg));
+}
+
+size_t Command::AddArgument(const char * name, AddressWithInterface * out, const char * desc, uint8_t flags)
+{
+    Argument arg;
+    arg.type  = ArgumentType::Address;
+    arg.name  = name;
+    arg.value = reinterpret_cast<void *>(out);
+    arg.flags = flags;
+    arg.desc  = desc;
+
+    return AddArgumentToList(std::move(arg));
+}
+
+size_t Command::AddArgument(const char * name, int64_t min, uint64_t max, std::vector<uint16_t> * value, const char * desc)
+{
+    Argument arg;
+    arg.type  = ArgumentType::Vector16;
+    arg.name  = name;
+    arg.value = static_cast<void *>(value);
+    arg.min   = min;
+    arg.max   = max;
+    arg.flags = 0;
+    arg.desc  = desc;
+
+    return AddArgumentToList(std::move(arg));
+}
+
+size_t Command::AddArgument(const char * name, int64_t min, uint64_t max, std::vector<uint32_t> * value, const char * desc)
+{
+    Argument arg;
+    arg.type  = ArgumentType::Vector32;
+    arg.name  = name;
+    arg.value = static_cast<void *>(value);
+    arg.min   = min;
+    arg.max   = max;
+    arg.flags = 0;
+    arg.desc  = desc;
+
+    return AddArgumentToList(std::move(arg));
+}
+
+size_t Command::AddArgument(const char * name, int64_t min, uint64_t max, chip::Optional<std::vector<uint32_t>> * value,
+                            const char * desc)
+{
+    Argument arg;
+    arg.type  = ArgumentType::Vector32;
+    arg.name  = name;
+    arg.value = static_cast<void *>(value);
+    arg.min   = min;
+    arg.max   = max;
+    arg.flags = Argument::kOptional;
+    arg.desc  = desc;
+
+    return AddArgumentToList(std::move(arg));
+}
+
+size_t Command::AddArgument(const char * name, int64_t min, uint64_t max, chip::Optional<std::vector<bool>> * value,
+                            const char * desc)
+{
+    Argument arg;
+    arg.type  = ArgumentType::VectorBool;
+    arg.name  = name;
+    arg.value = static_cast<void *>(value);
+    arg.min   = min;
+    arg.max   = max;
+    arg.flags = Argument::kOptional;
+    arg.desc  = desc;
+
+    return AddArgumentToList(std::move(arg));
+}
+
+size_t Command::AddArgument(const char * name, ComplexArgument * value, const char * desc, uint8_t flags)
+{
+    Argument arg;
+    arg.type  = ArgumentType::Complex;
+    arg.name  = name;
+    arg.value = static_cast<void *>(value);
+    arg.flags = flags;
+    arg.desc  = desc;
+
+    return AddArgumentToList(std::move(arg));
+}
+
+size_t Command::AddArgument(const char * name, CustomArgument * value, const char * desc)
+{
+    Argument arg;
+    arg.type  = ArgumentType::Custom;
+    arg.name  = name;
+    arg.value = const_cast<void *>(reinterpret_cast<const void *>(value));
+    arg.flags = 0;
+    arg.desc  = desc;
+
+    return AddArgumentToList(std::move(arg));
+}
+
+size_t Command::AddArgument(const char * name, std::vector<CustomArgument *> * value, const char * desc)
+{
+    Argument arg;
+    arg.type  = ArgumentType::VectorCustom;
+    arg.name  = name;
+    arg.value = static_cast<void *>(value);
+    arg.flags = 0;
+    arg.desc  = desc;
+
+    return AddArgumentToList(std::move(arg));
+}
+
+size_t Command::AddArgument(const char * name, float min, float max, float * out, const char * desc, uint8_t flags)
+{
+    Argument arg;
+    arg.type  = ArgumentType::Float;
+    arg.name  = name;
+    arg.value = reinterpret_cast<void *>(out);
+    arg.flags = flags;
+    arg.desc  = desc;
+    // Ignore min/max for now; they're always +-Infinity anyway.
+
+    return AddArgumentToList(std::move(arg));
+}
+
+size_t Command::AddArgument(const char * name, double min, double max, double * out, const char * desc, uint8_t flags)
+{
+    Argument arg;
+    arg.type  = ArgumentType::Double;
+    arg.name  = name;
+    arg.value = reinterpret_cast<void *>(out);
+    arg.flags = flags;
+    arg.desc  = desc;
+    // Ignore min/max for now; they're always +-Infinity anyway.
+
+    return AddArgumentToList(std::move(arg));
+}
+
+size_t Command::AddArgument(const char * name, int64_t min, uint64_t max, void * out, ArgumentType type, const char * desc,
+                            uint8_t flags)
+{
+    Argument arg;
+    arg.type  = type;
+    arg.name  = name;
+    arg.value = out;
+    arg.min   = min;
+    arg.max   = max;
+    arg.flags = flags;
+    arg.desc  = desc;
+
+    return AddArgumentToList(std::move(arg));
+}
+
+size_t Command::AddArgument(const char * name, int64_t min, uint64_t max, void * out, const char * desc, uint8_t flags)
+{
+    Argument arg;
+    arg.type  = ArgumentType::Number_uint8;
+    arg.name  = name;
+    arg.value = out;
+    arg.min   = min;
+    arg.max   = max;
+    arg.flags = flags;
+    arg.desc  = desc;
+
+    return AddArgumentToList(std::move(arg));
+}
+
+size_t Command::AddArgument(const char * name, std::vector<std::string> * value, const char * desc)
+{
+    Argument arg;
+    arg.type  = ArgumentType::VectorString;
+    arg.name  = name;
+    arg.value = static_cast<void *>(value);
+    arg.flags = 0;
+    arg.desc  = desc;
+
+    return AddArgumentToList(std::move(arg));
+}
+
+size_t Command::AddArgument(const char * name, chip::Optional<std::vector<std::string>> * value, const char * desc)
+{
+    Argument arg;
+    arg.type  = ArgumentType::VectorString;
+    arg.name  = name;
+    arg.value = static_cast<void *>(value);
+    arg.flags = Argument::kOptional;
+    arg.desc  = desc;
+
+    return AddArgumentToList(std::move(arg));
+}
+
+const char * Command::GetArgumentName(size_t index) const
+{
+    if (index < mArgs.size())
+    {
+        return mArgs.at(index).name;
+    }
+
+    return nullptr;
+}
+
+const char * Command::GetArgumentDescription(size_t index) const
+{
+    if (index < mArgs.size())
+    {
+        return mArgs.at(index).desc;
+    }
+
+    return nullptr;
+}
+
+const char * Command::GetReadOnlyGlobalCommandArgument() const
+{
+    if (GetAttribute())
+    {
+        return GetAttribute();
+    }
+
+    if (GetEvent())
+    {
+        return GetEvent();
+    }
+
+    return nullptr;
+}
+
+const char * Command::GetAttribute() const
+{
+    if (mReadOnlyGlobalCommandArgument.HasValue())
+    {
+        return mReadOnlyGlobalCommandArgument.Value().value;
+    }
+
+    return nullptr;
+}
+
+const char * Command::GetEvent() const
+{
+    if (mReadOnlyGlobalCommandArgument.HasValue())
+    {
+        return mReadOnlyGlobalCommandArgument.Value().value;
+    }
+
+    return nullptr;
+}
+
+size_t Command::AddArgumentToList(Argument && argument)
+{
+    if (argument.isOptional() || mArgs.empty() || !mArgs.back().isOptional())
+    {
+        // Safe to just append.
+        mArgs.emplace_back(std::move(argument));
+        return mArgs.size();
+    }
+
+    // We're inserting a non-optional arg but we already have something optional
+    // in the list.  Insert before the first optional arg.
+    for (auto cur = mArgs.cbegin(), end = mArgs.cend(); cur != end; ++cur)
+    {
+        if ((*cur).isOptional())
+        {
+            mArgs.emplace(cur, std::move(argument));
+            return mArgs.size();
+        }
+    }
+
+    // Never reached.
+    VerifyOrDie(false);
+    return 0;
+}
+
+namespace {
+template <typename T>
+void ResetOptionalArg(const Argument & arg)
+{
+    VerifyOrDie(arg.isOptional());
+
+    if (arg.isNullable())
+    {
+        reinterpret_cast<chip::Optional<chip::app::DataModel::Nullable<T>> *>(arg.value)->ClearValue();
+    }
+    else
+    {
+        reinterpret_cast<chip::Optional<T> *>(arg.value)->ClearValue();
+    }
+}
+} // anonymous namespace
+
+void Command::ResetArguments()
+{
+    for (const auto & arg : mArgs)
+    {
+        const ArgumentType type = arg.type;
+        if (arg.isOptional())
+        {
+            // Must always clean these up so they don't carry over to the next
+            // command invocation in interactive mode.
+            switch (type)
+            {
+            case ArgumentType::Complex: {
+                // Optional Complex arguments are not currently supported via the <chip::Optional> class.
+                // Instead, they must be explicitly specified as optional using the kOptional flag,
+                // and the base TypedComplexArgument<T> class is referenced.
+                auto argument = static_cast<ComplexArgument *>(arg.value);
+                argument->Reset();
+                break;
+            }
+            case ArgumentType::Custom: {
+                // No optional custom arguments so far.
+                VerifyOrDie(false);
+                break;
+            }
+            case ArgumentType::VectorString: {
+                ResetOptionalArg<std::vector<std::string>>(arg);
+                break;
+            }
+            case ArgumentType::VectorBool: {
+                ResetOptionalArg<std::vector<bool>>(arg);
+                break;
+            }
+            case ArgumentType::Vector16: {
+                // No optional Vector16 arguments so far.
+                VerifyOrDie(false);
+                break;
+            }
+            case ArgumentType::Vector32: {
+                ResetOptionalArg<std::vector<uint32_t>>(arg);
+                break;
+            }
+            case ArgumentType::VectorCustom: {
+                // No optional VectorCustom arguments so far.
+                VerifyOrDie(false);
+                break;
+            }
+            case ArgumentType::String: {
+                ResetOptionalArg<char *>(arg);
+                break;
+            }
+            case ArgumentType::CharString: {
+                ResetOptionalArg<chip::CharSpan>(arg);
+                break;
+            }
+            case ArgumentType::OctetString: {
+                ResetOptionalArg<chip::ByteSpan>(arg);
+                break;
+            }
+            case ArgumentType::Bool: {
+                ResetOptionalArg<bool>(arg);
+                break;
+            }
+            case ArgumentType::Number_uint8: {
+                ResetOptionalArg<uint8_t>(arg);
+                break;
+            }
+            case ArgumentType::Number_uint16: {
+                ResetOptionalArg<uint16_t>(arg);
+                break;
+            }
+            case ArgumentType::Number_uint32: {
+                ResetOptionalArg<uint32_t>(arg);
+                break;
+            }
+            case ArgumentType::Number_uint64: {
+                ResetOptionalArg<uint64_t>(arg);
+                break;
+            }
+            case ArgumentType::Number_int8: {
+                ResetOptionalArg<int8_t>(arg);
+                break;
+            }
+            case ArgumentType::Number_int16: {
+                ResetOptionalArg<int16_t>(arg);
+                break;
+            }
+            case ArgumentType::Number_int32: {
+                ResetOptionalArg<int32_t>(arg);
+                break;
+            }
+            case ArgumentType::Number_int64: {
+                ResetOptionalArg<int64_t>(arg);
+                break;
+            }
+            case ArgumentType::Float: {
+                ResetOptionalArg<float>(arg);
+                break;
+            }
+            case ArgumentType::Double: {
+                ResetOptionalArg<double>(arg);
+                break;
+            }
+            case ArgumentType::Address: {
+                ResetOptionalArg<AddressWithInterface>(arg);
+                break;
+            }
+            }
+        }
+        else
+        {
+            // Some non-optional arguments have state that needs to be cleaned
+            // up too.
+            if (type == ArgumentType::Vector16)
+            {
+                auto vectorArgument = static_cast<std::vector<uint16_t> *>(arg.value);
+                vectorArgument->clear();
+            }
+            else if (type == ArgumentType::Vector32)
+            {
+                auto vectorArgument = static_cast<std::vector<uint32_t> *>(arg.value);
+                vectorArgument->clear();
+            }
+            else if (type == ArgumentType::VectorCustom)
+            {
+                auto vectorArgument = static_cast<std::vector<CustomArgument *> *>(arg.value);
+                for (auto & customArgument : *vectorArgument)
+                {
+                    delete customArgument;
+                }
+                vectorArgument->clear();
+            }
+            else if (type == ArgumentType::Complex)
+            {
+                auto argument = static_cast<ComplexArgument *>(arg.value);
+                argument->Reset();
+            }
+        }
+    }
+}
diff --git a/examples/fabric-admin/commands/common/Command.h b/examples/fabric-admin/commands/common/Command.h
new file mode 100644
index 0000000..ec8b51d
--- /dev/null
+++ b/examples/fabric-admin/commands/common/Command.h
@@ -0,0 +1,307 @@
+/*
+ *   Copyright (c) 2024 Project CHIP Authors
+ *   All rights reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+#pragma once
+
+#include <app/data-model/Nullable.h>
+#include <commands/clusters/ComplexArgument.h>
+#include <commands/clusters/CustomArgument.h>
+#include <inet/InetInterface.h>
+#include <lib/core/Optional.h>
+#include <lib/support/Span.h>
+#include <lib/support/logging/CHIPLogging.h>
+
+#include <atomic>
+#include <condition_variable>
+#include <memory>
+#include <mutex>
+#include <string>
+#include <vector>
+
+class Command;
+
+template <typename T, typename... Args>
+std::unique_ptr<Command> make_unique(Args &&... args)
+{
+    return std::unique_ptr<Command>(new T(std::forward<Args>(args)...));
+}
+
+struct movable_initializer_list
+{
+    movable_initializer_list(std::unique_ptr<Command> && in) : item(std::move(in)) {}
+    operator std::unique_ptr<Command>() const && { return std::move(item); }
+    mutable std::unique_ptr<Command> item;
+};
+
+typedef std::initializer_list<movable_initializer_list> commands_list;
+
+enum ArgumentType
+{
+    Number_uint8,
+    Number_uint16,
+    Number_uint32,
+    Number_uint64,
+    Number_int8,
+    Number_int16,
+    Number_int32,
+    Number_int64,
+    Float,
+    Double,
+    Bool,
+    String,
+    CharString,
+    OctetString,
+    Address,
+    Complex,
+    Custom,
+    VectorBool,
+    Vector16,
+    Vector32,
+    VectorCustom,
+    VectorString, // comma separated string items
+};
+
+struct Argument
+{
+    const char * name;
+    ArgumentType type;
+    int64_t min;
+    uint64_t max;
+    void * value;
+    uint8_t flags;
+    const char * desc;
+
+    enum
+    {
+        kOptional = (1 << 0),
+        kNullable = (1 << 1),
+    };
+
+    bool isOptional() const { return flags & kOptional; }
+    bool isNullable() const { return flags & kNullable; }
+};
+
+struct ReadOnlyGlobalCommandArgument
+{
+    const char * name;
+    const char * value;
+    const char * desc;
+};
+
+class Command
+{
+public:
+    struct AddressWithInterface
+    {
+        ::chip::Inet::IPAddress address;
+        ::chip::Inet::InterfaceId interfaceId;
+    };
+
+    Command(const char * commandName, const char * helpText = nullptr) : mName(commandName), mHelpText(helpText) {}
+    virtual ~Command() {}
+
+    const char * GetName(void) const { return mName; }
+    const char * GetHelpText() const { return mHelpText; }
+    const char * GetReadOnlyGlobalCommandArgument(void) const;
+    const char * GetAttribute(void) const;
+    const char * GetEvent(void) const;
+    const char * GetArgumentName(size_t index) const;
+    const char * GetArgumentDescription(size_t index) const;
+    bool GetArgumentIsOptional(size_t index) const { return mArgs[index].isOptional(); }
+    size_t GetArgumentsCount(void) const { return mArgs.size(); }
+
+    bool InitArguments(int argc, char ** argv);
+    void AddArgument(const char * name, const char * value, const char * desc = "");
+    /**
+     * @brief
+     *   Add a char string command argument
+     *
+     * @param name  The name that will be displayed in the command help
+     * @param value A pointer to a `char *` where the argv value will be stored
+     * @param flags
+     * @param desc The description of the argument that will be displayed in the command help
+     * @returns The number of arguments currently added to the command
+     */
+    size_t AddArgument(const char * name, char ** value, const char * desc = "", uint8_t flags = 0);
+
+    /**
+     * Add an octet string command argument
+     */
+    size_t AddArgument(const char * name, chip::ByteSpan * value, const char * desc = "", uint8_t flags = 0);
+    size_t AddArgument(const char * name, chip::Span<const char> * value, const char * desc = "", uint8_t flags = 0);
+    size_t AddArgument(const char * name, AddressWithInterface * out, const char * desc = "", uint8_t flags = 0);
+    // Optional Complex arguments are not currently supported via the <chip::Optional> class.
+    // Instead, they must be explicitly specified as optional using kOptional in the flags parameter,
+    // and the base TypedComplexArgument<T> class is referenced.
+    size_t AddArgument(const char * name, ComplexArgument * value, const char * desc = "", uint8_t flags = 0);
+    size_t AddArgument(const char * name, CustomArgument * value, const char * desc = "");
+    size_t AddArgument(const char * name, int64_t min, uint64_t max, bool * out, const char * desc = "", uint8_t flags = 0)
+    {
+        return AddArgument(name, min, max, reinterpret_cast<void *>(out), Bool, desc, flags);
+    }
+    size_t AddArgument(const char * name, int64_t min, uint64_t max, int8_t * out, const char * desc = "", uint8_t flags = 0)
+    {
+        return AddArgument(name, min, max, reinterpret_cast<void *>(out), Number_int8, desc, flags);
+    }
+    size_t AddArgument(const char * name, int64_t min, uint64_t max, int16_t * out, const char * desc = "", uint8_t flags = 0)
+    {
+        return AddArgument(name, min, max, reinterpret_cast<void *>(out), Number_int16, desc, flags);
+    }
+    size_t AddArgument(const char * name, int64_t min, uint64_t max, int32_t * out, const char * desc = "", uint8_t flags = 0)
+    {
+        return AddArgument(name, min, max, reinterpret_cast<void *>(out), Number_int32, desc, flags);
+    }
+    size_t AddArgument(const char * name, int64_t min, uint64_t max, int64_t * out, const char * desc = "", uint8_t flags = 0)
+    {
+        return AddArgument(name, min, max, reinterpret_cast<void *>(out), Number_int64, desc, flags);
+    }
+    size_t AddArgument(const char * name, int64_t min, uint64_t max, uint8_t * out, const char * desc = "", uint8_t flags = 0)
+    {
+        return AddArgument(name, min, max, reinterpret_cast<void *>(out), Number_uint8, desc, flags);
+    }
+    size_t AddArgument(const char * name, int64_t min, uint64_t max, uint16_t * out, const char * desc = "", uint8_t flags = 0)
+    {
+        return AddArgument(name, min, max, reinterpret_cast<void *>(out), Number_uint16, desc, flags);
+    }
+    size_t AddArgument(const char * name, int64_t min, uint64_t max, uint32_t * out, const char * desc = "", uint8_t flags = 0)
+    {
+        return AddArgument(name, min, max, reinterpret_cast<void *>(out), Number_uint32, desc, flags);
+    }
+    size_t AddArgument(const char * name, int64_t min, uint64_t max, uint64_t * out, const char * desc = "", uint8_t flags = 0)
+    {
+        return AddArgument(name, min, max, reinterpret_cast<void *>(out), Number_uint64, desc, flags);
+    }
+
+    size_t AddArgument(const char * name, float min, float max, float * out, const char * desc = "", uint8_t flags = 0);
+    size_t AddArgument(const char * name, double min, double max, double * out, const char * desc = "", uint8_t flags = 0);
+
+    size_t AddArgument(const char * name, int64_t min, uint64_t max, std::vector<uint16_t> * value, const char * desc = "");
+    size_t AddArgument(const char * name, int64_t min, uint64_t max, std::vector<uint32_t> * value, const char * desc = "");
+    size_t AddArgument(const char * name, std::vector<CustomArgument *> * value, const char * desc = "");
+    size_t AddArgument(const char * name, int64_t min, uint64_t max, chip::Optional<std::vector<bool>> * value,
+                       const char * desc = "");
+    size_t AddArgument(const char * name, int64_t min, uint64_t max, chip::Optional<std::vector<uint32_t>> * value,
+                       const char * desc = "");
+
+    template <typename T, typename = std::enable_if_t<std::is_enum<T>::value>>
+    size_t AddArgument(const char * name, int64_t min, uint64_t max, T * out, const char * desc = "", uint8_t flags = 0)
+    {
+        return AddArgument(name, min, max, reinterpret_cast<std::underlying_type_t<T> *>(out), desc, flags);
+    }
+
+    template <typename T>
+    size_t AddArgument(const char * name, int64_t min, uint64_t max, chip::BitFlags<T> * out, const char * desc = "",
+                       uint8_t flags = 0)
+    {
+        // This is a terrible hack that relies on BitFlags only having the one
+        // mValue member.
+        return AddArgument(name, min, max, reinterpret_cast<T *>(out), desc, flags);
+    }
+
+    template <typename T>
+    size_t AddArgument(const char * name, int64_t min, uint64_t max, chip::BitMask<T> * out, const char * desc = "",
+                       uint8_t flags = 0)
+    {
+        // This is a terrible hack that relies on BitMask only having the one
+        // mValue member.
+        return AddArgument(name, min, max, reinterpret_cast<T *>(out), desc, flags);
+    }
+
+    template <typename T>
+    size_t AddArgument(const char * name, chip::Optional<T> * value, const char * desc = "")
+    {
+        return AddArgument(name, reinterpret_cast<T *>(value), desc, Argument::kOptional);
+    }
+
+    template <typename T>
+    size_t AddArgument(const char * name, int64_t min, uint64_t max, chip::Optional<T> * value, const char * desc = "")
+    {
+        return AddArgument(name, min, max, reinterpret_cast<T *>(value), desc, Argument::kOptional);
+    }
+
+    template <typename T>
+    size_t AddArgument(const char * name, chip::app::DataModel::Nullable<T> * value, const char * desc = "", uint8_t flags = 0)
+    {
+        return AddArgument(name, reinterpret_cast<T *>(value), desc, flags | Argument::kNullable);
+    }
+
+    template <typename T>
+    size_t AddArgument(const char * name, int64_t min, uint64_t max, chip::app::DataModel::Nullable<T> * value,
+                       const char * desc = "", uint8_t flags = 0)
+    {
+        return AddArgument(name, min, max, reinterpret_cast<T *>(value), desc, flags | Argument::kNullable);
+    }
+
+    size_t AddArgument(const char * name, float min, float max, chip::app::DataModel::Nullable<float> * value,
+                       const char * desc = "", uint8_t flags = 0)
+    {
+        return AddArgument(name, min, max, reinterpret_cast<float *>(value), desc, flags | Argument::kNullable);
+    }
+
+    size_t AddArgument(const char * name, double min, double max, chip::app::DataModel::Nullable<double> * value,
+                       const char * desc = "", uint8_t flags = 0)
+    {
+        return AddArgument(name, min, max, reinterpret_cast<double *>(value), desc, flags | Argument::kNullable);
+    }
+
+    size_t AddArgument(const char * name, std::vector<std::string> * value, const char * desc);
+    size_t AddArgument(const char * name, chip::Optional<std::vector<std::string>> * value, const char * desc);
+
+    void ResetArguments();
+
+    virtual CHIP_ERROR Run() = 0;
+
+    bool IsInteractive() { return mIsInteractive; }
+
+    CHIP_ERROR RunAsInteractive(const chip::Optional<char *> & interactiveStorageDirectory, bool advertiseOperational)
+    {
+        mStorageDirectory     = interactiveStorageDirectory;
+        mIsInteractive        = true;
+        mAdvertiseOperational = advertiseOperational;
+        return Run();
+    }
+
+    const chip::Optional<char *> & GetStorageDirectory() const { return mStorageDirectory; }
+
+protected:
+    // mStorageDirectory lives here so we can just set it in RunAsInteractive.
+    chip::Optional<char *> mStorageDirectory;
+
+    // mAdvertiseOperational lives here so we can just set it in
+    // RunAsInteractive; it's only used by CHIPCommand.
+    bool mAdvertiseOperational = false;
+
+private:
+    bool InitArgument(size_t argIndex, char * argValue);
+    size_t AddArgument(const char * name, int64_t min, uint64_t max, void * out, ArgumentType type, const char * desc,
+                       uint8_t flags);
+    size_t AddArgument(const char * name, int64_t min, uint64_t max, void * out, const char * desc, uint8_t flags);
+
+    /**
+     * Add the Argument to our list.  This preserves the property that all
+     * optional arguments come at the end of the list.
+     */
+    size_t AddArgumentToList(Argument && argument);
+
+    const char * mName     = nullptr;
+    const char * mHelpText = nullptr;
+    bool mIsInteractive    = false;
+
+    chip::Optional<ReadOnlyGlobalCommandArgument> mReadOnlyGlobalCommandArgument;
+    std::vector<Argument> mArgs;
+};
diff --git a/examples/fabric-admin/commands/common/Commands.cpp b/examples/fabric-admin/commands/common/Commands.cpp
new file mode 100644
index 0000000..3742978
--- /dev/null
+++ b/examples/fabric-admin/commands/common/Commands.cpp
@@ -0,0 +1,703 @@
+/*
+ *   Copyright (c) 2024 Project CHIP Authors
+ *   All rights reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+#include "Commands.h"
+
+#include "Command.h"
+
+#include <algorithm>
+#include <iomanip>
+#include <sstream>
+#include <string>
+
+#include <lib/support/Base64.h>
+#include <lib/support/CHIPMem.h>
+#include <lib/support/CodeUtils.h>
+#include <platform/CHIPDeviceConfig.h>
+#include <platform/KeyValueStoreManager.h>
+
+#include "../clusters/JsonParser.h"
+
+namespace {
+
+char kInteractiveModeName[]                         = "";
+constexpr size_t kInteractiveModeArgumentsMaxLength = 32;
+constexpr char kOptionalArgumentPrefix[]            = "--";
+constexpr char kJsonClusterKey[]                    = "cluster";
+constexpr char kJsonCommandKey[]                    = "command";
+constexpr char kJsonCommandSpecifierKey[]           = "command_specifier";
+constexpr char kJsonArgumentsKey[]                  = "arguments";
+
+#if !CHIP_DISABLE_PLATFORM_KVS
+template <typename T>
+struct HasInitWithString
+{
+    template <typename U>
+    static constexpr auto check(U *) -> typename std::is_same<decltype(std::declval<U>().Init("")), CHIP_ERROR>::type;
+
+    template <typename>
+    static constexpr std::false_type check(...);
+
+    typedef decltype(check<std::remove_reference_t<T>>(nullptr)) type;
+
+public:
+    static constexpr bool value = type::value;
+};
+
+// Template so we can do conditional enabling
+template <typename T, std::enable_if_t<HasInitWithString<T>::value, int> = 0>
+static void UseStorageDirectory(T & storageManagerImpl, const char * storageDirectory)
+{
+    std::string platformKVS = std::string(storageDirectory) + "/chip_tool_kvs";
+    storageManagerImpl.Init(platformKVS.c_str());
+}
+
+template <typename T, std::enable_if_t<!HasInitWithString<T>::value, int> = 0>
+static void UseStorageDirectory(T & storageManagerImpl, const char * storageDirectory)
+{}
+#endif // !CHIP_DISABLE_PLATFORM_KVS
+
+bool GetArgumentsFromJson(Command * command, Json::Value & value, bool optional, std::vector<std::string> & outArgs)
+{
+    auto memberNames = value.getMemberNames();
+
+    std::vector<std::string> args;
+    for (size_t i = 0; i < command->GetArgumentsCount(); i++)
+    {
+        auto argName             = command->GetArgumentName(i);
+        auto memberNamesIterator = memberNames.begin();
+        while (memberNamesIterator != memberNames.end())
+        {
+            auto memberName = *memberNamesIterator;
+            if (strcasecmp(argName, memberName.c_str()) != 0)
+            {
+                memberNamesIterator++;
+                continue;
+            }
+
+            if (command->GetArgumentIsOptional(i) != optional)
+            {
+                memberNamesIterator = memberNames.erase(memberNamesIterator);
+                continue;
+            }
+
+            if (optional)
+            {
+                args.push_back(std::string(kOptionalArgumentPrefix) + argName);
+            }
+
+            auto argValue = value[memberName].asString();
+            args.push_back(std::move(argValue));
+            memberNamesIterator = memberNames.erase(memberNamesIterator);
+            break;
+        }
+    }
+
+    if (memberNames.size())
+    {
+        auto memberName = memberNames.front();
+        ChipLogError(NotSpecified, "The argument \"\%s\" is not supported.", memberName.c_str());
+        return false;
+    }
+
+    outArgs = args;
+    return true;
+};
+
+// Check for arguments with a starting '"' but no ending '"': those
+// would indicate that people are using double-quoting, not single
+// quoting, on arguments with spaces.
+static void DetectAndLogMismatchedDoubleQuotes(int argc, char ** argv)
+{
+    for (int curArg = 0; curArg < argc; ++curArg)
+    {
+        char * arg = argv[curArg];
+        if (!arg)
+        {
+            continue;
+        }
+
+        auto len = strlen(arg);
+        if (len == 0)
+        {
+            continue;
+        }
+
+        if (arg[0] == '"' && arg[len - 1] != '"')
+        {
+            ChipLogError(NotSpecified,
+                         "Mismatched '\"' detected in argument: '%s'.  Use single quotes to delimit arguments with spaces "
+                         "in them: 'x y', not \"x y\".",
+                         arg);
+        }
+    }
+}
+
+} // namespace
+
+void Commands::Register(const char * commandSetName, commands_list commandsList, const char * helpText, bool isCluster)
+{
+    VerifyOrDieWithMsg(isCluster || helpText != nullptr, NotSpecified, "Non-cluster command sets must have help text");
+    mCommandSets[commandSetName].isCluster = isCluster;
+    mCommandSets[commandSetName].helpText  = helpText;
+    for (auto & command : commandsList)
+    {
+        mCommandSets[commandSetName].commands.push_back(std::move(command));
+    }
+}
+
+int Commands::Run(int argc, char ** argv)
+{
+    CHIP_ERROR err = CHIP_NO_ERROR;
+
+    err = chip::Platform::MemoryInit();
+    VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(Controller, "Init Memory failure: %s", chip::ErrorStr(err)));
+
+#ifdef CONFIG_USE_LOCAL_STORAGE
+    err = mStorage.Init();
+    VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(Controller, "Init Storage failure: %s", chip::ErrorStr(err)));
+
+    chip::Logging::SetLogFilter(mStorage.GetLoggingLevel());
+#endif // CONFIG_USE_LOCAL_STORAGE
+
+    err = RunCommand(argc, argv);
+    VerifyOrExit(err == CHIP_NO_ERROR, ChipLogError(NotSpecified, "Run command failure: %s", chip::ErrorStr(err)));
+
+exit:
+    return (err == CHIP_NO_ERROR) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
+
+int Commands::RunInteractive(const char * command, const chip::Optional<char *> & storageDirectory, bool advertiseOperational)
+{
+    std::vector<std::string> arguments;
+    VerifyOrReturnValue(DecodeArgumentsFromInteractiveMode(command, arguments), EXIT_FAILURE);
+
+    if (arguments.size() > (kInteractiveModeArgumentsMaxLength - 1 /* for interactive mode name */))
+    {
+        ChipLogError(NotSpecified, "Too many arguments. Ignoring.");
+        arguments.resize(kInteractiveModeArgumentsMaxLength - 1);
+    }
+
+    int argc                                        = 0;
+    char * argv[kInteractiveModeArgumentsMaxLength] = {};
+    argv[argc++]                                    = kInteractiveModeName;
+
+    std::string commandStr;
+    for (auto & arg : arguments)
+    {
+        argv[argc] = new char[arg.size() + 1];
+        strcpy(argv[argc++], arg.c_str());
+        commandStr += arg;
+        commandStr += " ";
+    }
+
+    ChipLogProgress(NotSpecified, "Command: %s", commandStr.c_str());
+    auto err = RunCommand(argc, argv, true, storageDirectory, advertiseOperational);
+
+    // Do not delete arg[0]
+    for (auto i = 1; i < argc; i++)
+    {
+        delete[] argv[i];
+    }
+
+    return (err == CHIP_NO_ERROR) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
+
+CHIP_ERROR Commands::RunCommand(int argc, char ** argv, bool interactive,
+                                const chip::Optional<char *> & interactiveStorageDirectory, bool interactiveAdvertiseOperational)
+{
+    Command * command = nullptr;
+
+    if (argc <= 1)
+    {
+        ChipLogError(NotSpecified, "Missing cluster or command set name");
+        ShowCommandSets(argv[0]);
+        return CHIP_ERROR_INVALID_ARGUMENT;
+    }
+
+    auto commandSetIter = GetCommandSet(argv[1]);
+    if (commandSetIter == mCommandSets.end())
+    {
+        ChipLogError(NotSpecified, "Unknown cluster or command set: %s", argv[1]);
+        ShowCommandSets(argv[0]);
+        return CHIP_ERROR_INVALID_ARGUMENT;
+    }
+
+    auto & commandList = commandSetIter->second.commands;
+    auto * helpText    = commandSetIter->second.helpText;
+
+    if (argc <= 2)
+    {
+        ChipLogError(NotSpecified, "Missing command name");
+        ShowCommandSet(argv[0], argv[1], commandList, helpText);
+        return CHIP_ERROR_INVALID_ARGUMENT;
+    }
+
+    bool isGlobalCommand = IsGlobalCommand(argv[2]);
+    if (!isGlobalCommand)
+    {
+        command = GetCommand(commandList, argv[2]);
+        if (command == nullptr)
+        {
+            ChipLogError(NotSpecified, "Unknown command: %s", argv[2]);
+            ShowCommandSet(argv[0], argv[1], commandList, helpText);
+            return CHIP_ERROR_INVALID_ARGUMENT;
+        }
+    }
+    else if (IsEventCommand(argv[2]))
+    {
+        if (argc <= 3)
+        {
+            ChipLogError(NotSpecified, "Missing event name");
+            ShowClusterEvents(argv[0], argv[1], argv[2], commandList);
+            return CHIP_ERROR_INVALID_ARGUMENT;
+        }
+
+        command = GetGlobalCommand(commandList, argv[2], argv[3]);
+        if (command == nullptr)
+        {
+            ChipLogError(NotSpecified, "Unknown event: %s", argv[3]);
+            ShowClusterEvents(argv[0], argv[1], argv[2], commandList);
+            return CHIP_ERROR_INVALID_ARGUMENT;
+        }
+    }
+    else
+    {
+        if (argc <= 3)
+        {
+            ChipLogError(NotSpecified, "Missing attribute name");
+            ShowClusterAttributes(argv[0], argv[1], argv[2], commandList);
+            return CHIP_ERROR_INVALID_ARGUMENT;
+        }
+
+        command = GetGlobalCommand(commandList, argv[2], argv[3]);
+        if (command == nullptr)
+        {
+            ChipLogError(NotSpecified, "Unknown attribute: %s", argv[3]);
+            ShowClusterAttributes(argv[0], argv[1], argv[2], commandList);
+            return CHIP_ERROR_INVALID_ARGUMENT;
+        }
+    }
+
+    int argumentsPosition = isGlobalCommand ? 4 : 3;
+    if (!command->InitArguments(argc - argumentsPosition, &argv[argumentsPosition]))
+    {
+        if (interactive)
+        {
+            DetectAndLogMismatchedDoubleQuotes(argc - argumentsPosition, &argv[argumentsPosition]);
+        }
+        ShowCommand(argv[0], argv[1], command);
+        return CHIP_ERROR_INVALID_ARGUMENT;
+    }
+
+    if (interactive)
+    {
+        return command->RunAsInteractive(interactiveStorageDirectory, interactiveAdvertiseOperational);
+    }
+
+    // Now that the command is initialized, get our storage from it as needed
+    // and set up our loging level.
+#ifdef CONFIG_USE_LOCAL_STORAGE
+    CHIP_ERROR err = mStorage.Init(nullptr, command->GetStorageDirectory().ValueOr(nullptr));
+    if (err != CHIP_NO_ERROR)
+    {
+        ChipLogError(Controller, "Init Storage failure: %s", chip::ErrorStr(err));
+        return err;
+    }
+
+    chip::Logging::SetLogFilter(mStorage.GetLoggingLevel());
+
+#if !CHIP_DISABLE_PLATFORM_KVS
+    UseStorageDirectory(chip::DeviceLayer::PersistedStorage::KeyValueStoreMgrImpl(), mStorage.GetDirectory());
+#endif // !CHIP_DISABLE_PLATFORM_KVS
+
+#endif // CONFIG_USE_LOCAL_STORAGE
+
+    return command->Run();
+}
+
+Commands::CommandSetMap::iterator Commands::GetCommandSet(std::string commandSetName)
+{
+    for (auto & commandSet : mCommandSets)
+    {
+        std::string key(commandSet.first);
+        std::transform(key.begin(), key.end(), key.begin(), ::tolower);
+        if (key.compare(commandSetName) == 0)
+        {
+            return mCommandSets.find(commandSet.first);
+        }
+    }
+
+    return mCommandSets.end();
+}
+
+Command * Commands::GetCommand(CommandsVector & commands, std::string commandName)
+{
+    for (auto & command : commands)
+    {
+        if (commandName.compare(command->GetName()) == 0)
+        {
+            return command.get();
+        }
+    }
+
+    return nullptr;
+}
+
+Command * Commands::GetGlobalCommand(CommandsVector & commands, std::string commandName, std::string attributeName)
+{
+    for (auto & command : commands)
+    {
+        if (commandName.compare(command->GetName()) == 0 && attributeName.compare(command->GetAttribute()) == 0)
+        {
+            return command.get();
+        }
+    }
+
+    return nullptr;
+}
+
+bool Commands::IsAttributeCommand(std::string commandName) const
+{
+    return commandName.compare("read") == 0 || commandName.compare("write") == 0 || commandName.compare("force-write") == 0 ||
+        commandName.compare("subscribe") == 0;
+}
+
+bool Commands::IsEventCommand(std::string commandName) const
+{
+    return commandName.compare("read-event") == 0 || commandName.compare("subscribe-event") == 0;
+}
+
+bool Commands::IsGlobalCommand(std::string commandName) const
+{
+    return IsAttributeCommand(commandName) || IsEventCommand(commandName);
+}
+
+void Commands::ShowCommandSetOverview(std::string commandSetName, const CommandSet & commandSet)
+{
+    std::transform(commandSetName.begin(), commandSetName.end(), commandSetName.begin(),
+                   [](unsigned char c) { return std::tolower(c); });
+    fprintf(stderr, "  | * %-82s|\n", commandSetName.c_str());
+    ShowHelpText(commandSet.helpText);
+}
+
+void Commands::ShowCommandSets(std::string executable)
+{
+    fprintf(stderr, "Usage:\n");
+    fprintf(stderr, "  %s cluster_name command_name [param1 param2 ...]\n", executable.c_str());
+    fprintf(stderr, "or:\n");
+    fprintf(stderr, "  %s command_set_name command_name [param1 param2 ...]\n", executable.c_str());
+    fprintf(stderr, "\n");
+    // Table of clusters
+    fprintf(stderr, "  +-------------------------------------------------------------------------------------+\n");
+    fprintf(stderr, "  | Clusters:                                                                           |\n");
+    fprintf(stderr, "  +-------------------------------------------------------------------------------------+\n");
+    for (auto & commandSet : mCommandSets)
+    {
+        if (commandSet.second.isCluster)
+        {
+            ShowCommandSetOverview(commandSet.first, commandSet.second);
+        }
+    }
+    fprintf(stderr, "  +-------------------------------------------------------------------------------------+\n");
+    fprintf(stderr, "\n");
+
+    // Table of command sets
+    fprintf(stderr, "  +-------------------------------------------------------------------------------------+\n");
+    fprintf(stderr, "  | Command sets:                                                                       |\n");
+    fprintf(stderr, "  +-------------------------------------------------------------------------------------+\n");
+    for (auto & commandSet : mCommandSets)
+    {
+        if (!commandSet.second.isCluster)
+        {
+            ShowCommandSetOverview(commandSet.first, commandSet.second);
+        }
+    }
+    fprintf(stderr, "  +-------------------------------------------------------------------------------------+\n");
+}
+
+void Commands::ShowCommandSet(std::string executable, std::string commandSetName, CommandsVector & commands, const char * helpText)
+{
+    fprintf(stderr, "Usage:\n");
+    fprintf(stderr, "  %s %s command_name [param1 param2 ...]\n", executable.c_str(), commandSetName.c_str());
+
+    if (helpText)
+    {
+        fprintf(stderr, "\n%s\n", helpText);
+    }
+
+    fprintf(stderr, "\n");
+    fprintf(stderr, "  +-------------------------------------------------------------------------------------+\n");
+    fprintf(stderr, "  | Commands:                                                                           |\n");
+    fprintf(stderr, "  +-------------------------------------------------------------------------------------+\n");
+    bool readCommand           = false;
+    bool writeCommand          = false;
+    bool writeOverrideCommand  = false;
+    bool subscribeCommand      = false;
+    bool readEventCommand      = false;
+    bool subscribeEventCommand = false;
+    for (auto & command : commands)
+    {
+        bool shouldPrint = true;
+
+        if (IsGlobalCommand(command->GetName()))
+        {
+            if (strcmp(command->GetName(), "read") == 0 && !readCommand)
+            {
+                readCommand = true;
+            }
+            else if (strcmp(command->GetName(), "write") == 0 && !writeCommand)
+            {
+                writeCommand = true;
+            }
+            else if (strcmp(command->GetName(), "force-write") == 0 && !writeOverrideCommand)
+            {
+                writeOverrideCommand = true;
+            }
+            else if (strcmp(command->GetName(), "subscribe") == 0 && !subscribeCommand)
+            {
+                subscribeCommand = true;
+            }
+            else if (strcmp(command->GetName(), "read-event") == 0 && !readEventCommand)
+            {
+                readEventCommand = true;
+            }
+            else if (strcmp(command->GetName(), "subscribe-event") == 0 && !subscribeEventCommand)
+            {
+                subscribeEventCommand = true;
+            }
+            else
+            {
+                shouldPrint = false;
+            }
+        }
+
+        if (shouldPrint)
+        {
+            fprintf(stderr, "  | * %-82s|\n", command->GetName());
+            ShowHelpText(command->GetHelpText());
+        }
+    }
+    fprintf(stderr, "  +-------------------------------------------------------------------------------------+\n");
+}
+
+void Commands::ShowClusterAttributes(std::string executable, std::string clusterName, std::string commandName,
+                                     CommandsVector & commands)
+{
+    fprintf(stderr, "Usage:\n");
+    fprintf(stderr, "  %s %s %s attribute-name [param1 param2 ...]\n", executable.c_str(), clusterName.c_str(),
+            commandName.c_str());
+    fprintf(stderr, "\n");
+    fprintf(stderr, "  +-------------------------------------------------------------------------------------+\n");
+    fprintf(stderr, "  | Attributes:                                                                         |\n");
+    fprintf(stderr, "  +-------------------------------------------------------------------------------------+\n");
+    for (auto & command : commands)
+    {
+        if (commandName.compare(command->GetName()) == 0)
+        {
+            fprintf(stderr, "  | * %-82s|\n", command->GetAttribute());
+        }
+    }
+    fprintf(stderr, "  +-------------------------------------------------------------------------------------+\n");
+}
+
+void Commands::ShowClusterEvents(std::string executable, std::string clusterName, std::string commandName,
+                                 CommandsVector & commands)
+{
+    fprintf(stderr, "Usage:\n");
+    fprintf(stderr, "  %s %s %s event-name [param1 param2 ...]\n", executable.c_str(), clusterName.c_str(), commandName.c_str());
+    fprintf(stderr, "\n");
+    fprintf(stderr, "  +-------------------------------------------------------------------------------------+\n");
+    fprintf(stderr, "  | Events:                                                                             |\n");
+    fprintf(stderr, "  +-------------------------------------------------------------------------------------+\n");
+    for (auto & command : commands)
+    {
+        if (commandName.compare(command->GetName()) == 0)
+        {
+            fprintf(stderr, "  | * %-82s|\n", command->GetEvent());
+        }
+    }
+    fprintf(stderr, "  +-------------------------------------------------------------------------------------+\n");
+}
+
+void Commands::ShowCommand(std::string executable, std::string clusterName, Command * command)
+{
+    fprintf(stderr, "Usage:\n");
+
+    std::string arguments;
+    std::string description;
+    arguments += command->GetName();
+
+    if (command->GetReadOnlyGlobalCommandArgument())
+    {
+        arguments += ' ';
+        arguments += command->GetReadOnlyGlobalCommandArgument();
+    }
+
+    size_t argumentsCount = command->GetArgumentsCount();
+    for (size_t i = 0; i < argumentsCount; i++)
+    {
+        std::string arg;
+        bool isOptional = command->GetArgumentIsOptional(i);
+        if (isOptional)
+        {
+            arg += "[--";
+        }
+        arg += command->GetArgumentName(i);
+        if (isOptional)
+        {
+            arg += "]";
+        }
+        arguments += " ";
+        arguments += arg;
+
+        const char * argDescription = command->GetArgumentDescription(i);
+        if ((argDescription != nullptr) && (strlen(argDescription) > 0))
+        {
+            description += "\n";
+            description += arg;
+            description += ":\n  ";
+            description += argDescription;
+            description += "\n";
+        }
+    }
+    fprintf(stderr, "  %s %s %s\n", executable.c_str(), clusterName.c_str(), arguments.c_str());
+
+    if (command->GetHelpText())
+    {
+        fprintf(stderr, "\n%s\n", command->GetHelpText());
+    }
+
+    if (description.size() > 0)
+    {
+        fprintf(stderr, "%s\n", description.c_str());
+    }
+}
+
+bool Commands::DecodeArgumentsFromInteractiveMode(const char * command, std::vector<std::string> & args)
+{
+    // Remote clients may not know the ordering of arguments, so instead of a strict ordering arguments can
+    // be passed in as a json payload encoded in base64 and are reordered on the fly.
+    return IsJsonString(command) ? DecodeArgumentsFromBase64EncodedJson(command, args)
+                                 : DecodeArgumentsFromStringStream(command, args);
+}
+
+bool Commands::DecodeArgumentsFromBase64EncodedJson(const char * json, std::vector<std::string> & args)
+{
+    Json::Value jsonValue;
+    bool parsed = JsonParser::ParseCustomArgument(json, json + kJsonStringPrefixLen, jsonValue);
+    VerifyOrReturnValue(parsed, false, ChipLogError(NotSpecified, "Error while parsing json."));
+    VerifyOrReturnValue(jsonValue.isObject(), false, ChipLogError(NotSpecified, "Unexpected json type."));
+    VerifyOrReturnValue(jsonValue.isMember(kJsonClusterKey), false,
+                        ChipLogError(NotSpecified, "'%s' key not found in json.", kJsonClusterKey));
+    VerifyOrReturnValue(jsonValue.isMember(kJsonCommandKey), false,
+                        ChipLogError(NotSpecified, "'%s' key not found in json.", kJsonCommandKey));
+    VerifyOrReturnValue(jsonValue.isMember(kJsonArgumentsKey), false,
+                        ChipLogError(NotSpecified, "'%s' key not found in json.", kJsonArgumentsKey));
+    VerifyOrReturnValue(IsBase64String(jsonValue[kJsonArgumentsKey].asString().c_str()), false,
+                        ChipLogError(NotSpecified, "'arguments' is not a base64 string."));
+
+    auto clusterName = jsonValue[kJsonClusterKey].asString();
+    auto commandName = jsonValue[kJsonCommandKey].asString();
+    auto arguments   = jsonValue[kJsonArgumentsKey].asString();
+
+    auto clusterIter = GetCommandSet(clusterName);
+    VerifyOrReturnValue(clusterIter != mCommandSets.end(), false,
+                        ChipLogError(NotSpecified, "Cluster '%s' is not supported.", clusterName.c_str()));
+
+    auto & commandList = clusterIter->second.commands;
+
+    auto command = GetCommand(commandList, commandName);
+
+    if (jsonValue.isMember(kJsonCommandSpecifierKey) && IsGlobalCommand(commandName))
+    {
+        auto commandSpecifierName = jsonValue[kJsonCommandSpecifierKey].asString();
+        command                   = GetGlobalCommand(commandList, commandName, commandSpecifierName);
+    }
+    VerifyOrReturnValue(nullptr != command, false, ChipLogError(NotSpecified, "Unknown command."));
+
+    auto encodedData = arguments.c_str();
+    encodedData += kBase64StringPrefixLen;
+
+    size_t encodedDataSize        = strlen(encodedData);
+    size_t expectedMaxDecodedSize = BASE64_MAX_DECODED_LEN(encodedDataSize);
+
+    chip::Platform::ScopedMemoryBuffer<uint8_t> decodedData;
+    VerifyOrReturnValue(decodedData.Calloc(expectedMaxDecodedSize + 1 /* for null */), false);
+
+    size_t decodedDataSize = chip::Base64Decode(encodedData, static_cast<uint16_t>(encodedDataSize), decodedData.Get());
+    VerifyOrReturnValue(decodedDataSize != 0, false, ChipLogError(NotSpecified, "Error while decoding base64 data."));
+
+    decodedData.Get()[decodedDataSize] = '\0';
+
+    Json::Value jsonArguments;
+    bool parsedArguments = JsonParser::ParseCustomArgument(encodedData, chip::Uint8::to_char(decodedData.Get()), jsonArguments);
+    VerifyOrReturnValue(parsedArguments, false, ChipLogError(NotSpecified, "Error while parsing json."));
+    VerifyOrReturnValue(jsonArguments.isObject(), false, ChipLogError(NotSpecified, "Unexpected json type, expects and object."));
+
+    std::vector<std::string> mandatoryArguments;
+    std::vector<std::string> optionalArguments;
+    VerifyOrReturnValue(GetArgumentsFromJson(command, jsonArguments, false /* addOptional */, mandatoryArguments), false);
+    VerifyOrReturnValue(GetArgumentsFromJson(command, jsonArguments, true /* addOptional */, optionalArguments), false);
+
+    args.push_back(std::move(clusterName));
+    args.push_back(std::move(commandName));
+    if (jsonValue.isMember(kJsonCommandSpecifierKey))
+    {
+        auto commandSpecifierName = jsonValue[kJsonCommandSpecifierKey].asString();
+        args.push_back(std::move(commandSpecifierName));
+    }
+    args.insert(args.end(), mandatoryArguments.begin(), mandatoryArguments.end());
+    args.insert(args.end(), optionalArguments.begin(), optionalArguments.end());
+
+    return true;
+}
+
+bool Commands::DecodeArgumentsFromStringStream(const char * command, std::vector<std::string> & args)
+{
+    std::string arg;
+    std::stringstream ss(command);
+    while (ss >> std::quoted(arg, '\''))
+    {
+        args.push_back(std::move(arg));
+    }
+
+    return true;
+}
+
+void Commands::ShowHelpText(const char * helpText)
+{
+    if (helpText == nullptr)
+    {
+        return;
+    }
+
+    // We leave 82 chars for command/cluster names.  The help text starts
+    // two chars further to the right, so there are 80 chars left
+    // for it.
+    if (strlen(helpText) > 80)
+    {
+        // Add "..." at the end to indicate truncation, and only
+        // show the first 77 chars, since that's what will fit.
+        fprintf(stderr, "  |   - %.77s...|\n", helpText);
+    }
+    else
+    {
+        fprintf(stderr, "  |   - %-80s|\n", helpText);
+    }
+}
diff --git a/examples/fabric-admin/commands/common/Commands.h b/examples/fabric-admin/commands/common/Commands.h
new file mode 100644
index 0000000..8638ede
--- /dev/null
+++ b/examples/fabric-admin/commands/common/Commands.h
@@ -0,0 +1,90 @@
+/*
+ *   Copyright (c) 2024 Project CHIP Authors
+ *   All rights reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+#pragma once
+
+#ifdef CONFIG_USE_LOCAL_STORAGE
+#include <controller/ExamplePersistentStorage.h>
+#endif // CONFIG_USE_LOCAL_STORAGE
+
+#include "Command.h"
+#include <map>
+#include <string>
+
+class Commands
+{
+public:
+    using CommandsVector = ::std::vector<std::unique_ptr<Command>>;
+
+    void RegisterCluster(const char * clusterName, commands_list commandsList)
+    {
+        Register(clusterName, commandsList, nullptr, true);
+    }
+    // Command sets represent fabric-admin functionality that is not actually
+    // XML-defined clusters.  All command sets should have help text explaining
+    // what sort of commands one should expect to find in the set.
+    void RegisterCommandSet(const char * commandSetName, commands_list commandsList, const char * helpText)
+    {
+        Register(commandSetName, commandsList, helpText, false);
+    }
+    int Run(int argc, char ** argv);
+    int RunInteractive(const char * command, const chip::Optional<char *> & storageDirectory, bool advertiseOperational);
+
+private:
+    struct CommandSet
+    {
+        CommandsVector commands;
+        bool isCluster        = false;
+        const char * helpText = nullptr;
+    };
+    // The tuple contains the commands, whether it's a synthetic cluster, and
+    // the help text for the cluster (which may be null).
+    using CommandSetMap = std::map<std::string, CommandSet>;
+
+    CHIP_ERROR RunCommand(int argc, char ** argv, bool interactive = false,
+                          const chip::Optional<char *> & interactiveStorageDirectory = chip::NullOptional,
+                          bool interactiveAdvertiseOperational                       = false);
+
+    CommandSetMap::iterator GetCommandSet(std::string commandSetName);
+    Command * GetCommand(CommandsVector & commands, std::string commandName);
+    Command * GetGlobalCommand(CommandsVector & commands, std::string commandName, std::string attributeName);
+    bool IsAttributeCommand(std::string commandName) const;
+    bool IsEventCommand(std::string commandName) const;
+    bool IsGlobalCommand(std::string commandName) const;
+
+    void ShowCommandSets(std::string executable);
+    static void ShowCommandSetOverview(std::string commandSetName, const CommandSet & commandSet);
+    void ShowCommandSet(std::string executable, std::string commandSetName, CommandsVector & commands, const char * helpText);
+    void ShowClusterAttributes(std::string executable, std::string clusterName, std::string commandName, CommandsVector & commands);
+    void ShowClusterEvents(std::string executable, std::string clusterName, std::string commandName, CommandsVector & commands);
+    void ShowCommand(std::string executable, std::string clusterName, Command * command);
+
+    bool DecodeArgumentsFromInteractiveMode(const char * command, std::vector<std::string> & args);
+    bool DecodeArgumentsFromBase64EncodedJson(const char * encodedData, std::vector<std::string> & args);
+    bool DecodeArgumentsFromStringStream(const char * command, std::vector<std::string> & args);
+
+    // helpText may be null, in which case it's not shown.
+    static void ShowHelpText(const char * helpText);
+
+    void Register(const char * commandSetName, commands_list commandsList, const char * helpText, bool isCluster);
+
+    CommandSetMap mCommandSets;
+#ifdef CONFIG_USE_LOCAL_STORAGE
+    PersistentStorage mStorage;
+#endif // CONFIG_USE_LOCAL_STORAGE
+};
diff --git a/examples/fabric-admin/commands/common/CredentialIssuerCommands.h b/examples/fabric-admin/commands/common/CredentialIssuerCommands.h
new file mode 100644
index 0000000..c36948f
--- /dev/null
+++ b/examples/fabric-admin/commands/common/CredentialIssuerCommands.h
@@ -0,0 +1,117 @@
+/*
+ *   Copyright (c) 2024 Project CHIP Authors
+ *   All rights reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+#pragma once
+
+#include <app/util/basic-types.h>
+#include <credentials/attestation_verifier/DeviceAttestationVerifier.h>
+#include <lib/core/CASEAuthTag.h>
+#include <lib/core/CHIPCore.h>
+#include <lib/core/CHIPPersistentStorageDelegate.h>
+#include <vector>
+
+namespace chip {
+namespace Controller {
+struct SetupParams;
+class OperationalCredentialsDelegate;
+} // namespace Controller
+} // namespace chip
+
+class CredentialIssuerCommands
+{
+public:
+    virtual ~CredentialIssuerCommands() {}
+
+    /**
+     * @brief
+     *   This function is used to initialize the Credentials Issuer, if needed.
+     *
+     * @param[in] storage A reference to the storage, where the Credentials Issuer can optionally use to access the keypair in
+     *                    storage.
+     *
+     * @return CHIP_ERROR CHIP_NO_ERROR on success, or corresponding error code.
+     */
+    virtual CHIP_ERROR InitializeCredentialsIssuer(chip::PersistentStorageDelegate & storage) = 0;
+
+    /**
+     * @brief
+     *   This function is used to setup Device Attestation Singletons and intialize Setup/Commissioning Parameters with a custom
+     *   Device Attestation Verifier object.
+     *
+     * @param[in] setupParams A reference to the Setup/Commissioning Parameters, to be initialized with custom Device Attestation
+     *                        Verifier.
+     * @param[in] trustStore  A pointer to the PAA trust store to use to find valid PAA roots.
+     *
+     * @return CHIP_ERROR CHIP_NO_ERROR on success, or corresponding error code.
+     */
+    virtual CHIP_ERROR SetupDeviceAttestation(chip::Controller::SetupParams & setupParams,
+                                              const chip::Credentials::AttestationTrustStore * trustStore) = 0;
+
+    /**
+     * @brief Add a list of additional non-default CD verifying keys (by certificate)
+     *
+     * Must be called AFTER SetupDeviceAttestation.
+     *
+     * @param additionalCdCerts - vector of X.509 DER verifying cert bodies
+     * @return CHIP_NO_ERROR on succes, another CHIP_ERROR on internal failures.
+     */
+    virtual CHIP_ERROR AddAdditionalCDVerifyingCerts(const std::vector<std::vector<uint8_t>> & additionalCdCerts) = 0;
+
+    virtual chip::Controller::OperationalCredentialsDelegate * GetCredentialIssuer() = 0;
+
+    virtual void SetCredentialIssuerCATValues(chip::CATValues cats) = 0;
+
+    /**
+     * @brief
+     *   This function is used to Generate NOC Chain for the Controller/Commissioner. Parameters follow the example implementation,
+     *   so some parameters may not translate to the real remote Credentials Issuer policy.
+     *
+     * @param[in] nodeId   The desired NodeId for the generated NOC Chain - May be optional/unused in some implementations.
+     * @param[in] fabricId The desired FabricId for the generated NOC Chain - May be optional/unused in some implementations.
+     * @param[in] cats     The desired CATs for the generated NOC Chain - May be optional/unused in some implementations.
+     * @param[in] keypair  The desired Keypair for the generated NOC Chain - May be optional/unused in some implementations.
+     * @param[in,out] rcac  Buffer to hold the Root Certificate of the generated NOC Chain.
+     * @param[in,out] icac  Buffer to hold the Intermediate Certificate of the generated NOC Chain.
+     * @param[in,out] noc   Buffer to hold the Leaf Certificate of the generated NOC Chain.
+     *
+     * @return CHIP_ERROR CHIP_NO_ERROR on success, or corresponding error code.
+     */
+    virtual CHIP_ERROR GenerateControllerNOCChain(chip::NodeId nodeId, chip::FabricId fabricId, const chip::CATValues & cats,
+                                                  chip::Crypto::P256Keypair & keypair, chip::MutableByteSpan & rcac,
+                                                  chip::MutableByteSpan & icac, chip::MutableByteSpan & noc) = 0;
+
+    // All options must start false
+    enum CredentialIssuerOptions : uint8_t
+    {
+        kMaximizeCertificateSizes = 0, // If set, certificate chains will be maximized for testing via padding
+        kAllowTestCdSigningKey    = 1, // If set, allow development/test SDK CD verifying key to be used
+    };
+
+    virtual void SetCredentialIssuerOption(CredentialIssuerOptions option, bool isEnabled)
+    {
+        // Do nothing
+        (void) option;
+        (void) isEnabled;
+    }
+
+    virtual bool GetCredentialIssuerOption(CredentialIssuerOptions option)
+    {
+        // All options always start false
+        return false;
+    }
+};
diff --git a/examples/fabric-admin/commands/common/CustomStringPrefix.h b/examples/fabric-admin/commands/common/CustomStringPrefix.h
new file mode 100644
index 0000000..be84429
--- /dev/null
+++ b/examples/fabric-admin/commands/common/CustomStringPrefix.h
@@ -0,0 +1,55 @@
+/*
+ *   Copyright (c) 2024 Project CHIP Authors
+ *   All rights reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+#pragma once
+
+#include <string.h>
+
+#include <lib/support/CodeUtils.h>
+
+static constexpr char kJsonStringPrefix[]    = "json:";
+inline constexpr size_t kJsonStringPrefixLen = ArraySize(kJsonStringPrefix) - 1; // Don't count the null
+
+static constexpr char kBase64StringPrefix[]    = "base64:";
+inline constexpr size_t kBase64StringPrefixLen = ArraySize(kBase64StringPrefix) - 1; // Don't count the null
+
+static constexpr char kHexStringPrefix[]    = "hex:";
+inline constexpr size_t kHexStringPrefixLen = ArraySize(kHexStringPrefix) - 1; // Don't count the null
+
+static constexpr char kStrStringPrefix[]    = "str:";
+inline constexpr size_t kStrStringPrefixLen = ArraySize(kStrStringPrefix) - 1; // Don't count the null
+
+inline bool IsJsonString(const char * str)
+{
+    return strncmp(str, kJsonStringPrefix, kJsonStringPrefixLen) == 0;
+}
+
+inline bool IsBase64String(const char * str)
+{
+    return strncmp(str, kBase64StringPrefix, kBase64StringPrefixLen) == 0;
+}
+
+inline bool IsHexString(const char * str)
+{
+    return strncmp(str, kHexStringPrefix, kHexStringPrefixLen) == 0;
+}
+
+inline bool IsStrString(const char * str)
+{
+    return strncmp(str, kStrStringPrefix, kStrStringPrefixLen) == 0;
+}
diff --git a/examples/fabric-admin/commands/common/DeviceScanner.cpp b/examples/fabric-admin/commands/common/DeviceScanner.cpp
new file mode 100644
index 0000000..e49eb85
--- /dev/null
+++ b/examples/fabric-admin/commands/common/DeviceScanner.cpp
@@ -0,0 +1,245 @@
+/*
+ *   Copyright (c) 2024 Project CHIP Authors
+ *   All rights reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+#include "DeviceScanner.h"
+
+using namespace chip;
+using namespace chip::Dnssd;
+
+#if CONFIG_NETWORK_LAYER_BLE
+using namespace chip::Ble;
+constexpr char kBleKey[] = "BLE";
+#endif // CONFIG_NETWORK_LAYER_BLE
+
+CHIP_ERROR DeviceScanner::Start()
+{
+    mDiscoveredResults.clear();
+
+#if CONFIG_NETWORK_LAYER_BLE
+    ReturnErrorOnFailure(DeviceLayer::PlatformMgrImpl().StartBleScan(this));
+#endif // CONFIG_NETWORK_LAYER_BLE
+
+    ReturnErrorOnFailure(chip::Dnssd::Resolver::Instance().Init(DeviceLayer::UDPEndPointManager()));
+
+    char serviceName[kMaxCommissionableServiceNameSize];
+    auto filter = DiscoveryFilterType::kNone;
+    ReturnErrorOnFailure(MakeServiceTypeName(serviceName, sizeof(serviceName), filter, DiscoveryType::kCommissionableNode));
+
+    return ChipDnssdBrowse(serviceName, DnssdServiceProtocol::kDnssdProtocolUdp, Inet::IPAddressType::kAny,
+                           Inet::InterfaceId::Null(), this);
+}
+
+CHIP_ERROR DeviceScanner::Stop()
+{
+#if CONFIG_NETWORK_LAYER_BLE
+    ReturnErrorOnFailure(DeviceLayer::PlatformMgrImpl().StopBleScan());
+#endif // CONFIG_NETWORK_LAYER_BLE
+
+    return ChipDnssdStopBrowse(this);
+}
+
+void DeviceScanner::OnNodeDiscovered(const DiscoveredNodeData & nodeData)
+{
+    VerifyOrReturn(nodeData.Is<CommissionNodeData>());
+    auto & commissionData = nodeData.Get<CommissionNodeData>();
+
+    auto discriminator = commissionData.longDiscriminator;
+    auto vendorId      = static_cast<VendorId>(commissionData.vendorId);
+    auto productId     = commissionData.productId;
+
+    ChipLogProgress(NotSpecified, "OnNodeDiscovered (MDNS): discriminator: %u, vendorId: %u, productId: %u", discriminator,
+                    vendorId, productId);
+
+    const CommonResolutionData & resolutionData = commissionData;
+
+    auto & instanceData  = mDiscoveredResults[commissionData.instanceName];
+    auto & interfaceData = instanceData[resolutionData.interfaceId.GetPlatformInterface()];
+
+    for (size_t i = 0; i < resolutionData.numIPs; i++)
+    {
+        auto params                = Controller::SetUpCodePairerParameters(resolutionData, i);
+        DeviceScannerResult result = { params, vendorId, productId, discriminator, chip::MakeOptional(resolutionData) };
+        interfaceData.push_back(result);
+    }
+
+    commissionData.LogDetail();
+}
+
+void DeviceScanner::OnBrowseAdd(chip::Dnssd::DnssdService service)
+{
+    ChipLogProgress(NotSpecified, "OnBrowseAdd: %s", service.mName);
+    LogErrorOnFailure(ChipDnssdResolve(&service, service.mInterface, this));
+
+    auto & instanceData  = mDiscoveredResults[service.mName];
+    auto & interfaceData = instanceData[service.mInterface.GetPlatformInterface()];
+    (void) interfaceData;
+}
+
+void DeviceScanner::OnBrowseRemove(chip::Dnssd::DnssdService service)
+{
+    ChipLogProgress(NotSpecified, "OnBrowseRemove: %s", service.mName);
+    auto & instanceData  = mDiscoveredResults[service.mName];
+    auto & interfaceData = instanceData[service.mInterface.GetPlatformInterface()];
+
+    // Check if the interface data has been resolved already, otherwise, just inform the
+    // back end that we may not need it anymore.
+    if (interfaceData.size() == 0)
+    {
+        ChipDnssdResolveNoLongerNeeded(service.mName);
+    }
+
+    // Delete the interface placeholder.
+    instanceData.erase(service.mInterface.GetPlatformInterface());
+
+    // If there is nothing else to resolve for the given instance name, just remove it
+    // too.
+    if (instanceData.size() == 0)
+    {
+        mDiscoveredResults.erase(service.mName);
+    }
+}
+
+void DeviceScanner::OnBrowseStop(CHIP_ERROR error)
+{
+    ChipLogProgress(NotSpecified, "OnBrowseStop: %" CHIP_ERROR_FORMAT, error.Format());
+
+    for (auto & instance : mDiscoveredResults)
+    {
+        for (auto & interface : instance.second)
+        {
+            if (interface.second.size() == 0)
+            {
+                ChipDnssdResolveNoLongerNeeded(instance.first.c_str());
+            }
+        }
+    }
+}
+
+#if CONFIG_NETWORK_LAYER_BLE
+void DeviceScanner::OnBleScanAdd(BLE_CONNECTION_OBJECT connObj, const ChipBLEDeviceIdentificationInfo & info)
+{
+    auto discriminator = info.GetDeviceDiscriminator();
+    auto vendorId      = static_cast<VendorId>(info.GetVendorId());
+    auto productId     = info.GetProductId();
+
+    ChipLogProgress(NotSpecified, "OnBleScanAdd (BLE): %p, discriminator: %u, vendorId: %u, productId: %u", connObj, discriminator,
+                    vendorId, productId);
+
+    auto params                = Controller::SetUpCodePairerParameters(connObj, false /* connected */);
+    DeviceScannerResult result = { params, vendorId, productId, discriminator };
+
+    auto & instanceData  = mDiscoveredResults[kBleKey];
+    auto & interfaceData = instanceData[chip::Inet::InterfaceId::Null().GetPlatformInterface()];
+    interfaceData.push_back(result);
+}
+
+void DeviceScanner::OnBleScanRemove(BLE_CONNECTION_OBJECT connObj)
+{
+    ChipLogProgress(NotSpecified, "OnBleScanRemove: %p", connObj);
+
+    auto & instanceData  = mDiscoveredResults[kBleKey];
+    auto & interfaceData = instanceData[chip::Inet::InterfaceId::Null().GetPlatformInterface()];
+
+    interfaceData.erase(std::remove_if(interfaceData.begin(), interfaceData.end(),
+                                       [connObj](const DeviceScannerResult & result) {
+                                           return result.mParams.HasDiscoveredObject() &&
+                                               result.mParams.GetDiscoveredObject() == connObj;
+                                       }),
+                        interfaceData.end());
+
+    if (interfaceData.size() == 0)
+    {
+        instanceData.clear();
+        mDiscoveredResults.erase(kBleKey);
+    }
+}
+#endif // CONFIG_NETWORK_LAYER_BLE
+
+CHIP_ERROR DeviceScanner::Get(uint16_t index, RendezvousParameters & params)
+{
+    uint16_t currentIndex = 0;
+    for (auto & instance : mDiscoveredResults)
+    {
+        for (auto & interface : instance.second)
+        {
+            for (auto & result : interface.second)
+            {
+                if (currentIndex == index)
+                {
+                    params = result.mParams;
+                    return CHIP_NO_ERROR;
+                }
+                currentIndex++;
+            }
+        }
+    }
+
+    return CHIP_ERROR_NOT_FOUND;
+}
+
+CHIP_ERROR DeviceScanner::Get(uint16_t index, Dnssd::CommonResolutionData & resolutionData)
+{
+    uint16_t currentIndex = 0;
+    for (auto & instance : mDiscoveredResults)
+    {
+        for (auto & interface : instance.second)
+        {
+            for (auto & result : interface.second)
+            {
+                if (currentIndex == index && result.mResolutionData.HasValue())
+                {
+                    resolutionData = result.mResolutionData.Value();
+                    return CHIP_NO_ERROR;
+                }
+                currentIndex++;
+            }
+        }
+    }
+
+    return CHIP_ERROR_NOT_FOUND;
+}
+
+void DeviceScanner::Log() const
+{
+    auto resultsCount = mDiscoveredResults.size();
+    VerifyOrReturn(resultsCount > 0, ChipLogProgress(NotSpecified, "No device discovered."));
+
+    [[maybe_unused]] uint16_t index = 0;
+    for (auto & instance : mDiscoveredResults)
+    {
+        ChipLogProgress(NotSpecified, "Instance Name: %s ", instance.first.c_str());
+        for (auto & interface : instance.second)
+        {
+            for (auto & result : interface.second)
+            {
+                char addr[Transport::PeerAddress::kMaxToStringSize];
+                result.mParams.GetPeerAddress().ToString(addr);
+
+                ChipLogProgress(NotSpecified, "\t %u - Discriminator: %u - Vendor: %u - Product: %u - %s", index,
+                                result.mDiscriminator, result.mVendorId, result.mProductId, addr);
+                index++;
+            }
+        }
+    }
+}
+
+DeviceScanner & GetDeviceScanner()
+{
+    static DeviceScanner scanner;
+    return scanner;
+}
diff --git a/examples/fabric-admin/commands/common/DeviceScanner.h b/examples/fabric-admin/commands/common/DeviceScanner.h
new file mode 100644
index 0000000..c3e81a5
--- /dev/null
+++ b/examples/fabric-admin/commands/common/DeviceScanner.h
@@ -0,0 +1,80 @@
+/*
+ *   Copyright (c) 2024 Project CHIP Authors
+ *   All rights reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+#pragma once
+
+#include <platform/CHIPDeviceConfig.h>
+
+#if CHIP_DEVICE_LAYER_TARGET_DARWIN
+
+#include <controller/CHIPDeviceController.h>
+#include <lib/dnssd/platform/Dnssd.h>
+
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+#if CONFIG_NETWORK_LAYER_BLE
+#include <platform/Darwin/BleScannerDelegate.h>
+#endif // CONFIG_NETWORK_LAYER_BLE
+
+struct DeviceScannerResult
+{
+    chip::Controller::SetUpCodePairerParameters mParams;
+    chip::VendorId mVendorId;
+    uint16_t mProductId;
+    uint16_t mDiscriminator;
+    chip::Optional<chip::Dnssd::CommonResolutionData> mResolutionData;
+};
+
+class DeviceScanner : public chip::Dnssd::DiscoverNodeDelegate,
+                      public chip::Dnssd::DnssdBrowseDelegate
+#if CONFIG_NETWORK_LAYER_BLE
+    ,
+                      public chip::DeviceLayer::BleScannerDelegate
+#endif // CONFIG_NETWORK_LAYER_BLE
+{
+public:
+    CHIP_ERROR Start();
+    CHIP_ERROR Stop();
+    CHIP_ERROR Get(uint16_t index, chip::RendezvousParameters & params);
+    CHIP_ERROR Get(uint16_t index, chip::Dnssd::CommonResolutionData & resolutionData);
+    void Log() const;
+
+    /////////// DiscoverNodeDelegate Interface /////////
+    void OnNodeDiscovered(const chip::Dnssd::DiscoveredNodeData & nodeData) override;
+
+    /////////// DnssdBrowseDelegate Interface /////////
+    void OnBrowseAdd(chip::Dnssd::DnssdService service) override;
+    void OnBrowseRemove(chip::Dnssd::DnssdService service) override;
+    void OnBrowseStop(CHIP_ERROR error) override;
+
+#if CONFIG_NETWORK_LAYER_BLE
+    /////////// BleScannerDelegate Interface /////////
+    void OnBleScanAdd(BLE_CONNECTION_OBJECT connObj, const chip::Ble::ChipBLEDeviceIdentificationInfo & info) override;
+    void OnBleScanRemove(BLE_CONNECTION_OBJECT connObj) override;
+#endif // CONFIG_NETWORK_LAYER_BLE
+
+private:
+    std::unordered_map<std::string, std::map<chip::Inet::InterfaceId::PlatformType, std::vector<DeviceScannerResult>>>
+        mDiscoveredResults;
+};
+
+DeviceScanner & GetDeviceScanner();
+
+#endif // CHIP_DEVICE_LAYER_TARGET_DARWIN
diff --git a/examples/fabric-admin/commands/common/HexConversion.h b/examples/fabric-admin/commands/common/HexConversion.h
new file mode 100644
index 0000000..99b7f65
--- /dev/null
+++ b/examples/fabric-admin/commands/common/HexConversion.h
@@ -0,0 +1,65 @@
+/*
+ *   Copyright (c) 2024 Project CHIP Authors
+ *   All rights reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ */
+
+#pragma once
+
+#include <lib/core/CHIPError.h>
+#include <lib/support/BytesToHex.h>
+#include <lib/support/Span.h>
+#include <lib/support/logging/CHIPLogging.h>
+
+/**
+ * Utility for converting a hex string to bytes, with the right error checking
+ * and allocation size computation.
+ *
+ * Takes a functor to allocate the buffer to use for the hex bytes.  The functor
+ * is expected to return uint8_t *.  The caller is responsible for cleaning up
+ * this buffer as needed.
+ *
+ * On success, *octetCount is filled with the number of octets placed in the
+ * buffer.  On failure, the value of *octetCount is undefined.
+ */
+template <typename F>
+CHIP_ERROR HexToBytes(chip::CharSpan hex, F bufferAllocator, size_t * octetCount)
+{
+    *octetCount = 0;
+
+    if (hex.size() % 2 != 0)
+    {
+        ChipLogError(NotSpecified, "Error while encoding '%.*s' as an octet string: Odd number of characters.",
+                     static_cast<int>(hex.size()), hex.data());
+        return CHIP_ERROR_INVALID_STRING_LENGTH;
+    }
+
+    const size_t bufferSize = hex.size() / 2;
+    uint8_t * buffer        = bufferAllocator(bufferSize);
+    if (buffer == nullptr && bufferSize != 0)
+    {
+        ChipLogError(NotSpecified, "Failed to allocate buffer of size: %llu", static_cast<unsigned long long>(bufferSize));
+        return CHIP_ERROR_NO_MEMORY;
+    }
+
+    size_t byteCount = chip::Encoding::HexToBytes(hex.data(), hex.size(), buffer, bufferSize);
+    if (byteCount == 0 && hex.size() != 0)
+    {
+        ChipLogError(NotSpecified, "Error while encoding '%.*s' as an octet string.", static_cast<int>(hex.size()), hex.data());
+        return CHIP_ERROR_INTERNAL;
+    }
+
+    *octetCount = byteCount;
+    return CHIP_NO_ERROR;
+}
diff --git a/examples/fabric-admin/commands/common/RemoteDataModelLogger.cpp b/examples/fabric-admin/commands/common/RemoteDataModelLogger.cpp
new file mode 100644
index 0000000..c8e9d5a
--- /dev/null
+++ b/examples/fabric-admin/commands/common/RemoteDataModelLogger.cpp
@@ -0,0 +1,279 @@
+/*
+ *   Copyright (c) 2024 Project CHIP Authors
+ *   All rights reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+#include "RemoteDataModelLogger.h"
+
+#include <lib/support/SafeInt.h>
+#include <lib/support/jsontlv/TlvJson.h>
+
+constexpr char kEventNumberKey[]    = "eventNumber";
+constexpr char kDataVersionKey[]    = "dataVersion";
+constexpr char kClusterIdKey[]      = "clusterId";
+constexpr char kEndpointIdKey[]     = "endpointId";
+constexpr char kAttributeIdKey[]    = "attributeId";
+constexpr char kEventIdKey[]        = "eventId";
+constexpr char kCommandIdKey[]      = "commandId";
+constexpr char kErrorIdKey[]        = "error";
+constexpr char kClusterErrorIdKey[] = "clusterError";
+constexpr char kValueKey[]          = "value";
+constexpr char kNodeIdKey[]         = "nodeId";
+constexpr char kNOCKey[]            = "NOC";
+constexpr char kICACKey[]           = "ICAC";
+constexpr char kRCACKey[]           = "RCAC";
+constexpr char kIPKKey[]            = "IPK";
+
+namespace {
+RemoteDataModelLoggerDelegate * gDelegate;
+
+CHIP_ERROR LogError(Json::Value & value, const chip::app::StatusIB & status)
+{
+    if (status.mClusterStatus.HasValue())
+    {
+        auto statusValue          = status.mClusterStatus.Value();
+        value[kClusterErrorIdKey] = statusValue;
+    }
+
+#if CHIP_CONFIG_IM_STATUS_CODE_VERBOSE_FORMAT
+    auto statusName    = chip::Protocols::InteractionModel::StatusName(status.mStatus);
+    value[kErrorIdKey] = statusName;
+#else
+    auto statusName    = status.mStatus;
+    value[kErrorIdKey] = chip::to_underlying(statusName);
+#endif // CHIP_CONFIG_IM_STATUS_CODE_VERBOSE_FORMAT
+
+    auto valueStr = chip::JsonToString(value);
+    return gDelegate->LogJSON(valueStr.c_str());
+}
+
+} // namespace
+
+namespace RemoteDataModelLogger {
+CHIP_ERROR LogAttributeAsJSON(const chip::app::ConcreteDataAttributePath & path, chip::TLV::TLVReader * data)
+{
+    VerifyOrReturnError(gDelegate != nullptr, CHIP_NO_ERROR);
+
+    Json::Value value;
+    value[kClusterIdKey]   = path.mClusterId;
+    value[kEndpointIdKey]  = path.mEndpointId;
+    value[kAttributeIdKey] = path.mAttributeId;
+    if (path.mDataVersion.HasValue())
+    {
+        value[kDataVersionKey] = path.mDataVersion.Value();
+    }
+
+    chip::TLV::TLVReader reader;
+    reader.Init(*data);
+    ReturnErrorOnFailure(chip::TlvToJson(reader, value));
+
+    auto valueStr = chip::JsonToString(value);
+    return gDelegate->LogJSON(valueStr.c_str());
+}
+
+CHIP_ERROR LogErrorAsJSON(const chip::app::ConcreteDataAttributePath & path, const chip::app::StatusIB & status)
+{
+    VerifyOrReturnError(gDelegate != nullptr, CHIP_NO_ERROR);
+
+    Json::Value value;
+    value[kClusterIdKey]   = path.mClusterId;
+    value[kEndpointIdKey]  = path.mEndpointId;
+    value[kAttributeIdKey] = path.mAttributeId;
+
+    return LogError(value, status);
+}
+
+CHIP_ERROR LogCommandAsJSON(const chip::app::ConcreteCommandPath & path, chip::TLV::TLVReader * data)
+{
+    VerifyOrReturnError(gDelegate != nullptr, CHIP_NO_ERROR);
+
+    Json::Value value;
+    value[kClusterIdKey]  = path.mClusterId;
+    value[kEndpointIdKey] = path.mEndpointId;
+    value[kCommandIdKey]  = path.mCommandId;
+
+    chip::TLV::TLVReader reader;
+    reader.Init(*data);
+    ReturnErrorOnFailure(chip::TlvToJson(reader, value));
+
+    auto valueStr = chip::JsonToString(value);
+    return gDelegate->LogJSON(valueStr.c_str());
+}
+
+CHIP_ERROR LogErrorAsJSON(const chip::app::ConcreteCommandPath & path, const chip::app::StatusIB & status)
+{
+    VerifyOrReturnError(gDelegate != nullptr, CHIP_NO_ERROR);
+
+    Json::Value value;
+    value[kClusterIdKey]  = path.mClusterId;
+    value[kEndpointIdKey] = path.mEndpointId;
+    value[kCommandIdKey]  = path.mCommandId;
+
+    return LogError(value, status);
+}
+
+CHIP_ERROR LogEventAsJSON(const chip::app::EventHeader & header, chip::TLV::TLVReader * data)
+{
+    VerifyOrReturnError(gDelegate != nullptr, CHIP_NO_ERROR);
+
+    Json::Value value;
+    value[kClusterIdKey]   = header.mPath.mClusterId;
+    value[kEndpointIdKey]  = header.mPath.mEndpointId;
+    value[kEventIdKey]     = header.mPath.mEventId;
+    value[kEventNumberKey] = header.mEventNumber;
+
+    chip::TLV::TLVReader reader;
+    reader.Init(*data);
+    ReturnErrorOnFailure(chip::TlvToJson(reader, value));
+
+    auto valueStr = chip::JsonToString(value);
+    return gDelegate->LogJSON(valueStr.c_str());
+}
+
+CHIP_ERROR LogErrorAsJSON(const chip::app::EventHeader & header, const chip::app::StatusIB & status)
+{
+    VerifyOrReturnError(gDelegate != nullptr, CHIP_NO_ERROR);
+
+    Json::Value value;
+    value[kClusterIdKey]  = header.mPath.mClusterId;
+    value[kEndpointIdKey] = header.mPath.mEndpointId;
+    value[kEventIdKey]    = header.mPath.mEventId;
+
+    return LogError(value, status);
+}
+
+CHIP_ERROR LogErrorAsJSON(const CHIP_ERROR & error)
+{
+    VerifyOrReturnError(gDelegate != nullptr, CHIP_NO_ERROR);
+
+    Json::Value value;
+    chip::app::StatusIB status;
+    status.InitFromChipError(error);
+    return LogError(value, status);
+}
+
+CHIP_ERROR LogGetCommissionerNodeId(chip::NodeId value)
+{
+    VerifyOrReturnError(gDelegate != nullptr, CHIP_NO_ERROR);
+
+    Json::Value rootValue;
+    rootValue[kValueKey]             = Json::Value();
+    rootValue[kValueKey][kNodeIdKey] = value;
+
+    auto valueStr = chip::JsonToString(rootValue);
+    return gDelegate->LogJSON(valueStr.c_str());
+}
+
+CHIP_ERROR LogGetCommissionerRootCertificate(const char * value)
+{
+    VerifyOrReturnError(gDelegate != nullptr, CHIP_NO_ERROR);
+
+    Json::Value rootValue;
+    rootValue[kValueKey]           = Json::Value();
+    rootValue[kValueKey][kRCACKey] = value;
+
+    auto valueStr = chip::JsonToString(rootValue);
+    return gDelegate->LogJSON(valueStr.c_str());
+}
+
+CHIP_ERROR LogIssueNOCChain(const char * noc, const char * icac, const char * rcac, const char * ipk)
+{
+    VerifyOrReturnError(gDelegate != nullptr, CHIP_NO_ERROR);
+
+    Json::Value rootValue;
+    rootValue[kValueKey]           = Json::Value();
+    rootValue[kValueKey][kNOCKey]  = noc;
+    rootValue[kValueKey][kICACKey] = icac;
+    rootValue[kValueKey][kRCACKey] = rcac;
+    rootValue[kValueKey][kIPKKey]  = ipk;
+
+    auto valueStr = chip::JsonToString(rootValue);
+    return gDelegate->LogJSON(valueStr.c_str());
+}
+
+CHIP_ERROR LogDiscoveredNodeData(const chip::Dnssd::CommissionNodeData & nodeData)
+{
+    VerifyOrReturnError(gDelegate != nullptr, CHIP_NO_ERROR);
+
+    auto & commissionData = nodeData;
+    auto & resolutionData = commissionData;
+
+    if (!chip::CanCastTo<uint8_t>(resolutionData.numIPs))
+    {
+        ChipLogError(NotSpecified, "Too many ips.");
+        return CHIP_ERROR_INVALID_ARGUMENT;
+    }
+
+    if (!chip::CanCastTo<uint64_t>(commissionData.rotatingIdLen))
+    {
+        ChipLogError(NotSpecified, "Can not convert rotatingId to json format.");
+        return CHIP_ERROR_INVALID_ARGUMENT;
+    }
+
+    char rotatingId[chip::Dnssd::kMaxRotatingIdLen * 2 + 1] = "";
+    ReturnErrorOnFailure(chip::Encoding::BytesToUppercaseHexString(commissionData.rotatingId, commissionData.rotatingIdLen,
+                                                                   rotatingId, sizeof(rotatingId)));
+
+    Json::Value value;
+    value["hostName"]           = resolutionData.hostName;
+    value["instanceName"]       = commissionData.instanceName;
+    value["longDiscriminator"]  = commissionData.longDiscriminator;
+    value["shortDiscriminator"] = ((commissionData.longDiscriminator >> 8) & 0x0F);
+    value["vendorId"]           = commissionData.vendorId;
+    value["productId"]          = commissionData.productId;
+    value["commissioningMode"]  = commissionData.commissioningMode;
+    value["deviceType"]         = commissionData.deviceType;
+    value["deviceName"]         = commissionData.deviceName;
+    value["rotatingId"]         = rotatingId;
+    value["rotatingIdLen"]      = static_cast<uint64_t>(commissionData.rotatingIdLen);
+    value["pairingHint"]        = commissionData.pairingHint;
+    value["pairingInstruction"] = commissionData.pairingInstruction;
+    value["supportsTcp"]        = resolutionData.supportsTcp;
+    value["port"]               = resolutionData.port;
+    value["numIPs"]             = static_cast<uint8_t>(resolutionData.numIPs);
+
+    if (resolutionData.mrpRetryIntervalIdle.has_value())
+    {
+        value["mrpRetryIntervalIdle"] = resolutionData.mrpRetryIntervalIdle->count();
+    }
+
+    if (resolutionData.mrpRetryIntervalActive.has_value())
+    {
+        value["mrpRetryIntervalActive"] = resolutionData.mrpRetryIntervalActive->count();
+    }
+
+    if (resolutionData.mrpRetryActiveThreshold.has_value())
+    {
+        value["mrpRetryActiveThreshold"] = resolutionData.mrpRetryActiveThreshold->count();
+    }
+
+    if (resolutionData.isICDOperatingAsLIT.has_value())
+    {
+        value["isICDOperatingAsLIT"] = *(resolutionData.isICDOperatingAsLIT);
+    }
+
+    Json::Value rootValue;
+    rootValue[kValueKey] = value;
+
+    auto valueStr = chip::JsonToString(rootValue);
+    return gDelegate->LogJSON(valueStr.c_str());
+}
+
+void SetDelegate(RemoteDataModelLoggerDelegate * delegate)
+{
+    gDelegate = delegate;
+}
+}; // namespace RemoteDataModelLogger
diff --git a/examples/fabric-admin/commands/common/RemoteDataModelLogger.h b/examples/fabric-admin/commands/common/RemoteDataModelLogger.h
new file mode 100644
index 0000000..c31636e
--- /dev/null
+++ b/examples/fabric-admin/commands/common/RemoteDataModelLogger.h
@@ -0,0 +1,48 @@
+/*
+ *   Copyright (c) 2024 Project CHIP Authors
+ *   All rights reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+#pragma once
+
+#include <app/ConcreteAttributePath.h>
+#include <app/ConcreteCommandPath.h>
+#include <app/EventHeader.h>
+#include <app/MessageDef/StatusIB.h>
+#include <crypto/CHIPCryptoPAL.h>
+#include <lib/dnssd/Resolver.h>
+
+class RemoteDataModelLoggerDelegate
+{
+public:
+    CHIP_ERROR virtual LogJSON(const char *) = 0;
+    virtual ~RemoteDataModelLoggerDelegate(){};
+};
+
+namespace RemoteDataModelLogger {
+CHIP_ERROR LogAttributeAsJSON(const chip::app::ConcreteDataAttributePath & path, chip::TLV::TLVReader * data);
+CHIP_ERROR LogErrorAsJSON(const chip::app::ConcreteDataAttributePath & path, const chip::app::StatusIB & status);
+CHIP_ERROR LogCommandAsJSON(const chip::app::ConcreteCommandPath & path, chip::TLV::TLVReader * data);
+CHIP_ERROR LogErrorAsJSON(const chip::app::ConcreteCommandPath & path, const chip::app::StatusIB & status);
+CHIP_ERROR LogEventAsJSON(const chip::app::EventHeader & header, chip::TLV::TLVReader * data);
+CHIP_ERROR LogErrorAsJSON(const chip::app::EventHeader & header, const chip::app::StatusIB & status);
+CHIP_ERROR LogErrorAsJSON(const CHIP_ERROR & error);
+CHIP_ERROR LogGetCommissionerNodeId(chip::NodeId value);
+CHIP_ERROR LogGetCommissionerRootCertificate(const char * value);
+CHIP_ERROR LogIssueNOCChain(const char * noc, const char * icac, const char * rcac, const char * ipk);
+CHIP_ERROR LogDiscoveredNodeData(const chip::Dnssd::CommissionNodeData & nodeData);
+void SetDelegate(RemoteDataModelLoggerDelegate * delegate);
+}; // namespace RemoteDataModelLogger
diff --git a/examples/fabric-admin/commands/example/ExampleCredentialIssuerCommands.h b/examples/fabric-admin/commands/example/ExampleCredentialIssuerCommands.h
new file mode 100644
index 0000000..a739ac7
--- /dev/null
+++ b/examples/fabric-admin/commands/example/ExampleCredentialIssuerCommands.h
@@ -0,0 +1,111 @@
+/*
+ *   Copyright (c) 2024 Project CHIP Authors
+ *   All rights reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+#pragma once
+
+#include <commands/common/CredentialIssuerCommands.h>
+#include <controller/CHIPDeviceControllerFactory.h>
+#include <controller/ExampleOperationalCredentialsIssuer.h>
+#include <credentials/DeviceAttestationCredsProvider.h>
+#include <credentials/attestation_verifier/DefaultDeviceAttestationVerifier.h>
+#include <credentials/attestation_verifier/DeviceAttestationVerifier.h>
+#include <credentials/examples/DeviceAttestationCredsExample.h>
+
+class ExampleCredentialIssuerCommands : public CredentialIssuerCommands
+{
+public:
+    CHIP_ERROR InitializeCredentialsIssuer(chip::PersistentStorageDelegate & storage) override
+    {
+        return mOpCredsIssuer.Initialize(storage);
+    }
+    CHIP_ERROR SetupDeviceAttestation(chip::Controller::SetupParams & setupParams,
+                                      const chip::Credentials::AttestationTrustStore * trustStore) override
+    {
+        chip::Credentials::SetDeviceAttestationCredentialsProvider(chip::Credentials::Examples::GetExampleDACProvider());
+
+        mDacVerifier                          = chip::Credentials::GetDefaultDACVerifier(trustStore);
+        setupParams.deviceAttestationVerifier = mDacVerifier;
+        mDacVerifier->EnableCdTestKeySupport(mAllowTestCdSigningKey);
+
+        return CHIP_NO_ERROR;
+    }
+    chip::Controller::OperationalCredentialsDelegate * GetCredentialIssuer() override { return &mOpCredsIssuer; }
+    void SetCredentialIssuerCATValues(chip::CATValues cats) override { mOpCredsIssuer.SetCATValuesForNextNOCRequest(cats); }
+    CHIP_ERROR GenerateControllerNOCChain(chip::NodeId nodeId, chip::FabricId fabricId, const chip::CATValues & cats,
+                                          chip::Crypto::P256Keypair & keypair, chip::MutableByteSpan & rcac,
+                                          chip::MutableByteSpan & icac, chip::MutableByteSpan & noc) override
+    {
+        return mOpCredsIssuer.GenerateNOCChainAfterValidation(nodeId, fabricId, cats, keypair.Pubkey(), rcac, icac, noc);
+    }
+
+    CHIP_ERROR AddAdditionalCDVerifyingCerts(const std::vector<std::vector<uint8_t>> & additionalCdCerts) override
+    {
+        VerifyOrReturnError(mDacVerifier != nullptr, CHIP_ERROR_INCORRECT_STATE);
+
+        for (const auto & cert : additionalCdCerts)
+        {
+            auto cdTrustStore = mDacVerifier->GetCertificationDeclarationTrustStore();
+            VerifyOrReturnError(cdTrustStore != nullptr, CHIP_ERROR_INCORRECT_STATE);
+            ReturnErrorOnFailure(cdTrustStore->AddTrustedKey(chip::ByteSpan(cert.data(), cert.size())));
+        }
+
+        return CHIP_NO_ERROR;
+    }
+
+    void SetCredentialIssuerOption(CredentialIssuerOptions option, bool isEnabled) override
+    {
+        switch (option)
+        {
+        case CredentialIssuerOptions::kMaximizeCertificateSizes:
+            mUsesMaxSizedCerts = isEnabled;
+            mOpCredsIssuer.SetMaximallyLargeCertsUsed(mUsesMaxSizedCerts);
+            break;
+        case CredentialIssuerOptions::kAllowTestCdSigningKey:
+            mAllowTestCdSigningKey = isEnabled;
+            if (mDacVerifier != nullptr)
+            {
+                mDacVerifier->EnableCdTestKeySupport(isEnabled);
+            }
+            break;
+        default:
+            break;
+        }
+    }
+
+    bool GetCredentialIssuerOption(CredentialIssuerOptions option) override
+    {
+        switch (option)
+        {
+        case CredentialIssuerOptions::kMaximizeCertificateSizes:
+            return mUsesMaxSizedCerts;
+        case CredentialIssuerOptions::kAllowTestCdSigningKey:
+            return mAllowTestCdSigningKey;
+        default:
+            return false;
+        }
+    }
+
+protected:
+    bool mUsesMaxSizedCerts = false;
+    // Starts true for legacy purposes
+    bool mAllowTestCdSigningKey = true;
+
+private:
+    chip::Controller::ExampleOperationalCredentialsIssuer mOpCredsIssuer;
+    chip::Credentials::DeviceAttestationVerifier * mDacVerifier;
+};
diff --git a/examples/fabric-admin/commands/interactive/Commands.h b/examples/fabric-admin/commands/interactive/Commands.h
new file mode 100644
index 0000000..e324dda
--- /dev/null
+++ b/examples/fabric-admin/commands/interactive/Commands.h
@@ -0,0 +1,34 @@
+/*
+ *   Copyright (c) 2024 Project CHIP Authors
+ *   All rights reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+#pragma once
+
+#include "commands/common/CHIPCommand.h"
+#include "commands/common/Commands.h"
+#include "commands/interactive/InteractiveCommands.h"
+
+void registerCommandsInteractive(Commands & commands, CredentialIssuerCommands * credsIssuerConfig)
+{
+    const char * clusterName = "interactive";
+
+    commands_list clusterCommands = {
+        make_unique<InteractiveStartCommand>(&commands, credsIssuerConfig),
+    };
+
+    commands.RegisterCommandSet(clusterName, clusterCommands, "Commands for starting long-lived interactive modes.");
+}
diff --git a/examples/fabric-admin/commands/interactive/InteractiveCommands.cpp b/examples/fabric-admin/commands/interactive/InteractiveCommands.cpp
new file mode 100644
index 0000000..9ef07e7
--- /dev/null
+++ b/examples/fabric-admin/commands/interactive/InteractiveCommands.cpp
@@ -0,0 +1,139 @@
+/*
+ *   Copyright (c) 2024 Project CHIP Authors
+ *   All rights reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+#include "InteractiveCommands.h"
+
+#include <platform/logging/LogV.h>
+
+#include <editline.h>
+
+#include <string>
+#include <vector>
+
+constexpr char kInteractiveModePrompt[]          = ">>> ";
+constexpr char kInteractiveModeHistoryFileName[] = "chip_tool_history";
+constexpr char kInteractiveModeStopCommand[]     = "quit()";
+
+namespace {
+
+void ClearLine()
+{
+    printf("\r\x1B[0J"); // Move cursor to the beginning of the line and clear from cursor to end of the screen
+}
+
+void ENFORCE_FORMAT(3, 0) LoggingCallback(const char * module, uint8_t category, const char * msg, va_list args)
+{
+    ClearLine();
+    chip::Logging::Platform::LogV(module, category, msg, args);
+    ClearLine();
+}
+
+} // namespace
+
+char * InteractiveStartCommand::GetCommand(char * command)
+{
+    if (command != nullptr)
+    {
+        free(command);
+        command = nullptr;
+    }
+
+    command = readline(kInteractiveModePrompt);
+
+    // Do not save empty lines
+    if (command != nullptr && *command)
+    {
+        add_history(command);
+        write_history(GetHistoryFilePath().c_str());
+    }
+
+    return command;
+}
+
+std::string InteractiveStartCommand::GetHistoryFilePath() const
+{
+    std::string storageDir;
+    if (GetStorageDirectory().HasValue())
+    {
+        storageDir = GetStorageDirectory().Value();
+    }
+    else
+    {
+        // Match what GetFilename in ExamplePersistentStorage.cpp does.
+        const char * dir = getenv("TMPDIR");
+        if (dir == nullptr)
+        {
+            dir = "/tmp";
+        }
+        storageDir = dir;
+    }
+
+    return storageDir + "/" + kInteractiveModeHistoryFileName;
+}
+
+CHIP_ERROR InteractiveStartCommand::RunCommand()
+{
+    read_history(GetHistoryFilePath().c_str());
+
+    // Logs needs to be redirected in order to refresh the screen appropriately when something
+    // is dumped to stdout while the user is typing a command.
+    chip::Logging::SetLogRedirectCallback(LoggingCallback);
+
+    char * command = nullptr;
+    int status;
+    while (true)
+    {
+        command = GetCommand(command);
+        if (command != nullptr && !ParseCommand(command, &status))
+        {
+            break;
+        }
+    }
+
+    if (command != nullptr)
+    {
+        free(command);
+        command = nullptr;
+    }
+
+    SetCommandExitStatus(CHIP_NO_ERROR);
+    return CHIP_NO_ERROR;
+}
+
+bool InteractiveCommand::ParseCommand(char * command, int * status)
+{
+    if (strcmp(command, kInteractiveModeStopCommand) == 0)
+    {
+        // If scheduling the cleanup fails, there is not much we can do.
+        // But if something went wrong while the application is leaving it could be because things have
+        // not been cleaned up properly, so it is still useful to log the failure.
+        LogErrorOnFailure(chip::DeviceLayer::PlatformMgr().ScheduleWork(ExecuteDeferredCleanups, 0));
+        return false;
+    }
+
+    ClearLine();
+
+    *status = mHandler->RunInteractive(command, GetStorageDirectory(), NeedsOperationalAdvertising());
+
+    return true;
+}
+
+bool InteractiveCommand::NeedsOperationalAdvertising()
+{
+    return mAdvertiseOperational.ValueOr(true);
+}
diff --git a/examples/fabric-admin/commands/interactive/InteractiveCommands.h b/examples/fabric-admin/commands/interactive/InteractiveCommands.h
new file mode 100644
index 0000000..21c14a7
--- /dev/null
+++ b/examples/fabric-admin/commands/interactive/InteractiveCommands.h
@@ -0,0 +1,68 @@
+/*
+ *   Copyright (c) 2024 Project CHIP Authors
+ *   All rights reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+#pragma once
+
+#include "../clusters/DataModelLogger.h"
+#include "../common/CHIPCommand.h"
+#include "../common/Commands.h"
+
+#include <websocket-server/WebSocketServer.h>
+
+#include <string>
+
+class Commands;
+
+class InteractiveCommand : public CHIPCommand
+{
+public:
+    InteractiveCommand(const char * name, Commands * commandsHandler, const char * helpText,
+                       CredentialIssuerCommands * credsIssuerConfig) :
+        CHIPCommand(name, credsIssuerConfig, helpText),
+        mHandler(commandsHandler)
+    {
+        AddArgument("advertise-operational", 0, 1, &mAdvertiseOperational,
+                    "Advertise operational node over DNS-SD and accept incoming CASE sessions.");
+    }
+
+    /////////// CHIPCommand Interface /////////
+    chip::System::Clock::Timeout GetWaitDuration() const override { return chip::System::Clock::Seconds16(0); }
+    bool NeedsOperationalAdvertising() override;
+
+    bool ParseCommand(char * command, int * status);
+
+private:
+    Commands * mHandler = nullptr;
+    chip::Optional<bool> mAdvertiseOperational;
+};
+
+class InteractiveStartCommand : public InteractiveCommand
+{
+public:
+    InteractiveStartCommand(Commands * commandsHandler, CredentialIssuerCommands * credsIssuerConfig) :
+        InteractiveCommand("start", commandsHandler, "Start an interactive shell that can then run other commands.",
+                           credsIssuerConfig)
+    {}
+
+    /////////// CHIPCommand Interface /////////
+    CHIP_ERROR RunCommand() override;
+
+private:
+    char * GetCommand(char * command);
+    std::string GetHistoryFilePath() const;
+};
diff --git a/examples/fabric-admin/commands/pairing/Commands.h b/examples/fabric-admin/commands/pairing/Commands.h
new file mode 100644
index 0000000..6fdface
--- /dev/null
+++ b/examples/fabric-admin/commands/pairing/Commands.h
@@ -0,0 +1,259 @@
+/*
+ *   Copyright (c) 2024 Project CHIP Authors
+ *   All rights reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+#pragma once
+
+#include "commands/common/Commands.h"
+#include "commands/pairing/GetCommissionerNodeIdCommand.h"
+#include "commands/pairing/GetCommissionerRootCertificateCommand.h"
+#include "commands/pairing/IssueNOCChainCommand.h"
+#include "commands/pairing/OpenCommissioningWindowCommand.h"
+#include "commands/pairing/PairingCommand.h"
+
+#include <app/server/Dnssd.h>
+#include <commands/common/CredentialIssuerCommands.h>
+#include <lib/dnssd/Resolver.h>
+
+class Unpair : public PairingCommand
+{
+public:
+    Unpair(CredentialIssuerCommands * credsIssuerConfig) :
+        PairingCommand("unpair", PairingMode::None, PairingNetworkType::None, credsIssuerConfig)
+    {}
+};
+
+class PairCode : public PairingCommand
+{
+public:
+    PairCode(CredentialIssuerCommands * credsIssuerConfig) :
+        PairingCommand("code", PairingMode::Code, PairingNetworkType::None, credsIssuerConfig)
+    {}
+};
+
+class PairCodePase : public PairingCommand
+{
+public:
+    PairCodePase(CredentialIssuerCommands * credsIssuerConfig) :
+        PairingCommand("code-paseonly", PairingMode::CodePaseOnly, PairingNetworkType::None, credsIssuerConfig)
+    {}
+};
+
+class PairCodeWifi : public PairingCommand
+{
+public:
+    PairCodeWifi(CredentialIssuerCommands * credsIssuerConfig) :
+        PairingCommand("code-wifi", PairingMode::Code, PairingNetworkType::WiFi, credsIssuerConfig)
+    {}
+};
+
+class PairCodeThread : public PairingCommand
+{
+public:
+    PairCodeThread(CredentialIssuerCommands * credsIssuerConfig) :
+        PairingCommand("code-thread", PairingMode::Code, PairingNetworkType::Thread, credsIssuerConfig)
+    {}
+};
+
+class PairOnNetwork : public PairingCommand
+{
+public:
+    PairOnNetwork(CredentialIssuerCommands * credsIssuerConfig) :
+        PairingCommand("onnetwork", PairingMode::OnNetwork, PairingNetworkType::None, credsIssuerConfig)
+    {}
+};
+
+class PairOnNetworkShort : public PairingCommand
+{
+public:
+    PairOnNetworkShort(CredentialIssuerCommands * credsIssuerConfig) :
+        PairingCommand("onnetwork-short", PairingMode::OnNetwork, PairingNetworkType::None, credsIssuerConfig,
+                       chip::Dnssd::DiscoveryFilterType::kShortDiscriminator)
+    {}
+};
+
+class PairOnNetworkLong : public PairingCommand
+{
+public:
+    PairOnNetworkLong(CredentialIssuerCommands * credsIssuerConfig) :
+        PairingCommand("onnetwork-long", PairingMode::OnNetwork, PairingNetworkType::None, credsIssuerConfig,
+                       chip::Dnssd::DiscoveryFilterType::kLongDiscriminator)
+    {}
+};
+
+class PairOnNetworkVendor : public PairingCommand
+{
+public:
+    PairOnNetworkVendor(CredentialIssuerCommands * credsIssuerConfig) :
+        PairingCommand("onnetwork-vendor", PairingMode::OnNetwork, PairingNetworkType::None, credsIssuerConfig,
+                       chip::Dnssd::DiscoveryFilterType::kVendorId)
+    {}
+};
+
+class PairOnNetworkFabric : public PairingCommand
+{
+public:
+    PairOnNetworkFabric(CredentialIssuerCommands * credsIssuerConfig) :
+        PairingCommand("onnetwork-fabric", PairingMode::OnNetwork, PairingNetworkType::None, credsIssuerConfig,
+                       chip::Dnssd::DiscoveryFilterType::kCompressedFabricId)
+    {}
+};
+
+class PairOnNetworkCommissioningMode : public PairingCommand
+{
+public:
+    PairOnNetworkCommissioningMode(CredentialIssuerCommands * credsIssuerConfig) :
+        PairingCommand("onnetwork-commissioning-mode", PairingMode::OnNetwork, PairingNetworkType::None, credsIssuerConfig,
+                       chip::Dnssd::DiscoveryFilterType::kCommissioningMode)
+    {}
+};
+
+class PairOnNetworkCommissioner : public PairingCommand
+{
+public:
+    PairOnNetworkCommissioner(CredentialIssuerCommands * credsIssuerConfig) :
+        PairingCommand("onnetwork-commissioner", PairingMode::OnNetwork, PairingNetworkType::None, credsIssuerConfig,
+                       chip::Dnssd::DiscoveryFilterType::kCommissioner)
+    {}
+};
+
+class PairOnNetworkDeviceType : public PairingCommand
+{
+public:
+    PairOnNetworkDeviceType(CredentialIssuerCommands * credsIssuerConfig) :
+        PairingCommand("onnetwork-device-type", PairingMode::OnNetwork, PairingNetworkType::None, credsIssuerConfig,
+                       chip::Dnssd::DiscoveryFilterType::kDeviceType)
+    {}
+};
+
+class PairOnNetworkInstanceName : public PairingCommand
+{
+public:
+    PairOnNetworkInstanceName(CredentialIssuerCommands * credsIssuerConfig) :
+        PairingCommand("onnetwork-instance-name", PairingMode::OnNetwork, PairingNetworkType::None, credsIssuerConfig,
+                       chip::Dnssd::DiscoveryFilterType::kInstanceName)
+    {}
+};
+
+class PairBleWiFi : public PairingCommand
+{
+public:
+    PairBleWiFi(CredentialIssuerCommands * credsIssuerConfig) :
+        PairingCommand("ble-wifi", PairingMode::Ble, PairingNetworkType::WiFi, credsIssuerConfig)
+    {}
+};
+
+class PairBleThread : public PairingCommand
+{
+public:
+    PairBleThread(CredentialIssuerCommands * credsIssuerConfig) :
+        PairingCommand("ble-thread", PairingMode::Ble, PairingNetworkType::Thread, credsIssuerConfig)
+    {}
+};
+
+class PairSoftAP : public PairingCommand
+{
+public:
+    PairSoftAP(CredentialIssuerCommands * credsIssuerConfig) :
+        PairingCommand("softap", PairingMode::SoftAP, PairingNetworkType::WiFi, credsIssuerConfig)
+    {}
+};
+
+class PairAlreadyDiscovered : public PairingCommand
+{
+public:
+    PairAlreadyDiscovered(CredentialIssuerCommands * credsIssuerConfig) :
+        PairingCommand("already-discovered", PairingMode::AlreadyDiscovered, PairingNetworkType::None, credsIssuerConfig)
+    {}
+};
+
+class PairAlreadyDiscoveredByIndex : public PairingCommand
+{
+public:
+    PairAlreadyDiscoveredByIndex(CredentialIssuerCommands * credsIssuerConfig) :
+        PairingCommand("already-discovered-by-index", PairingMode::AlreadyDiscoveredByIndex, PairingNetworkType::None,
+                       credsIssuerConfig)
+    {}
+};
+
+class PairAlreadyDiscoveredByIndexWithWiFi : public PairingCommand
+{
+public:
+    PairAlreadyDiscoveredByIndexWithWiFi(CredentialIssuerCommands * credsIssuerConfig) :
+        PairingCommand("already-discovered-by-index-with-wifi", PairingMode::AlreadyDiscoveredByIndex, PairingNetworkType::WiFi,
+                       credsIssuerConfig)
+    {}
+};
+
+class PairAlreadyDiscoveredByIndexWithCode : public PairingCommand
+{
+public:
+    PairAlreadyDiscoveredByIndexWithCode(CredentialIssuerCommands * credsIssuerConfig) :
+        PairingCommand("already-discovered-by-index-with-code", PairingMode::AlreadyDiscoveredByIndexWithCode,
+                       PairingNetworkType::None, credsIssuerConfig)
+    {}
+};
+
+class StartUdcServerCommand : public CHIPCommand
+{
+public:
+    StartUdcServerCommand(CredentialIssuerCommands * credsIssuerConfig) : CHIPCommand("start-udc-server", credsIssuerConfig) {}
+    chip::System::Clock::Timeout GetWaitDuration() const override { return chip::System::Clock::Seconds16(300); }
+
+    CHIP_ERROR RunCommand() override
+    {
+        chip::app::DnssdServer::Instance().StartServer(chip::Dnssd::CommissioningMode::kDisabled);
+        return CHIP_NO_ERROR;
+    }
+};
+
+void registerCommandsPairing(Commands & commands, CredentialIssuerCommands * credsIssuerConfig)
+{
+    const char * clusterName = "Pairing";
+
+    commands_list clusterCommands = {
+        make_unique<Unpair>(credsIssuerConfig),
+        make_unique<PairCode>(credsIssuerConfig),
+        make_unique<PairCodePase>(credsIssuerConfig),
+        make_unique<PairCodeWifi>(credsIssuerConfig),
+        make_unique<PairCodeThread>(credsIssuerConfig),
+        make_unique<PairBleWiFi>(credsIssuerConfig),
+        make_unique<PairBleThread>(credsIssuerConfig),
+        make_unique<PairSoftAP>(credsIssuerConfig),
+        make_unique<PairAlreadyDiscovered>(credsIssuerConfig),
+        make_unique<PairAlreadyDiscoveredByIndex>(credsIssuerConfig),
+        make_unique<PairAlreadyDiscoveredByIndexWithWiFi>(credsIssuerConfig),
+        make_unique<PairAlreadyDiscoveredByIndexWithCode>(credsIssuerConfig),
+        make_unique<PairOnNetwork>(credsIssuerConfig),
+        make_unique<PairOnNetworkShort>(credsIssuerConfig),
+        make_unique<PairOnNetworkLong>(credsIssuerConfig),
+        make_unique<PairOnNetworkVendor>(credsIssuerConfig),
+        make_unique<PairOnNetworkCommissioningMode>(credsIssuerConfig),
+        make_unique<PairOnNetworkCommissioner>(credsIssuerConfig),
+        make_unique<PairOnNetworkDeviceType>(credsIssuerConfig),
+        make_unique<PairOnNetworkInstanceName>(credsIssuerConfig),
+        // TODO(#13973) - enable CommissionedListCommand once DNS Cache is implemented
+        //        make_unique<CommissionedListCommand>(),
+        make_unique<StartUdcServerCommand>(credsIssuerConfig),
+        make_unique<OpenCommissioningWindowCommand>(credsIssuerConfig),
+        make_unique<GetCommissionerNodeIdCommand>(credsIssuerConfig),
+        make_unique<GetCommissionerRootCertificateCommand>(credsIssuerConfig),
+        make_unique<IssueNOCChainCommand>(credsIssuerConfig),
+    };
+
+    commands.RegisterCommandSet(clusterName, clusterCommands, "Commands for commissioning devices.");
+}
diff --git a/examples/fabric-admin/commands/pairing/GetCommissionerNodeIdCommand.h b/examples/fabric-admin/commands/pairing/GetCommissionerNodeIdCommand.h
new file mode 100644
index 0000000..3234cfe
--- /dev/null
+++ b/examples/fabric-admin/commands/pairing/GetCommissionerNodeIdCommand.h
@@ -0,0 +1,44 @@
+/*
+ *   Copyright (c) 2024 Project CHIP Authors
+ *   All rights reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+#pragma once
+
+#include "../common/CHIPCommand.h"
+#include "../common/RemoteDataModelLogger.h"
+
+class GetCommissionerNodeIdCommand : public CHIPCommand
+{
+public:
+    GetCommissionerNodeIdCommand(CredentialIssuerCommands * credIssuerCommands) :
+        CHIPCommand("get-commissioner-node-id", credIssuerCommands)
+    {}
+
+    /////////// CHIPCommand Interface /////////
+    CHIP_ERROR RunCommand() override
+    {
+        chip::NodeId id;
+        ReturnErrorOnFailure(GetIdentityNodeId(GetIdentity(), &id));
+        ChipLogProgress(NotSpecified, "Commissioner Node Id 0x:" ChipLogFormatX64, ChipLogValueX64(id));
+
+        ReturnErrorOnFailure(RemoteDataModelLogger::LogGetCommissionerNodeId(id));
+        SetCommandExitStatus(CHIP_NO_ERROR);
+        return CHIP_NO_ERROR;
+    }
+
+    chip::System::Clock::Timeout GetWaitDuration() const override { return chip::System::Clock::Seconds16(10); }
+};
diff --git a/examples/fabric-admin/commands/pairing/GetCommissionerRootCertificateCommand.h b/examples/fabric-admin/commands/pairing/GetCommissionerRootCertificateCommand.h
new file mode 100644
index 0000000..1d25efc
--- /dev/null
+++ b/examples/fabric-admin/commands/pairing/GetCommissionerRootCertificateCommand.h
@@ -0,0 +1,53 @@
+/*
+ *   Copyright (c) 2024 Project CHIP Authors
+ *   All rights reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+#pragma once
+
+#include "../common/CHIPCommand.h"
+#include "../common/RemoteDataModelLogger.h"
+
+#include "ToTLVCert.h"
+
+#include <string>
+
+class GetCommissionerRootCertificateCommand : public CHIPCommand
+{
+public:
+    GetCommissionerRootCertificateCommand(CredentialIssuerCommands * credIssuerCommands) :
+        CHIPCommand("get-commissioner-root-certificate", credIssuerCommands,
+                    "Returns a base64-encoded RCAC prefixed with: 'base64:'")
+    {}
+
+    /////////// CHIPCommand Interface /////////
+    CHIP_ERROR RunCommand() override
+    {
+        chip::ByteSpan span;
+        ReturnErrorOnFailure(GetIdentityRootCertificate(GetIdentity(), span));
+
+        std::string rcac;
+        ReturnErrorOnFailure(ToTLVCert(span, rcac));
+        ChipLogProgress(NotSpecified, "RCAC: %s", rcac.c_str());
+
+        ReturnErrorOnFailure(RemoteDataModelLogger::LogGetCommissionerRootCertificate(rcac.c_str()));
+
+        SetCommandExitStatus(CHIP_NO_ERROR);
+        return CHIP_NO_ERROR;
+    }
+
+    chip::System::Clock::Timeout GetWaitDuration() const override { return chip::System::Clock::Seconds16(10); }
+};
diff --git a/examples/fabric-admin/commands/pairing/IssueNOCChainCommand.h b/examples/fabric-admin/commands/pairing/IssueNOCChainCommand.h
new file mode 100644
index 0000000..0103b26
--- /dev/null
+++ b/examples/fabric-admin/commands/pairing/IssueNOCChainCommand.h
@@ -0,0 +1,91 @@
+/*
+ *   Copyright (c) 2024 Project CHIP Authors
+ *   All rights reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+#pragma once
+
+#include "../common/CHIPCommand.h"
+#include "../common/RemoteDataModelLogger.h"
+
+#include "ToTLVCert.h"
+
+#include <string>
+
+class IssueNOCChainCommand : public CHIPCommand
+{
+public:
+    IssueNOCChainCommand(CredentialIssuerCommands * credIssuerCommands) :
+        CHIPCommand("issue-noc-chain", credIssuerCommands,
+                    "Returns a base64-encoded NOC, ICAC, RCAC, and IPK prefixed with: 'base64:'"),
+        mDeviceNOCChainCallback(OnDeviceNOCChainGeneration, this)
+    {
+        AddArgument("elements", &mNOCSRElements, "NOCSRElements encoded in hexadecimal");
+        AddArgument("node-id", 0, UINT64_MAX, &mNodeId, "The target node id");
+    }
+
+    /////////// CHIPCommand Interface /////////
+    CHIP_ERROR RunCommand() override
+    {
+        auto & commissioner = CurrentCommissioner();
+        ReturnErrorOnFailure(commissioner.IssueNOCChain(mNOCSRElements, mNodeId, &mDeviceNOCChainCallback));
+        return CHIP_NO_ERROR;
+    }
+
+    chip::System::Clock::Timeout GetWaitDuration() const override { return chip::System::Clock::Seconds16(10); }
+
+    static void OnDeviceNOCChainGeneration(void * context, CHIP_ERROR status, const chip::ByteSpan & noc,
+                                           const chip::ByteSpan & icac, const chip::ByteSpan & rcac,
+                                           chip::Optional<chip::Crypto::IdentityProtectionKeySpan> ipk,
+                                           chip::Optional<chip::NodeId> adminSubject)
+    {
+        auto command = static_cast<IssueNOCChainCommand *>(context);
+
+        auto err = status;
+        VerifyOrReturn(CHIP_NO_ERROR == err, command->SetCommandExitStatus(err));
+
+        std::string nocStr;
+        err = ToTLVCert(noc, nocStr);
+        VerifyOrReturn(CHIP_NO_ERROR == err, command->SetCommandExitStatus(err));
+        ChipLogProgress(NotSpecified, "NOC: %s", nocStr.c_str());
+
+        std::string icacStr;
+        err = ToTLVCert(icac, icacStr);
+        VerifyOrReturn(CHIP_NO_ERROR == err, command->SetCommandExitStatus(err));
+        ChipLogProgress(NotSpecified, "ICAC: %s", icacStr.c_str());
+
+        std::string rcacStr;
+        err = ToTLVCert(rcac, rcacStr);
+        VerifyOrReturn(CHIP_NO_ERROR == err, command->SetCommandExitStatus(err));
+        ChipLogProgress(NotSpecified, "RCAC: %s", rcacStr.c_str());
+
+        std::string ipkStr;
+        if (ipk.HasValue())
+        {
+            err = ToBase64(ipk.Value(), ipkStr);
+            VerifyOrReturn(CHIP_NO_ERROR == err, command->SetCommandExitStatus(err));
+        }
+        ChipLogProgress(NotSpecified, "IPK: %s", ipkStr.c_str());
+
+        err = RemoteDataModelLogger::LogIssueNOCChain(nocStr.c_str(), icacStr.c_str(), rcacStr.c_str(), ipkStr.c_str());
+        command->SetCommandExitStatus(err);
+    }
+
+private:
+    chip::Callback::Callback<chip::Controller::OnNOCChainGeneration> mDeviceNOCChainCallback;
+    chip::ByteSpan mNOCSRElements;
+    chip::NodeId mNodeId;
+};
diff --git a/examples/fabric-admin/commands/pairing/OpenCommissioningWindowCommand.cpp b/examples/fabric-admin/commands/pairing/OpenCommissioningWindowCommand.cpp
new file mode 100644
index 0000000..bc4af6c
--- /dev/null
+++ b/examples/fabric-admin/commands/pairing/OpenCommissioningWindowCommand.cpp
@@ -0,0 +1,62 @@
+/*
+ *   Copyright (c) 2024 Project CHIP Authors
+ *   All rights reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+#include "OpenCommissioningWindowCommand.h"
+
+#include <system/SystemClock.h>
+
+using namespace ::chip;
+
+CHIP_ERROR OpenCommissioningWindowCommand::RunCommand()
+{
+    mWindowOpener = Platform::MakeUnique<Controller::CommissioningWindowOpener>(&CurrentCommissioner());
+    if (mCommissioningWindowOption == Controller::CommissioningWindowOpener::CommissioningWindowOption::kOriginalSetupCode)
+    {
+        return mWindowOpener->OpenBasicCommissioningWindow(mNodeId, System::Clock::Seconds16(mCommissioningWindowTimeout),
+                                                           &mOnOpenBasicCommissioningWindowCallback);
+    }
+
+    if (mCommissioningWindowOption == Controller::CommissioningWindowOpener::CommissioningWindowOption::kTokenWithRandomPIN)
+    {
+        SetupPayload ignored;
+        return mWindowOpener->OpenCommissioningWindow(mNodeId, System::Clock::Seconds16(mCommissioningWindowTimeout), mIteration,
+                                                      mDiscriminator, NullOptional, NullOptional,
+                                                      &mOnOpenCommissioningWindowCallback, ignored,
+                                                      /* readVIDPIDAttributes */ true);
+    }
+
+    ChipLogError(NotSpecified, "Unknown commissioning window option: %d", to_underlying(mCommissioningWindowOption));
+    return CHIP_ERROR_INVALID_ARGUMENT;
+}
+
+void OpenCommissioningWindowCommand::OnOpenCommissioningWindowResponse(void * context, NodeId remoteId, CHIP_ERROR err,
+                                                                       chip::SetupPayload payload)
+{
+    LogErrorOnFailure(err);
+
+    OnOpenBasicCommissioningWindowResponse(context, remoteId, err);
+}
+
+void OpenCommissioningWindowCommand::OnOpenBasicCommissioningWindowResponse(void * context, NodeId remoteId, CHIP_ERROR err)
+{
+    LogErrorOnFailure(err);
+
+    OpenCommissioningWindowCommand * command = reinterpret_cast<OpenCommissioningWindowCommand *>(context);
+    VerifyOrReturn(command != nullptr, ChipLogError(NotSpecified, "OnOpenCommissioningWindowCommand: context is null"));
+    command->SetCommandExitStatus(err);
+}
diff --git a/examples/fabric-admin/commands/pairing/OpenCommissioningWindowCommand.h b/examples/fabric-admin/commands/pairing/OpenCommissioningWindowCommand.h
new file mode 100644
index 0000000..99b179d
--- /dev/null
+++ b/examples/fabric-admin/commands/pairing/OpenCommissioningWindowCommand.h
@@ -0,0 +1,67 @@
+/*
+ *   Copyright (c) 2024 Project CHIP Authors
+ *   All rights reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+#pragma once
+
+#include "../common/CHIPCommand.h"
+
+#include <controller/CommissioningWindowOpener.h>
+#include <lib/support/CHIPMem.h>
+
+class OpenCommissioningWindowCommand : public CHIPCommand
+{
+public:
+    OpenCommissioningWindowCommand(CredentialIssuerCommands * credIssuerCommands) :
+        CHIPCommand("open-commissioning-window", credIssuerCommands),
+        mOnOpenCommissioningWindowCallback(OnOpenCommissioningWindowResponse, this),
+        mOnOpenBasicCommissioningWindowCallback(OnOpenBasicCommissioningWindowResponse, this)
+    {
+        AddArgument("node-id", 0, UINT64_MAX, &mNodeId, "Node to send command to.");
+        AddArgument("option", 0, 2, &mCommissioningWindowOption,
+                    "1 to use Enhanced Commissioning Method.\n  0 to use Basic Commissioning Method.");
+        AddArgument("window-timeout", 0, UINT16_MAX, &mCommissioningWindowTimeout,
+                    "Time, in seconds, before the commissioning window closes.");
+        AddArgument("iteration", chip::Crypto::kSpake2p_Min_PBKDF_Iterations, chip::Crypto::kSpake2p_Max_PBKDF_Iterations,
+                    &mIteration, "Number of PBKDF iterations to use to derive the verifier.  Ignored if 'option' is 0.");
+        AddArgument("discriminator", 0, 4096, &mDiscriminator, "Discriminator to use for advertising.  Ignored if 'option' is 0.");
+        AddArgument("timeout", 0, UINT16_MAX, &mTimeout, "Time, in seconds, before this command is considered to have timed out.");
+    }
+
+    /////////// CHIPCommand Interface /////////
+    CHIP_ERROR RunCommand() override;
+    // We issue multiple data model operations for this command, and the default
+    // timeout for those is 10 seconds, so default to 20 seconds.
+    chip::System::Clock::Timeout GetWaitDuration() const override { return chip::System::Clock::Seconds16(mTimeout.ValueOr(20)); }
+
+private:
+    NodeId mNodeId;
+    chip::Controller::CommissioningWindowOpener::CommissioningWindowOption mCommissioningWindowOption;
+    uint16_t mCommissioningWindowTimeout;
+    uint32_t mIteration;
+    uint16_t mDiscriminator;
+
+    chip::Optional<uint16_t> mTimeout;
+
+    chip::Platform::UniquePtr<chip::Controller::CommissioningWindowOpener> mWindowOpener;
+
+    static void OnOpenCommissioningWindowResponse(void * context, NodeId deviceId, CHIP_ERROR status, chip::SetupPayload payload);
+    static void OnOpenBasicCommissioningWindowResponse(void * context, NodeId deviceId, CHIP_ERROR status);
+
+    chip::Callback::Callback<chip::Controller::OnOpenCommissioningWindow> mOnOpenCommissioningWindowCallback;
+    chip::Callback::Callback<chip::Controller::OnOpenBasicCommissioningWindow> mOnOpenBasicCommissioningWindowCallback;
+};
diff --git a/examples/fabric-admin/commands/pairing/PairingCommand.cpp b/examples/fabric-admin/commands/pairing/PairingCommand.cpp
new file mode 100644
index 0000000..80775f0
--- /dev/null
+++ b/examples/fabric-admin/commands/pairing/PairingCommand.cpp
@@ -0,0 +1,551 @@
+/*
+ *   Copyright (c) 2024 Project CHIP Authors
+ *   All rights reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+#include "PairingCommand.h"
+#include "platform/PlatformManager.h"
+#include <commands/common/DeviceScanner.h>
+#include <controller/ExampleOperationalCredentialsIssuer.h>
+#include <crypto/CHIPCryptoPAL.h>
+#include <lib/core/CHIPSafeCasts.h>
+#include <lib/support/logging/CHIPLogging.h>
+#include <protocols/secure_channel/PASESession.h>
+
+#include <setup_payload/ManualSetupPayloadParser.h>
+#include <setup_payload/QRCodeSetupPayloadParser.h>
+
+#include <string>
+
+using namespace ::chip;
+using namespace ::chip::Controller;
+
+CHIP_ERROR PairingCommand::RunCommand()
+{
+    CurrentCommissioner().RegisterPairingDelegate(this);
+    // Clear the CATs in OperationalCredentialsIssuer
+    mCredIssuerCmds->SetCredentialIssuerCATValues(kUndefinedCATs);
+
+    mDeviceIsICD = false;
+
+    if (mCASEAuthTags.HasValue() && mCASEAuthTags.Value().size() <= kMaxSubjectCATAttributeCount)
+    {
+        CATValues cats = kUndefinedCATs;
+        for (size_t index = 0; index < mCASEAuthTags.Value().size(); ++index)
+        {
+            cats.values[index] = mCASEAuthTags.Value()[index];
+        }
+        if (cats.AreValid())
+        {
+            mCredIssuerCmds->SetCredentialIssuerCATValues(cats);
+        }
+    }
+    return RunInternal(mNodeId);
+}
+
+CHIP_ERROR PairingCommand::RunInternal(NodeId remoteId)
+{
+    CHIP_ERROR err = CHIP_NO_ERROR;
+
+    switch (mPairingMode)
+    {
+    case PairingMode::None:
+        err = Unpair(remoteId);
+        break;
+    case PairingMode::Code:
+        err = PairWithCode(remoteId);
+        break;
+    case PairingMode::CodePaseOnly:
+        err = PaseWithCode(remoteId);
+        break;
+    case PairingMode::Ble:
+        err = Pair(remoteId, PeerAddress::BLE());
+        break;
+    case PairingMode::OnNetwork:
+        err = PairWithMdns(remoteId);
+        break;
+    case PairingMode::SoftAP:
+        err = Pair(remoteId, PeerAddress::UDP(mRemoteAddr.address, mRemotePort, mRemoteAddr.interfaceId));
+        break;
+    case PairingMode::AlreadyDiscovered:
+        err = Pair(remoteId, PeerAddress::UDP(mRemoteAddr.address, mRemotePort, mRemoteAddr.interfaceId));
+        break;
+    case PairingMode::AlreadyDiscoveredByIndex:
+        err = PairWithMdnsOrBleByIndex(remoteId, mIndex);
+        break;
+    case PairingMode::AlreadyDiscoveredByIndexWithCode:
+        err = PairWithMdnsOrBleByIndexWithCode(remoteId, mIndex);
+        break;
+    }
+
+    return err;
+}
+
+CommissioningParameters PairingCommand::GetCommissioningParameters()
+{
+    auto params = CommissioningParameters();
+    params.SetSkipCommissioningComplete(mSkipCommissioningComplete.ValueOr(false));
+    if (mBypassAttestationVerifier.ValueOr(false))
+    {
+        params.SetDeviceAttestationDelegate(this);
+    }
+
+    switch (mNetworkType)
+    {
+    case PairingNetworkType::WiFi:
+        params.SetWiFiCredentials(Controller::WiFiCredentials(mSSID, mPassword));
+        break;
+    case PairingNetworkType::Thread:
+        params.SetThreadOperationalDataset(mOperationalDataset);
+        break;
+    case PairingNetworkType::None:
+        break;
+    }
+
+    if (mCountryCode.HasValue())
+    {
+        params.SetCountryCode(CharSpan::fromCharString(mCountryCode.Value()));
+    }
+
+    // mTimeZoneList is an optional argument managed by TypedComplexArgument mComplex_TimeZones.
+    // Since optional Complex arguments are not currently supported via the <chip::Optional> class,
+    // we will use mTimeZoneList.data() value to determine if the argument was provided.
+    if (mTimeZoneList.data())
+    {
+        params.SetTimeZone(mTimeZoneList);
+    }
+
+    // miDSTOffsetList is an optional argument managed by TypedComplexArgument mComplex_DSTOffsets.
+    // Since optional Complex arguments are not currently supported via the <chip::Optional> class,
+    // we will use mTimeZoneList.data() value to determine if the argument was provided.
+    if (mDSTOffsetList.data())
+    {
+        params.SetDSTOffsets(mDSTOffsetList);
+    }
+
+    if (mICDRegistration.ValueOr(false))
+    {
+        params.SetICDRegistrationStrategy(ICDRegistrationStrategy::kBeforeComplete);
+
+        if (!mICDSymmetricKey.HasValue())
+        {
+            chip::Crypto::DRBG_get_bytes(mRandomGeneratedICDSymmetricKey, sizeof(mRandomGeneratedICDSymmetricKey));
+            mICDSymmetricKey.SetValue(ByteSpan(mRandomGeneratedICDSymmetricKey));
+        }
+        if (!mICDCheckInNodeId.HasValue())
+        {
+            mICDCheckInNodeId.SetValue(CurrentCommissioner().GetNodeId());
+        }
+        if (!mICDMonitoredSubject.HasValue())
+        {
+            mICDMonitoredSubject.SetValue(mICDCheckInNodeId.Value());
+        }
+        // These Optionals must have values now.
+        // The commissioner will verify these values.
+        params.SetICDSymmetricKey(mICDSymmetricKey.Value());
+        if (mICDStayActiveDurationMsec.HasValue())
+        {
+            params.SetICDStayActiveDurationMsec(mICDStayActiveDurationMsec.Value());
+        }
+        params.SetICDCheckInNodeId(mICDCheckInNodeId.Value());
+        params.SetICDMonitoredSubject(mICDMonitoredSubject.Value());
+    }
+
+    return params;
+}
+
+CHIP_ERROR PairingCommand::PaseWithCode(NodeId remoteId)
+{
+    auto discoveryType = DiscoveryType::kAll;
+    if (mUseOnlyOnNetworkDiscovery.ValueOr(false))
+    {
+        discoveryType = DiscoveryType::kDiscoveryNetworkOnly;
+    }
+
+    if (mDiscoverOnce.ValueOr(false))
+    {
+        discoveryType = DiscoveryType::kDiscoveryNetworkOnlyWithoutPASEAutoRetry;
+    }
+
+    return CurrentCommissioner().EstablishPASEConnection(remoteId, mOnboardingPayload, discoveryType);
+}
+
+CHIP_ERROR PairingCommand::PairWithCode(NodeId remoteId)
+{
+    CommissioningParameters commissioningParams = GetCommissioningParameters();
+
+    // If no network discovery behavior and no network credentials are provided, assume that the pairing command is trying to pair
+    // with an on-network device.
+    if (!mUseOnlyOnNetworkDiscovery.HasValue())
+    {
+        auto threadCredentials = commissioningParams.GetThreadOperationalDataset();
+        auto wiFiCredentials   = commissioningParams.GetWiFiCredentials();
+        mUseOnlyOnNetworkDiscovery.SetValue(!threadCredentials.HasValue() && !wiFiCredentials.HasValue());
+    }
+
+    auto discoveryType = DiscoveryType::kAll;
+    if (mUseOnlyOnNetworkDiscovery.ValueOr(false))
+    {
+        discoveryType = DiscoveryType::kDiscoveryNetworkOnly;
+    }
+
+    if (mDiscoverOnce.ValueOr(false))
+    {
+        discoveryType = DiscoveryType::kDiscoveryNetworkOnlyWithoutPASEAutoRetry;
+    }
+
+    return CurrentCommissioner().PairDevice(remoteId, mOnboardingPayload, commissioningParams, discoveryType);
+}
+
+CHIP_ERROR PairingCommand::Pair(NodeId remoteId, PeerAddress address)
+{
+    auto params = RendezvousParameters().SetSetupPINCode(mSetupPINCode).SetDiscriminator(mDiscriminator).SetPeerAddress(address);
+
+    CHIP_ERROR err = CHIP_NO_ERROR;
+    if (mPaseOnly.ValueOr(false))
+    {
+        err = CurrentCommissioner().EstablishPASEConnection(remoteId, params);
+    }
+    else
+    {
+        auto commissioningParams = GetCommissioningParameters();
+        err                      = CurrentCommissioner().PairDevice(remoteId, params, commissioningParams);
+    }
+    return err;
+}
+
+CHIP_ERROR PairingCommand::PairWithMdnsOrBleByIndex(NodeId remoteId, uint16_t index)
+{
+#if CHIP_DEVICE_LAYER_TARGET_DARWIN
+    VerifyOrReturnError(IsInteractive(), CHIP_ERROR_INCORRECT_STATE);
+
+    RendezvousParameters params;
+    ReturnErrorOnFailure(GetDeviceScanner().Get(index, params));
+    params.SetSetupPINCode(mSetupPINCode);
+
+    CHIP_ERROR err = CHIP_NO_ERROR;
+    if (mPaseOnly.ValueOr(false))
+    {
+        err = CurrentCommissioner().EstablishPASEConnection(remoteId, params);
+    }
+    else
+    {
+        auto commissioningParams = GetCommissioningParameters();
+        err                      = CurrentCommissioner().PairDevice(remoteId, params, commissioningParams);
+    }
+    return err;
+#else
+    return CHIP_ERROR_NOT_IMPLEMENTED;
+#endif // CHIP_DEVICE_LAYER_TARGET_DARWIN
+}
+
+CHIP_ERROR PairingCommand::PairWithMdnsOrBleByIndexWithCode(NodeId remoteId, uint16_t index)
+{
+#if CHIP_DEVICE_LAYER_TARGET_DARWIN
+    VerifyOrReturnError(IsInteractive(), CHIP_ERROR_INCORRECT_STATE);
+
+    Dnssd::CommonResolutionData resolutionData;
+    auto err = GetDeviceScanner().Get(index, resolutionData);
+    if (CHIP_ERROR_NOT_FOUND == err)
+    {
+        // There is no device with this index that has some resolution data. This could simply
+        // be because the device is a ble device. In this case let's fall back to looking for
+        // a device with this index and some RendezvousParameters.
+        chip::SetupPayload payload;
+        bool isQRCode = strncmp(mOnboardingPayload, kQRCodePrefix, strlen(kQRCodePrefix)) == 0;
+        if (isQRCode)
+        {
+            ReturnErrorOnFailure(QRCodeSetupPayloadParser(mOnboardingPayload).populatePayload(payload));
+            VerifyOrReturnError(payload.isValidQRCodePayload(), CHIP_ERROR_INVALID_ARGUMENT);
+        }
+        else
+        {
+            ReturnErrorOnFailure(ManualSetupPayloadParser(mOnboardingPayload).populatePayload(payload));
+            VerifyOrReturnError(payload.isValidManualCode(), CHIP_ERROR_INVALID_ARGUMENT);
+        }
+
+        mSetupPINCode = payload.setUpPINCode;
+        return PairWithMdnsOrBleByIndex(remoteId, index);
+    }
+
+    err = CHIP_NO_ERROR;
+    if (mPaseOnly.ValueOr(false))
+    {
+        err = CurrentCommissioner().EstablishPASEConnection(remoteId, mOnboardingPayload, DiscoveryType::kDiscoveryNetworkOnly,
+                                                            MakeOptional(resolutionData));
+    }
+    else
+    {
+        auto commissioningParams = GetCommissioningParameters();
+        err                      = CurrentCommissioner().PairDevice(remoteId, mOnboardingPayload, commissioningParams,
+                                                                    DiscoveryType::kDiscoveryNetworkOnly, MakeOptional(resolutionData));
+    }
+    return err;
+#else
+    return CHIP_ERROR_NOT_IMPLEMENTED;
+#endif // CHIP_DEVICE_LAYER_TARGET_DARWIN
+}
+
+CHIP_ERROR PairingCommand::PairWithMdns(NodeId remoteId)
+{
+    Dnssd::DiscoveryFilter filter(mFilterType);
+    switch (mFilterType)
+    {
+    case chip::Dnssd::DiscoveryFilterType::kNone:
+        break;
+    case chip::Dnssd::DiscoveryFilterType::kShortDiscriminator:
+    case chip::Dnssd::DiscoveryFilterType::kLongDiscriminator:
+    case chip::Dnssd::DiscoveryFilterType::kCompressedFabricId:
+    case chip::Dnssd::DiscoveryFilterType::kVendorId:
+    case chip::Dnssd::DiscoveryFilterType::kDeviceType:
+        filter.code = mDiscoveryFilterCode;
+        break;
+    case chip::Dnssd::DiscoveryFilterType::kCommissioningMode:
+        break;
+    case chip::Dnssd::DiscoveryFilterType::kCommissioner:
+        filter.code = 1;
+        break;
+    case chip::Dnssd::DiscoveryFilterType::kInstanceName:
+        filter.code         = 0;
+        filter.instanceName = mDiscoveryFilterInstanceName;
+        break;
+    }
+
+    CurrentCommissioner().RegisterDeviceDiscoveryDelegate(this);
+    return CurrentCommissioner().DiscoverCommissionableNodes(filter);
+}
+
+CHIP_ERROR PairingCommand::Unpair(NodeId remoteId)
+{
+    mCurrentFabricRemover = Platform::MakeUnique<Controller::CurrentFabricRemover>(&CurrentCommissioner());
+    return mCurrentFabricRemover->RemoveCurrentFabric(remoteId, &mCurrentFabricRemoveCallback);
+}
+
+void PairingCommand::OnStatusUpdate(DevicePairingDelegate::Status status)
+{
+    switch (status)
+    {
+    case DevicePairingDelegate::Status::SecurePairingSuccess:
+        ChipLogProgress(NotSpecified, "Secure Pairing Success");
+        ChipLogProgress(NotSpecified, "CASE establishment successful");
+        break;
+    case DevicePairingDelegate::Status::SecurePairingFailed:
+        ChipLogError(NotSpecified, "Secure Pairing Failed");
+        SetCommandExitStatus(CHIP_ERROR_INCORRECT_STATE);
+        break;
+    }
+}
+
+void PairingCommand::OnPairingComplete(CHIP_ERROR err)
+{
+    if (err == CHIP_NO_ERROR)
+    {
+        ChipLogProgress(NotSpecified, "Pairing Success");
+        ChipLogProgress(NotSpecified, "PASE establishment successful");
+        if (mPairingMode == PairingMode::CodePaseOnly || mPaseOnly.ValueOr(false))
+        {
+            SetCommandExitStatus(err);
+        }
+    }
+    else
+    {
+        ChipLogProgress(NotSpecified, "Pairing Failure: %s", ErrorStr(err));
+    }
+
+    if (err != CHIP_NO_ERROR)
+    {
+        SetCommandExitStatus(err);
+    }
+}
+
+void PairingCommand::OnPairingDeleted(CHIP_ERROR err)
+{
+    if (err == CHIP_NO_ERROR)
+    {
+        ChipLogProgress(NotSpecified, "Pairing Deleted Success");
+    }
+    else
+    {
+        ChipLogProgress(NotSpecified, "Pairing Deleted Failure: %s", ErrorStr(err));
+    }
+
+    SetCommandExitStatus(err);
+}
+
+void PairingCommand::OnCommissioningComplete(NodeId nodeId, CHIP_ERROR err)
+{
+    if (err == CHIP_NO_ERROR)
+    {
+        ChipLogProgress(NotSpecified, "Device commissioning completed with success");
+    }
+    else
+    {
+        // When ICD device commissioning fails, the ICDClientInfo stored in OnICDRegistrationComplete needs to be removed.
+        if (mDeviceIsICD)
+        {
+            CHIP_ERROR deleteEntryError =
+                CHIPCommand::sICDClientStorage.DeleteEntry(ScopedNodeId(mNodeId, CurrentCommissioner().GetFabricIndex()));
+            if (deleteEntryError != CHIP_NO_ERROR)
+            {
+                ChipLogError(NotSpecified, "Failed to delete ICD entry: %s", ErrorStr(err));
+            }
+        }
+        ChipLogProgress(NotSpecified, "Device commissioning Failure: %s", ErrorStr(err));
+    }
+
+    SetCommandExitStatus(err);
+}
+
+void PairingCommand::OnReadCommissioningInfo(const Controller::ReadCommissioningInfo & info)
+{
+    ChipLogProgress(AppServer, "OnReadCommissioningInfo - vendorId=0x%04X productId=0x%04X", info.basic.vendorId,
+                    info.basic.productId);
+
+    // The string in CharSpan received from the device is not null-terminated, we use std::string here for coping and
+    // appending a numm-terminator at the end of the string.
+    std::string userActiveModeTriggerInstruction;
+
+    // Note: the callback doesn't own the buffer, should make a copy if it will be used it later.
+    if (info.icd.userActiveModeTriggerInstruction.size() != 0)
+    {
+        userActiveModeTriggerInstruction =
+            std::string(info.icd.userActiveModeTriggerInstruction.data(), info.icd.userActiveModeTriggerInstruction.size());
+    }
+
+    if (info.icd.userActiveModeTriggerHint.HasAny())
+    {
+        ChipLogProgress(AppServer, "OnReadCommissioningInfo - LIT UserActiveModeTriggerHint=0x%08x",
+                        info.icd.userActiveModeTriggerHint.Raw());
+        ChipLogProgress(AppServer, "OnReadCommissioningInfo - LIT UserActiveModeTriggerInstruction=%s",
+                        userActiveModeTriggerInstruction.c_str());
+    }
+    ChipLogProgress(AppServer, "OnReadCommissioningInfo ICD - IdleModeDuration=%u activeModeDuration=%u activeModeThreshold=%u",
+                    info.icd.idleModeDuration, info.icd.activeModeDuration, info.icd.activeModeThreshold);
+}
+
+void PairingCommand::OnICDRegistrationComplete(NodeId nodeId, uint32_t icdCounter)
+{
+    char icdSymmetricKeyHex[chip::Crypto::kAES_CCM128_Key_Length * 2 + 1];
+
+    chip::Encoding::BytesToHex(mICDSymmetricKey.Value().data(), mICDSymmetricKey.Value().size(), icdSymmetricKeyHex,
+                               sizeof(icdSymmetricKeyHex), chip::Encoding::HexFlags::kNullTerminate);
+
+    app::ICDClientInfo clientInfo;
+    clientInfo.peer_node         = ScopedNodeId(nodeId, CurrentCommissioner().GetFabricIndex());
+    clientInfo.monitored_subject = mICDMonitoredSubject.Value();
+    clientInfo.start_icd_counter = icdCounter;
+
+    CHIP_ERROR err = CHIPCommand::sICDClientStorage.SetKey(clientInfo, mICDSymmetricKey.Value());
+    if (err == CHIP_NO_ERROR)
+    {
+        err = CHIPCommand::sICDClientStorage.StoreEntry(clientInfo);
+    }
+
+    if (err != CHIP_NO_ERROR)
+    {
+        CHIPCommand::sICDClientStorage.RemoveKey(clientInfo);
+        ChipLogError(NotSpecified, "Failed to persist symmetric key for " ChipLogFormatX64 ": %s", ChipLogValueX64(nodeId),
+                     err.AsString());
+        SetCommandExitStatus(err);
+        return;
+    }
+
+    mDeviceIsICD = true;
+
+    ChipLogProgress(NotSpecified, "Saved ICD Symmetric key for " ChipLogFormatX64, ChipLogValueX64(nodeId));
+    ChipLogProgress(NotSpecified,
+                    "ICD Registration Complete for device " ChipLogFormatX64 " / Check-In NodeID: " ChipLogFormatX64
+                    " / Monitored Subject: " ChipLogFormatX64 " / Symmetric Key: %s / ICDCounter %u",
+                    ChipLogValueX64(nodeId), ChipLogValueX64(mICDCheckInNodeId.Value()),
+                    ChipLogValueX64(mICDMonitoredSubject.Value()), icdSymmetricKeyHex, icdCounter);
+}
+
+void PairingCommand::OnICDStayActiveComplete(NodeId deviceId, uint32_t promisedActiveDuration)
+{
+    ChipLogProgress(NotSpecified, "ICD Stay Active Complete for device " ChipLogFormatX64 " / promisedActiveDuration: %u",
+                    ChipLogValueX64(deviceId), promisedActiveDuration);
+}
+
+void PairingCommand::OnDiscoveredDevice(const chip::Dnssd::CommissionNodeData & nodeData)
+{
+    // Ignore nodes with closed commissioning window
+    VerifyOrReturn(nodeData.commissioningMode != 0);
+
+    auto & resolutionData = nodeData;
+
+    const uint16_t port = resolutionData.port;
+    char buf[chip::Inet::IPAddress::kMaxStringLength];
+    resolutionData.ipAddress[0].ToString(buf);
+    ChipLogProgress(NotSpecified, "Discovered Device: %s:%u", buf, port);
+
+    // Stop Mdns discovery.
+    auto err = CurrentCommissioner().StopCommissionableDiscovery();
+
+    // Some platforms does not implement a mechanism to stop mdns browse, so
+    // we just ignore CHIP_ERROR_NOT_IMPLEMENTED instead of bailing out.
+    if (CHIP_NO_ERROR != err && CHIP_ERROR_NOT_IMPLEMENTED != err)
+    {
+        SetCommandExitStatus(err);
+        return;
+    }
+
+    CurrentCommissioner().RegisterDeviceDiscoveryDelegate(nullptr);
+
+    auto interfaceId = resolutionData.ipAddress[0].IsIPv6LinkLocal() ? resolutionData.interfaceId : Inet::InterfaceId::Null();
+    auto peerAddress = PeerAddress::UDP(resolutionData.ipAddress[0], port, interfaceId);
+    err              = Pair(mNodeId, peerAddress);
+    if (CHIP_NO_ERROR != err)
+    {
+        SetCommandExitStatus(err);
+    }
+}
+
+void PairingCommand::OnCurrentFabricRemove(void * context, NodeId nodeId, CHIP_ERROR err)
+{
+    PairingCommand * command = reinterpret_cast<PairingCommand *>(context);
+    VerifyOrReturn(command != nullptr, ChipLogError(NotSpecified, "OnCurrentFabricRemove: context is null"));
+
+    if (err == CHIP_NO_ERROR)
+    {
+        ChipLogProgress(NotSpecified, "Device unpair completed with success: " ChipLogFormatX64, ChipLogValueX64(nodeId));
+    }
+    else
+    {
+        ChipLogProgress(NotSpecified, "Device unpair Failure: " ChipLogFormatX64 " %s", ChipLogValueX64(nodeId), ErrorStr(err));
+    }
+
+    command->SetCommandExitStatus(err);
+}
+
+chip::Optional<uint16_t> PairingCommand::FailSafeExpiryTimeoutSecs() const
+{
+    // We don't need to set additional failsafe timeout as we don't ask the final user if he wants to continue
+    return chip::Optional<uint16_t>();
+}
+
+void PairingCommand::OnDeviceAttestationCompleted(chip::Controller::DeviceCommissioner * deviceCommissioner,
+                                                  chip::DeviceProxy * device,
+                                                  const chip::Credentials::DeviceAttestationVerifier::AttestationDeviceInfo & info,
+                                                  chip::Credentials::AttestationVerificationResult attestationResult)
+{
+    // Bypass attestation verification, continue with success
+    auto err = deviceCommissioner->ContinueCommissioningAfterDeviceAttestation(
+        device, chip::Credentials::AttestationVerificationResult::kSuccess);
+    if (CHIP_NO_ERROR != err)
+    {
+        SetCommandExitStatus(err);
+    }
+}
diff --git a/examples/fabric-admin/commands/pairing/PairingCommand.h b/examples/fabric-admin/commands/pairing/PairingCommand.h
new file mode 100644
index 0000000..4ff3903
--- /dev/null
+++ b/examples/fabric-admin/commands/pairing/PairingCommand.h
@@ -0,0 +1,268 @@
+/*
+ *   Copyright (c) 2024 Project CHIP Authors
+ *   All rights reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+#pragma once
+
+#include "../common/CHIPCommand.h"
+#include <controller/CommissioningDelegate.h>
+#include <controller/CurrentFabricRemover.h>
+
+#include <commands/common/CredentialIssuerCommands.h>
+#include <lib/support/Span.h>
+#include <lib/support/ThreadOperationalDataset.h>
+
+enum class PairingMode
+{
+    None,
+    Code,
+    CodePaseOnly,
+    Ble,
+    SoftAP,
+    AlreadyDiscovered,
+    AlreadyDiscoveredByIndex,
+    AlreadyDiscoveredByIndexWithCode,
+    OnNetwork,
+};
+
+enum class PairingNetworkType
+{
+    None,
+    WiFi,
+    Thread,
+};
+
+class PairingCommand : public CHIPCommand,
+                       public chip::Controller::DevicePairingDelegate,
+                       public chip::Controller::DeviceDiscoveryDelegate,
+                       public chip::Credentials::DeviceAttestationDelegate
+{
+public:
+    PairingCommand(const char * commandName, PairingMode mode, PairingNetworkType networkType,
+                   CredentialIssuerCommands * credIssuerCmds,
+                   chip::Dnssd::DiscoveryFilterType filterType = chip::Dnssd::DiscoveryFilterType::kNone) :
+        CHIPCommand(commandName, credIssuerCmds),
+        mPairingMode(mode), mNetworkType(networkType), mFilterType(filterType),
+        mRemoteAddr{ IPAddress::Any, chip::Inet::InterfaceId::Null() }, mComplex_TimeZones(&mTimeZoneList),
+        mComplex_DSTOffsets(&mDSTOffsetList), mCurrentFabricRemoveCallback(OnCurrentFabricRemove, this)
+    {
+        AddArgument("node-id", 0, UINT64_MAX, &mNodeId);
+        AddArgument("bypass-attestation-verifier", 0, 1, &mBypassAttestationVerifier,
+                    "Bypass the attestation verifier. If not provided or false, the attestation verifier is not bypassed."
+                    " If true, the commissioning will continue in case of attestation verification failure.");
+        AddArgument("case-auth-tags", 1, UINT32_MAX, &mCASEAuthTags, "The CATs to be encoded in the NOC sent to the commissionee");
+        AddArgument("icd-registration", 0, 1, &mICDRegistration,
+                    "Whether to register for check-ins from ICDs during commissioning. Default: false");
+        AddArgument("icd-check-in-nodeid", 0, UINT64_MAX, &mICDCheckInNodeId,
+                    "The check-in node id for the ICD, default: node id of the commissioner.");
+        AddArgument("icd-monitored-subject", 0, UINT64_MAX, &mICDMonitoredSubject,
+                    "The monitored subject of the ICD, default: The node id used for icd-check-in-nodeid.");
+        AddArgument("icd-symmetric-key", &mICDSymmetricKey, "The 16 bytes ICD symmetric key, default: randomly generated.");
+        AddArgument("icd-stay-active-duration", 0, UINT32_MAX, &mICDStayActiveDurationMsec,
+                    "If set, a LIT ICD that is commissioned will be requested to stay active for this many milliseconds");
+        switch (networkType)
+        {
+        case PairingNetworkType::None:
+            break;
+        case PairingNetworkType::WiFi:
+            AddArgument("ssid", &mSSID);
+            AddArgument("password", &mPassword);
+            break;
+        case PairingNetworkType::Thread:
+            AddArgument("operationalDataset", &mOperationalDataset);
+            break;
+        }
+
+        switch (mode)
+        {
+        case PairingMode::None:
+            break;
+        case PairingMode::Code:
+            AddArgument("skip-commissioning-complete", 0, 1, &mSkipCommissioningComplete);
+            FALLTHROUGH;
+        case PairingMode::CodePaseOnly:
+            AddArgument("payload", &mOnboardingPayload);
+            AddArgument("discover-once", 0, 1, &mDiscoverOnce);
+            AddArgument("use-only-onnetwork-discovery", 0, 1, &mUseOnlyOnNetworkDiscovery);
+            break;
+        case PairingMode::Ble:
+            AddArgument("skip-commissioning-complete", 0, 1, &mSkipCommissioningComplete);
+            AddArgument("setup-pin-code", 0, 134217727, &mSetupPINCode);
+            AddArgument("discriminator", 0, 4096, &mDiscriminator);
+            break;
+        case PairingMode::OnNetwork:
+            AddArgument("skip-commissioning-complete", 0, 1, &mSkipCommissioningComplete);
+            AddArgument("setup-pin-code", 0, 134217727, &mSetupPINCode);
+            AddArgument("pase-only", 0, 1, &mPaseOnly);
+            break;
+        case PairingMode::SoftAP:
+            AddArgument("skip-commissioning-complete", 0, 1, &mSkipCommissioningComplete);
+            AddArgument("setup-pin-code", 0, 134217727, &mSetupPINCode);
+            AddArgument("discriminator", 0, 4096, &mDiscriminator);
+            AddArgument("device-remote-ip", &mRemoteAddr);
+            AddArgument("device-remote-port", 0, UINT16_MAX, &mRemotePort);
+            AddArgument("pase-only", 0, 1, &mPaseOnly);
+            break;
+        case PairingMode::AlreadyDiscovered:
+            AddArgument("skip-commissioning-complete", 0, 1, &mSkipCommissioningComplete);
+            AddArgument("setup-pin-code", 0, 134217727, &mSetupPINCode);
+            AddArgument("device-remote-ip", &mRemoteAddr);
+            AddArgument("device-remote-port", 0, UINT16_MAX, &mRemotePort);
+            AddArgument("pase-only", 0, 1, &mPaseOnly);
+            break;
+        case PairingMode::AlreadyDiscoveredByIndex:
+            AddArgument("skip-commissioning-complete", 0, 1, &mSkipCommissioningComplete);
+            AddArgument("setup-pin-code", 0, 134217727, &mSetupPINCode);
+            AddArgument("index", 0, UINT16_MAX, &mIndex);
+            AddArgument("pase-only", 0, 1, &mPaseOnly);
+            break;
+        case PairingMode::AlreadyDiscoveredByIndexWithCode:
+            AddArgument("skip-commissioning-complete", 0, 1, &mSkipCommissioningComplete);
+            AddArgument("payload", &mOnboardingPayload);
+            AddArgument("index", 0, UINT16_MAX, &mIndex);
+            AddArgument("pase-only", 0, 1, &mPaseOnly);
+            break;
+        }
+
+        switch (filterType)
+        {
+        case chip::Dnssd::DiscoveryFilterType::kNone:
+            break;
+        case chip::Dnssd::DiscoveryFilterType::kShortDiscriminator:
+            AddArgument("discriminator", 0, 15, &mDiscoveryFilterCode);
+            break;
+        case chip::Dnssd::DiscoveryFilterType::kLongDiscriminator:
+            AddArgument("discriminator", 0, 4096, &mDiscoveryFilterCode);
+            break;
+        case chip::Dnssd::DiscoveryFilterType::kVendorId:
+            AddArgument("vendor-id", 0, UINT16_MAX, &mDiscoveryFilterCode);
+            break;
+        case chip::Dnssd::DiscoveryFilterType::kCompressedFabricId:
+            AddArgument("fabric-id", 0, UINT64_MAX, &mDiscoveryFilterCode);
+            break;
+        case chip::Dnssd::DiscoveryFilterType::kCommissioningMode:
+        case chip::Dnssd::DiscoveryFilterType::kCommissioner:
+            break;
+        case chip::Dnssd::DiscoveryFilterType::kDeviceType:
+            AddArgument("device-type", 0, UINT16_MAX, &mDiscoveryFilterCode);
+            break;
+        case chip::Dnssd::DiscoveryFilterType::kInstanceName:
+            AddArgument("name", &mDiscoveryFilterInstanceName);
+            break;
+        }
+
+        if (mode != PairingMode::None)
+        {
+            AddArgument("country-code", &mCountryCode,
+                        "Country code to use to set the Basic Information cluster's Location attribute");
+
+            // mTimeZoneList is an optional argument managed by TypedComplexArgument mComplex_TimeZones.
+            // Since optional Complex arguments are not currently supported via the <chip::Optional> class,
+            // we explicitly set the kOptional flag.
+            AddArgument("time-zone", &mComplex_TimeZones,
+                        "TimeZone list to use when setting Time Synchronization cluster's TimeZone attribute", Argument::kOptional);
+
+            // mDSTOffsetList is an optional argument managed by TypedComplexArgument mComplex_DSTOffsets.
+            // Since optional Complex arguments are not currently supported via the <chip::Optional> class,
+            // we explicitly set the kOptional flag.
+            AddArgument("dst-offset", &mComplex_DSTOffsets,
+                        "DSTOffset list to use when setting Time Synchronization cluster's DSTOffset attribute",
+                        Argument::kOptional);
+        }
+
+        AddArgument("timeout", 0, UINT16_MAX, &mTimeout);
+    }
+
+    /////////// CHIPCommand Interface /////////
+    CHIP_ERROR RunCommand() override;
+    chip::System::Clock::Timeout GetWaitDuration() const override { return chip::System::Clock::Seconds16(mTimeout.ValueOr(120)); }
+
+    /////////// DevicePairingDelegate Interface /////////
+    void OnStatusUpdate(chip::Controller::DevicePairingDelegate::Status status) override;
+    void OnPairingComplete(CHIP_ERROR error) override;
+    void OnPairingDeleted(CHIP_ERROR error) override;
+    void OnReadCommissioningInfo(const chip::Controller::ReadCommissioningInfo & info) override;
+    void OnCommissioningComplete(NodeId deviceId, CHIP_ERROR error) override;
+    void OnICDRegistrationComplete(NodeId deviceId, uint32_t icdCounter) override;
+    void OnICDStayActiveComplete(NodeId deviceId, uint32_t promisedActiveDuration) override;
+
+    /////////// DeviceDiscoveryDelegate Interface /////////
+    void OnDiscoveredDevice(const chip::Dnssd::CommissionNodeData & nodeData) override;
+
+    /////////// DeviceAttestationDelegate /////////
+    chip::Optional<uint16_t> FailSafeExpiryTimeoutSecs() const override;
+    void OnDeviceAttestationCompleted(chip::Controller::DeviceCommissioner * deviceCommissioner, chip::DeviceProxy * device,
+                                      const chip::Credentials::DeviceAttestationVerifier::AttestationDeviceInfo & info,
+                                      chip::Credentials::AttestationVerificationResult attestationResult) override;
+
+private:
+    CHIP_ERROR RunInternal(NodeId remoteId);
+    CHIP_ERROR Pair(NodeId remoteId, PeerAddress address);
+    CHIP_ERROR PairWithMdns(NodeId remoteId);
+    CHIP_ERROR PairWithCode(NodeId remoteId);
+    CHIP_ERROR PaseWithCode(NodeId remoteId);
+    CHIP_ERROR PairWithMdnsOrBleByIndex(NodeId remoteId, uint16_t index);
+    CHIP_ERROR PairWithMdnsOrBleByIndexWithCode(NodeId remoteId, uint16_t index);
+    CHIP_ERROR Unpair(NodeId remoteId);
+    chip::Controller::CommissioningParameters GetCommissioningParameters();
+
+    const PairingMode mPairingMode;
+    const PairingNetworkType mNetworkType;
+    const chip::Dnssd::DiscoveryFilterType mFilterType;
+    Command::AddressWithInterface mRemoteAddr;
+    NodeId mNodeId;
+    chip::Optional<uint16_t> mTimeout;
+    chip::Optional<bool> mDiscoverOnce;
+    chip::Optional<bool> mUseOnlyOnNetworkDiscovery;
+    chip::Optional<bool> mPaseOnly;
+    chip::Optional<bool> mSkipCommissioningComplete;
+    chip::Optional<bool> mBypassAttestationVerifier;
+    chip::Optional<std::vector<uint32_t>> mCASEAuthTags;
+    chip::Optional<char *> mCountryCode;
+    chip::Optional<bool> mICDRegistration;
+    chip::Optional<NodeId> mICDCheckInNodeId;
+    chip::Optional<chip::ByteSpan> mICDSymmetricKey;
+    chip::Optional<uint64_t> mICDMonitoredSubject;
+    chip::Optional<uint32_t> mICDStayActiveDurationMsec;
+    chip::app::DataModel::List<chip::app::Clusters::TimeSynchronization::Structs::TimeZoneStruct::Type> mTimeZoneList;
+    TypedComplexArgument<chip::app::DataModel::List<chip::app::Clusters::TimeSynchronization::Structs::TimeZoneStruct::Type>>
+        mComplex_TimeZones;
+    chip::app::DataModel::List<chip::app::Clusters::TimeSynchronization::Structs::DSTOffsetStruct::Type> mDSTOffsetList;
+    TypedComplexArgument<chip::app::DataModel::List<chip::app::Clusters::TimeSynchronization::Structs::DSTOffsetStruct::Type>>
+        mComplex_DSTOffsets;
+
+    uint16_t mRemotePort;
+    uint16_t mDiscriminator;
+    uint32_t mSetupPINCode;
+    uint16_t mIndex;
+    chip::ByteSpan mOperationalDataset;
+    chip::ByteSpan mSSID;
+    chip::ByteSpan mPassword;
+    char * mOnboardingPayload;
+    uint64_t mDiscoveryFilterCode;
+    char * mDiscoveryFilterInstanceName;
+
+    bool mDeviceIsICD;
+    uint8_t mRandomGeneratedICDSymmetricKey[chip::Crypto::kAES_CCM128_Key_Length];
+
+    // For unpair
+    chip::Platform::UniquePtr<chip::Controller::CurrentFabricRemover> mCurrentFabricRemover;
+    chip::Callback::Callback<chip::Controller::OnCurrentFabricRemove> mCurrentFabricRemoveCallback;
+
+    static void OnCurrentFabricRemove(void * context, NodeId remoteNodeId, CHIP_ERROR status);
+    void PersistIcdInfo();
+};
diff --git a/examples/fabric-admin/commands/pairing/ToTLVCert.cpp b/examples/fabric-admin/commands/pairing/ToTLVCert.cpp
new file mode 100644
index 0000000..01f9156
--- /dev/null
+++ b/examples/fabric-admin/commands/pairing/ToTLVCert.cpp
@@ -0,0 +1,54 @@
+/*
+ *   Copyright (c) 2024 Project CHIP Authors
+ *   All rights reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+#include "ToTLVCert.h"
+
+#include <credentials/CHIPCert.h>
+#include <lib/support/Base64.h>
+
+#include <string>
+
+constexpr char kBase64Header[]    = "base64:";
+constexpr size_t kBase64HeaderLen = ArraySize(kBase64Header) - 1;
+
+CHIP_ERROR ToBase64(const chip::ByteSpan & input, std::string & outputAsPrefixedBase64)
+{
+    chip::Platform::ScopedMemoryBuffer<char> base64String;
+    base64String.Alloc(kBase64HeaderLen + BASE64_ENCODED_LEN(input.size()) + 1);
+    VerifyOrReturnError(base64String.Get() != nullptr, CHIP_ERROR_NO_MEMORY);
+
+    auto encodedLen = chip::Base64Encode(input.data(), static_cast<uint16_t>(input.size()), base64String.Get() + kBase64HeaderLen);
+    if (encodedLen)
+    {
+        memcpy(base64String.Get(), kBase64Header, kBase64HeaderLen);
+        encodedLen = static_cast<uint16_t>(encodedLen + kBase64HeaderLen);
+    }
+    base64String.Get()[encodedLen] = '\0';
+    outputAsPrefixedBase64         = std::string(base64String.Get(), encodedLen);
+
+    return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR ToTLVCert(const chip::ByteSpan & derEncodedCertificate, std::string & tlvCertAsPrefixedBase64)
+{
+    uint8_t chipCertBuffer[chip::Credentials::kMaxCHIPCertLength];
+    chip::MutableByteSpan chipCertBytes(chipCertBuffer);
+    ReturnErrorOnFailure(chip::Credentials::ConvertX509CertToChipCert(derEncodedCertificate, chipCertBytes));
+    ReturnErrorOnFailure(ToBase64(chipCertBytes, tlvCertAsPrefixedBase64));
+    return CHIP_NO_ERROR;
+}
diff --git a/examples/fabric-admin/commands/pairing/ToTLVCert.h b/examples/fabric-admin/commands/pairing/ToTLVCert.h
new file mode 100644
index 0000000..2995647
--- /dev/null
+++ b/examples/fabric-admin/commands/pairing/ToTLVCert.h
@@ -0,0 +1,25 @@
+/*
+ *   Copyright (c) 2024 Project CHIP Authors
+ *   All rights reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+#pragma once
+
+#include <lib/support/Span.h>
+#include <string>
+
+CHIP_ERROR ToBase64(const chip::ByteSpan & input, std::string & outputAsPrefixedBase64);
+CHIP_ERROR ToTLVCert(const chip::ByteSpan & derEncodedCertificate, std::string & tlvCertAsPrefixedBase64);
diff --git a/examples/fabric-admin/fabric-admin.gni b/examples/fabric-admin/fabric-admin.gni
new file mode 100644
index 0000000..021ab77
--- /dev/null
+++ b/examples/fabric-admin/fabric-admin.gni
@@ -0,0 +1,22 @@
+# Copyright (c) 2024 Project CHIP Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("//build_overrides/build.gni")
+import("//build_overrides/chip.gni")
+
+declare_args() {
+  # Use a separate eventloop for CHIP tasks
+  config_use_separate_eventloop = true
+  config_use_local_storage = true
+}
diff --git a/examples/fabric-admin/include/CHIPProjectAppConfig.h b/examples/fabric-admin/include/CHIPProjectAppConfig.h
new file mode 100644
index 0000000..b3f85d6
--- /dev/null
+++ b/examples/fabric-admin/include/CHIPProjectAppConfig.h
@@ -0,0 +1,67 @@
+/*
+ *
+ *    Copyright (c) 2024 Project CHIP Authors
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+/**
+ *    @file
+ *      Project configuration for Fabric Admin.
+ *
+ */
+#ifndef CHIPPROJECTCONFIG_H
+#define CHIPPROJECTCONFIG_H
+
+#define CHIP_CONFIG_MAX_FABRICS 17
+
+#define CHIP_CONFIG_EVENT_LOGGING_NUM_EXTERNAL_CALLBACKS 2
+
+// Uncomment this for a large Tunnel MTU.
+// #define CHIP_CONFIG_TUNNEL_INTERFACE_MTU                           (9000)
+
+// Enable support functions for parsing command-line arguments
+#define CHIP_CONFIG_ENABLE_ARG_PARSER 1
+
+// Use a default pairing code if one hasn't been provisioned in flash.
+#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE 20202021
+#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR 0xF00
+
+// Enable reading DRBG seed data from /dev/(u)random.
+// This is needed for test applications and the CHIP device manager to function
+// properly when CHIP_CONFIG_RNG_IMPLEMENTATION_CHIPDRBG is enabled.
+#define CHIP_CONFIG_DEV_RANDOM_DRBG_SEED 1
+
+// For convenience, Chip Security Test Mode can be enabled and the
+// requirement for authentication in various protocols can be disabled.
+//
+//    WARNING: These options make it possible to circumvent basic Chip security functionality,
+//    including message encryption. Because of this they MUST NEVER BE ENABLED IN PRODUCTION BUILDS.
+//
+#define CHIP_CONFIG_SECURITY_TEST_MODE 0
+
+#define CHIP_CONFIG_ENABLE_UPDATE 1
+
+#define CHIP_SYSTEM_CONFIG_PACKETBUFFER_POOL_SIZE 0
+
+#define CHIP_CONFIG_DATA_MANAGEMENT_CLIENT_EXPERIMENTAL 1
+
+#define CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY 1
+
+// Enable some test-only interaction model APIs.
+#define CONFIG_BUILD_FOR_HOST_UNIT_TEST 1
+
+// Allow us, for test purposes, to encode invalid enum values.
+#define CHIP_CONFIG_IM_ENABLE_ENCODING_SENTINEL_ENUM_VALUES 1
+
+#endif /* CHIPPROJECTCONFIG_H */
diff --git a/examples/fabric-admin/main.cpp b/examples/fabric-admin/main.cpp
new file mode 100644
index 0000000..e517c67
--- /dev/null
+++ b/examples/fabric-admin/main.cpp
@@ -0,0 +1,40 @@
+/*
+ *   Copyright (c) 2024 Project CHIP Authors
+ *   All rights reserved.
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+#include "commands/common/Commands.h"
+
+#include "commands/clusters/SubscriptionsCommands.h"
+#include "commands/interactive/Commands.h"
+#include "commands/pairing/Commands.h"
+#include <zap-generated/cluster/Commands.h>
+
+// ================================================================================
+// Main Code
+// ================================================================================
+int main(int argc, char * argv[])
+{
+    ExampleCredentialIssuerCommands credIssuerCommands;
+    Commands commands;
+
+    registerCommandsInteractive(commands, &credIssuerCommands);
+    registerCommandsPairing(commands, &credIssuerCommands);
+    registerClusters(commands, &credIssuerCommands);
+    registerCommandsSubscriptions(commands, &credIssuerCommands);
+
+    return commands.Run(argc, argv);
+}
diff --git a/examples/fabric-admin/third_party/connectedhomeip b/examples/fabric-admin/third_party/connectedhomeip
new file mode 120000
index 0000000..1b20c9f
--- /dev/null
+++ b/examples/fabric-admin/third_party/connectedhomeip
@@ -0,0 +1 @@
+../../../
\ No newline at end of file
