mcp-hs4
MCP server for controlling HomeSeer HS4 with safe, auditable, and guarded write operations.
README
mcp-hs4
Production-oriented MCP server for HomeSeer HS4.
This project provides MCP tools, resources, and prompts so MCP-compatible LLM agents can read and control HS4 safely with auditability, guarded writes, and local-sidecar deployment.
Start Here
- Install and build:
npm install
npm run build
- Configure environment:
cp .env.example .env
# set HS4_BASE_URL and any auth/guard settings needed for your installation
- Run server (production path):
node dist/index.js
- Optional development mode:
npm run dev
- Register in Codex CLI:
codex mcp add hs4 \
--env HS4_BASE_URL=http://127.0.0.1 \
--env HS4_REQUIRE_CONFIRM=true \
--env HS4_SAFE_MODE=read_write \
--env MCP_LOG_LEVEL=info \
-- node /absolute/path/to/mcp-hs4/dist/index.js
- Smoke test:
codex mcp list
codex mcp get hs4 --json
codex exec --skip-git-repo-check -C /absolute/path/to/mcp-hs4 \
"Use only hs4 MCP tools. Run hs4.selftest.run and summarize any warnings."
At a Glance
- Contract namespaces:
hs4.*,hs4.admin.* - Runtime: Node 20+, TypeScript
- Transports:
stdio(default),http(streamable MCP endpoint) - Safety defaults: confirm+intent+reason guardrails, dry-run-first intent tools, audit logging
- Write reliability: post-write verification with fallback logic in
hs4.devices.set
Architecture
MCP Client (Codex / Claude / Cursor / Cline)
-> MCP transport (stdio or HTTP)
mcp-hs4 server
-> HS4 JSON API (/JSON?request=...)
-> HS4 script route (/runscript.html)
HomeSeer HS4
Project Scope
- This repository is strictly the HomeSeer 4 MCP server implementation (
mcp-hs4). - Client-specific adapters, UIs, and app integrations belong in separate repositories.
- Public API contract in this repo is
hs4.*andhs4.admin.*.
Current Status
- Runtime: TypeScript/Node 20+
- MCP SDK:
@modelcontextprotocol/sdk - HS4 integration target: JSON API (
/JSON?request=...) plus script command path (/runscript.html) - Contract version:
1.0.0 - Deployment profiles:
stdiofor local MCP client process spawning (default),streamable-httpfor optional local LAN service mode
Implemented MCP Surface
Namespaces
hs4.*standard read and control operationshs4.admin.*privileged administration operations (disabled by default)
Tools
Registered tools are listed below. For release verification, confirm the runtime contract with hs4://capabilities/matrix.
Core tools:
hs4.health.geths4.help.routehs4.resolve.deviceshs4.resolve.eventshs4.resolve.camerashs4.change.preparehs4.change.commiths4.intent.device_set_by_namehs4.intent.event_run_by_namehs4.intent.scene_activatehs4.selftest.runhs4.devices.lisths4.devices.geths4.devices.controls.geths4.devices.status.geths4.devices.seths4.events.lisths4.events.geths4.events.definition.geths4.events.runhs4.scripts.runhs4.plugins.function.callhs4.plugins.lisths4.cameras.lisths4.cameras.snapshot.geths4.cameras.panhs4.audit.query
Admin tools:
hs4.admin.users.lisths4.admin.users.createhs4.admin.users.updatehs4.admin.users.deletehs4.admin.users.set_rolehs4.admin.plugins.catalog.geths4.admin.plugins.installhs4.admin.plugins.updatehs4.admin.plugins.removehs4.admin.plugins.set_enabledhs4.admin.plugins.restarths4.admin.interfaces.lisths4.admin.interfaces.addhs4.admin.interfaces.updatehs4.admin.interfaces.removehs4.admin.interfaces.restarths4.admin.interfaces.diagnosticshs4.admin.system.backup.starths4.admin.system.restore.starths4.admin.system.service.restarths4.admin.system.shutdownhs4.admin.system.config.geths4.admin.system.config.seths4.admin.cameras.config.lisths4.admin.cameras.config.createhs4.admin.cameras.config.updatehs4.admin.cameras.config.deletehs4.admin.cameras.stream_profile.seths4.admin.cameras.recording.seths4.admin.events.createhs4.admin.events.updatehs4.admin.events.deletehs4.admin.config.device_metadata.seths4.admin.config.categories.lisths4.admin.config.category.upserths4.admin.config.category.delete
Resources
hs4://devices/cataloghs4://devices/catalog/fullhs4://devices/statushs4://devices/status/fullhs4://events/cataloghs4://capabilities/matrixhs4://audit/recenths4://state/summaryhs4://catalog/aliaseshs4://agent/contracths4://admin/usershs4://admin/interfaceshs4://admin/pluginshs4://admin/cameras/confighs4://admin/policy/state(includes admin execution mode and related routing policy state)hs4://admin/audit/diff
Prompts
hs4_safe_controlhs4_scene_operatorhs4_diagnosticshs4_agent_contracths4_admin_change_controlhs4_admin_backup_restorehs4_admin_plugin_lifecycle
Guarded Write Model
Mutating tools are policy-gated by default.
Base guard requirements for all mutating tools:
confirm=truerequired (unless dry-run)intentandreasonrequired (unless dry-run)- Global read-only mode via
HS4_SAFE_MODE=read_only - Optional allowlists for device refs, event ids, script ids, camera ids, plugin functions
- Mutation attempts and outcomes are audit-logged
Admin tool guard model (hs4.admin.*):
- Inputs include
operationTier,domain,maintenanceWindowId,changeTicket, andriskLevel operationTiercurrently defaults tooperator- When
operationTier=admin, policy enforces: HS4_ADMIN_ENABLED=true- Domain-specific admin flag enabled for the selected domain
maintenanceWindowIdpresent (and matching configured allowlist/required id when set)changeTicketpresent whenHS4_ADMIN_REQUIRE_CHANGE_TICKET=true
Admin Execution Modes
Admin tools support three execution routing modes:
adapter(default): use adapter-backed admin execution paths first.direct: use direct HS4 admin execution paths.auto: try direct execution and cache unsupported operations so subsequent calls route straight to adapter.
Execution routing is controlled by:
HS4_ADMIN_EXECUTION_MODEdefault:adapterHS4_ADMIN_DIRECT_FALLBACKdefault:true(allow direct/auto paths to fall back to adapter when direct execution is unsupported)HS4_ADMIN_CAPABILITY_CACHE_TTL_SECdefault:300(cache TTL, in seconds, for unsupported direct-operation capability checks)
Production recommendation:
- Keep
HS4_ADMIN_EXECUTION_MODE=adapter,HS4_ADMIN_DIRECT_FALLBACK=true, andHS4_ADMIN_CAPABILITY_CACHE_TTL_SEC=300unless you have a validated operational reason to forcedirect. hs4://admin/policy/statereports the active admin execution mode and related routing policy state so operators can verify runtime behavior.
Two-phase mutation model (hs4.change.*):
hs4.change.preparevalidates and stages a mutation as a dry-run plan.hs4.change.commitexecutes the prepared token if policy checks still pass.- Prepared tokens are TTL-bound and can be persisted across restarts.
Device write reliability (hs4.devices.set):
- Default mutation mode is
control_value; useset_statusonly when explicitly required. verify=trueby default; writes are followed by targeted fresh-state readback.mode=set_statuswith a value may be auto-switched tocontrol_valuewhen control pairs indicate that path is safer.- If
set_statusdoes not converge, the server attempts a guardedcontrol_valuefallback when feasible. - Non-converged writes return
HS4_ERRORinstead of reporting a false success. - Successful write responses include convergence context (
requestedMode,mode,verification, optionalmodeAutoSwitch, optionalfallback). dryRun=truevalidates policy and schema only; it does not perform live write verification.
Resolver and intent targeting behavior:
hs4.resolve.devicesnow returnsrecommended=trueon the best mutation target and includesrecommendedRef.- For ambiguous parent/master vs endpoint matches, resolver ranking prefers actionable endpoints (for example child refs with control pairs) unless the query explicitly asks for
master,scene,parent, orroot. hs4.intent.device_set_by_nameand device-fallbackhs4.intent.scene_activateincluderesolutionmetadata and can emitwarningswith codePARENT_OR_WRAPPER_TARGETwhen a wrapper/master target is chosen while an endpoint alternative exists.hs4.intent.scene_activatesupports deterministic path control withpreferPath(auto,event,device_fallback).hs4.intent.scene_activatereturnsselectionmetadata (selectedPath,reason,topEventScore,topDeviceScore,eventMinScore) so clients can explain why an event or device fallback path was selected.
Actionable error contract (all tools):
- Every error includes:
code,message,retryable,fixHint,suggestedNextToolCalls. - Tool-specific context remains under
details.
Contract Naming
Tool names in this project follow the hs4.* and hs4.admin.* contract shown above.
Admin payload delta example
Standard script call:
{
"command": "my_script(arg1)",
"confirm": true,
"intent": "recover interface",
"reason": "operator request"
}
Admin mutation call:
{
"command": "my_script(arg1)",
"confirm": true,
"intent": "recover interface",
"reason": "operator request",
"operationTier": "admin",
"domain": "system",
"maintenanceWindowId": "MW-2026-02-23-02",
"changeTicket": "CHG-4821",
"riskLevel": "medium"
}
Detailed Setup and Client Integration
1) Install dependencies
npm install
2) Configure env
cp .env.example .env
# edit values as needed
3) Run in stdio mode (default)
npm run dev
Client Setup
This server is primarily designed to be used as an MCP stdio server (the client spawns node dist/index.js).
HTTP mode is optional and mainly useful when a client only supports streamable HTTP MCP.
Common stdio config pattern
- Command:
node - Args:
<absolute-path>/dist/index.js - Env: set
HS4_*andMCP_*variables (do not put credentials inHS4_BASE_URL)
Example environment values:
{
"HS4_BASE_URL": "http://127.0.0.1",
"HS4_REQUIRE_CONFIRM": "true",
"HS4_SAFE_MODE": "read_write",
"MCP_LOG_LEVEL": "info"
}
Codex CLI (recommended)
Register:
codex mcp add hs4 \
--env HS4_BASE_URL=http://127.0.0.1 \
--env HS4_REQUIRE_CONFIRM=true \
--env HS4_SAFE_MODE=read_write \
--env MCP_LOG_LEVEL=info \
-- node /absolute/path/to/mcp-hs4/dist/index.js
Verify registration:
codex mcp list
codex mcp get hs4 --json
Prompt-level test:
codex exec --skip-git-repo-check -C /absolute/path/to/mcp-hs4 \
"Use only hs4 MCP tools. Run hs4.selftest.run and summarize any warnings."
LLM Prompt Cookbook
Use these prompts as copy/paste starters for Codex or other MCP-capable agents. Device names shown here are examples; replace them with names from your own HS4 installation.
- Deterministic event-first scene activation
Use only hs4 MCP tools.
Objective: activate "movie time".
Workflow:
1) Dry-run `hs4.intent.scene_activate` with:
- objective: "movie time"
- preferPath: "event"
- execute: false
- dryRun: true
- confirm: true
- intent: "Activate movie time scene"
- reason: "Event-first deterministic scene activation"
2) If step 1 returns NOT_FOUND, run a second dry-run with preferPath: "device_fallback".
3) Execute only the successful path (`execute: true`, `dryRun: false`).
4) Report: `path`, `selection.selectedPath`, `selection.reason`, and any `warnings`.
- Deterministic device-fallback scene activation
Use only hs4 MCP tools.
Objective: activate "coffee bar" using direct device fallback.
Workflow:
1) Dry-run `hs4.intent.scene_activate` with:
- objective: "coffee bar"
- preferPath: "device_fallback"
- fallbackDeviceValue: 99
- execute: false
- dryRun: true
- confirm: true
- intent: "Direct device fallback activation"
- reason: "Prefer endpoint control over event path"
2) Execute the same call only if dry-run succeeds.
3) Return `selection` metadata and any `PARENT_OR_WRAPPER_TARGET` warnings.
- Endpoint-first light control (avoid wrapper/master ghost success)
Use only hs4 MCP tools.
Goal: turn on coffee bar and bar overhead to max.
Workflow:
1) Resolve candidates with `hs4.resolve.devices` for "coffee bar" and "bar overhead light", `includeEvidence=true`.
2) Choose each query's `recommendedRef` when available.
3) Write with `hs4.devices.set` using:
- mode: "control_value"
- value: 99
- verify: true
- confirm: true
- intent/reason filled
4) Immediately read back using `hs4.devices.get` (`includeControls=true`) for written refs.
5) Report per-ref: requested mode, applied mode, verification result, status, and value.
- Wrapper/master-safe intent flow
Use only hs4 MCP tools.
Goal: act on "bar overhead light master" safely.
Workflow:
1) Run `hs4.intent.device_set_by_name` dry-run with query "bar overhead light master", mode "control_value", value 99.
2) If warnings include code `PARENT_OR_WRAPPER_TARGET`, re-run dry-run using the warning `suggestedRef` with `hs4.devices.set`.
3) Execute only after the second dry-run confirms endpoint targeting.
4) Return both runs and explain which target was committed and why.
- Physical-state mismatch recovery prompt
Use only hs4 MCP tools.
User says: "HS4 reports on, but the light is physically off."
Workflow:
1) Read current state with `hs4.devices.get` (`includeControls=true`).
2) Apply recovery pulse with `hs4.devices.set` (`mode=control_value`, `value=0`, `verify=true`) then `value=99`, both with confirm/intent/reason.
3) Re-read state after each write.
4) If still mismatched, run `hs4.intent.scene_activate` dry-run with `preferPath=device_fallback`, then execute if clean.
5) Report exact tool outputs and where convergence failed or succeeded.
Claude Desktop
Add an MCP server entry (client UI/paths vary by OS and version; look for an MCP servers config section). Most installations accept a config shaped like:
{
"mcpServers": {
"hs4": {
"command": "node",
"args": ["/absolute/path/to/mcp-hs4/dist/index.js"],
"env": {
"HS4_BASE_URL": "http://127.0.0.1",
"HS4_REQUIRE_CONFIRM": "true",
"HS4_SAFE_MODE": "read_write",
"MCP_LOG_LEVEL": "info"
}
}
}
}
Cursor
Cursor’s MCP UI/config evolves quickly; use the same stdio pattern:
- Add MCP server named
hs4 - Command
node - Args
.../dist/index.js - Env includes
HS4_BASE_URL,HS4_REQUIRE_CONFIRM,HS4_SAFE_MODE
Cline (VS Code)
Cline’s MCP settings also evolve; use the same stdio pattern:
- Add MCP server named
hs4 - Command
node - Args
.../dist/index.js - Env includes
HS4_BASE_URL,HS4_REQUIRE_CONFIRM,HS4_SAFE_MODE
4) Optional: run as HTTP MCP service
MCP_TRANSPORT=http MCP_HTTP_HOST=127.0.0.1 MCP_HTTP_PORT=7422 npm run dev
Health endpoint in HTTP mode:
curl http://127.0.0.1:7422/healthz
When exposing beyond loopback, set an auth token and include Authorization: Bearer <token> on POST /mcp (and /healthz unless disabled):
MCP_TRANSPORT=http \
MCP_HTTP_HOST=0.0.0.0 \
MCP_HTTP_ALLOW_NON_LOOPBACK=true \
MCP_HTTP_AUTH_TOKEN=replace-me \
npm run dev
HTTP Client Compatibility (JSON-only clients)
Some MCP clients send Accept: application/json only on POST /mcp.
MCP_HTTP_ACCEPT_MODE=compat(default) allows these clients.MCP_HTTP_ALLOW_JSON_ONLY=true(default) enables a compatibility fallback that still preserves streamable clients.MCP_HTTP_ACCEPT_MODE=strictenforces explicitapplication/jsonandtext/event-stream.
Compatibility probes:
# JSON-only client probe (should pass in compat mode)
curl -si -X POST http://127.0.0.1:7422/mcp \
-H 'content-type: application/json' \
-H 'accept: application/json' \
--data '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"diag","version":"0"}}}'
# Strict streamable probe
curl -si -X POST http://127.0.0.1:7422/mcp \
-H 'content-type: application/json' \
-H 'accept: application/json, text/event-stream' \
--data '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"diag","version":"0"}}}'
Token-protected probe:
curl -si -X POST http://127.0.0.1:7422/mcp \
-H 'content-type: application/json' \
-H 'accept: application/json' \
-H 'authorization: Bearer replace-me' \
--data '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"diag","version":"0"}}}'
Build and Test
npm run typecheck
npm run build
npm test
Environment Variables
See .env.example for complete list. Important ones:
HS4_BASE_URLdefault:http://127.0.0.1HS4_USER,HS4_PASSHS4_SAFE_MODEone ofread_write,read_onlyHS4_REQUIRE_CONFIRMdefault:trueHS4_MAX_DEVICES_DEFAULT_CAPdefault:250(global default cap for device-heavy reads)HS4_STATUS_CACHE_TTL_MSdefault:1500(0disables status cache)HS4_SCRIPT_PAGE_PATHdefault:/runscript.htmlHS4_EVENTS_DATA_PATHdefault:/usr/local/HomeSeer/Data/HomeSeerData_2.json/events.jsonHS4_EVENT_GROUPS_DATA_PATHdefault:/usr/local/HomeSeer/Data/HomeSeerData_2.json/eventgroups.jsonHS4_ALIAS_LEARNED_ENABLEDdefault:true(enable learned aliases for resolver tools)HS4_ALIAS_CONFIG_PATHoptional path to alias JSON (device:<ref>,event:<id>,camera:<id>keys)HS4_CHANGE_TOKEN_TTL_SECdefault:900HS4_CHANGE_TOKEN_MAX_ENTRIESdefault:2000HS4_CHANGE_TOKEN_PERSIST_PATHoptional JSONL persistence path for prepared tokensHS4_ALLOWED_DEVICE_REFS,HS4_ALLOWED_EVENT_IDS,HS4_ALLOWED_CAMERA_IDSHS4_ALLOWED_SCRIPTS(lower-case ids)HS4_ALLOWED_PLUGIN_FUNCTIONSinplugin:functionformat (lower-case)HS4_ADMIN_ENABLEDdefault:falseHS4_ADMIN_USERS_ENABLEDdefault:falseHS4_ADMIN_PLUGINS_ENABLEDdefault:falseHS4_ADMIN_INTERFACES_ENABLEDdefault:falseHS4_ADMIN_SYSTEM_ENABLEDdefault:falseHS4_ADMIN_CAMERAS_ENABLEDdefault:falseHS4_ADMIN_EVENTS_ENABLEDdefault:falseHS4_ADMIN_CONFIG_ENABLEDdefault:falseHS4_ADMIN_MAINTENANCE_WINDOW_IDoptional strict window idHS4_ADMIN_ALLOWED_MAINTENANCE_WINDOW_IDSoptional allowlistHS4_ADMIN_REQUIRE_CHANGE_TICKETdefault:trueHS4_ADMIN_ROLLBACK_ENABLEDdefault:trueHS4_ADMIN_EXECUTION_MODEone ofadapter,direct,auto(default:adapter)HS4_ADMIN_DIRECT_FALLBACKdefault:true(recommended in production to preserve guarded fallback to adapter when direct is unsupported)HS4_ADMIN_CAPABILITY_CACHE_TTL_SECdefault:300(admin routing capability cache TTL in seconds; keep non-zero in production)HS4_ADMIN_ALLOWED_USER_IDS,HS4_ADMIN_ALLOWED_PLUGIN_IDS,HS4_ADMIN_ALLOWED_INTERFACE_IDS,HS4_ADMIN_ALLOWED_CATEGORY_IDSMCP_TRANSPORTone ofstdio,httpMCP_HTTP_ALLOW_NON_LOOPBACKdefault:false(must betrueto intentionally bind non-loopback HTTP hosts)MCP_HTTP_ACCEPT_MODEone ofcompat,strict(default:compat)MCP_HTTP_ALLOW_JSON_ONLYdefault:true(json-onlyAcceptfallback in compat mode)MCP_HTTP_AUTH_TOKENoptional bearer token for HTTP auth (required for non-loopback whenMCP_HTTP_AUTH_REQUIRED_NON_LOOPBACK=true)MCP_HTTP_AUTH_REQUIRED_NON_LOOPBACKdefault:true(startup fails on non-loopback HTTP bind without token)MCP_HTTP_AUTH_PROTECT_HEALTHZdefault:true(health endpoint also requires bearer token when auth is enabled)MCP_AUDIT_PERSIST_PATH(optional JSONL audit sink)
HS4 Script Execution Note
hs4.scripts.run uses POST /runscript.html with:
action=run_script_commandscriptcommand=<command>
This behavior is based on HS4 UI implementation patterns in /usr/local/HomeSeer/html/runscript.html (path may vary by installation). It is powerful; use strict allowlists in production.
Documentation
- Research:
docs/01_research/ - Architecture:
docs/02_architecture/ - Operations and hardening:
docs/04_operations/ - Admin enhancements backlog:
docs/05_roadmap/admin_full_parity.txt
Project Policies
- Contribution guide:
CONTRIBUTING.md - Security policy:
SECURITY.md
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。