ebb-ai — carbon-aware MCP scheduler
LocalAbout ebb-ai — carbon-aware MCP scheduler
@tidegap/mcp is an MCP server that schedules non-urgent LLM tasks for lower-carbon grid hours before a deadline, using a provider Batch API when time allows. It is intended for agent workflows that can defer work based on electricity emissions.
Key features
- 01Schedule lower-carbon windows before deadlines
- 02View grid carbon-intensity forecasts
- 03Manage queued tasks and deadlines
- 04Cancel, postpone, and retry tasks
- 05Create a carbon receipt per task
Use cases
- 01Defer an LLM task requested for overnight
- 02Find a lower-carbon window before a deadline
- 03Review queue status and task receipts
MCP support
The server exposes 12 tools to MCP clients over stdio, including grid forecasts, window recommendations, and task scheduling.
Configuration
Local server config is the same for every client. Copy it into your client’s MCP config file.
npx -y @ebb-ai/mcpEBB_DEFAULT_REGIONDefault grid region, e.g. GB, US-CAL-CISO, DEEBB_DB_PATHSQLite queue path (default ~/.ebb-ai/queue.db)ANTHROPIC_API_KEYSecretDispatch tasks to Anthropic (sync or Batch API)OPENAI_API_KEYSecretDispatch tasks to OpenAI (sync or Batch API)EBB_EIA_API_KEYSecretUS EIA grid data (CAISO, ERCOT, ISO-NE, PJM), free keyEBB_ENTSOE_SECURITY_TOKENSecretENTSO-E grid data (EU regions), free tokenWATTTIME_USERNAMEWattTime account (US marginal emissions)WATTTIME_PASSWORDSecretWattTime account passwordEBB_ELECTRICITY_MAPS_API_KEYSecretElectricity Maps fallback feedLocal servers need a runtime on your machine (e.g. Node.js 18+). Config file locations differ by client; see your client’s docs.
Tools
9Saved tool list · updated 2w ago
| Parameter | Type | Required | Description |
|---|---|---|---|
| hours | integer | No | Forecast horizon in hours (1-72). Defaults to 24. |
| region | string | Yes | Electricity Maps grid zone code (e.g. 'US-CAL-CISO', 'US-TEX-ERCO', 'GB', 'FR', 'DE'). On hosts that allow omitting it, defaults to the configured region, else a host-timezone guess, else GB. |
Details
From the project README@tidegap/mcp
Renamed from
@ebb-ai/mcpin 0.18.0. Use the host config keytidegapandnpx -y @tidegap/mcp; theebb-mcpbin and theEBB_*variables were removed in 0.19. See Renamed from Ebb AI.
MCP server that lets your agent run non-urgent LLM tasks at the cleanest grid hour before a deadline.
Add it to any MCP host. When a user says "do this tonight" or "by tomorrow", the agent calls schedule_task. Tidegap then runs the task at the lowest-carbon grid hour before the deadline, and through the provider Batch API when the deadline allows.
- 12 MCP tools (measured), among them
recommend_window,schedule_task,check_queue_status,get_grid_forecast,cancel_task,postpone_task,update_deadline. - Live 72-hour forecast. GB needs no key; other regions use free keys (EIA, ENTSO-E, WattTime, Electricity Maps).
- One signed carbon receipt per task, stored in
~/.tidegap/queue.db.
npx -y @tidegap/mcp
{ "mcpServers": {
"tidegap": { "command": "npx", "args": ["-y", "@tidegap/mcp"] }
} }
Proof: one real GB run, 2026-09-30. Forecast peak 183 gCO2/kWh vs recommended window 88 gCO2/kWh, about 52 % lower for this run only (forecast, projected). Receipt at dispatch: 158 gCO2/kWh (measured). Host-specific configs: https://www.tidegap.com/docs#install
Run
npx -y @tidegap/mcp
The server speaks MCP over stdio. To wire it into an agent client:
Claude Desktop
Edit ~/Library/Application Support/Claude/claude_desktop_config.json
on macOS (Linux/Windows have similar paths):
{
"mcpServers": {
"tidegap": {
"command": "npx",
"args": ["-y", "@tidegap/mcp"],
"env": {
"TIDEGAP_ELECTRICITY_MAPS_API_KEY": "optional - mock data without it",
"TIDEGAP_DEFAULT_REGION": "US-CAL-CISO"
}
}
}
}
Restart Claude Desktop after editing.
Claude Code
Add tidegap to your ~/.claude/mcp.json (or workspace .claude/mcp.json):
{
"mcpServers": {
"tidegap": {
"command": "npx",
"args": ["-y", "@tidegap/mcp"]
}
}
}
OpenClaw
Add to ~/.openclaw/mcp.json:
{
"mcpServers": {
"tidegap": {
"command": "npx",
"args": ["-y", "@tidegap/mcp"]
}
}
}
Tools exposed (12, measured)
| Tool | Purpose |
|---|---|
get_grid_forecast(region, hours?) | Hour-by-hour carbon intensity for a region; useful before deciding whether to defer. |
recommend_window(deadline, region?, ...) | Plan the cleanest window inside the deadline without queueing anything. |
schedule_task(prompt, deadline, model?, region?, carbon_budget_g?, repeat?, origin_session_id?, not_before?) | Queue a task to run in the cleanest window inside the deadline. Returns a task_id and one line that says whether it will run: Runs at <time> local., or the readiness sentence with its fix, for example Tasks will not run: no tick daemon. Run `tidegap install`.. not_before sets the earliest start. repeat defaults to none, also for deadline_kind: "quota_reset". |
check_queue_status(task_id?) | Inspect the queue or one specific task; includes a carbon receipt once the task has completed. |
cancel_task(task_id, series?) | Cancel a queued or scheduled task; on a repeating task, skip it, or end the series with series: true. |
reply_task(task_id, text, deadline?) | Continue a completed task: a new task with the conversation plus this text, same provider and model. |
expedite_task(task_id) | Dispatch a queued or scheduled task now, outside its carbon window. |
postpone_task(task_id, preset? | until? | delay_minutes?, reset_at?) | "Later": move a pending task later, never earlier. Presets 1h, tonight (22:00 to 06:00), tomorrow_morning (09:00 to 12:00), after_limit_reset (5 minutes after the Claude limit reset: reset_at, else this machine's limit reading, else a reset time given before). |
update_deadline(task_id, deadline) | Reschedule a task against a new deadline. |
retry_task(task_id) | Re-dispatch a failed task. |
cancel_all(status?) | Cancel every task that is still queued or scheduled. |
tidegap_usage(include_spend?) | Read-only: the Claude Code subscription limits of this machine and when they reset, and the Codex limits from its local logs. include_spend adds the current 5-hour window's tokens and an API list-price cost estimate. |
Environment variables
These variables configure this MCP server (and the tidegap CLI, which reads
the same set). They are read at the server's own entry point and injected into
@tidegap/core, which is environment-pure and reads nothing ambient itself.
OpenClaw plugin users: the
@vitalini/tidegapOpenClaw plugin reads no environment variables. Configure it through plugin config instead, underplugins.entries.tidegap.configin your gateway config — the "Plugin config" column below names the field that replaces each variable. OpenClaw resolves the"${ENV_VAR}"shorthand in those fields, so you can keep exporting the same variables and let the gateway read them on the plugin's behalf.
| Var | Plugin config | Purpose |
|---|---|---|
TIDEGAP_ELECTRICITY_MAPS_API_KEY | electricityMapsApiKey | API key from electricitymaps.com. Universal fallback. If unset (and no zone-specific feed is configured), the server falls back to deterministic mock data so you can still run the whole stack locally. |
TIDEGAP_EIA_API_KEY | eiaApiKey | Free US EIA key. Enables average-emissions intensity for the US ISO zones (CAISO / ERCOT / ISO-NE / NYISO / PJM / MISO). |
TIDEGAP_ENTSOE_SECURITY_TOKEN | entsoeSecurityToken | Free ENTSO-E token. Enables EU zone intensity (FR / DE / ES / IT / NL). |
WATTTIME_USERNAME + WATTTIME_PASSWORD | wattTimeUsername + wattTimePassword | Free WattTime v3 account. Enables marginal-emissions (co2_moer) forecasts for the US ISO zones — takes precedence over EIA where covered, falls through to EIA on any error. The marginal signal is disclosed as signalType: "marginal" on forecasts and receipts. |
TIDEGAP_DEFAULT_REGION | defaultRegion | Region when a tool call names none. Beats the stored region setting; see Grid region. |
ANTHROPIC_API_KEY | anthropicApiKey | Enables the anthropic provider (batch-capable). |
OPENAI_API_KEY | openaiApiKey | Enables the openai provider (batch-capable). |
GEMINI_API_KEY / GOOGLE_API_KEY | geminiApiKey / googleApiKey | Enables the gemini provider (Generative Language API, sync-only). GEMINI_API_KEY is preferred; GOOGLE_API_KEY is the fallback. |
OLLAMA_HOST | ollamaHost | Enables the local ollama provider (sync-only). Default http://localhost:11434; keyless — set this var to opt the provider in. |
Grid region
The server resolves the region of each tool call in this order:
- the tool call's
regionargument, TIDEGAP_DEFAULT_REGIONin the server's environment (the agent host's MCP config),- the region setting stored on this machine:
tidegap region set <zone>, or Settings → Grid region intidegap uiand the Mac app (keyTIDEGAP_DEFAULT_REGIONin~/.tidegap/config), - a guess from the machine's time zone,
GB.
The server reads the setting again when the file changes, so a new setting applies on the next tool call with no restart. A stored value that is not a supported zone is ignored, with one stderr warning per change. schedule_task replies carry region_source: flag | env | setting | timezone | fallback.
A region argument must be one of the 31 supported zones (any case). Another value is rejected with the closest zones and a link to request a region, for example Unknown zone UA. Closest: PL. Request a region: <link>. With TIDEGAP_ELECTRICITY_MAPS_API_KEY set, any zone passes, because Electricity Maps serves zones beyond the list; with TIDEGAP_ENTSOE_SECURITY_TOKEN set, IT passes too.
Develop
From the root of a clone of https://github.com/tidegap/tidegap:
pnpm install
pnpm --filter @tidegap/mcp build
node packages/mcp-server/dist/server.js
Comments
New to MCP?
From what the protocol is to installing your first server, these answers cover most first questions.
An open protocol that defines how AI applications connect to external tools and data in a uniform way. Clients talk to the model; MCP servers provide tools, resources and prompt templates. They exchange standard messages, so one server can be reused by many clients.