Skip to main content
Glama
homeassistant-ai

Home Assistant MCP Server

Official

Call Service

ha_call_service
Destructive

Control smart home entities and trigger automations by executing Home Assistant services like light.turn_on or climate.set_temperature.

Instructions

Execute Home Assistant services to control entities and trigger automations.

This is the universal tool for controlling all Home Assistant entities. Services follow the pattern domain.service (e.g., light.turn_on, climate.set_temperature).

Basic Usage:

# Turn on a light
ha_call_service("light", "turn_on", entity_id="light.living_room")

# Set temperature with parameters
ha_call_service("climate", "set_temperature",
              entity_id="climate.thermostat", data={"temperature": 22})

# Trigger automation
ha_call_service("automation", "trigger", entity_id="automation.morning_routine")

# Universal controls work with any entity
ha_call_service("homeassistant", "toggle", entity_id="switch.porch_light")

Key behavior:

  • Result compaction (default ON): result is trimmed to the targeted entity's record (drops parent-group propagation) and stripped of context / last_* metadata and heavy attribute lists (effect_list, hue_scenes). Escape hatches: verbose=True for the raw changed-state records, or result_fields / result_attribute_keys for explicit per-record projection (mirrors ha_get_state).

For detailed service documentation, use ha_get_skill_guide.

Common patterns: Use ha_get_state() to check current values before making changes. Use ha_search() to find correct entity IDs.

WebSocket command escape hatch (advanced): A few Home Assistant operations are WebSocket-only commands, not registered services — most notably dismissing a Repairs issue. Pass ws_command (instead of domain/service) to send one, with its parameters in data:

# Dismiss a repair (get domain/issue_id from ha_get_overview repairs
# or ha_get_system_health include="repairs")
ha_call_service(ws_command="repairs/ignore_issue",
                data={"domain": "sun", "issue_id": "abc", "ignore": True})

Only one-shot request/response commands are supported; streaming/two-phase and service-invoking commands are rejected, and the other service parameters (entity_id, return_response, etc.) don't apply.

Unavailable in Read Only Mode, including read-like services and WebSocket commands. Use dedicated read tools while that mode is enabled.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
dataNoExtra service-call parameters beyond entity_id (e.g. {'temperature': 22} for climate.set_temperature). Also carries the raw command payload when ws_command is set. If entity_id is also present in data, the entity_id parameter wins.
waitNoIf True (default), wait for the entity state to change before returning. Applies only to state-changing services called with a single entity_id. A comma-separated multi-target does not get confirmed by this: it falls through to a legacy path that polls for the literal composite entity_id and times out after 10s. Set wait=False for multi-target calls.
domainNoService domain (e.g. 'light', 'climate', 'automation'). Required for a service call; must be omitted when ws_command is set.
serviceNoService name within domain (e.g. 'turn_on', 'set_temperature', 'trigger'). Required for a service call; must be omitted when ws_command is set.
verboseNoReturn HA's raw changed-state records unchanged (default: False). Use as an escape hatch when you need the full propagation chain or raw attribute payload (debug / inspection). With return_response=True the response data still surfaces once as the top-level service_response key, never nested in result. WARNING: brings back token-bloat for nested-group targets — prefer result_fields / result_attribute_keys for targeted control.
entity_idNoEntity ID(s) the service call targets — one ID ('light.living_room') or several comma-separated ('light.a,light.b'). Optional for services that don't target a specific entity. Must be omitted when ws_command is set.
ws_commandNoAdvanced escape hatch: send a raw one-shot Home Assistant WebSocket command that is NOT a registered service (e.g. 'repairs/ignore_issue' to dismiss a Repairs issue). When set, omit domain/service and the other service params; put the command's parameters in data. Streaming/two-phase and service-invoking commands (call_service, execute_script) are rejected.
result_fieldsNoProject each record in 'result' to only these top-level keys (e.g. ['entity_id', 'state']). Mirrors ha_get_state's fields=. Setting this DISABLES default compaction — no entity-id filter, no metadata strip — and applies the explicit projection instead.
return_responseNoIf True, the service's response data is returned once, as the top-level 'service_response' key — never nested inside 'result' (default: False). Must stay False when ws_command is set.
result_attribute_keysNoProject each record's 'attributes' dict to only these keys (e.g. ['brightness', 'rgb_color']). Mirrors ha_get_state's attribute_keys=. Setting this DISABLES default compaction. Requires 'attributes' to be present in result_fields (or result_fields=None).

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed6 schema fields changedv8.4.1
    • addedInput schema / properties / data / description
      Added value: +"Extra service-call parameters beyond entity_id (e.g. {'temperature': 22} for climate.set_temperature). Also carries the raw command payload when ws_command is set. If entity_id is also present in data, the entity_id parameter wins."
    • addedInput schema / properties / domain / description
      Added value: +"Service domain (e.g. 'light', 'climate', 'automation'). Required for a service call; must be omitted when ws_command is set."
    • addedInput schema / properties / entity_id / description
      Added value: +"Entity ID(s) the service call targets — one ID ('light.living_room') or several comma-separated ('light.a,light.b'). Optional for services that don't target a specific entity. Must be omitted when ws_command is set."
    • addedInput schema / properties / return_response / description
      Added value: +"If True, the service's response data is returned once, as the top-level 'service_response' key — never nested inside 'result' (default: False). Must stay False when ws_command is set."
    • addedInput schema / properties / service / description
      Added value: +"Service name within domain (e.g. 'turn_on', 'set_temperature', 'trigger'). Required for a service call; must be omitted when ws_command is set."
    • addedInput schema / properties / wait / description
      Added value: +"If True (default), wait for the entity state to change before returning. Applies only to state-changing services called with a single entity_id. A comma-separated multi-target does not get confirmed by this: it falls through to a legacy path that polls for the literal composite entity_id and times out after 10s. Set wait=False for multi-target calls."
  2. Changed1 schema field changedv8.2.0
    • changedInput schema / properties / verbose / description
      Previous value: -"Return HA's raw service response unchanged (default: False). Use as an escape hatch when you need the full propagation chain or raw attribute payload (debug / inspection). WARNING: brings back token-bloat for nested-group targets — prefer result_fields / result_attribute_keys for targeted control."New value: +"Return HA's raw changed-state records unchanged (default: False). Use as an escape hatch when you need the full propagation chain or raw attribute payload (debug / inspection). With return_response=True the response data still surfaces once as the top-level service_response key, never nested in result. WARNING: brings back token-bloat for nested-group targets — prefer result_fields / result_attribute_keys for targeted control."
  3. First observedv7.14.2

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Despite annotations already carrying destructiveHint=true and readOnlyHint=false, the description adds substantial behavioral context: default result compaction that 'trims to the targeted entity's record' and strips context/last_* metadata, the ws_command escape hatch with explicit rejections of 'streaming/two-phase and service-invoking commands', and the Read Only Mode unavailability. The wait parameter's legacy-path fallback with '10s timeout' for multi-target calls is also disclosed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Long but every section earns its place: purpose statement, code examples, key behavior (compaction), advanced escape hatch, and mode restriction. The structure is front-loaded with the core purpose and examples before advanced topics, uses clear section headers and formatted code blocks. The density is proportionate to a universal 10-parameter tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Complete for a complex universal tool: covers invocation pattern, examples, result shaping behavior, escape hatches, rejected command types, and mode restrictions. With an output schema present, return values need not be re-explained. The only possible gap, detailed per-service parameters, is explicitly routed elsewhere: 'For detailed service documentation, use ha_get_skill_guide.'

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with already-detailed per-parameter descriptions, so baseline is 3. The description adds genuine value beyond the schema: concrete usage examples mapping data to service parameters (e.g., {'temperature': 22}), the entity_id-wins-over-data precedence, the interplay between result_fields/verbose and the default compaction behavior, and the wait=False recommendation for multi-target calls.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource: 'Execute Home Assistant services to control entities and trigger automations.' It then explicitly frames itself as 'the universal tool for controlling all Home Assistant entities' and explains the domain.service pattern with concrete examples. This clearly distinguishes it from siblings like ha_get_state (read), ha_call_event (events), and the config-mutation tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit when/when-not guidance: 'For detailed service documentation, use ha_get_skill_guide', 'Use ha_get_state() to check current values before making changes', 'Use ha_search() to find correct entity IDs', and 'Unavailable in Read Only Mode... Use dedicated read tools while that mode is enabled.' The ws_command section also clarifies when the advanced path applies versus registered services.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Deploy Server

Other Tools