diff --git a/features/kvm/kvm_websocket.hpp b/features/kvm/kvm_websocket.hpp
new file mode 100644
index 0000000..adf4c5e
--- /dev/null
+++ b/features/kvm/kvm_websocket.hpp
@@ -0,0 +1,213 @@
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileCopyrightText: Copyright OpenBMC Authors
+#pragma once
+#include "app.hpp"
+#include "io_context_singleton.hpp"
+#include "logging.hpp"
+#include "websocket.hpp"
+
+#include <sys/types.h>
+
+#include <boost/asio/buffer.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/ip/address.hpp>
+#include <boost/asio/ip/tcp.hpp>
+#include <boost/beast/core/flat_static_buffer.hpp>
+#include <boost/container/flat_map.hpp>
+
+#include <cstddef>
+#include <memory>
+#include <string>
+
+namespace crow
+{
+namespace obmc_kvm
+{
+
+static constexpr const uint maxSessions = 4;
+
+class KvmSession : public std::enable_shared_from_this<KvmSession>
+{
+  public:
+    explicit KvmSession(crow::websocket::Connection& connIn) :
+        conn(connIn), hostSocket(getIoContext())
+    {
+        boost::asio::ip::tcp::endpoint endpoint(
+            boost::asio::ip::make_address("127.0.0.1"), 5900);
+        hostSocket.async_connect(
+            endpoint, [this, &connIn](const boost::system::error_code& ec) {
+                if (ec)
+                {
+                    BMCWEB_LOG_ERROR(
+                        "conn:{}, Couldn't connect to KVM socket port: {}",
+                        logPtr(&conn), ec);
+                    if (ec != boost::asio::error::operation_aborted)
+                    {
+                        connIn.close("Error in connecting to KVM port");
+                    }
+                    return;
+                }
+
+                doRead();
+            });
+    }
+
+    void onMessage(const std::string& data)
+    {
+        if (data.length() > inputBuffer.capacity())
+        {
+            BMCWEB_LOG_ERROR("conn:{}, Buffer overrun when writing {} bytes",
+                             logPtr(&conn), data.length());
+            conn.close("Buffer overrun");
+            return;
+        }
+
+        BMCWEB_LOG_DEBUG("conn:{}, Read {} bytes from websocket", logPtr(&conn),
+                         data.size());
+        size_t copied = boost::asio::buffer_copy(
+            inputBuffer.prepare(data.size()), boost::asio::buffer(data));
+        BMCWEB_LOG_DEBUG("conn:{}, Committing {} bytes from websocket",
+                         logPtr(&conn), copied);
+        inputBuffer.commit(copied);
+
+        BMCWEB_LOG_DEBUG("conn:{}, inputbuffer size {}", logPtr(&conn),
+                         inputBuffer.size());
+        doWrite();
+    }
+
+  protected:
+    void doRead()
+    {
+        std::size_t bytes = outputBuffer.capacity() - outputBuffer.size();
+        BMCWEB_LOG_DEBUG("conn:{}, Reading {} from kvm socket", logPtr(&conn),
+                         bytes);
+        hostSocket.async_read_some(
+            outputBuffer.prepare(outputBuffer.capacity() - outputBuffer.size()),
+            [this, weak(weak_from_this())](const boost::system::error_code& ec,
+                                           std::size_t bytesRead) {
+                auto self = weak.lock();
+                if (self == nullptr)
+                {
+                    return;
+                }
+                BMCWEB_LOG_DEBUG("conn:{}, read done.  Read {} bytes",
+                                 logPtr(&conn), bytesRead);
+                if (ec)
+                {
+                    BMCWEB_LOG_ERROR(
+                        "conn:{}, Couldn't read from KVM socket port: {}",
+                        logPtr(&conn), ec);
+                    if (ec != boost::asio::error::operation_aborted)
+                    {
+                        conn.close("Error in connecting to KVM port");
+                    }
+                    return;
+                }
+
+                outputBuffer.commit(bytesRead);
+                std::string_view payload(
+                    static_cast<const char*>(outputBuffer.data().data()),
+                    bytesRead);
+                BMCWEB_LOG_DEBUG("conn:{}, Sending payload size {}",
+                                 logPtr(&conn), payload.size());
+                conn.sendBinary(payload);
+                outputBuffer.consume(bytesRead);
+
+                doRead();
+            });
+    }
+
+    void doWrite()
+    {
+        if (doingWrite)
+        {
+            BMCWEB_LOG_DEBUG("conn:{}, Already writing.  Bailing out",
+                             logPtr(&conn));
+            return;
+        }
+        if (inputBuffer.size() == 0)
+        {
+            BMCWEB_LOG_DEBUG("conn:{}, inputBuffer empty.  Bailing out",
+                             logPtr(&conn));
+            return;
+        }
+
+        doingWrite = true;
+        hostSocket.async_write_some(
+            inputBuffer.data(),
+            [this, weak(weak_from_this())](const boost::system::error_code& ec,
+                                           std::size_t bytesWritten) {
+                auto self = weak.lock();
+                if (self == nullptr)
+                {
+                    return;
+                }
+                BMCWEB_LOG_DEBUG("conn:{}, Wrote {}bytes", logPtr(&conn),
+                                 bytesWritten);
+                doingWrite = false;
+                inputBuffer.consume(bytesWritten);
+
+                if (ec == boost::asio::error::eof)
+                {
+                    conn.close("KVM socket port closed");
+                    return;
+                }
+                if (ec)
+                {
+                    BMCWEB_LOG_ERROR("conn:{}, Error in KVM socket write {}",
+                                     logPtr(&conn), ec);
+                    if (ec != boost::asio::error::operation_aborted)
+                    {
+                        conn.close("Error in reading to host port");
+                    }
+                    return;
+                }
+
+                doWrite();
+            });
+    }
+
+    crow::websocket::Connection& conn;
+    boost::asio::ip::tcp::socket hostSocket;
+    boost::beast::flat_static_buffer<1024UL * 50UL> outputBuffer;
+    boost::beast::flat_static_buffer<1024UL> inputBuffer;
+    bool doingWrite{false};
+};
+
+using SessionMap = boost::container::flat_map<crow::websocket::Connection*,
+                                              std::shared_ptr<KvmSession>>;
+// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
+static SessionMap sessions;
+
+inline void requestRoutes(App& app)
+{
+    sessions.reserve(maxSessions);
+
+    BMCWEB_ROUTE(app, "/kvm/0")
+        .privileges({{"ConfigureComponents", "ConfigureManager"}})
+        .websocket()
+        .onopen([](crow::websocket::Connection& conn) {
+            BMCWEB_LOG_DEBUG("Connection {} opened", logPtr(&conn));
+
+            if (sessions.size() == maxSessions)
+            {
+                conn.close("Max sessions are already connected");
+                return;
+            }
+
+            sessions[&conn] = std::make_shared<KvmSession>(conn);
+        })
+        .onclose([](crow::websocket::Connection& conn, const std::string&) {
+            sessions.erase(&conn);
+        })
+        .onmessage([](crow::websocket::Connection& conn,
+                      const std::string& data, bool) {
+            if (sessions[&conn])
+            {
+                sessions[&conn]->onMessage(data);
+            }
+        });
+}
+
+} // namespace obmc_kvm
+} // namespace crow
diff --git a/features/kvm/meson.build b/features/kvm/meson.build
new file mode 100644
index 0000000..ab60765
--- /dev/null
+++ b/features/kvm/meson.build
@@ -0,0 +1 @@
+incdir += include_directories('.')
