thermo-control-mcp
This server lets you monitor and control your Mac's thermal management (fan speeds and temperatures) through an MCP-compatible AI client.
Monitor thermal status: Read real-time per-sensor temperatures (CPU, GPU, memory), fan RPM (actual/target/min/max), fan mode, power draw in watts, current fan control state (manual vs. auto), and remaining TTL on any active manual setting. Thermal status can be read even without the root daemon installed.
Diagnose heat sources: Identify top CPU-consuming processes to pinpoint sources of heat.
Set fan speed manually: Put fans into manual mode using either absolute RPM or a percentage (0–100%) of each fan's min-to-max hardware range. Target all fans or a specific fan by index, with a configurable TTL (10s–7200s) after which fans automatically revert to system control.
Boost fans to maximum: Instantly ramp all fans to 100% for a configurable duration (default 600s, max 7200s) — useful for pre-cooling before intensive workloads.
Return fans to system control: Immediately release manual fan control and hand thermal management back to macOS.
Built-in safety guarantees (enforced by the root daemon):
All manual settings expire via a dead-man TTL switch (max 2 hours).
A hardcoded 102°C thermal failsafe automatically reverts fans to system control if any sensor overheats.
Fan RPM is always clamped to the hardware's safe min/max range.
Fans revert to system control if the daemon stops or the machine reboots.
Designed for Apple Silicon Macs (M1–M5), with dynamic sensor discovery that adapts to different Mac models.
Provides tools for monitoring Mac thermal status and controlling fan speed, including setting manual fan speeds with safety limits and automatic reversion.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@thermo-control-mcpI'm about to run a 20-minute build. Keep the machine cool."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
thermo-control-mcp
English | 한국어
An MCP server that lets Claude Code (or any MCP client) monitor your Mac's thermals and control fan speed — with a root daemon that enforces safety limits no matter what the LLM asks for.

A true story: the battery menu blamed "Terminal", Claude found a runaway language server, boosted the fans, and handed control back. (Rendered with Remotion — source in demo/.)
You: "I'm about to run a 20-minute Rust build. Keep the machine cool."
Claude: [get_thermal_status] → CPU 58°C, fans on system control
[set_fan_speed percent=80 ttl_seconds=1500] → fans spin up before the heat arrives
... build runs without thermal throttling ...
[set_fan_auto] → back to macOS controlWorks on Apple Silicon (M1–M5, including the M3/M4 firmware lock — see How it works). Reading thermals requires no privileges; fan control uses a small root LaunchDaemon.
Why
macOS ramps fans reactively — by the time they spin up, the CPU has already been throttling. An LLM agent knows in advance when it's about to start a heavy build, test suite, or local inference job. This server lets it pre-cool the machine, hold higher fan speeds through sustained load, and hand control back when done.
Related MCP server: MCP Experiments
Architecture
Claude Code ── stdio ──> MCP server (Node, unprivileged)
│
├─ reads (temps/RPM/power) ─── works even without the daemon
│
└─ unix socket /var/run/thermod.sock (root:admin 0660)
│
thermod daemon (root, launchd)
├─ SMC access via IOKit (AppleSMC)
├─ M3/M4 Ftst unlock sequence
└─ SAFETY POLICY (hardcoded):
· TTL dead-man switch
· 102°C thermal failsafe
· RPM clamped to hardware range
· revert-to-auto on daemon exitThe safety policy lives in the root daemon, not in the MCP layer the LLM talks to. The LLM can ask; the daemon decides.
Safeguard | Behavior |
Dead-man switch | Every manual setting carries a TTL (default 15 min, max 2 h). When it expires — or the daemon stops, or the machine reboots — fans revert to macOS control. Agents must re-request to keep control. |
Thermal failsafe | If any die sensor reaches 102°C while under manual control, the daemon abandons manual mode and returns fans to the system immediately. Not configurable over the socket. |
RPM clamping | Requested speeds are clamped to the fan's hardware-reported |
Sleep/wake handling | Firmware drops manual control across sleep; the daemon re-asserts it only if a valid, unexpired request is still active. |
Local-admin only | The control socket is |
Requirements
Apple Silicon Mac with fans (MacBook Air has none). Intel Macs may work (the legacy
fpe2format is implemented) but are untested.macOS 13+
Xcode Command Line Tools (
xcode-select --install) — for building the Swift daemonNode.js 18+
Install
There are two components: the MCP server (npm) and the thermod daemon (built from this repo — it's a root LaunchDaemon, so it intentionally never ships as a prebuilt binary; you build what you run).
git clone https://github.com/june4432/thermo-control-mcp.git
cd thermo-control-mcp
# 1. Build + register the MCP server
npm install && npm run build
# 2. Build + install the root daemon (asks for your password)
sudo ./scripts/install.sh
# 3. Register with Claude Code
claude mcp add thermo-control -- node "$(pwd)/dist/index.js"If you prefer the MCP server from npm (still needs step 2 above for fan control):
npm install -g thermo-control-mcp
claude mcp add thermo-control -- thermo-control-mcpWithout step 2, get_thermal_status still works (SMC reads are unprivileged); the control tools return an explanatory error.
Uninstall with sudo ./scripts/uninstall.sh — fans revert to system control.
MCP tools
Tool | What it does |
| Per-sensor die temperatures (CPU/GPU/memory), fan RPM/mode/range, power draw (W), current control state and remaining TTL. |
| Diagnose why the machine is hot: temperature summary plus the top CPU-consuming processes (with cumulative CPU time vs uptime, so runaways stand out). Breaks down what macOS's battery menu lumps together as "Terminal". |
| Manual mode at |
| All fans to 100% for |
| Release manual control back to macOS immediately. |
You can also poke the daemon directly:
echo '{"cmd":"status"}' | nc -U /var/run/thermod.sock | python3 -m json.tool
echo '{"cmd":"set","percent":70,"ttl_seconds":300}' | nc -U /var/run/thermod.sock
echo '{"cmd":"auto"}' | nc -U /var/run/thermod.sockAnd read thermals with no daemon at all: daemon/.build/release/thermod status.
How it works
Fan state lives in SMC keys (FNum, F0Ac actual RPM, F0Tg target, F0Mn/F0Mx range, F0Md mode, all floats little-endian on Apple Silicon), accessed from userspace through the AppleSMC IOKit service. Reads are allowed for any process; writes require root — enforced per-key by the SMC firmware itself.
On M3/M4 machines there is an extra gate: thermalmonitord holds the fans in "system mode" (mode 3) and the firmware rejects manual-mode writes with error 0x82. The daemon uses the community-documented unlock: try the direct write first (sufficient on M1/M2/M5 and Intel); on rejection, write the Ftst (force-test) diagnostic flag to 1, which suppresses thermalmonitord's reclaim logic, then retry the mode write until it lands (typically 3–6 s). Ftst must stay set while manual control is held — one of the reasons this is a persistent daemon rather than a one-shot CLI. The firmware clears Ftst across sleep/wake; the daemon detects and re-asserts.
Mode-key casing changed on M5 (F0md), and Ftst no longer exists there — both are probed at runtime. Pre-T2 Intel Macs have no mode key at all; there the legacy FS! force-bitmask is used instead.
Temperature sensors are discovered dynamically: the daemon enumerates the SMC's full key list (#KEY + read-by-index) and keeps every T… key that decodes as a plausible temperature — 291 sensors on an M4 Pro versus ~20 in a hand-curated list. This covers every chip variant (base/Pro/Max/Ultra) and future generations without per-model tables; curated catalogs only contribute friendly names where known. Values decode by declared SMC type (flt, sp78, fpe2, ui8/16/32), which also makes Intel's signed 7.8 fixed-point temperatures read correctly.
Credit where due: the unlock mechanism and much of the protocol behavior were documented by agoodkind/macos-smc-fan (via decompilation of thermalmonitord and AppleSMC.kext), with additional reference from raminsharifi/MacFanControl, the VirtualSMC SDK, and the Asahi Linux SMC docs. This project implements the protocol independently in Swift (MIT-licensed references only).
Compatibility
Hardware | Status |
M4 Pro ( | Verified end-to-end — 291 sensors discovered, manual fan control (2.3k→6.2k RPM), TTL dead-man revert observed live, via both the socket and MCP tools |
M1 / M2 / M3 / M5 | Implemented per documented behavior (direct mode write on M1/M2/M5, |
Intel (T2) | Direct mode write + |
Intel (pre-T2) | Legacy |
MacBook Air | No fans — status works, control does not apply |
Caveats
Don't run this alongside Macs Fan Control, TG Pro, or similar — two controllers will fight over the same SMC keys.
The
Ftstunlock is an undocumented Apple mechanism. A macOS update could change or remove it. Re-verify after major OS updates.Setting fans low under load is protected by the failsafe, but the failsafe is a backstop, not a thermostat. The intended use is raising fan speed, not silencing a hot machine.
macOS firmware retains its own independent thermal protection (throttling, emergency shutdown) regardless of this tool.
Disclaimer
This software manipulates system thermal management using undocumented interfaces. It ships with safety mechanisms, but you use it at your own risk. The authors are not responsible for hardware damage.
License
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/june4432/thermo-control-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server