@coffeerunhobby/mcp-ha-connect 2.2.1 → 2.3.1

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 (281) hide show
  1. package/.env.example +1 -1
  2. package/README.md +11 -2
  3. package/dist/omadaClient/client.d.ts +6 -1
  4. package/dist/omadaClient/client.js +12 -1
  5. package/dist/omadaClient/client.js.map +1 -1
  6. package/dist/omadaClient/diagnose.d.ts +68 -0
  7. package/dist/omadaClient/diagnose.js +164 -0
  8. package/dist/omadaClient/diagnose.js.map +1 -0
  9. package/dist/omadaClient/index.d.ts +6 -0
  10. package/dist/omadaClient/index.js +15 -0
  11. package/dist/omadaClient/index.js.map +1 -1
  12. package/dist/omadaClient/macGroups.d.ts +58 -0
  13. package/dist/omadaClient/macGroups.js +124 -0
  14. package/dist/omadaClient/macGroups.js.map +1 -0
  15. package/dist/tools/infra/actions.d.ts +1 -1
  16. package/dist/tools/infra/actions.js +1 -1
  17. package/dist/tools/omada/index.js +6 -0
  18. package/dist/tools/omada/index.js.map +1 -1
  19. package/dist/tools/omada/macGroups.d.ts +19 -0
  20. package/dist/tools/omada/macGroups.js +77 -0
  21. package/dist/tools/omada/macGroups.js.map +1 -0
  22. package/dist/tools/omada/namespace.js +8 -0
  23. package/dist/tools/omada/namespace.js.map +1 -1
  24. package/dist/version.d.ts +1 -1
  25. package/dist/version.js +1 -1
  26. package/package.json +5 -1
  27. package/.codex/review-rules.md +0 -16
  28. package/.dockerignore +0 -8
  29. package/.gitattributes +0 -30
  30. package/.github/workflows/ci.yml +0 -193
  31. package/AGENTS.md +0 -389
  32. package/Dockerfile +0 -50
  33. package/docker-compose.yml +0 -23
  34. package/docs/CHANGELOG.md +0 -341
  35. package/docs/COVERAGE.md +0 -219
  36. package/docs/QUICK_START.md +0 -240
  37. package/eslint.config.js +0 -33
  38. package/n8n/ai-agent-safety-monitor.json +0 -355
  39. package/openapi.json +0 -1259
  40. package/scripts/check-version-sync.mjs +0 -69
  41. package/scripts/generate-jwt.ts +0 -121
  42. package/src/config.ts +0 -440
  43. package/src/haClient/automations.ts +0 -261
  44. package/src/haClient/calendars.ts +0 -94
  45. package/src/haClient/config.ts +0 -52
  46. package/src/haClient/devices.ts +0 -653
  47. package/src/haClient/entities.ts +0 -128
  48. package/src/haClient/events.ts +0 -689
  49. package/src/haClient/history.ts +0 -73
  50. package/src/haClient/index.ts +0 -336
  51. package/src/haClient/request.ts +0 -142
  52. package/src/haClient/services.ts +0 -45
  53. package/src/haClient/states.ts +0 -60
  54. package/src/haClient/updates.ts +0 -58
  55. package/src/haClient/wsCommand.ts +0 -44
  56. package/src/index.ts +0 -164
  57. package/src/localAI/index.ts +0 -88
  58. package/src/localAI/prompts.ts +0 -50
  59. package/src/localAI/providers/base.ts +0 -120
  60. package/src/localAI/providers/ollama.ts +0 -78
  61. package/src/localAI/providers/openai.ts +0 -86
  62. package/src/localAI/types.ts +0 -67
  63. package/src/omadaClient/auth.ts +0 -178
  64. package/src/omadaClient/client.ts +0 -337
  65. package/src/omadaClient/device.ts +0 -118
  66. package/src/omadaClient/index.ts +0 -310
  67. package/src/omadaClient/network.ts +0 -284
  68. package/src/omadaClient/request.ts +0 -365
  69. package/src/omadaClient/security.ts +0 -51
  70. package/src/omadaClient/site.ts +0 -344
  71. package/src/ownerQuestions/service.ts +0 -536
  72. package/src/permissions/index.ts +0 -143
  73. package/src/resources/index.ts +0 -213
  74. package/src/server/auth.ts +0 -175
  75. package/src/server/chatFace.ts +0 -789
  76. package/src/server/chatSlice.ts +0 -57
  77. package/src/server/common.ts +0 -170
  78. package/src/server/eventSubscription.ts +0 -343
  79. package/src/server/http.ts +0 -626
  80. package/src/server/instructions.ts +0 -97
  81. package/src/server/rateLimiter.ts +0 -227
  82. package/src/server/stdio.ts +0 -41
  83. package/src/server/stream.ts +0 -205
  84. package/src/tools/ai/analyzeSensors.ts +0 -33
  85. package/src/tools/ai/index.ts +0 -20
  86. package/src/tools/common.ts +0 -442
  87. package/src/tools/homeassistant/askOwner.ts +0 -133
  88. package/src/tools/homeassistant/automationControls.ts +0 -66
  89. package/src/tools/homeassistant/calendar.ts +0 -97
  90. package/src/tools/homeassistant/callService.ts +0 -25
  91. package/src/tools/homeassistant/controlClimate.ts +0 -68
  92. package/src/tools/homeassistant/controlCover.ts +0 -48
  93. package/src/tools/homeassistant/controlFan.ts +0 -44
  94. package/src/tools/homeassistant/controlLight.ts +0 -38
  95. package/src/tools/homeassistant/controlMediaPlayer.ts +0 -50
  96. package/src/tools/homeassistant/createAutomation.ts +0 -35
  97. package/src/tools/homeassistant/deleteAutomation.ts +0 -24
  98. package/src/tools/homeassistant/entityAction.ts +0 -35
  99. package/src/tools/homeassistant/entityGuard.ts +0 -28
  100. package/src/tools/homeassistant/getAllSensors.ts +0 -46
  101. package/src/tools/homeassistant/getAutomationTrace.ts +0 -30
  102. package/src/tools/homeassistant/getDomainSummary.ts +0 -29
  103. package/src/tools/homeassistant/getEntitiesByDomain.ts +0 -56
  104. package/src/tools/homeassistant/getHistory.ts +0 -24
  105. package/src/tools/homeassistant/getState.ts +0 -24
  106. package/src/tools/homeassistant/getStates.ts +0 -46
  107. package/src/tools/homeassistant/getVersion.ts +0 -21
  108. package/src/tools/homeassistant/index.ts +0 -121
  109. package/src/tools/homeassistant/listAutomations.ts +0 -35
  110. package/src/tools/homeassistant/listEntities.ts +0 -44
  111. package/src/tools/homeassistant/listPersons.ts +0 -46
  112. package/src/tools/homeassistant/sceneAndScript.ts +0 -53
  113. package/src/tools/homeassistant/searchEntities.ts +0 -58
  114. package/src/tools/homeassistant/sendNotification.ts +0 -179
  115. package/src/tools/homeassistant/systemTools.ts +0 -52
  116. package/src/tools/homeassistant/triggerAutomation.ts +0 -24
  117. package/src/tools/index.ts +0 -78
  118. package/src/tools/infra/actions.ts +0 -95
  119. package/src/tools/infra/index.ts +0 -138
  120. package/src/tools/omada/blockClient.ts +0 -28
  121. package/src/tools/omada/cyclePoePort.ts +0 -32
  122. package/src/tools/omada/deleteClient.ts +0 -27
  123. package/src/tools/omada/disableClientRateLimit.ts +0 -23
  124. package/src/tools/omada/getClient.ts +0 -14
  125. package/src/tools/omada/getDevice.ts +0 -14
  126. package/src/tools/omada/getFirewallSetting.ts +0 -14
  127. package/src/tools/omada/getInternetInfo.ts +0 -14
  128. package/src/tools/omada/getLanNetworkList.ts +0 -14
  129. package/src/tools/omada/getLanProfileList.ts +0 -14
  130. package/src/tools/omada/getPortForwardingStatus.ts +0 -26
  131. package/src/tools/omada/getRateLimitProfiles.ts +0 -14
  132. package/src/tools/omada/getSiteNtpStatus.ts +0 -14
  133. package/src/tools/omada/getSsidDetail.ts +0 -22
  134. package/src/tools/omada/getSsidList.ts +0 -21
  135. package/src/tools/omada/getSwitchStackDetail.ts +0 -14
  136. package/src/tools/omada/getThreatList.ts +0 -42
  137. package/src/tools/omada/getWlanGroupList.ts +0 -14
  138. package/src/tools/omada/graph.ts +0 -187
  139. package/src/tools/omada/index.ts +0 -153
  140. package/src/tools/omada/listBlockedClients.ts +0 -17
  141. package/src/tools/omada/listClients.ts +0 -14
  142. package/src/tools/omada/listClientsActivity.ts +0 -25
  143. package/src/tools/omada/listClientsPastConnections.ts +0 -44
  144. package/src/tools/omada/listDevices.ts +0 -14
  145. package/src/tools/omada/listDevicesStats.ts +0 -41
  146. package/src/tools/omada/listMostActiveClients.ts +0 -14
  147. package/src/tools/omada/listSites.ts +0 -18
  148. package/src/tools/omada/namespace.ts +0 -1164
  149. package/src/tools/omada/searchDevices.ts +0 -20
  150. package/src/tools/omada/setClientRateLimit.ts +0 -26
  151. package/src/tools/omada/setClientRateLimitProfile.ts +0 -25
  152. package/src/tools/omada/setSiteNtpServers.ts +0 -36
  153. package/src/tools/omada/setSsidEnabled.ts +0 -38
  154. package/src/tools/omada/unblockClient.ts +0 -26
  155. package/src/tools/types.ts +0 -11
  156. package/src/tools/utils/pagination-schema.ts +0 -27
  157. package/src/types/ai/index.ts +0 -11
  158. package/src/types/ai/types.ts +0 -67
  159. package/src/types/homeassistant/automations.ts +0 -43
  160. package/src/types/homeassistant/calendars.ts +0 -26
  161. package/src/types/homeassistant/config.ts +0 -14
  162. package/src/types/homeassistant/entities.ts +0 -14
  163. package/src/types/homeassistant/errors.ts +0 -33
  164. package/src/types/homeassistant/haConfig.ts +0 -7
  165. package/src/types/homeassistant/history.ts +0 -13
  166. package/src/types/homeassistant/index.ts +0 -46
  167. package/src/types/homeassistant/request.ts +0 -6
  168. package/src/types/homeassistant/serviceCall.ts +0 -18
  169. package/src/types/homeassistant/states.ts +0 -58
  170. package/src/types/homeassistant/updates.ts +0 -28
  171. package/src/types/index.ts +0 -12
  172. package/src/types/omada/activeClientInfo.ts +0 -17
  173. package/src/types/omada/clientActivity.ts +0 -32
  174. package/src/types/omada/clientBlockStatus.ts +0 -11
  175. package/src/types/omada/clientPastConnection.ts +0 -82
  176. package/src/types/omada/index.ts +0 -14
  177. package/src/types/omada/omadaApiResponse.ts +0 -5
  178. package/src/types/omada/omadaClientInfo.ts +0 -11
  179. package/src/types/omada/omadaDeviceInfo.ts +0 -11
  180. package/src/types/omada/omadaDeviceStats.ts +0 -31
  181. package/src/types/omada/omadaSiteSummary.ts +0 -5
  182. package/src/types/omada/oswStackDetail.ts +0 -11
  183. package/src/types/omada/paginatedResult.ts +0 -6
  184. package/src/types/omada/rateLimitProfile.ts +0 -58
  185. package/src/types/omada/threatInfo.ts +0 -38
  186. package/src/types/omada/tokenResult.ts +0 -6
  187. package/src/types.ts +0 -2
  188. package/src/utils/config-validations.ts +0 -68
  189. package/src/utils/jwt.ts +0 -112
  190. package/src/utils/logger.ts +0 -121
  191. package/src/utils/plainText.ts +0 -48
  192. package/src/utils/redact.ts +0 -59
  193. package/src/utils/sanitizeError.ts +0 -18
  194. package/src/utils/tlsDispatcher.ts +0 -69
  195. package/src/version.ts +0 -5
  196. package/tests/bdd/automation-creation.spec.ts +0 -214
  197. package/tests/bdd/automation-management.spec.ts +0 -267
  198. package/tests/bdd/calendar.spec.ts +0 -190
  199. package/tests/bdd/configuration.spec.ts +0 -283
  200. package/tests/bdd/device-control.spec.ts +0 -344
  201. package/tests/bdd/entity-listing.spec.ts +0 -208
  202. package/tests/bdd/entity-search.spec.ts +0 -183
  203. package/tests/bdd/history-retrieval.spec.ts +0 -195
  204. package/tests/bdd/notifications.spec.ts +0 -238
  205. package/tests/bdd/service-calls.spec.ts +0 -144
  206. package/tests/bdd/state-retrieval.spec.ts +0 -204
  207. package/tests/bench/hotpaths.bench.ts +0 -68
  208. package/tests/config.test.ts +0 -355
  209. package/tests/features/automation-creation.feature +0 -36
  210. package/tests/features/automation-management.feature +0 -54
  211. package/tests/features/calendar.feature +0 -37
  212. package/tests/features/configuration.feature +0 -70
  213. package/tests/features/device-control.feature +0 -100
  214. package/tests/features/entity-listing.feature +0 -51
  215. package/tests/features/entity-search.feature +0 -44
  216. package/tests/features/history-retrieval.feature +0 -38
  217. package/tests/features/notifications.feature +0 -37
  218. package/tests/features/service-calls.feature +0 -35
  219. package/tests/features/state-retrieval.feature +0 -37
  220. package/tests/fixtures/openapi-default-slice.json +0 -290
  221. package/tests/haClient/automationTrace.test.ts +0 -59
  222. package/tests/haClient/automations.test.ts +0 -149
  223. package/tests/haClient/config.test.ts +0 -117
  224. package/tests/haClient/entities.test.ts +0 -188
  225. package/tests/haClient/events.test.ts +0 -455
  226. package/tests/haClient/eventsTls.test.ts +0 -52
  227. package/tests/haClient/history.test.ts +0 -228
  228. package/tests/haClient/index.test.ts +0 -243
  229. package/tests/haClient/request.test.ts +0 -217
  230. package/tests/haClient/services.test.ts +0 -120
  231. package/tests/haClient/states.test.ts +0 -119
  232. package/tests/haClient/updates.test.ts +0 -193
  233. package/tests/index.test.ts +0 -160
  234. package/tests/integration/homeassistant.test.ts +0 -144
  235. package/tests/integration/omada.test.ts +0 -167
  236. package/tests/integration/server.test.ts +0 -151
  237. package/tests/localAI/index.test.ts +0 -177
  238. package/tests/localAI/ollama.test.ts +0 -187
  239. package/tests/localAI/openai.test.ts +0 -257
  240. package/tests/omadaClient/actions.test.ts +0 -161
  241. package/tests/omadaClient/clientBlocks.test.ts +0 -170
  242. package/tests/omadaClient/ntp.test.ts +0 -381
  243. package/tests/omadaClient/site.test.ts +0 -37
  244. package/tests/ownerQuestions/service.test.ts +0 -499
  245. package/tests/ownerQuestions/tools.test.ts +0 -186
  246. package/tests/permissions/index.test.ts +0 -217
  247. package/tests/resources/index.test.ts +0 -288
  248. package/tests/scripts/generateJwt.test.ts +0 -44
  249. package/tests/security/accessControl.test.ts +0 -223
  250. package/tests/security/authentication.test.ts +0 -117
  251. package/tests/security/configuration.test.ts +0 -170
  252. package/tests/security/cryptoTransport.test.ts +0 -172
  253. package/tests/security/dependencies.test.ts +0 -152
  254. package/tests/security/injection.test.ts +0 -117
  255. package/tests/security/insecureDesign.test.ts +0 -121
  256. package/tests/security/logging.test.ts +0 -131
  257. package/tests/security/resourceConsumption.test.ts +0 -142
  258. package/tests/server/auth.test.ts +0 -249
  259. package/tests/server/chatFace.test.ts +0 -320
  260. package/tests/server/common.test.ts +0 -84
  261. package/tests/server/http.test.ts +0 -561
  262. package/tests/server/instructions.test.ts +0 -152
  263. package/tests/server/memoizeJsonSchema.test.ts +0 -71
  264. package/tests/server/stdio.test.ts +0 -99
  265. package/tests/server/stream.test.ts +0 -285
  266. package/tests/server/toolVisibility.http.test.ts +0 -111
  267. package/tests/server/toolVisibility.test.ts +0 -129
  268. package/tests/tools/ai/analyzeSensors.test.ts +0 -227
  269. package/tests/tools/common.test.ts +0 -123
  270. package/tests/tools/homeassistant/handlers.test.ts +0 -872
  271. package/tests/tools/infra/invokeAction.test.ts +0 -280
  272. package/tests/tools/omada/graph.test.ts +0 -385
  273. package/tests/tools/omada/handlers.test.ts +0 -897
  274. package/tests/tools/omada/namespace.test.ts +0 -483
  275. package/tests/tools/registry.test.ts +0 -168
  276. package/tests/utils/config-validations.test.ts +0 -352
  277. package/tests/utils/jwt.test.ts +0 -115
  278. package/tests/utils/logger.test.ts +0 -327
  279. package/tests/utils/redact.test.ts +0 -105
  280. package/tsconfig.json +0 -24
  281. 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
- });