Skip to main content
Glama
lukerweaver

beestat-mcp

by lukerweaver
README.md
# beestat-mcp

Python MCP server that wraps the [beestat API](https://beestat.notion.site/API-Documentation-e4a7746e6a3f45dbb58ea6b45b8f9744).

## What this provides

- A generic tool: `beestat_call(resource, method, arguments?, http_method?)`
- Convenience tools for documented resources:
  - `thermostat_read_id`
  - `ecobee_thermostat_read_id`
  - `sensor_read_id`
  - `ecobee_sensor_read_id`
  - `runtime_thermostat_read`
  - `runtime_thermostat_summary_read_id`
  - `runtime_sensor_read`
  - `thermostat_sync`
  - `sensor_sync`
  - `runtime_sync`

## Setup

```bash
python -m venv .venv
source .venv/bin/activate
pip install -e .
```

Set your beestat key:

```bash
export BEESTAT_API_KEY="your_api_key"
```

Run server (default transport: `streamable-http`):

```bash
beestat-mcp
```

Or force stdio:

```bash
beestat-mcp --transport stdio
```

## Docker

Build and run:

```bash
docker build -t beestat-mcp .
docker run --rm -p 8000:8000 \
  -e BEESTAT_API_KEY="your_api_key" \
  beestat-mcp
```

Or with compose:

```bash
cat > .env << 'EOF'
BEESTAT_API_KEY=your_api_key
BEESTAT_MCP_PORT=8000
BEESTAT_MCP_STREAMABLE_HTTP_PATH=/mcp
EOF

docker compose up -d --build
```

## n8n usage

Use n8n's MCP Client node with HTTP transport and point it at:

```text
http://127.0.0.1:8000/mcp
```

If both n8n and this service run in Docker Compose, use:

```text
http://beestat-mcp:8000/mcp
```

If n8n is in Docker and this server is on host, use `host.docker.internal` instead of `127.0.0.1`.

Server config env vars:

- `BEESTAT_MCP_TRANSPORT` (`streamable-http`, `sse`, `stdio`)
- `BEESTAT_MCP_HOST` (default `0.0.0.0`)
- `BEESTAT_MCP_PORT` (default `8000`)
- `BEESTAT_MCP_STREAMABLE_HTTP_PATH` (default `/mcp`)
- `BEESTAT_MCP_MOUNT_PATH` (default `/`)
- `BEESTAT_MCP_SSE_PATH` (default `/sse`)
- `BEESTAT_MCP_MESSAGE_PATH` (default `/messages/`)

## Example MCP client config (Claude Desktop)

```json
{
  "mcpServers": {
    "beestat": {
      "command": "/home/lrw5016/projects/beestat-mcp/.venv/bin/beestat-mcp",
      "env": {
        "BEESTAT_API_KEY": "your_api_key"
      }
    }
  }
}
```

## Notes

- `arguments` are forwarded directly to beestat as JSON.
- `http_method` supports `GET` (default) and `POST`.
- If beestat returns `success: false`, the MCP tool now raises a clear error message.

## Troubleshooting

If your agent hangs after lines like:

```text
Calling MCP_Client with input: {"tool":"runtime_thermostat_read","arguments":{"thermostat_id":71384}}
```

check these first:

1. Endpoint/network:
   - If n8n and beestat-mcp are in different compose projects, `127.0.0.1` inside n8n is not your host.
   - Use `http://host.docker.internal:8000/mcp` (host service) or put both services on a shared Docker network and use `http://beestat-mcp:8000/mcp`.
2. Tool argument shape:
   - `runtime_thermostat_read` is not a good tool for "how long has heat run today".
   - Use `runtime_thermostat_summary_read_id` and aggregate summary fields for the target date.
3. Server logs:
   - `docker compose logs -f beestat-mcp`
   - If you see `beestat API error ...`, that message now surfaces directly to the agent.