Skip to main content
Glama
cinderl
by cinderl
README.md
# Congatudo MCP Server

HTTP MCP server (SSE transport) that exposes your [Congatudo](https://congatudo.cloud)-powered Cecotec Conga robot vacuum as **26 tools** for AI agents (Claude, Cursor, OpenAI Agents SDK, etc.).

## Quick Start

```bash
# 1. Clone and configure
cp .env.example .env
# Edit .env → set CONGATUDO_HOST to your robot's IP

# 2. Build and start
docker compose up -d

# 3. Connect any MCP client to:
#    http://<host>:8114/sse
```

## Environment Variables

| Variable | Default | Description |
|---|---|---|
| `CONGATUDO_HOST` | `192.168.25.158` | Robot IP address |
| `CONGATUDO_PORT` | `80` | Robot HTTP port |
| `CONGATUDO_API_PREFIX` | `/api/v2` | REST API base path |
| `CONGATUDO_USERNAME` | *(empty)* | HTTP Basic Auth username (optional) |
| `CONGATUDO_PASSWORD` | *(empty)* | HTTP Basic Auth password (optional) |
| `MCP_SERVER_HOST` | `0.0.0.0` | MCP SSE bind address |
| `MCP_SERVER_PORT` | `8114` | MCP SSE port |

## Tools

### State
- **`get_robot_state`** — full state (status, battery, attachments, map)
- **`get_robot_state_attributes`** — status / battery / attachment attributes
- **`get_robot_map`** — raw map JSON

### Control
- **`basic_control(action)`** — start / pause / stop / home
- **`locate_robot()`** — plays a sound to find the robot
- **`manual_control(action, movement_command?)`** — check / enable / disable / move

### Cleaning Modes
- **`clean_zone(zones, iterations?)`** — clean rectangular zone(s)
- **`clean_segments(segment_ids, iterations?, custom_order?)`** — clean specific rooms
- **`go_to_location(x, y)`** — send robot to map coordinates

### Settings (fan + water)
- **`get_fan_presets()`** / **`set_fan_speed(name)`** — suction power
- **`get_water_presets()`** / **`set_water_usage(name)`** — mopping water flow

### Consumables
- **`get_consumables()`** — wear levels
- **`reset_consumable(type, sub_type?)`** — reset after replacement

### Timers (cron-based)
- **`get_timers()`** / **`create_timer(...)`** / **`update_timer(id, ...)`** / **`delete_timer(id)`** / **`toggle_timer(id)`**

### Do Not Disturb
- **`get_dnd_config()`** / **`set_dnd_config(enabled, start, end)`** — quiet hours

### System
- **`get_capabilities()`** — list what your robot supports
- **`get_robot_info()`** — manufacturer, model, implementation
- **`get_wifi_status()`** — SSID, RSSI, frequency, IPs
- **`get_system_info()`** — hostname, arch, uptime, CPU, memory

Call **`get_capabilities()`** first — if a capability isn't listed, its tool will return a clean error.

## Testing

A bash script validates the MCP connection and exercises 5 key tools:

```bash
./test_get_capabilities.sh
# or against a remote host:
./test_get_capabilities.sh http://192.168.1.100:8114
```

It performs the full MCP handshake, calls `get_capabilities`, `get_fan_presets`, `get_consumables`, `locate_robot` (beeps the robot), and `basic_control(action=home)` (sends robot to dock). Output:

```
--- MCP Congatudo Test ---
1. get_capabilities              PASS  (21 capabilities)
2. get_fan_presets               PASS  (4 presets)
3. get_consumables               PASS  (4 consumables)
4. locate_robot                  PASS  (robot beeps)
5. basic_control (HOME)          PASS  (robot returns to dock)
--- Results: 5 passed, 0 failed ---
```

## MCP Integration

### Claude Desktop

Add to your `claude_desktop_config.json`:

```json
{
  "mcpServers": {
	  "Congatudo": {
      "command": "mcp-proxy.exe",
      "env": {
        "SSE_URL": "http://localhost:8114/sse"
      }		
    }
  }
}
```

### Cursor

In Cursor Settings → MCP Servers → Add new:

- **Name:** `congatudo`
- **Type:** `SSE`
- **URL:** `http://192.168.1.100:8114/sse`

### Opencode

Add to your `opencode.json` or `.opencode.json`:

```json
{
  "mcp": {
    "congatudo": {
      "transport": "sse",
      "url": "http://192.168.1.100:8114/sse"
    }
  }
}
```

### OpenAI Agents SDK (Python)

```python
from agents import Agent, Runner
from agents.mcp import MCPServerSse

async with MCPServerSse(
    name="Congatudo",
    params={"url": "http://192.168.1.100:8114/sse"},
) as server:
    agent = Agent(name="Vacuum", mcp_servers=[server])
    await Runner.run(agent, "Start cleaning the kitchen")
```

### Any MCP Client

Point your client to:

```
http://<host>:8114/sse
```

Then call `get_capabilities()` first to discover what your robot supports.

## Docker Commands

```bash
docker compose build      # Build the image
docker compose up -d      # Start in background
docker compose logs -f    # Follow logs
docker compose down       # Stop
```