Skip to main content
Glama
homeassistant-ai

Home Assistant MCP Server

Official

Evaluate Template

ha_eval_template
Read-onlyIdempotent

Debug and test Jinja2 template expressions for Home Assistant automations with real-time evaluation using current states and functions.

Instructions

Evaluate Jinja2 templates using Home Assistant's template engine.

This tool allows testing and debugging of Jinja2 template expressions that are commonly used in Home Assistant automations, scripts, and configurations. It provides real-time evaluation with access to all Home Assistant states, functions, and template variables.

When NOT to use this for automation/script logic: Templates have legitimate uses (notification bodies, dynamic data.* values, debugging existing templates), but condition: / trigger: positions and action service names are better expressed as native HA constructs: native constructs are schema-validated at config load and surface structural errors loudly, whereas equivalent template logic only errors at runtime — and a template that renders a non-truthy value is silently treated as false. Prefer:

  • condition: numeric_state over {{ states('x') | float > N }}

  • condition: state over {{ is_state(...) }}

  • condition: time / condition: sun over now().hour / is_state('sun.sun', ...)

  • Native for: field on state/numeric_state triggers and state conditions over {{ now() - X.last_changed > timedelta(...) }} duration math

  • choose action over templated service: / action: strings See ha_get_skill_guide (best-practices skill) for the full anti-pattern list.

When to use (reach for this tool, don't compute it yourself): Any one-shot question whose answer is DERIVED from current HA state — an average/sum/min/max across sensors, a count of entities matching a condition, a boolean comparison, or a rendered message with live values. One render call beats fetching N states and doing the math yourself, and it is the canonical way to test a template before embedding it. This is for one-shot answers and template testing only — NOT for putting templates into automation logic; for condition: / trigger: positions native constructs win.

  • "average temperature across the bedroom sensors" -> {{ ([states('sensor.a'), states('sensor.b')] | map('float', 0) | sum) / 2 }}

  • "how many lights are on" -> {{ states.light | selectattr('state', 'eq', 'on') | list | count }} NOT for a plain single-entity value ("what's the state of X") — that is ha_get_state / ha_search; rendering {{ states('X') }} there is over-use.

Parameters:

  • template: The Jinja2 template string to evaluate

  • timeout: Maximum evaluation time in seconds (default: 3)

  • report_errors: Whether to return detailed error information (default: True)

Common Template Functions:

State Access:

{{ states('sensor.temperature') }}              # Get entity state value
{{ states.sensor.temperature.state }}           # Alternative syntax
{{ state_attr('light.bedroom', 'brightness') }} # Get entity attribute
{{ is_state('light.living_room', 'on') }}       # Check if entity has specific state

Numeric Operations:

{{ states('sensor.temperature') | float(0) }}   # Convert to float with default
{{ states('sensor.humidity') | int(0) }}        # Convert to integer with default
{{ (states('sensor.temp') | float(0) + 5) | round(1) }} # Math operations

Time and Date:

{{ now() }}                                     # Current datetime
{{ now().strftime('%H:%M:%S') }}               # Format current time
{{ as_timestamp(now()) }}                      # Convert to Unix timestamp
{{ now().hour }}                               # Current hour (0-23)
{{ now().weekday() }}                          # Day of week (0=Monday)

Conditional Logic (for display strings — not for condition: positions):

{{ 'Day' if now().hour < 18 else 'Night' }}    # Ternary operator
{% if is_state('alarm_control_panel.home', 'armed_away') %}
  Alarm is armed
{% else %}
  Alarm is disarmed
{% endif %}

Lists and Loops:

{% for entity in states.light %}
  {{ entity.entity_id }}: {{ entity.state }}
{% endfor %}

{{ states.light | selectattr('state', 'eq', 'on') | list | count }} # Count on lights

String Operations:

{{ states('sensor.weather') | title }}         # Title case
{{ 'Hello ' + states('input_text.name') }}     # String concatenation
{{ states('sensor.data') | regex_replace('pattern', 'replacement') }}

Device and Area Functions:

{{ device_entities('device_id_here') }}        # Get entities for device
{{ area_entities('living_room') }}             # Get entities in area
{{ device_id('light.bedroom') }}               # Get device ID for entity

Common Use Cases (legitimate template positions):

Dynamic Service Data:

# Dynamic brightness based on time
{{ 255 if now().hour < 22 else 50 }}

# Message with current values
"Temperature is {{ states('sensor.temp') }}°C, humidity {{ states('sensor.humidity') }}%"

Examples:

Test basic state access:

ha_eval_template("{{ states('light.living_room') }}")

Test a string expression (e.g. for a notification body):

ha_eval_template("{{ 'Day' if now().hour < 18 else 'Night' }}")

Test mathematical operations:

ha_eval_template("{{ (states('sensor.temperature') | float(0) + 5) | round(1) }}")

Test entity counting:

ha_eval_template("{{ states.light | selectattr('state', 'eq', 'on') | list | count }}")

IMPORTANT NOTES:

  • Templates have access to all current Home Assistant states and attributes

  • Use this tool to test templates before using them in automations or scripts

  • Template evaluation respects Home Assistant's security model and timeouts

  • Complex templates may affect Home Assistant performance - keep them efficient

  • Use default values (e.g., | float(0)) to handle missing or invalid states

For template documentation: https://www.home-assistant.io/docs/configuration/templating/

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
timeoutNo
templateYes
report_errorsNo

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Behavior4/5

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

Annotations already provide readOnlyHint, idempotentHint, openWorldHint. Description adds context about access to all HA states, security model, timeouts, and performance impact. No contradiction with annotations.

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

Conciseness3/5

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

Well-structured with sections and examples, but overly verbose with a large catalog of common template functions. Could be more concise while retaining essential information.

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?

Covers purpose, usage guidelines, parameter details, common functions, examples, and important notes. Output schema exists, so return values need not be described. Complete for the tool's complexity.

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 description coverage is 0%, but the description compensates with a 'Parameters:' section giving clear one-line explanations for each parameter (template, timeout, report_errors). Adds meaning beyond the bare schema.

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?

Clearly states 'Evaluate Jinja2 templates using Home Assistant's template engine', with specific verb and resource. Distinguishes from sibling tools like ha_get_state and ha_search by explicitly stating when not to use for plain state queries and providing alternatives.

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-to-use (one-shot derived answers, template testing) and when-not-to-use (automation/script logic) guidance, with specific alternatives for native constructs. Includes examples and references to ha_get_skill_guide for best practices.

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

Install Server

Other Tools

Latest Blog Posts

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/homeassistant-ai/ha-mcp'

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