Wzorzec mechaniczny: sekcje deploy/verify/install/testy wycinane do kb/runbooks/<serwis>-*.md, reszta zostaje dokumentem type: service. Wzajemne `links` w obie strony. Tresc sekcji nietknieta — przenoszone doslownie, dodany wylacznie naglowek H1 nowego runbooka. kb-query, paperless-worker, planner-agent, ha-diag-agent, ollama-piha, narty27, home-assistant, ha-mcp, job-gmail-header-backfill, job-mail-body-ingest. Weryfikacja: dla kazdego pliku multizbior niepustych linii (main + runbook) == oryginal z HEAD. Zero zgubionych, zero dodanych. Recon szacowal 13 splitow service+runbook; faktycznie 2-typowych jest 10, pozostale 5 (paperless, nextcloud, gokapi, fleet-prometheus, deploy-runner) sa 3-typowe i ida osobno jako splity wielotypowe. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
3.4 KiB
| okf | type | visibility | status | updated | links | |
|---|---|---|---|---|---|---|
| 0.1 | runbook | private | active | 2026-07-30 |
|
ha-mcp — instalacja i rejestracja
Install
The mcp SDK (and its pydantic/anyio/httpx dependency tree) is not packaged
for Debian and is not needed by anything else in this repo, so it goes into a
venv rather than into the system Python:
python3 -m venv --system-site-packages services/ha-mcp/.venv
services/ha-mcp/.venv/bin/pip install mcp pytest
--system-site-packages is deliberate: requests, PyYAML and
websocket-client are already installed system-wide and used by
scripts/ha/lib/*; the venv reuses those exact versions instead of shadowing
them with a second copy. .venv/ is already covered by the repo .gitignore.
pip install --break-system-packages mcp also works and is one line shorter,
but it writes into the system interpreter that runs every deploy script on
this workstation — a venv keeps a 40-package dependency tree out of that blast
radius for a tool only Claude Code uses. Use the venv.
run.sh prefers services/ha-mcp/.venv/bin/python and falls back to the
system python3; if neither can import mcp it exits with one actionable
line on stderr rather than a traceback.
Registration in Claude Code
.mcp.json in the repo root (project scope — shared with anyone who checks
out this repo):
{
"mcpServers": {
"ha": {
"command": "./services/ha-mcp/run.sh",
"args": [],
"env": {}
}
}
}
The command path is relative, so it resolves in any checkout (main or task
worktree) as long as Claude Code is started from the repo root. Start CC
there; on first run it asks whether to trust the project's MCP servers. Check
with /mcp — the server appears as ha, its tools as mcp__ha__<tool>.
Which repo the server reads is derived from its own location; override with
the HA_MCP_REPO environment variable if you ever need to point one checkout
at another's config.
Standalone
./services/ha-mcp/run.sh # stdio server — speaks JSON-RPC on stdout
services/ha-mcp/tests/run.sh # offline test suite (no HA, no token)
services/ha-mcp/.venv/bin/python services/ha-mcp/tests/smoke_live.py [instance] [entity_id]
smoke_live.py is the only thing here that touches the network (GET only). A
one-off tool call without a client is easiest through the package:
PYTHONPATH=services/ha-mcp/src services/ha-mcp/.venv/bin/python -c "
from ha_mcp import tools; from ha_mcp.backend import LiveBackend
from ha_mcp.config import get_instance, repo_root
n, c = get_instance('ken', repo_root()); print(tools.instance_status(LiveBackend(n, c, repo_root())))"
Tests
services/ha-mcp/tests/run.sh # 42 tests, offline
Offline in the same sense as scripts/ha/tests/*: no network, no HA
instance, no token. Small hand-made fixtures under tests/fixtures/ (shaped
like real /api/states and WebSocket registry payloads) cover the tool logic;
the repo's own config/ken/automations/ and newest fixtures/ken-states-*.yaml
cover the repo-backed and at-scale paths (ranking over ~1650 real entities
behaves differently from ranking over ten).
Live smoke (read-only, run against ken on 2026-07-30):
instance_status → HA 2026.7.2, 1647 entities, 377 unavailable, 115
automations, 13 areas; get_state("sensor.thsalon_temperature") → 24.5 °C.