Coder lets you build custom commands and logic without heavy scripting overhead. By leveraging native Java, Python, and Lua execution alongside a custom-built syntax parser, Coder gives you full, uncompromised control over your server environment.
🚀 What's New in v2.3.3
- New
/mc-console/ endpoint — Try combining a console connected to your Minecraft server alongside the GWI Editor!
- Secure SHA-256 Password generated via
/coder gen-pass.
🛠 Key Features
- Native Multi-Language Execution — Run Java, Python, and Lua scripts directly on your server.
- Zero Bloat & Lightweight — Highly optimized with no heavy or unnecessary dependencies.
- In-Memory Execution — Load scripts into server memory to keep active listeners and background processes running.
- Real Java Syntax Support — Run authentic Java syntax, call custom methods, and tap directly into Bukkit/Spigot imports.
- Active User Execution Control (UEC) — A security layer that intercepts unauthorized scripts and blocks malicious terminal access.
- VersionManager — Keep your system up to date with one-tap auto-updates.
- Graphical Web Interface (GWI) — Edit and manage scripts in real-time with a VS Code-like web editor.
- Virtual Console Interface (VCI) — Securely run commands via
https://coder-gwieditor.firesmasher.workers.dev/mc-console?=YOUR_TOKEN_HERE.
- Dual Backup Systems — Automated scheduled backups paired with instant manual snapshots.
- Clean Cache Directory — Compiled
.class files cleanly separated: Runtime: Coder/JavaClass/Runtime/, Loaded: Coder/JavaClass/Loaded/.
🛡 Security
GWI Editor
Session connections leverage SHA-256 tokens which are mathematically impossible to brute-force or guess. Every session token automatically expires after 30 minutes of inactivity.
Virtual Console Interface
The custom Minecraft console panel blocks /op commands and is secured by SHA-256 server password tokens. To disable this feature, go to /plugins/Coder/.gwi/secure/serverPassword.env and remove the value of serverPassword=.
📥 Installation
- Drop
Coder.jar into your server's /plugins/ folder.
- Start (or restart) the server to generate the directory structure.
- Place your scripts in the designated workspace.
Workspace Directories
| Purpose | Server Path |
| Scripts Directory | /plugins/Coder/scripts/ |
| Execution Logs | /plugins/Coder/Logs/ |
| GWI Directory | /plugins/Coder/.gwi/ |
⚙️ Command Reference
Script Management
| Command | Description |
/coder run <filename> | Executes a specified script. |
/coder load <filename> | Loads and compiles a script into server memory. |
/coder unload <filename> | Unloads an active script from server memory. |
/coder reload <filename> | Reloads a specific script's configuration. |
Security & UEC
| Command | Description |
/coder confirm | Manually permits a script flagged by the UEC. |
/coder cancel | Blocks and cancels a script caught by the UEC. |
GWI Web Editor
| Command | Description |
/coder editor start | Generates a secure SHA-256 link to the GWI Web Editor. |
/coder editor trust <username> | Grants access to a pending connection request. |
/coder editor do-not-trust <username> | Denies access to a connection request. |
/coder editor stop | Terminates the active GWI Web Editor session immediately. |
Virtual Console Interface
| Command | Description |
/coder gen-pass | Generates a unique SHA-256 server password for /mc-console/. |
System & Maintenance
| Command | Description |
/coder backup | Triggers an immediate manual backup of your script directory. |
/coder auto-backup-start | Starts the automated background backup scheduler. |
/coder auto-backup-stop | Halts the background backup scheduler. |
/coder reload-config | Hot-reloads the main config.yml file. |
/coder update | Checks for updates and retrieves a download link. |
/coder update-jar | Automatically downloads and replaces the plugin JAR file. |
/coder enable-activity-logging | Enables activity logging. |
/coder disable-activity-logging | Disables activity logging. |
📋 Console Session Example
A typical workflow demonstrating how to generate a server password:
coder gen-pass
[12:38:39 INFO]: [Coder] Server password regenerated and saved to .gwi/secure/serverPassword.env
[12:38:40 INFO]: [Coder] Server password generated!
[12:38:40 INFO]: Copy this hash into the MC Console auth form:
[12:38:40 INFO]: 857a675a14c2e8b19eeb838d28d16a91128262417c23e4fdb08e078ffdef211f
[12:38:40 INFO]: Saved to: plugins/Coder/.gwi/secure/serverPassword.env
⚠️ Security Warning
Important: Because Coder allows native Python, Java, and Lua execution, only allow trusted administrators to manage files in the /plugins/Coder/scripts/ directory. Scripts running through Coder have full, native access to system commands and the host environment.
📖 Resources
The Coder API lets you hook into the Coder plugin from your own Minecraft plugin. You can add it via Modrinth's Maven repository or reference the JAR locally.
Import the API in your code using: import me.coder.api.CoderAPI;
For future versions 2.4.x+, use: import dev.codestuff.coder.api.CoderAPI;
📦 Via Modrinth Repository
The recommended way to add Coder as a dependency — no local JAR needed.
Maven pom.xml — Java 21
<repositories>
<repository>
<id>Modrinth</id>
<name>Modrinth</name>
<url>https://api.modrinth.com/maven</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>maven.modrinth</groupId>
<artifactId>7QMwdTys</artifactId>
<version>2OmHB5Qv</version> <!-- Version 2.4.1 Java 21 -->
<scope>provided</scope>
</dependency>
</dependencies>
Maven pom.xml — Java 25
<repositories>
<repository>
<id>Modrinth</id>
<name>Modrinth</name>
<url>https://api.modrinth.com/maven</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>maven.modrinth</groupId>
<artifactId>7QMwdTys</artifactId>
<version>L7jkxaIL</version> <!-- Version 2.4.1 Java 25 -->
<scope>provided</scope>
</dependency>
</dependencies>
Gradle (Groovy DSL) — Java 21
repositories {
exclusiveContent {
forRepository {
maven {
name = "Modrinth"
url = "https://api.modrinth.com/maven"
}
}
// forRepositories(fg.repository) // Uncomment when using ForgeGradle
filter {
includeGroup "maven.modrinth"
}
}
}
dependencies {
implementation "maven.modrinth:7QMwdTys:2OmHB5Qv"
}
Gradle (Groovy DSL) — Java 25
repositories {
exclusiveContent {
forRepository {
maven {
name = "Modrinth"
url = "https://api.modrinth.com/maven"
}
}
// forRepositories(fg.repository) // Uncomment when using ForgeGradle
filter {
includeGroup "maven.modrinth"
}
}
}
dependencies {
implementation "maven.modrinth:7QMwdTys:L7jkxaIL"
}
📁 Local JAR
Requires Coder-2.4.1.jar placed in your project's libs/ folder.
Maven pom.xml
<dependencies>
<dependency>
<groupId>me.coder.api</groupId>
<artifactId>coder-api</artifactId>
<version>2.4.1</version>
<scope>system</scope>
<systemPath>${project.basedir}/libs/Coder-2.4.1.jar</systemPath>
</dependency>
</dependencies>
Gradle (Groovy DSL)
dependencies {
implementation files('libs/Coder-2.4.1.jar')
}
Gradle (Kotlin DSL)
dependencies {
implementation(files("libs/Coder-2.4.1.jar"))
}
📝 Import Reference
| Version | Import Statement |
Current (2.3.x) | import me.coder.api.CoderAPI; |
Future (2.4.x+) | import dev.codestuff.coder.api.CoderAPI; |
UEC sits between the command layer and the execution engine. When a script is submitted for execution, UEC intercepts it, scans for known malicious patterns, and either allows it through or halts it and notifies the admin. Nothing runs without passing UEC verification.
⚙️ How It Works
- Intercepts all scripts — UEC fires on every
/coder run and /coder load call regardless of language (Java, Python, or Lua).
- Malicious pattern scanning — Smarter detections scan for dangerous method calls, unauthorized system access attempts, and known exploit patterns before the script ever touches the runtime.
- Blocks terminal access — Any script attempting to break out to the host system's terminal is blocked immediately.
- Admin notification — When a script is flagged, the admin is notified in-game and must explicitly approve or deny execution.
- Language-agnostic — The same verification gate applies to Java, Python, and Lua. No language bypasses UEC.
🔄 Execution Flow
- Admin runs
/coder run <filename> or /coder load <filename>.
- UEC intercepts the request and scans the script content for malicious patterns.
- If the script is clean, it passes through to the execution engine immediately.
- If the script is flagged, execution is halted and the admin receives an in-game alert.
- Admin reviews the flag and responds with
/coder confirm to allow or /coder cancel to block.
⚡ UEC Commands
| Command | Description |
/coder confirm | Manually permits a script that was flagged by UEC and awaiting admin review. |
/coder cancel | Permanently blocks and cancels a flagged script, preventing it from executing. |
Warning: Using /coder confirm on a flagged script bypasses the UEC block entirely. Only confirm scripts you have personally reviewed and trust.
The Java Script Manager (JSM) is a specialized clone of the User Execution Control system, tuned specifically for .java script analysis. Where UEC handles all languages generically, JSM goes deeper into Java-specific threat patterns — dangerous imports, reflection abuse, native method calls, and more.
⚙️ How It Works
- UEC-derived engine — JSM is built on the same interception architecture as UEC, inheriting its core blocking and notification pipeline.
- Java-specific detections — Highly optimized to recognize dangerous
.java syntax, method signatures, and import patterns that generic scanners miss.
- Import analysis — Scans
import statements for known dangerous or unauthorized packages before compilation even begins.
- Method-level scanning — Detects calls to restricted methods such as
Runtime.exec(), ProcessBuilder, reflection-based access, and native library loading.
- Pre-compilation gate — JSM runs before the Java compiler, meaning malicious code is caught before it ever produces a
.class file in the cache directory.
🔍 JSM vs UEC
| Feature | UEC | JSM |
| Covers all languages | ✓ | ✗ (Java only) |
| Java-specific pattern matching | Basic | Deep |
| Import statement analysis | ✗ | ✓ |
| Method-level scanning | ✗ | ✓ |
| Pre-compilation gate | ✗ | ✓ |
| Admin confirm/cancel flow | ✓ | ✓ |
📝 Important Notes
- JSM and UEC both run for
.java scripts — JSM does not replace UEC, it layers on top of it.
- The same
/coder confirm and /coder cancel commands are used to respond to JSM flags.
- Compiled
.class files that passed JSM are stored in Coder/JavaClass/Runtime/ (temporary) and Coder/JavaClass/Loaded/ (persistent in-memory).
Addon SDK
Extend Coder with custom execution handlers, commands, event listeners, preprocessors, and more — all through a clean Java API.
Before building an addon, you must first implement the Coder API as a dependency in your project. See Implementing Coder API for Maven and Gradle setup. Maven is recommended for older hardware; Gradle is recommended for high-end machines and complex addons.
Get addon sdk 1.2.8 (JAR)
Get addon sdk 1.2.8 (ZIP)
🧩 The CoderAddon Interface
Every addon implements CoderAddon. Only four methods are required — everything else has sensible defaults.
Required Methods
| Method | Description |
getName() | Returns the addon's display name. |
getVersion() | Returns the addon version string. |
getAuthor() | Returns the author's name. |
onEnable() | Called when the addon is loaded. Initialize your resources here. |
onDisable() | Called when the addon is unloaded. Clean up resources here. |
Optional Overrides
| Method | Description |
getDescription() | Short description of what the addon does. Default: "A Coder addon". |
onReload() | Called on reload. Default behavior calls onDisable() then onEnable(). |
getPriority() | Load priority (0–100). Default: 50. |
getDependencies() | Array of other addon names this addon depends on. |
getAPIVersion() | Target API version. Default: 2. |
onAllAddonsLoaded() | Called after all addons have finished loading. |
registerCustomCommands(api) | Register your /coder subcommands here. |
getEventListener() | Return a CoderEventListener to hook into script and plugin events. |
getTabCompleter() | Return a CoderTabCompleter to provide custom tab-completion. |
getCustomJavaHandler() | Override Coder's default Java execution engine. |
getCustomPythonHandler() | Override Coder's default Python interpreter. |
getCustomLuaHandler() | Override Coder's default Lua interpreter. |
getScriptPreprocessor(lang) | Return a preprocessor to modify script content before execution. |
getScriptPostprocessor(lang) | Return a postprocessor to handle execution results. |
🔌 CoderAPI Reference
Get the API singleton with CoderAPI api = CoderAPI.getInstance(); then call any of these on api.
Messaging
| Call | Description |
api.sendMessage(sender, msg) | Send a prefixed message to a CommandSender. |
api.sendSuccess(sender, msg) | Send a green ✓ success message. |
api.sendError(sender, msg) | Send a red ✗ error message. |
api.sendWarning(sender, msg) | Send a yellow ⚠ warning message. |
api.sendInfo(sender, msg) | Send a blue ℹ info message. |
api.sendDebug(sender, msg) | Send a gray [DEBUG] message. |
api.sendRaw(sender, msg) | Send a raw message with no prefix. |
api.broadcastMessage(msg) | Send a prefixed message to all players and console. |
api.broadcastSuccess(msg) | Broadcast a green ✓ message to all players and console. |
api.broadcastWarning(msg) | Broadcast a yellow ⚠ message to all players and console. |
api.broadcastError(msg) | Broadcast a red ✗ message to all players and console. |
Logging
| Call | Description |
api.log(msg) | Write an info entry to the server log. |
api.logWarning(msg) | Write a warning entry to the server log. |
api.logError(msg) | Write a severe/error entry to the server log. |
api.logDebug(msg) | Write a debug info entry to the server log. |
Players
| Call | Description |
api.isPlayer(sender) | Check if a CommandSender is a Player. |
api.getPlayer(name) | Get an online player by name. |
api.getPlayerByUUID(uuid) | Get an online player by UUID. |
api.getOnlinePlayers() | Get all currently online players as Player[]. |
api.getOnlinePlayerCount() | Get the number of online players. |
api.teleportPlayer(player, loc) | Teleport a player to a location. |
api.damagePlayer(player, damage) | Deal damage to a player. |
api.healPlayer(player, amount) | Heal a player by the given amount, capped at max health. |
api.setPlayerHealth(player, hp) | Set a player's health directly. |
api.getPlayerHealth(player) | Get a player's current health value. |
Worlds
| Call | Description |
api.getWorld(name) | Get a world by name. |
api.getWorlds() | Get all loaded worlds as World[]. |
api.getWorldNames() | Get all loaded world names as String[]. |
Command Execution
| Call | Description |
api.executeCommand(cmd) | Execute a command as console. |
api.executeCommandAsPlayer(player, cmd) | Execute a command as a specific player. |
api.executeCommandAsConsole(cmd) | Alias for api.executeCommand(). |
Server Info
| Call | Description |
api.getServerMotd() | Get the server MOTD string. |
api.getBukkitVersion() | Get the Bukkit version string. |
api.getMinecraftVersion() | Get the Minecraft version string. |
api.getMaxPlayers() | Get the max player slot count. |
api.isServerRunning() | Returns true if the server is not stopping. |
api.getServerTicks() | Get the current server tick count. |
Other Plugins
| Call | Description |
api.getPlugin(name) | Get a loaded plugin by name. |
api.getPlugins() | Get all loaded plugins as Plugin[]. |
api.isPluginEnabled(name) | Check if a plugin is currently enabled. |
Engine Integration
| Call | Description |
api.registerCoderCommand(sub, handler) | Register a custom /coder <sub> subcommand. |
api.unregisterCoderCommand(sub) | Remove a previously registered subcommand. |
api.getRegisteredCoderCommands() | Get a Set<String> of all registered subcommand names. |
api.getCoderCommand(sub) | Get the handler registered for a subcommand. |
api.registerJavaHandler(handler) | Override the default Java execution engine. |
api.registerPythonHandler(handler) | Override the default Python interpreter. |
api.registerLuaHandler(handler) | Override the default Lua interpreter. |
api.getJavaHandler() | Get the currently active Java execution handler. |
api.getPythonHandler() | Get the currently active Python handler. |
api.getLuaHandler() | Get the currently active Lua handler. |
api.registerPreprocessor(lang, pp) | Register a script preprocessor for a language. |
api.registerPostprocessor(lang, pp) | Register a script postprocessor for a language. |
api.getPreprocessor(lang) | Get the active preprocessor for a language. |
api.getPostprocessor(lang) | Get the active postprocessor for a language. |
api.registerEventListener(listener) | Register a CoderEventListener. |
api.unregisterEventListener(listener) | Unregister a previously registered event listener. |
api.getEventListeners() | Get all registered event listeners. |
api.registerTabCompleter(completer) | Register a tab completer for /coder. |
api.getTabCompleters() | Get all registered tab completers. |
🔧 Execution Handlers
JavaExecutionHandler
Override how Coder compiles and runs .java scripts.
| Method | Description |
compileAndExecute(file, sender) | Compile and immediately execute a Java file. |
compileAndLoad(file, sender) | Compile and load a Java file into server memory. |
unloadClass(className, sender) | Unload a previously loaded class from memory. |
isClassLoaded(className) | Check whether a class is currently loaded. |
clearCache() | Clear all compiled class cache files. |
ScriptExecutionHandler (Python & Lua)
Override how Coder runs Python or Lua scripts.
| Method | Description |
execute(file, sender) | Execute a script file. |
executeString(content, sender) | Execute script content from a raw string. |
getLanguage() | Return "python" or "lua". |
initialize() | Initialize the interpreter on startup. |
cleanup() | Release interpreter resources on shutdown. |
isAvailable() | Returns whether the interpreter is ready. |
📡 Event Listener & Pre/Postprocessors
CoderEventListener
| Method | Fires when… |
onScriptStart(name, lang) | A script begins executing. |
onScriptEnd(name, lang, success) | A script finishes (success or fail). |
onScriptError(name, lang, error) | A script throws an error. |
onAddonLoad(addonName) | Any addon is loaded. |
onAddonUnload(addonName) | Any addon is unloaded. |
onCommandExecute(sub, args) | Any /coder subcommand is executed. |
ScriptPreprocessor
Modify script content before it reaches the execution engine. Return null to cancel execution entirely.
String process(String scriptName, String content);
ScriptPostprocessor
Handle the result after a script finishes — log output, send notifications, trigger follow-up actions.
void processResult(String scriptName, CommandSender executor,
boolean success, String output, Throwable error);
🚀 Minimal Addon Example
import dev.codestuff.coder.api.CoderAddon;
import dev.codestuff.coder.api.CoderAPI;
public class MyAddon implements CoderAddon {
@Override public String getName() { return "MyAddon"; }
@Override public String getVersion() { return "1.0.0"; }
@Override public String getAuthor() { return "yourname"; }
@Override
public void onEnable() {
CoderAPI api = CoderAPI.getInstance();
api.log("MyAddon enabled!");
// Register a custom /coder hello subcommand
api.registerCoderCommand("hello", new MyHelloCommand());
}
@Override
public void onDisable() {
CoderAPI api = CoderAPI.getInstance();
api.unregisterCoderCommand("hello");
api.log("MyAddon disabled.");
}
}
Use import me.coder.api.CoderAPI; if you are on version 2.3.x. The dev.codestuff.coder.api package is for 2.4.x+.
📦 Installation & Setup
What server software does Coder support?
Coder targets Bukkit/Spigot-compatible servers. It uses native Bukkit/Spigot imports for Java script execution, so Paper and its forks work as well.
Do I need Python or Lua installed on the server machine?
No. Coder uses Jython for Python execution and LuaJ for Lua — both run entirely on the JVM. No external Python or Lua installation is required on the host machine.
Where do I put my scripts?
All scripts go in /plugins/Coder/scripts/. Execution logs are written to /plugins/Coder/Logs/. The GWI web editor config lives under /plugins/Coder/.gwi/.
🛡 Security
Can players run scripts?
No. All /coder commands require the coder.admin permission. Only operators and users explicitly granted this permission can run or load scripts.
What does UEC actually block?
UEC intercepts unauthorized scripts and blocks any attempt to access the host system's terminal. The Java Script Manager additionally catches dangerous Java-specific patterns — such as Runtime.exec(), reflection abuse, and unauthorized imports — before compilation.
Is the GWI web editor safe to expose publicly?
The GWI uses SHA-256 session tokens that expire after 30 minutes of inactivity and are mathematically infeasible to brute-force. That said, you should only share GWI links with trusted administrators and never post them publicly.
How do I disable the Virtual Console Interface?
Open /plugins/Coder/.gwi/secure/serverPassword.env and remove the value after serverPassword=, leaving it blank. This disables the password gate and effectively locks the /mc-console/ endpoint.
📝 Scripting
What's the difference between /coder run and /coder load?
/coder run executes a script once and exits. /coder load compiles the script and keeps it resident in server memory, allowing it to maintain active listeners and background tasks indefinitely until you call /coder unload.
Where do compiled Java class files go?
Temporary runtime-compiled classes land in Coder/JavaClass/Runtime/. Classes that have been loaded into persistent server memory are tracked under Coder/JavaClass/Loaded/.
My script was flagged by UEC. What do I do?
Review the script yourself to confirm it doesn't contain any dangerous code. If you're satisfied it's safe, run /coder confirm to allow it through. If you're unsure or it looks suspicious, run /coder cancel to block it.
🧩 Addons
Maven or Gradle — which should I use?
Maven is recommended for older or lower-end hardware. Gradle is recommended for high-end machines and complex addons where build performance and flexibility matter more.
Can an addon replace Coder's Java execution engine?
Yes. Implement JavaExecutionHandler and return it from getCustomJavaHandler() in your CoderAddon, or register it directly via CoderAPI.getInstance().registerJavaHandler(handler). The same pattern applies for Python and Lua via ScriptExecutionHandler.