Architecture
mcidrac is deliberately small: a TOML registry, a pure-stdlib Redfish client, and a FastMCP server whose 27 tools are thin, honest wrappers. The interesting decisions are below the tools.
The shape
Section titled “The shape”Every tool call opens its own session and closes it — no pooling, no long-lived state. That trades a little latency for a property worth more on BMCs: the server can crash, restart, or run in parallel without leaking sessions into the iDRAC’s small pool.
Sessions, not Basic auth
Section titled “Sessions, not Basic auth”Redfish accepts per-request HTTP Basic, and mcidrac doesn’t use it, for
two iDRAC-specific reasons. First, repeated failed Basic attempts count
toward the iDRAC’s IP-block lockout — an innocent retry loop can lock
out the whole management workstation. Second, one inventory call makes
a dozen GETs; a token session amortizes authentication across all of
them. Login POSTs to /redfish/v1/SessionService/Sessions, every exit
path DELETEs the session URI, and a cleanup failure never masks the
error that mattered.
A per-host semaphore caps the server at 3 concurrent sessions per iDRAC — the BMC allows roughly 8 total, shared with web UI tabs and everyone else’s scripts, and a parallel fleet sweep shouldn’t be the thing that exhausts it.
One exception type
Section titled “One exception type”Everything below the transport raises RedfishError, full stop. HTTP
errors, TLS problems, half-open connections, timeouts, malformed
responses — all normalized at the one layer that has context, with
Dell’s @Message.ExtendedInfo diagnostics lifted into the message
(that’s where the useful text lives, not the status line). Tools and
resource wrappers rely on this invariant instead of defensively
catching stdlib exception zoo members.
Compatibility posture
Section titled “Compatibility posture”Fixed resource identities (System.Embedded.1, iDRAC.Embedded.1)
are hardcoded — they’re stable across iDRAC9 and iDRAC10. Where the
tree varies by generation or firmware, the client adapts: $expand
with per-member fallback for pre-4.10 firmware, pagination drained via
nextLink, virtual media discovered by MediaTypes with a
Manager-then-System path fallback (iDRAC10 deleted the old location),
and the deprecated-but-universal Thermal/Power resources over the
newer per-sensor collection. The full ledger is in
Firmware quirks.
Why stdlib only
Section titled “Why stdlib only”The sole dependency is FastMCP. Redfish is JSON over HTTPS;
urllib.request covers it, and every dependency not taken is a supply
chain and packaging problem not acquired. The cost — writing a session
manager and a task poller by hand — bought exact control over the two
things that matter most here: guaranteed logout and honest error
surfaces.