- User-scoped API keys (Profile > API Keys) for 3rd-party REST API access
and MCP clients, each locked to one scope at creation, with expiry,
revocation, and last-used tracking.
- A hand-rolled MCP (Model Context Protocol) server exposing the fleet
(connections, nodes, guests, storage, pools, alerts, cluster status) as
read tools plus one admin-gated power-action tool, so Claude Code/Desktop
or any other MCP client can query and operate the fleet directly.
- Both the REST API and MCP are off by default and toggleable instance-wide
from Settings > API & MCP, enforced live on every request.
- Admin-managed AI providers (any OpenAI-chat-completions-compatible
endpoint) backing the AI Assistant's tool-calling loop, replacing the
single hardcoded provider.
- A built-in, zero-config, no-API-key local provider backed by Needle 2
(internal/needle) for fully offline tool-calling, wired in as a one-click
preset. Requires the operator to separately download the Needle 2 binary
and point FERRUM_NEEDLE_BIN at it -- Ferrum never fetches executable
content from the network itself; see README "Built-in LLM (Needle 2)".
- System settings (CORS allow-list, instance-wide toggles) moved to the
admin Settings UI; environment variables are now scoped to true
bootstrap-level config only (listen address, TLS, DB connection, secret,
optional Needle binary path).
- Fixed: node Journal tab 502'ing with "unexpected end of JSON input" on an
empty response, and separately with a decode error on PVE versions that
return a bare-string journal line instead of the documented {n,t} object.
- Fixed: bottom content padding disappearing on every page except the AI
Assistant (an unconditional h-full on the content wrapper let overflowing
content bleed through where the padding should render).
- Fixed: Profile page felt cramped despite a wide viewport (stray max-w-2xl
cap not present on the equivalent Settings page).
- Test coverage added for the previously-untested MCP package and the new
Needle adapter (20 new Go tests), plus a regression test for the journal
decode fix.
- OIDC: RP-Initiated Logout is now opt-in (default off) via a new
'single_logout' setting, with the exact post-logout redirect URL shown
in Settings for the admin to register at their provider. Fixes the
regression from last time: enabling it unconditionally broke sign-out
for anyone whose IdP hadn't been told to trust the redirect yet
(Keycloak's invalid_redirect_uri, browser stuck on a stale page).
- formatBytes shows up to 2 decimals (was an adaptive 0-or-1 rule); every
bytes/rate chart now computes a rounded 'nice' axis scale (0/5/10/15/20
GB, the standard Heckbert algorithm) and locks every tick + the tooltip
to one consistent unit derived from the axis's own max.
- Storage page: the capacity donut is now sized by used bytes + a free
remainder instead of by total capacity share, which was always 100%
the moment there was only one pool — completely disconnected from the
"224 GB used" text next to it.
- Topology: Export SVG (fits the full diagram regardless of current pan/
zoom) and a Snap-to-grid toggle.
- New Disks tab on the node detail page: every physical disk with model/
serial/size/type, PASSED/FAILED health, SSD/NVMe wearout %, and a
per-drive temperature read from SMART, plus a full SMART attribute
table per disk. Backed by new /nodes/{node}/disks and
/nodes/{node}/disks/smart endpoints.
- CPU/GPU temperature is not exposed by Proxmox's own API (no built-in
lm-sensors/nvidia-smi integration) and isn't something this can add
without a node-side agent Proxmox doesn't ship — disk temperature via
SMART is the thermal data actually available.
- .gitignore/.dockerignore: cover Go build artifacts, env files, logs,
editor/OS cruft, and local runtime data (sqlite db/secret, config.yaml).
- README: add a Screenshots section (captured against a mock Proxmox
cluster) and a Deploying a release build section.
- LICENSE: MIT.
Deployable binaries:
- cmd/ferrum: -version flag with build-time version/commit/date via
-ldflags; -log-file flag (Windows services don't capture stdout/stderr
the way systemd does); native Windows Service Control Manager support
(service_windows.go) so ferrum.exe manages its own start/stop lifecycle
under a Windows service, same graceful-shutdown path SIGTERM already used
on Linux.
- packaging/systemd/ferrum.service: hardened systemd unit.
- scripts/build.sh, build.ps1: cross-compile linux/windows/darwin x
amd64/arm64, package as .tar.gz/.zip with an install script and
checksums.txt.
- scripts/linux/install.sh, uninstall.sh: create a dedicated system user,
install the binary, seed /etc/ferrum/config.yaml, enable + start the
systemd service.
- scripts/get.sh: one-line curl-pipeable installer (get.docker.com style)
that resolves the latest release, verifies its checksum, and hands off
to install.sh.
- scripts/windows/install-service.ps1, uninstall-service.ps1: register/
remove the self-managing Windows service.
- .github/workflows/release.yml: publish all platform archives + checksums
as GitHub Release assets on a vX.Y.Z tag push.
- .github/workflows/ci.yml: go vet/build/test, frontend lint/test/build,
and shell-script syntax checks on push/PR.