Herald
0
First released March 7, 2026 · Last updated October 7, 2026
Downloads from this site
45 total
10 latest (v2.2.1)
Sends a Discord webhook notification (or an email) when a player joins the server.
Usage
Last reported in use 9 days ago
8 server starts in the last 30 days
Server starts per day
Versions in use, by share of server starts
2.0.0-SNAPSHOT-8-8-2026
63% · 5 starts
2.1.0
38% · 3 starts
Usage reported by trace — how it works. CI and test servers are excluded.
Verified before release
Version 2.2.1 was started on real servers running Minecraft 1.19.4, 1.21.11, 26.2 and 26.3 before it was published. The jar you download is the exact one that passed. How releases work
Versions
All releases on GitHubAutomated build of main at 48a06ba030568d232a45912a96c7e28225e24ad8.
This is not a release. It is unreleased, unreviewed code that has not been through any release check, and a broken build can stop a server from starting. Do not run it on a server you care about without a backup.
Install it with Dan's Plugin Manager:
/dpm get herald --experimentalReturn to published releases with /dpm get herald --stable.
2.2.1
This is a maintenance release for servers running v2.2.0. Messaging, commands, permissions, configuration and stored data all work as before, and usage reporting behaves exactly as it did, including the server-wide opt-out and the existing server-id. The only thing an operator will notice is a new link for the usage-reporting details.
Changes
Usage reporting
- The usage-reporting details link now points to https://danielstephenson.dev/usage-reporting. You will see it in the startup console message, in the default
config.ymlcomments and in the comment header of a newly createdplugins/trace/config.yml. Existing config files are not rewritten. - The bundled usage-reporting client is updated to 0.6.1. Herald's reporting behaviour is unchanged: the same opt-outs apply, and a disabled client still reads and writes nothing.
Version
v2.2.0 → 2.2.1 — PATCH. Mechanical floor from comparing the two jars: PATCH.
Judgment: Herald itself behaves the same as in v2.2.0. The bundled usage-reporting client moves from 0.5.0 to 0.6.1. Its new installIdFile/installIdFromFile API is meant for non-Spigot programs, and Herald never calls it, so the install ID still comes from server-id in plugins/trace/config.yml. The only other changes are the usage-reporting details link in the console message, in config.yml comments and in the comment header of a newly created plugins/trace/config.yml, so I kept the patch floor. No merged pull requests were recorded, so the notes cite no PR numbers.
- no interface or storage difference observed between the jars
<details><summary>Java API changes (informational — nothing depends on this plugin)</summary>
- com.dansplugins.herald.trace.TraceClient: added public static java.lang.String installIdFromFile(java.io.File);
- com.dansplugins.herald.trace.TraceClient$Builder: added public com.dansplugins.herald.trace.TraceClient$Builder installIdFile(java.io.File);
</details>
Verification
Verified on a real Spigot server before publication; this release carries the exact jar that was verified.
- boot gate run: booted twice on a fresh Spigot server running Minecraft 1.19.4 (11 assertions passed).
- boot gate run: booted twice on a fresh Spigot server running Minecraft 1.21.11 (11 assertions passed).
- boot gate run: booted twice on a fresh Spigot server running Minecraft 26.2 (11 assertions passed).
- boot gate run: booted twice on a fresh Spigot server running Minecraft 26.3 (11 assertions passed).
Install with Dan's Plugin Manager: /dpm get <plugin>. How stable releases are made: Release channels.
drafted by Claude on behalf of Daniel Stephenson
2.2.0
For a server running v2.1.0, this release adds support for Minecraft 26.3 and changes what usage reporting sends. While reporting is on, Herald now generates a random server ID on first start. It saves the ID as a server-id: line in plugins/trace/config.yml and sends it with every usage event, so plugin usage can be counted per server rather than per event. The ID is a random UUID: it identifies no player, account or IP address, and every plugin on the server that reports to trace shares the same one. If reporting is turned off (in Herald's config.yml, in plugins/trace/config.yml, or with DO_NOT_TRACK=1 / TRACE_USAGE_REPORTING=off), no ID is generated or written. Commands, permissions and Herald's own data are unchanged.
Changes
Compatibility
- Added support for Minecraft 26.3 (#73).
Usage reporting
- Each usage event now includes a random server ID as the
installtag. Ifplugins/trace/config.ymlhas noserver-id:line, one is added to the end of the file under an explanatory comment, and the rest of the file is left exactly as it was. Deleting the line makes a new ID on the next start. If the file can't be read or written, the ID is used for the current run only and isn't saved (#71). - A
plugins/trace/config.ymlpath that the file system can't handle no longer risks an error at startup. It is now logged and reporting carries on (#71). - The startup console message and the comment in
config.ymlnow mention the random server ID (#72).
Version
v2.1.0 → 2.2.0 — MINOR. Mechanical floor from comparing the two jars: PATCH.
Judgment: Every usage-reporting event now carries a new install tag with a random server ID (#71). On first start, an enabled plugin also appends a new server-id: line to plugins/trace/config.yml. The mechanical check only saw the two added API methods, not this new data written to disk and sent over the network, so the floor is raised to minor. Nothing existing breaks: no config key changes meaning, opt-outs still work as before, and a disabled client never creates or writes the ID, so major is not justified.
- no interface or storage difference observed between the jars
<details><summary>Java API changes (informational — nothing depends on this plugin)</summary>
- com.dansplugins.herald.trace.TraceClient: added public java.lang.String installId();
- com.dansplugins.herald.trace.TraceClient$Builder: added public com.dansplugins.herald.trace.TraceClient$Builder installId(java.lang.String);
</details>
Verification
Verified on a real Spigot server before publication; this release carries the exact jar that was verified.
- boot gate run: booted twice on a fresh Spigot server running Minecraft 1.19.4 (11 assertions passed).
- boot gate run: booted twice on a fresh Spigot server running Minecraft 1.21.11 (11 assertions passed).
- boot gate run: booted twice on a fresh Spigot server running Minecraft 26.2 (11 assertions passed).
- boot gate run: booted twice on a fresh Spigot server running Minecraft 26.3 (11 assertions passed).
Install with Dan's Plugin Manager: /dpm get <plugin>. How stable releases are made: Release channels.
drafted by Claude on behalf of Daniel Stephenson
2.1.0
For a server running v2.0.0 this is a drop-in upgrade, and no configuration changes are needed. Herald now runs on Java 17 as well as newer versions, and declares support for Minecraft 1.19.4 and later. Usage reporting still sends the same small events with the same opt-outs. The difference is that every event now carries the plugin version, and you can add your own server-wide tags, such as marking a test server so its events are left out of real-installation figures.
Changes
Usage reporting
- Every usage-reporting event is now tagged with the Herald version, not only the startup event (#65).
plugins/trace/config.ymlnow accepts an optionaltags:block. Its tags are added to every event that plugins using trace report from this server, and a plugin's own tag of the same name wins. Invalid or unreadable entries are skipped without affecting reporting, andenabled: falsestill turns reporting off. Newly created copies of the file include a commented-outci: "true"example. An existing file is never rewritten (#64).
Compatibility
- Herald is now compiled for Java 17 instead of Java 21, so it loads on servers running Java 17 through 20. Supported Minecraft versions are declared as 1.19.4 through 26.2 (#63).
Version
v2.0.0 → 2.1.0 — MINOR. Mechanical floor from comparing the two jars: PATCH.
Judgment: Usage reporting now does more than before. Every event, not just startup, now carries the plugin version tag. The shared plugins/trace/config.yml file also accepts a new optional tags: block that is added to every report, and newly created copies of that file include a commented-out example. That is new behaviour and new data sent, which the mechanical check can't see. Nothing breaks for existing servers: the TraceClient builder signature change is internal to the plugin's own copy of trace-client, existing config files are left as they are, and compiling for Java 17 instead of 21 only widens the set of servers it runs on.
- no interface or storage difference observed between the jars
<details><summary>Java API changes (informational — nothing depends on this plugin)</summary>
- com.dansplugins.herald.trace.TraceClient: removed/changed public static com.dansplugins.herald.trace.TraceClient$Builder builder(java.lang.String, java.lang.String);
- com.dansplugins.herald.trace.TraceClient: added public static com.dansplugins.herald.trace.TraceClient$Builder builder(java.lang.String, java.lang.String, java.lang.String);
- com.dansplugins.herald.trace.TraceClient: added public static final java.lang.String VERSION;
</details>
Verification
Verified on a real Spigot server before publication; this release carries the exact jar that was verified.
- boot gate run: booted twice on a fresh Spigot server running Minecraft 1.19.4 (11 assertions passed).
- boot gate run: booted twice on a fresh Spigot server running Minecraft 1.21.11 (11 assertions passed).
- boot gate run: booted twice on a fresh Spigot server running Minecraft 26.2 (11 assertions passed).
Install with Dan's Plugin Manager: /dpm get <plugin>. How stable releases are made: Release channels.
drafted by Claude on behalf of Daniel Stephenson
2.0.0
Herald 2.0.0 hardens email delivery, checks the whole configuration at startup instead of failing on the first player join, adds usage reporting, and lets you customise the email subject and body. A server upgraded from 1.0.0 keeps its config.yml and its Discord notifications as they are. Email keeps working as long as your SMTP relay supports STARTTLS (when smtp.use-tls is true) and presents a certificate that matches smtp.server; if either is not the case, sends that used to succeed will start failing after the upgrade and need a one-line config change (see upgrade notes). On first start Herald also adds a usage-reporting block to config.yml, creates plugins/trace/config.yml, and sends one small event (plugin name and version) to the author's trace server unless you turn that off.
Changes
smtp.use-tls: truenow requires STARTTLS: a relay that cannot upgrade the connection fails the send instead of silently falling back to plaintext. The SMTP session now has connect, read and write timeouts, so an unreachable relay no longer parks the sending task forever (#44)- New
smtp.implicit-tlsfor SMTPS relays (conventionally port 465). It is an alternative tosmtp.use-tls, not an addition; setting both is reported at startup and email is skipped, and a port/mode mismatch on 465 or 587 is warned about (#47) - The relay's certificate is now checked against
smtp.server. Newsmtp.verify-server-identity(defaulttrue) opts out, with a startup warning explaining what that costs (#49) - New
email.enabledtoggle (defaulttrue) to switch email off without clearing the SMTP settings (#33) - New
email.subjectandemail.bodytemplates supporting{player},{server}and{time}; the default body now names the server instead of "the server" (#30, #15) - Startup warns when
smtp.usernameis set but no encryption mode is on, since credentials would go over the wire in the clear (#29, #44)
Discord
- A webhook message that Discord rate-limits is waited out (up to 10 s, as Discord's
Retry-Afterasks) and retried once, with a warning in the log (#40) discord.webhook-urlis validated at startup (must be an absolute http/https URL) without the token being echoed into the log; blankdiscord.join-messagesentries and templates that could exceed Discord's 2000-character limit once filled are reported at startup by position (#29, #33, #37)- Failed webhook calls include Discord's error body (invalid token, unknown webhook, etc.) in the logged failure (#21)
Startup checks and logging
- Every configuration problem is reported at startup, naming the config key, rather than surfacing one per join; email now needs
email.senderset and every address parseable before it is enabled, and warns when nothing is configured at all (#21, #29) - Notifier failures are logged with their cause and stack trace, and channels are named "Discord" and "email" in the log instead of by class name (#21, #30)
server-nameis read once at enable rather than on every join, is trimmed, and a whitespace-only value falls back to "Minecraft" (#15, #37)
Usage reporting
- On enable, Herald sends a startup event (plugin name and version, nothing about players or the server) to
https://trace.danielstephenson.dev, off the main thread and dropped silently if unreachable. Turn it off withusage-reporting.enabled: falsein Herald's config.yml, for every trace-reporting plugin withenabled: falseinplugins/trace/config.yml, or for the whole process withTRACE_USAGE_REPORTING=offorDO_NOT_TRACK=1. The console states whether reporting is on at every start (#50, #53)
Distribution
- A rolling prerelease of
mainis published as thedevrelease and can be installed with/dpm get herald --experimental; the release workflow no longer attaches a second, unverified jar to automated releases (#43, #46, #52)
Upgrade notes
- If your relay does not support STARTTLS and you relied on 1.0.0 falling back to plaintext, email will now fail. Set
smtp.use-tls: false(Herald will warn if credentials then go unencrypted) or move to a relay that supports STARTTLS. - If your relay's certificate does not name the host in
smtp.server(reached by IP address, or a self-signed certificate), email will now fail with a certificate error. Either setsmtp.serverto the name on the certificate or setsmtp.verify-server-identity: false. - If you use an SMTPS relay on port 465, set
smtp.implicit-tls: trueandsmtp.use-tls: false; the old configuration on that port fails with a protocol error. - If you do not want usage reporting, set
usage-reporting.enabled: falseinplugins/Herald/config.ymlafter the first start (Herald writes the block for you), or setenabled: falseinplugins/trace/config.ymlto cover every plugin that reports to trace. - If you have your own class implementing
com.dansplugins.herald.Notifier, it must now implementgetDisplayName().
Version
1.0.0 → 2.0.0 — MAJOR. Mechanical floor from comparing the two jars: MINOR.
Judgment: Two email changes alter what an unchanged 1.0.0 config.yml does, which the jar comparison cannot see: smtp.use-tls: true now requires STARTTLS instead of attempting it and falling back to plaintext (#44), and the SMTP server's certificate is now checked against smtp.server by default (#49). A server whose relay lacks STARTTLS or presents a certificate for another name sent mail under 1.0.0 and will fail every send after upgrading, with no key edited. The Notifier interface also gained an abstract method, breaking any outside implementor, and usage reporting is on by default and writes new files, which is minor on its own but worth calling out.
- minor: default config key added: email.body
- minor: default config key added: email.enabled
- minor: default config key added: email.subject
- minor: default config key added: smtp.implicit-tls
- minor: default config key added: smtp.verify-server-identity
- minor: default config key added: usage-reporting.enabled
- minor: default config key added: usage-reporting.endpoint
- minor: default config key added: usage-reporting.key
- info: public class added: com.dansplugins.herald.trace.TraceClient
- info: public class added: com.dansplugins.herald.trace.TraceClient$Builder
- info: com.dansplugins.herald.DiscordNotifier: added public com.dansplugins.herald.DiscordNotifier(java.lang.String, java.util.List<java.lang.String>, java.util.logging.Logger);
- info: com.dansplugins.herald.DiscordNotifier: added public java.lang.String getDisplayName();
- info: com.dansplugins.herald.DiscordNotifier: added public static java.util.List<java.lang.String> validateConfiguration(java.lang.String);
- info: com.dansplugins.herald.DiscordNotifier: added public static java.util.List<java.lang.String> validateConfiguration(java.lang.String, java.util.List<java.lang.String>);
- info: com.dansplugins.herald.DiscordNotifier: added public static java.util.List<java.lang.String> validateConfiguration(java.lang.String, java.util.List<java.lang.String>, java.lang.String);
- info: com.dansplugins.herald.EmailNotifier: added public com.dansplugins.herald.EmailNotifier(java.lang.String, int, java.lang.String, java.lang.String, java.lang.String, boolean, boolean, boolean, java.util.List<java.lang.String>, java.lang.String, java.lang.String);
- info: com.dansplugins.herald.EmailNotifier: added public com.dansplugins.herald.EmailNotifier(java.lang.String, int, java.lang.String, java.lang.String, java.lang.String, boolean, boolean, java.util.List<java.lang.String>, java.lang.String, java.lang.String);
- info: com.dansplugins.herald.EmailNotifier: added public com.dansplugins.herald.EmailNotifier(java.lang.String, int, java.lang.String, java.lang.String, java.lang.String, boolean, java.util.List<java.lang.String>, java.lang.String, java.lang.String);
- info: com.dansplugins.herald.EmailNotifier: added public java.lang.String getDisplayName();
- info: com.dansplugins.herald.EmailNotifier: added public static java.lang.String describeCredentialExposure(java.lang.String, boolean, boolean);
- info: com.dansplugins.herald.EmailNotifier: added public static java.lang.String describePortTlsMismatch(int, boolean);
- info: com.dansplugins.herald.EmailNotifier: added public static java.lang.String describeTlsModeConflict(boolean, boolean);
- info: com.dansplugins.herald.EmailNotifier: added public static java.lang.String describeUnverifiedServerIdentity(boolean, boolean, boolean);
- info: com.dansplugins.herald.EmailNotifier: added public static java.util.List<java.lang.String> validateConfiguration(java.util.List<java.lang.String>, java.lang.String, int, java.lang.String);
- info: com.dansplugins.herald.Notifier: added public abstract java.lang.String getDisplayName();
Verification
Booted twice on a real Spigot server before publication — boot gate run (8 assertions passed). This release carries the exact jar that was verified.
Install with Dan's Plugin Manager: /dpm get <plugin>. How stable releases are made: Release channels.
drafted by Claude on behalf of Daniel Stephenson
Snapshot release marking Herald's move to an AI-first development approach.
Day-to-day feature work, grooming, review and maintenance now run through AI agents working directly against this repository, with the maintainers setting direction and approving what lands. The version bump marks that change in how the project is built — it is not a compatibility break. Behaviour, configuration and stored data are unchanged, and existing installations can upgrade in place.
This is a dated snapshot, not a finished release. It follows the precedent set by Medieval
Factions' 6.0.0-SNAPSHOT-7-25-2026: the AI-first line has not yet been verified in live operation,
and the snapshot designation stays until it has.
Version changes
build.gradle:1.0.0→2.0.0-SNAPSHOT-8-8-2026
Opened as https://github.com/Dans-Plugins/Herald/pull/38.
Drafted by Claude on behalf of Daniel Stephenson.
What's Changed
- Align repository with DPC conventions by @Copilot in https://github.com/Dans-Plugins/Herald/pull/11
- Add GitHub Action to build and attach JAR to release by @Copilot in https://github.com/Dans-Plugins/Herald/pull/12
Full Changelog: https://github.com/Dans-Plugins/Herald/compare/0.1.0...1.0.0
What's Changed
- License/gpl3 by @dmccoystephenson in https://github.com/Dans-Plugins/Herald/pull/2
- Add GitHub Actions workflow to build and deploy plugin to OMCSI by @Copilot in https://github.com/Dans-Plugins/Herald/pull/7
- Sync branch w/ dev by @dmccoystephenson in https://github.com/Dans-Plugins/Herald/pull/9
- Make Discord the flagship notification method for player joins by @Copilot in https://github.com/Dans-Plugins/Herald/pull/5
- Make Discord join messages medieval-themed, randomized, and configurable with custom server name by @Copilot in https://github.com/Dans-Plugins/Herald/pull/10
- Dev by @dmccoystephenson in https://github.com/Dans-Plugins/Herald/pull/1
New Contributors
- @Copilot made their first contribution in https://github.com/Dans-Plugins/Herald/pull/7
Full Changelog: https://github.com/Dans-Plugins/Herald/commits/0.1.0
Related plugins
Something wrong, or something missing?
Bugs go to the plugin's issue tracker, where they can actually be fixed and tracked. Ideas for new behaviour go to the Dev Portal, where the community can upvote them.