@mp-consulting/homebridge-mcp-server 1.0.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 (58) hide show
  1. package/README.md +142 -0
  2. package/dist/__tests__/homebridge-client.test.d.ts +2 -0
  3. package/dist/__tests__/homebridge-client.test.d.ts.map +1 -0
  4. package/dist/__tests__/homebridge-client.test.js +262 -0
  5. package/dist/__tests__/homebridge-client.test.js.map +1 -0
  6. package/dist/__tests__/tools/accessories.test.d.ts +2 -0
  7. package/dist/__tests__/tools/accessories.test.d.ts.map +1 -0
  8. package/dist/__tests__/tools/accessories.test.js +252 -0
  9. package/dist/__tests__/tools/accessories.test.js.map +1 -0
  10. package/dist/__tests__/tools/config.test.d.ts +2 -0
  11. package/dist/__tests__/tools/config.test.d.ts.map +1 -0
  12. package/dist/__tests__/tools/config.test.js +85 -0
  13. package/dist/__tests__/tools/config.test.js.map +1 -0
  14. package/dist/__tests__/tools/plugins.test.d.ts +2 -0
  15. package/dist/__tests__/tools/plugins.test.d.ts.map +1 -0
  16. package/dist/__tests__/tools/plugins.test.js +119 -0
  17. package/dist/__tests__/tools/plugins.test.js.map +1 -0
  18. package/dist/__tests__/tools/server.test.d.ts +2 -0
  19. package/dist/__tests__/tools/server.test.d.ts.map +1 -0
  20. package/dist/__tests__/tools/server.test.js +126 -0
  21. package/dist/__tests__/tools/server.test.js.map +1 -0
  22. package/dist/__tests__/tools/system.test.d.ts +2 -0
  23. package/dist/__tests__/tools/system.test.d.ts.map +1 -0
  24. package/dist/__tests__/tools/system.test.js +62 -0
  25. package/dist/__tests__/tools/system.test.js.map +1 -0
  26. package/dist/homebridge-client.d.ts +35 -0
  27. package/dist/homebridge-client.d.ts.map +1 -0
  28. package/dist/homebridge-client.js +165 -0
  29. package/dist/homebridge-client.js.map +1 -0
  30. package/dist/index.d.ts +3 -0
  31. package/dist/index.d.ts.map +1 -0
  32. package/dist/index.js +24 -0
  33. package/dist/index.js.map +1 -0
  34. package/dist/tools/accessories.d.ts +4 -0
  35. package/dist/tools/accessories.d.ts.map +1 -0
  36. package/dist/tools/accessories.js +139 -0
  37. package/dist/tools/accessories.js.map +1 -0
  38. package/dist/tools/config.d.ts +4 -0
  39. package/dist/tools/config.d.ts.map +1 -0
  40. package/dist/tools/config.js +43 -0
  41. package/dist/tools/config.js.map +1 -0
  42. package/dist/tools/plugins.d.ts +4 -0
  43. package/dist/tools/plugins.d.ts.map +1 -0
  44. package/dist/tools/plugins.js +111 -0
  45. package/dist/tools/plugins.js.map +1 -0
  46. package/dist/tools/server.d.ts +4 -0
  47. package/dist/tools/server.d.ts.map +1 -0
  48. package/dist/tools/server.js +116 -0
  49. package/dist/tools/server.js.map +1 -0
  50. package/dist/tools/system.d.ts +4 -0
  51. package/dist/tools/system.d.ts.map +1 -0
  52. package/dist/tools/system.js +17 -0
  53. package/dist/tools/system.js.map +1 -0
  54. package/dist/types.d.ts +8 -0
  55. package/dist/types.d.ts.map +1 -0
  56. package/dist/types.js +2 -0
  57. package/dist/types.js.map +1 -0
  58. package/package.json +45 -0
@@ -0,0 +1,126 @@
1
+ import { describe, it, expect, vi } from "vitest";
2
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { register } from "../../tools/server.js";
4
+ function mockClient(overrides = {}) {
5
+ return {
6
+ getAccessories: vi.fn(),
7
+ getAccessoryLayout: vi.fn(),
8
+ setAccessoryCharacteristic: vi.fn(),
9
+ getHomebridgeStatus: vi.fn().mockResolvedValue({ status: "up" }),
10
+ getServerInformation: vi.fn().mockResolvedValue({ version: "1.0.0" }),
11
+ restartServer: vi.fn().mockResolvedValue(null),
12
+ getPairingInfo: vi.fn().mockResolvedValue({ setupCode: "123-45-678" }),
13
+ getCachedAccessories: vi.fn().mockResolvedValue([]),
14
+ removeCachedAccessory: vi.fn().mockResolvedValue(undefined),
15
+ resetCachedAccessories: vi.fn().mockResolvedValue(undefined),
16
+ getConfig: vi.fn(),
17
+ updateConfig: vi.fn(),
18
+ getPlugins: vi.fn(),
19
+ searchPlugins: vi.fn(),
20
+ lookupPlugin: vi.fn(),
21
+ getPluginVersions: vi.fn(),
22
+ getPluginConfigSchema: vi.fn(),
23
+ getPluginChangelog: vi.fn(),
24
+ getSystemInfo: vi.fn(),
25
+ ...overrides,
26
+ };
27
+ }
28
+ function extractToolHandlers(client) {
29
+ const server = new McpServer({ name: "test", version: "0.0.0" });
30
+ const handlers = new Map();
31
+ const origTool = server.tool.bind(server);
32
+ vi.spyOn(server, "tool").mockImplementation((...args) => {
33
+ const handler = args[args.length - 1];
34
+ const name = args[0];
35
+ handlers.set(name, handler);
36
+ return origTool(...args);
37
+ });
38
+ register(server, client);
39
+ return handlers;
40
+ }
41
+ describe("server tools", () => {
42
+ describe("get_homebridge_status", () => {
43
+ it("returns status", async () => {
44
+ const client = mockClient();
45
+ const handlers = extractToolHandlers(client);
46
+ const result = await handlers.get("get_homebridge_status")({});
47
+ expect(JSON.parse(result.content[0].text)).toEqual({ status: "up" });
48
+ });
49
+ it("handles errors", async () => {
50
+ const client = mockClient({
51
+ getHomebridgeStatus: vi.fn().mockRejectedValue(new Error("fail")),
52
+ });
53
+ const handlers = extractToolHandlers(client);
54
+ const result = await handlers.get("get_homebridge_status")({});
55
+ expect(result.isError).toBe(true);
56
+ });
57
+ });
58
+ describe("get_server_status", () => {
59
+ it("returns server information", async () => {
60
+ const client = mockClient();
61
+ const handlers = extractToolHandlers(client);
62
+ const result = await handlers.get("get_server_status")({});
63
+ expect(JSON.parse(result.content[0].text)).toEqual({ version: "1.0.0" });
64
+ });
65
+ });
66
+ describe("restart_homebridge", () => {
67
+ it("returns success message when result is falsy", async () => {
68
+ const client = mockClient();
69
+ const handlers = extractToolHandlers(client);
70
+ const result = await handlers.get("restart_homebridge")({});
71
+ expect(result.content[0].text).toContain("restart initiated successfully");
72
+ });
73
+ it("returns JSON when result is truthy", async () => {
74
+ const client = mockClient({
75
+ restartServer: vi.fn().mockResolvedValue({ status: "restarting" }),
76
+ });
77
+ const handlers = extractToolHandlers(client);
78
+ const result = await handlers.get("restart_homebridge")({});
79
+ expect(JSON.parse(result.content[0].text)).toEqual({ status: "restarting" });
80
+ });
81
+ });
82
+ describe("get_pairing_info", () => {
83
+ it("returns pairing info", async () => {
84
+ const client = mockClient();
85
+ const handlers = extractToolHandlers(client);
86
+ const result = await handlers.get("get_pairing_info")({});
87
+ expect(JSON.parse(result.content[0].text)).toEqual({ setupCode: "123-45-678" });
88
+ });
89
+ });
90
+ describe("get_cached_accessories", () => {
91
+ it("returns cached accessories", async () => {
92
+ const client = mockClient({
93
+ getCachedAccessories: vi.fn().mockResolvedValue([{ uuid: "u1" }]),
94
+ });
95
+ const handlers = extractToolHandlers(client);
96
+ const result = await handlers.get("get_cached_accessories")({});
97
+ expect(JSON.parse(result.content[0].text)).toEqual([{ uuid: "u1" }]);
98
+ });
99
+ });
100
+ describe("remove_cached_accessory", () => {
101
+ it("returns success message", async () => {
102
+ const client = mockClient();
103
+ const handlers = extractToolHandlers(client);
104
+ const result = await handlers.get("remove_cached_accessory")({ uuid: "u1" });
105
+ expect(result.content[0].text).toContain("u1");
106
+ expect(result.content[0].text).toContain("removed successfully");
107
+ });
108
+ it("handles errors", async () => {
109
+ const client = mockClient({
110
+ removeCachedAccessory: vi.fn().mockRejectedValue(new Error("fail")),
111
+ });
112
+ const handlers = extractToolHandlers(client);
113
+ const result = await handlers.get("remove_cached_accessory")({ uuid: "u1" });
114
+ expect(result.isError).toBe(true);
115
+ });
116
+ });
117
+ describe("reset_cached_accessories", () => {
118
+ it("returns success message", async () => {
119
+ const client = mockClient();
120
+ const handlers = extractToolHandlers(client);
121
+ const result = await handlers.get("reset_cached_accessories")({});
122
+ expect(result.content[0].text).toContain("reset");
123
+ });
124
+ });
125
+ });
126
+ //# sourceMappingURL=server.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.test.js","sourceRoot":"","sources":["../../../src/__tests__/tools/server.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAIjD,SAAS,UAAU,CAAC,YAAuC,EAAE;IAC3D,OAAO;QACL,cAAc,EAAE,EAAE,CAAC,EAAE,EAAE;QACvB,kBAAkB,EAAE,EAAE,CAAC,EAAE,EAAE;QAC3B,0BAA0B,EAAE,EAAE,CAAC,EAAE,EAAE;QACnC,mBAAmB,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;QAChE,oBAAoB,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;QACrE,aAAa,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC;QAC9C,cAAc,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC;QACtE,oBAAoB,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC;QACnD,qBAAqB,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC;QAC3D,sBAAsB,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC;QAC5D,SAAS,EAAE,EAAE,CAAC,EAAE,EAAE;QAClB,YAAY,EAAE,EAAE,CAAC,EAAE,EAAE;QACrB,UAAU,EAAE,EAAE,CAAC,EAAE,EAAE;QACnB,aAAa,EAAE,EAAE,CAAC,EAAE,EAAE;QACtB,YAAY,EAAE,EAAE,CAAC,EAAE,EAAE;QACrB,iBAAiB,EAAE,EAAE,CAAC,EAAE,EAAE;QAC1B,qBAAqB,EAAE,EAAE,CAAC,EAAE,EAAE;QAC9B,kBAAkB,EAAE,EAAE,CAAC,EAAE,EAAE;QAC3B,aAAa,EAAE,EAAE,CAAC,EAAE,EAAE;QACtB,GAAG,SAAS;KACkB,CAAC;AACnC,CAAC;AAED,SAAS,mBAAmB,CAAC,MAAwB;IACnD,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;IACjE,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAuB,CAAC;IAChD,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAE1C,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,kBAAkB,CAAC,CAAC,GAAG,IAAe,EAAE,EAAE;QACjE,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAgB,CAAC;QACrD,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAW,CAAC;QAC/B,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC5B,OAAO,QAAQ,CAAC,GAAI,IAAoC,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzB,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;QACrC,EAAE,CAAC,gBAAgB,EAAE,KAAK,IAAI,EAAE;YAC9B,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;YAC5B,MAAM,QAAQ,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;YAC7C,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,uBAAuB,CAAE,CAAC,EAAE,CAAC,CAAC;YAChE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QACvE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gBAAgB,EAAE,KAAK,IAAI,EAAE;YAC9B,MAAM,MAAM,GAAG,UAAU,CAAC;gBACxB,mBAAmB,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;aAClE,CAAC,CAAC;YACH,MAAM,QAAQ,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;YAC7C,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,uBAAuB,CAAE,CAAC,EAAE,CAAC,CAAC;YAChE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;QACjC,EAAE,CAAC,4BAA4B,EAAE,KAAK,IAAI,EAAE;YAC1C,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;YAC5B,MAAM,QAAQ,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;YAC7C,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,mBAAmB,CAAE,CAAC,EAAE,CAAC,CAAC;YAC5D,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QAC3E,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;QAClC,EAAE,CAAC,8CAA8C,EAAE,KAAK,IAAI,EAAE;YAC5D,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;YAC5B,MAAM,QAAQ,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;YAC7C,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,oBAAoB,CAAE,CAAC,EAAE,CAAC,CAAC;YAC7D,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,gCAAgC,CAAC,CAAC;QAC7E,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;YAClD,MAAM,MAAM,GAAG,UAAU,CAAC;gBACxB,aAAa,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;aACnE,CAAC,CAAC;YACH,MAAM,QAAQ,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;YAC7C,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,oBAAoB,CAAE,CAAC,EAAE,CAAC,CAAC;YAC7D,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC;QAC/E,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAChC,EAAE,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE;YACpC,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;YAC5B,MAAM,QAAQ,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;YAC7C,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,kBAAkB,CAAE,CAAC,EAAE,CAAC,CAAC;YAC3D,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC,CAAC;QAClF,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;QACtC,EAAE,CAAC,4BAA4B,EAAE,KAAK,IAAI,EAAE;YAC1C,MAAM,MAAM,GAAG,UAAU,CAAC;gBACxB,oBAAoB,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;aAClE,CAAC,CAAC;YACH,MAAM,QAAQ,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;YAC7C,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,wBAAwB,CAAE,CAAC,EAAE,CAAC,CAAC;YACjE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QACvE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,yBAAyB,EAAE,GAAG,EAAE;QACvC,EAAE,CAAC,yBAAyB,EAAE,KAAK,IAAI,EAAE;YACvC,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;YAC5B,MAAM,QAAQ,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;YAC7C,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,yBAAyB,CAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YAC9E,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YAC/C,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC;QACnE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gBAAgB,EAAE,KAAK,IAAI,EAAE;YAC9B,MAAM,MAAM,GAAG,UAAU,CAAC;gBACxB,qBAAqB,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;aACpE,CAAC,CAAC;YACH,MAAM,QAAQ,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;YAC7C,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,yBAAyB,CAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YAC9E,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;QACxC,EAAE,CAAC,yBAAyB,EAAE,KAAK,IAAI,EAAE;YACvC,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;YAC5B,MAAM,QAAQ,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;YAC7C,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,0BAA0B,CAAE,CAAC,EAAE,CAAC,CAAC;YACnE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=system.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/tools/system.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,62 @@
1
+ import { describe, it, expect, vi } from "vitest";
2
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { register } from "../../tools/system.js";
4
+ function mockClient(overrides = {}) {
5
+ return {
6
+ getAccessories: vi.fn(),
7
+ getAccessoryLayout: vi.fn(),
8
+ setAccessoryCharacteristic: vi.fn(),
9
+ getHomebridgeStatus: vi.fn(),
10
+ getServerInformation: vi.fn(),
11
+ restartServer: vi.fn(),
12
+ getPairingInfo: vi.fn(),
13
+ getCachedAccessories: vi.fn(),
14
+ removeCachedAccessory: vi.fn(),
15
+ resetCachedAccessories: vi.fn(),
16
+ getConfig: vi.fn(),
17
+ updateConfig: vi.fn(),
18
+ getPlugins: vi.fn(),
19
+ searchPlugins: vi.fn(),
20
+ lookupPlugin: vi.fn(),
21
+ getPluginVersions: vi.fn(),
22
+ getPluginConfigSchema: vi.fn(),
23
+ getPluginChangelog: vi.fn(),
24
+ getSystemInfo: vi.fn().mockResolvedValue({ cpu: { model: "ARM" }, memory: { total: 4096 } }),
25
+ ...overrides,
26
+ };
27
+ }
28
+ function extractToolHandlers(client) {
29
+ const server = new McpServer({ name: "test", version: "0.0.0" });
30
+ const handlers = new Map();
31
+ const origTool = server.tool.bind(server);
32
+ vi.spyOn(server, "tool").mockImplementation((...args) => {
33
+ const handler = args[args.length - 1];
34
+ const name = args[0];
35
+ handlers.set(name, handler);
36
+ return origTool(...args);
37
+ });
38
+ register(server, client);
39
+ return handlers;
40
+ }
41
+ describe("system tools", () => {
42
+ describe("get_system_info", () => {
43
+ it("returns system info", async () => {
44
+ const client = mockClient();
45
+ const handlers = extractToolHandlers(client);
46
+ const result = await handlers.get("get_system_info")({});
47
+ const parsed = JSON.parse(result.content[0].text);
48
+ expect(parsed.cpu.model).toBe("ARM");
49
+ expect(parsed.memory.total).toBe(4096);
50
+ });
51
+ it("handles errors", async () => {
52
+ const client = mockClient({
53
+ getSystemInfo: vi.fn().mockRejectedValue(new Error("fail")),
54
+ });
55
+ const handlers = extractToolHandlers(client);
56
+ const result = await handlers.get("get_system_info")({});
57
+ expect(result.isError).toBe(true);
58
+ expect(result.content[0].text).toContain("Error getting system info");
59
+ });
60
+ });
61
+ });
62
+ //# sourceMappingURL=system.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system.test.js","sourceRoot":"","sources":["../../../src/__tests__/tools/system.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * HTTP client for the Homebridge Config UI REST API.
3
+ * Handles JWT authentication, token refresh, and all API calls.
4
+ */
5
+ export declare class HomebridgeClient {
6
+ private readonly baseUrl;
7
+ private readonly username;
8
+ private readonly password;
9
+ private token;
10
+ constructor();
11
+ private authenticate;
12
+ private refreshToken;
13
+ private ensureAuthenticated;
14
+ private request;
15
+ getAccessories(): Promise<unknown[]>;
16
+ getAccessoryLayout(): Promise<unknown>;
17
+ setAccessoryCharacteristic(uniqueId: string, characteristicType: string, value: string | number | boolean): Promise<unknown>;
18
+ getHomebridgeStatus(): Promise<unknown>;
19
+ getServerInformation(): Promise<unknown>;
20
+ restartServer(): Promise<unknown>;
21
+ getPairingInfo(): Promise<unknown>;
22
+ getCachedAccessories(): Promise<unknown[]>;
23
+ removeCachedAccessory(uuid: string): Promise<unknown>;
24
+ resetCachedAccessories(): Promise<unknown>;
25
+ getConfig(): Promise<unknown>;
26
+ updateConfig(config: unknown): Promise<unknown>;
27
+ getPlugins(): Promise<unknown[]>;
28
+ searchPlugins(query: string): Promise<unknown[]>;
29
+ lookupPlugin(pluginName: string): Promise<unknown>;
30
+ getPluginVersions(pluginName: string): Promise<unknown>;
31
+ getPluginConfigSchema(pluginName: string): Promise<unknown>;
32
+ getPluginChangelog(pluginName: string): Promise<unknown>;
33
+ getSystemInfo(): Promise<unknown>;
34
+ }
35
+ //# sourceMappingURL=homebridge-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"homebridge-client.d.ts","sourceRoot":"","sources":["../src/homebridge-client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,KAAK,CAAuB;;YAkBtB,YAAY;YAgBZ,YAAY;YAsBZ,mBAAmB;YAQnB,OAAO;IAiDf,cAAc,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAIpC,kBAAkB,IAAI,OAAO,CAAC,OAAO,CAAC;IAItC,0BAA0B,CAC9B,QAAQ,EAAE,MAAM,EAChB,kBAAkB,EAAE,MAAM,EAC1B,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAC/B,OAAO,CAAC,OAAO,CAAC;IASb,mBAAmB,IAAI,OAAO,CAAC,OAAO,CAAC;IAIvC,oBAAoB,IAAI,OAAO,CAAC,OAAO,CAAC;IAIxC,aAAa,IAAI,OAAO,CAAC,OAAO,CAAC;IAIjC,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC;IAIlC,oBAAoB,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAI1C,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIrD,sBAAsB,IAAI,OAAO,CAAC,OAAO,CAAC;IAM1C,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;IAI7B,YAAY,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAM/C,UAAU,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAIhC,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAIhD,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIlD,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIvD,qBAAqB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAI3D,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAMxD,aAAa,IAAI,OAAO,CAAC,OAAO,CAAC;CAGxC"}
@@ -0,0 +1,165 @@
1
+ /**
2
+ * HTTP client for the Homebridge Config UI REST API.
3
+ * Handles JWT authentication, token refresh, and all API calls.
4
+ */
5
+ export class HomebridgeClient {
6
+ baseUrl;
7
+ username;
8
+ password;
9
+ token = null;
10
+ constructor() {
11
+ const url = process.env.HOMEBRIDGE_URL;
12
+ const username = process.env.HOMEBRIDGE_USERNAME;
13
+ const password = process.env.HOMEBRIDGE_PASSWORD;
14
+ if (!url)
15
+ throw new Error("HOMEBRIDGE_URL environment variable is required");
16
+ if (!username)
17
+ throw new Error("HOMEBRIDGE_USERNAME environment variable is required");
18
+ if (!password)
19
+ throw new Error("HOMEBRIDGE_PASSWORD environment variable is required");
20
+ this.baseUrl = url.replace(/\/+$/, "");
21
+ this.username = username;
22
+ this.password = password;
23
+ }
24
+ // ── Authentication ──────────────────────────────────────────────
25
+ async authenticate() {
26
+ const res = await fetch(`${this.baseUrl}/api/auth/login`, {
27
+ method: "POST",
28
+ headers: { "Content-Type": "application/json" },
29
+ body: JSON.stringify({ username: this.username, password: this.password }),
30
+ });
31
+ if (!res.ok) {
32
+ const body = await res.text();
33
+ throw new Error(`Authentication failed (${res.status}): ${body}`);
34
+ }
35
+ const data = (await res.json());
36
+ this.token = data.access_token;
37
+ }
38
+ async refreshToken() {
39
+ if (!this.token)
40
+ return false;
41
+ try {
42
+ const res = await fetch(`${this.baseUrl}/api/auth/refresh`, {
43
+ method: "POST",
44
+ headers: {
45
+ "Content-Type": "application/json",
46
+ Authorization: `Bearer ${this.token}`,
47
+ },
48
+ });
49
+ if (!res.ok)
50
+ return false;
51
+ const data = (await res.json());
52
+ this.token = data.access_token;
53
+ return true;
54
+ }
55
+ catch {
56
+ return false;
57
+ }
58
+ }
59
+ async ensureAuthenticated() {
60
+ if (!this.token) {
61
+ await this.authenticate();
62
+ }
63
+ }
64
+ // ── Generic request method ──────────────────────────────────────
65
+ async request(method, path, body) {
66
+ await this.ensureAuthenticated();
67
+ const doFetch = async () => {
68
+ const headers = {
69
+ Authorization: `Bearer ${this.token}`,
70
+ };
71
+ if (body !== undefined) {
72
+ headers["Content-Type"] = "application/json";
73
+ }
74
+ return fetch(`${this.baseUrl}${path}`, {
75
+ method,
76
+ headers,
77
+ body: body !== undefined ? JSON.stringify(body) : undefined,
78
+ });
79
+ };
80
+ let res = await doFetch();
81
+ // On 401, try refreshing the token, then re-authenticate as fallback
82
+ if (res.status === 401) {
83
+ const refreshed = await this.refreshToken();
84
+ if (!refreshed) {
85
+ await this.authenticate();
86
+ }
87
+ res = await doFetch();
88
+ }
89
+ if (!res.ok) {
90
+ const text = await res.text();
91
+ throw new Error(`Homebridge API error ${res.status} ${method} ${path}: ${text}`);
92
+ }
93
+ const contentType = res.headers.get("content-type") ?? "";
94
+ if (contentType.includes("application/json")) {
95
+ return (await res.json());
96
+ }
97
+ return (await res.text());
98
+ }
99
+ // ── Accessories ─────────────────────────────────────────────────
100
+ async getAccessories() {
101
+ return this.request("GET", "/api/accessories");
102
+ }
103
+ async getAccessoryLayout() {
104
+ return this.request("GET", "/api/accessories/layout");
105
+ }
106
+ async setAccessoryCharacteristic(uniqueId, characteristicType, value) {
107
+ return this.request("PUT", `/api/accessories/${encodeURIComponent(uniqueId)}`, {
108
+ characteristicType,
109
+ value,
110
+ });
111
+ }
112
+ // ── Server / Status ─────────────────────────────────────────────
113
+ async getHomebridgeStatus() {
114
+ return this.request("GET", "/api/status/homebridge");
115
+ }
116
+ async getServerInformation() {
117
+ return this.request("GET", "/api/status/server-information");
118
+ }
119
+ async restartServer() {
120
+ return this.request("PUT", "/api/server/restart");
121
+ }
122
+ async getPairingInfo() {
123
+ return this.request("GET", "/api/server/pairing");
124
+ }
125
+ async getCachedAccessories() {
126
+ return this.request("GET", "/api/server/cached-accessories");
127
+ }
128
+ async removeCachedAccessory(uuid) {
129
+ return this.request("DELETE", `/api/server/cached-accessories/${encodeURIComponent(uuid)}`);
130
+ }
131
+ async resetCachedAccessories() {
132
+ return this.request("PUT", "/api/server/reset-cached-accessories");
133
+ }
134
+ // ── Config ──────────────────────────────────────────────────────
135
+ async getConfig() {
136
+ return this.request("GET", "/api/config-editor");
137
+ }
138
+ async updateConfig(config) {
139
+ return this.request("POST", "/api/config-editor", config);
140
+ }
141
+ // ── Plugins ─────────────────────────────────────────────────────
142
+ async getPlugins() {
143
+ return this.request("GET", "/api/plugins");
144
+ }
145
+ async searchPlugins(query) {
146
+ return this.request("GET", `/api/plugins/search/${encodeURIComponent(query)}`);
147
+ }
148
+ async lookupPlugin(pluginName) {
149
+ return this.request("GET", `/api/plugins/lookup/${encodeURIComponent(pluginName)}`);
150
+ }
151
+ async getPluginVersions(pluginName) {
152
+ return this.request("GET", `/api/plugins/lookup/${encodeURIComponent(pluginName)}/versions`);
153
+ }
154
+ async getPluginConfigSchema(pluginName) {
155
+ return this.request("GET", `/api/plugins/config-schema/${encodeURIComponent(pluginName)}`);
156
+ }
157
+ async getPluginChangelog(pluginName) {
158
+ return this.request("GET", `/api/plugins/changelog/${encodeURIComponent(pluginName)}`);
159
+ }
160
+ // ── Platform Tools ──────────────────────────────────────────────
161
+ async getSystemInfo() {
162
+ return this.request("GET", "/api/platform-tools/system-information");
163
+ }
164
+ }
165
+ //# sourceMappingURL=homebridge-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"homebridge-client.js","sourceRoot":"","sources":["../src/homebridge-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import { HomebridgeClient } from "./homebridge-client.js";
5
+ import { register as registerAccessories } from "./tools/accessories.js";
6
+ import { register as registerServer } from "./tools/server.js";
7
+ import { register as registerConfig } from "./tools/config.js";
8
+ import { register as registerPlugins } from "./tools/plugins.js";
9
+ import { register as registerSystem } from "./tools/system.js";
10
+ const server = new McpServer({
11
+ name: "homebridge-mcp-server",
12
+ version: "1.0.0",
13
+ });
14
+ const client = new HomebridgeClient();
15
+ // Register all tool groups
16
+ registerAccessories(server, client);
17
+ registerServer(server, client);
18
+ registerConfig(server, client);
19
+ registerPlugins(server, client);
20
+ registerSystem(server, client);
21
+ // Start the server with stdio transport
22
+ const transport = new StdioServerTransport();
23
+ await server.connect(transport);
24
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,QAAQ,IAAI,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,QAAQ,IAAI,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,QAAQ,IAAI,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,QAAQ,IAAI,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,QAAQ,IAAI,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAE/D,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;IAC3B,IAAI,EAAE,uBAAuB;IAC7B,OAAO,EAAE,OAAO;CACjB,CAAC,CAAC;AAEH,MAAM,MAAM,GAAG,IAAI,gBAAgB,EAAE,CAAC;AAEtC,2BAA2B;AAC3B,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACpC,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAC/B,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAC/B,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAChC,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAE/B,wCAAwC;AACxC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;AAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { HomebridgeClient } from "../homebridge-client.js";
3
+ export declare function register(server: McpServer, client: HomebridgeClient): void;
4
+ //# sourceMappingURL=accessories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accessories.d.ts","sourceRoot":"","sources":["../../src/tools/accessories.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AA2BhE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAwK1E"}
@@ -0,0 +1,139 @@
1
+ import { z } from "zod";
2
+ function compactAccessory(acc) {
3
+ return {
4
+ uniqueId: acc.uniqueId,
5
+ serviceName: acc.serviceName,
6
+ type: acc.type,
7
+ manufacturer: acc.accessoryInformation?.Manufacturer ?? null,
8
+ model: acc.accessoryInformation?.Model ?? null,
9
+ values: acc.values ?? {},
10
+ };
11
+ }
12
+ export function register(server, client) {
13
+ server.tool("list_accessories", "List all Homebridge accessories with their current state (on/off, brightness, temperature, etc.)", {
14
+ room: z.string().optional().describe("Filter by room name (case-insensitive)"),
15
+ type: z.string().optional().describe("Filter by accessory type (e.g. 'Lightbulb', 'Switch', 'Thermostat')"),
16
+ manufacturer: z.string().optional().describe("Filter by manufacturer (case-insensitive, contains match)"),
17
+ excludeManufacturer: z.string().optional().describe("Exclude accessories from this manufacturer (case-insensitive, contains match)"),
18
+ name: z.string().optional().describe("Filter by service name (case-insensitive, contains match)"),
19
+ }, async ({ room, type, manufacturer, excludeManufacturer, name }) => {
20
+ try {
21
+ let accessories = (await client.getAccessories());
22
+ // Room filter: resolve UIDs from layout
23
+ if (room) {
24
+ const layout = (await client.getAccessoryLayout());
25
+ const matchedRoom = layout.find((r) => r.name.toLowerCase() === room.toLowerCase());
26
+ if (!matchedRoom) {
27
+ return {
28
+ content: [{ type: "text", text: `Room not found: "${room}". Available rooms: ${layout.map((r) => r.name).join(", ")}` }],
29
+ isError: true,
30
+ };
31
+ }
32
+ const roomUids = new Set(matchedRoom.services.map((s) => s.uniqueId));
33
+ accessories = accessories.filter((a) => roomUids.has(a.uniqueId));
34
+ }
35
+ if (type) {
36
+ accessories = accessories.filter((a) => a.type?.toLowerCase() === type.toLowerCase());
37
+ }
38
+ if (manufacturer) {
39
+ const mfr = manufacturer.toLowerCase();
40
+ accessories = accessories.filter((a) => a.accessoryInformation?.Manufacturer?.toLowerCase().includes(mfr));
41
+ }
42
+ if (excludeManufacturer) {
43
+ const excl = excludeManufacturer.toLowerCase();
44
+ accessories = accessories.filter((a) => !a.accessoryInformation?.Manufacturer?.toLowerCase().includes(excl));
45
+ }
46
+ if (name) {
47
+ const n = name.toLowerCase();
48
+ accessories = accessories.filter((a) => a.serviceName?.toLowerCase().includes(n));
49
+ }
50
+ const compact = accessories.map(compactAccessory);
51
+ return {
52
+ content: [{ type: "text", text: JSON.stringify(compact, null, 2) }],
53
+ };
54
+ }
55
+ catch (error) {
56
+ return {
57
+ content: [{ type: "text", text: `Error listing accessories: ${error}` }],
58
+ isError: true,
59
+ };
60
+ }
61
+ });
62
+ server.tool("get_accessory", "Get detailed information about a specific accessory by its uniqueId. Use list_accessories first to find the uniqueId.", { uniqueId: z.string().describe("The unique identifier of the accessory") }, async ({ uniqueId }) => {
63
+ try {
64
+ const accessories = await client.getAccessories();
65
+ const accessory = accessories.find((a) => a.uniqueId === uniqueId);
66
+ if (!accessory) {
67
+ return {
68
+ content: [{ type: "text", text: `Accessory not found with uniqueId: ${uniqueId}` }],
69
+ isError: true,
70
+ };
71
+ }
72
+ return {
73
+ content: [{ type: "text", text: JSON.stringify(accessory, null, 2) }],
74
+ };
75
+ }
76
+ catch (error) {
77
+ return {
78
+ content: [{ type: "text", text: `Error getting accessory: ${error}` }],
79
+ isError: true,
80
+ };
81
+ }
82
+ });
83
+ server.tool("set_accessory", "Control a Homebridge accessory — turn it on/off, set brightness, color temperature, etc. Use list_accessories first to find the uniqueId and available characteristicTypes.", {
84
+ uniqueId: z.string().describe("The unique identifier of the accessory"),
85
+ characteristicType: z
86
+ .string()
87
+ .describe("The characteristic to set (e.g. 'On', 'Brightness', 'ColorTemperature', 'Hue', 'Saturation', 'TargetTemperature', 'TargetDoorState')"),
88
+ value: z
89
+ .union([z.string(), z.number(), z.boolean()])
90
+ .describe("The value to set (e.g. true/false for On, 0-100 for Brightness)"),
91
+ }, async ({ uniqueId, characteristicType, value }) => {
92
+ try {
93
+ const result = await client.setAccessoryCharacteristic(uniqueId, characteristicType, value);
94
+ return {
95
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
96
+ };
97
+ }
98
+ catch (error) {
99
+ return {
100
+ content: [{ type: "text", text: `Error setting accessory: ${error}` }],
101
+ isError: true,
102
+ };
103
+ }
104
+ });
105
+ server.tool("get_accessory_layout", "Get the accessories room layout as configured in the Homebridge UI.", {}, async () => {
106
+ try {
107
+ const [layout, accessories] = await Promise.all([
108
+ client.getAccessoryLayout(),
109
+ client.getAccessories(),
110
+ ]);
111
+ const accessoryMap = new Map();
112
+ for (const acc of accessories) {
113
+ accessoryMap.set(acc.uniqueId, acc);
114
+ }
115
+ const enriched = layout.map((room) => ({
116
+ name: room.name,
117
+ services: room.services.map((svc) => {
118
+ const acc = accessoryMap.get(svc.uniqueId);
119
+ return {
120
+ uniqueId: svc.uniqueId,
121
+ serviceName: acc?.serviceName ?? svc.customName ?? "Unknown",
122
+ type: acc?.type ?? "Unknown",
123
+ manufacturer: acc?.accessoryInformation?.Manufacturer ?? null,
124
+ };
125
+ }),
126
+ }));
127
+ return {
128
+ content: [{ type: "text", text: JSON.stringify(enriched, null, 2) }],
129
+ };
130
+ }
131
+ catch (error) {
132
+ return {
133
+ content: [{ type: "text", text: `Error getting layout: ${error}` }],
134
+ isError: true,
135
+ };
136
+ }
137
+ });
138
+ }
139
+ //# sourceMappingURL=accessories.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accessories.js","sourceRoot":"","sources":["../../src/tools/accessories.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { HomebridgeClient } from "../homebridge-client.js";
3
+ export declare function register(server: McpServer, client: HomebridgeClient): void;
4
+ //# sourceMappingURL=config.d.ts.map