Provides tools for controlling and querying SmartThings devices, including listing locations, rooms, and devices, checking device status and health, controlling switches, and monitoring refrigerator-specific attributes like temperature and door states.
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
Setup
1. Get a SmartThings Personal Access Token (PAT)
Click "Generate new token"
Give it a name (e.g., "MCP Server")
Select required scopes:
devices(read and execute)locations(read)
Copy the generated token
2. Configure Environment
3. Build and Run
Using Docker
Using Docker Compose
Local Development
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 toSMARTTHINGS_LOCATION_IDenv 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 locationroomId(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 forcommand(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 IDname(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 |
| ✅ Yes | - | SmartThings Personal Access Token |
| ❌ No | - | Default location ID for room queries |
| ❌ No |
| SmartThings API base URL |
| ❌ No |
| MCP transport method |
Development
Running Tests
Logging Levels
Set the log level via environment:
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_PATenvironment variableCheck that your PAT has the correct scopes
"No locations found"
Verify your PAT has
locations:readscopeCheck that you have at least one location in your SmartThings account
"Device not found"
Use
list_devices()to see available devicesEnsure 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:
Add tests for new features
Update documentation
Follow existing code style
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
This server cannot be installed