Understanding the Project Structure of jauderho/nts-servers: A Complete Guide

The jauderho/nts-servers repository follows a flat, data-driven architecture centered on a single YAML source file that feeds Python and Bash scripts to generate NTP client configurations for Chrony and ntpd-rs.

The jauderho/nts-servers project maintains a curated list of Network Time Security (NTS) capable NTP servers. Its project structure prioritizes simplicity and automation, using a single source of truth to drive multiple output formats. This guide examines the repository layout, key components, and the conversion workflow that keeps the server list synchronized across different NTP client configurations.

Repository Overview and Design Philosophy

The nts-servers repository is deliberately flat, containing no nested source trees beyond the scripts/ and .github/ directories. This minimalist approach makes the project easy to audit and update. At its core, the architecture separates data from presentation: the canonical server definitions live in nts-sources.yml, while rendering logic resides in standalone utilities that convert YAML into client-specific formats.

Directory Layout and Key Files

Root Level Configuration and Documentation

The repository root contains the primary data source, generated artifacts, and project metadata:

  • nts-sources.yml — The canonical YAML file describing each NTS server, including hostname, stratum, location, owner, notes, and a vm boolean flag indicating virtualized infrastructure.
  • README.md — Human-readable documentation containing the rendered server table and usage instructions.
  • AGENTS.md — Instructions for automated agents that perform updates.
  • LICENSE — SPDX-style licensing information.
  • chrony.conf — Generated Chrony-compatible configuration file.
  • ntp.toml — Generated ntpd-rs compatible TOML configuration.

The Scripts Directory

The scripts/ folder houses the automation utilities that process the YAML data:

Continuous Integration

The .github/workflows/ directory contains GitHub Actions pipelines that enforce code style, run security scans (Semgrep, OpenSSF Scorecard), and execute automated verification checks against the server list.

The Data-to-Configuration Workflow

The project structure supports a clear conversion pipeline that maintains consistency across all client formats:

  1. Data Definition — Contributors edit nts-sources.yml to add or modify server entries, specifying hostname, stratum, location, owner, and optional notes.

  2. Asset Generation — Running ./scripts/ntpServerConverter.py nts-sources.yml updates the "The List" section in README.md, writes a fresh chrony.conf, and generates ntp.toml. The script parses the YAML, extracts plain hostnames (stripping markdown link syntax), and groups entries by location for readability.

  3. Verification — Before submitting changes, contributors run ./scripts/ntsCheck.sh <hostname> to confirm NTS reachability. The CI pipeline uses python3 ./scripts/verifyNTSServers.py nts-sources.yml to bulk-test every entry automatically.

Key Technical Components

nts-sources.yml Schema

Each entry in the canonical data source contains:

  • hostname — Server address, optionally wrapped in markdown link syntax
  • stratum — NTP stratum level (1, 2, etc.)
  • location — Geographic region for grouping
  • owner — Organization operating the server
  • notes — Optional operational details
  • vm — Boolean flag indicating virtualized infrastructure (displayed separately in outputs)

ntpServerConverter.py Functionality

The core script handles three distinct output formats:

  • Markdown — Updates the README table with grouped server listings
  • Chrony format — Generates chrony.conf with server directives including iburst nts flags
  • TOML format — Produces ntp.toml for ntpd-rs compatibility

Summary

  • The jauderho/nts-servers repository uses a flat, data-driven structure with nts-sources.yml as the single source of truth.
  • The scripts/ directory contains Python and Bash utilities that convert YAML into client-specific configurations for Chrony and ntpd-rs.
  • Generated artifacts (chrony.conf, ntp.toml, and the README table) are automatically produced by scripts/ntpServerConverter.py.
  • Verification tools (ntsCheck.sh and verifyNTSServers.py) ensure NTS reachability before changes are merged.
  • CI/CD pipelines in .github/workflows/ automate security scanning and bulk verification.

Frequently Asked Questions

What is the main data source in jauderho/nts-servers?

The canonical data source is nts-sources.yml located in the repository root. This YAML file contains structured entries for every NTS-capable server, including hostname, stratum, location, owner, notes, and a virtual-machine flag. All other files in the repository are derived from this single source of truth.

How are the configuration files generated?

The scripts/ntpServerConverter.py utility reads nts-sources.yml and outputs three formats simultaneously: it updates the Markdown table in README.md, writes a chrony.conf file for Chrony users, and generates an ntp.toml file for ntpd-rs compatibility. Contributors run this script after editing the YAML source to regenerate all derived assets.

What scripts are available for verifying NTS servers?

The repository provides two primary verification tools. scripts/ntsCheck.sh is a Bash wrapper that performs a single-shot NTS probe against a specific hostname using chronyd -Q. For bulk validation, scripts/verifyNTSServers.py iterates through every entry in nts-sources.yml and reports reachability failures, which is used by the CI pipeline to ensure list integrity.

Where are the CI workflows located?

All continuous integration configurations reside in .github/workflows/ at the repository root. These GitHub Actions pipelines handle automated security scanning with Semgrep, OpenSSF Scorecard analysis, and execution of the bulk verification scripts to ensure that every pull request maintains the quality and accuracy of the NTS server list.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →