Skip to main content
Glama
README.md7.81 kB
# SmartThings MCP Server (Python) A production-ready, Dockerized MCP (Model Context Protocol) server for controlling and querying SmartThings devices via Personal Access Token (PAT). ## Features - ✅ **Fully Async**: Efficient async/await implementation with proper resource management - ✅ **Comprehensive Logging**: Detailed logging for debugging and monitoring - ✅ **Type Safety**: Full type hints and Pydantic validation - ✅ **Error Handling**: Structured error handling with meaningful messages - ✅ **Optimized API Calls**: Direct device lookups to minimize API requests - ✅ **Docker Best Practices**: Non-root user, health checks, minimal image size - ✅ **Resource Cleanup**: Proper HTTP client lifecycle management ## Project Structure ``` . ├── Dockerfile # Production-ready Docker image ├── docker-compose.yml # Docker Compose configuration ├── .dockerignore # Docker build exclusions ├── .env.example # Environment variable template ├── requirements.txt # Python dependencies ├── app/ │ ├── __init__.py │ ├── main.py # MCP server and tool definitions │ └── smartthings.py # SmartThings API client └── README.md # This file ``` ## Setup ### 1. Get a SmartThings Personal Access Token (PAT) 1. Visit https://account.smartthings.com/tokens 2. Click "Generate new token" 3. Give it a name (e.g., "MCP Server") 4. Select required scopes: - `devices` (read and execute) - `locations` (read) 5. Copy the generated token ### 2. Configure Environment ```bash cp .env.example .env # Edit .env and add your SMARTTHINGS_PAT ``` ### 3. Build and Run #### Using Docker ```bash # Build the image docker build -t smartthings_mcp:latest . # Run with stdio transport docker run --rm -i \ -e SMARTTHINGS_PAT=$SMARTTHINGS_PAT \ -e SMARTTHINGS_LOCATION_ID=$SMARTTHINGS_LOCATION_ID \ smartthings_mcp:latest ``` #### Using Docker Compose ```bash # Build and run docker compose build docker compose run --rm smartthings-mcp python -m app.main ``` #### Local Development ```bash # Install dependencies pip install -r requirements.txt # Set environment variables export SMARTTHINGS_PAT="your_pat_here" # Run the server python -m app.main ``` ## Available Tools ### `list_locations()` List all SmartThings locations accessible with the current PAT. **Returns**: List of location objects with `locationId`, `name`, and metadata. --- ### `list_rooms(locationId?)` List all rooms in a SmartThings location. **Parameters**: - `locationId` (optional): The location ID. Falls back to `SMARTTHINGS_LOCATION_ID` env var or first available location. **Returns**: List of room objects with `roomId`, `name`, and metadata. --- ### `list_devices(locationId?, roomId?)` List all SmartThings devices, optionally filtered by location and/or room. **Parameters**: - `locationId` (optional): Filter devices by location - `roomId` (optional): Filter devices by room **Returns**: List of device objects with `deviceId`, `label`, `capabilities`, and metadata. --- ### `device_status({ deviceId?, name? })` Get the current status of a SmartThings device. **Parameters**: - `deviceId` (optional): The unique device ID (preferred for efficiency) - `name` (optional): Device name/label to search for (slower, searches all devices) **Returns**: Device information with current status and flattened summary. **Note**: Provide at least one of `deviceId` or `name`. --- ### `switch_device({ deviceId?, name?, command, component? })` Turn a SmartThings switch device on or off. **Parameters**: - `deviceId` (optional): The unique device ID (preferred) - `name` (optional): Device name/label to search for - `command` (required): Either `"on"` or `"off"` - `component` (optional): Device component (default: `"main"`) **Returns**: Device information and command execution result. --- ### `fridge_status({ deviceId?, name? })` Get detailed status of a SmartThings refrigerator/fridge device. **Parameters**: - `deviceId` (optional): The unique device ID - `name` (optional): Device name/label to search for **Returns**: Refrigerator-specific status summary including: - Power state - Refrigerator and freezer temperatures - Door open/closed state - Ice maker status - Defrost mode - All temperature, door, ice, humidity, and energy-related attributes **Note**: If neither parameter is provided, automatically searches for devices with "fridge" or "refrigerator" in the name. --- ### `device_health(deviceId)` Get the health status of a SmartThings device. **Parameters**: - `deviceId` (required): The unique device ID **Returns**: Device health information including online/offline state. ## Architecture Improvements ### Async Design - All tools are fully async for better concurrency - Uses a single HTTP client with connection pooling - Proper cleanup on shutdown via lifespan handler ### Error Handling - Pydantic validation for all inputs - Structured error messages - Graceful fallbacks (e.g., health check returns "unknown" instead of failing) ### Performance Optimizations - Direct device GET endpoint when using `deviceId` (avoids listing all devices) - Efficient device search with early exit - Connection reuse across all requests ### Security - Runs as non-root user in Docker - Minimal attack surface (no exposed ports) - Token never logged ### Logging - Comprehensive logging at INFO and DEBUG levels - Structured log format with timestamps - Request/response logging for debugging ## Environment Variables | Variable | Required | Default | Description | |----------|----------|---------|-------------| | `SMARTTHINGS_PAT` | ✅ Yes | - | SmartThings Personal Access Token | | `SMARTTHINGS_LOCATION_ID` | ❌ No | - | Default location ID for room queries | | `SMARTTHINGS_BASE_URL` | ❌ No | `https://api.smartthings.com/v1` | SmartThings API base URL | | `MCP_TRANSPORT` | ❌ No | `stdio` | MCP transport method | ## Development ### Running Tests ```bash # Install dev dependencies pip install pytest pytest-asyncio httpx # Run tests pytest ``` ### Logging Levels Set the log level via environment: ```bash # Debug level (verbose) export LOG_LEVEL=DEBUG # Info level (default) export LOG_LEVEL=INFO # Warning level (quiet) export LOG_LEVEL=WARNING ``` ### Code Style This project follows: - PEP 8 style guide - Type hints for all functions - Docstrings for all public APIs ## Troubleshooting ### "SMARTTHINGS_PAT is required" - Ensure you've set the `SMARTTHINGS_PAT` environment variable - Check that your PAT has the correct scopes ### "No locations found" - Verify your PAT has `locations:read` scope - Check that you have at least one location in your SmartThings account ### "Device not found" - Use `list_devices()` to see available devices - Ensure the device name or ID is correct (case-insensitive for names) - Check that the device is in the specified location/room if filters are applied ### HTTP Timeout Errors - Increase timeout in `smartthings.py` (default: 15s) - Check network connectivity to SmartThings API ## License MIT License - feel free to use and modify as needed. ## Contributing Contributions welcome! Please: 1. Add tests for new features 2. Update documentation 3. Follow existing code style 4. Ensure all tests pass ## Changelog ### v2.0.0 (Current) - ✅ Full async/await implementation - ✅ Comprehensive logging and error handling - ✅ Optimized API calls with direct device lookups - ✅ Docker best practices (non-root user, health checks) - ✅ Pydantic validation for all inputs - ✅ Proper resource cleanup - ✅ Complete type hints and docstrings ### v1.0.0 (Original) - Basic MCP server implementation - Synchronous tool functions - Basic error handling

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/bjornhovd/Samsung-SmartThings-MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server