Skip to main content
Glama
README.md
# OpenEcoBee MCP

An open-source MCP server for controlling ecobee thermostats from ChatGPT. The Cloudflare deployment is designed to run entirely in the cloud: people connect their own ecobee account through a browser, without installing a local companion or obtaining an ecobee developer API key.

**Experimental.** The Cloudflare deployment, GitHub sign-in, ecobee login, restoring and renewing an encrypted session, a thermostat read through ChatGPT, and a real indefinite cooling hold have been verified. Broader controls have implementation tests; live verification is recorded in the [coverage document](docs/feature-coverage.md). Ecobee can block cloud browsers, and portal changes can break this unofficial integration.

The [operator's hosted pilot](https://openecobee-mcp.eliseo-492.workers.dev) is currently restricted to the operator's GitHub account. Other users can deploy their own instance using the guide below.

## What “no auth token” means

People do not need an ecobee developer application or manually copied access token. They still sign in to their own ecobee account and complete its normal multifactor authentication. The service saves the resulting browser session so later MCP calls can use it. This is authenticated access, with token handling kept out of the user's setup.

For the hosted service, users sign in with GitHub to identify their OpenEcoBee account and authorize the MCP connection. Ecobee login happens separately in a hosted browser. **The operator hosting OpenEcoBee is trusted with the ecobee session:** saved state is encrypted, but the running service has the key needed to decrypt it. See [security](SECURITY.md).

Ecobee's standard portal sign-in requests thermostat access, profile read/write access, and sign-in grant management. OpenEcoBee exposes only its fixed thermostat tools, but the saved portal session has these broader permissions.

Ecobee [currently does not accept new developer registrations](https://www.ecobee.com/en-us/developers/), so this project uses its signed-in web portal instead of requiring a developer API key.

## Hosted setup

The operator deploys the Worker and configures GitHub OAuth once. End users do not need Cloudflare accounts, server keys, or a process running on their computer.

1. Deploy the service using [the Cloudflare guide](docs/cloudflare.md).
2. Open the deployed `/app` page and sign in with GitHub.
3. Connect ecobee, complete the normal login/MFA in the hosted browser, and finish the connection.
4. Keep access read-only initially; enable thermostat changes in the account page when ready.
5. Add the deployed HTTPS `/mcp` endpoint to ChatGPT with OAuth. See [Connect ChatGPT](docs/chatgpt.md).

The deployment starts with a closed user allowlist. Verify login, account isolation, and a deliberate thermostat command before broadening access.

If ecobee requires another sign-in, open your hosted `/app` page, choose **Open ecobee sign-in**, complete login/MFA in the private browser, and choose **Finish connecting ecobee**. Use **Check connection** to verify the restored session. Ecobee sign-in is separate from ChatGPT authorization; reconnecting ecobee keeps your existing ChatGPT connection and thermostat permissions.

## MCP tools

The server provides tools covering thermostat state and holds, eco+ master control, energy/automation inspection, Smart Recovery, comfort settings, weekly schedules, fan, sensors, vacations, alerts, messages, runtime reports, and documented settings. Use `get_capabilities` for the current catalog. See [feature coverage](docs/feature-coverage.md) for the distinction between implemented interfaces, live verification, device-specific support, and unverified eco+ subfeatures.

The original core tools remain available:

| Tool | Purpose |
| --- | --- |
| `list_thermostats` | List accessible thermostats and their identifiers. |
| `get_thermostat_status` | Read temperature, humidity, mode, connection state, and setpoints. |
| `set_temperature` | Set a heating/cooling hold with an explicit duration; accepts Fahrenheit or Celsius. |
| `set_hvac_mode` | Select `off`, `heat`, `cool`, or `auto`. |
| `resume_schedule` | End a hold and resume the thermostat's schedule. |

Changes require writes to be enabled. Holds can last 1–24 hours, until the next scheduled change, or until changed explicitly. Setpoints must fit the thermostat's reported limits; minimum heat/cool separation applies in Auto mode. A response distinguishes accepted delivery from observed readback. Always check a pending result before retrying a change. Schedule resumption is reported as accepted without claiming physical verification.

Example prompts:

- “List my thermostats and show the downstairs temperature.”
- “Set the downstairs heating setpoint to 68°F and cooling setpoint to 76°F for two hours.”
- “Resume the downstairs thermostat's schedule.”
- “Show my eco+ state, Smart Recovery preferences, and active holds without changing anything.”
- “Turn off the eco+ master setting.”
- “Enable Smart Recovery for cooling.”

An indefinite hold overrides the schedule, and Smart Recovery does not run during that hold. Individual eco+ switches and savings levels still require verified interfaces; the master control does not imply full eco+ feature coverage.

## Local development

Use Node.js 22 or newer:

```sh
npm install
npm run check
npm test
npm run build
```

Try the simulated thermostat without an account:

```sh
npm run demo
# To exercise changes against the simulation:
node dist/cli.js serve --demo --allow-writes
```

The demo is a stdio MCP server and waits for a client. It simulates the original five thermostat controls; the extended features require a real browser backend. For a local real-account experiment, install Chromium and complete ecobee login on this computer:

```sh
npx playwright install chromium
node dist/cli.js login
node dist/cli.js status
node dist/cli.js serve
# Explicitly opt in to thermostat changes:
node dist/cli.js serve --allow-writes
```

Local state defaults to `.openecobee/profile`, relative to the working directory. Use `--profile /absolute/path/to/profile` or `OPENECOBEE_PROFILE` when a client launches the server from a different directory. Treat the directory as credentials and run only one process against it at a time.

A generic local MCP client can launch the server with:

```json
{
  "mcpServers": {
    "openecobee": {
      "command": "node",
      "args": [
        "/absolute/path/to/OpenEcoBee/dist/cli.js",
        "serve",
        "--profile",
        "/absolute/path/to/OpenEcoBee/.openecobee/profile"
      ]
    }
  }
}
```

For local HTTP, run `node dist/cli.js serve --transport http`. It listens at `http://127.0.0.1:3000/mcp`, with local host/origin checks. This local endpoint has no OAuth and must remain private. The hosted Worker has a separate authenticated deployment path.

## Project notes

The browser integration depends on ecobee portal internals. Login sessions can expire, cloud browsers can be rejected, and the adapter can stop working after a portal release. There is no offline control path.

See [architecture](docs/architecture.md), [CONTRIBUTING.md](CONTRIBUTING.md), and [SECURITY.md](SECURITY.md). This is an independent MIT-licensed implementation inspired by [emrikol/ecobee-mcp](https://github.com/emrikol/ecobee-mcp); its code is not copied. [REA](https://github.com/morluto/rea/) is a reference for investigating browser applications, not a runtime dependency.

Not affiliated with or endorsed by ecobee, OpenAI, GitHub, or Cloudflare.

TDQS

A3.9/5.0

Scored across 5 tools

Disambiguation4/5

list_thermostats and get_thermostat_status both read thermostat state and their boundaries blur, since list_thermostats already returns temperatures and setpoints. However, the plural listing vs. single-thermostat detail distinction and the write actions (set_temperature, set_hvac_mode, resume_schedule) are otherwise clearly separable.

Naming Consistency5/5

All tools follow a clean snake_case verb_noun pattern: list_thermostats, get_thermostat_status, set_temperature, set_hvac_mode, resume_schedule. Verbs are consistently action-oriented and nouns are clear.

Tool Count5/5

Five tools is well-scoped for a thermostat controller: discovery, status read, temperature hold, mode change, and schedule resume. Each tool earns its place with no filler.

Completeness4/5

The surface covers the core read/set/resume lifecycle of thermostat control, but lacks operations like viewing the programmed schedule, setting fan/humidity modes, or canceling a hold explicitly. Minor gaps an agent can mostly work around.