ebb-ai

docs

Everything you need to install + use ebb-ai.

Pick your AI host below, copy the command. Then call any of the eight slash commands (Claude Code) or nine MCP tools (every other host).

install

Pick your host

Universal — add ebb-mcp to any host that speaks Model Context Protocol.

bash
npx -y @ebb-ai/mcp

then Wire this into your host's MCP config (the snippets for specific hosts are in the dropdown).

commands

Eight slash commands (Claude Code)

After installing the Claude Code plugin, these are available as/ebb-ai:<cmd>in any session. Identical CRUD over the task queue.

/ebb-ai:defer<prompt> [--by <when>] [--region <zone>] [--budget <g>]

Queue a task to run at the cleanest grid hour inside the deadline. Returns task_id + scheduled UTC time + region.

/ebb-ai:plan<deadline> [--region <zone>] [--budget <g>]

Preview what window the scheduler would pick — without queueing. Returns chosen hour, savings vs now, top-3 alternatives.

/ebb-ai:check[task_id] [--all]

List all tasks (default) or get full detail + carbon receipt for one task. Read-only.

/ebb-ai:cancel<task_id>

Cancel a queued or scheduled task. Idempotent — completed/failed/cancelled tasks return their existing status.

/ebb-ai:expedite<task_id>

Dispatch a scheduled task immediately, bypassing the cleanest-window pick. Receipt is tagged intensitySource=expedited.

/ebb-ai:reschedule<task_id> <new_deadline>

Re-score a task against a new deadline. Lets you extend (more window for clean hour) or compress (may exceed carbon budget).

/ebb-ai:retry<task_id>

Re-dispatch a task currently in failed status. New receipt overwrites the old. No-op for non-failed tasks.

/ebb-ai:grid<zone> [--hours N]

Show current carbon intensity + next-24h forecast for a region. Useful for deciding now-vs-wait without queueing.

mcp tools

Nine MCP tools (every host)

The same surface that powers the slash commands. Any MCP host can invoke these directly. Parameters are documented in each tool's JSON schema.

  • get_grid_forecastread-only

    Hourly carbon-intensity forecast for a region (gCO2/kWh + band). Backs /ebb-ai:grid.

  • recommend_windowread-only

    Cleanest in-deadline window + alternatives + savings vs now. Non-committal planning.

  • schedule_taskwrite

    Persist a task to the SQLite queue with a deadline. Returns task_id. Backs /ebb-ai:defer.

  • check_queue_statusread-only

    List all tasks or detail for one (with receipt). Backs /ebb-ai:check.

  • cancel_taskwrite

    Set a task's status to cancelled. Idempotent.

  • expedite_taskwrite (dispatch)

    Dispatch immediately, bypassing the scheduled window. Requires a provider API key.

  • update_deadlinewrite

    Re-score a task against a new deadline. Backs /ebb-ai:reschedule.

  • retry_taskwrite (dispatch)

    Re-dispatch a failed task. Requires a provider API key. Backs /ebb-ai:retry.

  • cancel_allwrite

    Cancel every non-terminal task at once. Useful for clearing a corrupted queue.

energy estimation

Per-model Wh/token coefficients (v0.10+)

Carbon receipts are computed from real per-model energy data — not a flat placeholder. Sources: Patterson et al. 2021 (arXiv:2104.10350), Luccioni, Jernite, Strubell 2024 “Power Hungry Processing” (FAccT 2024, arXiv:2311.16863), and the Hugging Face AI Energy Score.

Model classWh/input tokWh/output tokTypical call*Source
claude-opus-4 · gpt-4-turbo · o1 · gemini-1.5-pro0.0030.015~10.4 Whestimated
claude-sonnet-4 · llama-3.1-70b0.0010.005~3.5 Whestimated / measured
claude-haiku · gpt-4o-mini · gemini-flash · o1-mini0.0003 – 0.00060.0015 – 0.003~1.0 – 2.1 Whestimated
llama-3.1-8b · mistral-7b0.00020.001~0.7 Whmeasured
llama-3.1-405b · gpt-40.0050.025~17 Whmeasured / estimated

* Typical = 500 input + 500 output tokens × DEFAULT_PUE = 1.15. Closed-model coefficients are inferred from public parameter-count disclosures and the Luccioni scaling curve; may be off by ±50%. Each entry in MODEL_ENERGY_COEFFICIENTS carries asource field of "measured", "estimated", or "fallback" so dashboards can render confidence alongside numbers.

Public API (@ebb-ai/core 0.10+, ebb_ai 0.6+)

import {
  estimateEnergyKwh,
  gramsForIntensity,
  lookupModelEnergy,
  MODEL_ENERGY_COEFFICIENTS,
  ENERGY_SOURCES,
  DEFAULT_PUE,
  LEGACY_KWH_PER_TASK,
} from "@ebb-ai/core";

estimateEnergyKwh({
  model: "claude-sonnet-4",
  inputTokens: 1000,
  outputTokens: 2000,
});
// => 0.01265 kWh (1.0 in + 10.0 out Wh chip × 1.15 PUE)

gramsForIntensity(400, { model: "claude-haiku-4-5" });
// => 0.41 g CO2e (haiku at 400 g/kWh grid)

estimateEnergyKwh();
// => 0.0015 kWh (v0.1-v0.9 flat fallback, bit-exact)

verifiable receipts

Ed25519-signed carbon receipts (v0.11+)

Every dispatched task ships a cryptographic signature so any consumer can verify, offline and asynchronously, that (1) the receipt was produced by an ebb-ai installation holding the matching private key, and (2) none of the receipt's fields have been tampered with since signing. Direct path to B2B ESG export — receipts are auditable artefacts, not just claims.

Keys live at ~/.ebb-ai/signing.key (private, 0600) and signing.key.pub (public). Generated lazily on first dispatch — no opt-in friction. They never leave the machine; verification consumers bundle the receipt's signerPublicKey with the receipt itself, so downstream pipelines can pin the key on first sight.

CLI

# Verify the receipt for a completed task in the local ledger
$ ebb verify 1c5b...e0

✓ VALID

task_id           1c5b...e0
region            US-CAL-CISO
ran_at            2026-06-01T13:00:00.000Z
actual_g_co2      2.4
estimated_g_co2   2.6
delta_pct         -7.7
model             claude-sonnet-4-5
provider          anthropic

signer_public_key OnTm5l9VbQHFv9wD...
signed_at         2026-06-01T13:00:00.184Z

Ed25519 signature verified against canonical payload (412 bytes)

# Verify a receipt JSON file (e.g. as shipped to outputPath)
$ ebb verify --file ./out/task-1c5b.json --json
{ "outcome": "valid", "signerPublicKey": "OnTm5l9VbQHFv9wD...", ... }

# Pin the expected signer for B2B/ESG pipelines
$ ebb verify --file ./inbox/receipt.json --trusted-public-key OnTm5l9V...
# exit 0 on match; exit 3 on key-mismatch

Library (TypeScript)

import {
  signReceipt,
  verifyReceipt,
  loadOrCreateSigningKey,
} from "@ebb-ai/core";

const keyPair = loadOrCreateSigningKey();
const signed = signReceipt(receipt, keyPair);

const result = verifyReceipt(signed);
// { outcome: "valid" | "tampered" | "legacy-unsigned" | "key-mismatch", ... }

Library (Python — opt-in)

# pip install "ebb-ai[signing]"   (pulls in the cryptography library)

from ebb_ai import (
    sign_receipt, verify_receipt,
    load_or_create_signing_key, is_signing_available,
)

key_pair = load_or_create_signing_key()
signed = sign_receipt(receipt_dict, key_pair)
result = verify_receipt(signed)
# VerifyResult(outcome='valid', signer_public_key=..., reason=...)

Verifier outcomes: valid, tampered (signed but no longer matches), legacy-unsigned (pre-v0.11 receipt — accept-or-reject is the consumer's policy), key-mismatch (signed by someone other than the trusted public key). CLI exit codes mirror these: 0 / 1 / 2 / 3.

on-disk

Paths

~/.ebb-ai/queue.db

SQLite ledger — queue + carbon receipts. The CLI, MCP server, and dashboard all read this same file. Read-only from your agent; modifiable from the CLI.

~/.ebb-ai/signing.key

Per-installation Ed25519 private key (0600, with `signing.key.pub` alongside). Lazily generated on first dispatch; signs every carbon receipt so consumers can verify offline via `ebb verify`. Local-only — ebb-ai never sends it anywhere. v0.11+.

~/.ebb-ai/telemetry.key

Local-only 256-bit token + Ed25519 keypair for the (planned) opt-in leaderboard. Never sent. Not generated until you opt in.

environment

Optional API keys

ebb-ai works without any keys (GB is always live via UK National Grid ESO; everything else falls back to a deterministic mock). Set these in your MCP host's env block to unlock live data for more regions.

These environment variables configure the ebb CLI and the @ebb-ai/mcp server. The OpenClaw plugin reads no environment variables at all — configure it through plugin config instead, under plugins.entries.ebb.config in your gateway config. Each field below lists the plugin-config key that replaces it, and OpenClaw resolves "${ENV_VAR}" in those fields, so you can keep exporting the same variables and let the gateway read them.

  • EBB_EIA_API_KEY

    U.S. Energy Information Administration. Unlocks live AVERAGE-emissions data for the six US ISOs (CISO, ERCO, ISNE, MIDA-PJM, NY-NYIS, MIDW-MISO). Free at eia.gov/opendata/register.php.

    OpenClaw plugin config: eiaApiKey

  • WATTTIME_USERNAME · WATTTIME_PASSWORD

    WattTime v3 account. Unlocks live MARGINAL-emissions (co2_moer) forecasts for the US ISOs — the honest signal for time-shifting. Takes precedence over EIA where covered and falls through to EIA on any error; the marginal signal is disclosed as signalType:"marginal" on forecasts and receipts. Free account at watttime.org.

    OpenClaw plugin config: wattTimeUsername · wattTimePassword

  • EBB_ENTSOE_SECURITY_TOKEN

    ENTSO-E Transparency Platform. Unlocks live data for European zones (FR, DE, ES, IT, NL). Free at transparency.entsoe.eu.

    OpenClaw plugin config: entsoeSecurityToken

  • EBB_ELECTRICITY_MAPS_API_KEY

    Electricity Maps free tier (100 req/day). Universal fallback for any other zone. Free at electricitymaps.com/free-tier-api.

    OpenClaw plugin config: electricityMapsApiKey

  • ANTHROPIC_API_KEY · OPENAI_API_KEY

    Required only if you want ebb-ai to actually dispatch provider calls (vs. just queueing them). Either is enough. anthropic and openai can auto-route through a 50%-cheaper Batch API when the deadline allows.

    OpenClaw plugin config: anthropicApiKey · openaiApiKey

  • GEMINI_API_KEY · GOOGLE_API_KEY

    Dispatch through Google Gemini (generativelanguage.googleapis.com). GEMINI_API_KEY is preferred; GOOGLE_API_KEY is the fallback. Sync-only (no Batch API).

    OpenClaw plugin config: geminiApiKey · googleApiKey

  • OLLAMA_HOST · OLLAMA_MODELS

    Dispatch through a local Ollama server (default http://localhost:11434). Keyless — setting OLLAMA_HOST opts the ollama provider in. OLLAMA_MODELS (comma-separated) lets schedule_task infer the ollama provider from a bare model name. Sync-only.

    OpenClaw plugin config: ollamaHost · ollamaModels

deeper

Architecture, roadmap, source.