diff --git a/settings.gradle b/settings.gradle
index 21a2225684e38abe85a5b87abe8ef9ce4a23c51b..79726b62291ba2732224150d97a1c5b4558681f7 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -17,9 +17,9 @@ git {
   def pass = System.getenv("GIT_NSHMP_PASSWORD")
 
   if (user && pass) {
-    fetch("https://code.usgs.gov/ghsc/nshmp/nshm-conus-2018.git", {
-      name "nshmp-haz-dep--nshm-conus-2018"
-      tag "0.2.6"
+    fetch("https://code.usgs.gov/ghsc/nshmp/nshms/nshm-hawaii.git", {
+      name "nshmp-haz-dep--nshm-hi-2021"
+      tag "main"
     })
   }
 }
diff --git a/src/main/java/gov/usgs/earthquake/nshmp/www/SourceLogicTreesController.java b/src/main/java/gov/usgs/earthquake/nshmp/www/SourceLogicTreesController.java
new file mode 100644
index 0000000000000000000000000000000000000000..0e5aeba64c8f813b5ce7f1abacc8e87c53dc7746
--- /dev/null
+++ b/src/main/java/gov/usgs/earthquake/nshmp/www/SourceLogicTreesController.java
@@ -0,0 +1,57 @@
+package gov.usgs.earthquake.nshmp.www;
+
+import javax.inject.Inject;
+
+import gov.usgs.earthquake.nshmp.www.services.SourceLogicTreesService;
+
+import io.micronaut.http.HttpRequest;
+import io.micronaut.http.HttpResponse;
+import io.micronaut.http.annotation.Controller;
+import io.micronaut.http.annotation.Get;
+import io.micronaut.http.annotation.PathVariable;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
+import io.swagger.v3.oas.annotations.tags.Tag;
+
+/**
+ * Micronaut controller for NSHM source logic trees.
+ *
+ * @see SourceLogicTreesService
+ * @author U.S. Geological Survey
+ */
+@Tag(
+    name = "Source Logic Trees",
+    description = "NSHM source logic trees service")
+@Controller("/trees")
+public class SourceLogicTreesController {
+
+  @Inject
+  private NshmpMicronautServlet servlet;
+
+  @Operation(
+      description = "Returns the tectonic setting to source logic trees in the NSHM",
+      operationId = "trees_doGetMetadata",
+      summary = "Hazard model source logic trees")
+  @ApiResponse(
+      description = "Source logic trees metadata",
+      responseCode = "200")
+  @Get
+  public HttpResponse<String> doGetMetadata(HttpRequest<?> request) {
+    return SourceLogicTreesService.handleDoGetMetadata(request);
+  }
+
+  /**
+   * @param id Source tree id
+   */
+  @Operation(
+      description = "Returns the source logic tree for an id",
+      operationId = "trees_goGetTrees",
+      summary = "Get NSHM source logic tree")
+  @ApiResponse(
+      description = "NSHM source logic tree",
+      responseCode = "200")
+  @Get(uri = "/{id}")
+  public HttpResponse<String> doGetTrees(HttpRequest<?> request, @PathVariable int id) {
+    return SourceLogicTreesService.handleDoGetTrees(request, id);
+  }
+}
diff --git a/src/main/java/gov/usgs/earthquake/nshmp/www/services/ServletUtil.java b/src/main/java/gov/usgs/earthquake/nshmp/www/services/ServletUtil.java
index 3c277e2bad98b422863dceea9328c05f0a7229db..2c4c8951ba37afa7118abe57aa267b25614dd6cf 100644
--- a/src/main/java/gov/usgs/earthquake/nshmp/www/services/ServletUtil.java
+++ b/src/main/java/gov/usgs/earthquake/nshmp/www/services/ServletUtil.java
@@ -67,7 +67,6 @@ public class ServletUtil {
   // private static List<HazardModel> HAZARD_MODELS = new ArrayList<>();
 
   private static HazardModel HAZARD_MODEL;
-  private static final String MODEL_INFO = "model-info.json";
 
   static {
     /* TODO modified for deagg-epsilon branch; should be context var */
@@ -86,10 +85,6 @@ public class ServletUtil {
         .create();
   }
 
-  // static List<HazardModel> hazardModels() {
-  // return List.copyOf(HAZARD_MODELS);
-  // }
-
   static HazardModel model() {
     return HAZARD_MODEL;
   }
@@ -103,14 +98,6 @@ public class ServletUtil {
   @EventListener
   void startup(StartupEvent event) {
     HAZARD_MODEL = loadModel(modelPath);
-    // TODO should model path just be libs/model
-    // try {
-    // var modelFinder = new ModelFinder();
-    // Files.walkFileTree(modelPath, modelFinder);
-    // modelFinder.paths().forEach(path -> HAZARD_MODELS.add(loadModel(path)));
-    // } catch (IOException e) {
-    // throw new RuntimeException(e);
-    // }
   }
 
   private HazardModel loadModel(Path path) {
@@ -183,31 +170,7 @@ public class ServletUtil {
     }
   }
 
-  // private static class ModelFinder extends SimpleFileVisitor<Path> {
-  // private List<Path> paths;
-  //
-  // ModelFinder() {
-  // paths = new ArrayList<>();
-  // }
-  //
-  // List<Path> paths() {
-  // return List.copyOf(paths);
-  // }
-  //
-  // @Override
-  // public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) {
-  // var fileName = path.getFileName();
-  //
-  // if (fileName != null && fileName.toString().equals(MODEL_INFO)) {
-  // paths.add(path.getParent());
-  // }
-  //
-  // return FileVisitResult.CONTINUE;
-  // }
-  // }
-
   private static class PathConverter implements JsonSerializer<Path> {
-
     @Override
     public JsonElement serialize(
         Path path,
diff --git a/src/main/java/gov/usgs/earthquake/nshmp/www/services/SourceLogicTreesService.java b/src/main/java/gov/usgs/earthquake/nshmp/www/services/SourceLogicTreesService.java
new file mode 100644
index 0000000000000000000000000000000000000000..e867935c0f49265693851167a5746d49e483d9c1
--- /dev/null
+++ b/src/main/java/gov/usgs/earthquake/nshmp/www/services/SourceLogicTreesService.java
@@ -0,0 +1,57 @@
+package gov.usgs.earthquake.nshmp.www.services;
+
+import javax.inject.Singleton;
+
+import gov.usgs.earthquake.nshmp.model.Models;
+import gov.usgs.earthquake.nshmp.www.Response;
+import gov.usgs.earthquake.nshmp.www.SourceLogicTreesController;
+import gov.usgs.earthquake.nshmp.www.meta.Status;
+
+import io.micronaut.http.HttpRequest;
+import io.micronaut.http.HttpResponse;
+
+/**
+ * Source model tree handler for {@link SourceLogicTreesController}
+ *
+ * @author U.S. Geological Survey
+ */
+@Singleton
+public class SourceLogicTreesService {
+
+  private static final String NAME = "Source Logic Trees";
+
+  /** SourceLogicTreesController.doGetMetadata() handler */
+  public static HttpResponse<String> handleDoGetMetadata(HttpRequest<?> request) {
+    var url = request.getUri().getPath();
+
+    try {
+      var trees = Models.trees(ServletUtil.model());
+      var response = new Response<>(Status.SUCCESS, NAME, url, trees, url);
+      return HttpResponse.ok(ServletUtil.GSON.toJson(response));
+    } catch (Exception e) {
+      return ServicesUtil.handleError(e, NAME, url);
+    }
+  }
+
+  /** SourceLogicTreesController.doGetTrees() handler */
+  public static HttpResponse<String> handleDoGetTrees(HttpRequest<?> request, Integer id) {
+    var url = request.getUri().getPath();
+
+    try {
+      var tree = Models.tree(ServletUtil.model(), id);
+      var requestData = new RequestData(id);
+      var response = new Response<>(Status.SUCCESS, NAME, requestData, tree, url);
+      return HttpResponse.ok(ServletUtil.GSON.toJson(response));
+    } catch (Exception e) {
+      return ServicesUtil.handleError(e, NAME, url);
+    }
+  }
+
+  private static class RequestData {
+    int id;
+
+    RequestData(int id) {
+      this.id = id;
+    }
+  }
+}
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index d875d42d0166e8ad2674aaf6453f196f2e8f2be4..5be042a97e071be871a87e1f252a5c5323c4dc10 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -21,4 +21,4 @@ nshmp-haz:
   # The path to the models.
   # To specify the model to use:
   #     java -jar build/libs/nshmp-haz.jar --models=<path/to/models>
-  model-path: ${models:libs/nshmp-haz-dep--nshm-conus-2018}
+  model-path: ${models:libs/nshmp-haz-dep--nshm-hi-2021}