Watches any number of ARK:SE servers (RCON for players and chat, the query port for map, version and player cap), records joins, leaves, chat and an audit trail, and keeps a player database across servers. Control: save, broadcast, chat, whisper, kick, time of day, MOTD, wild dino wipe, a raw console with history and macros, restarts with timed warnings and a world save, optional start command and auto-start. Bans are kept by Megalodon: timed, cluster-wide and re-enforced when the player returns. Automation: schedules (every N or at times of day), Discord/ntfy/webhook notifications, welcome message, chat word filter. Access: viewer, moderator and admin roles, API tokens, Prometheus metrics. cmd/fakeark simulates a server for trying it out. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Megalodon
Remote management for ARK: Survival Evolved servers over RCON. One small binary (no database, no dependencies) that watches your servers, gives you a web dashboard to run them from, and does the boring parts on a schedule.
It talks to the server the way the game's own admin console does, so it works with any ARK:SE server that has RCON switched on, whether it runs in Docker, on TrueNAS, or on a plain machine.
What it does
Watch
- Live status of every server: online or not, players, map, version, RCON latency, uptime, and a 24-hour player-count graph. No RCON password needed for the map/version/player cap: it also asks the game's query port, like the Steam server browser does.
- Join/leave events, chat log, and an audit trail of everything anyone does from the dashboard.
- A player database across all servers: first and last seen, total play time, number of visits, notes.
- A watch list: get an event the moment a particular player joins.
- Prometheus metrics at
/metrics.
Control
- Save the world, broadcast, chat as SERVER, whisper to one player, kick, set the time of day, set the message of the day, wipe wild creatures.
- Bans that behave: with a reason, optionally for a set time, applied to every server in a cluster at once, and enforced again whenever the player turns up (even on a server that was offline when you banned them). Expired bans lift themselves.
- Restarts that warn people: a countdown with announcements at 30, 15, 10, 5, 2 and 1 minute and
30 and 10 seconds, a world save first, cancellable at any time. Optionally Megalodon starts the
server again itself (see
start_command), and can start it automatically if it stays down. - A raw console with history and suggestions, plus saved macros (named lists of commands).
- Cluster actions: broadcast or save on every server in one click.
Automate
- Schedules: a save every 30 minutes, a daily restart at 04:30 on weekdays, a broadcast every hour, any console command on a timer.
- Notifications to Discord, ntfy or any webhook for the events you choose.
- Welcome message whispered to each player who joins.
- Chat filter: warn, then kick or temporarily ban, for words you list.
Share it safely
- Three roles: viewer (look), moderator (talk to players, kick, ban, save), admin (everything, including the raw console, restarts, schedules and settings).
- API tokens with the same roles, for scripts and monitoring.
Setting up the server side
RCON is off by default. In GameUserSettings.ini under [ServerSettings]:
RCONEnabled=True
RCONPort=27020
ServerAdminPassword=choose-something-long
(or add ?RCONEnabled=True?RCONPort=27020?ServerAdminPassword=... to the launch command). The
password you set there is the RCON password.
Do not expose the RCON port to the internet. RCON is unencrypted and its password is the whole admin password. Keep it on your LAN or a VPN; only Megalodon needs to reach it. If Megalodon and the server are on the same machine or Docker network, nothing needs to be opened at all.
Running it
# download a release, or: go build ./cmd/megalodon
./megalodon serve
On first run it writes megalodon.json, creates a user called admin and prints its password
once in the log. Open http://127.0.0.1:8480, sign in, and use Add server. Or copy
megalodon.example.json and edit it.
By default the dashboard only listens on 127.0.0.1. To reach it from elsewhere, put it behind an
HTTPS reverse proxy, or expose it through Hammerhead,
and set "cookie_secure": true and "trust_proxy": true. Don't put the dashboard on the open
internet over plain HTTP.
Docker: see Dockerfile and deploy/docker-compose.yml.
Set TZ so scheduled times use your clock.
Commands
megalodon serve [-config megalodon.json] [-listen addr]
megalodon user NAME [ROLE] add a user, or change a password (reads MEGALODON_PASSWORD or stdin)
megalodon token NAME [ROLE] create an API token (printed once)
megalodon rcon -addr host:27020 -password PW [COMMAND...]
one-off console command, or an interactive prompt without a command
Configuration
Everything is in one JSON file, and everything except listen, data_dir, poll_seconds,
chat_seconds, trust_proxy and cookie_secure can be edited from the dashboard (changes are
written back to the file). See megalodon.example.json.
| Setting | Meaning |
|---|---|
servers[].host, rcon_port, password |
where to reach the console |
servers[].query_port |
game query port (UDP, usually 27015); 0 turns it off |
servers[].start_command |
shell command that starts the server (docker start ark-island, systemctl start ark, a script). Runs on the machine Megalodon is on; it must return promptly |
servers[].auto_start |
run start_command when the server has been down for auto_start_after seconds (default 120), at most every 5 minutes. A server you Stop from the dashboard stays stopped |
jobs[] |
action is save, broadcast, restart, command, destroy_wild_dinos or motd; use every ("30m") or at (["04:30"], optionally with days) |
notify[] |
kind is discord, ntfy or json. No events list means joins, leaves, up/down, restarts, bans and errors |
poll_seconds |
how often each server is asked who is online (default 10) |
Files in data_dir: events.jsonl (event log, rotated at 20 MB), players.json, bans.json,
samples-<server>.jsonl (the graph).
API
Everything the dashboard does goes through a JSON API. Sign in with POST /api/login, or send an
API token as Authorization: Bearer mgl_….
curl -H "Authorization: Bearer $TOKEN" http://127.0.0.1:8480/api/servers
curl -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"action":"broadcast","message":"Restart in 10 minutes"}' \
http://127.0.0.1:8480/api/servers/island/action
action is one of save, broadcast, say, whisper, kick, ban, unban, allow,
disallow, destroy_wild_dinos, set_time, motd, exec, restart, stop, cancel_restart
and start. POST /api/actions does the same on several (or all) servers. GET /api/events,
GET /api/players, GET /api/stream (live events, server-sent) and GET /metrics round it out.
Prometheus: megalodon_server_up, megalodon_players, megalodon_players_max,
megalodon_rcon_rtt_ms, megalodon_uptime_seconds, megalodon_restart_pending, all labelled by
server.
Security notes
- Passwords are stored as PBKDF2-SHA256 hashes; API tokens as SHA-256 hashes. RCON passwords sit in
megalodon.jsonin plain text (they have to), so the file is written0600: keep it that way. - Sessions are
HttpOnly,SameSite=Strictcookies, and every change needs a custom header a web page on another site can't send. Failed sign-ins are rate-limited per address. - The dashboard has a strict Content-Security-Policy and never renders game text as HTML.
- Values that go into console commands (Steam IDs, messages) are validated and stripped of quotes and line breaks, so a player name or message can't inject a second command. The raw console is admin-only and recorded in the event log.
- Moderators can see audit entries; viewers cannot.
Honest limits
- It has been tested against a simulated ARK server and unit tests, not yet against a real
ARK:SE server. The console's reply formats (
ListPlayers,GetChat) are parsed leniently, but if one differs on your version, open an issue with the raw reply (megalodon rcon … ListPlayers). - RCON can't read or write
GameUserSettings.ini, install mods or update the game; restarting and updating are left to whatever runs the server (Docker, systemd, SteamCMD). - Commands that take an in-game player ID rather than a Steam ID (
GiveItemToPlayer,GiveExpToPlayer) are available from the console but have no buttons, because RCON doesn't report that ID. - ARK:SE only (it is untested on ASA, which uses the same protocol but may differ in detail).
Development
go test ./...
go run ./cmd/fakeark & # a pretend server on :27020 (password "secret") with players and chat
go run ./cmd/megalodon serve
Releases are built by the Gitea workflow when a v* tag is pushed.
Licensed under the AGPL-3.0 (see LICENSE).