@coffeerunhobby/mcp-ha-connect 2.2.1 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (293) hide show
  1. package/.env.example +1 -1
  2. package/README.md +24 -2
  3. package/dist/omadaClient/accessControl.d.ts +290 -0
  4. package/dist/omadaClient/accessControl.js +509 -0
  5. package/dist/omadaClient/accessControl.js.map +1 -0
  6. package/dist/omadaClient/client.d.ts +6 -1
  7. package/dist/omadaClient/client.js +12 -1
  8. package/dist/omadaClient/client.js.map +1 -1
  9. package/dist/omadaClient/diagnose.d.ts +68 -0
  10. package/dist/omadaClient/diagnose.js +164 -0
  11. package/dist/omadaClient/diagnose.js.map +1 -0
  12. package/dist/omadaClient/index.d.ts +9 -0
  13. package/dist/omadaClient/index.js +19 -0
  14. package/dist/omadaClient/index.js.map +1 -1
  15. package/dist/omadaClient/macGroups.d.ts +58 -0
  16. package/dist/omadaClient/macGroups.js +110 -0
  17. package/dist/omadaClient/macGroups.js.map +1 -0
  18. package/dist/omadaClient/serialize.d.ts +13 -0
  19. package/dist/omadaClient/serialize.js +29 -0
  20. package/dist/omadaClient/serialize.js.map +1 -0
  21. package/dist/omadaClient/timeRange.d.ts +41 -0
  22. package/dist/omadaClient/timeRange.js +109 -0
  23. package/dist/omadaClient/timeRange.js.map +1 -0
  24. package/dist/tools/infra/actions.d.ts +1 -1
  25. package/dist/tools/infra/actions.js +1 -1
  26. package/dist/tools/omada/accessControl.d.ts +151 -0
  27. package/dist/tools/omada/accessControl.js +158 -0
  28. package/dist/tools/omada/accessControl.js.map +1 -0
  29. package/dist/tools/omada/index.js +9 -0
  30. package/dist/tools/omada/index.js.map +1 -1
  31. package/dist/tools/omada/macGroups.d.ts +19 -0
  32. package/dist/tools/omada/macGroups.js +77 -0
  33. package/dist/tools/omada/macGroups.js.map +1 -0
  34. package/dist/tools/omada/namespace.js +16 -0
  35. package/dist/tools/omada/namespace.js.map +1 -1
  36. package/dist/version.d.ts +1 -1
  37. package/dist/version.js +1 -1
  38. package/package.json +5 -1
  39. package/.codex/review-rules.md +0 -16
  40. package/.dockerignore +0 -8
  41. package/.gitattributes +0 -30
  42. package/.github/workflows/ci.yml +0 -193
  43. package/AGENTS.md +0 -389
  44. package/Dockerfile +0 -50
  45. package/docker-compose.yml +0 -23
  46. package/docs/CHANGELOG.md +0 -341
  47. package/docs/COVERAGE.md +0 -219
  48. package/docs/QUICK_START.md +0 -240
  49. package/eslint.config.js +0 -33
  50. package/n8n/ai-agent-safety-monitor.json +0 -355
  51. package/openapi.json +0 -1259
  52. package/scripts/check-version-sync.mjs +0 -69
  53. package/scripts/generate-jwt.ts +0 -121
  54. package/src/config.ts +0 -440
  55. package/src/haClient/automations.ts +0 -261
  56. package/src/haClient/calendars.ts +0 -94
  57. package/src/haClient/config.ts +0 -52
  58. package/src/haClient/devices.ts +0 -653
  59. package/src/haClient/entities.ts +0 -128
  60. package/src/haClient/events.ts +0 -689
  61. package/src/haClient/history.ts +0 -73
  62. package/src/haClient/index.ts +0 -336
  63. package/src/haClient/request.ts +0 -142
  64. package/src/haClient/services.ts +0 -45
  65. package/src/haClient/states.ts +0 -60
  66. package/src/haClient/updates.ts +0 -58
  67. package/src/haClient/wsCommand.ts +0 -44
  68. package/src/index.ts +0 -164
  69. package/src/localAI/index.ts +0 -88
  70. package/src/localAI/prompts.ts +0 -50
  71. package/src/localAI/providers/base.ts +0 -120
  72. package/src/localAI/providers/ollama.ts +0 -78
  73. package/src/localAI/providers/openai.ts +0 -86
  74. package/src/localAI/types.ts +0 -67
  75. package/src/omadaClient/auth.ts +0 -178
  76. package/src/omadaClient/client.ts +0 -337
  77. package/src/omadaClient/device.ts +0 -118
  78. package/src/omadaClient/index.ts +0 -310
  79. package/src/omadaClient/network.ts +0 -284
  80. package/src/omadaClient/request.ts +0 -365
  81. package/src/omadaClient/security.ts +0 -51
  82. package/src/omadaClient/site.ts +0 -344
  83. package/src/ownerQuestions/service.ts +0 -536
  84. package/src/permissions/index.ts +0 -143
  85. package/src/resources/index.ts +0 -213
  86. package/src/server/auth.ts +0 -175
  87. package/src/server/chatFace.ts +0 -789
  88. package/src/server/chatSlice.ts +0 -57
  89. package/src/server/common.ts +0 -170
  90. package/src/server/eventSubscription.ts +0 -343
  91. package/src/server/http.ts +0 -626
  92. package/src/server/instructions.ts +0 -97
  93. package/src/server/rateLimiter.ts +0 -227
  94. package/src/server/stdio.ts +0 -41
  95. package/src/server/stream.ts +0 -205
  96. package/src/tools/ai/analyzeSensors.ts +0 -33
  97. package/src/tools/ai/index.ts +0 -20
  98. package/src/tools/common.ts +0 -442
  99. package/src/tools/homeassistant/askOwner.ts +0 -133
  100. package/src/tools/homeassistant/automationControls.ts +0 -66
  101. package/src/tools/homeassistant/calendar.ts +0 -97
  102. package/src/tools/homeassistant/callService.ts +0 -25
  103. package/src/tools/homeassistant/controlClimate.ts +0 -68
  104. package/src/tools/homeassistant/controlCover.ts +0 -48
  105. package/src/tools/homeassistant/controlFan.ts +0 -44
  106. package/src/tools/homeassistant/controlLight.ts +0 -38
  107. package/src/tools/homeassistant/controlMediaPlayer.ts +0 -50
  108. package/src/tools/homeassistant/createAutomation.ts +0 -35
  109. package/src/tools/homeassistant/deleteAutomation.ts +0 -24
  110. package/src/tools/homeassistant/entityAction.ts +0 -35
  111. package/src/tools/homeassistant/entityGuard.ts +0 -28
  112. package/src/tools/homeassistant/getAllSensors.ts +0 -46
  113. package/src/tools/homeassistant/getAutomationTrace.ts +0 -30
  114. package/src/tools/homeassistant/getDomainSummary.ts +0 -29
  115. package/src/tools/homeassistant/getEntitiesByDomain.ts +0 -56
  116. package/src/tools/homeassistant/getHistory.ts +0 -24
  117. package/src/tools/homeassistant/getState.ts +0 -24
  118. package/src/tools/homeassistant/getStates.ts +0 -46
  119. package/src/tools/homeassistant/getVersion.ts +0 -21
  120. package/src/tools/homeassistant/index.ts +0 -121
  121. package/src/tools/homeassistant/listAutomations.ts +0 -35
  122. package/src/tools/homeassistant/listEntities.ts +0 -44
  123. package/src/tools/homeassistant/listPersons.ts +0 -46
  124. package/src/tools/homeassistant/sceneAndScript.ts +0 -53
  125. package/src/tools/homeassistant/searchEntities.ts +0 -58
  126. package/src/tools/homeassistant/sendNotification.ts +0 -179
  127. package/src/tools/homeassistant/systemTools.ts +0 -52
  128. package/src/tools/homeassistant/triggerAutomation.ts +0 -24
  129. package/src/tools/index.ts +0 -78
  130. package/src/tools/infra/actions.ts +0 -95
  131. package/src/tools/infra/index.ts +0 -138
  132. package/src/tools/omada/blockClient.ts +0 -28
  133. package/src/tools/omada/cyclePoePort.ts +0 -32
  134. package/src/tools/omada/deleteClient.ts +0 -27
  135. package/src/tools/omada/disableClientRateLimit.ts +0 -23
  136. package/src/tools/omada/getClient.ts +0 -14
  137. package/src/tools/omada/getDevice.ts +0 -14
  138. package/src/tools/omada/getFirewallSetting.ts +0 -14
  139. package/src/tools/omada/getInternetInfo.ts +0 -14
  140. package/src/tools/omada/getLanNetworkList.ts +0 -14
  141. package/src/tools/omada/getLanProfileList.ts +0 -14
  142. package/src/tools/omada/getPortForwardingStatus.ts +0 -26
  143. package/src/tools/omada/getRateLimitProfiles.ts +0 -14
  144. package/src/tools/omada/getSiteNtpStatus.ts +0 -14
  145. package/src/tools/omada/getSsidDetail.ts +0 -22
  146. package/src/tools/omada/getSsidList.ts +0 -21
  147. package/src/tools/omada/getSwitchStackDetail.ts +0 -14
  148. package/src/tools/omada/getThreatList.ts +0 -42
  149. package/src/tools/omada/getWlanGroupList.ts +0 -14
  150. package/src/tools/omada/graph.ts +0 -187
  151. package/src/tools/omada/index.ts +0 -153
  152. package/src/tools/omada/listBlockedClients.ts +0 -17
  153. package/src/tools/omada/listClients.ts +0 -14
  154. package/src/tools/omada/listClientsActivity.ts +0 -25
  155. package/src/tools/omada/listClientsPastConnections.ts +0 -44
  156. package/src/tools/omada/listDevices.ts +0 -14
  157. package/src/tools/omada/listDevicesStats.ts +0 -41
  158. package/src/tools/omada/listMostActiveClients.ts +0 -14
  159. package/src/tools/omada/listSites.ts +0 -18
  160. package/src/tools/omada/namespace.ts +0 -1164
  161. package/src/tools/omada/searchDevices.ts +0 -20
  162. package/src/tools/omada/setClientRateLimit.ts +0 -26
  163. package/src/tools/omada/setClientRateLimitProfile.ts +0 -25
  164. package/src/tools/omada/setSiteNtpServers.ts +0 -36
  165. package/src/tools/omada/setSsidEnabled.ts +0 -38
  166. package/src/tools/omada/unblockClient.ts +0 -26
  167. package/src/tools/types.ts +0 -11
  168. package/src/tools/utils/pagination-schema.ts +0 -27
  169. package/src/types/ai/index.ts +0 -11
  170. package/src/types/ai/types.ts +0 -67
  171. package/src/types/homeassistant/automations.ts +0 -43
  172. package/src/types/homeassistant/calendars.ts +0 -26
  173. package/src/types/homeassistant/config.ts +0 -14
  174. package/src/types/homeassistant/entities.ts +0 -14
  175. package/src/types/homeassistant/errors.ts +0 -33
  176. package/src/types/homeassistant/haConfig.ts +0 -7
  177. package/src/types/homeassistant/history.ts +0 -13
  178. package/src/types/homeassistant/index.ts +0 -46
  179. package/src/types/homeassistant/request.ts +0 -6
  180. package/src/types/homeassistant/serviceCall.ts +0 -18
  181. package/src/types/homeassistant/states.ts +0 -58
  182. package/src/types/homeassistant/updates.ts +0 -28
  183. package/src/types/index.ts +0 -12
  184. package/src/types/omada/activeClientInfo.ts +0 -17
  185. package/src/types/omada/clientActivity.ts +0 -32
  186. package/src/types/omada/clientBlockStatus.ts +0 -11
  187. package/src/types/omada/clientPastConnection.ts +0 -82
  188. package/src/types/omada/index.ts +0 -14
  189. package/src/types/omada/omadaApiResponse.ts +0 -5
  190. package/src/types/omada/omadaClientInfo.ts +0 -11
  191. package/src/types/omada/omadaDeviceInfo.ts +0 -11
  192. package/src/types/omada/omadaDeviceStats.ts +0 -31
  193. package/src/types/omada/omadaSiteSummary.ts +0 -5
  194. package/src/types/omada/oswStackDetail.ts +0 -11
  195. package/src/types/omada/paginatedResult.ts +0 -6
  196. package/src/types/omada/rateLimitProfile.ts +0 -58
  197. package/src/types/omada/threatInfo.ts +0 -38
  198. package/src/types/omada/tokenResult.ts +0 -6
  199. package/src/types.ts +0 -2
  200. package/src/utils/config-validations.ts +0 -68
  201. package/src/utils/jwt.ts +0 -112
  202. package/src/utils/logger.ts +0 -121
  203. package/src/utils/plainText.ts +0 -48
  204. package/src/utils/redact.ts +0 -59
  205. package/src/utils/sanitizeError.ts +0 -18
  206. package/src/utils/tlsDispatcher.ts +0 -69
  207. package/src/version.ts +0 -5
  208. package/tests/bdd/automation-creation.spec.ts +0 -214
  209. package/tests/bdd/automation-management.spec.ts +0 -267
  210. package/tests/bdd/calendar.spec.ts +0 -190
  211. package/tests/bdd/configuration.spec.ts +0 -283
  212. package/tests/bdd/device-control.spec.ts +0 -344
  213. package/tests/bdd/entity-listing.spec.ts +0 -208
  214. package/tests/bdd/entity-search.spec.ts +0 -183
  215. package/tests/bdd/history-retrieval.spec.ts +0 -195
  216. package/tests/bdd/notifications.spec.ts +0 -238
  217. package/tests/bdd/service-calls.spec.ts +0 -144
  218. package/tests/bdd/state-retrieval.spec.ts +0 -204
  219. package/tests/bench/hotpaths.bench.ts +0 -68
  220. package/tests/config.test.ts +0 -355
  221. package/tests/features/automation-creation.feature +0 -36
  222. package/tests/features/automation-management.feature +0 -54
  223. package/tests/features/calendar.feature +0 -37
  224. package/tests/features/configuration.feature +0 -70
  225. package/tests/features/device-control.feature +0 -100
  226. package/tests/features/entity-listing.feature +0 -51
  227. package/tests/features/entity-search.feature +0 -44
  228. package/tests/features/history-retrieval.feature +0 -38
  229. package/tests/features/notifications.feature +0 -37
  230. package/tests/features/service-calls.feature +0 -35
  231. package/tests/features/state-retrieval.feature +0 -37
  232. package/tests/fixtures/openapi-default-slice.json +0 -290
  233. package/tests/haClient/automationTrace.test.ts +0 -59
  234. package/tests/haClient/automations.test.ts +0 -149
  235. package/tests/haClient/config.test.ts +0 -117
  236. package/tests/haClient/entities.test.ts +0 -188
  237. package/tests/haClient/events.test.ts +0 -455
  238. package/tests/haClient/eventsTls.test.ts +0 -52
  239. package/tests/haClient/history.test.ts +0 -228
  240. package/tests/haClient/index.test.ts +0 -243
  241. package/tests/haClient/request.test.ts +0 -217
  242. package/tests/haClient/services.test.ts +0 -120
  243. package/tests/haClient/states.test.ts +0 -119
  244. package/tests/haClient/updates.test.ts +0 -193
  245. package/tests/index.test.ts +0 -160
  246. package/tests/integration/homeassistant.test.ts +0 -144
  247. package/tests/integration/omada.test.ts +0 -167
  248. package/tests/integration/server.test.ts +0 -151
  249. package/tests/localAI/index.test.ts +0 -177
  250. package/tests/localAI/ollama.test.ts +0 -187
  251. package/tests/localAI/openai.test.ts +0 -257
  252. package/tests/omadaClient/actions.test.ts +0 -161
  253. package/tests/omadaClient/clientBlocks.test.ts +0 -170
  254. package/tests/omadaClient/ntp.test.ts +0 -381
  255. package/tests/omadaClient/site.test.ts +0 -37
  256. package/tests/ownerQuestions/service.test.ts +0 -499
  257. package/tests/ownerQuestions/tools.test.ts +0 -186
  258. package/tests/permissions/index.test.ts +0 -217
  259. package/tests/resources/index.test.ts +0 -288
  260. package/tests/scripts/generateJwt.test.ts +0 -44
  261. package/tests/security/accessControl.test.ts +0 -223
  262. package/tests/security/authentication.test.ts +0 -117
  263. package/tests/security/configuration.test.ts +0 -170
  264. package/tests/security/cryptoTransport.test.ts +0 -172
  265. package/tests/security/dependencies.test.ts +0 -152
  266. package/tests/security/injection.test.ts +0 -117
  267. package/tests/security/insecureDesign.test.ts +0 -121
  268. package/tests/security/logging.test.ts +0 -131
  269. package/tests/security/resourceConsumption.test.ts +0 -142
  270. package/tests/server/auth.test.ts +0 -249
  271. package/tests/server/chatFace.test.ts +0 -320
  272. package/tests/server/common.test.ts +0 -84
  273. package/tests/server/http.test.ts +0 -561
  274. package/tests/server/instructions.test.ts +0 -152
  275. package/tests/server/memoizeJsonSchema.test.ts +0 -71
  276. package/tests/server/stdio.test.ts +0 -99
  277. package/tests/server/stream.test.ts +0 -285
  278. package/tests/server/toolVisibility.http.test.ts +0 -111
  279. package/tests/server/toolVisibility.test.ts +0 -129
  280. package/tests/tools/ai/analyzeSensors.test.ts +0 -227
  281. package/tests/tools/common.test.ts +0 -123
  282. package/tests/tools/homeassistant/handlers.test.ts +0 -872
  283. package/tests/tools/infra/invokeAction.test.ts +0 -280
  284. package/tests/tools/omada/graph.test.ts +0 -385
  285. package/tests/tools/omada/handlers.test.ts +0 -897
  286. package/tests/tools/omada/namespace.test.ts +0 -483
  287. package/tests/tools/registry.test.ts +0 -168
  288. package/tests/utils/config-validations.test.ts +0 -352
  289. package/tests/utils/jwt.test.ts +0 -115
  290. package/tests/utils/logger.test.ts +0 -327
  291. package/tests/utils/redact.test.ts +0 -105
  292. package/tsconfig.json +0 -24
  293. package/vitest.config.ts +0 -38
@@ -1,51 +0,0 @@
1
- Feature: Entity Listing
2
- As a Home Assistant user
3
- I want to list and filter entities
4
- So that I can get an overview of my smart home devices
5
-
6
- Scenario: List all entities without filters
7
- Given a Home Assistant instance with multiple entities
8
- When I list all entities
9
- Then I should get all 4 entities
10
-
11
- Scenario: Filter entities by domain
12
- Given a Home Assistant instance with multiple entities
13
- When I list entities filtered by domain "light"
14
- Then I should only get light entities
15
- And the count should be 2
16
-
17
- Scenario: Filter entities by state
18
- Given a Home Assistant instance with multiple entities
19
- When I list entities filtered by state "on"
20
- Then I should only get entities that are "on"
21
- And the count should be 2
22
-
23
- Scenario: Filter entities by search query
24
- Given a Home Assistant instance with multiple entities
25
- When I list entities filtered by search "room"
26
- Then I should only get entities matching "room"
27
- And the count should be 2
28
-
29
- Scenario: Apply limit to entity list
30
- Given a Home Assistant instance with multiple entities
31
- When I list entities with limit 2
32
- Then I should get at most 2 entities
33
-
34
- Scenario: Combine multiple filters
35
- Given a Home Assistant instance with multiple entities
36
- When I list entities filtered by domain "light" and state "on"
37
- Then I should only get lights that are on
38
- And the count should be 1
39
-
40
- Scenario: Get domain summary
41
- Given a Home Assistant instance with multiple entities
42
- When I get the summary for domain "light"
43
- Then the summary should show domain "light"
44
- And the total count should be 2
45
- And the state breakdown should show 1 "on" and 1 "off"
46
-
47
- Scenario: Get domain summary for non-existent domain
48
- Given a Home Assistant instance with multiple entities
49
- When I get the summary for domain "vacuum"
50
- Then the summary should show domain "vacuum"
51
- And the total count should be 0
@@ -1,44 +0,0 @@
1
- Feature: Entity Search
2
- As a Home Assistant user
3
- I want to search for entities by name or ID
4
- So that I can find and control my devices
5
-
6
- Scenario: Search entities by friendly name
7
- Given a Home Assistant instance with multiple entities
8
- When I search for "living"
9
- Then I should find entities with "living" in their friendly name
10
- And the results should include "light.living_room"
11
-
12
- Scenario: Search entities by entity ID
13
- Given a Home Assistant instance with multiple entities
14
- When I search for "kitchen"
15
- Then I should find entities with "kitchen" in their entity ID
16
- And the results should include "switch.kitchen"
17
-
18
- Scenario: Search is case insensitive
19
- Given a Home Assistant instance with multiple entities
20
- When I search for "BEDROOM"
21
- Then I should find entities matching "bedroom"
22
- And the results should include "light.bedroom"
23
-
24
- Scenario: Search returns multiple matches
25
- Given a Home Assistant instance with multiple entities
26
- When I search for "light"
27
- Then I should find all entities containing "light"
28
- And the result count should be 2
29
-
30
- Scenario: Search returns empty for no matches
31
- Given a Home Assistant instance with multiple entities
32
- When I search for "nonexistent"
33
- Then I should find no entities
34
-
35
- Scenario: Get entities by domain
36
- Given a Home Assistant instance with multiple entities
37
- When I get entities for domain "light"
38
- Then I should only get light entities
39
- And all entity IDs should start with "light."
40
-
41
- Scenario: Get entities for empty domain
42
- Given a Home Assistant instance with multiple entities
43
- When I get entities for domain "climate"
44
- Then I should find no entities
@@ -1,38 +0,0 @@
1
- Feature: History Retrieval
2
- As a Home Assistant user
3
- I want to retrieve historical data for my entities
4
- So that I can analyze trends and patterns
5
-
6
- Scenario: Get entity history for last 24 hours
7
- Given an entity "sensor.temperature" with historical data
8
- When I get the history for the last 24 hours
9
- Then I should receive historical state changes
10
- And the history API should be called with the correct time range
11
-
12
- Scenario: Get entity history with custom time range
13
- Given an entity "sensor.temperature" with historical data
14
- When I get the history for the last 48 hours
15
- Then I should receive historical state changes
16
- And the time range should be 48 hours
17
-
18
- Scenario: Get empty history for entity
19
- Given an entity with no history
20
- When I get the history
21
- Then I should receive an empty history array
22
-
23
- Scenario: Get system log entries
24
- Given a Home Assistant system log
25
- When I get the system log
26
- Then I should receive logbook entries
27
- And each entry should have timestamp and entity information
28
-
29
- Scenario: Get system log filtered by entity
30
- Given a Home Assistant system log
31
- When I get the system log for entity "light.living_room"
32
- Then I should receive only entries for that entity
33
- And the entity filter should be applied
34
-
35
- Scenario: Get system log with custom time range
36
- Given a Home Assistant system log
37
- When I get the system log for the last 48 hours
38
- Then the logbook API should use the 48 hour time range
@@ -1,37 +0,0 @@
1
- Feature: Send Notifications
2
- As a Home Assistant user
3
- I want to send notifications to my mobile devices
4
- So that I can be alerted about important events
5
-
6
- Scenario: Send a simple notification
7
- Given a notification message "Hello from MCP!"
8
- When I send the notification to "mobile_app_samsung_s25_fe"
9
- Then the notification should be sent successfully
10
- And the service called should be "notify.mobile_app_samsung_s25_fe"
11
-
12
- Scenario: Send notification with title
13
- Given a notification message "Motion detected in garage"
14
- And a notification title "Security Alert"
15
- When I send the notification to "mobile_app_samsung_s25_fe"
16
- Then the notification should be sent successfully
17
- And the title should be included in the service data
18
-
19
- Scenario: Send notification with action buttons
20
- Given a notification message "Someone is at the door"
21
- And an action button "OPEN" with title "Open Door"
22
- And an action button "IGNORE" with title "Ignore"
23
- When I send the notification to "mobile_app_samsung_s25_fe"
24
- Then the notification should be sent successfully
25
- And the notification data should contain 2 actions
26
-
27
- Scenario: Send persistent notification (no target)
28
- Given a notification message "System update available"
29
- When I send the notification without a target
30
- Then the notification should be sent to "persistent_notification"
31
-
32
- Scenario: Send high priority notification
33
- Given a notification message "Water leak detected!"
34
- And priority set to "high"
35
- When I send the notification to "mobile_app_samsung_s25_fe"
36
- Then the notification should be sent successfully
37
- And the notification data should have priority "high"
@@ -1,35 +0,0 @@
1
- Feature: Service Calls
2
- As a Home Assistant user
3
- I want to call Home Assistant services
4
- So that I can control my devices
5
-
6
- Scenario: Call service with domain and service name
7
- Given a Home Assistant connection
8
- When I call service "light.turn_on"
9
- Then the service should be called successfully
10
- And the request should go to "/services/light/turn_on"
11
-
12
- Scenario: Call service with target entity
13
- Given a Home Assistant connection
14
- When I call service "light.turn_on" targeting "light.living_room"
15
- Then the entity_id should be included in the request
16
-
17
- Scenario: Call service with service data
18
- Given a Home Assistant connection
19
- When I call service "light.turn_on" with brightness 255
20
- Then the brightness should be included in the request
21
-
22
- Scenario: Call service targeting multiple entities
23
- Given a Home Assistant connection
24
- When I call service "light.turn_off" targeting multiple entities
25
- Then all entity IDs should be included in the request
26
-
27
- Scenario: Call climate service with temperature
28
- Given a Home Assistant connection
29
- When I call service "climate.set_temperature" with temperature 22
30
- Then the temperature should be included in the request
31
-
32
- Scenario: Restart Home Assistant server
33
- Given a Home Assistant connection
34
- When I call the restart server operation
35
- Then the homeassistant.restart service should be called
@@ -1,37 +0,0 @@
1
- Feature: State Retrieval
2
- As a Home Assistant user
3
- I want to retrieve entity states
4
- So that I can monitor my smart home devices
5
-
6
- Scenario: Get all entity states
7
- Given a Home Assistant with multiple entities
8
- When I get all states
9
- Then I should receive all entity states
10
- And the states API should be called
11
-
12
- Scenario: Get state of specific entity
13
- Given an entity "light.living_room" exists
14
- When I get the state of "light.living_room"
15
- Then I should receive the entity state
16
- And the state should include entity_id, state, and attributes
17
-
18
- Scenario: Get state of non-existent entity
19
- Given an entity does not exist
20
- When I get the state of "nonexistent.entity"
21
- Then I should receive null
22
-
23
- Scenario: Handle API error gracefully
24
- Given the API returns a 500 error
25
- When I get the state of "sensor.temperature"
26
- Then it should throw an API error
27
-
28
- Scenario: Get all sensors
29
- Given a Home Assistant with sensors and other entities
30
- When I get all sensors
31
- Then I should only receive sensor and binary_sensor entities
32
- And other entity types should be excluded
33
-
34
- Scenario: Get sensors when none exist
35
- Given a Home Assistant with no sensors
36
- When I get all sensors
37
- Then I should receive an empty array
@@ -1,290 +0,0 @@
1
- {
2
- "openapi": "3.1.0",
3
- "info": {
4
- "title": "Home Assistant MCP Tools",
5
- "description": "MCP server for Home Assistant - exposes entity states and service calls",
6
- "version": "1.6.0"
7
- },
8
- "servers": [
9
- {
10
- "url": "http://__BASE_URL__"
11
- }
12
- ],
13
- "paths": {
14
- "/api/states": {
15
- "get": {
16
- "operationId": "getStates",
17
- "summary": "Get all entity states from Home Assistant",
18
- "responses": {
19
- "200": {
20
- "description": "List of all entity states",
21
- "content": {
22
- "application/json": {
23
- "schema": {
24
- "type": "array",
25
- "items": {
26
- "$ref": "#/components/schemas/EntityState"
27
- }
28
- }
29
- }
30
- }
31
- }
32
- }
33
- }
34
- },
35
- "/api/states/{entity_id}": {
36
- "get": {
37
- "operationId": "getState",
38
- "summary": "Get state of a specific entity",
39
- "parameters": [
40
- {
41
- "name": "entity_id",
42
- "in": "path",
43
- "required": true,
44
- "schema": {
45
- "type": "string"
46
- },
47
- "description": "Entity ID (e.g., light.living_room)"
48
- }
49
- ],
50
- "responses": {
51
- "200": {
52
- "description": "Entity state",
53
- "content": {
54
- "application/json": {
55
- "schema": {
56
- "$ref": "#/components/schemas/EntityState"
57
- }
58
- }
59
- }
60
- }
61
- }
62
- }
63
- },
64
- "/api/services/{domain}/{service}": {
65
- "post": {
66
- "operationId": "callService",
67
- "summary": "Call a Home Assistant service",
68
- "parameters": [
69
- {
70
- "name": "domain",
71
- "in": "path",
72
- "required": true,
73
- "schema": {
74
- "type": "string"
75
- },
76
- "description": "Service domain (e.g., light, switch)"
77
- },
78
- {
79
- "name": "service",
80
- "in": "path",
81
- "required": true,
82
- "schema": {
83
- "type": "string"
84
- },
85
- "description": "Service name (e.g., turn_on, turn_off)"
86
- }
87
- ],
88
- "requestBody": {
89
- "content": {
90
- "application/json": {
91
- "schema": {
92
- "type": "object",
93
- "properties": {
94
- "entity_id": {
95
- "type": "string",
96
- "description": "Target entity ID"
97
- },
98
- "data": {
99
- "type": "object",
100
- "description": "Service data"
101
- }
102
- }
103
- }
104
- }
105
- }
106
- },
107
- "responses": {
108
- "200": {
109
- "description": "Service call result"
110
- }
111
- }
112
- }
113
- },
114
- "/api/sensors": {
115
- "get": {
116
- "operationId": "getAllSensors",
117
- "summary": "Get all sensor and binary_sensor states",
118
- "responses": {
119
- "200": {
120
- "description": "List of sensor states",
121
- "content": {
122
- "application/json": {
123
- "schema": {
124
- "type": "array",
125
- "items": {
126
- "$ref": "#/components/schemas/EntityState"
127
- }
128
- }
129
- }
130
- }
131
- }
132
- }
133
- }
134
- },
135
- "/api/entities/{domain}": {
136
- "get": {
137
- "operationId": "getEntitiesByDomain",
138
- "summary": "Get all entities for a specific domain",
139
- "parameters": [
140
- {
141
- "name": "domain",
142
- "in": "path",
143
- "required": true,
144
- "schema": {
145
- "type": "string"
146
- },
147
- "description": "Domain name (e.g., light, sensor)"
148
- }
149
- ],
150
- "responses": {
151
- "200": {
152
- "description": "List of entities in domain",
153
- "content": {
154
- "application/json": {
155
- "schema": {
156
- "type": "array",
157
- "items": {
158
- "$ref": "#/components/schemas/EntityState"
159
- }
160
- }
161
- }
162
- }
163
- }
164
- }
165
- }
166
- },
167
- "/api/search": {
168
- "get": {
169
- "operationId": "searchEntities",
170
- "summary": "Search entities by name or ID",
171
- "parameters": [
172
- {
173
- "name": "q",
174
- "in": "query",
175
- "required": true,
176
- "schema": {
177
- "type": "string"
178
- },
179
- "description": "Search query"
180
- }
181
- ],
182
- "responses": {
183
- "200": {
184
- "description": "Matching entities",
185
- "content": {
186
- "application/json": {
187
- "schema": {
188
- "type": "array",
189
- "items": {
190
- "$ref": "#/components/schemas/EntityState"
191
- }
192
- }
193
- }
194
- }
195
- }
196
- }
197
- }
198
- },
199
- "/api/history/{entity_id}": {
200
- "get": {
201
- "operationId": "getHistory",
202
- "summary": "Get historical data for an entity",
203
- "parameters": [
204
- {
205
- "name": "entity_id",
206
- "in": "path",
207
- "required": true,
208
- "schema": {
209
- "type": "string"
210
- },
211
- "description": "Entity ID"
212
- },
213
- {
214
- "name": "hours",
215
- "in": "query",
216
- "schema": {
217
- "type": "number",
218
- "default": 24
219
- },
220
- "description": "Hours of history"
221
- }
222
- ],
223
- "responses": {
224
- "200": {
225
- "description": "Historical data",
226
- "content": {
227
- "application/json": {
228
- "schema": {
229
- "type": "array"
230
- }
231
- }
232
- }
233
- }
234
- }
235
- }
236
- },
237
- "/api/version": {
238
- "get": {
239
- "operationId": "getVersion",
240
- "summary": "Get Home Assistant version information",
241
- "responses": {
242
- "200": {
243
- "description": "Version information",
244
- "content": {
245
- "application/json": {
246
- "schema": {
247
- "type": "object",
248
- "properties": {
249
- "ha_version": {
250
- "type": "string",
251
- "description": "Home Assistant version"
252
- },
253
- "mcp_version": {
254
- "type": "string",
255
- "description": "MCP server version"
256
- }
257
- }
258
- }
259
- }
260
- }
261
- }
262
- }
263
- }
264
- }
265
- },
266
- "components": {
267
- "schemas": {
268
- "EntityState": {
269
- "type": "object",
270
- "properties": {
271
- "entity_id": {
272
- "type": "string"
273
- },
274
- "state": {
275
- "type": "string"
276
- },
277
- "attributes": {
278
- "type": "object"
279
- },
280
- "last_changed": {
281
- "type": "string"
282
- },
283
- "last_updated": {
284
- "type": "string"
285
- }
286
- }
287
- }
288
- }
289
- }
290
- }
@@ -1,59 +0,0 @@
1
- /**
2
- * getAutomationTrace goes over the WebSocket (`trace/list`), keyed by the
3
- * automation's config id — there is no REST trace endpoint in Home Assistant.
4
- */
5
-
6
- import { describe, it, expect, vi } from 'vitest';
7
-
8
- import { AutomationOperations } from '../../src/haClient/automations.js';
9
- import type { StateOperations } from '../../src/haClient/states.js';
10
-
11
- function setup(state: unknown, traces: unknown = []) {
12
- const stateOps = { getState: vi.fn().mockResolvedValue(state) } as unknown as StateOperations;
13
- const wsCommand = vi.fn().mockResolvedValue(traces);
14
- const request = { get: vi.fn() };
15
- const ops = new AutomationOperations(stateOps, undefined, request as never, wsCommand as never);
16
- return { ops, wsCommand, request };
17
- }
18
-
19
- const automation = (attributes: Record<string, unknown>) => ({ entity_id: 'automation.relay', state: 'on', attributes });
20
-
21
- const run = (id: string, start: string) => ({ run_id: id, timestamp: { start, finish: start }, trigger: 'state of sensor.x' });
22
-
23
- describe('AutomationOperations.getAutomationTrace', () => {
24
- it('lists traces by the automation id attribute, newest first, over the WebSocket only', async () => {
25
- const { ops, wsCommand, request } = setup(automation({ id: '1700000000000' }), [
26
- run('a', '2026-10-07T08:00:00Z'),
27
- run('c', '2026-10-07T10:00:00Z'),
28
- run('b', '2026-10-07T09:00:00Z'),
29
- ]);
30
-
31
- const traces = await ops.getAutomationTrace('automation.relay');
32
-
33
- expect(wsCommand).toHaveBeenCalledWith({ type: 'trace/list', domain: 'automation', item_id: '1700000000000' });
34
- expect(traces.map((t) => t.run_id)).toEqual(['c', 'b', 'a']);
35
- expect(request.get).not.toHaveBeenCalled();
36
- });
37
-
38
- it('returns at most `limit` runs (default 5)', async () => {
39
- const many = Array.from({ length: 8 }, (_, i) => run(String(i), `2026-10-07T0${i}:00:00Z`));
40
- const { ops } = setup(automation({ id: 7 }), many);
41
-
42
- expect(await ops.getAutomationTrace('automation.relay')).toHaveLength(5);
43
- expect((await ops.getAutomationTrace('automation.relay', 2)).map((t) => t.run_id)).toEqual(['7', '6']);
44
- });
45
-
46
- it('explains that a YAML automation without an id has no traces', async () => {
47
- const { ops, wsCommand } = setup(automation({ friendly_name: 'Relay' }));
48
-
49
- await expect(ops.getAutomationTrace('automation.relay')).rejects.toThrow(/has no 'id'.*no traces/);
50
- expect(wsCommand).not.toHaveBeenCalled();
51
- });
52
-
53
- it('reports an unknown automation', async () => {
54
- const { ops, wsCommand } = setup(null);
55
-
56
- await expect(ops.getAutomationTrace('automation.nope')).rejects.toThrow('Automation automation.nope not found');
57
- expect(wsCommand).not.toHaveBeenCalled();
58
- });
59
- });