diff --git a/Cargo.lock b/Cargo.lock
index b9cefe0..100d5ce 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1014,6 +1014,9 @@ name = "hostd"
 version = "0.2.0"
 dependencies = [
  "anyhow",
+ "serde",
+ "serde_derive",
+ "serde_json",
  "tokio",
  "varlink",
  "varlink_generator",
@@ -2616,9 +2619,9 @@ dependencies = [
 
 [[package]]
 name = "serde_json"
-version = "1.0.134"
+version = "1.0.135"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d00f4175c42ee48b15416f6193a959ba3a0d67fc699a0db9ad12df9f83991c7d"
+checksum = "2b0d7ba2887406110130a978386c4e1befb98c674b4fba677954e4db976630d9"
 dependencies = [
  "itoa",
  "memchr",
diff --git a/hostd/Cargo.toml b/hostd/Cargo.toml
index f6d79cc..fc9c6c3 100644
--- a/hostd/Cargo.toml
+++ b/hostd/Cargo.toml
@@ -5,6 +5,9 @@ edition.workspace = true
 
 [dependencies]
 anyhow.workspace = true
+serde.workspace = true
+serde_derive = "1.0.217"
+serde_json = "1.0.135"
 tokio.workspace = true
 varlink = "11.0.1"
 
diff --git a/hostd/src/main.rs b/hostd/src/main.rs
index 47ad8c6..02d26db 100644
--- a/hostd/src/main.rs
+++ b/hostd/src/main.rs
@@ -1,3 +1,67 @@
-fn main() {
-    println!("Hello World!");
+use std::{
+    collections::HashMap,
+    process::exit,
+    sync::{Arc, RwLock},
+};
+
+use crate::io_patagia_Hostd::{
+    Call_Apply, Call_Describe, Label, Machine, PatagiaAgentConfig, VarlinkInterface,
+};
+
+mod io_patagia_Hostd;
+
+struct Hostd {
+    pub state: Arc<RwLock<i64>>,
+}
+
+impl VarlinkInterface for Hostd {
+    fn apply(&self, call: &mut dyn Call_Apply, machine: Machine) -> varlink::Result<()> {
+        println!("Machine: {:#?}", machine);
+        return call.reply();
+    }
+
+    fn describe(&self, call: &mut dyn Call_Describe) -> varlink::Result<()> {
+        let machine = Machine {
+            machineId: "1".to_string(),
+            nodeLabels: Option::from(vec![Label {
+                key: "key".to_string(),
+                value: "value".to_string(),
+            }]),
+            patagiaAgent: Option::from(PatagiaAgentConfig {
+                url: "hostname".to_string(),
+                extraMounts: HashMap::new(),
+            }),
+        };
+        return call.reply(machine);
+    }
+}
+
+fn main() {
+    let state = Arc::new(RwLock::new(0));
+    let hostd = Hostd { state };
+    let hostd_interface = io_patagia_Hostd::new(Box::new(hostd));
+
+    let svc = varlink::VarlinkService::new(
+        "io.patagia.Hostd",
+        "Host controller for patagia",
+        "0.1",
+        "https://patagia.dev",
+        vec![Box::new(hostd_interface)],
+    );
+    let ret: Result<(), varlink::Error> = varlink::listen(
+        svc,
+        "unix:/tmp/io.patagia.Hostd",
+        &varlink::ListenConfig {
+            idle_timeout: 1,
+            ..Default::default()
+        },
+    );
+
+    exit(match ret {
+        Ok(_) => 0,
+        Err(e) => {
+            println!("Error: {}", e);
+            1
+        }
+    });
 }