{"name":"io.github.Vortitron/home-assistant-mcp","slug":"vortitron-home-assistant-mcp","title":null,"description":"Home Assistant and ESPHome for coding agents: states, services, automations, dashboards, flashing.","url":"https://mcp.market/server/vortitron-home-assistant-mcp","rating":null,"grade":"B","score":83,"certified":false,"status":"active","category":"other","tags":[],"presence":{"score":28,"stars":0,"forks":0,"downloads_week":114,"last_push_at":"2026-10-14T09:54:44.000Z","license":"MIT"},"uptime":null,"claimed":false,"transport":"npm","callable_via_gateway":false,"default_price_micros":0,"repository":"https://github.com/Vortitron/home-assistant-mcp","website":"https://github.com/Vortitron/home-assistant-mcp","version":"0.11.0","remotes":[],"packages":[{"registryType":"npm","identifier":"@vortitron/home-assistant-mcp","version":"0.11.0","transport":{"type":"stdio"},"environmentVariables":[{"description":"Your Home Assistant's address, e.g. http://homeassistant.local:8123 (or use VOMEHOME_TOKEN instead)","format":"string","name":"HA_URL"},{"description":"A Home Assistant long-lived access token","format":"string","isSecret":true,"name":"HA_TOKEN"},{"description":"Set to true to allow service calls and edits; reads only without it","format":"boolean","name":"HA_ALLOW_WRITE"},{"description":"A key from the Vome app's Agent tab, to reach the home through Vome instead of HA_URL and HA_TOKEN","format":"string","isSecret":true,"name":"VOMEHOME_TOKEN"}]}],"tools":[{"name":"esphome_activity","description":"What the ESPHome build commands (validate, compile, upload, logs) started in this session are doing:","write_action":false,"price_micros":0,"input_schema":null},{"name":"esphome_clean","description":"Delete the cached build files for a configuration. Use this when a compile fails for reasons","write_action":true,"price_micros":0,"input_schema":null},{"name":"esphome_compile","description":"Compile firmware for an ESPHome configuration and return the build output. Can take several minutes.","write_action":false,"price_micros":0,"input_schema":null},{"name":"esphome_dashboard_info","description":"Report whether ESPHome is reachable and what is possible right now — listing and","write_action":false,"price_micros":0,"input_schema":null},{"name":"esphome_edit_config","description":"Change part of an ESPHome configuration file in place: each edit replaces one exact piece of","write_action":false,"price_micros":0,"input_schema":null},{"name":"esphome_get_config","description":"Read the YAML for an ESPHome configuration file (e.g. 'living-room.yaml').","write_action":false,"price_micros":0,"input_schema":null},{"name":"esphome_list_devices","description":"List devices/configurations known to the ESPHome dashboard, including their configuration filenames (needed by the other ESPHome tools).","write_action":false,"price_micros":0,"input_schema":null},{"name":"esphome_list_migrations","description":"Report the ESPHome spellings a device's YAML still uses that have since been","write_action":false,"price_micros":0,"input_schema":null},{"name":"esphome_logs","description":"Stream the live logs from an ESPHome device and return what was captured. This is the way to","write_action":false,"price_micros":0,"input_schema":null},{"name":"esphome_save_config","description":"Write YAML to an ESPHome configuration file, whole: for a new file. To change part of an existing one, use esphome_edit_config. Requires HA_ALLOW_WRITE=true and HA_ALLOW_CONFIG_WRITE=true. Follow with esphome_validate to confirm it compiles, then esphome_upload to flash it.","write_action":true,"price_micros":0,"input_schema":null},{"name":"esphome_upload","description":"Compile and flash firmware to a device over the air. This is how you update an ESPHome device — no cable, no manual step in the ESPHome UI. 'port' is the device address or 'OTA' (the default). Requires write access.","write_action":true,"price_micros":0,"input_schema":null},{"name":"esphome_validate","description":"Validate (compile-check) an ESPHome configuration and return the output. The fast way to confirm a YAML edit is correct before compiling or flashing.","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_addon_install_vome","description":"Developer helper: add the VomeSync GitHub add-on repository to the Supervisor store (if missing), install the Vome add-on, and start it. Requires HAOS/Supervised. In brokered mode the API key's ha:config scope is authoritative — no HA_ALLOW_WRITE env flag needed. After install, restart Home Assistant once so custom_components/vomesync is loaded, then add the Vome integration.","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_call_service","description":"Call a Home Assistant service to change state (e.g. domain='light', service='turn_on', data={ brightness_pct: 60 }, target={ entity_id: 'light.kitchen' }). Refused unless writes are enabled, and blocked for denied domains. Returns the entities that changed, and service_response for services that return data.","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_camera_frame","description":"A camera's current still decoded and shrunk to at most width x height pixels, returned as RGB","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_camera_image","description":"Return a camera's current still as an image you can see — to check framing, exposure, or what the camera shows. For a camera entity that shows the latest snapshot file, this is that snapshot. Home Assistant scales it to 'width' pixels wide (default 1024). Through VomeHome the API key needs Cameras ticked under Sensitive devices.","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_change_user_password","description":"Reset the password for a user that already has a local login (created via","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_check_config","description":"Validate the current Home Assistant configuration (equivalent to Developer Tools -> Check configuration). Returns 'valid' or the specific errors. Run this after editing YAML and before reloading.","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_clear_system_log","description":"Empty Home Assistant's structured error store. The point is the debug loop: clear, reproduce the problem, then ha_get_system_log shows only what your reproduction caused. Does not touch home-assistant.log on disk. Requires HA_ALLOW_WRITE=true in direct mode.","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_config_entry_options","description":"Open a config entry's *options* flow — the per-integration settings panel — and","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_config_flow","description":"Add or configure an integration via Home Assistant's config flow API.","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_create_dashboard","description":"Register a new storage-mode Lovelace dashboard. After creating, call ha_save_dashboard to set its views/cards. Requires HA_ALLOW_WRITE=true and HA_ALLOW_CONFIG_WRITE=true.","write_action":true,"price_micros":0,"input_schema":null},{"name":"ha_create_user","description":"Create a new Home Assistant user with no login yet — call ha_set_user_credentials","write_action":true,"price_micros":0,"input_schema":null},{"name":"ha_delete_automation","description":"Delete an automation by its unique id. Requires HA_ALLOW_WRITE=true and HA_ALLOW_CONFIG_WRITE=true.","write_action":true,"price_micros":0,"input_schema":null},{"name":"ha_delete_config_entry","description":"Permanently delete one config entry (integration instance) by id. This is the fix for","write_action":true,"price_micros":0,"input_schema":null},{"name":"ha_delete_config_file","description":"Delete one file under the config directory — a throwaway test file, a superseded","write_action":true,"price_micros":0,"input_schema":null},{"name":"ha_delete_dashboard","description":"Delete a storage-mode Lovelace dashboard by its id (from ha_list_dashboards or ha_create_dashboard). Requires HA_ALLOW_WRITE=true and HA_ALLOW_CONFIG_WRITE=true.","write_action":true,"price_micros":0,"input_schema":null},{"name":"ha_delete_helper","description":"Delete a stored Home Assistant helper by id (from ha_list_helpers). The entity","write_action":true,"price_micros":0,"input_schema":null},{"name":"ha_delete_script","description":"Delete a script by id. Automations that call it will fail at that step, so remove those","write_action":true,"price_micros":0,"input_schema":null},{"name":"ha_delete_user","description":"Permanently delete a user and any login credentials attached to it. Cannot delete the","write_action":true,"price_micros":0,"input_schema":null},{"name":"ha_edit_config_file","description":"Change part of a text file under the config directory: each edit replaces one exact piece of","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_fire_event","description":"Fire a custom event on the Home Assistant event bus (advanced). Useful for triggering event-based automations during testing. Requires writes to be enabled.","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_get_automation","description":"Get the full configuration (triggers, conditions, actions) of an automation. Accepts either the entity_id (automation.xxx) or the unique id.","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_get_config","description":"Return core Home Assistant configuration: version, location name, time zone, unit system and the list of loaded integrations/components. A good first call to understand the instance.","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_get_dashboard","description":"Get the full Lovelace configuration for one dashboard (views, cards, etc.). Use url_path from ha_list_dashboards — e.g. 'lovelace' for the default overview, or a custom path like 'sam-energy'.","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_get_entity_registry","description":"Inspect the entity registry: platform, area, device, unique-id metadata and whether entities are disabled or hidden. Useful for finding disabled entities or the area/device an entity belongs to.","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_get_error_log","description":"Return the tail of the raw Home Assistant error log. ha_get_system_log is usually the better first stop (grouped and structured); reach for this one when you need the raw ordering, or lines the structured store drops.","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_get_history","description":"Get historical state changes for one or more entities over a time window. Times are ISO 8601 (e.g. 2026-06-05T06:00:00+00:00). Defaults to the last day if no start_time is given; with a start_time and no end_time it runs up to now (Home Assistant on its own would stop 24 hours after the start).","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_get_logbook","description":"Return human-readable logbook entries (what happened and when), optionally filtered to a single entity and time window.","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_get_script","description":"Get a script's full configuration (alias, sequence, fields, mode). List scripts with","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_get_state","description":"Get the full state and attributes for one or more entities. Use this to read exact current values before changing them or writing template/automation logic.","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_get_supervisor_log","description":"Tail the logs of an add-on, Home Assistant Core, the Supervisor itself, or the host — for problems that never reach HA's own error log (an add-on crash-looping, a failed install, host-level trouble). Requires a Supervised / HAOS install. Works through the VomeHome broker too (read scope).","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_get_system_log","description":"Home Assistant's deduplicated error store: one record per distinct problem, with level, logger, source file:line, occurrence count and first/last seen. Prefer this over ha_get_error_log — 20 grouped issues instead of 200 raw lines. Filter by minimum level, logger name or free text. Full tracebacks are omitted by default (you still get the final exception line); set include_exception=true, usually ","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_get_trace","description":"Step-by-step detail for one run: what triggered it, every condition and action in order with its result, and 'failed_at' naming the first step that errored or evaluated false. This is the tool for 'why didn't my automation run' — logs usually stay silent about a condition returning false. Give 'item' and omit run_id for its most recent run, or give a run_id from ha_list_traces (item is then option","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_hacs_add_repository","description":"Add a custom repository to HACS by GitHub 'owner/repo' (or its URL) and category","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_hacs_download_repository","description":"Install or update a repository HACS already knows about — this is the step that","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_hacs_info","description":"Whether HACS is installed and its version, configured country, and whether it has pending","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_hacs_list_repositories","description":"List repositories HACS knows about — both custom and default-store ones it has fetched","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_hacs_remove_repository","description":"Uninstall a HACS-managed repository's files and stop HACS tracking it as custom.","write_action":true,"price_micros":0,"input_schema":null},{"name":"ha_integration_setup_vome","description":"Ensure the Vome custom component is set up as a config entry: start the vomesync","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_list_areas","description":"List all Home Assistant areas (rooms/zones) with their ids, names and floor. Use the area_id or name to filter other tools.","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_list_automations","description":"List all automations with their entity_id, unique id (needed to read/edit config), on/off state and last triggered time.","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_list_config_entries","description":"List installed Home Assistant config entries (integrations). Optional domain filter, e.g. vomesync.","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_list_config_files","description":"List a directory under Home Assistant's config directory. Omit 'path' for the root,","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_list_dashboards","description":"List Home Assistant Lovelace dashboards (url_path, title, mode, sidebar visibility). Works in direct HA mode and VomeHome brokered mode.","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_list_devices","description":"List Home Assistant devices from the device registry. Optionally filter by area (id or name) and/or a search string matching name, manufacturer or model.","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_list_discovery_flows","description":"List config flows Home Assistant has started but not finished — chiefly integrations","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_list_entities","description":"List entities with their current state. Filter by domain (e.g. 'light'), a free-text search over entity_id and friendly name, and/or an area (id or name). This is the fastest way to discover what exists before calling services or editing automations.","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_list_helpers","description":"List the helpers Home Assistant stores — input_boolean, input_number, counter, timer","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_list_services","description":"List callable Home Assistant services. Without a domain, returns every domain and its service names. With a domain, returns that domain's services including their fields/parameters so you know what data to pass to ha_call_service.","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_list_traces","description":"List recent runs of an automation or script: when it ran, whether it finished, and how it stopped ('failed_condition' means a condition blocked it). Omit 'item' to list runs across everything in the domain. Home Assistant keeps a limited number of traces per item (5 by default), and none from before the last restart.","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_list_users","description":"List every user on this Home Assistant instance: id, name, username (if they have a","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_matter_reinterview","description":"Ask a Matter device to describe itself again — the device page's Re-interview button. Do this","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_provision_service_login","description":"Create a non-admin Home Assistant login for a program (an MQTT client such as","write_action":true,"price_micros":0,"input_schema":null},{"name":"ha_read_config_file","description":"Read a file under Home Assistant's config directory — configuration.yaml, a package, an","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_reload_automations","description":"Reload automations from configuration without restarting Home Assistant (calls automation.reload). Requires writes to be enabled.","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_remove_entity","description":"Remove an entity's registry entry, for cleaning up orphans: an entity whose integration no","write_action":true,"price_micros":0,"input_schema":null},{"name":"ha_remove_user_credentials","description":"Remove the local username/password login from a user, without deleting the user record","write_action":true,"price_micros":0,"input_schema":null},{"name":"ha_render_template","description":"Render a Home Assistant Jinja2 template against live state and return the result. Ideal for iterating on template sensors, automation conditions and value_templates until they produce the expected output. Example: \"{{ states('sensor.outside_temp') | float < 5 }}\".","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_save_dashboard","description":"Save (create or replace) the Lovelace configuration for a dashboard. 'config' is the dashboard body (title, views, …). Requires HA_ALLOW_WRITE=true and HA_ALLOW_CONFIG_WRITE=true.","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_set_automation","description":"Create or update an automation by unique id. 'config' is the automation body (alias, trigger, condition, action, mode). Home Assistant reloads automations automatically after saving. Requires HA_ALLOW_WRITE=true and HA_ALLOW_CONFIG_WRITE=true.","write_action":true,"price_micros":0,"input_schema":null},{"name":"ha_set_helper","description":"Create a Home Assistant helper, or update one that exists. **This is how to add a helper","write_action":true,"price_micros":0,"input_schema":null},{"name":"ha_set_log_level","description":"Raise or lower logging for one integration (or several) at runtime, via logger.set_level. Use this before reproducing a problem — debug on one integration, rather than global debug that drowns the log. Bare names are treated as core integrations ('hue' -> homeassistant.components.hue); anything containing a dot is used as-is ('custom_components.vomesync'). Levels reset on restart. Requires HA_ALLO","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_set_script","description":"Create or update a script by id. 'config' is the script body ({ alias, sequence, fields,","write_action":true,"price_micros":0,"input_schema":null},{"name":"ha_set_user_credentials","description":"Create a local username/password login and attach it to an existing user that has none","write_action":true,"price_micros":0,"input_schema":null},{"name":"ha_supervisor_api","description":"Call a Supervisor endpoint through Home Assistant's supervisor/api WebSocket command (e.g. /addons, /store/addons, /store/repositories). Requires a Supervised / HAOS install and ha:config for mutating methods. Use this for add-on store operations.","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_trigger_automation","description":"Manually run an automation's actions now (automation.trigger). Accepts entity_id or unique id. Set skip_condition=false to also evaluate conditions. Requires writes to be enabled.","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_update_entity","description":"Change an entity's registry entry: its display name, its entity_id, its area, its icon, or","write_action":true,"price_micros":0,"input_schema":null},{"name":"ha_update_user","description":"Change a user's name, role, active state, or local-only restriction. Omit a field to","write_action":true,"price_micros":0,"input_schema":null},{"name":"ha_view_snapshot","description":"In one call, everything a dashboard view shows: the state and attributes of each entity, each","write_action":false,"price_micros":0,"input_schema":null},{"name":"ha_write_config_file","description":"Write a file under Home Assistant's config directory. Defaults to UTF-8 text; pass","write_action":true,"price_micros":0,"input_schema":null},{"name":"nodered_create_flow","description":"Add a new Node-RED flow (a new tab) with its nodes, leaving existing flows untouched. The 'flow' object should have a 'label' and a 'nodes' array (Node-RED node objects). Requires HA_ALLOW_WRITE=true and HA_ALLOW_CONFIG_WRITE=true. Safer than nodered_set_flows because it cannot disturb other tabs.","write_action":true,"price_micros":0,"input_schema":null},{"name":"nodered_delete_flow","description":"Delete an entire Node-RED flow (one tab) and all of its nodes by id. This cannot be undone from here. Requires HA_ALLOW_WRITE=true and HA_ALLOW_CONFIG_WRITE=true.","write_action":true,"price_micros":0,"input_schema":null},{"name":"nodered_get_flow","description":"Get a single Node-RED flow (one editor tab) and its nodes by flow id. Use nodered_get_flows first to discover tab ids and labels.","write_action":false,"price_micros":0,"input_schema":null},{"name":"nodered_get_flows","description":"Get the full Node-RED flow configuration (the JSON array of all nodes across every tab) plus the current revision string. Pass that 'rev' back to nodered_set_flows to avoid clobbering a concurrent change. Prefer nodered_get_flow / nodered_update_flow for single-tab edits.","write_action":false,"price_micros":0,"input_schema":null},{"name":"nodered_list_nodes","description":"List the installed Node-RED node modules and the node types they provide (the palette). Use this to check which node types are available before writing a flow that references them.","write_action":false,"price_micros":0,"input_schema":null},{"name":"nodered_set_flows","description":"Replace the ENTIRE Node-RED flow configuration and deploy. This overwrites every tab — prefer nodered_create_flow / nodered_update_flow unless you really mean to rewrite everything. Pass the 'rev' from nodered_get_flows to avoid clobbering a concurrent change. deployment_type controls how Node-RED applies it ('full' restarts all flows; 'flows'/'nodes' restart only what changed; 'reload' re-reads f","write_action":false,"price_micros":0,"input_schema":null},{"name":"nodered_update_flow","description":"Replace a single Node-RED flow (one tab) and its nodes by id, leaving other tabs untouched. Read it first with nodered_get_flow, edit, then send the whole flow object back. Requires HA_ALLOW_WRITE=true and HA_ALLOW_CONFIG_WRITE=true.","write_action":true,"price_micros":0,"input_schema":null},{"name":"vome_health_check","description":"Start a fresh Vome health check on this Home Assistant: after fixing findings, this is how the score","write_action":false,"price_micros":0,"input_schema":null},{"name":"vome_health_report","description":"Vome's health score for this Home Assistant, out of 100, with everything its check found: each finding","write_action":false,"price_micros":0,"input_schema":null},{"name":"vomehome_complete_onboarding","description":"Finish the outstanding setup-wizard steps on a VomeHome instance, so it opens on a","write_action":false,"price_micros":0,"input_schema":null},{"name":"vomehome_create_guest_link","description":"Create a non-admin (unless admin=true) Home Assistant user for this instance, plus a","write_action":true,"price_micros":0,"input_schema":null},{"name":"vomehome_create_instance","description":"Create a new Home Assistant instance on VomeHome — useful for spinning up a throwaway test/sandbox install. In brokered mode the API key's create scope is authoritative (no local env flags required). Optionally set VOMEHOME_ALLOW_CREATE=false to block creation locally. The creating API key is granted full Home Assistant access on the new instance (ha:read, ha:write, ha:config, ha:files) and it bec","write_action":true,"price_micros":0,"input_schema":null},{"name":"vomehome_get_instance","description":"Get one VomeHome instance by id, including live status and the Home Assistant URL. Requires VOMEHOME_TOKEN.","write_action":false,"price_micros":0,"input_schema":null},{"name":"vomehome_get_login_url","description":"Get a one-click login URL that opens your VomeHome Home Assistant already signed in. Present the returned URL to the user as a link to open in a new browser tab/window. The URL embeds a short-lived credential, so treat it as a secret and do not log it. Requires VOMEHOME_TOKEN.","write_action":false,"price_micros":0,"input_schema":null},{"name":"vomehome_get_onboarding","description":"Which Home Assistant setup-wizard steps are still outstanding on a VomeHome instance.","write_action":false,"price_micros":0,"input_schema":null},{"name":"vomehome_list_guest_links","description":"List guest links created for this instance, including already-revoked ones (with","write_action":false,"price_micros":0,"input_schema":null},{"name":"vomehome_list_instances","description":"List the Home Assistant instances on your VomeHome account, with status, tier, HA URL and (where available) live health. Requires VOMEHOME_TOKEN.","write_action":false,"price_micros":0,"input_schema":null},{"name":"vomehome_reboot_instance","description":"Reboot a VomeHome Home Assistant instance (reboots the underlying VM). In brokered mode the API key's ha:write (or instances:write) scope is authoritative; an optional local VOMEHOME_INSTANCES write:false only adds a client-side block.","write_action":false,"price_micros":0,"input_schema":null},{"name":"vomehome_use_instance","description":"Switch which VomeHome instance the Home Assistant tools target. Subsequent ha_* calls (states, services, automations, templates, check_config) operate on this instance, and write/config permission follows that instance's own flags (declared in VOMEHOME_INSTANCES, the default instance, or auto-granted on create). An undeclared but reachable instance inherits the global default, which in brokered mo","write_action":false,"price_micros":0,"input_schema":null}],"scan":{"score":83,"grade":"B","scanned_at":"2026-10-14T12:20:33.169Z","report":{"scannerVersion":"0.1.10","scannedAt":"2026-10-14T12:20:33.108Z","components":{"code":{"score":25,"max":25,"notes":["105 source files scanned"]},"reliability":{"score":-1,"max":20,"notes":["no gateway calls yet and no remote to probe"]},"poisoning":{"score":-1,"max":15,"notes":["tools not inspected (local package is not executed); not counted"]},"auth":{"score":6,"max":15,"notes":["static API keys via environment variables"]},"maintenance":{"score":15,"max":15,"notes":["last push 0 days ago"]},"identity":{"score":8,"max":10,"notes":["registry namespace matches repository owner","GitHub account older than a year"]}},"findings":[],"inputs":{"packages":[{"registryType":"npm","identifier":"@vortitron/home-assistant-mcp","version":"0.11.0","found":true,"license":"MIT","hasInstallScripts":false,"dependencyCount":6,"publishedAt":"2026-10-14T08:39:02.825Z","repositoryUrl":"git+https://github.com/Vortitron/home-assistant-mcp.git","weeklyDownloads":114}],"repo":{"found":true,"owner":"Vortitron","repo":"home-assistant-mcp","archived":false,"pushedAt":"2026-10-14T09:54:44Z","stars":0,"forks":0,"openIssues":0,"ownerType":"User","ownerAvatarUrl":"https://avatars.githubusercontent.com/u/8288276?v=4","ownerCreatedAt":"2014-07-28T09:57:16Z","license":"MIT"},"icon":{"url":null,"source":"none"},"presence":{"stars":0,"forks":0,"downloadsWeek":114,"license":"MIT","lastPushAt":"2026-10-14T09:54:44.000Z","score":28}}}},"grade_history":[],"reviews":[]}