Units · loads · bills · solar · hedges · mining
The energy desk for your AI agent.
- Convert units, measure loads and price bills on your own tariff
- Set the price cap, budget, carbon and approval rules your agent follows
- Shift jobs to cheaper hours, size solar and storage, and check contract math
Customize
Your price cap, carbon and approval rules, in one file.
22 settings in 5 groups. Start from a preset, change anything, and your settings are written into ENERGY.md. Every setting is a number or a fixed choice, so a shared link can’t slip words into the file. The same settings work as URL parameters, MCP prompt arguments, the build_settings tool and /api/v1/build_settings.
Approval level, missing prices, the shift rule and the fixed rules: no trading, no contracts signed, licensed electrical work. Everything else follows the skill's defaults.
Prices you set
Your price cap, monthly budget and when to ask. Prices come from you, never from us.
Set by the person you work for, and only that person can change them. Rules an agent drafted count only after that person says yes. Where a rule here and the rest of this file differ, the rule wins. If a rule blocks the task, stop and ask; don't work around it. Every price, tariff and factor in your work comes from the person or their own records.
mkdir -p ~/.claude/skills/energy && curl -fsSL "https://energy.md/energy.md?approval_usd=100&missing_prices=ask&electrical_work=licensed_only&shift_flexible=ask&contracts=never&trading=never" -o ~/.claude/skills/energy/SKILL.mdhttps://energy.md/energy.md?approval_usd=100&missing_prices=ask&electrical_work=licensed_only&shift_flexible=ask&contracts=never&trading=neverCopy as JSON
The same settings as one JSON object. It feeds the build_settings tool or POST /api/v1/build_settings.
6 of 22 settings set. Anything not set follows the skill’s own rules.
Tools
Energy math your agent can call.
Units, loads and bills, load shifting, solar and storage, fixed vs floating prices, generation cost and flexible loads like mining. Every tool works only on the numbers you send and shows its formula. Run them here, or call them over HTTP or MCP. They calculate and compare; they never buy, sign or trade anything.
{
"devices": [
{
"label": "GPU server",
"count": 2,
"watts": 1500,
"hours_per_day": 24,
"duty": 0.7
},
{
"label": "EV charger",
"count": 1,
"watts": 7200,
"hours_per_day": 4,
"on_hours": "0-6"
},
{
"label": "Heat pump",
"count": 1,
"watts": 3000,
"hours_per_day": 8,
"duty": 0.6,
"on_hours": "6-22"
}
],
"overhead_factor": 1.1,
"days": 30,
"tariffs": [
{
"label": "Flat",
"fixed_usd_per_month": 15,
"flat_usd_per_kwh": 0.16
},
{
"label": "Time of use",
"fixed_usd_per_month": 15,
"flat_usd_per_kwh": 0.14,
"tou": [
{
"label": "Peak",
"hours": "16-21",
"usd_per_kwh": 0.32
},
{
"label": "Night",
"hours": "0-6",
"usd_per_kwh": 0.08
}
]
}
],
"grid_kg_co2e_per_kwh": 0.4
}curl -s https://energy.md/api/v1/load_energy -H 'content-type: application/json' -d '{"devices":[{"label":"GPU server","count":2,"watts":1500,"hours_per_day":24,"duty":0.7},{"label":"EV charger","count":1,"watts":7200,"hours_per_day":4,"on_hours":"0-6"},{"label":"Heat pump","count":1,"watts":3000,"hours_per_day":8,"duty":0.6,"on_hours":"6-22"}],"overhead_factor":1.1,"days":30,"tariffs":[{"label":"Flat","fixed_usd_per_month":15,"flat_usd_per_kwh":0.16},{"label":"Time of use","fixed_usd_per_month":15,"flat_usd_per_kwh":0.14,"tou":[{"label":"Peak","hours":"16-21","usd_per_kwh":0.32},{"label":"Night","hours":"0-6","usd_per_kwh":0.08}]}],"grid_kg_co2e_per_kwh":0.4}'Why
Agents mix up kW and kWh. Then they guess the price.
Ask an agent what a job will cost to run and it may confuse power with energy, skip the demand charge, or use a price it found somewhere. ENERGY.md gives it one method: units first, then the load, then your tariff, with your price cap, carbon factor and approval rules written in. The calculators do the arithmetic the same way every time and show the formula, so you can check it.
- Your prices only: tariffs, quotes and price curves come from you. We show no prices and no market data.
- Power is not energy: kW times hours is kWh. The tools flag a likely mix-up instead of guessing.
- A person signs: your agent never signs supply contracts, hedges or trades. It prepares the numbers.
- Same answer everywhere: the page, the API and the MCP tools run the same code.
- Nothing stored: requests are answered and forgotten.
Use it in your stack
Paste it, install it, or call it.
The skill alone gives an agent the method. The MCP server and API add the tools and your settings. No key, no account.
Paste the prompt into a system prompt or project instructions. Or keep the file in the repo and point AGENTS.md at it.
curl -fsSL https://energy.md/energy.md -o ENERGY.mdecho "Whenever a task converts energy units, measures or prices a load, schedules a flexible job, sizes solar or batteries, compares supply contracts or hedges, works out generation cost, or runs mining or another flexible load, follow ENERGY.md." >> AGENTS.mdFor agents that read a skills folder: install the skill so it loads when the topic comes up, and add the MCP server for the tools.
# The skillmkdir -p ~/.claude/skills/energycurl -fsSL https://energy.md/energy.md -o ~/.claude/skills/energy/SKILL.md# Tools: load_energy, shift_load, solar_storage, hedge_math, generation_cost, mining_power, energy_units, build_settingsclaude mcp add --transport http energy https://energy.md/mcpFor editors that read an mcp.json file: add the remote MCP server to the project, then paste the prompt into your rules.
// .cursor/mcp.json{ "mcpServers": { "energy": { "url": "https://energy.md/mcp" } } }// .vscode/mcp.json{ "servers": { "energy": { "type": "http", "url": "https://energy.md/mcp" } } }Any client that speaks remote MCP over HTTP can add it as a custom connector. Read-only, so there is nothing to authorize.
url: https://energy.md/mcptransport: streamable-http # stateless, JSON responsestools: load_energy, shift_load, solar_storage, hedge_math, generation_cost, mining_power, energy_units, build_settingsprompts: energy # the skill, with your settingsGET with query parameters or POST a JSON body. CORS open. An OpenAPI document is at /openapi.json.
# Every tool: GET or POST https://energy.md/api/v1/<tool>curl -s https://energy.md/api/v1 | jq '.tools[].name'curl -s "https://energy.md/api/v1/solar_storage?daily_load_kwh=30&peak_sun_hours=5&system_losses=0.14&offset_share=0.8&evening_shift_kwh=10&backup_hours=8&backup_load_kw=1.5&install_usd_per_w=2.5&battery_usd_per_kwh=700&incentive_share=0.3&tariff_usd_per_kwh=0.25&export_usd_per_kwh=0.05&self_consumption_share=0.85&discount_rate=0.05" | jq .summarycurl -s "https://energy.md/api/v1/settings" | jq '.presets[].id'claude mcp add --transport http energy https://energy.md/mcpExample code
Call it from your own code.
Working calls against the API. The full reference is at /api/v1 and /openapi.json.
Convert units, then measure a load and price it on two of your tariffs. No key; nothing is stored.
# Convert units, then measure a load and price it on two of your tariffs. No key; nothing is stored.API=https://energy.md/api/v1# Energy units: 1,500 kWh in MMBtu (and 5 kW for 8 hours in kWh)curl -s "$API/energy_units?value=1500&from=kWh&to=MMBtu" | jq .summarycurl -s "$API/energy_units?value=5&from=kW&to=kWh&hours=8" | jq .summary# A load: kWh per day, month and year, peak kW, load factor, a bill per tariff, emissions.# Prices and the grid factor are your own; these are round illustrative numbers, not market data.# on_hours (8:00 to 18:00 for the office) makes the time-of-use split and the demand charge exact.curl -s $API/load_energy -H 'content-type: application/json' -d '{ "devices": [ { "label": "GPU server", "count": 4, "watts": 1500, "hours_per_day": 24, "duty": 0.8 }, { "label": "office", "count": 1, "watts": 2000, "hours_per_day": 10, "on_hours": "8-18" } ], "overhead_factor": 1.2, "days": 30, "tariffs": [ { "label": "flat", "fixed_usd_per_month": 20, "flat_usd_per_kwh": 0.15 }, { "label": "time of use", "fixed_usd_per_month": 20, "demand_usd_per_kw": 8, "tou": [ { "label": "peak", "hours": [16, 17, 18, 19, 20], "usd_per_kwh": 0.3 }, { "label": "off-peak", "hours": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 21, 22, 23], "usd_per_kwh": 0.1 } ] } ], "grid_kg_co2e_per_kwh": 0.4}' | jq '{summary, not_checked}'A flexible load that can stop: margin, break-even power price and the hours to run under your 24 prices.
// A flexible load that can stop: margin, break-even power price and the hours to run under your 24 prices.const API = "https://energy.md/api/v1";// Revenue per TH per day and prices are your own figures. These are round illustrative// numbers, not market data, a price or a quote, and not any particular machine.const prices = [0.06, 0.05, 0.05, 0.04, 0.04, 0.05, 0.07, 0.09, 0.1, 0.09, 0.08, 0.07, 0.07, 0.08, 0.1, 0.12, 0.16, 0.2, 0.24, 0.22, 0.16, 0.12, 0.09, 0.07];const res = await fetch(`${API}/mining_power`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ machines: 10, hashrate_th_per_machine: 100, efficiency_j_per_th: 25, overhead_factor: 1.05, power_usd_per_kwh: 0.08, revenue_usd_per_th_day: 0.1, prices_usd_per_kwh: prices, }),});const out = await res.json();if (!res.ok) throw new Error(`${out.error ?? res.status}`);console.log(out.summary);// On these numbers: 26.25 kW, 630 kWh/day, $49.60 daily margin, break-even $0.1587/kWh;// it runs 19 of 24 hours (hours 16-20 stop) for a $41.37 margin.// Curtail in every hour priced above the break-even. Switching machines is your own control system's job.Before a flexible job runs: find its cheapest and cleanest hours over MCP, under your price cap.
// Before a flexible job runs: find its cheapest and cleanest hours over MCP, under your price cap.const MCP = "https://energy.md/mcp";async function call(name: string, args: Record<string, unknown>) { const res = await fetch(MCP, { method: "POST", headers: { "content-type": "application/json", accept: "application/json" }, body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "tools/call", params: { name, arguments: args } }), }); const { result } = await res.json(); if (result.isError) throw new Error(result.content[0].text); return result.structuredContent;}// Your own 24 hourly prices ($/kWh) and carbon factors (kg CO2e/kWh) for today.// Round example numbers; use the ones from your tariff and your grid data.const prices = [0.12, 0.11, 0.1, 0.1, 0.1, 0.11, 0.14, 0.18, 0.2, 0.16, 0.12, 0.09, 0.08, 0.08, 0.09, 0.12, 0.22, 0.3, 0.34, 0.32, 0.26, 0.2, 0.16, 0.13];const carbon = [0.45, 0.44, 0.43, 0.43, 0.44, 0.45, 0.42, 0.38, 0.33, 0.28, 0.24, 0.21, 0.2, 0.2, 0.22, 0.27, 0.34, 0.41, 0.46, 0.47, 0.47, 0.46, 0.46, 0.45];const plan = await call("shift_load", { energy_kwh: 60, // a batch job or a car to charge max_power_kw: 20, earliest_hour: 6, deadline_hour: 18, start_now_hour: 6, interruptible: true, max_price_usd_per_kwh: 0.25, // your cap: hours above it are never used prices_usd_per_kwh: prices, carbon_kg_per_kwh: carbon,});console.log(plan.summary);// A result is arithmetic, not an approval: if your rules say "ask first", show the plan and wait.Size solar and a backup battery, with payback and NPV on your own costs. A first estimate, not a design.
# Size solar and a backup battery, with payback and NPV on your own costs. A first estimate, not a design.# Installs, permits and grid connection approval are for licensed professionals. Round example numbers.curl -s https://energy.md/api/v1/solar_storage -H 'content-type: application/json' -d '{ "daily_load_kwh": 30, "peak_sun_hours": 4.5, "offset_share": 0.8, "backup_hours": 8, "backup_load_kw": 1.5, "install_usd_per_w": 2.5, "battery_usd_per_kwh": 600, "incentive_share": 0, "tariff_usd_per_kwh": 0.2, "export_usd_per_kwh": 0.05, "self_consumption_share": 0.7, "years": 25, "discount_rate": 0.06}' | jq '{summary, not_checked, note}'Fixed vs floating supply, hedge settlement and generation cost: educational arithmetic on your numbers.
# Fixed vs floating supply, hedge settlement and generation cost: educational arithmetic on your numbers.API=https://energy.md/api/v1# A fixed offer you received vs your own floating scenarios, 70% hedgedcurl -s $API/hedge_math -H 'content-type: application/json' -d '{ "volume_mwh": 1000, "fixed_usd_per_mwh": 60, "hedge_ratio": 0.7, "scenarios_usd_per_mwh": [40, 60, 90], "adder_usd_per_mwh": 2}' | jq '{summary, not_checked}'# Simple LCOE in parts, plus the spark spread at your power pricecurl -s "$API/generation_cost?capacity_mw=100&capacity_factor=0.55&capex_usd_per_kw=1000&fixed_om_usd_per_kw_year=20&variable_om_usd_per_mwh=3&fuel_usd_per_mmbtu=3&heat_rate_btu_per_kwh=7000&discount_rate=0.07&life_years=30&power_usd_per_mwh=45" \ | jq '{summary, formula}'FAQ
Does it buy power, sign contracts or trade?
Where do the prices come from?
Can it size solar, a battery or a generator?
Is the hedge math a trading signal?
Does it work for servers, GPUs and mining?
Is this advice?
Does it name brands or show prices?
Can an agent set up its own settings?
build_settings tool. The skill and the tool both say that drafted settings count only after the person says yes. Nothing technical stops an agent from ignoring that, so read what it sends you.