Root cause of the recurring "Request failed" / 502 errors on delete and
other actions: the Proxmox client was sending a request body on DELETE
calls, which Proxmox's API rejects outright. Params now go on the query
string instead, fixing delete for guests and replication jobs alike.
Other fixes:
- Guest console/shell errors now show Proxmox's actual message instead of
a generic failure, so a permission or lock issue is visible instead of
guessed at.
- Opening a console/shell popup no longer wastes the small window Proxmox
gives to claim a session ticket on the popup's own load time - the
ticket is requested only once the popup is ready to use it.
- An LXC container with an interface that has no IP address was crashing
the guest detail view ("Cannot read properties of null"). The backend
was sending a null array instead of an empty one; fixed at the source
plus a few related spots that had the same latent risk.
- The template upload dialog had broken spacing between its fields.
- Settings page: the "About" section could never show as active in the
sidebar nav because of how the scroll position was measured.
New:
- Direct SSH shell access from Inventory and node pages, independent of
Proxmox's own console/shell (useful when that's unreliable or
unavailable). Connections can now store SSH credentials (password or
private key) so this connects with one click instead of typing them in
each time.
- Network interfaces in a guest's Hardware tab are now editable as
separate fields (bridge, VLAN, IP, gateway, firewall, etc.) instead of
one raw text value, matching how Proxmox's own UI presents them. LXC
containers can also have their DNS nameserver/search domain set from
the same tab, and other hardware config keys can now be edited through
the same endpoint.
- 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.