ha-mcp-readonly Server

Máy chủ MCP (Model Context Protocol) chỉ đọc dành cho Home Assistant. Cung cấp cho các trợ lý AI (Claude Desktop, LibreChat, Cline) khả năng quan sát toàn diện ngôi nhà thông minh của bạn — trạng thái thực thể, tự động hóa, tập lệnh, thiết bị, nhật ký, chẩn đoán — mà không có quyền ghi. Đồng thời tạo các ảnh chụp nhanh ngữ cảnh AI tĩnh cho hệ thống RAG, ChatGPT Projects, Qwen và các công cụ khác chấp nhận tệp kiến thức tùy chỉnh. Được xây dựng bằng Python, chạy ở mọi nơi — cục bộ, trong Docker hoặc dưới dạng tích hợp MCP.

Tài liệu

HA-MCP-Readonly

CI Docker Python 3.11+ License: MIT

Read-only MCP (Model Context Protocol) server for Home Assistant. Gives AI assistants (Claude Desktop, LibreChat, Cline) full observability into your smart home — entity states, automations, scripts, devices, logs, diagnostics — without any write access. Also generates static AI context snapshots for RAG systems, ChatGPT Projects, Qwen, and other tools that accept custom knowledge files. Built in Python, runs anywhere — locally, in Docker, or as an MCP integration.

Requirements

  • Python 3.11+ (for local use) or Docker
  • A Home Assistant instance with a long-lived access token
    • Create one in your HA profile: Settings → Security → Long-Lived Access Tokens
  • Access to your Home Assistant config directory (for filesystem tools)

Quick Start

1. Configure environment

cp .env.example .env

Edit .env with your credentials:

HA_URL=http://your-ha-ip:8123
HA_TOKEN=your_long_lived_access_token_here
# HA_CONFIG_PATH=/config                # optional, default shown
# MCP_DEV_TOOLS_ENABLED=1               # optional, default shown
# HEALTH_CHECK_PORT=9091             # optional, default shown
# MCP_SSE_PORT=9092                   # optional, default shown
# REST_API_PORT=9093                 # optional, default shown
# RUN_TESTS_ON_STARTUP=0             # optional, default shown
# OUTPUT_PATH=/app/output/ha-ai-context.md  # optional, default shown

IMPORTANT: The .env file contains your access token. It is gitignored and must never be committed.

2. Run with Docker

First, configure your credentials. Either use a .env file (recommended) or pass variables directly.

Option A — with .env file and docker compose:

cp .env.example .env
# edit .env with your HA_URL and HA_TOKEN
docker compose up -d

The included docker-compose.yml pulls the image from GitHub Container Registry and mounts your HA config read-only:

services:
  ha-mcp-readonly:
    image: ghcr.io/paulomac1000/ha-mcp-readonly:latest
    container_name: ha-mcp-readonly
    env_file: .env
    ports:
      - "9091:9091"  # health
      - "9092:9092"  # MCP SSE
      - "9093:9093"  # REST API
    volumes:
      - /path/to/ha/config:/config:ro  # Replace with your HA config path (e.g., /config, ~/.homeassistant)
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-fsS", "http://localhost:9091/health"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 15s

Option B — with plain docker run:

docker run -d \
  --name ha-mcp-readonly \
  -p 9091:9091 \
  -p 9092:9092 \
  -p 9093:9093 \
  -e HA_URL=http://your-ha-ip:8123 \
  -e HA_TOKEN=your_token \
  -v /path/to/ha/config:/config:ro \
  ghcr.io/paulomac1000/ha-mcp-readonly:latest

Building locally:

docker build -t ha-mcp-readonly .
docker compose -f docker-compose.build.yml up -d

3. Run locally (Python 3.11+)

pip install -r requirements.txt
HA_URL=http://localhost:8123 HA_TOKEN=your_token python server.py

Ports

PortProtocolPurposeEndpoint
9091HTTPHealth checkGET /health
9092SSEMCP transport/sse, /messages
9093HTTPREST API + Context Generator/api/*

Verify

# Health check
curl http://localhost:9091/health

# List all MCP tools
curl http://localhost:9093/api/tools

# Generate a context snapshot
curl -X POST http://localhost:9093/api/context/generate \
  -H "Content-Type: application/json" \
  -d '{"mode": "hybrid"}'

Available Tools (158 with dev tools, 145 without)

Tools are organized by category (75 shown in table below). All are read-only — no state changes, no service calls, no modifications.

CategoryKey tools
Statesget_entity_state, get_states_grouped, search_entities, get_domains_summary, get_system_overview
Automationslist_automations, get_automation_code, get_automation_file_location, diagnose_automation, search_automations_by_entity, get_automation_conflicts, get_automation_entity_id
Scripts & Sceneslist_scripts, get_script_code, list_scenes, get_scene_code
Blueprintslist_blueprints, get_blueprint_code, get_blueprint_instances, get_blueprint_usage_summary, resolve_blueprint_automation
Devices & Areasget_device_details, search_devices, get_devices_by_area, get_area_devices_summary
Config entriesget_config_entry_details, search_config_entries, diagnose_config_entry, list_config_entry_domains
Integrationsget_integration_entities, get_integration_summary
Diagnosticsdiagnose_system_health, get_unavailable_entities_grouped, get_integration_health, diagnose_person_tracking
Logsget_log_insights, analyze_log_errors, get_startup_errors, get_log_timeline, search_logs
Historyget_entity_state_history_summary, get_recent_state_changes
Contextentity_get_context_tree, get_entity_dependencies, get_entity_consumers, get_context_chain
Configget_main_configuration, search_in_config, validate_yaml_syntax, read_config_file
Storagesearch_registries_batch, get_entity_registry, get_device_registry, get_area_registry, get_template_entity_code, get_cache_stats
Lovelaceget_lovelace_dashboards, get_lovelace_config, get_lovelace_resources, search_lovelace_config, get_lovelace_config_summary, diagnose_lovelace_setup
Batchbulk_search_entities, compare_entities_state, validate_yaml_batch, get_automation_codes_batch
Compositeinvestigate_entity, get_area_diagnostic, get_entity_with_automations, audit_config_orphans
Graphgraph_build_index, graph_find_references, graph_entity_impact, graph_get_neighbors, graph_detect_ghost_references, graph_detect_orphans, graph_export_mermaid
Dev toolstest_template, compare_templates, diagnose_entity, check_entity_exists, validate_automation_trigger, diagnose_template

Full tool catalog with schemas available at GET /api/tools

What's New in v1.6.0

  • 5 new tools: get_context_chain (Context), resolve_blueprint_automation (Blueprints), get_cache_stats (Storage), compare_templates (Dev tools), get_automation_entity_id (Automations)
  • choose_analysis in diagnose_automation: When detail_level="full", returns conditional branch analysis for automations using choose actions
  • Registry pagination: limit and offset parameters added to get_entity_registry, get_device_registry, get_area_registry, and get_config_entries for efficient scanning of large registries
  • data_quality field: Composite diagnostic tools (investigate_entity, get_area_diagnostic, get_entity_with_automations) now include a data_quality assessment flagging stale sensors, missing entities, and unavailable devices
  • New pre-commit hooks: mypy strict, Bandit, Semgrep, and AFDS documentation validation added to the pre-commit pipeline
  • Test infrastructure: 67 integration tests and 158 E2E tests for expanded real-HA and end-to-end coverage

Claude Desktop Configuration

Add the following to your Claude Desktop config:

macOS: ~/Library/Application Support/Claude/claude_desktop_config.json Linux: ~/.config/Claude/claude_desktop_config.json Windows: %APPDATA%\Claude\claude_desktop_config.json

{
  "mcpServers": {
    "ha-mcp-readonly": {
      "url": "http://localhost:9092/sse"
    }
  }
}

After restarting Claude Desktop, the 139 Home Assistant tools will be available (127 without dev tools enabled).

LibreChat

mcpServers:
  ha-mcp-readonly:
    url: http://ha-mcp-readonly:9092/sse
    timeout: 30000

Context Generator

Generates a comprehensive Markdown snapshot of your entire Home Assistant instance. Designed for scenarios where live MCP access isn't available or desired:

Use cases:

  • RAG systems — use the generated file as a knowledge base for retrieval-augmented generation (e.g., with LangChain, LlamaIndex, or custom RAG pipelines)
  • ChatGPT Projects / Qwen / Claude Projects — upload the file as custom knowledge to give the AI full awareness of your smart home without network access to HA
  • Static context for AI coding tools — provide the file alongside your codebase so AI assistants understand your automations, devices, and entity relationships
  • Documentation snapshots — freeze configuration state for auditing, debugging, or sharing with other users

Modes:

ModeDescription
offlineReads only from local filesystem (/config), no API calls
onlineFetches data from HA REST API (states, history, config)
hybridCombines offline and online data (default)

The generated file includes entity inventory, automation analysis, script/scene listing, dashboard usage, log error patterns, device topology, config entry health, blueprint usage, and template entity references.

# Via REST API
curl -X POST http://localhost:9093/api/context/generate \
  -H "Content-Type: application/json" \
  -d '{"mode": "hybrid"}'

curl http://localhost:9093/api/context/download > ha-ai-context.md

REST API

The REST API on port 9093 provides HTTP access to all tools and the context generator with an OpenAPI schema.

# List tools
curl http://localhost:9093/api/tools

# Call a tool
curl -X POST http://localhost:9093/api/tools/get_entity_state \
  -H "Content-Type: application/json" \
  -d '{"entity_id": "sun.sun"}'

# OpenAPI schema
curl http://localhost:9093/api/openapi.json

Development

Setup

git clone https://github.com/paulomac1000/ha-mcp-readonly.git
cd ha-mcp-readonly
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt

Run tests

# Unit tests (no credentials needed, 1142 tests, <20s)
pytest tests/unit/ -q

# Smoke tests (requires local MCP server, 84 tests, <5s)
pytest tests/smoke/ -q

# Integration tests (requires real HA, 278 tests, ~2min)
export HA_URL=http://your-ha:8123
export HA_TOKEN=your_token
pytest tests/integration/ -q

# E2E tests (requires real HA + local MCP server, 182 tests, ~30s)
pytest tests/e2e/ -q

# All tests
pytest tests/unit/ tests/smoke/ tests/e2e/ tests/integration/ -q

All unit tests use mocked dependencies — no real Home Assistant instance required. 1602 total tests across 4 suites.

Lint & format

ruff check .
ruff format --check .

Architecture

server.py                  # Main entry point — FastMCP + REST API + health check
context_generator/
├── core.py                # Entry points: main(), generate_context_file()
├── analyzers.py           # RegistryCollector, AutomationAnalyzer, LogAnalyzer, etc.
├── formatters.py          # ReportGenerator — Markdown output
├── constants.py           # ENTITY_PATTERN, HA URLs, ignorable domains, YAML loader
└── utils.py               # Registry cache, HA API client, YAML helpers

ha_graph/
└── graph_builder.py       # HA Semantic Graph: build, query, and export

tools/
├── automations.py         # Automation analysis (17 tools)
├── batch_operations.py    # Bulk entity operations (5 tools)
├── blueprints.py          # Blueprint management (4 tools)
├── capabilities.py        # Zero-I/O MCP introspection tool catalog (1 tool)
├── categories.py          # Category management (automation, script, scene, helpers) (1 tool)
├── composite.py           # Composite diagnostic tools (4 tools)
├── config.py              # Configuration file tools (10 tools)
├── config_entries.py      # Config entry diagnostics (4 tools)
├── devices.py, areas.py   # Device and area tools (6+1 tools)
├── dev_tools.py           # Template testing, validation (13 tools)
├── diagnostics.py         # System health, energy dashboard (18 tools)
├── entity_context.py      # Entity context tree (2 tools)
├── entity_dependencies.py # Entity dependency graph (2 tools)
├── filesystem_explorer.py # Secured filesystem browsing (3 tools)
├── graph_tools.py           # HA entity graph tools (7 tools)
├── health_reporter.py     # Health score and metrics (1 tool)
├── helpers_health.py      # Helper entity health diagnostics (1 tool)
├── history.py             # State history and recent changes (2 tools)
├── integrations.py        # Integration entity analysis (2 tools)
├── logs.py                # Log analysis and insights (8 tools)
├── manifests.py           # TOOL_MANIFESTS, risk prefix injection
├── observability.py       # request_id, invocation counters
├── scripts.py, scenes.py  # Script and scene inspection (2+2 tools)
├── states.py              # Entity state queries (12 tools)
├── storage.py             # Registry dump and search tools (30 tools)
├── utils.py               # Shared: HA API client, registry loader, log sanitizer
└── yaml_utils.py          # HomeAssistantLoader for HA-specific YAML tags

tests/
├── unit/                  # 39 test files, 1181 tests, fully mocked
├── integration/           # Real HA tests (requires HA_URL + HA_TOKEN)
├── smoke/                 # REST API smoke tests (requires local server)
└── e2e/                   # End-to-end pipeline tests (requires real HA)

Security

  • Read-only by design — no write operations to Home Assistant. Cannot modify states, execute services, or trigger automations.
  • Filesystem restrictions — access limited to /config directory. Path traversal (.., ~) blocked. Max file size 10MB. Max directory depth 20.
  • Auth data blockedauth, auth_provider.*, onboarding registries are never returned.
  • Credential redactionHA_TOKEN is never logged or exposed in outputs. JWTs, passwords, API keys, and IP addresses are sanitized from log output.

Notes

  • The server exposes three ports: 9091 (health), 9092 (MCP SSE), 9093 (REST API). Ports are configurable via env.
  • MCP_DEV_TOOLS_ENABLED=0 disables template execution and debugging tools for production use.
  • Security note: Ports 9091-9093 should not be exposed publicly. Use firewall rules or reverse proxy with authentication if needed.
  • Registry files (areas, devices, entities, config entries) are cached for 5 minutes to reduce filesystem I/O.
  • All tool responses return JSON with a success field — always check this before reading data.

Troubleshooting

For common issues and solutions, see docs/documentation.md#troubleshooting.

License

MIT — see LICENSE for details.