diff --git a/src/mctp/MCTPDeviceRepository.hpp b/src/mctp/MCTPDeviceRepository.hpp
new file mode 100644
index 0000000..475acbe
--- /dev/null
+++ b/src/mctp/MCTPDeviceRepository.hpp
@@ -0,0 +1,77 @@
+#pragma once
+
+#include "MCTPEndpoint.hpp"
+
+class MCTPDeviceRepository
+{
+  private:
+    // FIXME: Ugh, hack. Figure out a better data structure?
+    std::map<std::string, std::shared_ptr<MCTPDevice>> devices;
+
+    auto lookup(const std::shared_ptr<MCTPDevice>& device)
+    {
+        auto pred = [&device](const auto& it) { return it.second == device; };
+        return std::ranges::find_if(devices, pred);
+    }
+
+  public:
+    MCTPDeviceRepository() = default;
+    MCTPDeviceRepository(const MCTPDeviceRepository&) = delete;
+    MCTPDeviceRepository(MCTPDeviceRepository&&) = delete;
+    ~MCTPDeviceRepository() = default;
+
+    MCTPDeviceRepository& operator=(const MCTPDeviceRepository&) = delete;
+    MCTPDeviceRepository& operator=(MCTPDeviceRepository&&) = delete;
+
+    void add(const std::string& inventory,
+             const std::shared_ptr<MCTPDevice>& device)
+    {
+        auto [entry, fresh] = devices.emplace(inventory, device);
+        if (!fresh && entry->second.get() != device.get())
+        {
+            throw std::system_error(
+                std::make_error_code(std::errc::device_or_resource_busy),
+                std::format("Tried to add entry for existing device: {}",
+                            device->describe()));
+        }
+    }
+
+    void remove(const std::shared_ptr<MCTPDevice>& device)
+    {
+        auto entry = lookup(device);
+        if (entry == devices.end())
+        {
+            throw std::system_error(
+                std::make_error_code(std::errc::no_such_device),
+                std::format("Trying to remove unknown device: {}",
+                            entry->second->describe()));
+        }
+        devices.erase(entry);
+    }
+
+    bool contains(const std::shared_ptr<MCTPDevice>& device)
+    {
+        return lookup(device) != devices.end();
+    }
+
+    std::optional<std::string>
+        inventoryFor(const std::shared_ptr<MCTPDevice>& device)
+    {
+        auto entry = lookup(device);
+        if (entry == devices.end())
+        {
+            return {};
+        }
+        return entry->first;
+    }
+
+    std::shared_ptr<MCTPDevice> deviceFor(const std::string& inventory)
+    {
+        auto entry = devices.find(inventory);
+        if (entry == devices.end())
+        {
+            return {};
+        }
+        return entry->second;
+    }
+};
diff --git a/src/mctp/MCTPEndpoint.cpp b/src/mctp/MCTPEndpoint.cpp
new file mode 100644
index 0000000..a8fcc91
--- /dev/null
+++ b/src/mctp/MCTPEndpoint.cpp
@@ -0,0 +1,407 @@
+#include "MCTPEndpoint.hpp"
+
+#include "Utils.hpp"
+#include "VariantVisitors.hpp"
+
+#include <bits/fs_dir.h>
+
+#include <boost/system/detail/errc.hpp>
+#include <phosphor-logging/lg2.hpp>
+#include <sdbusplus/asio/connection.hpp>
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/bus/match.hpp>
+#include <sdbusplus/exception.hpp>
+#include <sdbusplus/message.hpp>
+#include <sdbusplus/message/native_types.hpp>
+
+#include <cassert>
+#include <charconv>
+#include <cstdint>
+#include <exception>
+#include <filesystem>
+#include <format>
+#include <functional>
+#include <map>
+#include <memory>
+#include <optional>
+#include <set>
+#include <stdexcept>
+#include <string>
+#include <system_error>
+#include <utility>
+#include <variant>
+#include <vector>
+
+PHOSPHOR_LOG2_USING;
+
+static constexpr const char* mctpdBusName = "xyz.openbmc_project.MCTP";
+static constexpr const char* mctpdControlPath = "/xyz/openbmc_project/mctp";
+static constexpr const char* mctpdControlInterface =
+    "au.com.CodeConstruct.MCTP";
+static constexpr const char* mctpdEndpointControlInterface =
+    "au.com.CodeConstruct.MCTP.Endpoint";
+
+MCTPDDevice::MCTPDDevice(
+    const std::shared_ptr<sdbusplus::asio::connection>& connection,
+    const std::string& interface, const std::vector<uint8_t>& physaddr) :
+    connection(connection), interface(interface), physaddr(physaddr)
+{}
+
+void MCTPDDevice::onEndpointInterfacesRemoved(
+    const std::weak_ptr<MCTPDDevice>& weak, const std::string& objpath,
+    sdbusplus::message_t& msg)
+{
+    auto path = msg.unpack<sdbusplus::message::object_path>();
+    assert(path.str == objpath);
+
+    auto removedIfaces = msg.unpack<std::set<std::string>>();
+    if (!removedIfaces.contains(mctpdEndpointControlInterface))
+    {
+        return;
+    }
+
+    if (auto self = weak.lock())
+    {
+        self->endpointRemoved();
+    }
+    else
+    {
+        info(
+            "Device for inventory at '{INVENTORY_PATH}' was destroyed concurrent to endpoint removal",
+            "INVENTORY_PATH", objpath);
+    }
+}
+
+void MCTPDDevice::finaliseEndpoint(
+    const std::string& objpath, uint8_t eid, int network,
+    std::function<void(const std::error_code& ec,
+                       const std::shared_ptr<MCTPEndpoint>& ep)>& added)
+{
+    const auto matchSpec =
+        sdbusplus::bus::match::rules::interfacesRemovedAtPath(objpath);
+    removeMatch = std::make_unique<sdbusplus::bus::match_t>(
+        *connection, matchSpec,
+        std::bind_front(MCTPDDevice::onEndpointInterfacesRemoved,
+                        weak_from_this(), objpath));
+    endpoint = std::make_shared<MCTPDEndpoint>(shared_from_this(), connection,
+                                               objpath, network, eid);
+    added({}, endpoint);
+}
+
+void MCTPDDevice::setup(
+    std::function<void(const std::error_code& ec,
+                       const std::shared_ptr<MCTPEndpoint>& ep)>&& added)
+{
+    // Use a lambda to separate state validation from business logic,
+    // where the business logic for a successful setup() is encoded in
+    // MctpdDevice::finaliseEndpoint()
+    auto onSetup = [weak{weak_from_this()}, added{std::move(added)}](
+                       const boost::system::error_code& ec, uint8_t eid,
+                       int network, const std::string& objpath,
+                       bool allocated [[maybe_unused]]) mutable {
+        if (ec)
+        {
+            added(ec, {});
+            return;
+        }
+
+        if (auto self = weak.lock())
+        {
+            self->finaliseEndpoint(objpath, eid, network, added);
+        }
+        else
+        {
+            info(
+                "Device object for inventory at '{INVENTORY_PATH}' was destroyed concurrent to completion of its endpoint setup",
+                "INVENTORY_PATH", objpath);
+        }
+    };
+    connection->async_method_call(onSetup, mctpdBusName, mctpdControlPath,
+                                  mctpdControlInterface, "AssignEndpoint",
+                                  interface, physaddr);
+}
+
+void MCTPDDevice::endpointRemoved()
+{
+    if (endpoint)
+    {
+        debug("Endpoint removed @ [ {MCTP_ENDPOINT} ]", "MCTP_ENDPOINT",
+              endpoint->describe());
+        removeMatch.reset();
+        endpoint->removed();
+        endpoint.reset();
+    }
+}
+
+void MCTPDDevice::remove()
+{
+    if (endpoint)
+    {
+        debug("Removing endpoint @ [ {MCTP_ENDPOINT} ]", "MCTP_ENDPOINT",
+              endpoint->describe());
+        endpoint->remove();
+    }
+}
+
+std::string MCTPDDevice::describe() const
+{
+    std::string description = std::format("interface: {}", interface);
+    if (!physaddr.empty())
+    {
+        description.append(", address: 0x [ ");
+        auto it = physaddr.begin();
+        for (; it != physaddr.end() - 1; it++)
+        {
+            description.append(std::format("{:02x} ", *it));
+        }
+        description.append(std::format("{:02x} ]", *it));
+    }
+    return description;
+}
+
+std::string MCTPDEndpoint::path(const std::shared_ptr<MCTPEndpoint>& ep)
+{
+    return std::format("/xyz/openbmc_project/mctp/{}/{}", ep->network(),
+                       ep->eid());
+}
+
+void MCTPDEndpoint::onMctpEndpointChange(sdbusplus::message_t& msg)
+{
+    auto [iface, changed, _] =
+        msg.unpack<std::string, std::map<std::string, BasicVariantType>,
+                   std::vector<std::string>>();
+    if (iface != mctpdEndpointControlInterface)
+    {
+        return;
+    }
+
+    auto it = changed.find("Connectivity");
+    if (it == changed.end())
+    {
+        return;
+    }
+
+    updateEndpointConnectivity(std::get<std::string>(it->second));
+}
+
+void MCTPDEndpoint::updateEndpointConnectivity(const std::string& connectivity)
+{
+    if (connectivity == "Degraded")
+    {
+        if (notifyDegraded)
+        {
+            notifyDegraded(shared_from_this());
+        }
+    }
+    else if (connectivity == "Available")
+    {
+        if (notifyAvailable)
+        {
+            notifyAvailable(shared_from_this());
+        }
+    }
+    else
+    {
+        debug("Unrecognised connectivity state: '{CONNECTIVITY_STATE}'",
+              "CONNECTIVITY_STATE", connectivity);
+    }
+}
+
+int MCTPDEndpoint::network() const
+{
+    return mctp.network;
+}
+
+uint8_t MCTPDEndpoint::eid() const
+{
+    return mctp.eid;
+}
+
+void MCTPDEndpoint::subscribe(Event&& degraded, Event&& available,
+                              Event&& removed)
+{
+    const auto matchSpec =
+        sdbusplus::bus::match::rules::propertiesChangedNamespace(
+            objpath.str, mctpdEndpointControlInterface);
+
+    this->notifyDegraded = std::move(degraded);
+    this->notifyAvailable = std::move(available);
+    this->notifyRemoved = std::move(removed);
+
+    try
+    {
+        connectivityMatch.emplace(
+            static_cast<sdbusplus::bus_t&>(*connection), matchSpec,
+            [weak{weak_from_this()},
+             path{objpath.str}](sdbusplus::message_t& msg) {
+                if (auto self = weak.lock())
+                {
+                    self->onMctpEndpointChange(msg);
+                }
+                else
+                {
+                    info(
+                        "The endpoint for the device at inventory path '{INVENTORY_PATH}' was destroyed concurrent to the removal of its state change match",
+                        "INVENTORY_PATH", path);
+                }
+            });
+        connection->async_method_call(
+            [weak{weak_from_this()},
+             path{objpath.str}](const boost::system::error_code& ec,
+                                const std::variant<std::string>& value) {
+                if (ec)
+                {
+                    debug(
+                        "Failed to get current connectivity state: {ERROR_MESSAGE}",
+                        "ERROR_MESSAGE", ec.message(), "ERROR_CATEGORY",
+                        ec.category().name(), "ERROR_CODE", ec.value());
+                    return;
+                }
+
+                if (auto self = weak.lock())
+                {
+                    const std::string& connectivity =
+                        std::get<std::string>(value);
+                    self->updateEndpointConnectivity(connectivity);
+                }
+                else
+                {
+                    info(
+                        "The endpoint for the device at inventory path '{INVENTORY_PATH}' was destroyed concurrent to the completion of its connectivity state query",
+                        "INVENTORY_PATH", path);
+                }
+            },
+            mctpdBusName, objpath.str, "org.freedesktop.DBus.Properties", "Get",
+            mctpdEndpointControlInterface, "Connectivity");
+    }
+    catch (const sdbusplus::exception::SdBusError& err)
+    {
+        this->notifyDegraded = nullptr;
+        this->notifyAvailable = nullptr;
+        this->notifyRemoved = nullptr;
+        std::throw_with_nested(
+            MCTPException("Failed to register connectivity signal match"));
+    }
+}
+
+void MCTPDEndpoint::remove()
+{
+    connection->async_method_call(
+        [self{shared_from_this()}](const boost::system::error_code& ec) {
+            if (ec)
+            {
+                debug("Failed to remove endpoint @ [ {MCTP_ENDPOINT} ]",
+                      "MCTP_ENDPOINT", self->describe());
+                return;
+            }
+        },
+        mctpdBusName, objpath.str, mctpdEndpointControlInterface, "Remove");
+}
+
+void MCTPDEndpoint::removed()
+{
+    if (notifyRemoved)
+    {
+        notifyRemoved(shared_from_this());
+    }
+}
+
+std::string MCTPDEndpoint::describe() const
+{
+    return std::format("network: {}, EID: {} | {}", mctp.network, mctp.eid,
+                       dev->describe());
+}
+
+std::shared_ptr<MCTPDevice> MCTPDEndpoint::device() const
+{
+    return dev;
+}
+
+std::optional<SensorBaseConfigMap>
+    I2CMCTPDDevice::match(const SensorData& config)
+{
+    auto iface = config.find(configInterfaceName(configType));
+    if (iface == config.end())
+    {
+        return std::nullopt;
+    }
+    return iface->second;
+}
+
+bool I2CMCTPDDevice::match(const std::set<std::string>& interfaces)
+{
+    return interfaces.contains(configInterfaceName(configType));
+}
+
+std::shared_ptr<I2CMCTPDDevice> I2CMCTPDDevice::from(
+    const std::shared_ptr<sdbusplus::asio::connection>& connection,
+    const SensorBaseConfigMap& iface)
+{
+    auto mType = iface.find("Type");
+    if (mType == iface.end())
+    {
+        throw std::invalid_argument(
+            "No 'Type' member found for provided configuration object");
+    }
+
+    auto type = std::visit(VariantToStringVisitor(), mType->second);
+    if (type != configType)
+    {
+        throw std::invalid_argument("Not an SMBus device");
+    }
+
+    auto mAddress = iface.find("Address");
+    auto mBus = iface.find("Bus");
+    auto mName = iface.find("Name");
+    if (mAddress == iface.end() || mBus == iface.end() || mName == iface.end())
+    {
+        throw std::invalid_argument(
+            "Configuration object violates MCTPI2CTarget schema");
+    }
+
+    auto sAddress = std::visit(VariantToStringVisitor(), mAddress->second);
+    std::uint8_t address{};
+    auto [aptr, aec] = std::from_chars(
+        sAddress.data(), sAddress.data() + sAddress.size(), address);
+    if (aec != std::errc{})
+    {
+        throw std::invalid_argument("Bad device address");
+    }
+
+    auto sBus = std::visit(VariantToStringVisitor(), mBus->second);
+    int bus{};
+    auto [bptr,
+          bec] = std::from_chars(sBus.data(), sBus.data() + sBus.size(), bus);
+    if (bec != std::errc{})
+    {
+        throw std::invalid_argument("Bad bus index");
+    }
+
+    try
+    {
+        return std::make_shared<I2CMCTPDDevice>(connection, bus, address);
+    }
+    catch (const MCTPException& ex)
+    {
+        warning(
+            "Failed to create I2CMCTPDDevice at [ bus: {I2C_BUS}, address: {I2C_ADDRESS} ]: {EXCEPTION}",
+            "I2C_BUS", bus, "I2C_ADDRESS", address, "EXCEPTION", ex);
+        return {};
+    }
+}
+
+std::string I2CMCTPDDevice::interfaceFromBus(int bus)
+{
+    std::filesystem::path netdir =
+        std::format("/sys/bus/i2c/devices/i2c-{}/net", bus);
+    std::error_code ec;
+    std::filesystem::directory_iterator it(netdir, ec);
+    if (ec || it == std::filesystem::end(it))
+    {
+        error("No net device associated with I2C bus {I2C_BUS} at {NET_DEVICE}",
+              "I2C_BUS", bus, "NET_DEVICE", netdir);
+        throw MCTPException("Bus is not configured as an MCTP interface");
+    }
+
+    return it->path().filename();
+}
diff --git a/src/mctp/MCTPEndpoint.hpp b/src/mctp/MCTPEndpoint.hpp
new file mode 100644
index 0000000..02322d1
--- /dev/null
+++ b/src/mctp/MCTPEndpoint.hpp
@@ -0,0 +1,321 @@
+#pragma once
+
+#include "Utils.hpp"
+
+#include <boost/asio/steady_timer.hpp>
+#include <sdbusplus/asio/connection.hpp>
+#include <sdbusplus/bus/match.hpp>
+#include <sdbusplus/message.hpp>
+#include <sdbusplus/message/native_types.hpp>
+
+#include <cstdint>
+#include <iostream>
+
+/**
+ * @file
+ * @brief Abstract and concrete classes representing MCTP concepts and
+ *        behaviours.
+ */
+
+/**
+ * @brief An exception type that may be thrown by implementations of the MCTP
+ * abstract classes.
+ *
+ * This exception should be the basis for all exceptions thrown out of the MCTP
+ * APIs, and should capture any other exceptions that occur.
+ */
+class MCTPException : public std::exception
+{
+  public:
+    MCTPException() = delete;
+    explicit MCTPException(const char* desc) : desc(desc) {}
+    const char* what() const noexcept override
+    {
+        return desc;
+    }
+
+  private:
+    const char* desc;
+};
+
+/**
+ * @brief An enum of the MCTP transports described in DSP0239 v1.10.0 Section 7.
+ *
+ * https://www.dmtf.org/sites/default/files/standards/documents/DSP0239_1.10.0.pdf
+ */
+enum class MCTPTransport
+{
+    Reserved = 0x00,
+    SMBus = 0x01,
+};
+
+/**
+ * @brief Captures properties of MCTP interfaces.
+ *
+ * https://github.com/CodeConstruct/mctp/blob/v1.1/src/mctp.c#L672-L703
+ */
+struct MCTPInterface
+{
+    std::string name;
+    MCTPTransport transport;
+
+    auto operator<=>(const MCTPInterface& r) const = default;
+};
+
+class MCTPDevice;
+
+/**
+ * @brief Captures the behaviour of an endpoint at the MCTP layer
+ *
+ * The lifetime of an instance of MctpEndpoint is proportional to the lifetime
+ * of the endpoint configuration. If an endpoint is deconfigured such that its
+ * device has no assigned EID, then any related MctpEndpoint instance must be
+ * destructed as a consequence.
+ */
+class MCTPEndpoint
+{
+  public:
+    using Event = std::function<void(const std::shared_ptr<MCTPEndpoint>& ep)>;
+    using Result = std::function<void(const std::error_code& ec)>;
+
+    virtual ~MCTPEndpoint() = default;
+
+    /**
+     * @return The Linux network ID of the network in which the endpoint
+               participates
+     */
+    virtual int network() const = 0;
+
+    /**
+     * @return The MCTP endpoint ID of the endpoint in its network
+     */
+    virtual uint8_t eid() const = 0;
+
+    /**
+     * @brief Subscribe to events produced by an endpoint object across its
+     *        lifecycle
+     *
+     * @param degraded The callback to execute when the MCTP layer indicates the
+     *                 endpoint is unresponsive
+     *
+     * @param available The callback to execute when the MCTP layer indicates
+     *                  that communication with the degraded endpoint has been
+     *                  recovered
+     *
+     * @param removed The callback to execute when the MCTP layer indicates the
+     *                endpoint has been removed.
+     */
+    virtual void subscribe(Event&& degraded, Event&& available,
+                           Event&& removed) = 0;
+
+    /**
+     * @brief Remove the endpoint from its associated network
+     */
+    virtual void remove() = 0;
+
+    /**
+     * @return A formatted string representing the endpoint in terms of its
+     *         address properties
+     */
+    virtual std::string describe() const = 0;
+
+    /**
+     * @return A shared pointer to the device instance associated with the
+     *         endpoint.
+     */
+    virtual std::shared_ptr<MCTPDevice> device() const = 0;
+};
+
+/**
+ * @brief Represents an MCTP-capable device on a bus.
+ *
+ * It is often known that an MCTP-capable device exists on a bus prior to the
+ * MCTP stack configuring the device for communication. MctpDevice exposes the
+ * ability to set-up the endpoint device for communication.
+ *
+ * The lifetime of an MctpDevice instance is proportional to the existence of an
+ * MCTP-capable device in the system. If a device represented by an MctpDevice
+ * instance is removed from the system then any related MctpDevice instance must
+ * be destructed a consequence.
+ *
+ * Successful set-up of the device as an endpoint yields an MctpEndpoint
+ * instance. The lifetime of the MctpEndpoint instance produced must not exceed
+ * the lifetime of its parent MctpDevice.
+ */
+class MCTPDevice
+{
+  public:
+    virtual ~MCTPDevice() = default;
+
+    /**
+     * @brief Configure the device for MCTP communication
+     *
+     * @param added The callback to invoke once the setup process has
+     *              completed. The provided error code @p ec must be
+     *              checked as the request may not have succeeded. If
+     *              the request was successful then @p ep contains a
+     *              valid MctpEndpoint instance.
+     */
+    virtual void
+        setup(std::function<void(const std::error_code& ec,
+                                 const std::shared_ptr<MCTPEndpoint>& ep)>&&
+                  added) = 0;
+
+    /**
+     * @brief Remove the device and any associated endpoint from the MCTP stack.
+     */
+    virtual void remove() = 0;
+
+    /**
+     * @return A formatted string representing the device in terms of its
+     *         address properties.
+     */
+    virtual std::string describe() const = 0;
+};
+
+class MCTPDDevice;
+
+/**
+ * @brief An implementation of MctpEndpoint in terms of the D-Bus interfaces
+ *        exposed by @c mctpd.
+ *
+ * The lifetime of an MctpdEndpoint is proportional to the lifetime of the
+ * endpoint object exposed by @c mctpd. The lifecycle of @c mctpd endpoint
+ * objects is discussed here:
+ *
+ * https://github.com/CodeConstruct/mctp/pull/23/files#diff-00234f5f2543b8b9b8a419597e55121fe1cc57cf1c7e4ff9472bed83096bd28e
+ */
+class MCTPDEndpoint :
+    public MCTPEndpoint,
+    public std::enable_shared_from_this<MCTPDEndpoint>
+{
+  public:
+    static std::string path(const std::shared_ptr<MCTPEndpoint>& ep);
+
+    MCTPDEndpoint() = delete;
+    MCTPDEndpoint(
+        const std::shared_ptr<MCTPDDevice>& dev,
+        const std::shared_ptr<sdbusplus::asio::connection>& connection,
+        sdbusplus::message::object_path objpath, int network, uint8_t eid) :
+        dev(dev), connection(connection), objpath(std::move(objpath)),
+        mctp{network, eid}
+    {}
+    MCTPDEndpoint& McptdEndpoint(const MCTPDEndpoint& other) = delete;
+    MCTPDEndpoint(MCTPDEndpoint&& other) noexcept = default;
+    ~MCTPDEndpoint() override = default;
+
+    int network() const override;
+    uint8_t eid() const override;
+    void subscribe(Event&& degraded, Event&& available,
+                   Event&& removed) override;
+    void remove() override;
+
+    std::string describe() const override;
+
+    std::shared_ptr<MCTPDevice> device() const override;
+
+    /**
+     * @brief Indicate the endpoint has been removed
+     *
+     * Called from the implementation of MctpdDevice for resource cleanup
+     * prior to destruction. Resource cleanup is delegated by invoking the
+     * notifyRemoved() callback. As the actions may be abitrary we avoid
+     * invoking notifyRemoved() in the destructor.
+     */
+    void removed();
+
+  private:
+    std::shared_ptr<MCTPDDevice> dev;
+    std::shared_ptr<sdbusplus::asio::connection> connection;
+    sdbusplus::message::object_path objpath;
+    struct
+    {
+        int network;
+        uint8_t eid;
+    } mctp;
+    MCTPEndpoint::Event notifyAvailable;
+    MCTPEndpoint::Event notifyDegraded;
+    MCTPEndpoint::Event notifyRemoved;
+    std::optional<sdbusplus::bus::match_t> connectivityMatch;
+
+    void onMctpEndpointChange(sdbusplus::message_t& msg);
+    void updateEndpointConnectivity(const std::string& connectivity);
+};
+
+/**
+ * @brief An implementation of MctpDevice in terms of D-Bus interfaces exposed
+ *        by @c mctpd.
+ *
+ * The construction or destruction of an MctpdDevice is not required to be
+ * correlated with signals from @c mctpd. For instance, EntityManager may expose
+ * the existance of an MCTP-capable device through its usual configuration
+ * mechanisms.
+ */
+class MCTPDDevice :
+    public MCTPDevice,
+    public std::enable_shared_from_this<MCTPDDevice>
+{
+  public:
+    MCTPDDevice() = delete;
+    MCTPDDevice(const std::shared_ptr<sdbusplus::asio::connection>& connection,
+                const std::string& interface,
+                const std::vector<uint8_t>& physaddr);
+    MCTPDDevice(const MCTPDDevice& other) = delete;
+    MCTPDDevice(MCTPDDevice&& other) = delete;
+    ~MCTPDDevice() override = default;
+
+    void setup(std::function<void(const std::error_code& ec,
+                                  const std::shared_ptr<MCTPEndpoint>& ep)>&&
+                   added) override;
+    void remove() override;
+    std::string describe() const override;
+
+  private:
+    static void onEndpointInterfacesRemoved(
+        const std::weak_ptr<MCTPDDevice>& weak, const std::string& objpath,
+        sdbusplus::message_t& msg);
+
+    std::shared_ptr<sdbusplus::asio::connection> connection;
+    const std::string interface;
+    const std::vector<uint8_t> physaddr;
+    std::shared_ptr<MCTPDEndpoint> endpoint;
+    std::unique_ptr<sdbusplus::bus::match_t> removeMatch;
+
+    /**
+     * @brief Actions to perform once endpoint setup has succeeded
+     *
+     * Now that the endpoint exists two tasks remain:
+     *
+     * 1. Setup the match capturing removal of the endpoint object by mctpd
+     * 2. Invoke the callback to notify the requester that setup has completed,
+     *    providing the MctpEndpoint instance associated with the MctpDevice.
+     */
+    void finaliseEndpoint(
+        const std::string& objpath, uint8_t eid, int network,
+        std::function<void(const std::error_code& ec,
+                           const std::shared_ptr<MCTPEndpoint>& ep)>& added);
+    void endpointRemoved();
+};
+
+class I2CMCTPDDevice : public MCTPDDevice
+{
+  public:
+    static std::optional<SensorBaseConfigMap> match(const SensorData& config);
+    static bool match(const std::set<std::string>& interfaces);
+    static std::shared_ptr<I2CMCTPDDevice>
+        from(const std::shared_ptr<sdbusplus::asio::connection>& connection,
+             const SensorBaseConfigMap& iface);
+
+    I2CMCTPDDevice() = delete;
+    I2CMCTPDDevice(
+        const std::shared_ptr<sdbusplus::asio::connection>& connection, int bus,
+        uint8_t physaddr) :
+        MCTPDDevice(connection, interfaceFromBus(bus), {physaddr})
+    {}
+    ~I2CMCTPDDevice() override = default;
+
+  private:
+    static constexpr const char* configType = "MCTPI2CTarget";
+
+    static std::string interfaceFromBus(int bus);
+};
diff --git a/src/mctp/MCTPReactor.cpp b/src/mctp/MCTPReactor.cpp
new file mode 100644
index 0000000..9d32682
--- /dev/null
+++ b/src/mctp/MCTPReactor.cpp
@@ -0,0 +1,209 @@
+#include "MCTPReactor.hpp"
+
+#include "MCTPDeviceRepository.hpp"
+#include "MCTPEndpoint.hpp"
+#include "Utils.hpp"
+
+#include <boost/system/detail/error_code.hpp>
+#include <phosphor-logging/lg2.hpp>
+
+#include <cstdlib>
+#include <memory>
+#include <optional>
+#include <string>
+#include <system_error>
+#include <utility>
+#include <vector>
+
+PHOSPHOR_LOG2_USING;
+
+void MCTPReactor::deferSetup(const std::shared_ptr<MCTPDevice>& dev)
+{
+    debug("Deferring setup for MCTP device at [ {MCTP_DEVICE} ]", "MCTP_DEVICE",
+          dev->describe());
+
+    deferred.emplace(dev);
+}
+
+void MCTPReactor::untrackEndpoint(const std::shared_ptr<MCTPEndpoint>& ep)
+{
+    server.disassociate(MCTPDEndpoint::path(ep));
+}
+
+void MCTPReactor::trackEndpoint(const std::shared_ptr<MCTPEndpoint>& ep)
+{
+    info("Added MCTP endpoint to device: [ {MCTP_ENDPOINT} ]", "MCTP_ENDPOINT",
+         ep->describe());
+
+    ep->subscribe(
+        // Degraded
+        [](const std::shared_ptr<MCTPEndpoint>& ep) {
+            debug("Endpoint entered degraded state: [ {MCTP_ENDPOINT} ]",
+                  "MCTP_ENDPOINT", ep->describe());
+        },
+        // Available
+        [](const std::shared_ptr<MCTPEndpoint>& ep) {
+            debug("Endpoint entered available state: [ {MCTP_ENDPOINT} ]",
+                  "MCTP_ENDPOINT", ep->describe());
+        },
+        // Removed
+        [weak{weak_from_this()}](const std::shared_ptr<MCTPEndpoint>& ep) {
+            info("Removed MCTP endpoint from device: [ {MCTP_ENDPOINT} ]",
+                 "MCTP_ENDPOINT", ep->describe());
+            if (auto self = weak.lock())
+            {
+                self->untrackEndpoint(ep);
+                // Only defer the setup if we know inventory is still present
+                if (self->devices.contains(ep->device()))
+                {
+                    self->deferSetup(ep->device());
+                }
+            }
+            else
+            {
+                info(
+                    "The reactor object was destroyed concurrent to the removal of the remove match for the endpoint '{MCTP_ENDPOINT}'",
+                    "MCTP_ENDPOINT", ep->describe());
+            }
+        });
+
+    // Proxy-host the association back to the inventory at the same path as the
+    // endpoint in mctpd.
+    //
+    // clang-format off
+    // ```
+    // # busctl call xyz.openbmc_project.ObjectMapper /xyz/openbmc_project/object_mapper xyz.openbmc_project.ObjectMapper GetAssociatedSubTree ooias /xyz/openbmc_project/mctp/1/9/configured_by / 0 1 xyz.openbmc_project.Configuration.MCTPDevice
+    // a{sa{sas}} 1 "/xyz/openbmc_project/inventory/system/nvme/NVMe_1/NVMe_1_Temp" 1 "xyz.openbmc_project.EntityManager" 1 "xyz.openbmc_project.Configuration.MCTPDevice"
+    // ```
+    // clang-format on
+    std::optional<std::string> item = devices.inventoryFor(ep->device());
+    if (!item)
+    {
+        error("Inventory missing for endpoint: [ {MCTP_ENDPOINT} ]",
+              "MCTP_ENDPOINT", ep->describe());
+        return;
+    }
+    std::vector<Association> associations{
+        {"configured_by", "configures", *item}};
+    server.associate(MCTPDEndpoint::path(ep), associations);
+}
+
+void MCTPReactor::setupEndpoint(const std::shared_ptr<MCTPDevice>& dev)
+{
+    debug(
+        "Attempting to setup up MCTP endpoint for device at [ {MCTP_DEVICE} ]",
+        "MCTP_DEVICE", dev->describe());
+    dev->setup([weak{weak_from_this()},
+                dev](const std::error_code& ec,
+                     const std::shared_ptr<MCTPEndpoint>& ep) mutable {
+        auto self = weak.lock();
+        if (!self)
+        {
+            info(
+                "The reactor object was destroyed concurrent to the completion of the endpoint setup for '{MCTP_ENDPOINT}'",
+                "MCTP_ENDPOINT", ep->describe());
+            return;
+        }
+
+        if (ec)
+        {
+            debug(
+                "Setup failed for MCTP device at [ {MCTP_DEVICE} ]: {ERROR_MESSAGE}",
+                "MCTP_DEVICE", dev->describe(), "ERROR_MESSAGE", ec.message());
+
+            self->deferSetup(dev);
+            return;
+        }
+
+        try
+        {
+            self->trackEndpoint(ep);
+        }
+        catch (const MCTPException& e)
+        {
+            error("Failed to track endpoint '{MCTP_ENDPOINT}': {EXCEPTION}",
+                  "MCTP_ENDPOINT", ep->describe(), "EXCEPTION", e);
+            self->deferSetup(dev);
+        }
+    });
+}
+
+void MCTPReactor::tick()
+{
+    auto toSetup = std::exchange(deferred, {});
+    for (const auto& entry : toSetup)
+    {
+        setupEndpoint(entry);
+    }
+}
+
+void MCTPReactor::manageMCTPDevice(const std::string& path,
+                                   const std::shared_ptr<MCTPDevice>& device)
+{
+    if (!device)
+    {
+        return;
+    }
+
+    try
+    {
+        devices.add(path, device);
+        debug("MCTP device inventory added at '{INVENTORY_PATH}'",
+              "INVENTORY_PATH", path);
+        setupEndpoint(device);
+    }
+    catch (const std::system_error& e)
+    {
+        if (e.code() != std::errc::device_or_resource_busy)
+        {
+            throw e;
+        }
+
+        auto current = devices.deviceFor(path);
+        if (!current)
+        {
+            warning(
+                "Invalid state: Failed to manage device for inventory at '{INVENTORY_PATH}', but the inventory item is unrecognised",
+                "INVENTORY_PATH", path);
+            return;
+        }
+
+        // TODO: Ensure remove completion happens-before add. For now this
+        // happens unsynchronised. Make some noise about it.
+        warning(
+            "Unsynchronised endpoint reinitialsation due to configuration change at '{INVENTORY_PATH}': Removing '{MCTP_DEVICE}'",
+            "INVENTORY_PATH", path, "MCTP_DEVICE", current->describe());
+
+        unmanageMCTPDevice(path);
+
+        devices.add(path, device);
+
+        // Pray (this is the unsynchronised bit)
+        deferSetup(device);
+    }
+}
+
+void MCTPReactor::unmanageMCTPDevice(const std::string& path)
+{
+    auto device = devices.deviceFor(path);
+    if (!device)
+    {
+        debug("Unrecognised inventory item: {INVENTORY_PATH}", "INVENTORY_PATH",
+              path);
+        return;
+    }
+
+    debug("MCTP device inventory removed at '{INVENTORY_PATH}'",
+          "INVENTORY_PATH", path);
+
+    deferred.erase(device);
+
+    // Remove the device from the repository before notifying the device itself
+    // of removal so we don't defer its setup
+    devices.remove(device);
+
+    debug("Stopping management of MCTP device at [ {MCTP_DEVICE} ]",
+          "MCTP_DEVICE", device->describe());
+
+    device->remove();
+}
diff --git a/src/mctp/MCTPReactor.hpp b/src/mctp/MCTPReactor.hpp
new file mode 100644
index 0000000..ca20b45
--- /dev/null
+++ b/src/mctp/MCTPReactor.hpp
@@ -0,0 +1,53 @@
+#pragma once
+
+#include "MCTPDeviceRepository.hpp"
+#include "MCTPEndpoint.hpp"
+#include "Utils.hpp"
+
+#include <string>
+#include <vector>
+
+struct AssociationServer
+{
+    virtual ~AssociationServer() = default;
+
+    virtual void associate(const std::string& path,
+                           const std::vector<Association>& associations) = 0;
+    virtual void disassociate(const std::string& path) = 0;
+};
+
+class MCTPReactor : public std::enable_shared_from_this<MCTPReactor>
+{
+    using MCTPDeviceFactory = std::function<std::shared_ptr<MCTPDevice>(
+        const std::string& interface, const std::vector<std::uint8_t>& physaddr,
+        std::optional<std::uint8_t> eid)>;
+
+  public:
+    MCTPReactor() = delete;
+    MCTPReactor(const MCTPReactor&) = delete;
+    MCTPReactor(MCTPReactor&&) = delete;
+    explicit MCTPReactor(AssociationServer& server) : server(server) {}
+    ~MCTPReactor() = default;
+    MCTPReactor& operator=(const MCTPReactor&) = delete;
+    MCTPReactor& operator=(MCTPReactor&&) = delete;
+
+    void tick();
+
+    void manageMCTPDevice(const std::string& path,
+                          const std::shared_ptr<MCTPDevice>& device);
+    void unmanageMCTPDevice(const std::string& path);
+
+  private:
+    static std::optional<std::string> findSMBusInterface(int bus);
+
+    AssociationServer& server;
+    MCTPDeviceRepository devices;
+
+    // Tracks MCTP devices that have failed their setup
+    std::set<std::shared_ptr<MCTPDevice>> deferred;
+
+    void deferSetup(const std::shared_ptr<MCTPDevice>& dev);
+    void setupEndpoint(const std::shared_ptr<MCTPDevice>& dev);
+    void trackEndpoint(const std::shared_ptr<MCTPEndpoint>& ep);
+    void untrackEndpoint(const std::shared_ptr<MCTPEndpoint>& ep);
+};
diff --git a/src/mctp/MCTPReactorMain.cpp b/src/mctp/MCTPReactorMain.cpp
new file mode 100644
index 0000000..9abc0fc
--- /dev/null
+++ b/src/mctp/MCTPReactorMain.cpp
@@ -0,0 +1,249 @@
+#include "MCTPEndpoint.hpp"
+#include "MCTPReactor.hpp"
+#include "Utils.hpp"
+
+#include <boost/asio/io_context.hpp>
+#include <boost/asio/post.hpp>
+#include <boost/asio/steady_timer.hpp>
+#include <phosphor-logging/lg2.hpp>
+#include <sdbusplus/asio/connection.hpp>
+#include <sdbusplus/asio/object_server.hpp>
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/bus/match.hpp>
+#include <sdbusplus/message.hpp>
+#include <sdbusplus/message/native_types.hpp>
+
+#include <chrono>
+#include <cstdlib>
+#include <format>
+#include <functional>
+#include <map>
+#include <memory>
+#include <optional>
+#include <set>
+#include <stdexcept>
+#include <system_error>
+#include <vector>
+
+PHOSPHOR_LOG2_USING;
+
+class DBusAssociationServer : public AssociationServer
+{
+  public:
+    DBusAssociationServer() = delete;
+    DBusAssociationServer(const DBusAssociationServer&) = delete;
+    DBusAssociationServer(DBusAssociationServer&&) = delete;
+    explicit DBusAssociationServer(
+        const std::shared_ptr<sdbusplus::asio::connection>& connection) :
+        server(connection)
+    {
+        server.add_manager("/xyz/openbmc_project/mctp");
+    }
+    ~DBusAssociationServer() override = default;
+    DBusAssociationServer& operator=(const DBusAssociationServer&) = delete;
+    DBusAssociationServer& operator=(DBusAssociationServer&&) = delete;
+
+    void associate(const std::string& path,
+                   const std::vector<Association>& associations) override
+    {
+        auto [entry, _] = objects.emplace(
+            path, server.add_interface(path, association::interface));
+        std::shared_ptr<sdbusplus::asio::dbus_interface> iface = entry->second;
+        iface->register_property("Associations", associations);
+        iface->initialize();
+    }
+
+    void disassociate(const std::string& path) override
+    {
+        const auto entry = objects.find(path);
+        if (entry == objects.end())
+        {
+            throw std::logic_error(std::format(
+                "Attempted to untrack path that was not tracked: {}", path));
+        }
+        std::shared_ptr<sdbusplus::asio::dbus_interface> iface = entry->second;
+        server.remove_interface(entry->second);
+        objects.erase(entry);
+    }
+
+  private:
+    std::shared_ptr<sdbusplus::asio::connection> connection;
+    sdbusplus::asio::object_server server;
+    std::map<std::string, std::shared_ptr<sdbusplus::asio::dbus_interface>>
+        objects;
+};
+
+static std::shared_ptr<MCTPDevice> deviceFromConfig(
+    const std::shared_ptr<sdbusplus::asio::connection>& connection,
+    const SensorData& config)
+{
+    try
+    {
+        std::optional<SensorBaseConfigMap> iface;
+        // NOLINTNEXTLINE(bugprone-assignment-in-if-condition)
+        if ((iface = I2CMCTPDDevice::match(config)))
+        {
+            return I2CMCTPDDevice::from(connection, *iface);
+        }
+    }
+    catch (const std::invalid_argument& ex)
+    {
+        error("Unable to create device: {EXCEPTION}", "EXCEPTION", ex);
+    }
+
+    return {};
+}
+
+static void addInventory(
+    const std::shared_ptr<sdbusplus::asio::connection>& connection,
+    const std::shared_ptr<MCTPReactor>& reactor, sdbusplus::message_t& msg)
+{
+    auto [path,
+          exposed] = msg.unpack<sdbusplus::message::object_path, SensorData>();
+    try
+    {
+        reactor->manageMCTPDevice(path, deviceFromConfig(connection, exposed));
+    }
+    catch (const std::logic_error& e)
+    {
+        error(
+            "Addition of inventory at '{INVENTORY_PATH}' caused an invalid program state: {EXCEPTION}",
+            "INVENTORY_PATH", path, "EXCEPTION", e);
+    }
+    catch (const std::system_error& e)
+    {
+        error(
+            "Failed to manage device described by inventory at '{INVENTORY_PATH}: {EXCEPTION}'",
+            "INVENTORY_PATH", path, "EXCEPTION", e);
+    }
+}
+
+static void removeInventory(const std::shared_ptr<MCTPReactor>& reactor,
+                            sdbusplus::message_t& msg)
+{
+    auto [path, removed] =
+        msg.unpack<sdbusplus::message::object_path, std::set<std::string>>();
+    try
+    {
+        if (I2CMCTPDDevice::match(removed))
+        {
+            reactor->unmanageMCTPDevice(path.str);
+        }
+    }
+    catch (const std::logic_error& e)
+    {
+        error(
+            "Removal of inventory at '{INVENTORY_PATH}' caused an invalid program state: {EXCEPTION}",
+            "INVENTORY_PATH", path, "EXCEPTION", e);
+    }
+    catch (const std::system_error& e)
+    {
+        error(
+            "Failed to unmanage device described by inventory at '{INVENTORY_PATH}: {EXCEPTION}'",
+            "INVENTORY_PATH", path, "EXCEPTION", e);
+    }
+}
+
+static void manageMCTPEntity(
+    const std::shared_ptr<sdbusplus::asio::connection>& connection,
+    const std::shared_ptr<MCTPReactor>& reactor, ManagedObjectType& entities)
+{
+    for (const auto& [path, config] : entities)
+    {
+        try
+        {
+            reactor->manageMCTPDevice(path,
+                                      deviceFromConfig(connection, config));
+        }
+        catch (const std::logic_error& e)
+        {
+            error(
+                "Addition of inventory at '{INVENTORY_PATH}' caused an invalid program state: {EXCEPTION}",
+                "INVENTORY_PATH", path, "EXCEPTION", e);
+        }
+        catch (const std::system_error& e)
+        {
+            error(
+                "Failed to manage device described by inventory at '{INVENTORY_PATH}: {EXCEPTION}'",
+                "INVENTORY_PATH", path, "EXCEPTION", e);
+        }
+    }
+}
+
+static void exitReactor(boost::asio::io_context* io, sdbusplus::message_t& msg)
+{
+    auto name = msg.unpack<std::string>();
+    info("Shutting down mctpreactor, lost dependency '{SERVICE_NAME}'",
+         "SERVICE_NAME", name);
+    io->stop();
+}
+
+int main()
+{
+    constexpr std::chrono::seconds period(5);
+
+    boost::asio::io_context io;
+    auto systemBus = std::make_shared<sdbusplus::asio::connection>(io);
+    DBusAssociationServer associationServer(systemBus);
+    auto reactor = std::make_shared<MCTPReactor>(associationServer);
+    boost::asio::steady_timer clock(io);
+
+    std::function<void(const boost::system::error_code&)> alarm =
+        [&](const boost::system::error_code& ec) {
+            if (ec)
+            {
+                return;
+            }
+            clock.expires_after(period);
+            clock.async_wait(alarm);
+            reactor->tick();
+        };
+    clock.expires_after(period);
+    clock.async_wait(alarm);
+
+    using namespace sdbusplus::bus::match;
+
+    const std::string entityManagerNameLostSpec =
+        rules::nameOwnerChanged("xyz.openbmc_project.EntityManager");
+
+    auto entityManagerNameLostMatch = sdbusplus::bus::match_t(
+        static_cast<sdbusplus::bus_t&>(*systemBus), entityManagerNameLostSpec,
+        std::bind_front(exitReactor, &io));
+
+    const std::string mctpdNameLostSpec =
+        rules::nameOwnerChanged("xyz.openbmc_project.MCTP");
+
+    auto mctpdNameLostMatch = sdbusplus::bus::match_t(
+        static_cast<sdbusplus::bus_t&>(*systemBus), mctpdNameLostSpec,
+        std::bind_front(exitReactor, &io));
+
+    const std::string interfacesRemovedMatchSpec =
+        rules::sender("xyz.openbmc_project.EntityManager") +
+        // Trailing slash on path: Listen for signals on the inventory subtree
+        rules::interfacesRemovedAtPath("/xyz/openbmc_project/inventory/");
+
+    auto interfacesRemovedMatch = sdbusplus::bus::match_t(
+        static_cast<sdbusplus::bus_t&>(*systemBus), interfacesRemovedMatchSpec,
+        std::bind_front(removeInventory, reactor));
+
+    const std::string interfacesAddedMatchSpec =
+        rules::sender("xyz.openbmc_project.EntityManager") +
+        // Trailing slash on path: Listen for signals on the inventory subtree
+        rules::interfacesAddedAtPath("/xyz/openbmc_project/inventory/");
+
+    auto interfacesAddedMatch = sdbusplus::bus::match_t(
+        static_cast<sdbusplus::bus_t&>(*systemBus), interfacesAddedMatchSpec,
+        std::bind_front(addInventory, systemBus, reactor));
+
+    systemBus->request_name("xyz.openbmc_project.MCTPReactor");
+
+    boost::asio::post(io, [reactor, systemBus]() {
+        auto gsc = std::make_shared<GetSensorConfiguration>(
+            systemBus, std::bind_front(manageMCTPEntity, systemBus, reactor));
+        gsc->getConfiguration({"MCTPI2CTarget"});
+    });
+
+    io.run();
+
+    return EXIT_SUCCESS;
+}
diff --git a/src/mctp/meson.build b/src/mctp/meson.build
new file mode 100644
index 0000000..2b10004
--- /dev/null
+++ b/src/mctp/meson.build
@@ -0,0 +1,8 @@
+executable(
+    'mctpreactor',
+    'MCTPReactorMain.cpp',
+    'MCTPReactor.cpp',
+    'MCTPEndpoint.cpp',
+    dependencies: [ default_deps, utils_dep ],
+    install: true
+)
diff --git a/src/meson.build b/src/meson.build
index 64d156d..85b754b 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -101,6 +101,10 @@
     subdir('ipmb')
 endif
 
+if get_option('mctp').allowed()
+    subdir('mctp')
+endif
+
 if get_option('mcu').allowed()
     subdir('mcu')
 endif
diff --git a/src/tests/meson.build b/src/tests/meson.build
index 0415e96..c477843 100644
--- a/src/tests/meson.build
+++ b/src/tests/meson.build
@@ -56,3 +56,28 @@
         include_directories: src_inc,
     ),
 )
+
+test(
+    'MCTPReactor',
+    executable(
+        'test_MCTPReactor',
+        'test_MCTPReactor.cpp',
+        '../mctp/MCTPReactor.cpp',
+        '../mctp/MCTPEndpoint.cpp',
+        dependencies: [ gmock_dep, ut_deps_list, utils_dep ],
+        implicit_include_directories: false,
+        include_directories: '../mctp'
+    )
+)
+
+test(
+    'MCTPEndpoint',
+    executable(
+        'test_MCTPEndpoint',
+        'test_MCTPEndpoint.cpp',
+        '../mctp/MCTPEndpoint.cpp',
+        dependencies: [ gmock_dep, ut_deps_list, utils_dep ],
+        implicit_include_directories: false,
+        include_directories: '../mctp'
+    )
+)
diff --git a/src/tests/test_MCTPEndpoint.cpp b/src/tests/test_MCTPEndpoint.cpp
new file mode 100644
index 0000000..36b7d3c
--- /dev/null
+++ b/src/tests/test_MCTPEndpoint.cpp
@@ -0,0 +1,88 @@
+#include "MCTPEndpoint.hpp"
+#include "Utils.hpp"
+
+#include <stdexcept>
+
+#include <gtest/gtest.h>
+
+TEST(I2CMCTPDDevice, matchEmptyConfig)
+{
+    SensorData config{};
+    EXPECT_FALSE(I2CMCTPDDevice::match(config));
+}
+
+TEST(I2CMCTPDDevice, matchIrrelevantConfig)
+{
+    SensorData config{{"xyz.openbmc_project.Configuration.NVME1000", {}}};
+    EXPECT_FALSE(I2CMCTPDDevice::match(config));
+}
+
+TEST(I2CMCTPDDevice, matchRelevantConfig)
+{
+    SensorData config{{"xyz.openbmc_project.Configuration.MCTPI2CTarget", {}}};
+    EXPECT_TRUE(I2CMCTPDDevice::match(config));
+}
+
+TEST(I2CMCTPDDevice, fromBadIfaceNoType)
+{
+    SensorBaseConfigMap iface{{}};
+    EXPECT_THROW(I2CMCTPDDevice::from({}, iface), std::invalid_argument);
+}
+
+TEST(I2CMCTPDDevice, fromBadIfaceWrongType)
+{
+    SensorBaseConfigMap iface{{"Type", "NVME1000"}};
+    EXPECT_THROW(I2CMCTPDDevice::from({}, iface), std::invalid_argument);
+}
+
+TEST(I2CMCTPDDevice, fromBadIfaceNoAddress)
+{
+    SensorBaseConfigMap iface{
+        {"Bus", "0"},
+        {"Name", "test"},
+        {"Type", "MCTPI2CTarget"},
+    };
+    EXPECT_THROW(I2CMCTPDDevice::from({}, iface), std::invalid_argument);
+}
+
+TEST(I2CMCTPDDevice, fromBadIfaceBadAddress)
+{
+    SensorBaseConfigMap iface{
+        {"Address", "not a number"},
+        {"Bus", "0"},
+        {"Name", "test"},
+        {"Type", "MCTPI2CTarget"},
+    };
+    EXPECT_THROW(I2CMCTPDDevice::from({}, iface), std::invalid_argument);
+}
+
+TEST(I2CMCTPDDevice, fromBadIfaceNoBus)
+{
+    SensorBaseConfigMap iface{
+        {"Address", "0x1d"},
+        {"Name", "test"},
+        {"Type", "MCTPI2CTarget"},
+    };
+    EXPECT_THROW(I2CMCTPDDevice::from({}, iface), std::invalid_argument);
+}
+
+TEST(I2CMCTPDDevice, fromBadIfaceBadBus)
+{
+    SensorBaseConfigMap iface{
+        {"Address", "0x1d"},
+        {"Bus", "not a number"},
+        {"Name", "test"},
+        {"Type", "MCTPI2CTarget"},
+    };
+    EXPECT_THROW(I2CMCTPDDevice::from({}, iface), std::invalid_argument);
+}
+
+TEST(I2CMCTPDDevice, fromBadIfaceNoName)
+{
+    SensorBaseConfigMap iface{
+        {"Address", "0x1d"},
+        {"Bus", "0"},
+        {"Type", "MCTPI2CTarget"},
+    };
+    EXPECT_THROW(I2CMCTPDDevice::from({}, iface), std::invalid_argument);
+}
diff --git a/src/tests/test_MCTPReactor.cpp b/src/tests/test_MCTPReactor.cpp
new file mode 100644
index 0000000..abdd9e9
--- /dev/null
+++ b/src/tests/test_MCTPReactor.cpp
@@ -0,0 +1,250 @@
+#include "MCTPEndpoint.hpp"
+#include "MCTPReactor.hpp"
+#include "Utils.hpp"
+
+#include <cstdint>
+#include <functional>
+#include <memory>
+#include <string>
+#include <system_error>
+#include <vector>
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+class MockMCTPDevice : public MCTPDevice
+{
+  public:
+    ~MockMCTPDevice() override = default;
+
+    MOCK_METHOD(void, setup,
+                (std::function<void(const std::error_code& ec,
+                                    const std::shared_ptr<MCTPEndpoint>& ep)> &&
+                 added),
+                (override));
+    MOCK_METHOD(void, remove, (), (override));
+    MOCK_METHOD(std::string, describe, (), (const, override));
+};
+
+class MockMCTPEndpoint : public MCTPEndpoint
+{
+  public:
+    ~MockMCTPEndpoint() override = default;
+
+    MOCK_METHOD(int, network, (), (const, override));
+    MOCK_METHOD(uint8_t, eid, (), (const, override));
+    MOCK_METHOD(void, subscribe,
+                (Event && degraded, Event&& available, Event&& removed),
+                (override));
+    MOCK_METHOD(void, remove, (), (override));
+    MOCK_METHOD(std::string, describe, (), (const, override));
+    MOCK_METHOD(std::shared_ptr<MCTPDevice>, device, (), (const, override));
+};
+
+class MockAssociationServer : public AssociationServer
+{
+  public:
+    ~MockAssociationServer() override = default;
+
+    MOCK_METHOD(void, associate,
+                (const std::string& path,
+                 const std::vector<Association>& associations),
+                (override));
+    MOCK_METHOD(void, disassociate, (const std::string& path), (override));
+};
+
+class MCTPReactorFixture : public testing::Test
+{
+  protected:
+    void SetUp() override
+    {
+        reactor = std::make_shared<MCTPReactor>(assoc);
+        device = std::make_shared<MockMCTPDevice>();
+        EXPECT_CALL(*device, describe())
+            .WillRepeatedly(testing::Return("mock device"));
+
+        endpoint = std::make_shared<MockMCTPEndpoint>();
+        EXPECT_CALL(*endpoint, device())
+            .WillRepeatedly(testing::Return(device));
+        EXPECT_CALL(*endpoint, describe())
+            .WillRepeatedly(testing::Return("mock endpoint"));
+        EXPECT_CALL(*endpoint, eid()).WillRepeatedly(testing::Return(9));
+        EXPECT_CALL(*endpoint, network()).WillRepeatedly(testing::Return(1));
+    }
+
+    void TearDown() override
+    {
+        // https://stackoverflow.com/a/10289205
+        EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(endpoint.get()));
+        EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(device.get()));
+    }
+
+    MockAssociationServer assoc;
+    std::shared_ptr<MCTPReactor> reactor;
+    std::shared_ptr<MockMCTPDevice> device;
+    std::shared_ptr<MockMCTPEndpoint> endpoint;
+};
+
+TEST_F(MCTPReactorFixture, manageNullDevice)
+{
+    reactor->manageMCTPDevice("/test", {});
+    reactor->unmanageMCTPDevice("/test");
+}
+
+TEST_F(MCTPReactorFixture, manageMockDeviceSetupFailure)
+{
+    EXPECT_CALL(*device, remove());
+    EXPECT_CALL(*device, setup(testing::_))
+        .WillOnce(testing::InvokeArgument<0>(
+            std::make_error_code(std::errc::permission_denied), endpoint));
+
+    reactor->manageMCTPDevice("/test", device);
+    reactor->unmanageMCTPDevice("/test");
+}
+
+TEST_F(MCTPReactorFixture, manageMockDevice)
+{
+    std::function<void(const std::shared_ptr<MCTPEndpoint>& ep)> removeHandler;
+
+    std::vector<Association> requiredAssociation{
+        {"configured_by", "configures", "/test"}};
+    EXPECT_CALL(assoc, associate("/xyz/openbmc_project/mctp/1/9",
+                                 requiredAssociation));
+    EXPECT_CALL(assoc, disassociate("/xyz/openbmc_project/mctp/1/9"));
+
+    EXPECT_CALL(*endpoint, remove()).WillOnce(testing::Invoke([&]() {
+        removeHandler(endpoint);
+    }));
+    EXPECT_CALL(*endpoint, subscribe(testing::_, testing::_, testing::_))
+        .WillOnce(testing::SaveArg<2>(&removeHandler));
+
+    EXPECT_CALL(*device, remove()).WillOnce(testing::Invoke([&]() {
+        endpoint->remove();
+    }));
+    EXPECT_CALL(*device, setup(testing::_))
+        .WillOnce(testing::InvokeArgument<0>(std::error_code(), endpoint));
+
+    reactor->manageMCTPDevice("/test", device);
+    reactor->unmanageMCTPDevice("/test");
+}
+
+TEST_F(MCTPReactorFixture, manageMockDeviceDeferredSetup)
+{
+    std::function<void(const std::shared_ptr<MCTPEndpoint>& ep)> removeHandler;
+
+    std::vector<Association> requiredAssociation{
+        {"configured_by", "configures", "/test"}};
+    EXPECT_CALL(assoc, associate("/xyz/openbmc_project/mctp/1/9",
+                                 requiredAssociation));
+    EXPECT_CALL(assoc, disassociate("/xyz/openbmc_project/mctp/1/9"));
+
+    EXPECT_CALL(*endpoint, remove()).WillOnce(testing::Invoke([&]() {
+        removeHandler(endpoint);
+    }));
+    EXPECT_CALL(*endpoint, subscribe(testing::_, testing::_, testing::_))
+        .WillOnce(testing::SaveArg<2>(&removeHandler));
+
+    EXPECT_CALL(*device, remove()).WillOnce(testing::Invoke([&]() {
+        endpoint->remove();
+    }));
+    EXPECT_CALL(*device, setup(testing::_))
+        .WillOnce(testing::InvokeArgument<0>(
+            std::make_error_code(std::errc::permission_denied), endpoint))
+        .WillOnce(testing::InvokeArgument<0>(std::error_code(), endpoint));
+
+    reactor->manageMCTPDevice("/test", device);
+    reactor->tick();
+    reactor->unmanageMCTPDevice("/test");
+}
+
+TEST_F(MCTPReactorFixture, manageMockDeviceRemoved)
+{
+    std::function<void(const std::shared_ptr<MCTPEndpoint>& ep)> removeHandler;
+
+    std::vector<Association> requiredAssociation{
+        {"configured_by", "configures", "/test"}};
+    EXPECT_CALL(assoc,
+                associate("/xyz/openbmc_project/mctp/1/9", requiredAssociation))
+        .Times(2);
+    EXPECT_CALL(assoc, disassociate("/xyz/openbmc_project/mctp/1/9")).Times(2);
+
+    EXPECT_CALL(*endpoint, remove()).WillOnce(testing::Invoke([&]() {
+        removeHandler(endpoint);
+    }));
+    EXPECT_CALL(*endpoint, subscribe(testing::_, testing::_, testing::_))
+        .Times(2)
+        .WillRepeatedly(testing::SaveArg<2>(&removeHandler));
+
+    EXPECT_CALL(*device, remove()).WillOnce(testing::Invoke([&]() {
+        endpoint->remove();
+    }));
+    EXPECT_CALL(*device, setup(testing::_))
+        .Times(2)
+        .WillRepeatedly(
+            testing::InvokeArgument<0>(std::error_code(), endpoint));
+
+    reactor->manageMCTPDevice("/test", device);
+    removeHandler(endpoint);
+    reactor->tick();
+    reactor->unmanageMCTPDevice("/test");
+}
+
+TEST(MCTPReactor, replaceConfiguration)
+{
+    MockAssociationServer assoc{};
+    auto reactor = std::make_shared<MCTPReactor>(assoc);
+    std::function<void(const std::shared_ptr<MCTPEndpoint>& ep)> removeHandler;
+
+    std::vector<Association> requiredAssociation{
+        {"configured_by", "configures", "/test"}};
+
+    EXPECT_CALL(assoc,
+                associate("/xyz/openbmc_project/mctp/1/9", requiredAssociation))
+        .Times(2);
+    EXPECT_CALL(assoc, disassociate("/xyz/openbmc_project/mctp/1/9")).Times(2);
+
+    auto endpoint = std::make_shared<MockMCTPEndpoint>();
+    EXPECT_CALL(*endpoint, describe())
+        .WillRepeatedly(testing::Return("mock endpoint"));
+    EXPECT_CALL(*endpoint, eid()).WillRepeatedly(testing::Return(9));
+    EXPECT_CALL(*endpoint, network()).WillRepeatedly(testing::Return(1));
+    EXPECT_CALL(*endpoint, remove())
+        .Times(2)
+        .WillRepeatedly(testing::Invoke([&]() { removeHandler(endpoint); }));
+    EXPECT_CALL(*endpoint, subscribe(testing::_, testing::_, testing::_))
+        .Times(2)
+        .WillRepeatedly(testing::SaveArg<2>(&removeHandler));
+
+    auto initial = std::make_shared<MockMCTPDevice>();
+    EXPECT_CALL(*initial, describe())
+        .WillRepeatedly(testing::Return("mock device: initial"));
+    EXPECT_CALL(*initial, setup(testing::_))
+        .WillOnce(testing::InvokeArgument<0>(std::error_code(), endpoint));
+    EXPECT_CALL(*initial, remove()).WillOnce(testing::Invoke([&]() {
+        endpoint->remove();
+    }));
+
+    auto replacement = std::make_shared<MockMCTPDevice>();
+    EXPECT_CALL(*replacement, describe())
+        .WillRepeatedly(testing::Return("mock device: replacement"));
+    EXPECT_CALL(*replacement, setup(testing::_))
+        .WillOnce(testing::InvokeArgument<0>(std::error_code(), endpoint));
+    EXPECT_CALL(*replacement, remove()).WillOnce(testing::Invoke([&]() {
+        endpoint->remove();
+    }));
+
+    EXPECT_CALL(*endpoint, device())
+        .WillOnce(testing::Return(initial))
+        .WillOnce(testing::Return(initial))
+        .WillOnce(testing::Return(replacement))
+        .WillOnce(testing::Return(replacement));
+
+    reactor->manageMCTPDevice("/test", initial);
+    reactor->manageMCTPDevice("/test", replacement);
+    reactor->tick();
+    reactor->unmanageMCTPDevice("/test");
+
+    EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(initial.get()));
+    EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(replacement.get()));
+    EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(endpoint.get()));
+}
