jango-blockchained 344c43a22f Add Docker support and enhance configuration management
- Introduced Dockerfile for building and running the application in a containerized environment.
- Added .dockerignore to exclude unnecessary files from the Docker context.
- Updated README.md with detailed Docker installation instructions and Node.js version management using nvm.
- Refactored environment variable handling in src/index.ts and src/config/hass.config.ts for improved configuration management.
- Enhanced TypeScript configuration to include JSON module resolution and updated exclusion patterns.
- Updated .gitignore to include additional files for better environment management.
2024-12-16 14:37:25 +01:00
2024-12-11 22:30:27 -08:00

A Model Context Protocol Server for Home Assistant

The server uses the MCP protocol to share access to a local Home Assistant instance with an LLM application. It provides a comprehensive interface for controlling various Home Assistant entities through natural language.

Features

  • Entity Control: Full support for controlling common Home Assistant entities:
    • 💡 Lights: Brightness, color temperature, RGB color
    • 🌡️ Climate: Temperature, HVAC modes, fan modes, humidity
    • 🚪 Covers: Position control, tilt control
    • 🔌 Switches: Basic on/off control
    • 🚨 Contacts: State monitoring
  • Entity State Access: Query and monitor entity states
  • Area and Floor Organization: Logical grouping of devices
  • Robust Error Handling: Clear error messages and state validation

Prerequisites

  • Node.js 20.10.0 or higher (Required for Array.prototype.toSorted())
  • NPM package manager
  • A running Home Assistant instance
  • A long-lived access token from Home Assistant

Node.js Version Management

If you're using an older version of Node.js, you can use nvm (Node Version Manager) to install and use the correct version:

# Install nvm (if not already installed)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash

# Reload shell configuration
source ~/.bashrc  # or source ~/.zshrc for Zsh

# Install Node.js 20.10.0
nvm install 20.10.0

# Use Node.js 20.10.0
nvm use 20.10.0

Installation

Classic Installation

# Clone the repository
git clone https://github.com/jango-blockchained/homeassistant-mcp.git
cd homeassistant-mcp

# Install dependencies
npm install

# Build the server
npm run build

Docker Installation

  1. Clone the repository:

    git clone https://github.com/jango-blockchained/homeassistant-mcp.git
    cd homeassistant-mcp
    
  2. Create a .env file with your Home Assistant configuration:

    NODE_ENV=production
    HASS_HOST=your_home_assistant_url
    HASS_TOKEN=your_home_assistant_token
    
  3. Start the container:

    docker-compose up -d
    

Using Docker Directly

  1. Build the image:

    docker build -t homeassistant-mcp .
    
  2. Run the container:

    docker run -d \
      --name homeassistant-mcp \
      -e HASS_HOST=your_home_assistant_url \
      -e HASS_TOKEN=your_home_assistant_token \
      -p 3000:3000 \
      homeassistant-mcp
    

Docker Management Commands

# Stop the container
docker-compose down

# View logs
docker-compose logs -f

# Restart the container
docker-compose restart

# Update to latest version
git pull
docker-compose up -d --build

Configuration

  1. Home Assistant Token

  2. Environment Variables Create a .env file with:

    NODE_ENV=development
    HASS_HOST=your_home_assistant_url  # e.g., http://homeassistant.local:8123
    HASS_TOKEN=your_home_assistant_token
    
  3. MCP Client Configuration Configure your MCP client (like Claude Desktop) with:

    {
        "mcpServers": {
            "homeassistant": {
                "command": "node",
                "args": [
                    "/path/to/dist/index.js"
                ],
                "env": {
                    "HASS_TOKEN": "your_home_assistant_token",
                    "HASS_HOST": "your_home_assistant_url"
                }
            }
        }
    }
    

How to Use

The server provides two main tools for interacting with Home Assistant:

1. List Devices Tool

Use this tool to discover all available devices and their current states:

{
  "tool": "list_devices"
}

This will return a structured response with all devices grouped by domain:

{
  "success": true,
  "devices": {
    "light": [
      {
        "entity_id": "light.living_room",
        "state": "on",
        "attributes": {
          "brightness": 128,
          "color_temp": 4000,
          "friendly_name": "Living Room Light"
        }
      }
    ],
    "climate": [
      {
        "entity_id": "climate.bedroom",
        "state": "heat",
        "attributes": {
          "temperature": 22,
          "hvac_mode": "heat",
          "friendly_name": "Bedroom Thermostat"
        }
      }
    ]
  }
}

2. Control Tool

Use this tool to control your devices. Here are some common usage examples:

Light Control

// Turn on a light
{
  "tool": "control",
  "command": "turn_on",
  "entity_id": "light.living_room"
}

// Set brightness
{
  "tool": "control",
  "command": "turn_on",
  "entity_id": "light.living_room",
  "brightness": 128
}

// Set color temperature
{
  "tool": "control",
  "command": "turn_on",
  "entity_id": "light.living_room",
  "color_temp": 4000
}

// Set RGB color (red)
{
  "tool": "control",
  "command": "turn_on",
  "entity_id": "light.living_room",
  "rgb_color": [255, 0, 0]
}

Climate Control

// Set temperature
{
  "tool": "control",
  "command": "set_temperature",
  "entity_id": "climate.living_room",
  "temperature": 22
}

// Set HVAC mode
{
  "tool": "control",
  "command": "set_hvac_mode",
  "entity_id": "climate.living_room",
  "hvac_mode": "heat"
}

// Set fan mode
{
  "tool": "control",
  "command": "set_fan_mode",
  "entity_id": "climate.living_room",
  "fan_mode": "auto"
}

Cover Control

// Open/Close cover
{
  "tool": "control",
  "command": "open_cover",  // or "close_cover"
  "entity_id": "cover.living_room"
}

// Set position
{
  "tool": "control",
  "command": "set_position",
  "entity_id": "cover.living_room",
  "position": 50
}

// Set tilt
{
  "tool": "control",
  "command": "set_tilt_position",
  "entity_id": "cover.living_room",
  "tilt_position": 45
}

Switch Control

// Turn on/off
{
  "tool": "control",
  "command": "turn_on",  // or "turn_off"
  "entity_id": "switch.office"
}

// Toggle
{
  "tool": "control",
  "command": "toggle",
  "entity_id": "switch.office"
}

Error Handling

The server provides clear error messages when something goes wrong:

{
  "success": false,
  "message": "Failed to execute set_temperature for light.living_room: Unsupported operation for domain: light"
}

Common error scenarios:

  1. Invalid entity ID
  2. Unsupported operation for domain
  3. Invalid parameter values
  4. Home Assistant connection issues

Best Practices

  1. Entity Discovery

    • Always use list_devices first to discover available entities
    • Note the supported attributes for each device
  2. Parameter Validation

    • Brightness: 0-255
    • Position/Tilt: 0-100
    • Temperature: Depends on your system's configuration
    • Color temperature: Typically 2000-6500K
  3. Error Recovery

    • If a command fails, check:
      • Entity ID exists and is correct
      • Command is supported by the domain
      • Parameters are within valid ranges
  4. State Awareness

    • Use list_devices to check current state before making changes
    • Verify command execution by checking state afterward

Development

# Run in development mode
yarn dev

# Build and start
yarn build:start

# Run tests
yarn test

Troubleshooting

Common Issues

  1. Node.js Version Error (positive.toSorted is not a function)

    • This error occurs when using Node.js version lower than 20
    • Solution: Update to Node.js 20.10.0 or higher using nvm (see Prerequisites section)
    • Docker users: The container automatically uses the correct Node.js version
  2. Connection Errors

    • Verify your Home Assistant instance is running
    • Check the HASS_HOST is correct and accessible
    • Ensure your token has the required permissions

Project Status

Completed

  • Access to entities
  • Access to Floors
  • Access to Areas
  • Control for entities
    • Lights
    • Thermostats
    • Covers
    • Contacts
    • Climates
    • Switches

In Progress

  • Testing / writing custom prompts
  • Testing using resources for high-level context
  • Test varying tool organization

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create a feature branch
  3. Commit your changes
  4. Push to the branch
  5. Create a Pull Request

License

This project is licensed under the MIT License - see the LICENSE file for details.

Using with LLMs (AI Assistants)

The MCP server is designed to work seamlessly with AI language models. Here's how to interact with your Home Assistant using natural language:

Natural Language Examples

  1. Discovering Devices

    "What devices do I have in my home?"
    "Show me all my lights"
    "List the climate controls in the bedroom"
    

    The LLM will use the list_devices tool to fetch and present this information in a human-readable format.

  2. Basic Controls

    "Turn on the living room lights"
    "Set the bedroom temperature to 22 degrees"
    "Close all the blinds"
    

    The LLM will translate these commands into appropriate tool calls using the control tool.

  3. Complex Operations

    "Make the living room cozy for movie night"
    → LLM might:
    - Dim the lights (set brightness to 30%)
    - Set warm color temperature
    - Lower the blinds
    - Adjust the temperature
    
    "Set up my morning routine"
    → LLM might:
    - Open the bedroom blinds
    - Turn on specific lights
    - Adjust the thermostat
    
  4. State-Aware Commands

    "Is my front door closed?"
    "Which lights are currently on?"
    "What's the temperature in the bedroom?"
    

    The LLM will check current states using list_devices before responding.

Context and Memory

The LLM can maintain context across multiple interactions:

User: "How warm is it in the bedroom?"
LLM: [checks temperature] "The bedroom is currently 20°C"
User: "Make it a bit warmer"
LLM: [remembers context, adjusts by reasonable increment] "I'll increase it to 22°C"

Natural Parameter Handling

The LLM can interpret natural language into specific parameters:

"Make the lights very dim" → brightness: 10%
"Set a comfortable temperature" → temperature: 21-23°C
"Change the lights to a warm color" → color_temp: ~2700K

Intelligent Error Prevention

The LLM will:

  1. Validate commands before execution
  2. Check device capabilities
  3. Ensure parameters are within acceptable ranges
  4. Provide helpful feedback if a command can't be executed

Example:

User: "Set the kitchen light to blue"
LLM: [checks if the light supports RGB]
- If supported: Sets rgb_color to [0, 0, 255]
- If not supported: "I'm sorry, but your kitchen light doesn't support color changes. I can only adjust its brightness."

Best Practices for LLM Interactions

  1. Be Specific with Locations

    • Good: "Turn on the kitchen lights"
    • Better: "Turn on the lights above the kitchen counter"
  2. Use Natural Increments

    • "Make it a little brighter" → +20% brightness
    • "Make it much warmer" → +3-4°C
  3. Group Related Commands

    "Set up the living room for watching TV:
    - Dim the lights to 20%
    - Set them to a warm color
    - Lower the blinds
    - Set the temperature to 22 degrees"
    
  4. Ask for Confirmation

    User: "Turn off all lights"
    LLM: "I'll turn off all 12 lights in your home. Would you like me to proceed?"
    

Handling Complex Scenarios

  1. Conditional Commands

    "If the temperature is above 25°C, turn on the fan"
    → LLM will:
    1. Check current temperature
    2. Execute command if condition is met
    
  2. Time-Based Context

    "Set up my evening lighting"
    → LLM considers:
    - Time of day
    - Current light levels
    - User preferences
    
  3. Multi-Room Coordination

    "Prepare the house for bedtime"
    → LLM orchestrates:
    - Turning off main living area lights
    - Dimming hallway lights
    - Setting night mode temperatures
    - Ensuring doors are locked
    

Troubleshooting with LLMs

The LLM can help diagnose issues:

User: "The living room lights aren't responding"
LLM: Let me check:
1. Verifies device availability
2. Checks current state
3. Reviews recent commands
4. Suggests potential solutions

Security Considerations

  1. Confirmation for Critical Actions

    • The LLM will ask for confirmation before:
      • Controlling security devices
      • Making large temperature changes
      • Executing commands affecting multiple devices
  2. Permission Awareness

    • The LLM respects device permissions
    • Provides clear feedback when actions aren't permitted
Description
An advanced MCP server for Home Assistant. 🔋 Batteries included.
Readme Apache-2.0 2.6 MiB
Languages
TypeScript 92.2%
Shell 3.4%
Python 2.3%
JavaScript 1.7%
Dockerfile 0.4%