MCP Hub

MCP Hub

A single MCP server that gives an AI assistant comprehensive access to manage a homelab, including SSH, Docker, Proxmox, Synology, Cloudflare, and more, with 85 tools and a centralized configuration.

Category
Visit Server

README

<p align="center"> <img src="mcp-hub.png" alt="MCP Hub" width="640"> </p>

MCP Hub

One MCP server that gives your AI assistant the keys to your whole homelab.

Release License: MIT Python 3.11+ MCP CI

MCP Hub is a single Model Context Protocol server that sits on one machine in your network and fans out from there: SSH to every host in your fleet, Proxmox containers, Docker, Synology DSM, Cloudflare tunnels and DNS, n8n workflows, Notion, your password vault. Instead of running a dozen MCP servers and wiring each one into your client, you run one and point your assistant at it.

"Why is Jellyfin unreachable?" — and the assistant checks the container, reads the journal, notices the tunnel ingress is stale, fixes it, and tells you what it did.

⚠️ Read SECURITY.md before you deploy this. MCP Hub hands an LLM root shell access across your fleet. That is the point of it, and it is genuinely dangerous. Defaults are safe (127.0.0.1, read-only); the danger starts when you change them.

Troubleshooting demo

The repository includes a sanitized Asciinema recording of a complete, observation-first troubleshooting session: failed endpoint, systemd diagnosis, exact mutation plan, explicit confirmation, restart, and final health checks. It uses the example inventory and contains no private infrastructure data.

asciinema play docs/troubleshooting.cast

See the recording directly when Asciinema is not installed; the cast format is newline-delimited JSON and remains reviewable.

Contents

Features

  • 103 tools, one endpoint, one config file.
  • Config-driven. Your network lives in hosts.yaml and .env. Nothing about your infrastructure is baked into the code.
  • Multiplexed SSH. Persistent control sockets, so fleet-wide commands take milliseconds rather than a TCP handshake each.
  • Optional integrations. Every integration is off by default and enabled with a single flag. Run it as a pure SSH fleet tool if that is all you want.
  • Pluggable secrets. Read credentials from the environment, or from a Bitwarden/Vaultwarden vault via bw serve.
  • Bearer-token authentication on top of an unguessable endpoint path.
  • Global read-only mode, on by default: one flag disables all 39 mutating tools, enforced centrally rather than tool by tool.
  • Automatic secret redaction in file reads and command output.
  • Background jobs with polling, logs, and a persistent SQLite state store.

Quick start

Requires Python 3.11+ and a Linux host with SSH access to the machines you want to manage.

git clone https://github.com/wnx82/mcp-hub.git
cd mcp-hub

python3 -m venv .venv && . .venv/bin/activate
pip install -e .

cp .env.example .env                  # then edit — see below
cp hosts.example.yaml hosts.yaml      # then edit: your fleet
chmod 600 .env hosts.yaml

python server.py

At minimum, set these two in .env:

MCP_SECRET_PATH=/$(openssl rand -hex 16)   # unguessable endpoint path
MCP_AUTH_TOKEN=$(openssl rand -hex 32)     # bearer token — the real auth

The server then listens on http://127.0.0.1:8000<MCP_SECRET_PATH>, with MCP_READ_ONLY=true. Point your MCP client at that URL and send Authorization: Bearer <MCP_AUTH_TOKEN>. Requests without the token get a 401; requests to any other path get a 404.

For a systemd deployment, sudo ./deploy/install.sh creates a dedicated mcphub user and SSH key, generates both secrets into /etc/default/mcp-hub, and installs the unit. It is idempotent and never overwrites existing config. See deploy/.

For a complete Claude Code setup, safe token handling, connection checks, a first read-only prompt, and the current Claude Desktop limitation, see Connect MCP Hub to Claude.

If you want your assistant to understand your private topology, host roles, change windows, and MCP operating rules without committing any of that data, start from PROJECT_INSTRUCTIONS.example.md and keep your customized PROJECT_INSTRUCTIONS.md local-only.

Deployment

MCP Hub supports three execution modes:

Mode Intended use Command Support level
Editable package Development and contributions pip install -e ".[dev]" then mcp-hub Supported for development
Direct source execution Quick local evaluation python server.py Supported, operator manages the process
systemd installation Persistent homelab deployment sudo ./deploy/install.sh Recommended for production

The Python package and direct execution use the current checkout and its virtualenv. They do not create a service account, SSH key, environment file, or restart policy. The systemd installer provisions those operational pieces, keeps local configuration intact when rerun, and installs Rescue outside the hub virtualenv.

Container images are not an official deployment target yet. The hub needs network access, an SSH identity, persistent state.db, and access to its local inventory; operators packaging it in a container must preserve those properties themselves.

See docs/docker-packaging.md for the current requirements and what an official image would need to guarantee before it could be recommended.

Local testing

For a contributor-focused checklist covering lint, unit tests, tool registration, generated docs, installer smoke tests, and a manual read-only run, see docs/testing-local.md.

Before opening a PR or publishing a branch, you can also run the local release readiness checks:

python3 scripts/check_repo_hygiene.py
python3 scripts/check_tool_annotations.py
python3 scripts/check_security_readiness.py

To wire the security readiness check into Git automatically on push:

./scripts/install_pre_push_hook.sh

Architecture

server.py remains the FastMCP composition root while domain code is moving incrementally into tools/. SSH command construction, Cloudflare paths and response extraction, DSM protocol metadata, inventory, and playbook builders are already isolated. tools/registry.py assigns extracted tools to a domain; that domain is included in each audit summary. New protocol logic should live in its domain module and must not import server.py.

Future integrations are prioritized in docs/integration-evaluation.md, including their least-privilege scope and promotion gates.

Rescue diagnostics

mcp-hub-rescue is a read-only local CLI designed to keep working when the main server cannot import or its virtualenv is broken. The systemd installer copies it to /opt/mcp-hub-rescue and runs it with the system Python, outside the MCP Hub process and virtualenv.

sudo mcp-hub-rescue doctor
sudo mcp-hub-rescue status
sudo mcp-hub-rescue health
sudo mcp-hub-rescue logs --lines 50
sudo mcp-hub-rescue validate-config

Results are structured JSON. Rescue never imports server.py, tools/*, MCP, or an optional integration, and this boundary is enforced by CI. The current commands only observe and diagnose; restart, repair, and rollback operations will be added separately with confirmation and last-known-good safeguards.

Configuration

All git-ignored — each has a tracked .example template:

File Purpose Required
.env Ports, auth, feature flags, API tokens yes
hosts.yaml Fleet inventory: hostnames, users, roles, tags yes
topology.yaml Curated overlay: guest mapping, recycled-IP traps, do-not-touch list no
endpoints.yaml HTTP health probes for endpoints_health no

A host entry is minimal by design:

hosts:
  nas:
    hostname: nas.example.lan
    user: admin
    role: storage
    tags: [nas, backup]
    mac: "aa:bb:cc:dd:ee:01"   # optional, enables wake_host()

Tags are how you address groups: fleet_exec(tag="backup", command="df -h"). For a copy-ready two-host inventory, start with docs/examples/hosts.minimal.yaml. The larger hosts.example.yaml demonstrates every supported host option.

Pair it with docs/examples/topology.guarded.yaml to map Proxmox guests, record stale-address traps, and surface infrastructure that must not be changed casually. The _do_not_touch entries are operational context for the assistant, not an enforced access-control boundary; use token profiles and host restrictions for technical enforcement.

Add docs/examples/endpoints.minimal.yaml to monitor always-on and intermittent HTTP services. Call endpoints_health() for the regular set, or endpoints_health(include_intermittent=true) to include services that may normally be powered off. Responses from 200 through 399 count as healthy; redirects are not followed.

The complete defaults, limits, integration settings, and secret-handling notes are in the environment variable reference.

Pair those tracked examples with a private, untracked PROJECT_INSTRUCTIONS.md so your assistant sees topology caveats, maintenance windows, naming conventions, and "do not touch" guidance that should not live in the repository.

Tool reference

Every tool returns the same top-level envelope:

{
  "ok": true,
  "data": {},
  "error": null,
  "duration_ms": 12,
  "host": "example",
  "request_id": "4d52b1f69b974b7784bf65dd",
  "tool": "system_info"
}

data contains the tool-specific payload. Security refusals and controlled exceptions use the same shape with ok: false, making chained calls and audit correlation predictable.

The central tool wrapper also bounds request size, calls per token, concurrent calls per target, repeated target failures, and mutation frequency. Defaults are documented in .env.example; limit refusals use the same response envelope and audit trail as every other call.

Group Tools
Fleet & shell list_hosts topology get_topology system_info get_system_info remote_exec local_exec fleet_exec batch_exec read_file service_ctl journal_query get_journal_entries apt_status list_package_updates ssh_reset_control wake_host dhcp_reservations endpoints_health infra_snapshot destroy_resource
Proxmox & containers proxmox_list list_proxmox_guests proxmox_ct_status proxmox_ct_exec ct_exec ct_write_file pbs_status docker_ps list_docker_containers docker_exec
Synology DSM dsm_health dsm_system_info dsm_storage dsm_shares dsm_packages dsm_package_control dsm_updates dsm_connections dsm_logs dsm_power dsm_file_list dsm_file_search dsm_download_list dsm_download_create dsm_download_control dsm_api dsm_relogin
Cloudflare cloudflare_tunnels_list list_cloudflare_tunnels cloudflare_tunnel_get cloudflare_tunnel_config_get cloudflare_tunnel_config_update cloudflare_dns_list cloudflare_dns_create cloudflare_dns_delete cf_ingress_dump get_cloudflare_tunnel_ingress cloudflare_api
n8n n8n_health n8n_list_workflows n8n_get_workflow n8n_activate_workflow n8n_deactivate_workflow n8n_list_executions n8n_get_execution n8n_call_webhook
Notion notion_search notion_get_page notion_create_page notion_update_page notion_archive_page notion_query_database notion_get_block_children notion_append_blocks notion_append_table_row notion_delete_block notion_reload_token
Vault vault_search vault_get_item vault_get_field vault_create_item vault_update_item vault_list_folders
LM Studio lmstudio_status lmstudio_load lmstudio_unload
Guided diagnostics diagnose_service diagnose_endpoint audit_host check_backup_chain
Jobs & introspection job_run job_status job_list job_logs mcp_health get_mcp_health mcp_stats get_mcp_stats audit_export plan_mutation confirm_mutation rollback_change

The complete generated tool reference expands every group into a table with each tool's exact signature and model-facing description. CI verifies it against the registered functions.

Guided diagnostics always stop after observation. They return evidence, assessment, and suggested next steps with correction_applied: false; check_backup_chain is a freshness and storage signal, not proof that a restore will succeed.

Security

MCP Hub is a remote code execution service by design. Before exposing it:

  • Keep the default 127.0.0.1 bind, or put it behind a tunnel with access policies.
  • Set MCP_AUTH_TOKEN — the secret URL path is obscurity, not authentication.
  • Leave MCP_READ_ONLY=true until you trust what your model does with it.
  • Keep the resource-guard defaults enabled, then tune them from observed audit traffic rather than disabling them.
  • Give it a dedicated SSH key and a minimal hosts.yaml.

Full threat model, hardening guide, and vulnerability reporting: SECURITY.md.

For a local pre-publish checklist and optional Git hook that catches common secret-leak mistakes before push, see scripts/check_security_readiness.py and scripts/install_pre_push_hook.sh.

Versioning

SemVer. Pre-1.0, breaking changes bump the minor — so read the Changed and Removed notes before upgrading one. _version.py is the single source of truth; the running server reports it via mcp-hub --version, in the MCP handshake, and in mcp_health.

Every release is documented in CHANGELOG.md, with security-relevant changes called out in their own section.

Contributing

Issues and pull requests are welcome — bug reports, new integrations, and documentation fixes especially. See CONTRIBUTING.md.

License

MIT © wnx82

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured