Skip to main content

hc-mcp

hc-mcp is the Model Context Protocol server for HomeCore. It exposes typed tools an MCP-aware LLM client (Claude Desktop, Claude Code, etc.) can call to inspect a running HomeCore instance and invoke plugin actions on it.

The repo lives at homeCore-io/hc-mcp.


What's available

Read-only (always on)

ToolEndpointPurpose
system_healthGET /system/statusOverall health snapshot
list_pluginsGET /pluginsStatus of every plugin
plugin_status(plugin_id)GET /plugins/:idOne plugin in detail
plugin_capabilities(plugin_id)GET /plugins/:id/capabilitiesDeclared actions
list_devicesGET /devicesAll registered devices
device_state(device_id)GET /devices/:idSingle device + schema
device_history(device_id, ...)GET /devices/:id/historyTime-series for an attribute
list_rulesGET /automationsAll automations
get_rule(rule_id)GET /automations/:idOne automation full body
rule_firings(rule_id, limit)GET /automations/:id/historyRecent fire history
recent_events(limit)GET /eventsTail of the event ring buffer
list_plugin_actions(caps fanout)Flatten every plugin manifest into one list

Write-gated (require HC_MCP_ALLOW_WRITE)

ToolCategoryEffect
invoke_plugin_actionplugin_actionsPOST /plugins/:id/command for non-streaming manifest actions
await_streaming_plugin_actionplugin_actionsPOST a streaming action and consume its SSE stream until a terminal stage

Set HC_MCP_ALLOW_WRITE=plugin_actions (or all) in the hc-mcp environment to enable both. await_streaming_plugin_action aggregates progress / item / warning events along the way and returns them alongside the terminal payload — see Capabilities → In hc-mcp for the full result shape.


Install

cd /path/to/clients/hc-mcp
python3 -m venv .venv
.venv/bin/pip install -e .

Python ≥ 3.11 (for the stdlib tomllib + modern type syntax).

Configure

1. Issue an API key

On the HomeCore host:

hc-cli api-key create --label mcp-service \
--scopes devices:read,plugins:read,automations:read,events:read,audit:read

The token is printed once — save it.

For Phase 4a (invoke_plugin_action) you also need plugins:write. Issue a separate key for that and only export it from a more-privileged shell when you intend to invoke actions.

2. Write a config file

~/.config/hc-mcp/config.toml:

[homecore]
base_url = "http://127.0.0.1:8080"
api_key = "hc_sk_..." # from step 1
timeout_secs = 5

Or set HC_MCP_BASE_URL / HC_MCP_API_KEY env vars instead.


Wire into a Claude client

Claude Code

Add to ~/.claude.json (or per-project .claude/settings.json):

{
"mcpServers": {
"homecore": {
"command": "/path/to/hc-mcp/.venv/bin/hc-mcp"
}
}
}

To enable plugin-action invocation, pass the env var through the config:

{
"mcpServers": {
"homecore": {
"command": "/path/to/hc-mcp/.venv/bin/hc-mcp",
"env": { "HC_MCP_ALLOW_WRITE": "plugin_actions" }
}
}
}

Claude Desktop

Same shape in ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or the equivalent on your platform.


How invoke_plugin_action interacts with capabilities

hc-mcp doesn't know what actions exist — it discovers them at call time by reading each plugin's capability manifest. The flow:

  1. Claude calls list_plugin_actions. Result is a flat list of every declared action with plugin_id, action_id, label, description, params schema, requires_role, stream flag, etc.
  2. Claude picks an action and calls invoke_plugin_action(plugin_id, action, params).
  3. hc-mcp checks the write gate, looks up the action in the plugin's manifest to confirm it exists and isn't a streaming action, POSTs /plugins/:id/command, and returns the response.

When you ship a new plugin action, no hc-mcp changes are needed — it appears in the next list_plugin_actions call automatically.


Standalone smoke test

Outside an MCP client:

.venv/bin/hc-mcp --help

The server speaks MCP over stdio; you can drive it with the MCP inspector or any conformant client. A 401 against a running core with a dummy key proves your transport, base URL, and auth header are wired correctly.


Limitations and roadmap

  • stdio only. HTTP/SSE transport (so Claude Desktop on another machine can connect over Tailscale) lands in a follow-up.
  • Read-only by default. Writes are explicitly gated per category.
  • Streaming actions return an error. Awaiting their terminal stage cleanly through MCP needs design — likely a "watch this request_id" variant or progress notifications.
  • No live MQTT tap, no rule mutation, no plugin scaffolding. Those are the targets for later phases (mqtt_tap, correlation_trace, create_rule, scaffold_plugin).

The full design spec lives at clients/hc-mcp/DESIGN.md.