diff --git a/src/args.cpp b/src/args.cpp
new file mode 100644
index 0000000..b81de5a
--- /dev/null
+++ b/src/args.cpp
@@ -0,0 +1,46 @@
+#include "args.hpp"
+
+#include <fmt/format.h>
+#include <getopt.h>
+
+#include <stdexcept>
+
+namespace kcsbridge
+{
+
+Args::Args(int argc, char* argv[])
+{
+    static const char opts[] = ":c:";
+    static const struct option longopts[] = {
+        {"channel", required_argument, nullptr, 'c'},
+        {nullptr, 0, nullptr, 0},
+    };
+    int c;
+    optind = 0;
+    while ((c = getopt_long(argc, argv, opts, longopts, nullptr)) > 0)
+    {
+        switch (c)
+        {
+            case 'c':
+                channel = optarg;
+                break;
+            case ':':
+                throw std::runtime_error(
+                    fmt::format("Missing argument for `{}`", argv[optind - 1]));
+                break;
+            default:
+                throw std::runtime_error(fmt::format(
+                    "Invalid command line argument `{}`", argv[optind - 1]));
+        }
+    }
+    if (optind != argc)
+    {
+        throw std::invalid_argument("Requires no additional arguments");
+    }
+    if (channel == nullptr)
+    {
+        throw std::invalid_argument("Missing KCS channel");
+    }
+}
+
+} // namespace kcsbridge
diff --git a/src/args.hpp b/src/args.hpp
new file mode 100644
index 0000000..e528162
--- /dev/null
+++ b/src/args.hpp
@@ -0,0 +1,14 @@
+#pragma once
+#include <cstddef>
+
+namespace kcsbridge
+{
+
+struct Args
+{
+    const char* channel = nullptr;
+
+    Args(int argc, char* argv[]);
+};
+
+} // namespace kcsbridge
diff --git a/src/cmd.cpp b/src/cmd.cpp
new file mode 100644
index 0000000..3a97498
--- /dev/null
+++ b/src/cmd.cpp
@@ -0,0 +1,99 @@
+#include "cmd.hpp"
+
+#include <fmt/format.h>
+
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/exception.hpp>
+#include <sdbusplus/message.hpp>
+#include <sdbusplus/slot.hpp>
+#include <stdplus/exception.hpp>
+#include <stdplus/fd/ops.hpp>
+#include <stdplus/types.hpp>
+
+#include <array>
+#include <map>
+#include <stdexcept>
+#include <tuple>
+#include <utility>
+#include <variant>
+#include <vector>
+
+namespace kcsbridge
+{
+
+using sdbusplus::bus::bus;
+using sdbusplus::message::message;
+using sdbusplus::slot::slot;
+
+void write(stdplus::Fd& kcs, message&& m)
+{
+    std::array<uint8_t, 1024> buffer;
+    stdplus::span<uint8_t> out(buffer.begin(), 3);
+    try
+    {
+        if (m.is_method_error())
+        {
+            // Extra copy to workaround lack of `const sd_bus_error` constructor
+            auto error = *m.get_error();
+            throw sdbusplus::exception::SdBusError(&error, "ipmid response");
+        }
+        std::tuple<uint8_t, uint8_t, uint8_t, uint8_t, std::vector<uint8_t>>
+            ret;
+        m.read(ret);
+        const auto& [netfn, lun, cmd, cc, data] = ret;
+        // Based on the IPMI KCS spec Figure 9-2
+        // netfn needs to be changed to odd in KCS responses
+        if (data.size() + 3 > buffer.size())
+        {
+            throw std::runtime_error(fmt::format(
+                "too large {} > {}", data.size() + 3, buffer.size()));
+        }
+        buffer[0] = (netfn | 1) << 2;
+        buffer[0] |= lun;
+        buffer[1] = cmd;
+        buffer[2] = cc;
+        memcpy(&buffer[3], data.data(), data.size());
+        out = stdplus::span<uint8_t>(buffer.begin(), data.size() + 3);
+    }
+    catch (const std::exception& e)
+    {
+        fmt::print(stderr, "IPMI response failure: {}\n", e.what());
+        buffer[0] |= 1 << 2;
+        buffer[2] = 0xff;
+    }
+    stdplus::fd::writeExact(kcs, out);
+}
+
+void read(stdplus::Fd& kcs, bus& bus, slot& outstanding)
+{
+    std::array<uint8_t, 1024> buffer;
+    auto in = stdplus::fd::read(kcs, buffer);
+    if (in.empty())
+    {
+        return;
+    }
+    if (outstanding)
+    {
+        fmt::print(stderr, "Canceling outstanding request\n");
+        outstanding = slot(nullptr);
+    }
+    if (in.size() < 2)
+    {
+        fmt::print(stderr, "Read too small, ignoring\n");
+        return;
+    }
+    auto m = bus.new_method_call("xyz.openbmc_project.Ipmi.Host",
+                                 "/xyz/openbmc_project/Ipmi",
+                                 "xyz.openbmc_project.Ipmi.Server", "execute");
+    std::map<std::string, std::variant<int>> options;
+    // Based on the IPMI KCS spec Figure 9-1
+    uint8_t netfn = in[0] >> 2, lun = in[0] & 3, cmd = in[1];
+    m.append(netfn, lun, cmd, in.subspan(2), options);
+    outstanding = m.call_async(
+        stdplus::exception::ignore([&outstanding, &kcs](message&& m) {
+            outstanding = slot(nullptr);
+            write(kcs, std::move(m));
+        }));
+}
+
+} // namespace kcsbridge
diff --git a/src/cmd.hpp b/src/cmd.hpp
new file mode 100644
index 0000000..a6a6fa3
--- /dev/null
+++ b/src/cmd.hpp
@@ -0,0 +1,14 @@
+#pragma once
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/message.hpp>
+#include <sdbusplus/slot.hpp>
+#include <stdplus/fd/intf.hpp>
+
+namespace kcsbridge
+{
+
+void write(stdplus::Fd& kcs, sdbusplus::message::message&& m);
+void read(stdplus::Fd& kcs, sdbusplus::bus::bus& bus,
+          sdbusplus::slot::slot& outstanding);
+
+} // namespace kcsbridge
diff --git a/src/kcsbridged.cpp b/src/kcsbridged.cpp
deleted file mode 100644
index 9380367..0000000
--- a/src/kcsbridged.cpp
+++ /dev/null
@@ -1,343 +0,0 @@
-/* Copyright 2017 - 2019 Intel
- *
- * 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 <getopt.h>
-#include <linux/ipmi_bmc.h>
-
-#include <CLI/CLI.hpp>
-#include <boost/algorithm/string/replace.hpp>
-#include <boost/asio.hpp>
-#include <phosphor-logging/log.hpp>
-#include <sdbusplus/asio/connection.hpp>
-#include <sdbusplus/asio/object_server.hpp>
-
-#include <iostream>
-
-using namespace phosphor::logging;
-
-namespace
-{
-namespace io_control
-{
-struct ClearSmsAttention
-{
-    // Get the name of the IO control command.
-    int name() const
-    {
-        return static_cast<int>(IPMI_BMC_IOCTL_CLEAR_SMS_ATN);
-    }
-
-    // Get the address of the command data.
-    boost::asio::detail::ioctl_arg_type* data()
-    {
-        return nullptr;
-    }
-};
-
-struct SetSmsAttention
-{
-    // Get the name of the IO control command.
-    int name() const
-    {
-        return static_cast<int>(IPMI_BMC_IOCTL_SET_SMS_ATN);
-    }
-
-    // Get the address of the command data.
-    boost::asio::detail::ioctl_arg_type* data()
-    {
-        return nullptr;
-    }
-};
-
-struct ForceAbort
-{
-    // Get the name of the IO control command.
-    int name() const
-    {
-        return static_cast<int>(IPMI_BMC_IOCTL_FORCE_ABORT);
-    }
-
-    // Get the address of the command data.
-    boost::asio::detail::ioctl_arg_type* data()
-    {
-        return nullptr;
-    }
-};
-} // namespace io_control
-
-class SmsChannel
-{
-  public:
-    static constexpr size_t kcsMessageSize = 4096;
-    static constexpr uint8_t netFnShift = 2;
-    static constexpr uint8_t lunMask = (1 << netFnShift) - 1;
-
-    SmsChannel(std::shared_ptr<boost::asio::io_context>& io,
-               std::shared_ptr<sdbusplus::asio::connection>& bus,
-               const std::string& channel, bool verbose) :
-        io(io),
-        bus(bus), verbose(verbose)
-    {
-        static constexpr const char devBase[] = "/dev/";
-        std::string devName = devBase + channel;
-        // open device
-        int fd = open(devName.c_str(), O_RDWR | O_NONBLOCK);
-        if (fd < 0)
-        {
-            log<level::ERR>("Couldn't open SMS channel O_RDWR",
-                            entry("FILENAME=%s", devName.c_str()),
-                            entry("ERROR=%s", strerror(errno)));
-            return;
-        }
-        else
-        {
-            dev = std::make_unique<boost::asio::posix::stream_descriptor>(*io,
-                                                                          fd);
-        }
-
-        async_read();
-
-        // register interfaces...
-        server = std::make_shared<sdbusplus::asio::object_server>(bus);
-
-        static constexpr const char pathBase[] =
-            "/xyz/openbmc_project/Ipmi/Channel/";
-        std::shared_ptr<sdbusplus::asio::dbus_interface> iface =
-            server->add_interface(
-                pathBase + boost::replace_all_copy(channel, "-", "_"),
-                "xyz.openbmc_project.Ipmi.Channel.SMS");
-        iface->register_method("setAttention",
-                               [this]() { return setAttention(); });
-        iface->register_method("clearAttention",
-                               [this]() { return clearAttention(); });
-        iface->register_method("forceAbort", [this]() { return forceAbort(); });
-        iface->initialize();
-    }
-
-    bool initOK() const
-    {
-        return !!dev;
-    }
-
-    void channelAbort(const char* msg, const boost::system::error_code& ec)
-    {
-        log<level::ERR>(msg, entry("ERROR=%s", ec.message().c_str()));
-        // bail; maybe a restart from systemd can clear the error
-        io->stop();
-    }
-
-    void async_read()
-    {
-        boost::asio::async_read(
-            *dev, boost::asio::buffer(xferBuffer, xferBuffer.size()),
-            boost::asio::transfer_at_least(2),
-            [this](const boost::system::error_code& ec, size_t rlen) {
-                processMessage(ec, rlen);
-            });
-    }
-
-    void processMessage(const boost::system::error_code& ecRd, size_t rlen)
-    {
-        if (ecRd || rlen < 2)
-        {
-            channelAbort("Failed to read req msg", ecRd);
-            return;
-        }
-
-        async_read();
-
-        // trim raw to be only bytes returned from read
-        // separate netfn/lun/cmd from payload
-        auto rawIter = xferBuffer.cbegin();
-        auto rawEnd = rawIter + rlen;
-        uint8_t netfn = *rawIter >> netFnShift;
-        uint8_t lun = *rawIter++ & lunMask;
-        uint8_t cmd = *rawIter++;
-        if (verbose)
-        {
-            log<level::INFO>("Read req msg", entry("NETFN=0x%02x", netfn),
-                             entry("LUN=0x%02x", lun),
-                             entry("CMD=0x%02x", cmd));
-        }
-        // copy out payload
-        std::vector<uint8_t> data(rawIter, rawEnd);
-        // non-session bridges still need to pass an empty options map
-        std::map<std::string, std::variant<int>> options;
-        // the response is a tuple because dbus can only return a single value
-        using IpmiDbusRspType = std::tuple<uint8_t, uint8_t, uint8_t, uint8_t,
-                                           std::vector<uint8_t>>;
-        static constexpr const char ipmiQueueService[] =
-            "xyz.openbmc_project.Ipmi.Host";
-        static constexpr const char ipmiQueuePath[] =
-            "/xyz/openbmc_project/Ipmi";
-        static constexpr const char ipmiQueueIntf[] =
-            "xyz.openbmc_project.Ipmi.Server";
-        static constexpr const char ipmiQueueMethod[] = "execute";
-        bus->async_method_call(
-            [this, netfnCap{netfn}, lunCap{lun},
-             cmdCap{cmd}](const boost::system::error_code& ec,
-                          const IpmiDbusRspType& response) {
-                std::vector<uint8_t> rsp;
-                const auto& [netfn, lun, cmd, cc, payload] = response;
-                if (ec)
-                {
-                    log<level::ERR>(
-                        "kcs<->ipmid bus error:", entry("NETFN=0x%02x", netfn),
-                        entry("LUN=0x%02x", lun), entry("CMD=0x%02x", cmd),
-                        entry("ERROR=%s", ec.message().c_str()));
-                    // send unspecified error for a D-Bus error
-                    constexpr uint8_t ccResponseNotAvailable = 0xce;
-                    rsp.resize(sizeof(netfn) + sizeof(cmd) + sizeof(cc));
-                    rsp[0] =
-                        ((netfnCap + 1) << netFnShift) | (lunCap & lunMask);
-                    rsp[1] = cmdCap;
-                    rsp[2] = ccResponseNotAvailable;
-                }
-                else
-                {
-                    rsp.resize(sizeof(netfn) + sizeof(cmd) + sizeof(cc) +
-                               payload.size());
-
-                    // write the response
-                    auto rspIter = rsp.begin();
-                    *rspIter++ = (netfn << netFnShift) | (lun & lunMask);
-                    *rspIter++ = cmd;
-                    *rspIter++ = cc;
-                    if (payload.size())
-                    {
-                        std::copy(payload.cbegin(), payload.cend(), rspIter);
-                    }
-                }
-                if (verbose)
-                {
-                    log<level::INFO>(
-                        "Send rsp msg", entry("NETFN=0x%02x", netfn),
-                        entry("LUN=0x%02x", lun), entry("CMD=0x%02x", cmd),
-                        entry("CC=0x%02x", cc));
-                }
-                boost::system::error_code ecWr;
-                size_t wlen =
-                    boost::asio::write(*dev, boost::asio::buffer(rsp), ecWr);
-                if (ecWr || wlen != rsp.size())
-                {
-                    log<level::ERR>(
-                        "Failed to send rsp msg", entry("SIZE=%d", wlen),
-                        entry("EXPECT=%d", rsp.size()),
-                        entry("ERROR=%s", ecWr.message().c_str()),
-                        entry("NETFN=0x%02x", netfn), entry("LUN=0x%02x", lun),
-                        entry("CMD=0x%02x", cmd), entry("CC=0x%02x", cc));
-                }
-            },
-            ipmiQueueService, ipmiQueuePath, ipmiQueueIntf, ipmiQueueMethod,
-            netfn, lun, cmd, data, options);
-    }
-
-    int64_t setAttention()
-    {
-        if (verbose)
-        {
-            log<level::INFO>("Sending SET_SMS_ATTENTION");
-        }
-        io_control::SetSmsAttention command;
-        boost::system::error_code ec;
-        dev->io_control(command, ec);
-        if (ec)
-        {
-            log<level::ERR>("Couldn't SET_SMS_ATTENTION",
-                            entry("ERROR=%s", ec.message().c_str()));
-            return ec.value();
-        }
-        return 0;
-    }
-
-    int64_t clearAttention()
-    {
-        if (verbose)
-        {
-            log<level::INFO>("Sending CLEAR_SMS_ATTENTION");
-        }
-        io_control::ClearSmsAttention command;
-        boost::system::error_code ec;
-        dev->io_control(command, ec);
-        if (ec)
-        {
-            log<level::ERR>("Couldn't CLEAR_SMS_ATTENTION",
-                            entry("ERROR=%s", ec.message().c_str()));
-            return ec.value();
-        }
-        return 0;
-    }
-
-    int64_t forceAbort()
-    {
-        if (verbose)
-        {
-            log<level::INFO>("Sending FORCE_ABORT");
-        }
-        io_control::ForceAbort command;
-        boost::system::error_code ec;
-        dev->io_control(command, ec);
-        if (ec)
-        {
-            log<level::ERR>("Couldn't FORCE_ABORT",
-                            entry("ERROR=%s", ec.message().c_str()));
-            return ec.value();
-        }
-        return 0;
-    }
-
-  protected:
-    std::array<uint8_t, kcsMessageSize> xferBuffer;
-    std::shared_ptr<boost::asio::io_context> io;
-    std::shared_ptr<sdbusplus::asio::connection> bus;
-    std::shared_ptr<sdbusplus::asio::object_server> server;
-    std::unique_ptr<boost::asio::posix::stream_descriptor> dev = nullptr;
-    bool verbose;
-};
-
-} // namespace
-
-int main(int argc, char* argv[])
-{
-    CLI::App app("KCS IPMI bridge");
-    std::string channel;
-    app.add_option("-c,--channel", channel, "channel name. e.g., ipmi-kcs3")
-        ->required();
-    bool verbose = false;
-    app.add_option("-v,--verbose", verbose, "print more verbose output");
-    CLI11_PARSE(app, argc, argv);
-
-    // Connect to system bus
-    auto io = std::make_shared<boost::asio::io_context>();
-    sd_bus* dbus;
-    sd_bus_default_system(&dbus);
-    auto bus = std::make_shared<sdbusplus::asio::connection>(*io, dbus);
-
-    // Create the channel, listening on D-Bus and on the SMS device
-    SmsChannel smsChannel(io, bus, channel, verbose);
-
-    if (!smsChannel.initOK())
-    {
-        return EXIT_FAILURE;
-    }
-
-    static constexpr const char busBase[] = "xyz.openbmc_project.Ipmi.Channel.";
-    std::string busName(busBase + boost::replace_all_copy(channel, "-", "_"));
-    bus->request_name(busName.c_str());
-
-    io->run();
-
-    return 0;
-}
diff --git a/src/main.cpp b/src/main.cpp
new file mode 100644
index 0000000..e8863e8
--- /dev/null
+++ b/src/main.cpp
@@ -0,0 +1,85 @@
+#include "args.hpp"
+#include "cmd.hpp"
+#include "server.hpp"
+
+#include <fmt/format.h>
+#include <systemd/sd-daemon.h>
+
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/slot.hpp>
+#include <sdeventplus/event.hpp>
+#include <sdeventplus/source/io.hpp>
+#include <sdeventplus/source/signal.hpp>
+#include <stdplus/exception.hpp>
+#include <stdplus/fd/create.hpp>
+#include <stdplus/signal.hpp>
+
+#include <algorithm>
+#include <stdexcept>
+#include <string>
+
+namespace kcsbridge
+{
+
+using sdeventplus::source::IO;
+using sdeventplus::source::Signal;
+using stdplus::fd::OpenAccess;
+using stdplus::fd::OpenFlag;
+using stdplus::fd::OpenFlags;
+
+int execute(const char* channel)
+{
+    // Set up our DBus and event loop
+    auto event = sdeventplus::Event::get_default();
+    auto bus = sdbusplus::bus::new_default();
+    bus.attach_event(event.get(), SD_EVENT_PRIORITY_NORMAL);
+
+    // Configure basic signal handling
+    auto exit_handler = [&event](Signal&, const struct signalfd_siginfo*) {
+        fmt::print(stderr, "Interrupted, Exiting\n");
+        event.exit(0);
+    };
+    stdplus::signal::block(SIGINT);
+    Signal sig_int(event, SIGINT, exit_handler);
+    stdplus::signal::block(SIGTERM);
+    Signal sig_term(event, SIGTERM, exit_handler);
+
+    // Open an FD for the KCS channel
+    stdplus::ManagedFd kcs = stdplus::fd::open(
+        fmt::format("/dev/{}", channel),
+        OpenFlags(OpenAccess::ReadWrite).set(OpenFlag::NonBlock));
+    sdbusplus::slot::slot slot(nullptr);
+
+    // Add a reader to the bus for handling inbound IPMI
+    IO ioSource(
+        event, kcs.get(), EPOLLIN | EPOLLET,
+        stdplus::exception::ignore(
+            [&kcs, &bus, &slot](IO&, int, uint32_t) { read(kcs, bus, slot); }));
+
+    // Allow processes to affect the state machine
+    std::string dbusChannel = channel;
+    std::replace(dbusChannel.begin(), dbusChannel.end(), '-', '_');
+    auto obj = "/xyz/openbmc_project/Ipmi/Channel/" + dbusChannel;
+    auto srv = "xyz.openbmc_project.Ipmi.Channel." + dbusChannel;
+    auto intf = createSMSHandler(bus, obj.c_str(), kcs);
+    bus.request_name(srv.c_str());
+
+    sd_notify(0, "READY=1");
+    return event.loop();
+}
+
+} // namespace kcsbridge
+
+int main(int argc, char* argv[])
+{
+    try
+    {
+        kcsbridge::Args args(argc, argv);
+        return kcsbridge::execute(args.channel);
+    }
+    catch (const std::exception& e)
+    {
+        fmt::print(stderr, "FAILED: {}\n", e.what());
+        return 1;
+    }
+}
diff --git a/src/meson.build b/src/meson.build
index 7d57e5a..68b6f9a 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -1,35 +1,49 @@
-# CLI11 might not have a pkg-config. It is header only so just make
-# sure we can access the needed symbols from the header.
-cli11_dep = dependency('cli11', required: false)
-has_cli11 = meson.get_compiler('cpp').has_header_symbol(
-  'CLI/CLI.hpp',
-  'CLI::App',
-  dependencies: cli11_dep,
-  required: false)
-assert(has_cli11, 'CLI11 is required')
+headers = include_directories('.')
+
+fmt_dep = dependency('fmt', required: false)
+if not fmt_dep.found()
+  fmt_opts = import('cmake').subproject_options()
+  fmt_opts.add_cmake_defines({
+    'CMAKE_POSITION_INDEPENDENT_CODE': 'ON',
+    'MASTER_PROJECT': 'OFF',
+  })
+  fmt_proj = import('cmake').subproject(
+    'fmt',
+    options: fmt_opts,
+    required: false)
+  assert(fmt_proj.found(), 'fmtlib is required')
+  fmt_dep = fmt_proj.dependency('fmt')
+endif
+
+
+deps = [
+  fmt_dep,
+  dependency('stdplus', fallback: ['stdplus', 'stdplus_dep']),
+  dependency('sdbusplus', fallback: ['sdbusplus', 'sdbusplus_dep']),
+]
+
+lib = static_library(
+  'kcsbridged',
+  'args.cpp',
+  'cmd.cpp',
+  'server.cpp',
+  include_directories: headers,
+  implicit_include_directories: false,
+  dependencies: deps)
+
+dep = declare_dependency(
+  dependencies: deps,
+  include_directories: headers,
+  link_with: lib)
 
 kcsbridged = executable(
   'kcsbridged',
-  'kcsbridged.cpp',
+  'main.cpp',
   implicit_include_directories: false,
   dependencies: [
-    dependency(
-      'boost',
-      modules: [
-        'coroutine',
-        'context',
-      ],
-    ),
-    cli11_dep,
-    dependency('phosphor-logging'),
-    dependency('sdbusplus'),
-  ],
-  cpp_args: [
-    '-DBOOST_ASIO_DISABLE_THREADS',
-    '-DBOOST_ALL_NO_LIB',
-    '-DBOOST_SYSTEM_NO_DEPRECATED',
-    '-DBOOST_ERROR_CODE_HEADER_ONLY',
-    '-DBOOST_COROUTINES_NO_DEPRECATION_WARNING',
+    dep,
+    dependency('sdeventplus', fallback: ['sdeventplus', 'sdeventplus_dep']),
+    dependency('libsystemd'),
   ],
   install: true,
   install_dir: get_option('libexecdir'))
diff --git a/src/server.cpp b/src/server.cpp
new file mode 100644
index 0000000..836ac43
--- /dev/null
+++ b/src/server.cpp
@@ -0,0 +1,72 @@
+#include "server.hpp"
+
+#include <fmt/format.h>
+#include <linux/ipmi_bmc.h>
+
+#include <sdbusplus/exception.hpp>
+#include <sdbusplus/server/interface.hpp>
+#include <sdbusplus/vtable.hpp>
+#include <stdplus/fd/ops.hpp>
+
+#include <stdexcept>
+
+namespace kcsbridge
+{
+
+void setAttention(sdbusplus::message::message& m, stdplus::Fd& kcs)
+{
+    stdplus::fd::ioctl(kcs, IPMI_BMC_IOCTL_SET_SMS_ATN, nullptr);
+    m.new_method_return().method_return();
+}
+
+void clearAttention(sdbusplus::message::message& m, stdplus::Fd& kcs)
+{
+    stdplus::fd::ioctl(kcs, IPMI_BMC_IOCTL_CLEAR_SMS_ATN, nullptr);
+    m.new_method_return().method_return();
+}
+
+void forceAbort(sdbusplus::message::message& m, stdplus::Fd& kcs)
+{
+    stdplus::fd::ioctl(kcs, IPMI_BMC_IOCTL_FORCE_ABORT, nullptr);
+    m.new_method_return().method_return();
+}
+
+template <auto func, typename Data>
+int methodRsp(sd_bus_message* mptr, void* dataptr, sd_bus_error* error) noexcept
+{
+    sdbusplus::message::message m(mptr);
+    try
+    {
+        func(m, *reinterpret_cast<Data*>(dataptr));
+    }
+    catch (const std::exception& e)
+    {
+        fmt::print(stderr, "Method response failed: {}\n", e.what());
+        sd_bus_error_set(error,
+                         "xyz.openbmc_project.Common.Error.InternalFailure",
+                         "The operation failed internally.");
+    }
+    return 1;
+}
+
+template <typename Data>
+constexpr sdbusplus::vtable::vtable_t dbusMethods[] = {
+    sdbusplus::vtable::start(),
+    sdbusplus::vtable::method("setAttention", "", "",
+                              methodRsp<setAttention, Data>),
+    sdbusplus::vtable::method("clearAttention", "", "",
+                              methodRsp<clearAttention, Data>),
+    sdbusplus::vtable::method("forceAbort", "", "",
+                              methodRsp<forceAbort, Data>),
+    sdbusplus::vtable::end(),
+};
+
+sdbusplus::server::interface::interface createSMSHandler(
+    sdbusplus::bus::bus& bus, const char* obj, stdplus::Fd& kcs)
+{
+    return sdbusplus::server::interface::interface(
+        bus, obj, "xyz.openbmc_project.Ipmi.Channel.SMS",
+        dbusMethods<stdplus::Fd>, reinterpret_cast<stdplus::Fd*>(&kcs));
+}
+
+} // namespace kcsbridge
diff --git a/src/server.hpp b/src/server.hpp
new file mode 100644
index 0000000..6a5f1fe
--- /dev/null
+++ b/src/server.hpp
@@ -0,0 +1,12 @@
+#pragma once
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/server/interface.hpp>
+#include <stdplus/fd/intf.hpp>
+
+namespace kcsbridge
+{
+
+sdbusplus::server::interface::interface createSMSHandler(
+    sdbusplus::bus::bus& bus, const char* obj, stdplus::Fd& kcs);
+
+}
