diff --git a/services/tunnelbroker/src/constants.rs b/services/tunnelbroker/src/constants.rs
--- a/services/tunnelbroker/src/constants.rs
+++ b/services/tunnelbroker/src/constants.rs
@@ -1,2 +1,3 @@
 pub const GRPC_TX_QUEUE_SIZE: usize = 32;
 pub const GRPC_PING_INTERVAL_MS: u64 = 3000;
+pub const GRPC_SERVER_PORT: u64 = 50051;
diff --git a/services/tunnelbroker/src/main.rs b/services/tunnelbroker/src/main.rs
--- a/services/tunnelbroker/src/main.rs
+++ b/services/tunnelbroker/src/main.rs
@@ -1,6 +1,10 @@
 pub mod constants;
 pub mod cxx_bridge;
+pub mod server;
+use anyhow::Result;
 
-pub fn main() {
+#[tokio::main]
+async fn main() -> Result<()> {
   cxx_bridge::ffi::initialize();
+  server::run_grpc_server().await
 }
diff --git a/services/tunnelbroker/src/server/mod.rs b/services/tunnelbroker/src/server/mod.rs
new file mode 100644
--- /dev/null
+++ b/services/tunnelbroker/src/server/mod.rs
@@ -0,0 +1,96 @@
+use super::constants;
+use anyhow::Result;
+use futures::Stream;
+use std::pin::Pin;
+use tonic::transport::Server;
+use tonic::{Request, Response, Status, Streaming};
+use tunnelbroker::tunnelbroker_service_server::{
+  TunnelbrokerService, TunnelbrokerServiceServer,
+};
+
+mod tunnelbroker {
+  tonic::include_proto!("tunnelbroker");
+}
+
+#[derive(Debug, Default)]
+struct TunnelbrokerServiceHandlers {}
+
+#[tonic::async_trait]
+impl TunnelbrokerService for TunnelbrokerServiceHandlers {
+  async fn session_signature(
+    &self,
+    _request: Request<tunnelbroker::SessionSignatureRequest>,
+  ) -> Result<Response<tunnelbroker::SessionSignatureResponse>, Status> {
+    Err(Status::unimplemented("Not implemented yet"))
+  }
+
+  async fn new_session(
+    &self,
+    _request: Request<tunnelbroker::NewSessionRequest>,
+  ) -> Result<Response<tunnelbroker::NewSessionResponse>, Status> {
+    Err(Status::unimplemented("Not implemented yet"))
+  }
+
+  type MessagesStreamStream = Pin<
+    Box<
+      dyn Stream<Item = Result<tunnelbroker::MessageToClient, Status>> + Send,
+    >,
+  >;
+  async fn messages_stream(
+    &self,
+    _request: Request<Streaming<tunnelbroker::MessageToTunnelbroker>>,
+  ) -> Result<Response<Self::MessagesStreamStream>, Status> {
+    Err(Status::unimplemented("Not implemented yet"))
+  }
+
+  // These empty old API handlers are deprecated and should be removed.
+  // They are implemented only to fix the building process.
+  async fn check_if_primary_device_online(
+    &self,
+    _request: Request<tunnelbroker::CheckRequest>,
+  ) -> Result<Response<tunnelbroker::CheckResponse>, Status> {
+    Err(Status::cancelled("Deprecated"))
+  }
+
+  async fn become_new_primary_device(
+    &self,
+    _request: Request<tunnelbroker::NewPrimaryRequest>,
+  ) -> Result<Response<tunnelbroker::NewPrimaryResponse>, Status> {
+    Err(Status::cancelled("Deprecated"))
+  }
+
+  async fn send_pong(
+    &self,
+    _request: Request<tunnelbroker::PongRequest>,
+  ) -> Result<Response<()>, Status> {
+    Err(Status::cancelled("Deprecated"))
+  }
+
+  async fn send(
+    &self,
+    _request: Request<tunnelbroker::SendRequest>,
+  ) -> Result<Response<()>, Status> {
+    Err(Status::cancelled("Deprecated"))
+  }
+
+  type GetStream = Pin<
+    Box<dyn Stream<Item = Result<tunnelbroker::GetResponse, Status>> + Send>,
+  >;
+  async fn get(
+    &self,
+    _request: Request<tunnelbroker::GetRequest>,
+  ) -> Result<Response<Self::GetStream>, Status> {
+    Err(Status::cancelled("Deprecated"))
+  }
+}
+
+pub async fn run_grpc_server() -> Result<()> {
+  let addr = format!("[::1]:{}", constants::GRPC_SERVER_PORT).parse()?;
+  Server::builder()
+    .add_service(TunnelbrokerServiceServer::new(
+      TunnelbrokerServiceHandlers::default(),
+    ))
+    .serve(addr)
+    .await?;
+  Ok(())
+}