A community-driven registry for Claude, Cursor, Windsurf, Cline & more. Not affiliated with Anthropic.
Are you the author? Sign in to claim
Model Context Protocol (MCP) servers for managing homelab infrastructure through Claude Desktop. Monitor Docker/Podman c
Model Context Protocol (MCP) servers for managing homelab infrastructure through Claude Desktop.
A collection of Model Context Protocol (MCP) servers for managing and monitoring your homelab infrastructure through Claude Desktop.
⚠️ IMPORTANT: Please read SECURITY.md before deploying this project.
This project interacts with critical infrastructure (Docker APIs, DNS, network devices). Improper configuration can expose your homelab to security risks.
Key Security Requirements:
.env file secure - Contains API keys and should never be committedSee SECURITY.md for comprehensive security guidance.
This project includes several documentation files for different audiences:
👥 For End Users: Follow this README + copy PROJECT_INSTRUCTIONS.md to Claude 🔄 Migrating from v1.x? See MIGRATION_V3.md for unified server migration 🤖 For AI Assistants: Read CLAUDE.md for complete development context 🔧 For Contributors: Start with CONTRIBUTING.md and CLAUDE.md
After setting up the MCP servers, create your personalized project instructions:
Copy the example template:
# Windows
copy PROJECT_INSTRUCTIONS.example.md PROJECT_INSTRUCTIONS.md
# Linux/Mac
cp PROJECT_INSTRUCTIONS.example.md PROJECT_INSTRUCTIONS.md
Edit the file with your actual infrastructure details:
PROJECT_INSTRUCTIONS.md (for Claude Desktop project instructions):
CLAUDE_CUSTOM.md (for AI development work - contributors only):
Add to Claude Desktop:
PROJECT_INSTRUCTIONS.mdWhat's included:
This README covers installation and basic setup. The project instructions provide Claude with comprehensive usage context.
Version 3.0.0 offers flexible deployment with two modes and two methods:
Choose how your MCP servers are organized:
Run all MCP servers in a single process with namespaced tools. This is the recommended approach for new installations and required for Docker deployments.
{
"mcpServers": {
"homelab-unified": {
"command": "python",
"args": ["C:\\Path\\To\\Homelab-MCP\\homelab_unified_mcp.py"]
}
}
}
Advantages:
docker_get_containers, ping_ping_host)Run each MCP server as a separate process. This mode remains fully supported for backward compatibility and only available with native Python installation.
{
"mcpServers": {
"docker": {
"command": "python",
"args": ["C:\\Path\\To\\Homelab-MCP\\docker_mcp_podman.py"]
},
"ollama": {
"command": "python",
"args": ["C:\\Path\\To\\Homelab-MCP\\ollama_mcp.py"]
}
}
}
Advantages:
get_docker_containers, ping_host)Note: Tool names differ between modes. See MIGRATION_V3.md for detailed migration instructions and tool name changes.
Choose how to install and run the servers:
Pre-built images available on Docker Hub for immediate deployment. See 🐳 Docker Deployment for full setup instructions.
Quick Start:
docker pull bjeans/homelab-mcp:latest
docker-compose up -d
Advantages:
Limitations:
Install Python dependencies directly and run servers from source. See 📦 Installation for full setup instructions.
Quick Start:
pip install -r requirements.txt
python homelab_unified_mcp.py
Advantages:
Requirements:
Migration Guide: See MIGRATION_V3.md for detailed instructions on switching between modes or methods.
Version 3.0.0 uses FastMCP: A modern MCP framework that simplifies server architecture while adding support for multiple transport mechanisms and tool annotations.
FastMCP is a lightweight framework that:
@mcp.tool()) for tool definitionsAll 39 tools now include MCP annotations (readOnlyHint, idempotentHint, etc.) to help Claude make informed decisions about tool usage.
FastMCP servers can operate using different transport mechanisms:
The traditional MCP transport used by Claude Desktop. This is the default and recommended option for most users.
# Run with stdio (default)
python homelab_unified_mcp.py
# Or explicitly specify stdio transport
python homelab_unified_mcp.py --transport stdio
When to use:
Run MCP servers as HTTP services for remote or flexible deployment scenarios.
# Start server with HTTP transport
python homelab_unified_mcp.py --transport http --host 0.0.0.0 --port 8000
# Test the HTTP endpoint
curl http://localhost:8000/tools
When to use:
Stream-based protocol for real-time bidirectional communication.
# Start server with SSE transport
python homelab_unified_mcp.py --transport sse --host 0.0.0.0 --port 8000
# Connect via SSE client
curl http://localhost:8000/sse
When to use:
Claude Desktop continues to use stdio transport by default. No configuration changes are required:
{
"mcpServers": {
"homelab-unified": {
"command": "python",
"args": ["C:\\Path\\To\\Homelab-MCP\\homelab_unified_mcp.py"]
}
}
}
If you're upgrading from v2.2.0:
No action required - just update and restart Claude Desktop.
git clone https://github.com/bjeans/homelab-mcp
cd homelab-mcp
# Install pre-push git hook for automatic security validation
python helpers/install_git_hook.py
Environment variables:
# Windows
copy .env.example .env
# Linux/Mac
cp .env.example .env
Edit .env with your actual values:
# Windows
notepad .env
# Linux/Mac
nano .env
Ansible inventory (if using):
# Windows
copy ansible_hosts.example.yml ansible_hosts.yml
# Linux/Mac
cp ansible_hosts.example.yml ansible_hosts.yml
Edit with your infrastructure details.
Project instructions:
# Windows
copy PROJECT_INSTRUCTIONS.example.md PROJECT_INSTRUCTIONS.md
# Linux/Mac
cp PROJECT_INSTRUCTIONS.example.md PROJECT_INSTRUCTIONS.md
Customize with your network topology and servers.
AI development guide customizations (optional):
# Windows
copy CLAUDE_CUSTOM.example.md CLAUDE_CUSTOM.md
# Linux/Mac
cp CLAUDE_CUSTOM.example.md CLAUDE_CUSTOM.md
Customize with your actual server names and infrastructure details. This file is gitignored and allows Claude to understand your specific homelab setup. See CLAUDE.md for more information about local customizations.
pip install -r requirements.txt
Config file location:
%APPDATA%\Claude\claude_desktop_config.json~/Library/Application Support/Claude/claude_desktop_config.json~/.config/Claude/claude_desktop_config.jsonOption A: Unified Server (Recommended)
Single entry for all homelab servers:
{
"mcpServers": {
"homelab-unified": {
"command": "python",
"args": ["C:\\Path\\To\\Homelab-MCP\\homelab_unified_mcp.py"],
"env": {
"ANSIBLE_INVENTORY_PATH": "C:\\Path\\To\\ansible_hosts.yml"
}
}
}
}
Note: The unified server includes 7 MCP servers: Ansible, Docker/Podman, Ollama, Pi-hole, Unifi, UPS, and Ping. The deprecated mcp-registry-inspector is not included.
Option B: Individual Servers (Legacy)
Separate entry for each server:
{
"mcpServers": {
"docker": {
"command": "python",
"args": ["C:\\Path\\To\\Homelab-MCP\\docker_mcp_podman.py"],
"env": {
"ANSIBLE_INVENTORY_PATH": "C:\\Path\\To\\ansible_hosts.yml"
}
},
"ollama": {
"command": "python",
"args": ["C:\\Path\\To\\Homelab-MCP\\ollama_mcp.py"],
"env": {
"ANSIBLE_INVENTORY_PATH": "C:\\Path\\To\\ansible_hosts.yml"
}
},
"pihole": {
"command": "python",
"args": ["C:\\Path\\To\\Homelab-MCP\\pihole_mcp.py"],
"env": {
"ANSIBLE_INVENTORY_PATH": "C:\\Path\\To\\ansible_hosts.yml"
}
},
"unifi": {
"command": "python",
"args": ["C:\\Path\\To\\Homelab-MCP\\unifi_mcp_optimized.py"],
"env": {
"ANSIBLE_INVENTORY_PATH": "C:\\Path\\To\\ansible_hosts.yml"
}
},
"ping": {
"command": "python",
"args": ["C:\\Path\\To\\Homelab-MCP\\ping_mcp_server.py"],
"env": {
"ANSIBLE_INVENTORY_PATH": "C:\\Path\\To\\ansible_hosts.yml"
}
},
"ups-monitor": {
"command": "python",
"args": ["C:\\Path\\To\\Homelab-MCP\\ups_mcp_server.py"],
"env": {
"ANSIBLE_INVENTORY_PATH": "C:\\Path\\To\\ansible_hosts.yml"
}
}
}
}
Note: Tool names differ between modes. See MIGRATION_V3.md for details. The deprecated mcp-registry-inspector has been removed from this example. Ansible MCP server integration is tracked in #39.
PROJECT_INSTRUCTIONS.mdRun the MCP servers in Docker containers for easier distribution, isolation, and production deployment.
Docker Hub: bjeans/homelab-mcp
Pre-built images are automatically published to Docker Hub with multi-platform support (amd64/arm64):
# Pull the latest image
docker pull bjeans/homelab-mcp:latest
# Run with your Ansible inventory
docker run -d \
--name homelab-mcp \
--network host \
-v $(pwd)/ansible_hosts.yml:/config/ansible_hosts.yml:ro \
bjeans/homelab-mcp:latest
# Or use a specific commit
docker pull bjeans/homelab-mcp:main-17bae01
Available on Docker Hub: https://hub.docker.com/r/bjeans/homelab-mcp/tags
Currently available tags:
latest - Latest stable release from main branch (recommended)edge - Latest development build from main branchmain-<git-sha> - Specific commit builds for traceability (e.g., main-17bae01)Semantic version tags (available after release):
2.2.0, 2.2, 2 will be created when the v2.2.0 Git release is publishedlatest for the most recent stable buildMulti-platform support:
linux/amd64 - x86_64 servers and workstationslinux/arm64 - Raspberry Pi, ARM-based systemsBuild the image locally if you need to customize:
# Pull the pre-built image from Docker Hub (recommended)
docker pull bjeans/homelab-mcp:latest
# Run with Docker Compose (recommended for production)
docker-compose up -d
# Or run unified server directly
docker run -d \
--name homelab-mcp \
--network host \
-v $(pwd)/ansible_hosts.yml:/config/ansible_hosts.yml:ro \
bjeans/homelab-mcp:latest
Building from source (optional):
# Clone and navigate to repository
git clone https://github.com/bjeans/homelab-mcp
cd homelab-mcp
# Build the image locally
docker build -t homelab-mcp:latest .
2.0.0 Docker Improvements:
Method 1: Ansible Inventory (Recommended)
# Create your ansible_hosts.yml with infrastructure details
# Then mount as volume:
docker run -d \
--name homelab-mcp \
--network host \
-v $(pwd)/ansible_hosts.yml:/config/ansible_hosts.yml:ro \
bjeans/homelab-mcp:latest
Method 2: Environment Variables (Marketplace Ready)
docker run -d \
--name homelab-mcp \
--network host \
-e DOCKER_SERVER1_ENDPOINT=192.168.1.100:2375 \
-e DOCKER_SERVER1_NAME=Local-Docker \
-e OLLAMA_SERVER1_ENDPOINT=192.168.1.100:11434 \
bjeans/homelab-mcp:latest
For backward compatibility, you can still run individual servers by setting ENABLED_SERVERS:
docker run -d \
--name homelab-mcp-docker \
--network host \
-e ENABLED_SERVERS=docker \
-v $(pwd)/ansible_hosts.yml:/config/ansible_hosts.yml:ro \
bjeans/homelab-mcp:latest
Unified Mode (Default):
ansible_get_all_hosts, docker_get_containers, ups_get_ups_status)Legacy Mode (Set ENABLED_SERVERS):
ansible - Ansible inventory queriesdocker - Docker/Podman container managementping - Network ping utilitiesollama - Ollama AI model managementpihole - Pi-hole DNS statisticsunifi - Unifi network device monitoringups - UPS/NUT power monitoringTwo configuration methods supported:
-e flagsSee DOCKER.md for comprehensive Docker deployment guide including:
Unified Mode (Recommended):
{
"mcpServers": {
"homelab-unified": {
"command": "docker",
"args": ["exec", "-i", "homelab-mcp", "python", "homelab_unified_mcp.py"]
}
}
}
Legacy Mode (Individual Servers):
{
"mcpServers": {
"homelab-docker": {
"command": "docker",
"args": ["exec", "-i", "homelab-mcp-docker", "python", "docker_mcp_podman.py"]
},
"homelab-ping": {
"command": "docker",
"args": ["exec", "-i", "homelab-mcp", "python", "ping_mcp_server.py"]
}
}
}
Important: Use docker exec -i (not -it) for proper MCP stdio communication.
Quick verification test (using environment variables - marketplace ready):
# Test Unified Server
docker run --rm --network host \
-e DOCKER_SERVER1_ENDPOINT=localhost:2375 \
-e OLLAMA_SERVER1_ENDPOINT=localhost:11434 \
bjeans/homelab-mcp:latest
# Test Individual Server (legacy)
docker run --rm --network host \
-e ENABLED_SERVERS=ping \
bjeans/homelab-mcp:latest
Docker Compose testing:
docker-compose up -d
docker-compose logs -f
For comprehensive Docker deployment guide, see DOCKER.md.
When you configure Ansible inventory, Claude Desktop will automatically show your infrastructure options in dropdown menus. No more guessing hostnames or group names!
What gets auto-populated:
How it works:
ANSIBLE_INVENTORY_PATH in your .env fileImportant Notes:
Example before/after:
Before: "Which group should I ping?" → User manually types "webservers" (or guesses)
After: "Which group should I ping?" → User selects from dropdown: all, docker_hosts, webservers, databases, etc.
Troubleshooting:
ANSIBLE_INVENTORY_PATH is set and restart Claude DesktopDeprecation Notice (v2.3.0): This tool is deprecated. Claude Desktop now has native file system access, making this MCP server unnecessary. You can simply ask Claude to read your MCP server files or configuration directly.
Replacement: Use Claude's built-in file access:
For users with existing configurations: This server will continue to work but will not receive updates. It will be removed from documentation in v3.0.0. Consider removing it from your claude_desktop_config.json.
Tools:
get_claude_config - View Claude Desktop MCP configurationlist_mcp_servers - List all registered MCP serverslist_mcp_directory - Browse MCP development directoryread_mcp_file - Read MCP server source codewrite_mcp_file - Write/update MCP server filessearch_mcp_files - Search for files by nameConfiguration:
MCP_DIRECTORY=/path/to/your/Homelab-MCP
CLAUDE_CONFIG_PATH=/path/to/claude_desktop_config.json # Optional
Manage Docker and Podman containers across multiple hosts.
🔒 Security Warning: Docker/Podman APIs typically use unencrypted HTTP without authentication. See SECURITY.md for required firewall configuration.
Tools:
Individual server mode:
get_docker_containers - Get containers on a specific hostget_all_containers - Get all containers across all hostsget_container_stats - Get CPU and memory statscheck_container - Check if a specific container is runningfind_containers_by_label - Find containers by labelget_container_labels - Get all labels for a containerUnified server mode (namespaced):
docker_get_containers - Get containers on a specific hostdocker_get_all_containers - Get all containers across all hostsdocker_get_container_stats - Get CPU and memory statsdocker_check_container - Check if a specific container is runningdocker_find_containers_by_label - Find containers by labeldocker_get_container_labels - Get all labels for a containerConfiguration Options:
Option 1: Using Ansible Inventory (Recommended)
ANSIBLE_INVENTORY_PATH=/path/to/ansible_hosts.yml
# Ansible inventory group names (default: docker_hosts, podman_hosts)
# Change these if you use different group names in your ansible_hosts.yml
DOCKER_ANSIBLE_GROUP=docker_hosts
PODMAN_ANSIBLE_GROUP=podman_hosts
Option 2: Using Environment Variables
DOCKER_SERVER1_ENDPOINT=192.168.1.100:2375
DOCKER_SERVER2_ENDPOINT=192.168.1.101:2375
PODMAN_SERVER1_ENDPOINT=192.168.1.102:8080
Monitor and manage Ollama AI model instances across your homelab, plus check your LiteLLM proxy for unified API access.
Ollama Monitoring:
LiteLLM Proxy Integration:
Why use LiteLLM?
http://192.0.2.10:4000) for all modelsTools:
get_ollama_status - Check status of all Ollama instances and model countsget_ollama_models - Get detailed model list for a specific hostget_litellm_status - Verify LiteLLM proxy is online and respondingConfiguration Options:
Option 1: Using Ansible Inventory (Recommended)
ANSIBLE_INVENTORY_PATH=/path/to/ansible_hosts.yml
OLLAMA_PORT=11434 # Default Ollama port
# Ansible inventory group name (default: ollama_servers)
# Change this if you use a different group name in your ansible_hosts.yml
OLLAMA_INVENTORY_GROUP=ollama_servers
# LiteLLM Configuration
LITELLM_HOST=192.168.1.100 # Host running LiteLLM proxy
LITELLM_PORT=4000 # LiteLLM proxy port (default: 4000)
Option 2: Using Environment Variables
# Ollama Instances
OLLAMA_SERVER1=192.168.1.100
OLLAMA_SERVER2=192.168.1.101
OLLAMA_WORKSTATION=192.168.1.150
# LiteLLM Proxy
LITELLM_HOST=192.168.1.100
LITELLM_PORT=4000
Setting Up LiteLLM (Optional):
If you want to use LiteLLM for unified access to your Ollama instances:
Install LiteLLM on one of your servers:
pip install litellm[proxy]
Create configuration (litellm_config.yaml):
model_list:
- model_name: llama3.2
litellm_params:
model: ollama/llama3.2
api_base: http://server1:11434
- model_name: llama3.2
litellm_params:
model: ollama/llama3.2
api_base: http://server2:11434
router_settings:
routing_strategy: usage-based-routing
Start LiteLLM proxy:
litellm --config litellm_config.yaml --port 4000
Use the MCP tool to verify it's running:
Example Usage:
Monitor Pi-hole DNS statistics and status.
🔒 Security Note: Store Pi-hole API keys securely in .env file. Generate unique keys per instance.
Tools:
get_pihole_stats - Get DNS statistics from all Pi-hole instancesget_pihole_status - Check which Pi-hole instances are onlineConfiguration Options:
Option 1: Using Ansible Inventory (Recommended)
ANSIBLE_INVENTORY_PATH=/path/to/ansible_hosts.yml
# Ansible inventory group name (default: PiHole)
# Change this if you use a different group name in your ansible_hosts.yml
PIHOLE_ANSIBLE_GROUP=PiHole
# API keys still required in .env:
PIHOLE_API_KEY_SERVER1=your-api-key-here
PIHOLE_API_KEY_SERVER2=your-api-key-here
Option 2: Using Environment Variables
PIHOLE_API_KEY_SERVER1=your-api-key
PIHOLE_API_KEY_SERVER2=your-api-key
PIHOLE_SERVER1_HOST=pihole1.local
PIHOLE_SERVER1_PORT=80
PIHOLE_SERVER2_HOST=pihole2.local
PIHOLE_SERVER2_PORT=8053
Getting Pi-hole API Keys:
pihole -a -p on Pi-hole serverMonitor Unifi network infrastructure and clients with caching for performance.
🔒 Security Note: Use a dedicated API key with minimal required permissions.
Tools:
get_network_devices - Get all network devices (switches, APs, gateways)get_network_clients - Get all active network clientsget_network_summary - Get network overviewrefresh_network_data - Force refresh from controller (bypasses cache)Configuration:
UNIFI_API_KEY=your-unifi-api-key
UNIFI_HOST=192.168.1.1
Note: Data is cached for 5 minutes to improve performance. Use refresh_network_data to force update.
Query Ansible inventory information (read-only). Available in both unified and standalone modes.
Unified Mode Tools (with ansible_ prefix):
ansible_get_all_hosts - Get all hosts in inventoryansible_get_all_groups - Get all groupsansible_get_host_details - Get detailed host informationansible_get_group_details - Get detailed group informationansible_get_hosts_by_group - Get hosts in specific groupansible_search_hosts - Search hosts by pattern or variableansible_get_inventory_summary - High-level inventory overviewansible_reload_inventory - Reload inventory from diskStandalone Mode Tools (without prefix):
get_all_hosts - Get all hosts in inventoryget_all_groups - Get all groupsget_host_details - Get detailed host informationget_group_details - Get detailed group informationget_hosts_by_group - Get hosts in specific groupsearch_hosts - Search hosts by pattern or variableget_inventory_summary - High-level inventory overviewreload_inventory - Reload inventory from diskConfiguration:
ANSIBLE_INVENTORY_PATH=/path/to/ansible_hosts.yml
Deployment:
python ansible_mcp_server.pyTest network connectivity and host availability using ICMP ping across your infrastructure.
Why use this?
Tools:
ping_host - Ping a single host by name (resolved from Ansible inventory)ping_group - Ping all hosts in an Ansible group concurrentlyping_all - Ping all infrastructure hosts concurrentlylist_groups - List available Ansible groups for ping operationsFeatures:
ping command (no extra libraries needed)Configuration:
ANSIBLE_INVENTORY_PATH=/path/to/ansible_hosts.yml
# No additional API keys required!
Example Usage:
When to use:
Monitor UPS (Uninterruptible Power Supply) devices across your infrastructure using Network UPS Tools (NUT) protocol.
Why use this?
Tools:
get_ups_status - Check status of all UPS devices across all NUT serversget_ups_details - Get detailed information for a specific UPS deviceget_battery_runtime - Get battery runtime estimates for all UPS devicesget_power_events - Check for recent power events (on battery, low battery)list_ups_devices - List all UPS devices configured in inventoryreload_inventory - Reload Ansible inventory after changesFeatures:
Configuration:
Option 1: Using Ansible Inventory (Recommended)
ANSIBLE_INVENTORY_PATH=/path/to/ansible_hosts.yml
# Default NUT port (optional, defaults to 3493)
NUT_PORT=3493
# NUT authentication (optional - only if your NUT server requires it)
NUT_USERNAME=monuser
NUT_PASSWORD=secret
Ansible inventory example:
nut_servers:
hosts:
dell-server.example.local:
ansible_host: 192.168.1.100
nut_port: 3493
ups_devices:
- name: tripplite
description: "TrippLite SMART1500LCDXL"
Option 2: Using Environment Variables
NUT_PORT=3493
NUT_USERNAME=monuser
NUT_PASSWORD=secret
Prerequisites:
Install NUT on servers with UPS devices:
# Debian/Ubuntu
sudo apt install nut nut-client nut-server
# RHEL/Rocky/CentOS
sudo dnf install nut nut-client
Configure NUT daemon (/etc/nut/ups.conf):
[tripplite]
driver = usbhid-ups
port = auto
desc = "TrippLite SMART1500LCDXL"
Enable network monitoring (/etc/nut/upsd.conf):
LISTEN 0.0.0.0 3493
Configure access (/etc/nut/upsd.users):
[monuser]
password = secret
upsmon master
Start NUT services:
sudo systemctl enable nut-server nut-client
sudo systemctl start nut-server nut-client
Example Usage:
When to use:
Common UPS Status Codes:
OL - Online (normal operation, AC power present)OB - On Battery (power outage, running on battery)LB - Low Battery (critically low battery, shutdown imminent)CHRG - Charging (battery is charging)RB - Replace Battery (battery needs replacement)This project includes automated security validation to prevent accidental exposure of sensitive data:
Install the pre-push git hook (recommended):
# From project root
python helpers/install_git_hook.py
What it does:
helpers/pre_publish_check.py before every git pushManual security check:
# Run security validation manually
python helpers/pre_publish_check.py
Bypass security check (use with extreme caution):
# Only when absolutely necessary
git push --no-verify
Configuration Files:
.env.example as a template.env file permissions restrictive (chmod 600 on Linux/Mac).env to version controlansible_hosts.yml with real infrastructurePROJECT_INSTRUCTIONS.md with real network topologyAPI Security:
Network Security:
For detailed security guidance, see SECURITY.md
Install via requirements.txt:
pip install -r requirements.txt
Core dependencies:
mcp - Model Context Protocol SDKaiohttp - Async HTTP clientpyyaml - YAML parsing for Ansible inventoryDeveloped and tested on:
Windows: Fully tested and supported ✅ macOS: Should work but untested ⚠️ Linux: Should work but untested ⚠️
Known platform differences:
.env file permissions should be set on Unix (chmod 600 .env)Contributions for other platforms welcome!
📖 First time contributing? Read CLAUDE.md for complete development guidance including architecture patterns, security requirements, and AI assistant workflows.
Install security git hook (required for contributors):
python helpers/install_git_hook.py
Set up development environment:
pip install -r requirements.txt
cp .env.example .env
# Edit .env with your test values
Before submitting a PR, test your MCP server changes locally using the MCP Inspector tool.
Quick start:
# MCP Inspector is an optional Node.js tool for interactive testing
# Option 1: Use npx (no installation needed - recommended)
npx @modelcontextprotocol/inspector uv --directory . run <server>_mcp.py
# Option 2: Install globally first (one-time setup)
npm install -g @modelcontextprotocol/inspector
# Then run: mcp-inspector uv --directory . run <server>_mcp.py
This opens a web-based debugger at http://localhost:5173 where you can:
For detailed testing instructions, see the Testing MCP Servers Locally section in CONTRIBUTING.md.
The helpers/ directory contains utility scripts for development and deployment:
install_git_hook.py - Installs git pre-push hook for automatic security checkspre_publish_check.py - Security validation script (runs automatically via git hook)Usage:
# Install security git hook
python helpers/install_git_hook.py
# Run security check manually
python helpers/pre_publish_check.py
Homelab-MCP/
├── MCP Servers (7 production servers)
│ ├── ansible_mcp_server.py # Ansible inventory queries (integration in progress)
│ ├── docker_mcp_podman.py # Docker/Podman container monitoring
│ ├── ollama_mcp.py # Ollama AI model management
│ ├── pihole_mcp.py # Pi-hole DNS monitoring
│ ├── ping_mcp_server.py # Network connectivity testing
│ ├── unifi_mcp_optimized.py # Unifi network device monitoring
│ └── ups_mcp_server.py # UPS/NUT monitoring
│
├── Unified Server & Core Modules
│ ├── homelab_unified_mcp.py # Combines all servers (Docker entrypoint)
│ ├── mcp_config_loader.py # Secure environment variable loading
│ ├── mcp_error_handler.py # Centralized error handling
│ └── ansible_config_manager.py # Ansible inventory + enum generation
│
├── Utilities & Deprecated Tools
│ ├── unifi_exporter.py # Unifi data export utility
│ └── mcp_registry_inspector.py # MCP file management (⚠️ DEPRECATED v2.3.0)
│
├── Configuration & Examples
│ ├── .env.example # Configuration template (gitignored)
│ ├── ansible_hosts.example.yml # Ansible inventory example (gitignored)
│ ├── PROJECT_INSTRUCTIONS.example.md # AI assistant guide template
│ └── CLAUDE_CUSTOM.example.md # Local customization template (gitignored)
│
├── Documentation
│ ├── README.md # This file - user documentation
│ ├── CLAUDE.md # AI assistant development guide
│ ├── SECURITY.md # Security guidelines
│ ├── CONTRIBUTING.md # Contribution guide
│ ├── CHANGELOG.md # Version history
│ ├── MIGRATION_V3.md # Version migration guide
│ ├── CONTEXT_AWARE_SECURITY.md # Security scanning docs
│ ├── CI_CD_CHECKS.md # CI/CD automation docs
│ └── LICENSE # MIT License
│
├── Docker Deployment
│ ├── Dockerfile # Container build configuration
│ ├── docker-compose.yml # Container orchestration (uses bjeans/homelab-mcp:latest)
│ └── docker-entrypoint.sh # Container startup script
│
├── Development Tools
│ ├── helpers/
│ │ ├── install_git_hook.py # Git pre-push hook installer
│ │ ├── pre_publish_check.py # Security validation
│ │ ├── run_checks.py # CI/CD check runner
│ │ └── requirements-dev.txt # Development dependencies
│ ├── requirements.txt # Production Python dependencies
│ └── .gitignore # Git ignore rules
Create the server file
#!/usr/bin/env python3
"""
My Service MCP Server
Description of what it does
"""
import asyncio
from mcp.server import Server
# ... implement tools ...
Add configuration to .env.example
# My Service Configuration
MY_SERVICE_HOST=192.168.1.100
MY_SERVICE_API_KEY=your-api-key
Update documentation
PROJECT_INSTRUCTIONS.example.mdCLAUDE.md if adding new patterns or capabilitiesTest thoroughly
All MCP servers support two configuration methods:
1. Environment Variables (.env file)
2. Ansible Inventory (recommended for production)
ANSIBLE_INVENTORY_PATH in .envBefore committing changes:
python helpers/install_git_hook.py)python helpers/pre_publish_check.py).gitignore updated if neededCheck Claude Desktop config:
# Windows
type %APPDATA%\Claude\claude_desktop_config.json
# Mac/Linux
cat ~/.config/Claude/claude_desktop_config.json
Verify Python path is correct in config
Restart Claude Desktop completely
Check logs - MCP servers log to stderr
Docker/Podman API:
# Test connectivity
curl http://your-host:2375/containers/json
# Check firewall
netstat -an | grep 2375
Pi-hole API:
# Test API key
curl "http://your-pihole/api/stats/summary?sid=YOUR_API_KEY"
Ollama:
# Test Ollama endpoint
curl http://your-host:11434/api/tags
Error Message Format (v2.2.0+):
All MCP servers now provide detailed, actionable error messages in this format:
✗ [Service] [Error Type] (HTTP Status)
[Specific problem description]
Host: [hostname:port]
→ [Actionable remediation steps]
Technical details: [error details] (timestamp)
Common Error Types:
Example:
✗ Pi-hole Authentication Failed (401)
Invalid API key for pi-hole-1
Host: 192.168.1.5:80
→ Verify PIHOLE_API_KEY_PI_HOLE_1 in .env matches your Pi-hole admin password.
→ You can find/reset this in Pi-hole Settings > API.
How to Fix:
.env file for the correct API key variableExample:
✗ Unifi Connection Failed
Unable to connect to unifi-controller:443
Host: unifi-controller:443
→ Ensure Unifi controller is running and accessible at unifi-controller:443.
→ Test connectivity: nc -zv unifi-controller 443
→ Check firewall: sudo iptables -L | grep 443
How to Fix:
systemctl status [service-name]nc or telnetExample:
✗ Ollama Timeout
Connection to ollama-1:11434 timed out (after 5s)
Host: ollama-1:11434
→ The service is not responding. Check if Ollama is running and not overloaded.
→ Check service status and logs for performance issues.
How to Fix:
systemctl status ollamaping [hostname]Example:
✗ Service Authorization Failed (403)
Valid credentials but insufficient permissions
→ Ensure the API key/account has the required permissions for this operation.
How to Fix:
Before (v2.1.0):
Error: Exporter failed with code 1
After (v2.2.0):
✗ Unifi Authentication Failed
Invalid Unifi API key for unifi-controller
Host: unifi-controller
→ Verify UNIFI_API_KEY in .env matches the API key from Unifi Settings > Admins > API.
→ Ensure the key has not expired.
Technical details: 401 Unauthorized (at 2025-11-20T10:30:45Z)
How to Fix:
UNIFI_API_KEY in .env fileHow to Fix:
Enable Detailed Logging:
All errors are logged to stderr with full context. Check Claude Desktop logs:
%APPDATA%\Claude\logs\~/Library/Logs/Claude/~/.config/Claude/logs/Test API Endpoints Directly:
Use curl or httpie to test API endpoints outside of MCP:
# Pi-hole
curl "http://pi-hole:80/api/stats/summary?sid=YOUR_API_KEY"
# Docker
curl http://docker-host:2375/containers/json
# Unifi (requires SSL and API key)
curl -k -H "X-API-KEY: YOUR_KEY" https://unifi:443/api/stat/sta
# Ollama
curl http://ollama:11434/api/tags
# NUT (Network UPS Tools)
telnet nut-server 3493
> LIST UPS
Check Configuration:
# Verify .env file exists and is readable
ls -la .env
# Check for syntax errors in .env
cat .env | grep -v '^#' | grep -v '^$'
# Verify Ansible inventory
ansible-inventory -i ansible_hosts.yml --list
If you get Python import errors:
# Reinstall dependencies
pip install --upgrade -r requirements.txt
# Verify MCP installation
pip show mcp
On Linux/Mac:
# Fix .env permissions
chmod 600 .env
# Make scripts executable
chmod +x *.py
MIT License - See LICENSE file for details
Copyright (c) 2025 Barnaby Jeans
Contributions are welcome! Please see CONTRIBUTING.md for detailed guidelines.
📖 Read CLAUDE.md first - This file contains:
python helpers/install_git_hook.py)git checkout -b feature/amazing-feature)git commit -m 'Add amazing feature')git push origin feature/amazing-feature)Remember: This project handles critical infrastructure. Always prioritize security and test changes in a safe environment first!
MCP server integration for DaVinci Resolve Studio
mcp-language-server gives MCP enabled clients access semantic tools like get definition, references, rename, and diagnos
Run Claude Code as an MCP server so any agent can delegate coding tasks to it
Browser automation using accessibility snapshots instead of screenshots