FAQ & Troubleshooting

Common questions and solutions for ha-mcp setup.

General Questions

Do I need a Claude Pro subscription?

No. Claude Desktop works with a free Claude account. The MCP integration is available to all users, though free accounts have usage limits.

You can also use ha-mcp with other AI clients. See the Setup Wizard for 15+ supported clients.

Do I need the Home Assistant Add-on?

No. The HA add-on is just one installation method. Most users run ha-mcp directly on their computer using uvx (recommended for Claude Desktop). The add-on is only needed if you want to run ha-mcp inside your Home Assistant OS environment.

If you do run the add-on, you don't also need uvx — that would be a second, separate instance. HTTP-native clients (Codex, Cursor, Windsurf, Claude Code) connect straight to the add-on's URL, no proxy needed. One caveat: as of early 2026, Codex's HTTP MCP support has a known initialization bug where it loads no tools; if you hit that, run ha-mcp locally over stdio with uvx instead.

What's the difference between ha-mcp and Home Assistant's built-in MCP?

Feature Built-in HA MCP ha-mcp
Tools ~15 basic tools 80+ comprehensive tools
Focus Device control Full system administration
Automations Limited Create, edit, debug, trace
Dashboards No Full dashboard management
Cameras No Screenshot and analysis

Built-in = operate devices. ha-mcp = administer your system.

How do I open the ha-mcp settings page?

ha-mcp ships a web settings page where you can enable, disable, and pin individual MCP tools, toggle feature flags and advanced (beta) settings, manage automatic backups, and review tool-approval requests. How you reach it depends on how ha-mcp is running:

  • Claude Desktop / Claude Code / any stdio install (uvx ha-mcp): a localhost settings server spawns automatically alongside the MCP process. The easiest way to find the URL is to ask the AI something like "how do I open the ha-mcp settings page?" — the URL is included in ha_get_overview's response. You can also read it directly from ~/.ha-mcp/ui.url (Windows: %USERPROFILE%\.ha-mcp\ui.url). The URL is bound to 127.0.0.1 only and gated by a random secret path generated when the settings server starts.
  • HA Add-on: easiest is the "Open Web UI" button on the add-on page (served over Home Assistant ingress — no secret needed). For direct or remote access outside the HA UI, the page lives behind the add-on's secret path: http://<home-assistant-ip>:9583/<secret-path>/settings. Find <secret-path> in the add-on's Configuration tab ("Secret path override") or in /data/secret_path.txt. The bare :9583/settings without the secret path is rejected for non-ingress callers.
  • ha-mcp-web / Docker (HTTP): append /settings to your MCP secret-path URL. The default MCP_SECRET_PATH is /mcp, so the page is at http://<host>:8086/mcp/settings; if you set a custom secret path, use that instead (e.g. http://<host>:8086/private_xxx/settings).
  • Remote (Cloudflare Tunnel / reverse proxy): same as Docker/HTTP — the page sits under your secret path wherever the MCP endpoint is reachable, e.g. https://<your-host>/<secret-path>/settings.

Changes apply on the next MCP-server restart. To stop the stdio sidecar entirely, click the "Permanently disable settings server" button on the page, set HA_MCP_DISABLE_SETTINGS_UI=1 in your MCP client config, or create an empty ~/.ha-mcp/settings_ui_disabled file.

Try Without Your Own Home Assistant

Want to test before connecting to your own Home Assistant? Use our public demo:

URL https://ha-mcp-demo-server.qc-h.net
Token demo
Web UI Login with mcp / mcp

The demo environment resets weekly. Your changes won't persist.

Troubleshooting

OAuth stopped working after upgrading to v7.0.0

v7.0.0 removed the Home Assistant URL field from the OAuth consent form to fix security vulnerabilities (SSRF and XSS). Set HOMEASSISTANT_URL as a server-side environment variable before starting ha-mcp.

# Docker
docker run -d -p 8086:8086 \
  -e HOMEASSISTANT_URL=https://your-ha-instance.example.com \
  -e MCP_BASE_URL=https://your-mcp-server.example.com \
  ghcr.io/homeassistant-ai/ha-mcp:latest ha-mcp-oauth

# uvx
HOMEASSISTANT_URL=https://your-ha-instance.example.com \
MCP_BASE_URL=https://your-mcp-server.example.com \
uvx --from=ha-mcp@latest ha-mcp-oauth

The consent form now accepts only the token. See the full migration guide for details.

macOS: "All connection attempts failed" to local Home Assistant

If ha-mcp connects to the demo server but fails to reach your local Home Assistant (192.168.x.x, 10.x.x.x, etc.) on macOS, check the following. See #867 (Local Network Privacy), #630 (env vars), #773 (Python version) for related reports.

1. macOS Local Network Privacy (Sequoia 15+)

macOS Sequoia silently blocks subprocess connections to local network IPs. Claude Desktop spawns uvx as a child process, and macOS may block its outbound LAN connections without showing a permission dialog.

  • Check System Settings → Privacy & Security → Local Network for Claude Desktop
  • If Claude Desktop is not listed, try restarting it to trigger the permission prompt

Workaround — SSH tunnel to localhost:

macOS does not restrict connections to localhost, so an SSH port forward bypasses the restriction:

ssh -N -L 8123:localhost:8123 user@your-ha-server-ip

Then set HOMEASSISTANT_URL to http://localhost:8123 in your config.

2. Firewall software (Little Snitch, Lulu, etc.)

Third-party firewalls may block python or node processes spawned by Claude Desktop. Check your firewall rules and allow connections for these processes. See #780 for an example resolution.

3. http:// vs https://

Home Assistant running in container mode (Docker, K3s) uses HTTP by default. Using https:// causes a TLS handshake error. Use http:// unless you have explicitly configured SSL/TLS or a reverse proxy.

4. Python version too old

ha-mcp requires Python 3.13+. If you are on Python 3.12 or older, uvx installs an outdated version with known bugs (including read-only filesystem errors). Upgrade Python:

brew install python@3.13

Then force a refresh:

uvx --refresh ha-mcp@latest

If uvx still uses the old Python after installing 3.13, explicitly pin it by adding --python 3.13 to your config args:

"args": ["--python", "3.13", "ha-mcp@latest"]

SSL certificate errors (self-signed certificates)

If your Home Assistant uses HTTPS with a self-signed certificate or custom CA, you may see SSL verification errors.

Docker solution:

  1. Create a combined CA bundle:
    cat $(python3 -m certifi) /path/to/your-ca.crt > combined-ca-bundle.crt
  2. Mount it and set SSL_CERT_FILE:
    docker run --rm \
      -e SSL_CERT_FILE=/certs/ca-bundle.crt \
      -v ./combined-ca-bundle.crt:/certs/ca-bundle.crt:ro \
      ...

uvx fails with invalid peer certificate: UnknownIssuer

If uvx can't download ha-mcp (or mcp-proxy, if you connect to the add-on through it) and the log shows a certificate error fetching from PyPI, the failure is in uv's package download — it never reaches Home Assistant:

Failed to fetch: https://pypi.org/simple/ha-mcp/
  invalid peer certificate: UnknownIssuer

In Claude Desktop this often shows up as the server briefly connecting, then "transport closed unexpectedly" — uvx exits when it can't fetch the package.

Cause: uv (which backs uvx) ships its own bundled root-certificate store and ignores the operating-system certificate store by default. If anything on your machine intercepts HTTPS — a corporate proxy, Zscaler, or antivirus with HTTPS/SSL scanning (Kaspersky, ESET, Bitdefender, etc.) — it presents a certificate chained to a root your OS trusts but uv's bundled store does not, producing UnknownIssuer. This is most common on Windows.

Fix: point uv at the OS native certificate store by adding UV_NATIVE_TLS=1 to the server's env block:

{
  "mcpServers": {
    "Home Assistant": {
      "command": "uvx",
      "args": ["ha-mcp@latest"],
      "env": {
        "HOMEASSISTANT_URL": "http://homeassistant.local:8123",
        "HOMEASSISTANT_TOKEN": "your_long_lived_token",
        "UV_NATIVE_TLS": "1"
      }
    }
  }
}

Connecting to the HA add-on through uvx mcp-proxy instead? Add the same UV_NATIVE_TLS=1 entry to that config's env block. The equivalent --native-tls flag also works, but it is a global uv option, so it must come before the package name. See #1506.

"uvx not found" error

After installing uv, restart your terminal (or Claude Desktop) for the PATH changes to take effect.

Mac:

# Reload shell or restart terminal
source ~/.zshrc
# Or verify with full path
~/.local/bin/uvx --version

Windows:

# Restart PowerShell/cmd after installing uv
# Or use full path
%USERPROFILE%\.local\bin\uvx.exe --version

Claude Desktop note: Claude Desktop does not inherit your shell's PATH. If uvx is not found even after restarting, use the absolute path in your config instead of uvx. Find it with which uvx in your terminal, then set "command": "/Users/<you>/.local/bin/uvx" (macOS/Linux) or the equivalent Windows path.

MCP server not showing in Claude Desktop

  1. Restart Claude completely - Use Cmd+Q (Mac) or Alt+F4 (Windows), not just close the window
  2. Check config file location:
    • Mac: ~/Library/Application Support/Claude/claude_desktop_config.json
    • Windows (traditional installer): %APPDATA%\Claude\claude_desktop_config.json
    • Windows (Microsoft Store): path varies by package — see the Windows setup guide for a detection snippet
  3. Verify JSON syntax - No trailing commas, proper quotes
  4. Check the MCP icon - Bottom left of Claude Desktop shows connected servers

"Token invalid" or authentication errors

  1. Generate a new token:
    • Home Assistant → Click your username (bottom left)
    • Security tab → Long-lived access tokens
    • Create Token → Copy immediately (shown only once)
  2. Check token format - Don't wrap the token in quotes in your config
  3. Token expiration - Tokens don't expire by default, but can be revoked

Claude says it can't see Home Assistant

  1. Open Claude Desktop Settings (gear icon)
  2. Go to the Developer tab
  3. Check Local MCP Servers for any errors
  4. If "Home Assistant" is not listed, check your config file syntax
  5. Try asking Claude: "Can you list your available tools?"

Can't connect remotely? Try the Webhook Proxy add-on

If you're having trouble setting up remote access — TLS errors, Cloudflare configuration issues, or port forwarding problems — the Webhook Proxy add-on may be a simpler alternative.

Instead of requiring a dedicated tunnel to port 9583, the Webhook Proxy routes MCP traffic through Home Assistant's main port (8123) via a webhook. If you already have Nabu Casa or any reverse proxy pointing at your HA instance, this can be the easiest remote setup.

  1. Install the MCP Server add-on and the Webhook Proxy add-on from the add-on store
  2. Start the webhook proxy and restart Home Assistant when prompted
  3. Copy the webhook URL from the add-on logs
  4. Use that URL in your MCP client configuration

See #784 for an example where this resolved a TLS connection issue.

Webhook Proxy: securing the URL

By default the Webhook Proxy add-on registers an unauthenticated webhook endpoint. The webhook URL itself is the shared secret — anyone with the full URL can reach your MCP server, which exposes powerful Home Assistant control. Treat the URL like a password.

Don't share the URL

  • Avoid pasting it into screenshots, log paste-bins, public configs, or chat transcripts.
  • Mask the part after /api/webhook/ if you have to share anything.
  • Anyone with the full URL can call your MCP tools.

Rotating the URL if it leaks

  1. Stop the Webhook Proxy add-on.
  2. Delete /data/webhook_id.txt from the add-on's filesystem (e.g. via SSH/Terminal add-on).
  3. Start the add-on. A new webhook ID and URL are generated on first launch.
  4. Copy the new URL from the add-on logs into your MCP client(s). The old URL stops working immediately.

Optional: Enable OAuth (Beta)

For a real auth layer on top of the URL secret, the Webhook Proxy add-on (v1.1.0 and later) ships an optional OAuth 2.1 mode. Toggle Show unused optional configuration options, turn Enable OAuth (Beta) on, leave Client ID and Client Secret blank, and restart the add-on. The add-on generates a strong Client ID and Client Secret on first start, persists them at /data/oauth_creds.json, and prints them in the add-on log.

In Claude.ai, expand the connector's Advanced settings when adding it and paste the Client ID and Client Secret from the add-on log into the OAuth fields. Claude.ai handles the rest of the OAuth handshake automatically. When the toggle is off, the webhook URL behaves exactly as before with no auth check.

OAuth flow end-to-end

  1. Claude.ai redirects your browser to https://<host>/authorize?... with PKCE parameters.
  2. The add-on serves a consent page showing the redirect destination — verify it's Claude.ai's callback URL.
  3. Click Allow. The add-on issues a one-time auth code and redirects back to Claude.ai.
  4. Claude.ai exchanges the code at https://<host>/token using your Client ID + Client Secret + the PKCE verifier. The add-on returns a 1-hour access token and a 30-day refresh token, both HMAC-signed.
  5. From then on Claude.ai sends every MCP request with Authorization: Bearer <token>; expired access tokens are refreshed automatically.

The Client Secret is the real security boundary

The /authorize consent page is reachable without being logged into Home Assistant or Nabu Casa — that's how OAuth works (the consent page must be reachable from the OAuth client's browser session). What stops an attacker who clicks "Allow" on a phishing authorize URL: the resulting auth code is bound to PKCE and useless without your OAuth Client Secret at the token endpoint. So the Client Secret is the actual gate, not the consent page.

Treat the Client Secret like a password. Don't paste it into screenshots, support threads, or public configs. If you suspect it has leaked — or want a clean slate after sharing logs for debugging — rotate it immediately. After rotation, any tokens issued under the old credentials stop refreshing, forcing the client to redo OAuth.

Rotating OAuth credentials

  • From the addon UI (recommended): turn on Regenerate OAuth Credentials on Next Start, save, restart the add-on. The add-on wipes the stored credentials, generates fresh ones, prints them in the log, and auto-clears the regenerate toggle. Update your MCP client to match. Takes ~30 seconds.
  • Custom values: type new strings into the Client ID and Client Secret fields and restart — your values override the stored file.
  • Filesystem: stop the addon, delete /data/oauth_creds.json, start the addon. Equivalent to the UI option but requires SSH/Terminal access.

Beta status: the OAuth flow is built against the MCP 2025-06-18 spec and tested with Claude.ai. Other clients' OAuth coverage may vary. Report issues on GitHub.

Server works but responses are slow

  1. First request is slow - uvx downloads packages on first run
  2. Subsequent requests - Should be faster (packages cached)
  3. Alternative - Use Docker for consistent performance

Antigravity client troubleshooting

  • "Unexpected server output" error: Add FASTMCP_SHOW_SERVER_BANNER=false to your stdio env config. This disables the startup banner that Antigravity misinterprets as unexpected output.
  • "EOF" errors: Use absolute paths for the command, not relative paths.
  • First run timeout: Run uvx ha-mcp@latest --version in your terminal first to download and cache the package before Antigravity tries to start it.
  • Tools load but fail when called: Try switching to stdio mode instead of HTTP. HTTP mode can experience "connection closed" or reconnection errors with this client.
  • Connection issues after config changes: Restart the Agent session in Antigravity after saving any config changes.

Claude.ai connection issues

If tools stop responding or the connector appears disconnected in Claude.ai:

  1. Restart both Claude.ai and the MCP server. Refresh the Claude.ai page in your browser and restart the ha-mcp process (or Docker container). Either side can hold stale connection state. An intermittent connect failure is usually a transient tunnel/relay hiccup, so a restart and retry often clears it.
  2. A 405 Method Not Allowed on a GET in your ha-mcp logs is normal and not the cause of a failed connect. Claude.ai pre-flights with a GET and the Streamable HTTP MCP endpoint only accepts POST (and DELETE), not GET, so a 405 shows up even on a successful connection (the log annotates it NORMAL for most non-SSE connections).
  3. Check that your tunnel (Cloudflare, ngrok, etc.) is still running and the URL has not changed.
  4. Verify the server is reachable by visiting the MCP URL directly in your browser — you should see a response from the server (with OAuth enabled on the webhook proxy, an Unauthorized response is expected and correct).
  5. Reachability from Anthropic's servers: Claude.ai connects from the cloud, not your network — a URL that works in Claude Code or your browser (both on your LAN) can still be unreachable for Claude.ai web. Open the URL on your phone with Wi-Fi off; if it doesn't load, it isn't publicly reachable and Claude.ai can't reach it either.
  6. Don't forget to click Connect on the connector — and, with OAuth enabled, click Allow on the consent page. Adding the connector alone does not complete the connection.

Test ha-mcp without configuring a client

Before setting up a client, you can run a quick smoke test against the public demo server to confirm uvx is installed and ha-mcp launches correctly:

HOMEASSISTANT_URL=https://ha-mcp-demo-server.qc-h.net HOMEASSISTANT_TOKEN=demo uvx ha-mcp@latest

This starts ha-mcp in stdio mode connected to the public demo Home Assistant instance. Press Ctrl+C to stop. If it launches without errors, your environment is ready — replace the URL and token with your own values to connect to your Home Assistant.

Keep ha-mcp-web running in the background

To run the ha-mcp HTTP server detached from the terminal so it survives logout:

nohup uvx --from ha-mcp@latest ha-mcp-web > /dev/null 2>&1 &

nohup detaches the process from the terminal and redirects output to /dev/null. The trailing & sends it to the background. For more robust setups (auto-restart on crash, start on boot), use systemd or the Home Assistant add-on instead.

Docker: changing the port requires updating both places

When running ha-mcp-web in Docker, the port is set in two independent places and they must match:

  • The second number in -p HOST:CONTAINER — this is the container-side port Docker listens on
  • The MCP_PORT environment variable — this is the port ha-mcp binds inside the container

If these differ, the container starts but requests never reach the server. Example using port 9000:

docker run -d --name ha-mcp \
  -p 9000:9000 \
  -e HOMEASSISTANT_URL=http://homeassistant.local:8123 \
  -e HOMEASSISTANT_TOKEN=your_token \
  -e MCP_PORT=9000 \
  ghcr.io/homeassistant-ai/ha-mcp:latest \
  ha-mcp-web

The first number in -p (the host port) can be anything — only the second number must match MCP_PORT.

Custom Component (ha_mcp_tools)

What is the custom component and why do I need it?

Some tools require a companion custom component installed in Home Assistant. Standard HA APIs do not expose file system access or YAML config editing. This component provides both.

Tools that require the component:

  • ha_config_set_yaml — Safely add, replace, or remove top-level YAML keys in configuration.yaml and package files (automatic backup, validation, and config check)
  • ha_list_files — List files in allowed directories (www/, themes/, custom_templates/)
  • ha_read_file — Read files from allowed paths (config YAML, logs, www/, themes/, custom_templates/, custom_components/)
  • ha_write_file — Write files to allowed directories
  • ha_delete_file — Delete files from allowed directories

All other tools work without the component. These five return an error with installation instructions if the component is missing.

How do I install it?

Using HACS (recommended):

Open your Home Assistant instance and open a repository inside the Home Assistant Community Store.

To add manually: open HACS > Integrations > three-dot menu > Custom repositories > add https://github.com/homeassistant-ai/ha-mcp (category: Integration) > Download.

After installing, restart Home Assistant. Then open Settings > Devices & Services > Add Integration and search for HA MCP Tools.

Manual install: Copy custom_components/ha_mcp_tools/ from the repository into your HA config's custom_components/ directory. Restart Home Assistant, then add the integration as described above.

Do I also need to enable feature flags?

Yes. The component is required, but the tools are also gated by feature flags for safety:

Variable Enables
HAMCP_ENABLE_FILESYSTEM_TOOLS=true ha_list_files, ha_read_file, ha_write_file, ha_delete_file
ENABLE_YAML_CONFIG_EDITING=true ha_config_set_yaml
HAMCP_ENABLE_CUSTOM_COMPONENT_INTEGRATION=true ha_install_mcp_tools (automated installer)

Configuration Options

Environment Variables

Variable Description Required
HOMEASSISTANT_URL Your Home Assistant URL Yes
HOMEASSISTANT_TOKEN Long-lived access token (or demo) Yes
BACKUP_HINT Backup recommendation level No
HA_MCP_DISABLE_SETTINGS_UI Set to 1 to skip the localhost settings-page sidecar that stdio installs spawn by default (details). No

Backup Hint Modes

Mode Behavior
strong Suggests backup before first modification each day/session
normal Suggests backup only before irreversible operations (recommended)
weak Rarely suggests backups
auto Same as normal (future: auto-detection)

Feedback & Help

We'd love to hear how you're using ha-mcp!

Ready to get started? Go to Setup Wizard