Skip to content

Commit b6da07c

Browse files
author
Jordan Munch O'Hare
committed
feat!: restructure generic
1 parent e3f3fbe commit b6da07c

38 files changed

+2430
-182
lines changed

.claude/CLAUDE.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# MCP SSH Unraid - Project Instructions
1+
# MCP SSH SRE - Project Instructions
22

33
## User Expectations
44

@@ -58,4 +58,14 @@ When testing the deployed MCP server, use the MCP tools (e.g., `mcp__unraid-ssh_
5858

5959
## Filter System
6060

61-
All 79 tools support comprehensive output filtering. Filters are defined in `src/filters.ts` and applied via `...outputFiltersSchema.shape` pattern. When adding new tools, always include filter support.
61+
All 12 tool modules (with 79+ total actions) support comprehensive output filtering. Filters are defined in `src/filters.ts` and applied via `...outputFiltersSchema.shape` pattern. When adding new tools, always include filter support.
62+
63+
## Platform Architecture
64+
65+
The server uses a platform abstraction layer:
66+
- **Core tools** (`src/tools/core/`): 10 modules, always loaded on any Linux system
67+
- **Platform-specific tools** (`src/platforms/*/`): Loaded based on auto-detection
68+
- Unraid: 2 modules (array-tools, plugin-tools)
69+
- Generic Linux: No extra modules (uses core only)
70+
71+
Tool loading is handled by `src/tool-loader.ts` based on the detected platform.

README.md

Lines changed: 86 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,21 @@
1-
# MCP SSH Unraid
1+
# MCP SSH SRE
22

3-
A Model Context Protocol (MCP) server that provides secure, read-only SSH access to Unraid servers for debugging and monitoring through AI assistants like Claude.
3+
A Model Context Protocol (MCP) server that provides secure, read-only SSH access to Linux servers for debugging and monitoring through AI assistants like Claude. Supports multiple platforms with auto-detection.
4+
5+
## Supported Platforms
6+
7+
| Platform | Status | Tools |
8+
|----------|--------|-------|
9+
| **Unraid** | Full support | 12 modules (10 core + 2 Unraid-specific) |
10+
| **Generic Linux** | Full support | 10 core modules |
11+
| **TrueNAS** | Planned | - |
12+
| **Proxmox** | Planned | - |
13+
14+
The server automatically detects your platform at startup and loads the appropriate tools.
415

516
## Why Use This?
617

7-
Managing an Unraid server often involves SSH-ing in, running multiple commands, correlating logs, and interpreting system metrics. This MCP server enables AI assistants to do that work for you using natural language.
18+
Managing a Linux server often involves SSH-ing in, running multiple commands, correlating logs, and interpreting system metrics. This MCP server enables AI assistants to do that work for you using natural language.
819

920
**Ask questions like:**
1021

@@ -15,90 +26,58 @@ Managing an Unraid server often involves SSH-ing in, running multiple commands,
1526

1627
Instead of manually running `docker logs`, `smartctl`, `docker inspect`, parsing outputs, and correlating information across multiple tools, your AI assistant does it all in seconds.
1728

18-
## Why SSH Instead of the Unraid API?
19-
20-
Unraid 7.2+ includes a [GraphQL API](https://docs.unraid.net/API/), so you might wonder why this project uses SSH instead. The short answer: **the API has significant gaps** for the kind of deep monitoring and debugging this project provides.
21-
22-
### What the Unraid API Cannot Do
23-
24-
The Unraid GraphQL API is still evolving and has documented limitations:
25-
26-
| Feature | API | SSH |
27-
| -------------------------------------------- | --- | --- |
28-
| Docker container logs |||
29-
| SMART disk health data |||
30-
| Real-time CPU usage/load averages |||
31-
| Network bandwidth monitoring |||
32-
| Disk spin status |||
33-
| Process monitoring (ps/top) |||
34-
| Log file analysis |||
35-
| VM management (libvirt/virsh) |||
36-
| GPU monitoring |||
37-
| UPS status |||
38-
| User scripts |||
39-
| Security auditing (open ports, SSH sessions) |||
40-
41-
Additionally, the API has a [known 32-bit integer overflow](https://github.com/domalab/ha-unraid-connect/issues/8) affecting memory monitoring on systems with >4GB RAM.
42-
43-
### What SSH Enables
44-
45-
With SSH, this project provides **79 specialized tools** that can:
29+
## Why SSH Instead of Platform APIs?
4630

47-
- **Analyze Docker logs** - Search, filter, and correlate logs across all containers simultaneously
48-
- **Parse SMART data** - Detailed drive health analysis including temperature trends, error counts, and failure predictions
49-
- **Monitor everything** - CPU, memory, I/O, network connections, and processes in real-time
50-
- **Search logs everywhere** - Pattern matching across syslog, Docker logs, and application logs
51-
- **Debug inter-container networking** - Test connectivity, DNS resolution, and trace routes between containers
52-
- **Manage VMs** - Full libvirt/virsh access for VM inspection, VNC details, and QEMU logs
53-
- **Audit security** - Check open ports, failed logins, certificate expiration, and container privileges
31+
Many platforms have APIs (like Unraid's GraphQL API), but they often have significant gaps for deep monitoring and debugging:
5432

55-
### Compatibility
33+
| Feature | APIs | SSH |
34+
| -------------------------------------------- | ---- | --- |
35+
| Docker container logs |||
36+
| SMART disk health data |||
37+
| Real-time CPU usage/load averages |||
38+
| Network bandwidth monitoring |||
39+
| Process monitoring (ps/top) |||
40+
| Log file analysis |||
41+
| VM management (libvirt/virsh) |||
42+
| Security auditing (open ports, SSH sessions) |||
5643

57-
| Approach | Unraid Version | Rate Limits |
58-
| ----------- | ----------------------------- | ----------- |
59-
| GraphQL API | 7.2+ only (or Connect plugin) | Yes |
60-
| SSH | All versions | No |
61-
62-
### The Bottom Line
63-
64-
The Unraid API is great for basic status checks and container start/stop operations. But for the deep debugging, log analysis, and comprehensive monitoring that AI assistants need to actually diagnose problems, SSH provides unrestricted access to all system tools—on any Unraid version, without rate limiting.
44+
SSH provides unrestricted access to all system tools on any Linux system, without rate limiting.
6545

6646
## Features
6747

68-
- **79 specialized tools** for comprehensive Unraid server management through natural language
48+
- **Auto-detection** - Automatically detects your platform (Unraid, generic Linux) and loads appropriate tools
49+
- **12 tool modules with 79+ actions** for comprehensive server management through natural language
6950
- **Dual transport modes** - Run via stdio (local) or HTTP/SSE (network-accessible)
7051
- **Read-only by design** - Zero risk of accidental system modifications
7152
- **Docker container management** - Inspect, logs, stats, environment variables, port mappings, network topology, and inter-container communication testing
72-
- **Storage & array management** - Parity checks, SMART data analysis, drive temperatures, array sync status, mover logs, cache usage, and share configuration
73-
- **Health diagnostics** - Comprehensive monitoring that aggregates array status, temperatures, disk space, container health, and system resources with automatic issue detection
53+
- **Storage & array management** - Parity checks, SMART data analysis, drive temperatures, array sync status, mover logs, cache usage, and share configuration (Unraid)
54+
- **Health diagnostics** - Comprehensive monitoring that aggregates system status, temperatures, disk space, container health, and system resources with automatic issue detection
7455
- **System monitoring** - Process monitoring, resource usage analysis, disk I/O statistics, network connections, and memory pressure detection
7556
- **Log analysis** - Search and analyze logs across all containers and system logs simultaneously with pattern detection
7657
- **VM management** - List, inspect, and monitor virtual machines with VNC connection details and libvirt/QEMU logs
7758
- **Security auditing** - Port scanning, failed login monitoring, permission audits, and vulnerability scanning
7859
- **Filesystem operations** - Browse files, search patterns, check permissions, and monitor disk usage with read-only safety
79-
- **AI-powered insights** - Let Claude correlate data across multiple tools and provide actionable recommendations
80-
- **Faster troubleshooting** - Diagnose complex issues in seconds instead of manually running multiple commands
8160

8261
## Quick Start
8362

8463
### Prerequisites
8564

8665
- Node.js 18 or higher
87-
- Unraid server with SSH access enabled
66+
- Linux server with SSH access enabled
8867
- SSH key pair for passwordless authentication
8968

9069
### Installation
9170

9271
```bash
93-
git clone <repository-url>
94-
cd mcp-ssh-unraid
72+
git clone https://github.com/ohare93/mcp-ssh-sre.git
73+
cd mcp-ssh-sre
9574
npm install
9675
npm run build
9776
```
9877

9978
### Configuration
10079

101-
Create a `.env` file with your Unraid server details:
80+
Create a `.env` file with your server details:
10281

10382
```bash
10483
cp .env.example .env
@@ -108,7 +87,7 @@ cp .env.example .env
10887
Required environment variables:
10988

11089
```bash
111-
SSH_HOST=unraid.local # Your Unraid server hostname or IP
90+
SSH_HOST=server.local # Your server hostname or IP
11291
SSH_PORT=22 # SSH port (default: 22)
11392
SSH_USERNAME=mcp-readonly # Username for SSH connection
11493
SSH_KEY_PATH=~/.ssh/id_rsa_mcp # Path to SSH private key
@@ -121,9 +100,9 @@ Add to your MCP client configuration (e.g., Claude Desktop):
121100
```json
122101
{
123102
"mcpServers": {
124-
"unraid-ssh": {
103+
"ssh-sre": {
125104
"command": "node",
126-
"args": ["/absolute/path/to/mcp-ssh-unraid/dist/index.js"]
105+
"args": ["/absolute/path/to/mcp-ssh-sre/dist/index.js"]
127106
}
128107
}
129108
}
@@ -136,19 +115,19 @@ Add to your MCP client configuration (e.g., Claude Desktop):
136115

137116
For HTTP mode configuration, see the [HTTP/SSE Mode](#httpsse-mode-network-accessible) section below.
138117

139-
## 🔒 Securing Your Deployment
118+
## Securing Your Deployment
140119

141120
### Authentication (Required by Default)
142121

143-
OAuth authentication is **REQUIRED by default** in v1.1.0+.
122+
OAuth authentication is **REQUIRED by default** in v2.0.0+.
144123

145124
Configure via `REQUIRE_AUTH` environment variable:
146125

147126
| Value | Use Case |
148127
| ---------------- | ------------------------------------------ |
149-
| `true` (default) | Production - require OAuth token |
150-
| `false` | ⚠️ Local dev only - allows unauthenticated |
151-
| `development` | ⚠️ Local dev - logs warnings |
128+
| `true` (default) | Production - require OAuth token |
129+
| `false` | Local dev only - allows unauthenticated |
130+
| `development` | Local dev - logs warnings |
152131

153132
**Never set `REQUIRE_AUTH=false` in production!**
154133

@@ -188,8 +167,8 @@ Configure via `REQUIRE_AUTH` environment variable:
188167

189168
### Network Security
190169

191-
🚫 **DON'T:** Expose directly to internet
192-
**DO:** Use VPN/Tailscale or reverse proxy with TLS
170+
- **DON'T:** Expose directly to internet
171+
- **DO:** Use VPN/Tailscale or reverse proxy with TLS
193172

194173
### Security Checklist
195174

@@ -200,36 +179,32 @@ Configure via `REQUIRE_AUTH` environment variable:
200179

201180
## Security Setup
202181

203-
For secure access, create a dedicated read-only user on your Unraid server:
182+
For secure access, create a dedicated read-only user on your server:
204183

205184
```bash
206-
# On Unraid server as root
185+
# On server as root
207186
useradd -m -s /bin/bash mcp-readonly
208187
passwd mcp-readonly
209188
usermod -aG docker mcp-readonly
210-
211-
# Make persistent across reboots
212-
echo "useradd -m -s /bin/bash mcp-readonly 2>/dev/null" >> /boot/config/go
213-
echo "usermod -aG docker mcp-readonly 2>/dev/null" >> /boot/config/go
214189
```
215190

216191
Generate and deploy SSH key:
217192

218193
```bash
219194
# On your local machine
220-
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_mcp -C "mcp-ssh-unraid"
221-
ssh-copy-id -i ~/.ssh/id_ed25519_mcp.pub mcp-readonly@unraid.local
195+
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_mcp -C "mcp-ssh-sre"
196+
ssh-copy-id -i ~/.ssh/id_ed25519_mcp.pub mcp-readonly@server.local
222197
```
223198

224199
## Example Usage
225200

226201
Once configured, you can use natural language prompts with your MCP client:
227202

228-
- "List all Docker containers on my Unraid server"
203+
- "List all Docker containers on my server"
229204
- "Show me the logs for the Plex container"
230205
- "What's the current system load and memory usage?"
231206
- "Run a comprehensive health check"
232-
- "Check the array status and drive temperatures"
207+
- "Check the array status and drive temperatures" (Unraid)
233208
- "Which containers are using the most resources?"
234209

235210
## Development
@@ -250,29 +225,29 @@ npm run build
250225
**Choose your deployment mode:**
251226

252227
- **Stdio Mode**: Best for local development or when connecting directly from Claude Desktop on the same machine
253-
- **HTTP Mode**: Ideal for running on your Unraid server itself or when accessing from remote clients
228+
- **HTTP Mode**: Ideal for running on your server itself or when accessing from remote clients
254229

255230
### Stdio Mode (Default)
256231

257232
For use with local MCP clients (like Claude Desktop):
258233

259234
```bash
260235
# Build and run with Docker
261-
docker build -t mcp-ssh-unraid .
262-
docker run -d --env-file .env mcp-ssh-unraid
236+
docker build -t mcp-ssh-sre .
237+
docker run -d --env-file .env mcp-ssh-sre
263238

264239
# Or use Docker Compose
265240
docker-compose up -d
266241
```
267242

268243
### HTTP/SSE Mode (Network-Accessible)
269244

270-
For remote access or running as a service on your Unraid server:
245+
For remote access or running as a service on your server:
271246

272247
```bash
273248
# Build and run with Docker
274-
docker build -f Dockerfile.http -t mcp-ssh-unraid-http .
275-
docker run -d -p 3000:3000 --env-file .env mcp-ssh-unraid-http
249+
docker build -f Dockerfile.http -t mcp-ssh-sre .
250+
docker run -d -p 3000:3000 --env-file .env mcp-ssh-sre
276251

277252
# Or use Docker Compose (recommended)
278253
docker-compose -f docker-compose.http.yml up -d
@@ -286,7 +261,6 @@ In addition to the SSH configuration variables, HTTP mode supports:
286261
HTTP_PORT=3000 # Port for HTTP server (default: 3000)
287262
CORS_ORIGIN=* # CORS origin (default: *, allows all origins)
288263
OAUTH_SERVER_URL=https://mcp.example.com # Public URL for OAuth discovery (REQUIRED for production)
289-
MOCK_TOKEN=mcp-unraid-access-token # Mock token for testing (optional)
290264
```
291265

292266
> **Important:** When deploying behind a reverse proxy (Traefik, nginx, etc.), you **must** set `OAUTH_SERVER_URL` to your public URL (e.g., `https://mcp.example.com`). This URL is returned in OAuth discovery metadata endpoints. If not set correctly, OAuth clients will fail with a "protected resource does not match" error.
@@ -305,7 +279,7 @@ Add to your MCP client configuration:
305279
```json
306280
{
307281
"mcpServers": {
308-
"unraid-ssh-http": {
282+
"ssh-sre": {
309283
"url": "http://your-server:3000/mcp",
310284
"transport": "http"
311285
}
@@ -318,13 +292,38 @@ Or for Claude Desktop with HTTP support:
318292
```json
319293
{
320294
"mcpServers": {
321-
"unraid-ssh-http": {
322-
"url": "http://your-unraid-server.local:3000/mcp"
295+
"ssh-sre": {
296+
"url": "http://your-server.local:3000/mcp"
323297
}
324298
}
325299
}
326300
```
327301

302+
## Architecture
303+
304+
The server uses a platform abstraction layer:
305+
306+
```
307+
src/
308+
├── platforms/
309+
│ ├── types.ts # Platform interfaces
310+
│ ├── registry.ts # Platform detection & registration
311+
│ ├── linux/ # Generic Linux (baseline)
312+
│ └── unraid/ # Unraid-specific tools
313+
├── tools/
314+
│ └── core/ # 10 core tool modules (all platforms)
315+
├── tool-loader.ts # Dynamic tool loading
316+
├── index.ts # Stdio transport entry
317+
└── http-server.ts # HTTP transport entry
318+
```
319+
320+
### Adding New Platforms
321+
322+
1. Create `src/platforms/<platform>/index.ts` implementing the `Platform` interface
323+
2. Add detection logic (file checks, command output parsing)
324+
3. Create platform-specific tool modules
325+
4. Register in `src/platforms/index.ts`
326+
328327
## Contributing
329328

330329
Contributions are welcome! Please ensure:
@@ -340,4 +339,4 @@ ISC
340339

341340
## Support
342341

343-
For issues and questions, please open an issue on the repository.
342+
For issues and questions, please open an issue on the [GitHub repository](https://github.com/ohare93/mcp-ssh-sre).

package.json

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
2-
"name": "mcp-ssh-unraid",
3-
"version": "1.1.2",
4-
"description": "MCP server for SSH access to Unraid",
2+
"name": "mcp-ssh-sre",
3+
"version": "2.0.0",
4+
"description": "MCP server for SRE operations across multiple platforms via SSH",
55
"main": "dist/index.js",
66
"type": "module",
77
"scripts": {
@@ -17,7 +17,12 @@
1717
"keywords": [
1818
"mcp",
1919
"ssh",
20-
"unraid"
20+
"sre",
21+
"devops",
22+
"unraid",
23+
"linux",
24+
"docker",
25+
"monitoring"
2126
],
2227
"author": "",
2328
"license": "ISC",

src/__tests__/container-topology-tools.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { describe, it, expect, vi, beforeEach } from 'vitest';
2-
import { registerContainerTopologyTools } from '../container-topology-tools.js';
2+
import { registerContainerTopologyTools } from '../tools/core/container-topology-tools.js';
33

44
describe('Container Topology Tools', () => {
55
let mockServer: any;

src/__tests__/docker-tools.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { describe, it, expect, vi, beforeEach } from 'vitest';
2-
import { registerDockerTools } from '../docker-tools.js';
2+
import { registerDockerTools } from '../tools/core/docker-tools.js';
33

44
describe('Docker Tools', () => {
55
let mockServer: any;

0 commit comments

Comments
 (0)