NapNodes

← Discord bot guides

Discord bots · updated 20 October 2026

Discord Bot Showing Your Minecraft Server Status (Players Online)

The question asked most often on a server's Discord is “is it up?”. This bot answers it by itself: in the member list it shows “Playing 3/20 players” (or “Server offline”) and updates every minute, and /status shows the version, the ping and who's connected. It's about 60 lines of Python and works for any Minecraft Java server, wherever it's hosted.

How the bot knows whether the server is online

It asks the server the same thing your game does when you open the multiplayer server list: the “Server List Ping”. The server replies with the players online, the maximum, the version and a sample of names. You don't need to install any plugin or touch the server, and it doesn't need RCON or passwords: the mcstatus library does it.

That's why it works with any Minecraft Java server that has a public address, even one that isn't yours. If the server has “hide-online-players” turned on in server.properties, it'll say how many there are but not their names. And the game shows at most 12 names: with more people, you get 12.

If what you want is the in-game chat in a Discord channel (and join and leave messages), that's something else: a plugin inside the server, DiscordSRV. You can have both at once.

Rather not set it up yourself? Discord bot hosting from €1.50 a month, no contract and a full refund within 72 hours. Or create a free Discord bot, no card needed.

1. Create the bot on Discord

  1. Create the application

    Go to discord.com/developers/applications, click “New Application” and give it a name, for example your server's. That's your bot; the picture you give it is what people will see in the member list.

  2. Get the token

    In the “Bot” tab, click “Reset Token” and copy the token. It's the bot's password: whoever has it controls the bot, so don't share it or push it to GitHub. This bot doesn't read messages, so you don't need to turn on any “Privileged Gateway Intent”.

  3. Invite it to your server

    In “OAuth2” → “URL Generator”, tick “bot” and “applications.commands”, for permissions tick “Send Messages” and “Embed Links”, and open the link it gives you to add it to your Discord server.

2. The code

Three files in one folder. requirements.txt lists the libraries; .env holds the token and your Minecraft server's address (no quotes, with “:port” after it only if you type it to join); and app.py is the bot.

What it does: every minute it asks the server and changes the bot's activity (“Playing 2/20 players” in green, or “Server offline” in red). The /status command asks the same thing right then and replies with a card: players, version, ping and the names of whoever's in.

requirements.txt
discord.py
mcstatus
python-dotenv
.env
DISCORD_TOKEN=paste-your-token-here
MC_ADDRESS=yourname1.play.napnodes.com
app.py
import os

import discord
from discord import app_commands
from discord.ext import tasks
from dotenv import load_dotenv
from mcstatus import JavaServer

load_dotenv()  # reads the token and the address from the .env file
ADDRESS = os.environ["MC_ADDRESS"]  # the one in “Address to play”, with :port if it has one

intents = discord.Intents.default()
client = discord.Client(intents=intents)
tree = app_commands.CommandTree(client)


async def query():
    """Asks the server the way the game's server list does. None if it doesn't answer."""
    try:
        server = await JavaServer.async_lookup(ADDRESS)
        return await server.async_status()
    except Exception:
        return None


@tasks.loop(minutes=1)
async def update_status():
    status = await query()
    if status is None:
        await client.change_presence(status=discord.Status.dnd, activity=discord.Game("Server offline"))
    else:
        text = f"{status.players.online}/{status.players.max} players"
        await client.change_presence(status=discord.Status.online, activity=discord.Game(text))


@tree.command(name="status", description="Is the Minecraft server online and who's playing?")
async def status_cmd(interaction: discord.Interaction):
    await interaction.response.defer()  # the query can take a couple of seconds
    status = await query()
    if status is None:
        await interaction.followup.send(f"🔴 **{ADDRESS}** isn't answering: it's offline or starting.")
        return
    names = [p.name for p in (status.players.sample or [])]
    embed = discord.Embed(title=f"🟢 {ADDRESS}", color=0x5B4AE8)
    embed.add_field(name="Players", value=f"{status.players.online}/{status.players.max}")
    embed.add_field(name="Version", value=status.version.name)
    embed.add_field(name="Ping", value=f"{round(status.latency)} ms")
    if names:
        embed.add_field(name="Online", value=", ".join(names), inline=False)
    await interaction.followup.send(embed=embed)


@client.event
async def on_ready():
    await tree.sync()  # publishes the /status command
    if not update_status.is_running():
        update_status.start()
    print(f"Logged in as {client.user}")


client.run(os.environ["DISCORD_TOKEN"])

3. Try it on your computer

With Python 3.10 or newer: open a terminal in the folder, install the libraries with “pip install -r requirements.txt” and start it with “python app.py”. When it says “Logged in as…”, within a minute the bot changes its activity, and you can type /status on your Discord server. Slash commands can take a few minutes to show up the first time.

If it says “isn't answering” and the server is on, check MC_ADDRESS: it has to be the same thing you type in Minecraft to join. A server that's starting up or generating the world doesn't answer either until it's done.

Ideas to extend it

A channel with the player count in its name (“🟢 3 players”) looks great, but Discord only lets you rename a channel a couple of times every 10 minutes: if you do it, do it every 10 minutes, not every minute, or Discord will rate-limit the bot. The bot's activity, on the other hand, can be updated every minute without trouble.

To announce “the server is up!”, store whether the last query got an answer and, when it goes from no to yes, send a message to a channel with client.get_channel(CHANNEL_ID).send(…). With several servers, a list of addresses and one card field for each.

For Valheim or Project Zomboid

Valheim and Project Zomboid don't answer the Minecraft ping, but the Steam query (the one the Steam server browser uses). With the python-a2s library, replace the query function with this one and, where the bot reads status.players.online and status.players.max, use status.player_count and status.max_players. Remove the version and the names from the card, or use status.version and status.server_name.

Watch the port: Valheim answers on the game port plus one (if you join on 2456, this one is 2457) and Project Zomboid on the same port you join on.

app.py (Valheim or Zomboid)
import a2s  # in requirements.txt, add: python-a2s

# Valheim answers on the game port + 1; Project Zomboid, on the same game port
SERVER = ("yourname1.play.napnodes.com", 2457)


async def query():
    try:
        return await a2s.ainfo(SERVER)
    except Exception:
        return None

4. Keep it online all the time (for free)

A status bot is only useful if it's always online: if it lives on your computer, it disconnects when you switch it off and stops reporting.

On NapNodes: create the free bot, switch it to Python in “Settings” → “Language” (it starts out on Node.js), upload the three files in “Files” (or set your GitHub repository, without the .env) and click “Start”. The libraries in requirements.txt install themselves at startup and app.py is the startup file that comes set. The bot doesn't need to open any port.

The NapNodes free bot has 256 MB, plenty for a bot like this one, and you only have to renew it with one click every week. If it grows, Mini (512 MB) costs €1.50 a month. And if the Minecraft server is on NapNodes too, its address is the one on the “Address to play” card in “Home”.

Frequently asked questions

How do I make a Discord bot show how many players are on my Minecraft server?

With a bot that asks the server the way the game's multiplayer list does (in Python, the mcstatus library) and puts the number in its activity, for example every minute. No plugin is needed on the server.

Do I need to install anything on the Minecraft server?

No. The bot uses the same query as the game's server list, which every Minecraft Java server answers. You only need a plugin like DiscordSRV if you also want the in-game chat on Discord.

Why does the bot say how many there are but not their names?

Because the server has “hide-online-players” turned on in server.properties, or because there are more than 12 online: the game only shows a sample of 12 names.

Does it work for Valheim and Project Zomboid?

Yes, by replacing the query with the Steam one using the python-a2s library. Valheim answers on the game port plus one and Project Zomboid on the same port.

Where do I keep the bot online all the time?

On a server. NapNodes has a free 256 MB bot that you only have to renew with one click every week.

Shall we set it up for you?

Discord bot hosting from €1.50 a month, never oversold: your RAM is yours alone. And if you'd rather start without paying, there's a free Discord bot, no card needed.

Free tool: Is my Minecraft server online?. Type a Minecraft server address and see whether it responds, how many are playing, its version and its MOTD.

Keep reading

All Discord bot guides, sorted →