Repository navigation
v3.0.0
Breaking
set_accessoryrefuses lock, garage door and security system targets; use the new destructiveset_security_accessorytool, which asks for confirmation.get_config'sincludeSecretsis opt-in (HOMEBRIDGE_ALLOW_SECRETS, or theallowSecretsoption forcreateServer/runHttpServer) and never available in read-only mode.RegisterToolstakes a thirdoptionsargument, and write tools declare a tokenscope.- The default OpenAI model is
gpt-6.1-sol(over the Responses API) and the default Gemini modelgemini-3.8-flash.
Added
- OpenAI through the Responses API (from ai-core): the
openaiprovider calls/responseswithstore: false, which newer OpenAI models need for tool calling, and replays their encrypted reasoning in agent loops. The newopenaiApisetting (responses|chat, inconfig.schema.json) switches back to Chat Completions for proxies or local servers that only speak it (openai-compatiblekeeps Chat Completions by default). Theeffortsetting now also applies to OpenAI (reasoning.effort). - Assistant requests are retried when the provider is busy, rate limits them or can't be reached (from ai-core): new
maxRetriessetting (default 2, 0 turns it off) inconfig.schema.jsonand the README. - Claude prompt caching and
effort(from ai-core): agent loops reuse the cached tools, system prompt and conversation, and the neweffortsetting (config.schema.json, Claude only) controls how much Claude thinks. Costs now price cache reads and writes correctly. - Usage tracking that survives restarts, with daily / monthly totals and optional token or USD budgets (
UsageTracker,JsonFileUsageStore,trackUsage, from ai-core). ./mcpalso exportsnormalizeFingerprintandpemFingerprints, next tocreateTrustedFetch, so apps can pin the Homebridge UI certificate without their own copy.- Server helpers from ai-core, re-exported from
.:SlidingWindowRateLimiter,TtlCache,withConfirmTimeout,ConfirmationBroker,redactPairing,readLogTail,tailLines,stripAnsi. Thehomebridge://logs/recentresource uses ai-core's ANSI stripping, which also removes cursor and erase codes. - Config safety.
update_configandpatch_configtakedryRun: true, which returns what would change without writing: a list of changed JSON paths and a unified diff of the pretty-printed file, both with secrets redacted. Every real write now names the config.json backup the Homebridge UI made of the previous file (both Homebridge UI and Glass UI copy config.json tobackups/config-backupsbefore each save, so no local store is needed), with therestore_configcall that undoes it. - New MCP tools
list_config_backups(read-only,GET /api/config-editor/backups) andrestore_config(destructive; readsGET /api/config-editor/backups/:idand saves it, so the replaced file is itself backed up; supportsdryRun). - New MCP tools
create_backupandlist_backups: create a full instance backup in the UI's backup directory (POST /api/backup) and list those backups (GET /api/backup/scheduled-backups). A UI without these routes gets a clear "requires Homebridge Glass UI" error. - New MCP tool
set_accessories: set one characteristic on many accessories at once, picked byuniqueIdsor by thelist_accessoriesfilters (room,type,name,manufacturer,excludeManufacturer). Each value is checked per accessory likeset_accessory;dryRunpreviews current → new value per target; the result lists each target's outcome and the skipped ones with the reason. At most 25 targets unlessmaxTargets(up to 200) is raised. Lock, garage door and security system targets (LockTargetState,TargetDoorState,SecuritySystemTargetState) are refused and pointed toset_accessory. - Scenes (Homebridge Glass UI):
list_scenes,run_scene,save_scene.run_scenetakes a scene id or name (POST /api/scenes/:id/run) and returns the result per action; a scene that changes a lock, garage door or security system is refused (apply those actions withset_security_accessory, which asks the user, or run the scene in Glass UI).save_scenecaptures the current writable values of the chosen accessories (optionally only some characteristics; never lock/door/alarm states,Identifyor names) and creates the scene withPOST /api/scenes, with adryRunpreview. - New MCP tool
get_child_bridge_health(Glass UI,GET /api/status/homebridge/child-bridges/health): status, uptime, restart and crash counts and crash-loop detection per child bridge, optionally for onedeviceId. - New MCP tool
send_test_notification(Glass UI,POST /api/notifications/test): send a test message to one notification channel or every enabled one. search_logsfilters:since/until(ISO, or a duration back from now such as30m,1h,2d), a minimumlevel(error,warn,info,debug, read from the colours Homebridge's logger writes, so the log is fetched withcolour=yeswhen it is used; falls back to the words in the line),plugin(the[Prefix]after the timestamp) andcontext(lines around each match, grep-Cstyle). Lines without a timestamp, such as stack traces, belong to the entry above.patternis now optional when a filter is given.- MCP resource templates
homebridge://accessory/{uniqueId},homebridge://plugin/{name}andhomebridge://child-bridge/{id}, each listed inresources/list(a Homebridge error lists nothing rather than failing the list) and with completion for its variable. Child bridges never include pairing codes. - MCP prompts
troubleshoot-device,nightly-health-checkandscene-builder: guided workflows over the tools (device state → plugin → child bridge health → logs; a read-only health report; a scene proposed, confirmed, applied withset_accessoriesand saved withsave_scene). - Structured tool output.
list_accessories,get_accessory,list_plugins,list_child_bridges,get_child_bridge_health,get_homebridge_status,get_server_status,search_logsandlist_scenesdeclare anoutputSchemaand returnstructuredContent(lists wrapped as{ accessories: [...] },{ plugins: [...] }, …;search_logsgives{ total, shown, truncated, matches: [{ line, time, level, plugin, text }] }). The text block keeps the JSON these tools always returned. Schemas are loose so extra fields from newer Homebridge UIs pass. - Server-side confirmation through MCP elicitation. When the connected client advertises form elicitation, every destructive tool (
destructiveHint: true) asks the user to confirm before it runs, showing its arguments with secrets redacted. Declined, cancelled or failed confirmations return an error and nothing runs;dryRuncalls are not asked. Clients without elicitation (includingrunAgent, which keeps itsconfirmcallback) behave as before. On by default;HOMEBRIDGE_ELICITATION=falseorcreateServer(client, { elicitation: false })turns it off. HomebridgeClientthrows aHomebridgeApiError(withstatus,method,path,bodyandmissingRoute) for non-2xx answers, same message as before;requireGlassUi()turns a missing route into a readable error.- Scoped client tokens. Besides the main client token (still full access), the HTTP MCP server takes more tokens, each
read(read-only tools),control(plusset_accessory/set_security_accessory) oradmin(everything):clientsoption,mcp.http.clients({ name, token, scope }), orHOMEBRIDGE_AI_MCP_TOKENS=read:abc,control:deffor the CLI. A session belongs to the token that opened it (403for another token). Tools declare the scope they need with a newscopefield in their config (write tools default toadmin);createServertakesscope. - Read-only HTTP from the plugin.
mcp.http.readOnlycaps every client token atread; the plugin passed no read-only setting before. - Audit log of write tool calls: one JSON object per line with time, tool, arguments (secrets redacted with
redactSecrets), result (ok/error), MCP session, client name, token name and scope. The plugin writes it to<Homebridge storage>/homebridge-ai-kit-audit.jsonlby default (mcp.http.auditLog,mcp.http.auditLogPath); the CLI withHOMEBRIDGE_AI_AUDIT_LOG=<path>. It rotates at 5 MB, keeping three old files../mcpexportscreateAuditLog(), andcreateServer/runHttpServertake anyauditsink. - The plugin's settings page has switches for read-only and the audit log, the audit log path and the allowed browser origins (scoped tokens are edited in the JSON config).
Changed
- The settings page uses
@mp-consulting/homebridge-ui-kit1.3:lib/theme-boot.jsapplies the theme before first paint andMpKit.Theme.init()follows the Homebridge setting (its own theme script is gone), and only the minified kit files are copied (mp-ui-kit-copy --only). - Depends on
@mp-consulting/homebridge-ai-core^2.2.0. - The default OpenAI model is
gpt-6.1-sol(wasgpt-5, whose snapshot OpenAI shuts down on 2026-12-11), in ai-core, the settings page,config.schema.jsonand the README. - The default Gemini model is
gemini-3.8-flash(wasgemini-2.5-pro, which Google now limits to projects that already used it), in ai-core, the settings page andconfig.schema.json. update_configno longer echoes the Homebridge UI's answer, which is the saved file with its secrets; it returns a short confirmation instead.- HTTP sessions expire. A session with no request for 30 minutes is closed (
sessionIdleMs,HOMEBRIDGE_AI_MCP_SESSION_IDLE_MINUTES), and at most 32 stay open (maxSessions,HOMEBRIDGE_AI_MCP_MAX_SESSIONS); the least recently used idle session makes room for a new one. Sessions with an open stream are never idle. - One change feed for all HTTP sessions. Sessions subscribed to the same resource now share a single socket.io connection (or poller) to Homebridge instead of opening one each.
./mcpexportsshareLiveSource(). - Behaviour changes for clients:
set_accessorynow refuses locks, garage doors and security systems (useset_security_accessory), andget_configonly offersincludeSecretswithHOMEBRIDGE_ALLOW_SECRETS. Library callers ofcreateServer/runHttpServermust passallowSecrets: trueto keep returning secrets. - Needs the unreleased
@mp-consulting/homebridge-ai-corechanges in this workspace (newmcp.httpsettings and the base prompt rule); release ai-core first and raise the dependency. - Log text is cleaned with ai-core's
stripAnsi(all escape codes, not just colours). - Tests cover the MCP prompts, the CLI's env parsing (
stdio.ts) and the custom UI server (homebridge-ui/server.js).
Fixed
- The settings page follows your Homebridge theme. It applied the system's light/dark preference (after hard-coding dark in the markup) and ignored the Homebridge user setting; it now applies the user's light, dark or auto setting (
homebridge.getUserSettings()where available, elseuserCurrentLightingMode()), following the system in auto mode and when it changes. - The settings page no longer loads
lib/ai.csson top oflib/kit.css, which already contains the Assistant components, and its theme script and styles moved from inline blocks into same-origin files (js/theme.js,css/app.css) so they work under the Homebridge UI's content-security policy.
Security
- One rule for locks, garage doors and alarms.
set_accessory,set_accessories,run_sceneandsave_sceneshare one check (isSecurityWrite(): the lock / door / alarm characteristics, or any characteristic of aLockMechanism,LockManagement,GarageDoorOpenerorSecuritySystemaccessory) and point toset_security_accessory, the only tool that writes them; it is destructive, so MCP clients, server-side elicitation andrunAgentall ask the user.run_sceneno longer takesconfirm: truefor such scenes: a flag the model sets is not the user's consent. - Token scopes cover the new tools:
set_accessoriesandrun_sceneneedcontrol;save_scene,restore_config,create_backup,send_test_notificationand the config writes (dry runs included) needadmin. - The audit log records declined confirmations (
notConfirmed: true, from MCP elicitation orrunAgent'sconfirm), andrunAgenttakes anauditsink (principalagent). - The
homebridge://logs/recentresource andsearch_logs' text are marked as untrusted data;structuredContentstays raw. - Unlocking a door now needs the user's consent.
set_accessoryis non-destructive, so MCP clients andrunAgentnever asked before it unlocked a lock, opened a garage door or disarmed an alarm. Those writes (LockTargetState,TargetDoorState,SecuritySystemTargetState, and any characteristic of aLockMechanism,LockManagement,GarageDoorOpenerorSecuritySystemservice) now go through the newset_security_accessorytool, annotateddestructiveHint: true, andset_accessoryrefuses them with a pointer to it. A separate tool rather than a per-call check keeps the MCP annotations truthful for every client, not justrunAgent; light and switch writes still don't prompt. 43 tools in all, with the other tools added in this release. - Read-only mode no longer hands out secrets.
get_config'sincludeSecretsreturned real passwords and tokens even withHOMEBRIDGE_READ_ONLY. It now only exists when the server opts in withHOMEBRIDGE_ALLOW_SECRETS=true(allowSecretsforcreateServer/runHttpServer), and never in read-only mode; otherwise the parameter is gone and secrets stay redacted.runAgentnever allows it. - Prompt-injection hardening. Homebridge-sourced free text (
get_recent_logs,search_logs,get_plugin_changelog) is wrapped in<untrusted-data source="…">delimiters, andrunAgentwraps every tool result it sends to the model the same way (thetoolCallsit returns keep the raw text). A delimiter inside the data is defused so it can't close the block early. The shared base system prompt (PROMPTS.base, from ai-core) now says tool output is untrusted data, never to follow instructions in it, and to change devices, config or plugins only when the user asked. - The HTTP MCP server checks the
Originheader, as the MCP Streamable HTTP spec requires, so a web page can't reach it through DNS rebinding. Requests withoutOrigin(desktop clients) are unaffected; browser requests must come from a loopback origin, the server's own IP address, or an origin listed in the newallowedOriginsoption (HOMEBRIDGE_AI_MCP_ALLOWED_ORIGINS, plugin:mcp.http.allowedOrigins). Others get403. - Repeated bad tokens are slowed down. After 5 failed attempts from one address, the server answers
429withRetry-After, doubling the wait up to 5 minutes; a correct token resets the count.
Also publishes @mp-consulting/homebridge-ai-core 2.2.0 (see packages/ai-core/CHANGELOG.md).