@tmhs/homelab-mcp 0.5.0 → 0.7.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 (36) hide show
  1. package/README.md +10 -1
  2. package/dist/index.js +17 -1
  3. package/dist/index.js.map +1 -1
  4. package/dist/tools/aptHistory.d.ts +3 -0
  5. package/dist/tools/aptHistory.d.ts.map +1 -0
  6. package/dist/tools/aptHistory.js +31 -0
  7. package/dist/tools/aptHistory.js.map +1 -0
  8. package/dist/tools/aptUpgradable.d.ts +3 -0
  9. package/dist/tools/aptUpgradable.d.ts.map +1 -0
  10. package/dist/tools/aptUpgradable.js +19 -0
  11. package/dist/tools/aptUpgradable.js.map +1 -0
  12. package/dist/tools/journalLogs.d.ts +3 -0
  13. package/dist/tools/journalLogs.d.ts.map +1 -0
  14. package/dist/tools/journalLogs.js +45 -0
  15. package/dist/tools/journalLogs.js.map +1 -0
  16. package/dist/tools/kernelInfo.d.ts +3 -0
  17. package/dist/tools/kernelInfo.d.ts.map +1 -0
  18. package/dist/tools/kernelInfo.js +24 -0
  19. package/dist/tools/kernelInfo.js.map +1 -0
  20. package/dist/tools/logSearch.d.ts +3 -0
  21. package/dist/tools/logSearch.d.ts.map +1 -0
  22. package/dist/tools/logSearch.js +35 -0
  23. package/dist/tools/logSearch.js.map +1 -0
  24. package/dist/tools/ntfySend.d.ts +3 -0
  25. package/dist/tools/ntfySend.d.ts.map +1 -0
  26. package/dist/tools/ntfySend.js +59 -0
  27. package/dist/tools/ntfySend.js.map +1 -0
  28. package/dist/tools/ntfyTopics.d.ts +3 -0
  29. package/dist/tools/ntfyTopics.d.ts.map +1 -0
  30. package/dist/tools/ntfyTopics.js +41 -0
  31. package/dist/tools/ntfyTopics.js.map +1 -0
  32. package/dist/tools/systemdServices.d.ts +3 -0
  33. package/dist/tools/systemdServices.d.ts.map +1 -0
  34. package/dist/tools/systemdServices.js +27 -0
  35. package/dist/tools/systemdServices.js.map +1 -0
  36. package/package.json +2 -2
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Home Lab MCP Server
2
2
 
3
- MCP (Model Context Protocol) server for home lab operations. Connects to a Raspberry Pi via SSH and provides 33 tools for system management, Docker Compose stacks, service monitoring, networking, backups, disaster recovery, and security auditing.
3
+ MCP (Model Context Protocol) server for home lab operations. Connects to a Raspberry Pi via SSH and provides 41 tools for system management, Docker Compose stacks, service monitoring, networking, backups, disaster recovery, security auditing, log analysis, notifications, and OS management.
4
4
 
5
5
  ## Tools
6
6
 
@@ -38,6 +38,14 @@ MCP (Model Context Protocol) server for home lab operations. Connects to a Raspb
38
38
  | Security | `homelab_fail2banStatus` | List fail2ban jails and banned IPs |
39
39
  | Security | `homelab_openPorts` | Scan listening TCP ports and map to processes |
40
40
  | Security | `homelab_containerScan` | Scan container images for vulnerabilities via Trivy |
41
+ | Logs | `homelab_journalLogs` | Query systemd journal with unit, priority, time filters |
42
+ | Logs | `homelab_logSearch` | Search across container logs with grep patterns |
43
+ | Notifications | `homelab_ntfySend` | Send a push notification via Ntfy |
44
+ | Notifications | `homelab_ntfyTopics` | List Ntfy topics and recent messages |
45
+ | OS | `homelab_aptUpgradable` | List upgradable packages with version details |
46
+ | OS | `homelab_aptHistory` | Show recent apt install/upgrade/remove history |
47
+ | OS | `homelab_kernelInfo` | Kernel version, boot parameters, loaded modules |
48
+ | OS | `homelab_systemdServices` | List systemd units or get status of a specific unit |
41
49
  | SSH | `homelab_sshTest` | Test SSH connectivity |
42
50
 
43
51
  ## Setup
@@ -73,6 +81,7 @@ Set environment variables:
73
81
  | `HOMELAB_NPM_EMAIL` | `admin@example.com` | NPM admin email |
74
82
  | `HOMELAB_NPM_PASSWORD` | `changeme` | NPM admin password |
75
83
  | `HOMELAB_NPM_PORT` | `81` | NPM admin API port override |
84
+ | `HOMELAB_NTFY_PORT` | `8080` | Ntfy server port override |
76
85
 
77
86
  ## Usage with Cursor
78
87
 
package/dist/index.js CHANGED
@@ -34,9 +34,17 @@ import { register as registerUfwStatus } from "./tools/ufwStatus.js";
34
34
  import { register as registerFail2banStatus } from "./tools/fail2banStatus.js";
35
35
  import { register as registerOpenPorts } from "./tools/openPorts.js";
36
36
  import { register as registerContainerScan } from "./tools/containerScan.js";
37
+ import { register as registerJournalLogs } from "./tools/journalLogs.js";
38
+ import { register as registerLogSearch } from "./tools/logSearch.js";
39
+ import { register as registerNtfySend } from "./tools/ntfySend.js";
40
+ import { register as registerNtfyTopics } from "./tools/ntfyTopics.js";
41
+ import { register as registerAptUpgradable } from "./tools/aptUpgradable.js";
42
+ import { register as registerAptHistory } from "./tools/aptHistory.js";
43
+ import { register as registerKernelInfo } from "./tools/kernelInfo.js";
44
+ import { register as registerSystemdServices } from "./tools/systemdServices.js";
37
45
  const server = new McpServer({
38
46
  name: "homelab-mcp",
39
- version: "0.5.0",
47
+ version: "0.7.0",
40
48
  });
41
49
  registerPiStatus(server);
42
50
  registerPiReboot(server);
@@ -71,6 +79,14 @@ registerUfwStatus(server);
71
79
  registerFail2banStatus(server);
72
80
  registerOpenPorts(server);
73
81
  registerContainerScan(server);
82
+ registerJournalLogs(server);
83
+ registerLogSearch(server);
84
+ registerNtfySend(server);
85
+ registerNtfyTopics(server);
86
+ registerAptUpgradable(server);
87
+ registerAptHistory(server);
88
+ registerKernelInfo(server);
89
+ registerSystemdServices(server);
74
90
  async function main() {
75
91
  const transport = new StdioServerTransport();
76
92
  await server.connect(transport);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
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;AAEjF,OAAO,EAAE,QAAQ,IAAI,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,EAAE,QAAQ,IAAI,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,EAAE,QAAQ,IAAI,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAC7E,OAAO,EAAE,QAAQ,IAAI,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,QAAQ,IAAI,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAC/E,OAAO,EAAE,QAAQ,IAAI,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAAE,QAAQ,IAAI,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,QAAQ,IAAI,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,QAAQ,IAAI,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAAE,QAAQ,IAAI,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,QAAQ,IAAI,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAAE,QAAQ,IAAI,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC3E,OAAO,EAAE,QAAQ,IAAI,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAAE,QAAQ,IAAI,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAAE,QAAQ,IAAI,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,QAAQ,IAAI,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AACjF,OAAO,EAAE,QAAQ,IAAI,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AACjF,OAAO,EAAE,QAAQ,IAAI,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AACnF,OAAO,EAAE,QAAQ,IAAI,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAAE,QAAQ,IAAI,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AACnF,OAAO,EAAE,QAAQ,IAAI,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC3E,OAAO,EAAE,QAAQ,IAAI,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAC/E,OAAO,EAAE,QAAQ,IAAI,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AACjF,OAAO,EAAE,QAAQ,IAAI,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAC7E,OAAO,EAAE,QAAQ,IAAI,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,EAAE,QAAQ,IAAI,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,QAAQ,IAAI,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAC7E,OAAO,EAAE,QAAQ,IAAI,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,QAAQ,IAAI,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC3E,OAAO,EAAE,QAAQ,IAAI,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAAE,QAAQ,IAAI,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAC/E,OAAO,EAAE,QAAQ,IAAI,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAAE,QAAQ,IAAI,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAC7E,OAAO,EAAE,QAAQ,IAAI,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,EAAE,QAAQ,IAAI,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAAE,QAAQ,IAAI,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,EAAE,QAAQ,IAAI,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,QAAQ,IAAI,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAC7E,OAAO,EAAE,QAAQ,IAAI,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,QAAQ,IAAI,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,QAAQ,IAAI,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAEjF,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;IAC3B,IAAI,EAAE,aAAa;IACnB,OAAO,EAAE,OAAO;CACjB,CAAC,CAAC;AAEH,gBAAgB,CAAC,MAAM,CAAC,CAAC;AACzB,gBAAgB,CAAC,MAAM,CAAC,CAAC;AACzB,qBAAqB,CAAC,MAAM,CAAC,CAAC;AAC9B,mBAAmB,CAAC,MAAM,CAAC,CAAC;AAC5B,sBAAsB,CAAC,MAAM,CAAC,CAAC;AAC/B,iBAAiB,CAAC,MAAM,CAAC,CAAC;AAC1B,mBAAmB,CAAC,MAAM,CAAC,CAAC;AAC5B,mBAAmB,CAAC,MAAM,CAAC,CAAC;AAC5B,iBAAiB,CAAC,MAAM,CAAC,CAAC;AAC1B,mBAAmB,CAAC,MAAM,CAAC,CAAC;AAC5B,iBAAiB,CAAC,MAAM,CAAC,CAAC;AAC1B,oBAAoB,CAAC,MAAM,CAAC,CAAC;AAC7B,iBAAiB,CAAC,MAAM,CAAC,CAAC;AAC1B,iBAAiB,CAAC,MAAM,CAAC,CAAC;AAC1B,eAAe,CAAC,MAAM,CAAC,CAAC;AACxB,uBAAuB,CAAC,MAAM,CAAC,CAAC;AAChC,uBAAuB,CAAC,MAAM,CAAC,CAAC;AAChC,wBAAwB,CAAC,MAAM,CAAC,CAAC;AACjC,iBAAiB,CAAC,MAAM,CAAC,CAAC;AAC1B,wBAAwB,CAAC,MAAM,CAAC,CAAC;AACjC,oBAAoB,CAAC,MAAM,CAAC,CAAC;AAC7B,sBAAsB,CAAC,MAAM,CAAC,CAAC;AAC/B,uBAAuB,CAAC,MAAM,CAAC,CAAC;AAChC,qBAAqB,CAAC,MAAM,CAAC,CAAC;AAC9B,gBAAgB,CAAC,MAAM,CAAC,CAAC;AACzB,kBAAkB,CAAC,MAAM,CAAC,CAAC;AAC3B,qBAAqB,CAAC,MAAM,CAAC,CAAC;AAC9B,kBAAkB,CAAC,MAAM,CAAC,CAAC;AAC3B,oBAAoB,CAAC,MAAM,CAAC,CAAC;AAC7B,iBAAiB,CAAC,MAAM,CAAC,CAAC;AAC1B,sBAAsB,CAAC,MAAM,CAAC,CAAC;AAC/B,iBAAiB,CAAC,MAAM,CAAC,CAAC;AAC1B,qBAAqB,CAAC,MAAM,CAAC,CAAC;AAC9B,mBAAmB,CAAC,MAAM,CAAC,CAAC;AAC5B,iBAAiB,CAAC,MAAM,CAAC,CAAC;AAC1B,gBAAgB,CAAC,MAAM,CAAC,CAAC;AACzB,kBAAkB,CAAC,MAAM,CAAC,CAAC;AAC3B,qBAAqB,CAAC,MAAM,CAAC,CAAC;AAC9B,kBAAkB,CAAC,MAAM,CAAC,CAAC;AAC3B,kBAAkB,CAAC,MAAM,CAAC,CAAC;AAC3B,uBAAuB,CAAC,MAAM,CAAC,CAAC;AAEhC,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function register(server: McpServer): void;
3
+ //# sourceMappingURL=aptHistory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aptHistory.d.ts","sourceRoot":"","sources":["../../src/tools/aptHistory.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAazE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAuBhD"}
@@ -0,0 +1,31 @@
1
+ import { z } from "zod";
2
+ import { execSSH, errorResponse } from "../utils/ssh-api.js";
3
+ const inputSchema = {
4
+ lines: z
5
+ .number()
6
+ .int()
7
+ .positive()
8
+ .optional()
9
+ .default(50)
10
+ .describe("Number of recent history entries to return"),
11
+ };
12
+ export function register(server) {
13
+ server.tool("homelab_aptHistory", "Show recent apt install, upgrade, and remove history", inputSchema, async (args) => {
14
+ try {
15
+ const cmd = `(grep -E '(Install|Upgrade|Remove|Commandline)' /var/log/apt/history.log 2>/dev/null; ` +
16
+ `zgrep -E '(Install|Upgrade|Remove|Commandline)' /var/log/apt/history.log.*.gz 2>/dev/null) ` +
17
+ `| tail -${args.lines}`;
18
+ const output = await execSSH(cmd);
19
+ return {
20
+ content: [{
21
+ type: "text",
22
+ text: output || "No apt history entries found.",
23
+ }],
24
+ };
25
+ }
26
+ catch (error) {
27
+ return errorResponse(error);
28
+ }
29
+ });
30
+ }
31
+ //# sourceMappingURL=aptHistory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aptHistory.js","sourceRoot":"","sources":["../../src/tools/aptHistory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAE7D,MAAM,WAAW,GAAG;IAClB,KAAK,EAAE,CAAC;SACL,MAAM,EAAE;SACR,GAAG,EAAE;SACL,QAAQ,EAAE;SACV,QAAQ,EAAE;SACV,OAAO,CAAC,EAAE,CAAC;SACX,QAAQ,CAAC,4CAA4C,CAAC;CAC1D,CAAC;AAEF,MAAM,UAAU,QAAQ,CAAC,MAAiB;IACxC,MAAM,CAAC,IAAI,CACT,oBAAoB,EACpB,sDAAsD,EACtD,WAAW,EACX,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,IAAI,CAAC;YACH,MAAM,GAAG,GACP,wFAAwF;gBACxF,6FAA6F;gBAC7F,WAAW,IAAI,CAAC,KAAK,EAAE,CAAC;YAC1B,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC;YAClC,OAAO;gBACL,OAAO,EAAE,CAAC;wBACR,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,MAAM,IAAI,+BAA+B;qBAChD,CAAC;aACH,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function register(server: McpServer): void;
3
+ //# sourceMappingURL=aptUpgradable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aptUpgradable.d.ts","sourceRoot":"","sources":["../../src/tools/aptUpgradable.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAqBhD"}
@@ -0,0 +1,19 @@
1
+ import { execSSH, errorResponse } from "../utils/ssh-api.js";
2
+ const inputSchema = {};
3
+ export function register(server) {
4
+ server.tool("homelab_aptUpgradable", "List upgradable packages with current and candidate versions", inputSchema, async () => {
5
+ try {
6
+ const output = await execSSH("apt list --upgradable 2>/dev/null | grep -v '^Listing'");
7
+ return {
8
+ content: [{
9
+ type: "text",
10
+ text: output || "All packages are up to date.",
11
+ }],
12
+ };
13
+ }
14
+ catch (error) {
15
+ return errorResponse(error);
16
+ }
17
+ });
18
+ }
19
+ //# sourceMappingURL=aptUpgradable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aptUpgradable.js","sourceRoot":"","sources":["../../src/tools/aptUpgradable.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAE7D,MAAM,WAAW,GAAG,EAAE,CAAC;AAEvB,MAAM,UAAU,QAAQ,CAAC,MAAiB;IACxC,MAAM,CAAC,IAAI,CACT,uBAAuB,EACvB,8DAA8D,EAC9D,WAAW,EACX,KAAK,IAAI,EAAE;QACT,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAC1B,wDAAwD,CACzD,CAAC;YACF,OAAO;gBACL,OAAO,EAAE,CAAC;wBACR,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,MAAM,IAAI,8BAA8B;qBAC/C,CAAC;aACH,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function register(server: McpServer): void;
3
+ //# sourceMappingURL=journalLogs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"journalLogs.d.ts","sourceRoot":"","sources":["../../src/tools/journalLogs.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA4BzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAkBhD"}
@@ -0,0 +1,45 @@
1
+ import { z } from "zod";
2
+ import { execSSH, errorResponse } from "../utils/ssh-api.js";
3
+ const inputSchema = {
4
+ unit: z
5
+ .string()
6
+ .optional()
7
+ .describe("Systemd unit name to filter (e.g. docker.service, ssh.service)"),
8
+ priority: z
9
+ .number()
10
+ .int()
11
+ .min(0)
12
+ .max(7)
13
+ .optional()
14
+ .describe("Syslog priority level 0-7 (0=emerg, 3=err, 4=warning, 6=info, 7=debug)"),
15
+ since: z
16
+ .string()
17
+ .optional()
18
+ .describe("Time specification like '1 hour ago', '2024-01-01', 'today'"),
19
+ lines: z
20
+ .number()
21
+ .int()
22
+ .positive()
23
+ .optional()
24
+ .default(50)
25
+ .describe("Number of journal lines to return"),
26
+ };
27
+ export function register(server) {
28
+ server.tool("homelab_journalLogs", "Query systemd journal logs with unit, priority, and time filters", inputSchema, async (args) => {
29
+ try {
30
+ const parts = ["journalctl", "--no-pager", `-n ${args.lines}`];
31
+ if (args.unit)
32
+ parts.push(`--unit '${args.unit}'`);
33
+ if (args.priority !== undefined)
34
+ parts.push(`--priority ${args.priority}`);
35
+ if (args.since)
36
+ parts.push(`--since '${args.since}'`);
37
+ const output = await execSSH(parts.join(" "));
38
+ return { content: [{ type: "text", text: output || "No journal entries matched the filters." }] };
39
+ }
40
+ catch (error) {
41
+ return errorResponse(error);
42
+ }
43
+ });
44
+ }
45
+ //# sourceMappingURL=journalLogs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"journalLogs.js","sourceRoot":"","sources":["../../src/tools/journalLogs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAE7D,MAAM,WAAW,GAAG;IAClB,IAAI,EAAE,CAAC;SACJ,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,gEAAgE,CAAC;IAC7E,QAAQ,EAAE,CAAC;SACR,MAAM,EAAE;SACR,GAAG,EAAE;SACL,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,EAAE;SACV,QAAQ,CAAC,wEAAwE,CAAC;IACrF,KAAK,EAAE,CAAC;SACL,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,6DAA6D,CAAC;IAC1E,KAAK,EAAE,CAAC;SACL,MAAM,EAAE;SACR,GAAG,EAAE;SACL,QAAQ,EAAE;SACV,QAAQ,EAAE;SACV,OAAO,CAAC,EAAE,CAAC;SACX,QAAQ,CAAC,mCAAmC,CAAC;CACjD,CAAC;AAEF,MAAM,UAAU,QAAQ,CAAC,MAAiB;IACxC,MAAM,CAAC,IAAI,CACT,qBAAqB,EACrB,kEAAkE,EAClE,WAAW,EACX,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,CAAC,YAAY,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;YAC/D,IAAI,IAAI,CAAC,IAAI;gBAAE,KAAK,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;YACnD,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS;gBAAE,KAAK,CAAC,IAAI,CAAC,cAAc,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;YAC3E,IAAI,IAAI,CAAC,KAAK;gBAAE,KAAK,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;YACtD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;YAC9C,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,MAAM,IAAI,yCAAyC,EAAE,CAAC,EAAE,CAAC;QAC7G,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function register(server: McpServer): void;
3
+ //# sourceMappingURL=kernelInfo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kernelInfo.d.ts","sourceRoot":"","sources":["../../src/tools/kernelInfo.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAwBhD"}
@@ -0,0 +1,24 @@
1
+ import { execSSH, errorResponse } from "../utils/ssh-api.js";
2
+ const inputSchema = {};
3
+ export function register(server) {
4
+ server.tool("homelab_kernelInfo", "Show kernel version, boot parameters, and loaded modules", inputSchema, async () => {
5
+ try {
6
+ const cmd = [
7
+ "echo '=== Kernel ==='",
8
+ "uname -a",
9
+ "echo",
10
+ "echo '=== Boot Parameters ==='",
11
+ "cat /proc/cmdline",
12
+ "echo",
13
+ "echo '=== Loaded Modules (top 30) ==='",
14
+ "lsmod | head -31",
15
+ ].join(" && ");
16
+ const output = await execSSH(cmd);
17
+ return { content: [{ type: "text", text: output }] };
18
+ }
19
+ catch (error) {
20
+ return errorResponse(error);
21
+ }
22
+ });
23
+ }
24
+ //# sourceMappingURL=kernelInfo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kernelInfo.js","sourceRoot":"","sources":["../../src/tools/kernelInfo.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAE7D,MAAM,WAAW,GAAG,EAAE,CAAC;AAEvB,MAAM,UAAU,QAAQ,CAAC,MAAiB;IACxC,MAAM,CAAC,IAAI,CACT,oBAAoB,EACpB,0DAA0D,EAC1D,WAAW,EACX,KAAK,IAAI,EAAE;QACT,IAAI,CAAC;YACH,MAAM,GAAG,GAAG;gBACV,uBAAuB;gBACvB,UAAU;gBACV,MAAM;gBACN,gCAAgC;gBAChC,mBAAmB;gBACnB,MAAM;gBACN,wCAAwC;gBACxC,kBAAkB;aACnB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACf,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC;YAClC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;QAChE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function register(server: McpServer): void;
3
+ //# sourceMappingURL=logSearch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logSearch.d.ts","sourceRoot":"","sources":["../../src/tools/logSearch.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAqBzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAkBhD"}
@@ -0,0 +1,35 @@
1
+ import { z } from "zod";
2
+ import { execSSH, errorResponse } from "../utils/ssh-api.js";
3
+ const inputSchema = {
4
+ pattern: z
5
+ .string()
6
+ .min(1)
7
+ .describe("Grep pattern to search for in container logs"),
8
+ service: z
9
+ .string()
10
+ .optional()
11
+ .describe("Container name to search. Searches all running containers if omitted"),
12
+ lines: z
13
+ .number()
14
+ .int()
15
+ .positive()
16
+ .optional()
17
+ .default(100)
18
+ .describe("Maximum matching lines to return"),
19
+ };
20
+ export function register(server) {
21
+ server.tool("homelab_logSearch", "Search across Docker container logs with grep patterns", inputSchema, async (args) => {
22
+ try {
23
+ const escaped = args.pattern.replace(/'/g, "'\\''");
24
+ const cmd = args.service
25
+ ? `docker logs '${args.service}' 2>&1 | grep -i '${escaped}' | tail -${args.lines}`
26
+ : `docker ps --format '{{.Names}}' | while read name; do matches=$(docker logs "$name" 2>&1 | grep -i '${escaped}' | tail -${args.lines}); if [ -n "$matches" ]; then echo "=== $name ==="; echo "$matches"; echo; fi; done`;
27
+ const output = await execSSH(cmd);
28
+ return { content: [{ type: "text", text: output || `No matches found for pattern '${args.pattern}'.` }] };
29
+ }
30
+ catch (error) {
31
+ return errorResponse(error);
32
+ }
33
+ });
34
+ }
35
+ //# sourceMappingURL=logSearch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logSearch.js","sourceRoot":"","sources":["../../src/tools/logSearch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAE7D,MAAM,WAAW,GAAG;IAClB,OAAO,EAAE,CAAC;SACP,MAAM,EAAE;SACR,GAAG,CAAC,CAAC,CAAC;SACN,QAAQ,CAAC,8CAA8C,CAAC;IAC3D,OAAO,EAAE,CAAC;SACP,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,sEAAsE,CAAC;IACnF,KAAK,EAAE,CAAC;SACL,MAAM,EAAE;SACR,GAAG,EAAE;SACL,QAAQ,EAAE;SACV,QAAQ,EAAE;SACV,OAAO,CAAC,GAAG,CAAC;SACZ,QAAQ,CAAC,kCAAkC,CAAC;CAChD,CAAC;AAEF,MAAM,UAAU,QAAQ,CAAC,MAAiB;IACxC,MAAM,CAAC,IAAI,CACT,mBAAmB,EACnB,wDAAwD,EACxD,WAAW,EACX,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YACpD,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO;gBACtB,CAAC,CAAC,gBAAgB,IAAI,CAAC,OAAO,qBAAqB,OAAO,aAAa,IAAI,CAAC,KAAK,EAAE;gBACnF,CAAC,CAAC,uGAAuG,OAAO,aAAa,IAAI,CAAC,KAAK,qFAAqF,CAAC;YAC/N,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC;YAClC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,MAAM,IAAI,iCAAiC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,CAAC;QACrH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function register(server: McpServer): void;
3
+ //# sourceMappingURL=ntfySend.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ntfySend.d.ts","sourceRoot":"","sources":["../../src/tools/ntfySend.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAmCzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA+BhD"}
@@ -0,0 +1,59 @@
1
+ import { z } from "zod";
2
+ import { execSSH, errorResponse } from "../utils/ssh-api.js";
3
+ import { CommandFailedError } from "../utils/errors.js";
4
+ const DEFAULT_PORT = 8080;
5
+ const SERVICE_NAME = "Ntfy";
6
+ const inputSchema = {
7
+ topic: z
8
+ .string()
9
+ .min(1)
10
+ .describe("Ntfy topic to publish to"),
11
+ message: z
12
+ .string()
13
+ .min(1)
14
+ .describe("Notification message body"),
15
+ title: z
16
+ .string()
17
+ .optional()
18
+ .describe("Notification title"),
19
+ priority: z
20
+ .enum(["min", "low", "default", "high", "urgent"])
21
+ .optional()
22
+ .describe("Notification priority level"),
23
+ tags: z
24
+ .string()
25
+ .optional()
26
+ .describe("Comma-separated tags/emojis (e.g. 'warning,server')"),
27
+ };
28
+ function getPort() {
29
+ const override = process.env.HOMELAB_NTFY_PORT;
30
+ return override ? parseInt(override, 10) : DEFAULT_PORT;
31
+ }
32
+ export function register(server) {
33
+ server.tool("homelab_ntfySend", "Send a push notification via Ntfy", inputSchema, async (args) => {
34
+ const port = getPort();
35
+ try {
36
+ const headers = [];
37
+ if (args.title)
38
+ headers.push(`-H 'Title: ${args.title}'`);
39
+ if (args.priority)
40
+ headers.push(`-H 'Priority: ${args.priority}'`);
41
+ if (args.tags)
42
+ headers.push(`-H 'Tags: ${args.tags}'`);
43
+ const escaped = args.message.replace(/'/g, "'\\''");
44
+ const cmd = `curl -sf -d '${escaped}' ${headers.join(" ")} 'http://localhost:${port}/${args.topic}'`;
45
+ const output = await execSSH(cmd);
46
+ return { content: [{ type: "text", text: output || `Notification sent to topic '${args.topic}'.` }] };
47
+ }
48
+ catch (error) {
49
+ if (error instanceof CommandFailedError) {
50
+ if (error.exitCode === 7) {
51
+ return errorResponse(new Error(`Could not connect to ${SERVICE_NAME} on port ${port}. Is it running? ` +
52
+ `Set HOMELAB_NTFY_PORT if using a non-default port.`));
53
+ }
54
+ }
55
+ return errorResponse(error);
56
+ }
57
+ });
58
+ }
59
+ //# sourceMappingURL=ntfySend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ntfySend.js","sourceRoot":"","sources":["../../src/tools/ntfySend.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function register(server: McpServer): void;
3
+ //# sourceMappingURL=ntfyTopics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ntfyTopics.d.ts","sourceRoot":"","sources":["../../src/tools/ntfyTopics.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAwBzE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA2BhD"}
@@ -0,0 +1,41 @@
1
+ import { z } from "zod";
2
+ import { execSSH, errorResponse } from "../utils/ssh-api.js";
3
+ import { CommandFailedError } from "../utils/errors.js";
4
+ const DEFAULT_PORT = 8080;
5
+ const SERVICE_NAME = "Ntfy";
6
+ const inputSchema = {
7
+ topic: z
8
+ .string()
9
+ .optional()
10
+ .describe("Specific topic to check. Lists all cached messages if omitted"),
11
+ since: z
12
+ .string()
13
+ .optional()
14
+ .default("1h")
15
+ .describe("Time window for recent messages (e.g. '1h', '30m', '1d')"),
16
+ };
17
+ function getPort() {
18
+ const override = process.env.HOMELAB_NTFY_PORT;
19
+ return override ? parseInt(override, 10) : DEFAULT_PORT;
20
+ }
21
+ export function register(server) {
22
+ server.tool("homelab_ntfyTopics", "List Ntfy topics and recent messages", inputSchema, async (args) => {
23
+ const port = getPort();
24
+ try {
25
+ const topicPath = args.topic || "*";
26
+ const cmd = `curl -sf 'http://localhost:${port}/${topicPath}/json?since=${args.since}&poll=1'`;
27
+ const output = await execSSH(cmd);
28
+ return { content: [{ type: "text", text: output || "No recent messages found." }] };
29
+ }
30
+ catch (error) {
31
+ if (error instanceof CommandFailedError) {
32
+ if (error.exitCode === 7) {
33
+ return errorResponse(new Error(`Could not connect to ${SERVICE_NAME} on port ${port}. Is it running? ` +
34
+ `Set HOMELAB_NTFY_PORT if using a non-default port.`));
35
+ }
36
+ }
37
+ return errorResponse(error);
38
+ }
39
+ });
40
+ }
41
+ //# sourceMappingURL=ntfyTopics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ntfyTopics.js","sourceRoot":"","sources":["../../src/tools/ntfyTopics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAExD,MAAM,YAAY,GAAG,IAAI,CAAC;AAC1B,MAAM,YAAY,GAAG,MAAM,CAAC;AAE5B,MAAM,WAAW,GAAG;IAClB,KAAK,EAAE,CAAC;SACL,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,+DAA+D,CAAC;IAC5E,KAAK,EAAE,CAAC;SACL,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,OAAO,CAAC,IAAI,CAAC;SACb,QAAQ,CAAC,0DAA0D,CAAC;CACxE,CAAC;AAEF,SAAS,OAAO;IACd,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;IAC/C,OAAO,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC;AAC1D,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,MAAiB;IACxC,MAAM,CAAC,IAAI,CACT,oBAAoB,EACpB,sCAAsC,EACtC,WAAW,EACX,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;QACvB,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,IAAI,GAAG,CAAC;YACpC,MAAM,GAAG,GAAG,8BAA8B,IAAI,IAAI,SAAS,eAAe,IAAI,CAAC,KAAK,UAAU,CAAC;YAC/F,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC;YAClC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,MAAM,IAAI,2BAA2B,EAAE,CAAC,EAAE,CAAC;QAC/F,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,kBAAkB,EAAE,CAAC;gBACxC,IAAI,KAAK,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;oBACzB,OAAO,aAAa,CAClB,IAAI,KAAK,CACP,wBAAwB,YAAY,YAAY,IAAI,mBAAmB;wBACrE,oDAAoD,CACvD,CACF,CAAC;gBACJ,CAAC;YACH,CAAC;YACD,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function register(server: McpServer): void;
3
+ //# sourceMappingURL=systemdServices.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"systemdServices.d.ts","sourceRoot":"","sources":["../../src/tools/systemdServices.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAczE,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAiBhD"}
@@ -0,0 +1,27 @@
1
+ import { z } from "zod";
2
+ import { execSSH, errorResponse } from "../utils/ssh-api.js";
3
+ const inputSchema = {
4
+ unit: z
5
+ .string()
6
+ .optional()
7
+ .describe("Specific unit name to get status for (e.g. docker.service, restic-backup.timer)"),
8
+ type: z
9
+ .enum(["service", "timer", "socket", "mount"])
10
+ .optional()
11
+ .describe("Filter by unit type when listing. Defaults to 'service'"),
12
+ };
13
+ export function register(server) {
14
+ server.tool("homelab_systemdServices", "List systemd units or get status of a specific unit", inputSchema, async (args) => {
15
+ try {
16
+ const cmd = args.unit
17
+ ? `systemctl status '${args.unit}' --no-pager 2>&1`
18
+ : `systemctl list-units --type=${args.type || "service"} --no-pager 2>&1`;
19
+ const output = await execSSH(cmd);
20
+ return { content: [{ type: "text", text: output }] };
21
+ }
22
+ catch (error) {
23
+ return errorResponse(error);
24
+ }
25
+ });
26
+ }
27
+ //# sourceMappingURL=systemdServices.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"systemdServices.js","sourceRoot":"","sources":["../../src/tools/systemdServices.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAE7D,MAAM,WAAW,GAAG;IAClB,IAAI,EAAE,CAAC;SACJ,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,iFAAiF,CAAC;IAC9F,IAAI,EAAE,CAAC;SACJ,IAAI,CAAC,CAAC,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;SAC7C,QAAQ,EAAE;SACV,QAAQ,CAAC,yDAAyD,CAAC;CACvE,CAAC;AAEF,MAAM,UAAU,QAAQ,CAAC,MAAiB;IACxC,MAAM,CAAC,IAAI,CACT,yBAAyB,EACzB,qDAAqD,EACrD,WAAW,EACX,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI;gBACnB,CAAC,CAAC,qBAAqB,IAAI,CAAC,IAAI,mBAAmB;gBACnD,CAAC,CAAC,+BAA+B,IAAI,CAAC,IAAI,IAAI,SAAS,kBAAkB,CAAC;YAC5E,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC;YAClC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;QAChE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tmhs/homelab-mcp",
3
- "version": "0.5.0",
4
- "description": "MCP server for home lab operations via SSH - 33 tools for system status, Docker Compose management, service health, monitoring, DNS, reverse proxy, networking, backups, disaster recovery, security auditing, and administration on a Raspberry Pi.",
3
+ "version": "0.7.0",
4
+ "description": "MCP server for home lab operations via SSH - 41 tools for system status, Docker Compose management, service health, monitoring, DNS, reverse proxy, networking, backups, disaster recovery, security auditing, logs, notifications, OS management, and administration on a Raspberry Pi.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "bin": {