Getting started
What works immediately without touching your Minecraft server — and how to set it up.
A large part of the bot does not need your server at all. Status, charts, images, embeds and voice channels work from the public address — the same one players connect to. Only chat, whitelist and commands need a real link into the game.
- Invite the bot via invite.mc-sync.eu and pick your Discord server.
- Run
/setup. It first asks what you want to set up, then asks exactly one question per step. /server add name: Survival address: your-address.netregisters your server once —/status,/embed,/voice-channeland/default-ipcan all point at it by name afterwards./languagesets the language the bot replies to you in.- If you would rather click than type: the dashboard does the same, with previews and pick lists instead of commands.
- Invite the botPick your Discord server, done
- Open the dashboardSign in with Discord
- Download plugin or modOne file per loader and version
/help shows the same overview inside Discord, sorted into the same groups as the command reference on this site.
The dashboard
Everything the slash commands can do — in the browser, with pick lists, previews and no typos.
The dashboard is the same setup as in Discord, seen from the other side. What you change here applies there immediately, and the other way round — there is no second configuration to keep in sync. What it adds is looking: reading the console live, the player count over time as a chart, a log of every change, a preview of an embed before it sits in the channel.
- Go to mc-sync.eu/dashboard and sign in with Discord.
- Pick the Discord server. Every server on which you hold “Manage Server” is listed — and where the bot is missing, you can invite it from there.
- Pick a section on the left. Its address is
/dashboard/<discord-server-id>/<section>and can be bookmarked.
- Open the dashboardSign in with Discord, session lasts eight hours
- MonitoringOutage alerts — yours, not a server's
The sections in the left column, grouped by the question they answer:
| Section | What you can do there |
|---|---|
| Overview | How many Minecraft servers are registered, how many of them are connected, how many accounts are linked — and what is still missing from the setup. |
| Servers | The server list: name, address, edition and the attached connection. This is also where a public status page is published. |
| Console | Run commands, read the server console live, create buttons and schedules. |
| Chat sync | Create connections, reissue and time-limit tokens, set the chat format, read the chat history. |
| Statistics | The player count over 24 hours, 7 or 30 days. |
| Whitelist | Add and remove names — one at a time or a whole list at once. |
| Linked accounts | Who connected their Discord account to which Minecraft name. |
| Role sync | Rules: a role gained or lost, a command runs. |
| Permissions | Which Discord role may trigger which server commands. |
| Displays | Embeds and status voice channels, with a preview before posting. |
| Alerts | Alert role, audit channel, console channel and what the service reports by itself. |
| Access rights | Which Discord role may do what inside the dashboard. |
| Activity log | Who changed what and when — searchable and as CSV. |
Each of those has its own section further down. The shortest ways there:
The server list
One entry per Minecraft server — address, edition and chat sync together.
Before /server, a Minecraft server was several separate things nobody connected: an address typed into /status, /embed and every voice channel by hand, and a chat sync created with /chat-sync add that knew nothing about that address. Moving to a new domain meant finding every one of those places.
/server add name: Survival address: play.example.eu
/server settings server: Survival chat-sync: #minecraft - Survival
/server listBoth halves stay optional, and either one alone is a real case: an entry without an address is a server you cannot ping from outside; one without a chat sync is a server with no plugin or mod running. The bot works without a plugin too — then it shows exactly what a ping returns.
settings changes one field at a time; clear removes a single entry (address, chat sync or edition) without deleting the whole server. remove only takes the server off this list — an attached chat sync keeps running under its own name.
The dashboard holds the same list under “Servers”, with the same four fields as a form. There — and only there — an entry can also be published as a public status page: /s/<name>, reachable without signing in, plus an SVG badge for a README or a forum signature. Public are state, player count, version, address and the history — not the player list, not the Discord server behind it, not the whitelist.
Setting up chat sync
Minecraft chat in a Discord channel and Discord messages back into the game — through the plugin, with no open port.
This needs the MC-Sync plugin on your server. It opens the connection itself, outbound: an ordinary HTTPS request that stays open. You do not have to forward a port or register an address anywhere.
- Download the right file: mc-sync.eu/plugin. There is one per loader and version range.
- Put it into
plugins(Spigot, Paper, Folia) ormods(Fabric, Quilt, Forge, NeoForge) and restart the server once. That creates the config file. - In Discord, run
/chat-sync add channel: #your-channel name: Survival. The bot replies with a token, visible to you alone. - Put the token into the configuration and restart the server again.
/mcsync statusin-game then tells you whether the connection is up.
# plugins/mc-sync/config.yml
api:
token: "your-token-from-discord"
# What happens when a newer build is released:
# install (default) | notify | off
update:
mode: install
# The live console in the dashboard. While nobody is
# watching it costs nothing — not a byte goes out.
console:
live: trueWhat is transferred is up to you, switch by switch. They all live on /chat-sync settings:
| Option | What it turns on or off |
|---|---|
| chat-messages | Ordinary chat messages from the game |
| join-leave-messages | Joining and leaving |
| death-messages | Death messages |
| advancements | Advancements (Minecraft 1.12 and up) |
| language | Language of the messages the bot writes itself |
| active | Pauses the sync without deleting it |
| channel | Moves it to a different channel |
/chat-sync list
/chat-sync settings server: #minecraft - Survival death-messages: False
/chat-sync settings server: #minecraft - Survival channel: #minecraft-newThe dashboard holds the same switches under “Chat sync”, and adds three things no slash command offers: the chat format — what a line looks like in Discord (as the player through a webhook, as a box or as a plain line), your own templates for join, leave, death and advancement, and a word filter in both directions —, the token's lifetime with a grace period and an expiry date, and the chat history, read straight out of Discord.
In-game the plugin brings /mcsync: status shows whether the connection is up and what the server accepts in the way of commands, reload re-reads the configuration without a restart, and toggle turns the Discord chat off for yourself. The first two require the mcsync.admin permission; toggle is open to everyone — it is your own display.
There is one file per loader and version range. Which one you need depends on your server:
| Loader | Minecraft versions |
|---|---|
| Spigot | 1.8.8 to current |
| Paper | 1.16.5 to current |
| Folia | 1.20.1 to current (the Paper file) |
| Forge | 1.8.8 to current (except 1.13.2) |
| Fabric | 1.19.2 to current |
| Quilt | 1.19.2 to current |
| NeoForge | 1.20.2 to current |
Running commands from Discord
whitelist add, say or kick from Discord — over the same connection chat sync already uses.
Once chat sync is in place, the same path can carry commands. It needs no open port and no extra password — that is what took the place of RCON here.
Two questions are answered separately, and that matters. Who may ask is settled in Discord, per role, under /server-command permission. What your server accepts is settled in config.yml. Both have to agree.
/server-command permission add role: @Moderator commands: whitelist,say,kick
/server-command permission list
/server-command run command: whitelist add NotchOn the server side, commands.mode decides what gets through at all:
| commands.mode | What is executed |
|---|---|
| off | Nothing, not even the whitelist. |
| whitelist | Only whitelist add, whitelist remove and whitelist list. The default — exactly what the whitelist channel needs. whitelist off and whitelist reload are explicitly not part of it. |
| allow | The whitelist plus everything listed under commands.allow. |
| all | Every command. That hands your server console to whoever is authorised in Discord. |
# plugins/mc-sync/config.yml
commands:
mode: allow
allow:
- say
- whitelist add
- lp user * parent addThe command is entered without the leading slash. Both sides always answer: a rejected command comes back as “rejected” rather than as silence — and, if /alerts audit-channel is set, as a line in the audit log too. Where the server returns console output it is included in the reply; many commands only answer in-game or not at all, and then it stays empty.
The dashboard does the same, and there you get the output: the console shows what the server replies, and who is online right now.
Console, buttons and schedules
Run commands and watch them work — in the browser instead of a Discord channel.
The console in the dashboard takes the same path as /server-command run: the same connection, the same check on the Minecraft server, the same audit log. What it adds is the output. At the top is what the server says about itself — greeting, player count, version —, below that who is playing, then the console window with the command field inside it, and at the bottom the history of what was triggered last.
- Open your Discord server in the dashboard and pick “Console” on the left.
- If there is more than one: pick the Minecraft server. With only one the step disappears.
- Type the command — without the leading slash — and send it. Arrow up brings back the previous one, and clicking a player's name writes it into the field.
The live console shows what the Minecraft server prints, while it prints it. It hangs off one switch in the configuration:
# plugins/mc-sync/config.yml
console:
live: trueTwo things exist only here and not as a slash command:
| Tool | What it does |
|---|---|
| Buttons | A labelled button for a command you need constantly. One click writes it into the field — it is only sent afterwards, so no restart happens by accident. |
| Schedules | A command at a time of day, optionally on certain weekdays. No weekday selected means every day. The time applies in your browser's time zone, and any schedule can be switched off without deleting it. |
Whitelist channel
A channel where players post their Minecraft name and the bot whitelists them.
Instead of somebody on the team typing every name by hand, the bot does it: it reads the name, verifies it with Mojang and whitelists it through the plugin. A name that does not exist is never passed on.
/whitelist-channel add channel: #whitelist role: @Member
/whitelist-channel listmode decides what happens to a valid name:
| Mode | Meaning |
|---|---|
| Add to the whitelist | Through the plugin. Default. |
| Verify only | The name is checked with Mojang but not whitelisted — for teams that want to decide themselves. |
server picks which registered Minecraft server (/server add) this channel whitelists to — skip it if you only have one. Without role anyone in the channel may submit a name; up to three roles narrow that down — to everyone who has been through an application, for instance.
The “Whitelist” section in the dashboard shows who is on it — with the name of whoever submitted them, and including the names somebody typed directly on the server. The other direction works from there too: add or remove a name, and with “Paste a list” a whole list of names at once, one per line. Commas, semicolons, bullets and quotes are cleared away in the process.
Embeds and voice channels
Two ways to keep the server state visible without anyone running a command.
An embed is a message the bot rewrites every five minutes. It stays where it is instead of filling the channel with repeats.
/embed add type: Status ip: play.example.eu channel: #server-info
/embed add type: Diagram ip: play.example.eu
/embed list
/embed remove embed: #server-info — status — play.example.eu| type | Contents |
|---|---|
| Status | Reachability, MOTD, version, edition, player count |
| Whitelist | The whitelisted names. Needs the plugin. |
| Diagram | Player count over time |
| Player stats | Totals reported by the linked chat sync |
| Connection | State of the chat sync itself, and when it was last heard from |
A voice channel does the same in its name — visible at the top of the list without anyone opening a channel. Status, player count and version are available.
/voice-channel add type: Status ip: play.example.eu
/voice-channel add type: Players ip: play.example.euFor voice channels the bot needs “Manage Channels”, and for embeds it needs permission to send and edit messages in the target channel. If one is missing, it says so when you create it. Both also accept server: instead of ip: to point at a server registered with /server add.
In the dashboard the area is called “Displays” and holds both in one place. It can do two things the command cannot. First the preview: pick type, channel and server, and below it stands how the embed will look in the channel — before posting, not after. Second, editing: a running display can be changed instead of being stopped and recreated. For a voice channel that includes its name — a template with placeholders such as {status} or {players}, so it is not stuck with an English sentence forever.
Linking accounts
Who someone is in Discord, and who they are in Minecraft.
/link start prints a one-time code. Typing it in the Minecraft chat as !link <code> proves both sides at once: the code, because it was only ever shown to you in Discord, and the Minecraft name, because it came from inside the game.
- Run
/link startin Discord. You get a code valid for ten minutes. - In Minecraft, type:
!link <code> - The bot confirms the link back in Discord.
The link is per Discord server, in both directions, and gone again with /link remove. It is what makes /role-sync possible, and what turns @Name written in the Minecraft chat into a real, ringing mention in Discord — for a single, unambiguous name, never for @everyone or @here.
The “Linked accounts” section in the dashboard shows all of them at once: which Discord name belongs to which Minecraft name, since when, when they were last seen and which role-sync rules apply to them. A link can be cut there as well — useful when somebody has changed their Minecraft account.
Roles that reach into the game
A Discord role that runs a command the moment it is given or taken away.
/role-sync add role: @VIP on-grant: lp user {player} parent add vip on-revoke: lp user {player} parent remove vip
/role-sync list{player} is replaced with the Minecraft name of whoever received or lost the role. Nothing is stored about a particular permission plugin — only the command itself, so this works with LuckPerms, PermissionsEx or a server's own rank plugin equally.
The dashboard puts a form around it, with a role picker and both fields side by side, and below them the line that will actually run on the server — with the name filled in instead of {player}. If the placeholder is missing it says so: without it the same command runs for everybody, which can be intended but rarely is.
Alerts and audit log
Who hears about an outage, and where server commands leave a trail.
A short reconnect is not an outage — the bot only speaks up after 20 minutes of silence, and takes it back the moment the server answers again. /alerts role decides who gets pinged when that happens.
/alerts role role: @Staff
/alerts audit-channel channel: #server-log
/alerts console-channel channel: #server-errors
/alerts notifications server-start: False server-stop: False| Setting | What it does |
|---|---|
| role | Pinged on a real outage — never on a short reconnect. |
| audit-channel | Every /server-command run, including rejected attempts. |
| console-channel | Warnings and errors from the Minecraft server — not the full log. |
| notifications | Four independent switches: service (master), delivery-warnings, server-start, server-stop. |
Leaving role, audit-channel or console-channel empty turns that alert back off. /alerts show lists everything currently set.
The dashboard holds the same five settings under “Alerts” as one form — role and channels as pick lists, the four reports as switches. If you want an alert that does not go to Discord but to an email address, a webhook or your phone, that is what monitoring is for.
Monitoring and status page
Hear about an outage by email, webhook, push or Discord. And a page that shows the state to everyone.
Monitoring belongs to you, not to a Discord server. It needs neither the bot nor permissions anywhere — only that you sign in with Discord. You will find it in the dashboard at /dashboard/watch, as a tile next to the server picker. The links from the mails themselves — confirm and unsubscribe — still work without signing in.
Every address entered is pinged once a minute. Nothing is reported until it has stayed silent for the grace period you set — which is what keeps a brief hiccup at the host from counting as an outage.
| What is reported | Needs a connection |
|---|---|
| Server stopped answering / is back | no |
| More or fewer players than a threshold | no |
| Version changed | no |
| Chat sync down or back up | yes |
| Token never used or found in public | yes |
| Server command rejected | yes |
| Warning from the console | yes |
| Whitelist request waiting | yes |
Reports travel four ways, several at once allowed: email, webhook (Discord, Slack, ntfy, Gotify or something of your own — https only), push into this browser and, if you are signed in, as a Discord direct message. Each way can be given a delay: it is only served if the matter still stands that much later. That turns several ways into an escalation instead of four copies of the same message.
The public status page answers the other half of the question: not “tell me”, but “see for yourself”. It is published in the dashboard under “Servers”, gets a name in the address and then lives at /s/<name> — no sign-in, open to anyone. There is an SVG badge to go with it, ready to embed in a README or a forum signature.
Along the way the bot records the state of every server it polls, every thirty seconds. That is what /diagram, the chart embeds and the “Statistics” area of the dashboard are built from — there over 24 hours, 7 or 30 days, with the peak and the share of reachable polls. A server polled for the first time today therefore has no week-long history yet.
Permissions and roles
Who sees which command, who may run it, who gets into the dashboard — and where each of those is set.
Discord assigns permissions per command, not per subcommand. That produces three cases, marked as badges on every command in the reference.
| Badge | Meaning |
|---|---|
| Administrators only | Discord hides the command from everyone else. That can be changed per role or per person under Integrations in the server settings. |
| Granted per role | The command is visible to everyone, because otherwise granting it could never take effect. Who may use it is set in /server-command permission add. |
| Discord servers only | Needs a server — the command does not exist in a direct message. |
| Works in DMs too | Installable as a user app and therefore available anywhere, including where the bot is not a member. |
The bot itself needs: send and edit messages (embeds), manage channels (voice channels), manage webhooks (/news-channel and the “as the player” chat style) and read messages in the channel chat sync uses. If something is missing, it says which during setup.
The dashboard has a second layer of its own. Whoever may manage the Discord server has everything there anyway; under “Access rights” further roles can be unlocked, area by area. What stands there can only give, never take away.
| Area | What it allows |
|---|---|
| View | Opening the server in the dashboard. It comes along automatically as soon as somebody may do anything at all. |
| Console | Running commands, managing schedules and buttons. What gets through is still up to the Minecraft server. |
| Whitelist | Adding and removing names. |
| Settings | Changing server entries, connections, chat formatting and alerts. |
| Displays | Managing embeds and voice channels. |
| Permissions | Role sync, command grants and this access list itself. |
| Tokens | Issuing, reissuing and time-limiting tokens — and thereby connecting a Minecraft server. |
The activity log
Who changed what and when — and how to find it again.
The activity log records every change: who made it, when, to what — and what was refused. A console command that ran is in there, and so is a reissued token, a cut link, or an attempt by somebody without the permission. It can be filtered by action, period and name, and downloaded as CSV.
When something does not work
The cases that reach support most often — and what they usually come down to.
| What you see | Usual cause |
|---|---|
| A command does not appear in Discord | It requires elevated permissions, or the commands have not reached this server yet. After inviting the bot that takes a moment; restarting the Discord client does not help, waiting does. |
| Chat arrives in Discord but not back in the game | Usually active is off, or the bot may not read messages in the channel. /chat-sync settings shows the current state. |
| No chat at all although the plugin is running | Token not entered under api.token, copied incorrectly, or the server was not restarted after entering it. /mcsync status in-game tells you which of those it is. |
| The embed stopped updating | The bot may no longer edit the message — usually because permissions in the channel changed. /embed list shows what is still registered. |
| The voice channel shows old numbers | That is normal: Discord limits renames, and the bot refreshes roughly every 25 minutes. |
/server-command run says “rejected” | The command is not covered by commands.mode, or not listed under commands.allow on the server. An entry there is matched word by word against the start of the command. |
| A role change does not run its command | Check /link show for the member — /role-sync only fires for an account that has been linked. |
| No notification although the server restarted | Direct messages from server members are turned off in the Discord settings. |
| No Discord server to pick in the dashboard | Only servers where you hold “Manage Server” are listed. That is the permission the dashboard asks for — everything beyond it goes through the access list. |
| The “Console” section is missing from the left column | The “Console” permission is missing under “Access rights”. Only what is genuinely closed gets hidden. |
| The live console stays empty | console.live is set to false, or the plugin build predates the feature. Commands you run and their replies still show up. |
If none of that helps, the support server is the quickest way. Mention the loader and Minecraft version, the command you ran and what the bot replied — that settles most cases in a single message.