Compare Minecraft client and server mod directories and detect missing mods and discrepancies between versions and disabled state.
The compare_mods.py tool reads internal mod metadata (Forge, NeoForge, Fabric, Quilt) directly from JAR files and
produces a clear, colorized comparison table. Can alternatively return structured JSON, to be used for automation.
- ✅ Supports Forge, NeoForge, Fabric, and Quilt
- ✅ Compare local and remote (SSH) mod directories
- ✅ Detect:
- Version mismatches
- Missing mods (client-only / server-only)
- Disabled-state mismatches (
.jar.disabled)
- ✅ Clean colorized terminal output with summary
- ✅
--jsonmode for scripting and CI - ✅ Meaningful exit codes
Most Minecraft users will not need this tool:
- If you only play locally (not multiplayer)
- If you only play vanilla Minecraft (no mods)
- If you play multiplayer but don't manage your own server
...then this tool will not be useful to you.
But for those Minecraft enthusiasts who manage their own servers, AND:
- maintain their own custom collection of mods
- use a pre-built modpack, but have customized it by adding additional or removing/disabling included mods
...then this tool makes it easier to ensure any changes to your modpack match client-side and server-side. This tool is especially useful for pre-built modpack upgrades, where included mods get upgraded automatically, but your customizations do not.
Mods like Better Compatability Checker try to help explain modpack discrepancies, so the situation isn't as bad as it used to be without it. But still, it can be a pain to make sure you know exactly which mods are missing or mismatched, and that's why this tool was created.
Looking at the screenshots above, I can tell you that the differences between my local client and my server are much more vast than what's being portrayed.
- Python 3.11+
- Python ≥ 3.11 available on remote host (if accessing via SSH)
Dependencies:
This tool has been tested on:
- macOS Tahoe (26.4)
- Ubuntu Noble (24.04) and Resolute (26.04)
- Debian Bookworm (12) and Trixie (13)
I understand that a significant number of Minecraft users who would benefit from this tool might be using Windows. I don't use Windows, however, so I didn't try very hard to support it.
Theoretically, it should work on any platform that supports Python 3.11+, which would include Windows. Comparing a remote source via SSH, for example, won't work though (but you could mount the remote directory as a shared folder so that it could be treated like a local path). The work-around for this might be to run this tool in a WSL environment, which should work just fine (I assume).
Install dependencies:
- macOS (via Homebrew):
brew install python-packaging
- Debian/Ubuntu/others (via apt):
sudo apt install python3-packaging
Note
Alternatively, you could create and activate a virtual environment, then install dependencies with pip, but that's
beyond the scope of this guide -- if you know that's what you want to do, then I assume you already know how to do it.
Download:
curl -O https://raw.githubusercontent.com/MaffooClock/minecraft-mod-checker/refs/heads/main/compare_mods.py && chmod +x compare_mods.pyRun:
./compare_mods.py <client_mods_path> <server_mods_path> [<flags>, ...]Install pipx:
- macOS (via Homebrew):
brew install pipx
- Debian/Ubuntu/others (via apt):
sudo apt install pipx
Download:
git clone https://github.com/MaffooClock/minecraft-mod-checker.gitInstall:
cd minecraft-mod-checker
pipx install .Run:
compare-mods <client_mods_path> <server_mods_path> [<flags>, ...]The only required arguments are the paths to the client and server mod directories. Without any additional flags, the output will be a single table listing only mods that differ between the client and server (matching mods will be omitted).
For comparing the Minecraft client on your local machine with a remote server:
compare-mods ~/minecraft/mods user@server:/opt/minecraft/modsNote
Currently, the use of SSH assumes the following:
- you're using private key authentication
- your public key is already installed on the remote server.
- SSH on the remote server is listening on port 22
- no extra SSH options are required to connect
Future versions of this tool will add support for specifying SSH options (such as port, etc.).
The examples below assume you installed this as a CLI command (see Installation: Option 2) on *nix. If you're executing the script directly or using Windows, be sure to adjust the commands accordingly.
If both your Minecraft server and client are installed on the same machine, or if the remote server directory is mounted locally (such as via Samba or NFS or similar):
compare-mods ~/minecraft/client/mods /mnt/minecraft-server/modsMods that are present on both sides and have matching versions will be omitted. But if you want to include these:
compare-mods <client_mods_path> <server_mods_path> --show-okBy default, version strings are sanitized to make them easier to read (by removing noise, such as mc1.21.1, neoforge).
This flag disables that behavior:
compare-mods <client_mods_path> <server_mods_path> --no-sanitizeSuppress results for missing mods or mods with mismatched disabled state:
compare-mods <client_mods_path> <server_mods_path> --only-version-diffSuppress results for mods with mismatched version or disabled state:
compare-mods <client_mods_path> <server_mods_path> --only-missingYou can specify multiple filters. Separate tables will be rendered for each status set:
compare-mods <client_mods_path> <server_mods_path> --show-ok --only-version-diff --only-missingBy default, this tool will display live progress indicators before rendering the results. You can suppress this
behavior, useful for scripting (e.g. piping into grep):
compare-mods <client_mods_path> <server_mods_path> --quietOutput a machine-readable version of the results, without progress indicators or colorized output (suitable for piping
into jq or other tools):
compare-mods <client_mods_path> <server_mods_path> --jsonImportant
Filtering flags (--show-ok, --only-*) are ignored when using --json, and version strings are not sanitized.
This tool offers these basic sanity checks:
- Paths must exist and be directories.
- Directories must contain at least one valid mod (
.jar) file. - If no valid mod metadata is found, the script exits with an error.
- Colorized output
- Emoji status indicators
- Summary section
| Status | Meaning |
|---|---|
| ✅ OK | Mod is present on both sides with matching versions |
| 🔄 VERSION_MISMATCH | Versions differ |
| 🚫 DISABLED_MISMATCH | Disabled state differs (e.g. disabled on client but not server, or vice-versa) |
| 💻 CLIENT_ONLY | Present only on client |
| 🖥️ SERVER_ONLY | Present only on server |
Produces structured output suitable for automation or further processing:
{
"rows": [
{
"mod": "minecolonies",
"client_version": "1.1.1307-1.21.1-snapshot",
"server_version": "1.1.1300-1.21.1-snapshot",
"status": [
"VERSION_MISMATCH"
]
}
],
"summary": {
"total": 460,
"ok": 343,
"client_only": 34,
"server_only": 3,
"disabled_mismatch": 0,
"version_mismatch": 80
}
}In this mode, the progress indicators and messages are suppressed, making it safe to pipe the output into other tools:
compare-mods <client_mods_path> <server_mods_path> --json | jqYou can also save the results to a file for later analysis:
compare-mods <client_mods_path> <server_mods_path> --json > mods_comparison.jsonThis utility can be used in automation and returns the following exit codes:
| Code | Meaning |
|---|---|
| 0 | All mods match |
| 1 | Missing mods detected |
| 2 | Version mismatches detected or usage error |
Contributions are welcome in the form of bug reports and pull requests.
Bug fixes and enhancements to existing functionality are certainly welcome, but requests for new features may not necessarily be accepted, as this tool is intended to be simple and perform only one task: comparing two lists of mods. This tool is not a modpack manager, so there is currently no intention to offer the ability to add or remove mods, synchronize them, automatically download them, or even offer links to details or downloads.
This project is offered under the MIT License. See LICENSE file for details.


