diff --git a/build/source_list.bzl b/build/source_list.bzl
index ebc17ad..9c579af 100644
--- a/build/source_list.bzl
+++ b/build/source_list.bzl
@@ -1758,6 +1758,7 @@
     "quic/qbone/qbone_server_session.h",
     "quic/qbone/qbone_session_base.h",
     "quic/qbone/qbone_stream.h",
+    "quic/qbone/test_tools/basic_quic_server.h",
 ]
 qbone_srcs = [
     "quic/qbone/bonnet/icmp_reachable.cc",
@@ -1795,6 +1796,7 @@
     "quic/qbone/qbone_session_test.cc",
     "quic/qbone/qbone_stream.cc",
     "quic/qbone/qbone_stream_test.cc",
+    "quic/qbone/test_tools/basic_quic_server.cc",
 ]
 blind_sign_auth_hdrs = [
     "blind_sign_auth/blind_sign_auth.h",
diff --git a/build/source_list.gni b/build/source_list.gni
index 0bc2ac7..b6a23cf 100644
--- a/build/source_list.gni
+++ b/build/source_list.gni
@@ -1763,6 +1763,7 @@
     "src/quiche/quic/qbone/qbone_server_session.h",
     "src/quiche/quic/qbone/qbone_session_base.h",
     "src/quiche/quic/qbone/qbone_stream.h",
+    "src/quiche/quic/qbone/test_tools/basic_quic_server.h",
 ]
 qbone_srcs = [
     "src/quiche/quic/qbone/bonnet/icmp_reachable.cc",
@@ -1800,6 +1801,7 @@
     "src/quiche/quic/qbone/qbone_session_test.cc",
     "src/quiche/quic/qbone/qbone_stream.cc",
     "src/quiche/quic/qbone/qbone_stream_test.cc",
+    "src/quiche/quic/qbone/test_tools/basic_quic_server.cc",
 ]
 blind_sign_auth_hdrs = [
     "src/quiche/blind_sign_auth/blind_sign_auth.h",
diff --git a/build/source_list.json b/build/source_list.json
index 1b3cbe7..d0589ee 100644
--- a/build/source_list.json
+++ b/build/source_list.json
@@ -1761,7 +1761,8 @@
     "quiche/quic/qbone/qbone_packet_writer.h",
     "quiche/quic/qbone/qbone_server_session.h",
     "quiche/quic/qbone/qbone_session_base.h",
-    "quiche/quic/qbone/qbone_stream.h"
+    "quiche/quic/qbone/qbone_stream.h",
+    "quiche/quic/qbone/test_tools/basic_quic_server.h"
   ],
   "qbone_srcs": [
     "quiche/quic/qbone/bonnet/icmp_reachable.cc",
@@ -1798,7 +1799,8 @@
     "quiche/quic/qbone/qbone_session_base.cc",
     "quiche/quic/qbone/qbone_session_test.cc",
     "quiche/quic/qbone/qbone_stream.cc",
-    "quiche/quic/qbone/qbone_stream_test.cc"
+    "quiche/quic/qbone/qbone_stream_test.cc",
+    "quiche/quic/qbone/test_tools/basic_quic_server.cc"
   ],
   "blind_sign_auth_hdrs": [
     "quiche/blind_sign_auth/blind_sign_auth.h",
diff --git a/quiche/quic/qbone/test_tools/basic_quic_server.cc b/quiche/quic/qbone/test_tools/basic_quic_server.cc
new file mode 100644
index 0000000..00d58bf
--- /dev/null
+++ b/quiche/quic/qbone/test_tools/basic_quic_server.cc
@@ -0,0 +1,596 @@
+// Copyright 2026 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quiche/quic/qbone/test_tools/basic_quic_server.h"
+
+#include <array>
+#include <cstddef>
+#include <memory>
+#include <queue>
+#include <string>
+#include <thread>  // NOLINT (for open-sourceable thread ID)
+#include <utility>
+#include <vector>
+
+#include "absl/base/attributes.h"
+#include "absl/base/nullability.h"
+#include "absl/base/thread_annotations.h"
+#include "absl/container/flat_hash_map.h"
+#include "absl/status/status.h"
+#include "absl/status/statusor.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "absl/synchronization/mutex.h"
+#include "absl/synchronization/notification.h"
+#include "absl/types/span.h"
+#include "quiche/quic/core/connection_id_generator.h"
+#include "quiche/quic/core/crypto/proof_source.h"
+#include "quiche/quic/core/crypto/quic_crypto_server_config.h"
+#include "quiche/quic/core/crypto/quic_random.h"
+#include "quiche/quic/core/deterministic_connection_id_generator.h"
+#include "quiche/quic/core/io/quic_default_event_loop.h"
+#include "quiche/quic/core/io/quic_event_loop.h"
+#include "quiche/quic/core/io/quic_server_io_harness.h"
+#include "quiche/quic/core/io/socket.h"
+#include "quiche/quic/core/quic_alarm_factory.h"
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_crypto_server_stream_base.h"
+#include "quiche/quic/core/quic_default_clock.h"
+#include "quiche/quic/core/quic_default_connection_helper.h"
+#include "quiche/quic/core/quic_dispatcher.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_stream.h"
+#include "quiche/quic/core/quic_stream_sequencer.h"
+#include "quiche/quic/core/quic_time.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/quic_utils.h"
+#include "quiche/quic/core/quic_version_manager.h"
+#include "quiche/quic/core/quic_versions.h"
+#include "quiche/quic/platform/api/quic_socket_address.h"
+#include "quiche/quic/tools/quic_simple_crypto_server_stream_helper.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+#include "quiche/common/platform/api/quiche_thread.h"
+#include "quiche/common/quiche_callbacks.h"
+#include "quiche/common/quiche_mem_slice.h"
+#include "quiche/common/quiche_socket_address.h"
+#include "quiche/common/quiche_status_utils.h"
+
+namespace quic::test {
+namespace {
+
+using ::quiche::QuicheMemSlice;
+using ::quiche::QuicheSocketAddress;
+using ::quiche::QuicheThread;
+using ::quiche::SingleUseCallback;
+
+constexpr auto kSupportedQuicVersions = std::to_array<ParsedQuicVersion>({
+    ParsedQuicVersion::RFCv1(),
+});
+
+class Stream : public QuicStream {
+ public:
+  Stream(QuicStreamId id,
+         QuicSession* absl_nonnull session ABSL_ATTRIBUTE_LIFETIME_BOUND,
+         BasicQuicServer::Handler* absl_nonnull handler
+             ABSL_ATTRIBUTE_LIFETIME_BOUND)
+      : QuicStream(id, session, /*is_static=*/false,
+                   QuicUtils::GetStreamType(
+                       id, session->connection()->perspective(),
+                       session->IsIncomingStream(id), session->version())),
+        handler_(handler) {
+    // This stream allows leaving data unconsumed in the sequencer, so need to
+    // use level-triggered reading to notify the handler on any increase in
+    // readable bytes.
+    sequencer()->set_level_triggered(true);
+  }
+
+  void OnDataAvailable() override {
+    int consumed = handler_->OnStreamDataAvailable(session()->connection_id(),
+                                                   id(), *sequencer());
+    if (consumed > 0) {
+      sequencer()->MarkConsumed(consumed);
+    }
+  }
+
+ private:
+  BasicQuicServer::Handler* absl_nonnull const handler_;
+};
+
+class Session : public QuicSession {
+ public:
+  class DestructionObserver {
+   public:
+    virtual ~DestructionObserver() = default;
+
+    virtual void OnSessionDestroyed(Session* session) = 0;
+  };
+
+  Session(std::unique_ptr<QuicConnection> absl_nonnull connection,
+          Visitor* visitor, const QuicConfig& config,
+          const QuicCryptoServerConfig* crypto_config,
+          BasicQuicServer::Handler* absl_nonnull handler
+              ABSL_ATTRIBUTE_LIFETIME_BOUND)
+      : QuicSession(connection.get(), visitor, config,
+                    connection->supported_versions(),
+                    /*num_expected_unidirectional_static_streams=*/0),
+        connection_(std::move(connection)),
+        handler_(handler) {
+    crypto_stream_ = handler_->OnNewSession(this, crypto_config);
+    Initialize();
+  }
+
+  ~Session() override {
+    handler_->OnSessionEnd(connection_id());
+
+    if (destruction_observer_) {
+      destruction_observer_->OnSessionDestroyed(this);
+    }
+  }
+
+  void RegisterDestructionObserver(DestructionObserver* absl_nonnull observer) {
+    QUICHE_CHECK(!destruction_observer_);
+    destruction_observer_ = observer;
+  }
+
+  void UnregisterDestructionObserver() {
+    QUICHE_CHECK(destruction_observer_);
+    destruction_observer_ = nullptr;
+  }
+
+  // QuicSession:
+
+  const QuicCryptoStream* GetCryptoStream() const override {
+    return crypto_stream_.get();
+  }
+
+  std::vector<absl::string_view>::const_iterator SelectAlpn(
+      const std::vector<absl::string_view>& alpns) const override {
+    return handler_->SelectAlpn(connection_id(), alpns);
+  }
+
+ protected:
+  QuicStream* CreateIncomingStream(QuicStreamId id) override {
+    if (handler_->OnNewStream(connection_id(), id)) {
+      auto stream = std::make_unique<Stream>(id, this, handler_);
+      Stream* stream_ptr = stream.get();
+      ActivateStream(std::move(stream));
+      return stream_ptr;
+    } else {
+      return nullptr;
+    }
+  }
+
+  QuicCryptoStream* GetMutableCryptoStream() override {
+    return crypto_stream_.get();
+  }
+
+  bool ShouldKeepConnectionAlive() const override { return true; }
+
+  void OnDatagramReceived(absl::string_view datagram) override {
+    absl::Span<const std::byte> datagram_bytes(
+        reinterpret_cast<const std::byte*>(datagram.data()), datagram.size());
+    handler_->OnDatagramReceived(connection_id(), datagram_bytes);
+  }
+
+ private:
+  std::unique_ptr<QuicConnection> connection_;
+  std::unique_ptr<QuicCryptoStream> crypto_stream_;
+  DestructionObserver* absl_nullable destruction_observer_ = nullptr;
+  BasicQuicServer::Handler* absl_nonnull const handler_;
+};
+
+class Dispatcher : public QuicDispatcher, public Session::DestructionObserver {
+ public:
+  Dispatcher(
+      const QuicConfig* config ABSL_ATTRIBUTE_LIFETIME_BOUND,
+      const QuicCryptoServerConfig* crypto_config ABSL_ATTRIBUTE_LIFETIME_BOUND,
+      QuicVersionManager* version_manager ABSL_ATTRIBUTE_LIFETIME_BOUND,
+      std::unique_ptr<QuicAlarmFactory> alarm_factory,
+      ConnectionIdGeneratorInterface* absl_nonnull connection_id_generator
+          ABSL_ATTRIBUTE_LIFETIME_BOUND,
+      BasicQuicServer::Handler* absl_nonnull handler
+          ABSL_ATTRIBUTE_LIFETIME_BOUND)
+      : QuicDispatcher(config, crypto_config, version_manager,
+                       std::make_unique<QuicDefaultConnectionHelper>(),
+                       std::make_unique<QuicSimpleCryptoServerStreamHelper>(),
+                       std::move(alarm_factory), kQuicDefaultConnectionIdLength,
+                       *connection_id_generator),
+        handler_(handler) {}
+
+  ~Dispatcher() override {
+    // Stop sessions from notifying back to this dispatcher on destruction.
+    for (auto& [connection_id, session] : sessions_) {
+      session->UnregisterDestructionObserver();
+    }
+  }
+
+  absl::StatusOr<Session*> GetSession(QuicConnectionId connection_id) {
+    auto it = sessions_.find(connection_id);
+    if (it == sessions_.end()) {
+      return absl::NotFoundError("Session not found.");
+    } else {
+      return it->second;
+    }
+  }
+
+  // Session::DestructionObserver
+  void OnSessionDestroyed(Session* session) override {
+    QUICHE_CHECK_EQ(sessions_.erase(session->connection_id()), 1);
+  }
+
+ protected:
+  std::unique_ptr<QuicSession> CreateQuicSession(
+      QuicConnectionId server_connection_id,
+      const QuicSocketAddress& self_address,
+      const QuicSocketAddress& peer_address, absl::string_view alpn,
+      const ParsedQuicVersion& version, const ParsedClientHello& parsed_chlo,
+      ConnectionIdGeneratorInterface& connection_id_generator) override {
+    QUICHE_LOG(INFO) << "Creating QuicSession for connection "
+                     << server_connection_id << " with peer "
+                     << peer_address.ToString() << " and ALPN " << alpn;
+
+    auto connection = std::make_unique<QuicConnection>(
+        server_connection_id, self_address, peer_address, helper(),
+        alarm_factory(), writer(),
+        /*owns_writer=*/false, Perspective::IS_SERVER,
+        ParsedQuicVersionVector{version}, connection_id_generator);
+
+    auto session = std::make_unique<Session>(
+        std::move(connection), this, config(), crypto_config(), handler_);
+    auto [it, inserted] =
+        sessions_.emplace(server_connection_id, session.get());
+    QUICHE_CHECK(inserted);
+    session->RegisterDestructionObserver(this);
+
+    return session;
+  }
+
+ private:
+  // Non-refed Session pointers to allow destruction, but expect the Session to
+  // call OnSessionDestroyed to remove itself.
+  absl::flat_hash_map<QuicConnectionId, Session*, QuicConnectionIdHash>
+      sessions_;
+
+  BasicQuicServer::Handler* absl_nonnull const handler_;
+};
+
+}  // namespace
+
+class BasicQuicServer::ServerThread : public QuicheThread {
+ public:
+  ServerThread(QuicheSocketAddress socket_address,
+               const QuicConfig* absl_nonnull config
+                   ABSL_ATTRIBUTE_LIFETIME_BOUND,
+               const QuicCryptoServerConfig* absl_nonnull crypto_config
+                   ABSL_ATTRIBUTE_LIFETIME_BOUND,
+               std::unique_ptr<BasicQuicServer::Handler> absl_nonnull handler)
+      : QuicheThread("BasicQuicServerThread"),
+        socket_address_(std::move(socket_address)),
+        config_(config),
+        crypto_config_(crypto_config),
+        handler_(std::move(handler)) {}
+
+  ~ServerThread() override {
+    // Expect/require server to be stopped before destruction.
+    QUICHE_CHECK(!running_notification_.HasBeenNotified() ||
+                 shutdown_notification_.HasBeenNotified());
+    QUICHE_CHECK(!dispatcher_);
+    QUICHE_CHECK(!event_loop_);
+  }
+
+  void Run() override {
+    QUICHE_CHECK(!running_notification_.HasBeenNotified());
+    QUICHE_CHECK(!shutdown_notification_.HasBeenNotified());
+
+    thread_id_ = std::this_thread::get_id();
+
+    QUICHE_CHECK(absl::IsUnknown(initialization_status_));
+    initialization_status_ = Initialize();
+    if (!initialization_status_.ok()) {
+      QUICHE_LOG(ERROR) << "Failed to initialize BasicQuicServer: "
+                        << initialization_status_;
+      running_notification_.Notify();
+      return;
+    }
+
+    bound_address_ = io_harness_->local_address();
+
+    QUICHE_LOG(INFO) << "Starting BasicQuicServer on " << bound_address_;
+    running_notification_.Notify();
+    while (!shutdown_notification_.HasBeenNotified()) {
+      ExecuteScheduledActions();
+      event_loop_->RunEventLoopOnce(QuicTimeDelta::FromMilliseconds(50));
+    }
+    thread_id_ = std::thread::id();
+
+    bound_address_ = QuicheSocketAddress();
+
+    dispatcher_->Shutdown();
+    io_harness_.reset();
+    socket_fd_.reset();
+    dispatcher_.reset();
+
+    // Don't reset `event_loop_`, as off-thread callers may attempt to use it
+    // to call WakeUp().
+  }
+
+  absl::Status WaitForRunning() {
+    running_notification_.WaitForNotification();
+    QUICHE_CHECK(!absl::IsUnknown(initialization_status_));
+    return initialization_status_;
+  }
+
+  void Shutdown() {
+    QUICHE_CHECK(running_notification_.HasBeenNotified());
+    QUICHE_CHECK(!shutdown_notification_.HasBeenNotified());
+    QUICHE_CHECK(!IsRunningOnThread());
+
+    shutdown_notification_.Notify();
+    if (event_loop_->SupportsWakeUp()) {
+      event_loop_->WakeUp();
+    }
+
+    Join();
+  }
+
+  absl::StatusOr<QuicheSocketAddress> bound_address() const {
+    QUICHE_CHECK(IsRunningOnThread());
+
+    return bound_address_;
+  }
+
+  absl::StatusOr<int> SendStreamData(QuicConnectionId server_connection_id,
+                                     QuicStreamId stream_id,
+                                     absl::Span<QuicheMemSlice> data,
+                                     bool fin) {
+    QUICHE_CHECK(IsRunningOnThread());
+    QUICHE_CHECK(dispatcher_);
+
+    QUICHE_ASSIGN_OR_RETURN(QuicSession * session,
+                            dispatcher_->GetSession(server_connection_id));
+
+    QuicStream* stream = session->GetActiveStream(stream_id);
+    if (!stream) {
+      return absl::NotFoundError("Stream not found.");
+    }
+    return stream->WriteMemSlices(data, fin).bytes_consumed;
+  }
+
+  absl::Status SendDatagram(QuicConnectionId server_connection_id,
+                            absl::Span<QuicheMemSlice> data) {
+    QUICHE_CHECK(IsRunningOnThread());
+    QUICHE_CHECK(dispatcher_);
+
+    QUICHE_ASSIGN_OR_RETURN(QuicSession * session,
+                            dispatcher_->GetSession(server_connection_id));
+
+    if (!session->connection() || !session->connection()->connected()) {
+      return absl::FailedPreconditionError("Session is not connected.");
+    }
+
+    DatagramResult result = session->SendDatagram(data);
+    if (result.status == DATAGRAM_STATUS_SUCCESS) {
+      return absl::OkStatus();
+    } else {
+      return absl::InternalError(absl::StrCat(
+          "Failed to send datagram: ", DatagramStatusToString(result.status)));
+    }
+  }
+
+  void Schedule(quiche::SingleUseCallback<void()> callback) {
+    QUICHE_CHECK(running_notification_.HasBeenNotified());
+    QUICHE_CHECK(!shutdown_notification_.HasBeenNotified());
+
+    {
+      absl::MutexLock lock(scheduled_actions_mutex_);
+      scheduled_actions_.push(std::move(callback));
+    }
+
+    if (IsRunningOnThread()) {
+      // Run all scheduled actions immediately if already on the server thread.
+      // This is important to avoid deadlocks if the caller of Schedule() waits
+      // on signals contained in the callback.
+      ExecuteScheduledActions();
+    } else if (event_loop_->SupportsWakeUp()) {
+      event_loop_->WakeUp();
+    }
+  }
+
+  void ScheduleAndWaitForCompletion(
+      quiche::SingleUseCallback<void()> callback) {
+    QUICHE_CHECK(running_notification_.HasBeenNotified());
+    QUICHE_CHECK(!shutdown_notification_.HasBeenNotified());
+
+    if (IsRunningOnThread()) {
+      ExecuteScheduledActions();
+      std::move(callback)();
+    } else {
+      absl::Notification done;
+      Schedule([&callback, &done]() {
+        std::move(callback)();
+        done.Notify();
+      });
+      done.WaitForNotification();
+    }
+  }
+
+  bool IsRunningOnThread() const {
+    return running_notification_.HasBeenNotified() &&
+           thread_id_ == std::this_thread::get_id();
+  }
+
+ private:
+  absl::Status Initialize() {
+    event_loop_ = GetDefaultEventLoop()->Create(QuicDefaultClock::Get());
+    dispatcher_ =
+        std::make_unique<Dispatcher>(config_, crypto_config_, &version_manager_,
+                                     event_loop_->CreateAlarmFactory(),
+                                     &connection_id_generator_, handler_.get());
+
+    QUICHE_ASSIGN_OR_RETURN(socket_fd_,
+                            CreateAndBindServerSocket(socket_address_));
+    QUICHE_ASSIGN_OR_RETURN(
+        io_harness_,
+        QuicServerIoHarness::Create(event_loop_.get(), dispatcher_.get(),
+                                    socket_fd_.get()));
+    io_harness_->InitializeWriter();
+
+    return absl::OkStatus();
+  }
+
+  void ExecuteScheduledActions() {
+    QUICHE_CHECK(IsRunningOnThread());
+
+    std::queue<quiche::SingleUseCallback<void()>> actions;
+    {
+      absl::MutexLock lock(scheduled_actions_mutex_);
+      actions.swap(scheduled_actions_);
+    }
+
+    while (!actions.empty() && !shutdown_notification_.HasBeenNotified()) {
+      std::move(actions.front())();
+      actions.pop();
+    }
+  }
+
+  const QuicheSocketAddress socket_address_;
+  const QuicConfig* absl_nonnull const config_;
+  const QuicCryptoServerConfig* absl_nonnull const crypto_config_;
+  const std::unique_ptr<BasicQuicServer::Handler> absl_nonnull handler_;
+
+  // Must be set before `running_notification_` is notified and not changed
+  // after that.
+  absl::Status initialization_status_ = absl::UnknownError("Not initialized.");
+  std::thread::id thread_id_;
+
+  absl::Notification running_notification_;
+  absl::Notification shutdown_notification_;
+
+  absl::Mutex scheduled_actions_mutex_;
+  std::queue<quiche::SingleUseCallback<void()>> scheduled_actions_
+      ABSL_GUARDED_BY(scheduled_actions_mutex_);
+
+  QuicVersionManager version_manager_{ParsedQuicVersionVector(
+      kSupportedQuicVersions.begin(), kSupportedQuicVersions.end())};
+  DeterministicConnectionIdGenerator connection_id_generator_{
+      kQuicDefaultConnectionIdLength};
+
+  std::unique_ptr<QuicEventLoop> event_loop_;
+  std::unique_ptr<Dispatcher> dispatcher_;
+  OwnedSocketFd socket_fd_;
+  std::unique_ptr<QuicServerIoHarness> io_harness_;
+
+  QuicheSocketAddress bound_address_;
+};
+
+BasicQuicServer::BasicQuicServer(
+    QuicheSocketAddress socket_address,
+    std::unique_ptr<ProofSource> absl_nonnull proof_source)
+    : socket_address_(std::move(socket_address)),
+      crypto_config_(std::make_unique<QuicCryptoServerConfig>(
+          QuicCryptoServerConfig::TESTING, QuicRandom::GetInstance(),
+          std::move(proof_source), KeyExchangeSource::Default())) {}
+
+BasicQuicServer::~BasicQuicServer() {
+  if (server_thread_) {
+    QUICHE_LOG(WARNING) << "BasicQuicServer not stopped before destruction.";
+    QUICHE_CHECK_OK(Stop());
+  }
+}
+
+absl::Status BasicQuicServer::Start(
+    std::unique_ptr<Handler> absl_nonnull handler) {
+  QUICHE_CHECK(!server_thread_) << "Server already running.";
+
+  server_thread_ = std::make_unique<ServerThread>(
+      socket_address_, &config_, crypto_config_.get(), std::move(handler));
+  server_thread_->Start();
+
+  absl::Status status = server_thread_->WaitForRunning();
+  if (!status.ok()) {
+    server_thread_->Shutdown();
+    server_thread_.reset();
+    return status;
+  }
+
+  return absl::OkStatus();
+}
+
+absl::Status BasicQuicServer::Stop() {
+  QUICHE_CHECK(server_thread_) << "Server not running.";
+
+  server_thread_->Shutdown();
+  server_thread_.reset();
+
+  return absl::OkStatus();
+}
+
+void BasicQuicServer::Schedule(quiche::SingleUseCallback<void()> callback) {
+  QUICHE_CHECK(server_thread_) << "Server not running.";
+  server_thread_->Schedule(std::move(callback));
+}
+
+void BasicQuicServer::ScheduleAndWaitForCompletion(
+    quiche::SingleUseCallback<void()> callback) {
+  QUICHE_CHECK(server_thread_) << "Server not running.";
+  server_thread_->ScheduleAndWaitForCompletion(std::move(callback));
+}
+
+absl::StatusOr<QuicheSocketAddress> BasicQuicServer::bound_address() {
+  QUICHE_CHECK(server_thread_) << "Server not running.";
+
+  absl::StatusOr<QuicheSocketAddress> result;
+  const ServerThread* server_thread = server_thread_.get();
+  ScheduleAndWaitForCompletion(
+      [&result, server_thread]() { result = server_thread->bound_address(); });
+  return result;
+}
+
+absl::StatusOr<int> BasicQuicServer::SendStreamData(
+    QuicConnectionId server_connection_id, QuicStreamId stream_id,
+    absl::Span<const std::byte> data, bool fin) {
+  auto mem_slice = QuicheMemSlice::Copy(absl::string_view(
+      reinterpret_cast<const char*>(data.data()), data.size()));
+  return SendStreamData(server_connection_id, stream_id,
+                        absl::MakeSpan(&mem_slice, 1), fin);
+}
+
+absl::StatusOr<int> BasicQuicServer::SendStreamData(
+    QuicConnectionId server_connection_id, QuicStreamId stream_id,
+    absl::Span<quiche::QuicheMemSlice> data, bool fin) {
+  QUICHE_CHECK(server_thread_) << "Server not running.";
+
+  ServerThread* server_thread = server_thread_.get();
+  absl::StatusOr<int> result;
+  ScheduleAndWaitForCompletion(
+      [&result, server_thread, server_connection_id, stream_id, data, fin]() {
+        result = server_thread->SendStreamData(server_connection_id, stream_id,
+                                               data, fin);
+      });
+  return result;
+}
+
+absl::Status BasicQuicServer::SendDatagram(
+    QuicConnectionId server_connection_id, absl::Span<const std::byte> data) {
+  auto mem_slice = QuicheMemSlice::Copy(absl::string_view(
+      reinterpret_cast<const char*>(data.data()), data.size()));
+  return SendDatagram(server_connection_id, absl::MakeSpan(&mem_slice, 1));
+}
+
+absl::Status BasicQuicServer::SendDatagram(
+    QuicConnectionId server_connection_id,
+    absl::Span<quiche::QuicheMemSlice> data) {
+  QUICHE_CHECK(server_thread_) << "Server not running.";
+
+  ServerThread* server_thread = server_thread_.get();
+  absl::Status result;
+  ScheduleAndWaitForCompletion(
+      [&result, server_thread, server_connection_id, data]() {
+        result = server_thread->SendDatagram(server_connection_id, data);
+      });
+  return result;
+}
+
+}  // namespace quic::test
diff --git a/quiche/quic/qbone/test_tools/basic_quic_server.h b/quiche/quic/qbone/test_tools/basic_quic_server.h
new file mode 100644
index 0000000..91b190d
--- /dev/null
+++ b/quiche/quic/qbone/test_tools/basic_quic_server.h
@@ -0,0 +1,124 @@
+// Copyright 2026 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_QBONE_TEST_TOOLS_BASIC_QUIC_SERVER_H_
+#define QUICHE_QUIC_QBONE_TEST_TOOLS_BASIC_QUIC_SERVER_H_
+
+#include <cstddef>
+#include <memory>
+#include <vector>
+
+#include "absl/base/nullability.h"
+#include "absl/status/status.h"
+#include "absl/status/statusor.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/span.h"
+#include "quiche/quic/core/crypto/proof_source.h"
+#include "quiche/quic/core/quic_connection.h"
+#include "quiche/quic/core/quic_connection_id.h"
+#include "quiche/quic/core/quic_dispatcher.h"
+#include "quiche/quic/core/quic_session.h"
+#include "quiche/quic/core/quic_stream_sequencer.h"
+#include "quiche/quic/core/quic_types.h"
+#include "quiche/quic/core/tls_server_handshaker.h"
+#include "quiche/common/quiche_callbacks.h"
+#include "quiche/common/quiche_mem_slice.h"
+#include "quiche/common/quiche_socket_address.h"
+
+namespace quic::test {
+
+// Lightweight QUIC (not necessarily HTTP/3) server for tests and experiments,
+// especially for simulating QBONE Terminator functionality. Receives traffic
+// over a socket on the given socket address, which may be a loopback interface
+// for same-machine (or same-process) testing. Runs on its own dedicated server
+// thread for ease of running same-process as a client.
+class BasicQuicServer final {
+ public:
+  // Interface for handling server events. All calls will be made on the server
+  // thread.
+  class Handler {
+   public:
+    virtual ~Handler() = default;
+
+    // Called on construction of a new QuicSession. Returns the QuicCryptoStream
+    // to use for the session.
+    virtual std::unique_ptr<QuicCryptoStream> OnNewSession(
+        QuicSession* session, const QuicCryptoServerConfig* crypto_config) {
+      return std::make_unique<TlsServerHandshaker>(session, crypto_config);
+    }
+
+    virtual void OnSessionEnd(QuicConnectionId server_connection_id) {}
+
+    // See QuicSession::SelectAlpn.
+    virtual std::vector<absl::string_view>::const_iterator SelectAlpn(
+        QuicConnectionId server_connection_id,
+        const std::vector<absl::string_view>& alpns) const {
+      return alpns.cbegin();
+    }
+
+    // Called on initiation of a new stream from the peer. Returns true iff the
+    // stream should be accepted and created.
+    virtual bool OnNewStream(QuicConnectionId server_connection_id,
+                             QuicStreamId stream_id) {
+      return true;
+    }
+
+    // Called when new data is available on a stream. Returns the number of
+    // bytes that were successfully processed and that should be consumed from
+    // stream buffers.
+    virtual int OnStreamDataAvailable(
+        QuicConnectionId server_connection_id, QuicStreamId stream_id,
+        const QuicStreamSequencer& data_sequencer) {
+      return data_sequencer.ReadableBytes();
+    }
+
+    virtual void OnDatagramReceived(QuicConnectionId server_connection_id,
+                                    absl::Span<const std::byte> data) {}
+  };
+
+  BasicQuicServer(quiche::QuicheSocketAddress socket_address,
+                  std::unique_ptr<ProofSource> absl_nonnull proof_source);
+  ~BasicQuicServer();
+
+  absl::Status Start(std::unique_ptr<Handler> absl_nonnull handler);
+  absl::Status Stop();
+
+  // The following interactions should be safe from any thread, and will
+  // marshall to the server thread as necessary.
+
+  // Not guaranteed to run if the server is stopped.
+  void Schedule(quiche::SingleUseCallback<void()> callback);
+  // Not guaranteed to ever return if the server is stopped.
+  void ScheduleAndWaitForCompletion(quiche::SingleUseCallback<void()> callback);
+
+  absl::StatusOr<quiche::QuicheSocketAddress> bound_address();
+
+  // Returns the number of bytes consumed into the stream (written or buffered).
+  absl::StatusOr<int> SendStreamData(QuicConnectionId server_connection_id,
+                                     QuicStreamId stream_id,
+                                     absl::Span<const std::byte> data,
+                                     bool fin = false);
+  absl::StatusOr<int> SendStreamData(QuicConnectionId server_connection_id,
+                                     QuicStreamId stream_id,
+                                     absl::Span<quiche::QuicheMemSlice> data,
+                                     bool fin = false);
+
+  absl::Status SendDatagram(QuicConnectionId server_connection_id,
+                            absl::Span<const std::byte> data);
+  absl::Status SendDatagram(QuicConnectionId server_connection_id,
+                            absl::Span<quiche::QuicheMemSlice> data);
+
+ private:
+  class ServerThread;
+
+  const quiche::QuicheSocketAddress socket_address_;
+
+  const QuicConfig config_;
+  const std::unique_ptr<QuicCryptoServerConfig> crypto_config_;
+  std::unique_ptr<ServerThread> server_thread_;
+};
+
+}  // namespace quic::test
+
+#endif  // QUICHE_QUIC_QBONE_TEST_TOOLS_BASIC_QUIC_SERVER_H_
