diff --git a/build.gradle b/build.gradle
index 78d36a5f00a7e492ed942c37129a398fdbd17f26..c78af92822950c89b84ac6a4f23fcbf49817f2bb 100644
--- a/build.gradle
+++ b/build.gradle
@@ -6,7 +6,7 @@ plugins {
   id "com.github.spotbugs" version "${spotbugsVersion}"
   id "com.palantir.git-version" version "${gitVersionVersion}" apply false
   id "com.star-zero.gradle.githook" version "${githooksVersion}"
-  id "de.undercouch.download" version "${downloadVersion}"
+  id "org.ajoberstar.grgit" version "${grgitVersion}"
   id "eclipse-wtp"
   id "jacoco"
   id "maven-publish"
diff --git a/gradle.properties b/gradle.properties
index 20fe253f34ab6885bc84bff3094199822fca801f..4957dd250c4fc2b5e21abe2c9fabf1831a5a1fd9 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -2,17 +2,18 @@ awsEc2Version = 1.11.619
 awsLambdaCoreVersion = 1.1.0
 awsLambdaVersion = 1.11.461
 awsS3Version = 1.11.579
-downloadVersion = 5.1.0
 githooksVersion = 1.2.0
 gitVersionVersion = 0.15.0
+grgitVersion = 4.1.1
 jacksonVersion = 2.9.0
+jgitVersion = 6.7.0.202309050840-r
 junitVersion = 5.8.2
 micronautVersion = 3.2.3
 micronautRxVersion = 2.1.1
 nodePluginVersion = 3.0.1
 nodeVersion = 16.3.0
-nshmpLibVersion = 1.4.0
-nshmpWsUtilsVersion = 0.3.12
+nshmpLibVersion = 1.4.1
+nshmpWsUtilsVersion = 0.3.13
 openApiVersion = 4.0.0
 shadowVersion = 7.1.2
 spotbugsVersion = 4.7.0
diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle
index 11c2ead627a716c70f4ecccbdec81ef355105031..db7668355832eeab383d73a4b8604a4f7be4e173 100644
--- a/gradle/dependencies.gradle
+++ b/gradle/dependencies.gradle
@@ -8,6 +8,9 @@ dependencies {
   }
   implementation "ghsc:nshmp-ws-utils:${nshmpWsUtilsVersion}"
 
+  // Git
+  implementation "org.eclipse.jgit:org.eclipse.jgit:${jgitVersion}"
+
   // AWS
   implementation "com.amazonaws:aws-lambda-java-core:${awsLambdaCoreVersion}"
   implementation "com.amazonaws:aws-java-sdk-lambda:${awsLambdaVersion}"
diff --git a/gradle/nshm.gradle b/gradle/nshm.gradle
index ea8f4b1076a19a9dbc091c17a86727d7ebdaef08..a8ca1f442528a484ea4a6d33aec483a4889d775b 100644
--- a/gradle/nshm.gradle
+++ b/gradle/nshm.gradle
@@ -1,4 +1,4 @@
-apply plugin: "de.undercouch.download"
+apply plugin: "org.ajoberstar.grgit"
 
 buildscript {
   repositories {
@@ -16,32 +16,22 @@ ext {
   envMemory = System.getenv("CI_RUNNER_MEMORY")
   xmx = envMemory ? envMemory : "16g"
 
-  // Download and unzip NSHM
+  // Clone repo
   downloadNshm = {nshm ->
     def repo = nshm.repo
     def tag = nshm.tag
     def year = nshm.year
-
-    def zipName = "${repo}-${tag}.zip";
-    def zipFile = new File(nshmDir, zipName)
-    def nshmFile = file("${nshmDir}/${repo}-${year}")
+    def uri = "https://code.usgs.gov/ghsc/nshmp/nshms/${repo}.git"
+    def nshmFile = new File("${projectDir}/${nshmDir}/${repo}-${year}")
 
     if (nshmFile.exists()) {
       delete nshmFile
     }
 
-    download.run {
-      src "https://code.usgs.gov/ghsc/nshmp/nshms/${repo}/-/archive/${tag}/${zipName}"
-      dest zipFile
-    }
-    copy {
-      from zipTree(zipFile)
-      into nshmDir
-    }
-    file("${nshmDir}/${repo}-${tag}").renameTo(nshmFile)
-    delete {
-      delete zipFile
-    }
+    grgit.clone(
+        dir: nshmFile,
+        uri: uri,
+        refToCheckout: tag)
   }
 
   // Returns a NSHM from nshms.yml array
diff --git a/src/main/java/gov/usgs/earthquake/nshmp/DisaggCalc.java b/src/main/java/gov/usgs/earthquake/nshmp/DisaggCalc.java
index 227d1796a70e4e73523fae99695f41e89a990230..3af0e75d83302c1355680dd127c1c0d637eb2dd8 100644
--- a/src/main/java/gov/usgs/earthquake/nshmp/DisaggCalc.java
+++ b/src/main/java/gov/usgs/earthquake/nshmp/DisaggCalc.java
@@ -130,8 +130,8 @@ public class DisaggCalc {
       fh.setFormatter(new Logging.ConsoleFormatter());
       log.getParent().addHandler(fh);
 
-      log.info(PROGRAM + " version: " + HazardCalc.VERSION);
       Path modelPath = Paths.get(args[0]);
+      log.info(PROGRAM + " version: " + HazardCalc.versions(modelPath));
       HazardModel model = HazardModel.load(modelPath);
 
       log.info("");
@@ -535,7 +535,7 @@ public class DisaggCalc {
 
   private static final String USAGE = new StringBuilder()
       .append(NEWLINE)
-      .append(PROGRAM).append(" version:").append(HazardCalc.VERSION)
+      .append(PROGRAM).append(" version:").append(HazardCalc.versions(null))
       .append(NEWLINE)
       .append("Usage:").append(NEWLINE)
       .append("  ").append(USAGE_COMMAND).append(NEWLINE)
diff --git a/src/main/java/gov/usgs/earthquake/nshmp/HazardCalc.java b/src/main/java/gov/usgs/earthquake/nshmp/HazardCalc.java
index 9c14fc32ec22e4e620fd8d3a9569840d6b5d0b97..2e1b268fe0229085290369c8c101762ea105db5f 100644
--- a/src/main/java/gov/usgs/earthquake/nshmp/HazardCalc.java
+++ b/src/main/java/gov/usgs/earthquake/nshmp/HazardCalc.java
@@ -96,8 +96,8 @@ public class HazardCalc {
       fh.setFormatter(new Logging.ConsoleFormatter());
       log.getParent().addHandler(fh);
 
-      log.info(PROGRAM + " version: " + VERSION);
       Path modelPath = Paths.get(args[0]);
+      log.info(PROGRAM + " version: " + versions(modelPath));
       HazardModel model = HazardModel.load(modelPath);
 
       /* Calculation configuration, possibly user supplied. */
@@ -254,11 +254,9 @@ public class HazardCalc {
     return Optional.of(sb.toString());
   }
 
-  public static final StringBuilder VERSION = versions();
-
-  private static StringBuilder versions() {
+  static StringBuilder versions(Path modelPath) {
     StringBuilder sb = new StringBuilder().append(NEWLINE);
-    for (VersionInfo component : HazVersion.appVersions()) {
+    for (VersionInfo component : HazVersion.appVersions(modelPath)) {
       sb.append("\t").append(component.projectName)
           .append(": ").append(component.version)
           .append(NEWLINE);
@@ -276,7 +274,7 @@ public class HazardCalc {
 
   private static final String USAGE = new StringBuilder()
       .append(NEWLINE)
-      .append(PROGRAM).append(" version:").append(VERSION)
+      .append(PROGRAM).append(" version:").append(versions(null))
       .append(NEWLINE)
       .append("Usage:").append(NEWLINE)
       .append("  ").append(USAGE_COMMAND).append(NEWLINE)
diff --git a/src/main/java/gov/usgs/earthquake/nshmp/RateCalc.java b/src/main/java/gov/usgs/earthquake/nshmp/RateCalc.java
index 6c2f651eab405400afb16d2cfb3489b5b2e03873..2251645d2f22f15fe6bb01cb1ebe8d0a564600fb 100644
--- a/src/main/java/gov/usgs/earthquake/nshmp/RateCalc.java
+++ b/src/main/java/gov/usgs/earthquake/nshmp/RateCalc.java
@@ -96,8 +96,8 @@ public class RateCalc {
       fh.setFormatter(new Logging.ConsoleFormatter());
       log.getParent().addHandler(fh);
 
-      log.info(PROGRAM + " version: " + HazardCalc.VERSION);
       Path modelPath = Paths.get(args[0]);
+      log.info(PROGRAM + " version: " + HazardCalc.versions(modelPath));
       HazardModel model = HazardModel.load(modelPath);
 
       CalcConfig config = model.config();
@@ -222,7 +222,7 @@ public class RateCalc {
 
   private static final String USAGE = new StringBuilder()
       .append(NEWLINE)
-      .append(PROGRAM).append(" version:").append(HazardCalc.VERSION)
+      .append(PROGRAM).append(" version:").append(HazardCalc.versions(null))
       .append(NEWLINE)
       .append("Usage:").append(NEWLINE)
       .append("  ").append(USAGE_COMMAND).append(NEWLINE)
diff --git a/src/main/java/gov/usgs/earthquake/nshmp/www/HazVersion.java b/src/main/java/gov/usgs/earthquake/nshmp/www/HazVersion.java
index c8ad4aecb2533d855fda9393eee13feeecfcf17c..7d96e729882df8c862f5cd25112a6625ed45146d 100644
--- a/src/main/java/gov/usgs/earthquake/nshmp/www/HazVersion.java
+++ b/src/main/java/gov/usgs/earthquake/nshmp/www/HazVersion.java
@@ -1,5 +1,10 @@
 package gov.usgs.earthquake.nshmp.www;
 
+import java.nio.file.Path;
+import java.util.ArrayList;
+
+import org.eclipse.jgit.api.Git;
+
 import com.google.common.io.Resources;
 
 import gov.usgs.earthquake.nshmp.internal.AppVersion;
@@ -7,17 +12,61 @@ import gov.usgs.earthquake.nshmp.internal.LibVersion;
 
 public class HazVersion implements AppVersion {
 
-  public static VersionInfo[] appVersions() {
-    VersionInfo[] versions = {
-        new HazVersion().getVersionInfo(),
-        new LibVersion().getVersionInfo(),
-        new WsUtilsVersion().getVersionInfo(),
-    };
-    return versions;
+  public static VersionInfo[] appVersions(Path modelPath) {
+    var versions = new ArrayList<VersionInfo>();
+    versions.add(new HazVersion().getVersionInfo());
+    versions.add(new LibVersion().getVersionInfo());
+    versions.add(new WsUtilsVersion().getVersionInfo());
+
+    var nshmVersion = getNshmVersion(modelPath);
+
+    if (nshmVersion != null) {
+      versions.add(nshmVersion);
+    }
+
+    return versions.toArray(new VersionInfo[0]);
   }
 
+  /**
+   * Returns the version info from resources file.
+   */
   public VersionInfo getVersionInfo() {
     var resource = Resources.getResource("version/nshmp-haz-version.json");
     return AppVersion.versionInfo(resource);
   }
+
+  /**
+   * Returns the version info of a repository.
+   *
+   * If the model path is not a git repository, returns null.
+   *
+   * @param modelPath The path to the model
+   */
+  private static VersionInfo getNshmVersion(Path modelPath) {
+    try {
+      var git = Git.open(modelPath.toFile());
+      var repo = git.getRepository();
+      var hash = repo.getRefDatabase().findRef("HEAD").getObjectId().name();
+      var url = repo
+          .getConfig()
+          .getString("remote", "origin", "url")
+          .split(".git")[0];
+      var slash = url.split("/");
+      var projectName = slash[slash.length - 1];
+
+      return VersionInfo.builder()
+          .projectName(projectName)
+          .url(repo.getConfig().getString("remote", "origin", "url"))
+          .version(git.describe().call())
+          .branchName(repo.getBranch())
+          .commitDistance(0)
+          .gitHash(hash.substring(0, 10))
+          .gitHashFull(hash)
+          .isCleanTag(git.status().call().isClean())
+          .lastTag("")
+          .build();
+    } catch (Exception e) {
+      return null;
+    }
+  }
 }
diff --git a/src/main/java/gov/usgs/earthquake/nshmp/www/ServletUtil.java b/src/main/java/gov/usgs/earthquake/nshmp/www/ServletUtil.java
index 134c57ef8377ded5a6dfa889679214b93797a197..647df9436153ba35c86be735c54fea1ac59f3510 100644
--- a/src/main/java/gov/usgs/earthquake/nshmp/www/ServletUtil.java
+++ b/src/main/java/gov/usgs/earthquake/nshmp/www/ServletUtil.java
@@ -167,7 +167,7 @@ public class ServletUtil {
     var svcResponse = ResponseBody.error()
         .name(name)
         .url(url)
-        .metadata(new ResponseMetadata(HazVersion.appVersions()))
+        .metadata(new ResponseMetadata(HazVersion.appVersions(model().root())))
         .request(url)
         .response(msg)
         .build();
diff --git a/src/main/java/gov/usgs/earthquake/nshmp/www/hazard/DisaggService.java b/src/main/java/gov/usgs/earthquake/nshmp/www/hazard/DisaggService.java
index 6bc206c396403e7e60eb10b6166a96e7df2dcdd5..ee40597a027167d673b70c0c77f91d49129b4978 100644
--- a/src/main/java/gov/usgs/earthquake/nshmp/www/hazard/DisaggService.java
+++ b/src/main/java/gov/usgs/earthquake/nshmp/www/hazard/DisaggService.java
@@ -82,7 +82,7 @@ public final class DisaggService {
     var response = ResponseBody.usage()
         .name(NAME)
         .url(url)
-        .metadata(new ResponseMetadata(HazVersion.appVersions()))
+        .metadata(new ResponseMetadata(HazVersion.appVersions(ServletUtil.model().root())))
         .request(url)
         .response(usage)
         .build();
@@ -102,7 +102,7 @@ public final class DisaggService {
     var body = ResponseBody.success()
         .name(NAME)
         .url(request.http.getUri().toString())
-        .metadata(new ResponseMetadata(HazVersion.appVersions()))
+        .metadata(new ResponseMetadata(HazVersion.appVersions(ServletUtil.model().root())))
         .request(request)
         .response(response)
         .build();
@@ -122,7 +122,7 @@ public final class DisaggService {
     var body = ResponseBody.success()
         .name(NAME)
         .url(request.http.getUri().toString())
-        .metadata(new ResponseMetadata(HazVersion.appVersions()))
+        .metadata(new ResponseMetadata(HazVersion.appVersions(ServletUtil.model().root())))
         .request(request)
         .response(response)
         .build();
diff --git a/src/main/java/gov/usgs/earthquake/nshmp/www/hazard/HazardService.java b/src/main/java/gov/usgs/earthquake/nshmp/www/hazard/HazardService.java
index 691d27f40ee9189e6062c90ba07e941266951776..d1f40f19947b4e1aaa83872ed4f60f7dc7119770 100644
--- a/src/main/java/gov/usgs/earthquake/nshmp/www/hazard/HazardService.java
+++ b/src/main/java/gov/usgs/earthquake/nshmp/www/hazard/HazardService.java
@@ -65,7 +65,7 @@ public final class HazardService {
     var body = ResponseBody.usage()
         .name(NAME)
         .url(url)
-        .metadata(new ResponseMetadata(HazVersion.appVersions()))
+        .metadata(new ResponseMetadata(HazVersion.appVersions(ServletUtil.model().root())))
         .request(url)
         .response(usage)
         .build();
@@ -85,7 +85,7 @@ public final class HazardService {
     var body = ResponseBody.success()
         .name(NAME)
         .url(request.http.getUri().toString())
-        .metadata(new ResponseMetadata(HazVersion.appVersions()))
+        .metadata(new ResponseMetadata(HazVersion.appVersions(ServletUtil.model().root())))
         .request(request)
         .response(response)
         .build();
diff --git a/src/main/java/gov/usgs/earthquake/nshmp/www/source/FeatureCollectionService.java b/src/main/java/gov/usgs/earthquake/nshmp/www/source/FeatureCollectionService.java
index eb7bf05e76eb6edf929f1ed00cfe26dcada4cf2b..ed865dace6fcb6a3c5cf826117c50c9523f52591 100644
--- a/src/main/java/gov/usgs/earthquake/nshmp/www/source/FeatureCollectionService.java
+++ b/src/main/java/gov/usgs/earthquake/nshmp/www/source/FeatureCollectionService.java
@@ -32,7 +32,7 @@ public class FeatureCollectionService {
       var response = ResponseBody.<RequestData, JsonElement> success()
           .name(name)
           .url(http.getUri().toString())
-          .metadata(new ResponseMetadata(HazVersion.appVersions()))
+          .metadata(new ResponseMetadata(HazVersion.appVersions(ServletUtil.model().root())))
           .request(requestData)
           .response(fc.toJsonTree())
           .build();
diff --git a/src/main/java/gov/usgs/earthquake/nshmp/www/source/FeaturesService.java b/src/main/java/gov/usgs/earthquake/nshmp/www/source/FeaturesService.java
index 843110517c9d3d7110220d3ced6ad14ba88a8a69..a7ce6e5423567449f4550aba80e8bbaf84d12b24 100644
--- a/src/main/java/gov/usgs/earthquake/nshmp/www/source/FeaturesService.java
+++ b/src/main/java/gov/usgs/earthquake/nshmp/www/source/FeaturesService.java
@@ -110,7 +110,7 @@ public class FeaturesService {
       var response = ResponseBody.success()
           .name(NAME)
           .url(url)
-          .metadata(new ResponseMetadata(HazVersion.appVersions()))
+          .metadata(new ResponseMetadata(HazVersion.appVersions(ServletUtil.model().root())))
           .request(requestData)
           .response(features.orElseThrow().toJsonTree())
           .build();
@@ -125,7 +125,7 @@ public class FeaturesService {
     var response = ResponseBody.usage()
         .name(NAME)
         .url(url)
-        .metadata(new ResponseMetadata(HazVersion.appVersions()))
+        .metadata(new ResponseMetadata(HazVersion.appVersions(ServletUtil.model().root())))
         .request(url)
         .response(metadata)
         .build();
diff --git a/src/main/java/gov/usgs/earthquake/nshmp/www/source/LogicTreesService.java b/src/main/java/gov/usgs/earthquake/nshmp/www/source/LogicTreesService.java
index 1a679b0d96e9c296492537a2bd64baf5a2283fe3..3d961d8bd07493b2bb00e95a939e0779720c1c90 100644
--- a/src/main/java/gov/usgs/earthquake/nshmp/www/source/LogicTreesService.java
+++ b/src/main/java/gov/usgs/earthquake/nshmp/www/source/LogicTreesService.java
@@ -32,7 +32,7 @@ public class LogicTreesService {
     var response = ResponseBody.usage()
         .name(NAME)
         .url(url)
-        .metadata(new ResponseMetadata(HazVersion.appVersions()))
+        .metadata(new ResponseMetadata(HazVersion.appVersions(ServletUtil.model().root())))
         .request(url)
         .response(metadata)
         .build();
@@ -46,7 +46,7 @@ public class LogicTreesService {
     var response = ResponseBody.success()
         .name(NAME)
         .url(url)
-        .metadata(new ResponseMetadata(HazVersion.appVersions()))
+        .metadata(new ResponseMetadata(HazVersion.appVersions(ServletUtil.model().root())))
         .request(requestData)
         .response(featureTree)
         .build();
@@ -60,7 +60,7 @@ public class LogicTreesService {
     var response = ResponseBody.success()
         .name(NAME)
         .url(url)
-        .metadata(new ResponseMetadata(HazVersion.appVersions()))
+        .metadata(new ResponseMetadata(HazVersion.appVersions(ServletUtil.model().root())))
         .request(requestData)
         .response(mfdTree)
         .build();
diff --git a/src/main/java/gov/usgs/earthquake/nshmp/www/source/MfdsService.java b/src/main/java/gov/usgs/earthquake/nshmp/www/source/MfdsService.java
index 4062fd449bc564e643924d10a62246d07410fe06..4acad3ac39db553762e4cfc548e9c39368173128 100644
--- a/src/main/java/gov/usgs/earthquake/nshmp/www/source/MfdsService.java
+++ b/src/main/java/gov/usgs/earthquake/nshmp/www/source/MfdsService.java
@@ -37,7 +37,7 @@ public class MfdsService {
     var response = ResponseBody.usage()
         .name(NAME)
         .url(url)
-        .metadata(new ResponseMetadata(HazVersion.appVersions()))
+        .metadata(new ResponseMetadata(HazVersion.appVersions(ServletUtil.model().root())))
         .request(url)
         .response(metadata)
         .build();
@@ -55,7 +55,7 @@ public class MfdsService {
     var response = ResponseBody.success()
         .name(NAME)
         .url(url)
-        .metadata(new ResponseMetadata(HazVersion.appVersions()))
+        .metadata(new ResponseMetadata(HazVersion.appVersions(ServletUtil.model().root())))
         .request(requestData)
         .response(mfd)
         .build();
diff --git a/src/main/java/gov/usgs/earthquake/nshmp/www/source/RateService.java b/src/main/java/gov/usgs/earthquake/nshmp/www/source/RateService.java
index b610a993541d31d71cee1cac50d9311e20b1c95e..0907b014c71b1bb890cc9b372d119b58e8222774 100644
--- a/src/main/java/gov/usgs/earthquake/nshmp/www/source/RateService.java
+++ b/src/main/java/gov/usgs/earthquake/nshmp/www/source/RateService.java
@@ -69,7 +69,7 @@ public final class RateService {
     var body = ResponseBody.success()
         .name(NAME_RATE)
         .url(request.http.getUri().toString())
-        .metadata(new ResponseMetadata(HazVersion.appVersions()))
+        .metadata(new ResponseMetadata(HazVersion.appVersions(ServletUtil.model().root())))
         .request(request)
         .response(response)
         .build();
@@ -88,7 +88,7 @@ public final class RateService {
     var body = ResponseBody.success()
         .name(NAME_PROBABILITY)
         .url(request.http.getUri().toString())
-        .metadata(new ResponseMetadata(HazVersion.appVersions()))
+        .metadata(new ResponseMetadata(HazVersion.appVersions(ServletUtil.model().root())))
         .request(request)
         .response(response)
         .build();
@@ -337,7 +337,7 @@ public final class RateService {
     var body = ResponseBody.usage()
         .name(NAME_RATE)
         .url(url)
-        .metadata(new ResponseMetadata(HazVersion.appVersions()))
+        .metadata(new ResponseMetadata(HazVersion.appVersions(ServletUtil.model().root())))
         .request(url)
         .response(usage)
         .build();
@@ -351,7 +351,7 @@ public final class RateService {
     var body = ResponseBody.usage()
         .name(NAME_PROBABILITY)
         .url(url)
-        .metadata(new ResponseMetadata(HazVersion.appVersions()))
+        .metadata(new ResponseMetadata(HazVersion.appVersions(ServletUtil.model().root())))
         .request(url)
         .response(usage)
         .build();
diff --git a/src/main/java/gov/usgs/earthquake/nshmp/www/source/SourceService.java b/src/main/java/gov/usgs/earthquake/nshmp/www/source/SourceService.java
index 6cedce847c694e6243773f74bde87e91ba7be2f5..6534fa804265c160f9f5378d2eea2dc5ef35912e 100644
--- a/src/main/java/gov/usgs/earthquake/nshmp/www/source/SourceService.java
+++ b/src/main/java/gov/usgs/earthquake/nshmp/www/source/SourceService.java
@@ -39,7 +39,7 @@ public class SourceService {
     var response = ResponseBody.usage()
         .name(NAME)
         .url(url)
-        .metadata(new ResponseMetadata(HazVersion.appVersions()))
+        .metadata(new ResponseMetadata(HazVersion.appVersions(ServletUtil.model().root())))
         .request(url)
         .response(new ResponseData())
         .build();