On this page
Web panel
The panel is a small web app served by the plugin itself. It needs no web hosting and no database, loads nothing from a CDN and makes no request to any third party: every file comes from the plugin.
Signing in #
- The default address is
http://127.0.0.1:8765/, which only answers on the server machine. See Reaching the panel to open it from elsewhere. - Sign in with your Minecraft name and the password you set in game with
/mm password, or run/mm panelin game for a one-time link that signs you in directly (valid for 10 minutes, single use). - If the owner turns on game login, staff can also use the password of the server's login plugin (LoginSecurity or AuthMe).
- The panel speaks English, Spanish and Rioplatense Spanish; the language you pick follows your account to other browsers. It has light and dark themes, follows your device by default, and works on phones.
- Pages update in real time, and the dashboard shows who else is viewing the panel.
Sections and who sees them #
Each account sees what its groups (access.groups in config.yml) or its manukamod.panel.* permissions allow. Sections outside that scope are hidden from the menu.
| Section | Needs | What it shows |
|---|---|---|
| Dashboard | any account | Counters compared with the previous period, insights, the latest open cases and punishments, and who else is viewing the panel. |
| Cases | at least one violation type | A filterable list (status, type, severity, player, group, assignee, dates), bulk status changes and live updates. |
| Case page | the case's type | The evidence with the matched text highlighted, the conversation around it, notes, history, the player's punishments and the AI assessment. |
| Players | any account | Search or recently seen players. A player's page shows the player's current skin and adds their cases, punishments (punishments scope) and recent chat (logs scope). |
| Punishments | punishments | A timeline of bans, mutes, kicks and warnings from every source. |
| Chat logs | logs | Days with message counts, the lines of a day, search over up to 31 days, and links straight to a line such as 2026-10-01#5512. |
| Analytics | analytics | Charts of messages, active players, cases by type and severity, punishments, filter evasion and review times, each also viewable as a table. |
| Notifications | settings | E-mail server, recipients, a test button and the outbox. |
| Settings | settings | Every option of config.yml. On Free, only the language, theme and accent colour can be changed here. |
| Users | users | Panel accounts and what each one may see. On Pro also creating, enabling and disabling accounts, setting passwords and ending sessions. |
| Status | any account | Version, database, queues, e-mail and AI state, license and updates. Activating a key and downloading updates need the settings scope. |
The settings scope is equivalent to console access, because it can edit the automatic commands. Give it to owners only. Secret values (SMTP password, AI key, license key) are never sent to the browser.
Reaching the panel #
Local only (the default) #
panel:
bind: 127.0.0.1
port: 8765
The panel answers only on the server machine. To open it from your computer, use an SSH tunnel: ssh -L 8765:127.0.0.1:8765 user@your-server, then browse to http://127.0.0.1:8765/.
Behind a reverse proxy (recommended) #
Put nginx, Caddy or another HTTPS reverse proxy in front of the plugin. The panel then gets HTTPS, secure cookies and the visitor's real address for rate limits and the audit log. Keep bind: 127.0.0.1, so the plugin is only reachable through the proxy, and trust the proxy's forwarded headers:
panel:
bind: 127.0.0.1
port: 8765
base-path: "" # "/mm" when the panel lives under a path
public-url: "https://panel.example.com"
behind-proxy: { enabled: true, trusted-proxies: ["127.0.0.1"] }
Live updates use Server-Sent Events, so the proxy must not buffer the panel's responses. For a sub-domain such as https://panel.example.com/:
server {
listen 443 ssl;
server_name panel.example.com;
# ssl_certificate ...; ssl_certificate_key ...;
location / {
proxy_pass http://127.0.0.1:8765;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off; # live updates (Server-Sent Events)
proxy_read_timeout 1h;
}
}
panel.example.com {
reverse_proxy 127.0.0.1:8765 {
flush_interval -1
}
}
For a sub-path such as https://www.example.com/mm/, set base-path: "/mm" and public-url: "https://www.example.com/mm", and forward the path unchanged (in nginx, location /mm/ { proxy_pass http://127.0.0.1:8765; ... }, with no path after the port). Every address the panel builds is relative, so it works under any path.
Built-in HTTPS #
The plugin can also serve the panel over HTTPS (TLS 1.2 and 1.3) by itself, with a PKCS12 (.p12, .pfx) or JKS keystore in plugins/ManukaModeration/:
panel:
https:
enabled: true
keystore: "keystore.p12"
password: "" # or the MM_PANEL_KEYSTORE_PASSWORD environment variable
alias: "" # empty = the first key in the keystore
A certificate and key in PEM files can be turned into a keystore with openssl pkcs12 -export -in fullchain.pem -inkey privkey.pem -out keystore.p12; the export password you choose goes in panel.https.password. Unlike a reverse proxy, the plugin does not renew certificates: when yours is renewed, replace the keystore and restart the server. Changes to the panel.https settings take effect after a restart or /mm reload from the console or the game.
Whenever the panel listens on an address other than the local machine, the console warns at start. In that case a reverse proxy that limits slow and repeated connections is still the safer setup.
On your own website (Pro) #
You can host the panel's files on your own website (for example https://www.example.com/staff/) while the API stays on the Minecraft server:
- Set
panel.public-urlto the address the plugin is reachable at (ideally behind HTTPS) and add your website's origin topanel.allowed-origins, for example["https://www.example.com"]. - In the panel, open Status and download the panel bundle for your website. It comes with the API address already filled in.
- Unzip it where the panel should live on your site, keeping the folder layout.
- Serve it with a Content-Security-Policy that allows the API, for example
default-src 'self'; connect-src 'self' https://mc.example.com:8765; img-src 'self' data:; frame-ancestors 'none'.
The hosted copy signs in with a token kept in the browser tab's session storage. On Free, the server refuses this kind of sign-in.
Signing in with the in-game password #
On a server where players already log in with LoginSecurity (3.x) or AuthMe Reloaded, staff can sign in to the panel with the same name and password, without a separate panel password. It is off by default and works on Free and Pro:
panel:
game-login:
enabled: true
provider: auto # auto (LoginSecurity, then AuthMe) | loginsecurity | authme
create-accounts: true # the first game login creates the panel account
Apply it with /mm reload. The login form then says "Use the same password as your in-game login", and /mm status names the login plugin in use.
- Only players whose groups may use the panel get in. Everyone else gets the same "Wrong name or password" as a wrong password, and every attempt counts toward the login rate limit and lockout.
- The first game login creates the panel account, within the Free limit of 3 accounts. The player must have joined the server at least once since Manuka Moderation was installed.
- Use HTTPS whenever the panel is reachable from other machines: these are the players' in-game passwords. The console warns when they could cross the network unencrypted.
- AuthMe two-factor codes are not checked by the panel. If your server enforces AuthMe two-factor for staff, leave game login off and use panel passwords.
- To take access away, remove the player from the allowed groups, or disable their panel account on the Users page (Pro). Deleting the account is not enough while
create-accountsis on. - Changing the in-game password does not end panel sessions that are already open. End them from the Users page (Pro), or with
/mm user setpassword <name> <password>, which logs out every session of that account.
Player skins #
A player's page opens with a picture of their current skin, read from the player's game profile when they join. It works on online-mode servers, on offline-mode servers with SkinsRestorer, and for Bedrock players through Geyser and Floodgate.
To show it, the server downloads each skin image from Mojang's skin server, textures.minecraft.net, over HTTPS, and keeps the images in plugins/ManukaModeration/skins/. Browsers get the image from the plugin and never contact Mojang. Set panel.skin-downloads: false when your host blocks outbound traffic or the server must not contact Mojang: nothing is downloaded, and the page shows a neutral silhouette instead.
Keyboard shortcuts #
Press ? in the panel for the list. Shortcuts are off while you type in a field.
| Key | Action |
|---|---|
/ | Focus the search or filter field |
j / k | Next / previous row in the cases list |
Enter | Open the selected case |
r / e / d | Mark reviewed / resolve / dismiss |
g then c | Go to cases |
g then l | Go to chat logs |
t | Switch between light and dark |
? | Show the shortcut help |
Security #
- Passwords are hashed with PBKDF2. Logins have rate limits and a lockout, and logins and staff actions are written to an audit log (
plugins/ManukaModeration/logs/audit-<date>.log). - Sessions use
HttpOnly; SameSite=Strictcookies (plusSecureover HTTPS), and every change carries a CSRF token./mm user setpasswordends every session of an account; on Pro, owners can also end sessions from the Users page. - Pages are served with a strict Content-Security-Policy,
X-Frame-Options: DENYandReferrer-Policy: no-referrer. Everything that comes from players is shown as plain text, never as HTML. - The one-time link from
/mm panelis removed from the address bar before it is used, so it does not stay in the browser history.
Customizing the files #
Any panel file can be replaced by putting a file with the same relative path in plugins/ManukaModeration/panel/ (for example panel/assets/logo.svg). Delete your copy to go back to the bundled file after an update.