Tidegap

io.github.tidegapPublished by GitHub account tidegapv0.20.0Updated Nov 3, 2026

Runs non-urgent LLM tasks at the cleanest grid hour before a deadline, via Batch APIs when allowed.

Overview

Tidegap's local MCP server; no sign-in required; STDIO; 12 tools.

No AI overview yet: these facts come from the registry entry and the server itself.

Installation

In SourceWeft

  1. Open Tidegap in the dashboard and add it to a workspace.
  2. Enable the server for the chats that should use its tools.

Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.

Other MCP clients

Follow the launch instructions in the repository.

README

[Tidegap]

@tidegap/mcp

Renamed from @ebb-ai/mcp in 0.18.0. Use the host config key tidegap and npx -y @tidegap/mcp; the ebb-mcp bin and the EBB_* 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.
bash
npx -y @tidegap/mcp
json
{ "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

bash
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):

json
{  "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):

json
{  "mcpServers": {    "tidegap": {      "command": "npx",      "args": ["-y", "@tidegap/mcp"]    }  }}

OpenClaw

Add to ~/.openclaw/mcp.json:

json
{  "mcpServers": {    "tidegap": {      "command": "npx",      "args": ["-y", "@tidegap/mcp"]    }  }}

Tools exposed (12, measured)

ToolPurpose
schedule_task(... repeat?, every_hours?, days?, window?, time_zone?) with repeat daily, weekdays, weekly or every_n_hoursCreate a recurring job: each run is a new task at the cleanest hour of its period. End it with cancel_task(series: true).
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".
schedule_task(... runner?, cwd?, permission_profile?, result_path?, wake_session?)Hand off the work shape: runner is another name for provider; cwd is the folder a claude-code run works in (another folder than the session's runs fresh there); permission_profile is read, web or none (read with a cwd); result_path is a new file Tidegap writes the result text to, inside cwd, the session's project folder or the temp folder. wake_session: true wakes the idle Claude Code session that queued the task when it finishes (within 12 hours after its last turn; refused outside a session). runner or provider command is refused with the tidegap queue add --runner command line. output_path follows the same folder rules.
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/tidegap OpenClaw plugin reads no environment variables. Configure it through plugin config instead, under plugins.entries.tidegap.config in 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.

VarPlugin configPurpose
TIDEGAP_ELECTRICITY_MAPS_API_KEYelectricityMapsApiKeyAPI 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_KEYeiaApiKeyFree US EIA key. Enables average-emissions intensity for the US ISO zones (CAISO / ERCOT / ISO-NE / NYISO / PJM / MISO).
TIDEGAP_ENTSOE_SECURITY_TOKENentsoeSecurityTokenFree ENTSO-E token. Enables EU zone intensity (FR / DE / ES / IT / NL).
WATTTIME_USERNAME + WATTTIME_PASSWORDwattTimeUsername + wattTimePasswordFree 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_REGIONdefaultRegionRegion when a tool call names none. Beats the stored region setting; see Grid region.
ANTHROPIC_API_KEYanthropicApiKeyEnables the anthropic provider (batch-capable).
OPENAI_API_KEYopenaiApiKeyEnables the openai provider (batch-capable).
GEMINI_API_KEY / GOOGLE_API_KEYgeminiApiKey / googleApiKeyEnables the gemini provider (Generative Language API, sync-only). GEMINI_API_KEY is preferred; GOOGLE_API_KEY is the fallback.
OLLAMA_HOSTollamaHostEnables 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:

  1. the tool call's region argument,
  2. TIDEGAP_DEFAULT_REGION in the server's environment (the agent host's MCP config),
  3. the region setting stored on this machine: tidegap region set <zone>, or Settings → Grid region in tidegap ui and the Mac app (key TIDEGAP_DEFAULT_REGION in ~/.tidegap/config),
  4. a guess from the machine's time zone,
  5. 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:

bash
pnpm installpnpm --filter @tidegap/mcp buildnode packages/mcp-server/dist/server.js

Source: packages/mcp-server/README.md at commit 04e6502

Tools

12

get_grid_forecast

Grid carbon forecast

Return the hour-by-hour grid carbon intensity forecast for one region, up to 72 hours ahead. Use when: the user asks how clean the grid is now or later, or wants the raw curve. Do not use to pick a run time for a task (use recommend_window) or to queue work (use schedule_task). Behavior: writes nothing; reads one grid feed, no login; GB is live without a key, other zones need a feed key or get synthetic data (Source: mock). Returns: region, source, generated time, one row per hour (gCO2/kWh and band), and the cleanest and dirtiest hour. Rejects an unknown zone and lists the closest zones.

Parametershoursregionrequired

recommend_window

Preview cleanest window

Preview the cleanest run window before a task's deadline, without queuing it. Use when: the user asks when a task would run or what waiting saves. Do not use to queue the task (use schedule_task) or for the raw hourly curve (use get_grid_forecast). Behavior: writes nothing; reads the grid forecast; no login or key. Returns: scheduled_for, intensity, band, estimated_carbon_g_co2, estimated_savings_vs_now_pct, batch_eligible, grid_source (mock = synthetic), alternatives, reasoning; routing_preview with 2+ candidates. Rejects a past deadline, an unknown zone, or a carbon_budget_g no window meets.

Parametersmodelregionrequireddeadlinerequiredcandidatesroute_weightscarbon_budget_g

schedule_task

Schedule task at cleanest hour

Queue an AI task or recurring job to run at the cleanest grid hour before its deadline; long deadlines may use the provider Batch API. Use when: the user defers work ("tonight", "no rush", "before my limit resets") or wants it repeated ("every night", "daily", a cron); map that to deadline or repeat. Do not use for work the user waits on (do it now), to preview only (use recommend_window or dry_run) or for limits (use tidegap_usage). Behavior: adds one task, one run of one runner (dry_run writes nothing), or with repeat a job of such tasks; `tidegap tick` runs it; reads the grid forecast; no login; the result stays in the queue (check_queue_status). Returns: task_id, status, scheduled_for, deadline, provider, model, runs_in, estimated_carbon_g_co2, a readiness line; a job adds job_id and its guarantee. Rejects a past deadline, an unknown zone, disallowed tools and shell commands.

Parameterscwddaysmodeltitletoolspromptrequiredregionrepeatrunnerwindowdry_rundeadline+17 more

check_queue_status

Show task queue

Show the local task queue and jobs: every task in brief or one in full. Use when: the user asks what is queued or repeats, whether a task finished, or for its result. Do not use to change a task (use cancel_task, postpone_task, update_deadline or retry_task) or for limits (use tidegap_usage). Behavior: no network or login; marks a shown completed or failed task read; never changes a status. Returns: without task_id, status counts, last_tick_at, a line per task and job (guarantee, next run and id, last result); with task_id, its prompt, result, receipt and events. Rejects an unknown task_id.

Parameterstask_id

tidegap_usage

Claude usage limits

Report this machine's Claude Code limits: 5-hour and weekly percent used, reset times, and Codex limits if present. Use when: the user asks how much quota is left, or before heavy Claude Code work; at 90% or more, pass after_limit_reset to schedule_task. Do not use for task state (use check_queue_status). Behavior: reads the statusline reading, no API key; TIDEGAP_USAGE_OAUTH=1 calls the usage endpoint with the Claude Code login and caches it in ~/.tidegap/usage.json; never writes tasks or settings. Returns: a summary line and the usage/v1 JSON (windows, reading age, after_limit_reset wait).

Parametersinclude_spend

cancel_task

Cancel one task

Cancel one queued or scheduled task by task_id; for all pending, use cancel_all. Use when: the user drops one task. Do not use to delay it (use postpone_task) or rerun a failed one (use retry_task). Behavior: marks it cancelled locally (no network) and redacts its prompt. Also cancels running and submitted tasks; a Batch call may still bill. A job or series skips this run; series=true ends it, even from a finished run. Else a finished task or repeat call changes nothing. Returns: "Task <id> status: <status>", terminated_at, and a job or series line when ended. Rejects an unknown task_id.

Parametersseriestask_idrequired

expedite_task

Run task now

Run one queued or scheduled task now, skipping its clean window. Use when: the user wants the result now. Do not use for a failed task (use retry_task), to pick a new deadline (use update_deadline), or for a claude-code task (run `tidegap queue run-now <id>`). Behavior: drops its earliest start and makes one provider call at the current grid intensity; needs the task provider's key in the server env (and ANTHROPIC_API_KEY or OPENAI_API_KEY); the receipt records intensitySource=expedited. Returns: status and error on failure. Rejects running, submitted, finished and unknown tasks.

Parameterstask_idrequired

update_deadline

Change task deadline

Change the deadline of one queued or scheduled task and re-pick its cleanest window inside it. Use when: the user moves the due time, earlier or later ("by 6pm instead"). Do not use to delay the start inside the same deadline (use postpone_task), to run now (use expedite_task) or to stop it (use cancel_task). Behavior: rewrites only this task in the local queue, clears its earliest start and quota rule, re-reads the grid forecast; no login. A repeat call only re-picks the hour. Returns: status, scheduled_for, new_deadline. Rejects running, finished or unknown tasks and a past deadline.

Parameterstask_idrequireddeadlinerequired

postpone_task

Postpone task

Move one queued or scheduled task later; it never runs earlier than planned. Use when: the user says "tonight" or "after my limit resets"; pass exactly one of preset, until or delay_minutes. Do not use to set a new due time (use update_deadline) or to stop it (use cancel_task). Behavior: rewrites this task's earliest start in the local queue and re-picks the cleanest hour after it, but an until time is kept exactly; after_limit_reset reads the Claude limits. Returns: status, not_before, scheduled_for, deadline. Rejects a target at or before the planned start, finished and unknown tasks.

Parametersuntilpresettask_idrequiredreset_atdelay_minutes

reply_task

Reply to a completed task

Send a follow-up message in a completed task's conversation, as a new queued task. Use when: the user follows up on a finished task's result. Do not use for a failed task (use retry_task) or for an unrelated new task (use schedule_task). Behavior: each call adds one task to the local queue with earlier turns as history, the same provider and model, and its own clean window; no login now; it runs later as one provider call with the original's credentials. Returns: task_id, parent_task_id, status, scheduled_for, deadline. Rejects non-completed and unknown tasks and text over 32000 characters.

Parameterstextrequiredtask_idrequireddeadline

retry_task

Retry a failed task

Run a failed task again now, with the same prompt, provider and model. Use when: a task failed on a transient error (rate limit, 5xx). Do not use for a task that did not fail (use expedite_task to run it now, update_deadline to move it), or for a claude-code task (run `tidegap queue run-now <id>`). Behavior: one provider call now; needs the task provider's key in the server env (and ANTHROPIC_API_KEY or OPENAI_API_KEY); the new result and signed receipt replace the old ones. Returns: status (completed or failed) and error on failure. Rejects non-failed and unknown tasks.

Parameterstask_idrequired

cancel_all

Cancel all pending tasks

Cancel every queued and scheduled task in the local queue at once; for a single task use cancel_task. Use when: the user says "cancel everything" or "clear the queue". Do not use to drop one task or to end a repeating series (use cancel_task, with series=true for a series). Behavior: marks each pending task cancelled; running, submitted and finished tasks stay as they are; no network or login. A repeating task skips this occurrence and its next one is queued, so a second call cancels that one too. Returns: "Cancelled N of M task(s)." and one error line per task that could not be cancelled.

Parametersstatus

Version history

3
  1. v0.20.0LatestNov 3, 2026
  2. v0.19.0Oct 17, 2026
  3. v0.18.0Oct 16, 2026

Score

90% of the applicable checks met

How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.

  • Reached in the last 30 days25 pts
  • Auth declared10 pts

    Declare the credential headers in the registry entry, or keep the endpoint answering the probe so its auth can be classified.

  • Tools listedRequired15 pts
  • DescriptionRequired15 pts
  • Logo10 pts
  • Documentation15 pts
  • License10 pts