TrueTick closes on December 1, 2026. Download your worlds from your server's Backups before then. Moving to another host? BlockByte gives TrueTick customers a discount with the code truetick at blockbyte.host.

← Blog · 2026-07-01

A live dev loop for Minecraft plugins (and the API behind it)

Every plugin developer knows this loop, because every host has forced them into it:

mvn package

Then: open the panel in a browser tab. Find the file manager. Drag the new jar over the old one, wait for the upload bar. Click into the console tab. Type restart, or find the restart button. Wait for the server to come back. Scroll the console for the stack trace you're hoping isn't there. Fix one line. Repeat.

None of that is hard. It's slow, manual work, and it all happens away from your editor. Your IDE built the jar in one second, and then you spent the next thirty doing file management. Over the dozens of iterations a feature takes, that adds up to a good part of a dev session spent switching to a browser instead of watching your code run.

We host Minecraft servers, and it bothered us enough that we built a CLI around fixing it.

The fix: truetick dev

TrueTick now ships @truetick/cli, and the main command in it is truetick dev. Point it at your plugin, and every time you rebuild, it uploads the new jar and restarts the server automatically, with no browser and no drag-and-drop. You can try the CLI through npx without installing anything first:

npx @truetick/cli servers list

Here's the whole loop, start to finish:

truetick login --key ttk_…
cd my-plugin
truetick init --create --name Dev --ram 4096 --type PAPER --yes
truetick dev

login saves your key locally so every later command is authenticated. init --create provisions a fresh Paper server sized for plugin dev and writes a truetick.toml in your project. That file holds the server ID, the build command and the glob for your build artifact, so nobody on the team has to remember the setup by hand. (Because --create creates a server, the CLI requires an explicit --yes.)

Then truetick dev takes over. It runs your build once, uploads the jar over per-server SFTP, restarts the server, and starts tailing the live log, all in your terminal. From there it watches your build output, and on every rebuild it repeats the cycle: upload, restart, tail. Save a file in your editor, run your build (or let a watcher run it for you), and the new behavior is live on a real server by the time you've alt-tabbed to check. Ctrl-C stops watching; the server itself doesn't move.

As for cost, the server that init --create provisions is metered and scale-to-zero, so you pay only while it's awake. You're billed only for the minutes it's running, not for the hours between your afternoon and evening dev sessions or for the week you spend on something else. When you're done, truetick down --yes deletes the dev server outright, so nothing keeps billing in the background after you've moved on.

The deploy-a-plugin guide has the full walkthrough, including debounce behavior and how dev decides what counts as a rebuild.

The rest of the surface

The CLI is the fastest way into a dev loop, but it's a thin client over the same public API that runs the dashboard. Everything it does, you can also do from your own code, from an AI agent, or from raw HTTP.

The TypeScript SDK is the same primitives as the CLI, typed, for when you're scripting something bigger than a plugin reload: a deploy pipeline, a Discord bot that restarts a server on demand, a test harness that spins up a server, runs an integration suite against it, and tears it down.

npm i @truetick/sdk
import { TrueTickClient } from "@truetick/sdk";

const client = new TrueTickClient({ apiKey: "ttk_…" });

const servers = await client.servers.list();
const m = await client.servers.metrics(servers[0].id);

// `tps` is a reading only when tpsSource says so. TPS_SOURCE_UNSPECIFIED means
// there is none — the first poll after a start or wake, or a world parked by
// pause-when-empty — and `tps` is a zero VALUE there, not zero performance.
const rate = m.tpsSource === "TPS_SOURCE_UNSPECIFIED" ? "no TPS reading yet" : `TPS ${m.tps}`;
console.log(`${servers[0].hostname}: ${rate}, ${m.players} players`);

The MCP server puts the same tool surface in front of an AI agent. Run npx -y @truetick/mcp from your Claude Desktop config with an API key in the environment, and you can ask Claude to list your servers, restart one, pull recent logs, or add a mod from Modrinth in plain English. The agent calls the API underneath instead of guessing.

npx -y @truetick/mcp

The raw REST API is what both of the above call, and it's fully documented for anyone who wants to skip the wrapper. Every request needs only an x-api-key header:

curl -H "x-api-key: ttk_…" https://api.truetick.gg/v1/whoami

That one call is enough to confirm a key works and see which account it's bound to, with no other setup. From there, the full API reference covers servers, console, files, backups, and mods, plus which scope each endpoint needs.

All four surfaces (CLI, SDK, MCP and REST) are documented together at /developers and in the docs at docs.truetick.gg, if you want to see the full command and endpoint list in one place.

The same numbers, everywhere

We built TrueTick on a simple premise: show you the numbers, and don't let the platform do anything behind your back that you couldn't see or do yourself. That applies beyond the dashboard too.

Tick-capable servers (Paper, Purpur, Forge, NeoForge, plus Vanilla and Fabric from Minecraft 1.20.3) expose live TPS and MSPT through /metrics. These are the same numbers you'd watch in the panel, from servers we don't oversell, and you can read them with client.servers.metrics() or a plain GET /v1/servers/{id}/metrics without opening the dashboard. The response says where the rate came from (tpsSource: counted off the world's tick counter, or reported by the core), and when there is no reading yet it says so instead of sending a zero that looks like one. GET /v1/servers/{id}/tick-history gives the same measurements as minute buckets, and the minutes the server slept are absent. The API uses the same poll of the running server as the panel, with the same staleness handling and the same empty state when a server is asleep. Nothing gets rounded up or smoothed over for the API consumer that wasn't already true for the browser.

API keys are scoped: a key with servers:read can't restart anything, and a key without billing:read can't see your wallet. The public reference doesn't expose a single admin endpoint. A key can't do anything the panel won't let you do, and there's no back channel.

That's the idea TrueTick was built on: the metric is the contract. A contract is more useful when it's also an API, because then your build pipeline can read it, your bot can act on it, and your own tooling can hold us to it, the same way a browser tab always could.

If you're building a plugin right now, the fastest way to feel the difference is to run the four commands under "The fix" above and watch your next mvn package show up on a live server without you ever opening a browser tab.

TrueTick is metered Minecraft hosting with guaranteed, never-oversold CPU and live TPS on screen. See what your server would cost or create one.