NeoServer picks up CPU temperature automatically on most Linux hosts: it tries sensors from lm-sensors, AMD Tctl, and the kernel’s hwmon/thermal zones in /sys. On a Mac, the temperature row stays empty. That is not a bug — macOS simply exposes no standard sensor interface over SSH. One small command deployed on the Mac closes the gap, and this post shows exactly how the mechanism works.
Why the Mac temperature metric is empty
NeoServer’s built-in temperature sources are Linux-specific: there is no lm-sensors, no /sys/class/hwmon, no /proc on macOS. A Mac’s CPU temperature sits behind the System Management Controller (SMC), and Apple ships no command-line tool that reads it. Worse, popular community tools such as osx-cpu-temp do not support Apple Silicon. The reliable open-source reader for Apple Silicon CPU temperature is smctemp, which talks to the AppleSMC IOService directly.
The neo_get_temp contract
On every non-Windows host, NeoServer probes for a custom temperature fetcher before falling back to the Linux sources:
if command -v neo_get_temp >/dev/null 2>&1; then neo_get_temp; else echo NEO_NO_CMD; fi
The contract for neo_get_temp is deliberately minimal:
- Output one integer, the CPU temperature in °C multiplied by 1000.
45000means 45.0 °C. - No labels, no units, no extra lines.
Three outcomes follow from the protocol:
| State | Result |
|---|---|
| Valid integer | Temperature is displayed |
Script not installed (NEO_NO_CMD) | Linux fallbacks apply — and on macOS they find nothing, so the metric stays hidden |
Installed but prints garbage, null or nothing | Temperature is hidden and fallbacks are skipped — the script’s output is authoritative once installed |
Two implementation details are worth knowing. The parser is forgiving about format: a bare whole-degree reading like 45 is also accepted and multiplied internally, multi-line output is resolved by taking the highest valid line, and anything above 200 °C is discarded as bogus. Stick to the ×1000 format anyway, because it is unambiguous. Also, never make the script print a made-up constant — a fabricated number is indistinguishable from a real sensor reading, as the NeoServer FAQ warns.
One practical detail saves you PATH headaches: NeoServer prepends export PATH=$PATH:/opt/homebrew/bin:...:/usr/local/bin:... before running the probe. Even a non-interactive SSH session will find the script in those directories.
Install on the Mac
On the Mac you want to monitor, install smctemp first:
which smctemp || brew install narugit/smctemp/smctemp
smctemp -c prints a plain Celsius reading such as 48.6. Deploy the wrapper as neo_get_temp:
cat > /opt/homebrew/bin/neo_get_temp <<'EOF'
#!/bin/bash
smctemp -c | awk '{printf "%d\n", $1*1000}'
EOF
chmod +x /opt/homebrew/bin/neo_get_temp
Prefer /opt/homebrew/bin: it is the Homebrew standard directory on Apple Silicon, writable without sudo, and on the probe’s PATH. On an Intel Mac, /usr/local/bin is on the PATH too. Then verify:
neo_get_temp
48600
Confirm from NeoServer
Enable Remote Login in System Settings on the Mac, add the host in NeoServer, and refresh the metrics page — the temperature row now appears. The quickest end-to-end test runs from any other machine:
ssh user@your-mac 'neo_get_temp'
If that prints a number over SSH, NeoServer will show it.
Troubleshooting
- Temperature still missing: run the
sshone-liner above. If it fails, check that the file is executable and located in one of the directories NeoServer adds to PATH. smctemp -cerrors out: the wrapper then prints nothing, and NeoServer hides the temperature by design rather than guessing.- Readings look wrong: run
smctemp -cdirectly and compare. Do not patch the script to echo a constant — fix the source instead.
With the script in place, a Mac behaves like any other monitored host: CPU temperature shows up next to load, memory and disk, both in the app and in server widgets.
Ready to try it?
NeoServer · SSH, Mosh, Docker & SFTP client for iPhone, iPad and Mac
Free on the App Store