heatgate
electron-flow heat throttle: pauses heavy work when the CPU is hot and resumes it when it cools.
pipx install heatgate # or: pip install heatgate
A tiny, zero-dependency Python throttle that slows work down when the machine is "hot".
Why load instead of temperature? Cloud VMs usually hide thermal sensors (/sys/class/thermal is empty,
psutil.sensors_temperatures() returns nothing). What a VM can see is how busy its CPUs are. Busy CPUs are
what make the host chip hot, so heatgate uses CPU load as a stand-in for heat.
How heat is computed
heat = max(load1 / cores, cpu_utilization [, (temp_C - 40) / 50 if a sensor exists])
load1comes from/proc/loadavg(falls back toos.getloadavg()).cpu_utilizationis the busy fraction from two/proc/statsamples taken 0.2 s apart.- If
/sys/class/thermal/thermal_zone*/tempor psutil sensors ever show up, they are added in. If not, they are skipped.
0.0 means idle and 1.0 means every core is saturated.
Install
pip install heatgate # or: pipx install heatgate / uvx heatgate status
pip install git+https://github.com/fitzyracing1/heatgate # from source
Demo
In a real run wrapping a CPU-saturating job, heatgate run --high 0.8 --low 0.5 went through 12 pauses and
12 resumes. It paused at about 100% load and resumed at about 20%, so the job ran in a duty cycle and
the box never stayed pinned.
Use it from any AI
heatgate includes a zero-dependency stdio MCP server: heatgate mcp. It exposes these tools:
| tool | what it does |
|---|---|
heat_status |
heat, load1, cores, cpu, temp_c |
should_pause |
{pause: heat >= high} |
recommended_workers |
worker count scaled down by heat |
run_throttled(cmd) |
runs a shell command under heatgate run. Disabled unless HEATGATE_ALLOW_RUN=1 |
Claude Desktop (claude_desktop_config.json) and Cursor (~/.cursor/mcp.json or .cursor/mcp.json) use the same shape:
{
"mcpServers": {
"heatgate": {
"command": "uvx",
"args": ["heatgate", "mcp"],
"env": { "HEATGATE_ALLOW_RUN": "0" }
}
}
}
Set "HEATGATE_ALLOW_RUN": "1" only if you want the AI to be able to launch commands. With pipx, use
"command": "pipx", "args": ["run", "heatgate", "mcp"]. If heatgate is already installed, use "command": "heatgate", "args": ["mcp"].
Grok / Grok Bot: add a custom MCP server (stdio) with command uvx heatgate mcp (or pipx run heatgate mcp).
Add env HEATGATE_ALLOW_RUN=1 only if you want it to run jobs.
ChatGPT and other MCP clients: any client that can launch a local stdio MCP server works with the same
command, uvx heatgate mcp. Clients that only accept remote (HTTP) servers need a stdio-to-HTTP bridge,
for example npx -y supergateway --stdio "uvx heatgate mcp".
Agents without MCP: load skills/heatgate/SKILL.md, a plain instructions file that
covers install, checking heat, and wrapping heavy jobs.
Python API
import heatgate
heatgate.heat() # -> 0.0..1.0+
with heatgate.Gate(high=0.8, low=0.5): # blocks while heat >= 0.8, until it drops below 0.5
do_work()
for batch in batches:
heatgate.pace(high=0.8, low=0.5, max_sleep=5) # no sleep below low, up to max_sleep at/above high
process(batch)
@heatgate.throttled(high=0.8, low=0.5)
def step(): ...
from concurrent.futures import ProcessPoolExecutor
with ProcessPoolExecutor(heatgate.workers(max_workers=8)) as ex: # fewer workers when hot
...
CLI
heatgate status # heat=0.10 load1=0.78 cores=8 load/core=0.10 cpu=1% temp=n/a (hidden)
heatgate status --json
heatgate run [--high 0.8] [--low 0.5] [--poll 1] -- <cmd...>
heatgate mcp # stdio MCP server
run starts the command in its own process group. When heat reaches high, it sends SIGSTOP to the whole group.
When heat falls below low, it sends SIGCONT. Each transition is logged to stderr, and the run ends with a summary
of pause/resume counts and heat min/avg/max. Ctrl-C and SIGTERM are passed on to the child, which is resumed first.
Note: if the child is the only thing loading the box, it will cycle: it runs until the box is hot, gets paused,
the box cools, and it resumes. The effect is a duty cycle. If you want fewer transitions, widen the gap between
high and low or raise --poll.
Wrapping the marslog heat training
The marslog repo has a training entrypoint (marslog/heat.py, run with python -m marslog.heat train).
heatgate does not change it. To run it under heatgate:
cd marslog && heatgate run --high 0.8 --low 0.5 -- python -m marslog.heat train
License
MIT
Metadata
Release files for heatgate 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| heatgate-0.1.0.tar.gz | 9.8 kB | Without provenance | Details for heatgate-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| heatgate-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for heatgate-0.1.0-py3-none-any.whl |
Total release size: 19.6 kB
Release files / heatgate-0.1.0.tar.gz
| Download URL | heatgate-0.1.0.tar.gz |
|---|---|
| Size | 9.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8794302976d7f24e6665dd6fd03f12105caf669662eeb71b42aa4a39588dd614
|
|
BLAKE2b-256 checksum How to use checksums |
b4112e43b111d4bbd89be31a7e578ebe10fc6ec2d0698be7c1134573bd1d50ba
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.5
|
Release files / heatgate-0.1.0-py3-none-any.whl
| Download URL | heatgate-0.1.0-py3-none-any.whl |
|---|---|
| Size | 9.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
78479d5862e37817f505f5164c5585fd12c0a4afb971f338d16a700824433e55
|
|
BLAKE2b-256 checksum How to use checksums |
adf7e8b0a3117de1407a955cca7dc59aefd2ac49a3a510822f5943ce62553f57
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.5
|
Security for heatgate 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.