Guides
Deploy a plugin

Deploy a plugin

Get your built .jar onto a server, restart, and confirm it actually loaded. The CLI does all four steps for you; the manual SFTP path is there when you want control.

The fast path: truetick deploy

If you're iterating on a plugin, the CLI dev-loop is the shortest route. init binds a project to a server (or creates an ephemeral one) and writes truetick.toml; deploy builds, uploads over SFTP, restarts, and confirms the jar loaded by scanning the log.

Initialize the project

cd my-plugin
# Bind to an existing server:
truetick init --server my-smp
# …or create a fresh metered dev server:
truetick init --create --name "Dev" --ram 4096 --type PAPER --yes

init auto-detects your build: Gradle (build.gradle) → gradle build with artifact build/libs/*.jar, Maven (pom.xml) → mvn -q package with target/*.jar. It writes truetick.toml with the server id, target dir (plugins for Bukkit cores, mods for loaders), build command, and artifact glob.

Deploy

truetick deploy

This runs the build, uploads the newest matching jar over per-server SFTP (binary-safe, no size cap), restarts the server, then tails the post-restart log looking for an "Enabling <PluginName>" / "Done" line — or a stack trace. It prints ✓ … loaded or ✗ … failed accordingly and exits non-zero on failure, so it's CI-friendly.

Iterate

truetick dev

dev deploys once, then watches the artifact glob and redeploys (debounced) on every rebuild while tailing logs live. Ctrl-C to stop.

truetick.toml fields: server (id), target (plugins|mods), build (command, optional), artifact (glob), on_deploy (restart), ephemeral (true for --create servers). Full reference: CLI.

The manual path: SFTP + restart + confirm

If you'd rather drive it yourself, the building blocks are exposed over the API.

Enable SFTP and get credentials

POST /v1/servers/{id}:enable-sftp returns host/port/username/password (scope files:write):

const cred = await client.servers.enableSftp("my-smp");
// { host, port, username, password } — upload your jar to plugins/<file>.jar

Upload the jar to plugins/yourplugin.jar (or mods/ for a mod loader) with any SFTP client. For small text files you can also use the file API (files.write), but jars are binary — prefer SFTP.

Restart to load it

await client.servers.restart("my-smp");

Confirm it loaded

Read the post-restart log and look for the enable line:

const { lines } = await client.servers.recentLogs("my-smp", { tail: 200 });
const loaded = lines.some((l) => /Enabling\s+YourPlugin\b/i.test(l));
const errored = lines.some((l) => /Exception|Caused by:|Could not load/i.test(l));
console.log(loaded ? "loaded ✓" : errored ? "failed ✗" : "still starting…");
⚠️

Plugins vs mods. Bukkit-family cores (PAPER, PURPUR, SPIGOT, FOLIA) load .jar files from plugins/. Mod loaders (FABRIC, FORGE, NEOFORGE, QUILT) load from mods/, and a Bukkit plugin won't run on them (and vice-versa). For published projects, prefer managed mods (mods.add) so installs are reconciled for you.