Ephemeral test server
Need a real Minecraft server for a few minutes — to run an integration test, validate a plugin, or let an agent try something — then throw it away? This is exactly what metered + scale-to-zero billing is for. You pay for the minutes it's awake and nothing for its existence.
A 4 GB server awake for a 5-minute CI job costs ~5 minutes of GB-hours. Created-but-never-started, or deleted right after, it rounds to nothing.
The pattern
Create (cheap, stopped)
import { TrueTickClient } from "@truetick/sdk";
const client = new TrueTickClient(); // TRUETICK_API_KEY
const server = await client.servers.create({
name: `ci-${process.env.GITHUB_RUN_ID ?? Date.now()}`,
ramMb: 4096,
type: "PAPER",
version: "1.21.1",
plan: "metered",
});Start and wait for running
await client.servers.start(server.id);
// Poll until ready (Paper cold start ≈ 12s)
for (let i = 0; i < 60; i++) {
const s = await client.servers.get(server.id);
if (s.state === "running") break;
await new Promise((r) => setTimeout(r, 2000));
}Run your test
Drive the server over RCON and assert on real behavior + honest metrics:
await client.console.run(server.id, "say test harness online");
const m = await client.servers.metrics(server.id);
if (m.live && m.tps < 19) {
throw new Error(`TPS regression under test: ${m.tps}`);
}Tear down (always)
await client.servers.delete(server.id);Put the delete in a finally so a failed test still cleans up — otherwise the server keeps billing
while awake (until idle hibernation kicks in).
Full CI script
import { TrueTickClient } from "@truetick/sdk";
const client = new TrueTickClient();
const name = `ci-${process.env.GITHUB_RUN_ID ?? Date.now()}`;
let id: string | undefined;
try {
const server = await client.servers.create({ name, ramMb: 4096, type: "PAPER", version: "1.21.1" });
id = server.id;
await client.servers.start(id);
for (let i = 0; i < 60; i++) {
if ((await client.servers.get(id)).state === "running") break;
await new Promise((r) => setTimeout(r, 2000));
}
// … your assertions over RCON / metrics / logs …
const { output } = await client.console.run(id, "list");
console.log(output);
} finally {
if (id) await client.servers.delete(id);
}CLI variant
The CLI's init --create / down pair gives you the same ephemeral lifecycle for plugin work, and it
marks the server ephemeral so down knows it's safe to delete:
truetick init --create --name "ci-run" --ram 4096 --type PAPER --yes
truetick deploy # build, upload, restart, confirm the jar loaded
# … run tests against the server …
truetick down --yes # delete the ephemeral dev serverSee Deploy a plugin for the deploy half, and Programmatic control for agents for the agent angle.