Skip to main content
Glama

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

cp .env.example .env # Edit .env and add your SMARTTHINGS_PAT

3. Build and Run

Using Docker

# 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

# Build and run docker compose build docker compose run --rm smartthings-mcp python -m app.main

Local Development

# 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

# Install dev dependencies pip install pytest pytest-asyncio httpx # Run tests pytest

Logging Levels

Set the log level via environment:

# 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

-
security - not tested
F
license - not found
-
quality - not tested

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