docs(onboarding): improve new user experience + fix OpenPanel tools

- Add DOCKER_README.md for Docker Hub overview page
- Fix docker-compose.yaml port mapping for local users ("8000:8000")
- Add "Verify It Works" section with dashboard URL to README
- Restructure env.example with clear REQUIRED section
- Add post-Docker verification checklist to getting-started.md
- Fix 4 OpenPanel tools: parameter ordering (non-default before default)
- Rebrand all "Coolify Projects" to "MCP Hub" in server and Dockerfile
- Make MCP namespace prefix stripping generic

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
airano
2026-02-18 02:22:48 +03:30
parent 58aa0684b2
commit 3a3f04aca8
6 changed files with 241 additions and 61 deletions

124
DOCKER_README.md Normal file
View File

@@ -0,0 +1,124 @@
# MCP Hub
**The AI-native management hub for WordPress, WooCommerce, and self-hosted services.**
589 tools across 9 plugins. Connect your sites, stores, repos, and databases — manage them all through Claude, ChatGPT, Cursor, or any MCP client.
## Quick Start
### 1. Create a `.env` file
```bash
# Required
MASTER_API_KEY=your-secure-key-here
# Add at least one WordPress site
WORDPRESS_SITE1_URL=https://your-site.com
WORDPRESS_SITE1_USERNAME=admin
WORDPRESS_SITE1_APP_PASSWORD=xxxx xxxx xxxx xxxx
WORDPRESS_SITE1_ALIAS=mysite
```
### 2. Run the container
```bash
docker run -d \
--name mcphub \
-p 8000:8000 \
--env-file .env \
airano/mcphub:latest
```
### 3. Verify it works
```bash
# Health check (wait ~30 seconds for startup)
curl http://localhost:8000/health
# Open the web dashboard
# http://localhost:8000/dashboard
```
### 4. Connect your AI client
In Claude Desktop's `claude_desktop_config.json`:
```json
{
"mcpServers": {
"mcphub": {
"url": "http://localhost:8000/mcp",
"headers": {
"Authorization": "Bearer your-secure-key-here"
}
}
}
}
```
## Using Docker Compose
```yaml
services:
mcphub:
image: airano/mcphub:latest
ports:
- "8000:8000"
env_file:
- .env
volumes:
- mcphub-data:/app/data
- mcphub-logs:/app/logs
restart: unless-stopped
volumes:
mcphub-data:
mcphub-logs:
```
```bash
docker compose up -d
```
## After Starting
| URL | Description |
|-----|-------------|
| `http://localhost:8000/health` | Health check & status |
| `http://localhost:8000/dashboard` | Web dashboard (manage API keys, view sites, health) |
| `http://localhost:8000/mcp` | MCP endpoint (connect AI clients here) |
## Environment Variables
| Variable | Required | Description |
|----------|----------|-------------|
| `MASTER_API_KEY` | **Yes** | API key for authentication |
| `WORDPRESS_SITE1_URL` | For WP | WordPress site URL |
| `WORDPRESS_SITE1_USERNAME` | For WP | WordPress admin username |
| `WORDPRESS_SITE1_APP_PASSWORD` | For WP | WordPress Application Password |
| `WORDPRESS_SITE1_ALIAS` | Recommended | Friendly name (e.g., `myblog`) |
| `OAUTH_JWT_SECRET_KEY` | For OAuth | JWT secret for ChatGPT/Claude auto-registration |
| `OAUTH_BASE_URL` | For OAuth | Public URL of your server |
Add more sites with `SITE2`, `SITE3`, etc. See [full configuration guide](https://github.com/airano-ir/mcphub/blob/main/docs/getting-started.md).
## Supported Plugins
| Plugin | Tools | Env Prefix |
|--------|-------|------------|
| WordPress | 67 | `WORDPRESS_` |
| WooCommerce | 28 | `WOOCOMMERCE_` |
| WordPress Advanced | 22 | `WORDPRESS_` |
| Gitea | 56 | `GITEA_` |
| n8n | 56 | `N8N_` |
| Supabase | 70 | `SUPABASE_` |
| OpenPanel | 73 | `OPENPANEL_` |
| Appwrite | 100 | `APPWRITE_` |
| Directus | 100 | `DIRECTUS_` |
## Links
- **GitHub**: [github.com/airano-ir/mcphub](https://github.com/airano-ir/mcphub)
- **PyPI**: [pypi.org/project/mcphub-server](https://pypi.org/project/mcphub-server/)
- **Documentation**: [Getting Started Guide](https://github.com/airano-ir/mcphub/blob/main/docs/getting-started.md)
- **License**: MIT

View File

@@ -1,5 +1,5 @@
# ===================================
# Coolify Projects MCP Server - Dockerfile
# MCP Hub — Dockerfile
# ===================================
# Multi-stage build for optimized image size
# Production-ready with security best practices

View File

@@ -72,14 +72,15 @@ MCP Hub is the first MCP server that lets you manage WordPress, WooCommerce, and
git clone https://github.com/airano-ir/mcphub.git
cd mcphub
cp env.example .env
# Edit .env with your site credentials
# Edit .env — set MASTER_API_KEY and add your site credentials
docker compose up -d
```
### Option 2: PyPI
### Option 2: Docker Hub (No Clone)
```bash
pip install mcphub-server
# Create a .env file with your credentials (see "Configure Your Sites" below)
docker run -d --name mcphub -p 8000:8000 --env-file .env airano/mcphub:latest
```
### Option 3: From Source
@@ -93,6 +94,19 @@ cp env.example .env
python server.py --transport sse --port 8000
```
### Verify It Works
After starting the server, wait ~30 seconds then:
```bash
# Check server health
curl http://localhost:8000/health
```
Open the **web dashboard** in your browser: **http://localhost:8000/dashboard**
You should see the login page. Use your `MASTER_API_KEY` to log in.
### Configure Your Sites
Add site credentials to `.env`:

View File

@@ -1,17 +1,16 @@
# ===================================
# MCP Hub — Docker Compose Configuration
# ===================================
#
# Build Pack: Docker Compose
# ⚠️ CRITICAL RULES FOR COOLIFY:
# 1. NO host port mappings: Use "8000" NOT "8000:8000"
# 2. Listen on 0.0.0.0 (NOT localhost)
# 3. Health checks for ALL services
# 4. Use environment variables for ALL configs
#
# After starting:
# docker compose up -d
# curl http://localhost:8000/health # verify server is running
# open http://localhost:8000/dashboard # web dashboard
#
# For Coolify deployments:
# Change ports to "8000" (no host mapping) — Coolify handles routing.
# ===================================
version: '3.8'
services:
mcp-server:
build:
@@ -19,11 +18,9 @@ services:
dockerfile: Dockerfile
container_name: mcphub
restart: unless-stopped
# ⚠️ CRITICAL: Only container port (NO host port mapping)
# Coolify will handle routing via domain
ports:
- "8000"
- "8000:8000"
# Environment variables
environment:

View File

@@ -48,14 +48,18 @@ For each WordPress site you want to manage:
git clone https://github.com/airano-ir/mcphub.git
cd mcphub
cp env.example .env
# Edit .env with your site credentials
# Edit .env — set MASTER_API_KEY and add your site credentials (see Configuration below)
docker compose up -d
```
### Option 2: PyPI
After starting, see [Verify Installation](#verify-installation) below.
### Option 2: Docker Hub (No Clone)
```bash
pip install mcphub-server
# 1. Create a .env file (see Configuration section below)
# 2. Run:
docker run -d --name mcphub -p 8000:8000 --env-file .env airano/mcphub:latest
```
### Option 3: From Source
@@ -190,22 +194,48 @@ python server.py --transport sse --port 8000
python server.py
```
### Verify Server is Running
### Verify Installation
Check logs for:
After starting (via Docker or locally), wait ~30 seconds for the server to initialize, then:
```
INFO: MCP Hub initialized
INFO: Registered 589 tools
INFO: Server ready
```
Or test the health endpoint:
**1. Check health:**
```bash
curl http://localhost:8000/health
# Expected: {"status": "ok", "tools_loaded": 589, ...}
```
**2. Open the web dashboard:**
Open **http://localhost:8000/dashboard** in your browser. Log in with your `MASTER_API_KEY`.
The dashboard lets you:
- View all connected sites and their health status
- Create and manage per-project API keys
- View audit logs
- Monitor rate limits
**3. Check container status (Docker only):**
```bash
docker compose ps
# Look for Status: "Up (healthy)"
# Note: Health check starts after 40 seconds — "starting" is normal initially
# View logs if something is wrong:
docker compose logs -f mcphub
```
**4. Troubleshooting:**
| Problem | Solution |
|---------|----------|
| Container exits immediately | Check logs: `docker compose logs mcphub` |
| Port 8000 already in use | Change port in docker-compose.yaml: `"8001:8000"` |
| Health check shows "unhealthy" | Wait 60 seconds, then check logs for startup errors |
| Dashboard login fails | Make sure you're using the `MASTER_API_KEY` value from your `.env` |
| Sites not showing up | Restart after adding new env vars: `docker compose restart` |
---
## Connect Your AI Client
@@ -334,34 +364,40 @@ Use specific endpoints to limit tool access:
docker compose up -d
```
After starting, verify the installation:
```bash
curl http://localhost:8000/health # server health
open http://localhost:8000/dashboard # web dashboard
```
See [Verify Installation](#verify-installation) for detailed steps.
### Docker Commands
```bash
# View logs
docker compose logs -f
docker compose logs -f mcphub
# Check status
# Check status (look for "healthy")
docker compose ps
# Restart
# Restart (needed after .env changes)
docker compose restart
# Stop
docker compose down
# Rebuild
# Rebuild (after code changes)
docker compose up --build -d
```
### Health Check
### Adding Sites After Startup
```bash
# Check container health
docker compose ps
# Test API endpoint
curl http://localhost:8000/health
```
1. Edit your `.env` file to add new site credentials
2. Restart the container: `docker compose restart`
3. Verify: `curl http://localhost:8000/health` — check that tools are loaded
4. The dashboard at http://localhost:8000/dashboard will show the new sites
---

View File

@@ -1,9 +1,9 @@
#!/usr/bin/env python3
"""
Coolify Projects MCP Server
MCP Hub Server
Universal MCP server for managing Coolify projects through plugins.
Supports WordPress, Supabase, Gitea, and custom project types.
Universal MCP server for managing self-hosted services through plugins.
Supports WordPress, WooCommerce, Gitea, n8n, Supabase, OpenPanel, Appwrite, and Directus.
Usage:
# With stdio transport (Claude Desktop)
@@ -228,7 +228,7 @@ if OAUTH_AUTH_MODE == "trusted_domains":
logger.info(f"OAuth Trusted Domains: {', '.join(OAUTH_TRUSTED_DOMAINS)}")
# Initialize MCP server
mcp = FastMCP("Coolify Projects Manager")
mcp = FastMCP("MCP Hub")
# Initialize Jinja2 templates (Phase E - OAuth Authorization Page)
templates = Jinja2Templates(directory="templates")
@@ -261,7 +261,7 @@ tool_registry = get_tool_registry()
tool_generator = ToolGenerator(site_manager)
logger.info("=" * 60)
logger.info("Coolify Projects MCP Server - Option B Clean Architecture")
logger.info("MCP Hub Server - Initialized")
logger.info("=" * 60)
_mk = auth_manager.get_master_key()
logger.info(f"Master API Key: {_mk[:8]}***{_mk[-4:]}")
@@ -471,10 +471,11 @@ def extract_plugin_type_from_tool(tool_name: str) -> str | None:
Returns:
Plugin type string or None for system tools
"""
# Remove MCP namespace prefix if present
# Remove MCP namespace prefix if present (e.g., "mcp__mcp-hub__wordpress_...")
clean_name = tool_name
if tool_name.startswith("mcp__coolify-projects__"):
clean_name = tool_name.replace("mcp__coolify-projects__", "")
if tool_name.startswith("mcp__") and "__" in tool_name[5:]:
# Strip "mcp__{server-name}__" prefix
clean_name = tool_name.split("__", 2)[-1]
# Check for plugin types (order matters - check more specific first)
# wordpress_advanced must be checked before wordpress
@@ -683,15 +684,15 @@ class UserAuthMiddleware(Middleware):
else:
# All plugin tools that have a 'site' parameter are unified tools
# They defer project access check to execution time
# Clean any MCP namespace prefix before checking
check_name = tool_name
if tool_name.startswith("mcp__") and "__" in tool_name[5:]:
check_name = tool_name.split("__", 2)[-1]
is_unified_tool = (
tool_name.startswith("wordpress_")
or tool_name.startswith("wordpress_advanced_")
or tool_name.startswith("woocommerce_")
or tool_name.startswith("gitea_")
or tool_name.startswith("mcp__coolify-projects__wordpress_")
or tool_name.startswith("mcp__coolify-projects__wordpress_advanced_")
or tool_name.startswith("mcp__coolify-projects__woocommerce_")
or tool_name.startswith("mcp__coolify-projects__gitea_")
check_name.startswith("wordpress_")
or check_name.startswith("wordpress_advanced_")
or check_name.startswith("woocommerce_")
or check_name.startswith("gitea_")
)
logger.debug(
@@ -992,9 +993,11 @@ class RateLimitMiddleware(Middleware):
tool_name = params.name if hasattr(params, "name") else "unknown"
# Determine plugin type from tool name
if tool_name.startswith("wordpress_") or tool_name.startswith(
"mcp__coolify-projects__wordpress_"
):
# Clean any MCP namespace prefix
tn = tool_name
if tool_name.startswith("mcp__") and "__" in tool_name[5:]:
tn = tool_name.split("__", 2)[-1]
if tn.startswith("wordpress_"):
plugin_type = "wordpress"
elif tool_name.startswith("woocommerce_"):
plugin_type = "woocommerce"
@@ -1540,6 +1543,12 @@ def create_dynamic_tool(name: str, description: str, handler, input_schema: dict
)
)
# Sort params: required (no default) first, then optional (with default).
# Python/inspect.Signature requires non-default args before default args.
required_first = [p for p in params if p.default is inspect.Parameter.empty]
optional_after = [p for p in params if p.default is not inspect.Parameter.empty]
params = required_first + optional_after
# Create signature
sig = inspect.Signature(params)
@@ -4313,7 +4322,7 @@ def main():
import uvicorn
# Parse command line arguments for transport configuration
parser = argparse.ArgumentParser(description="Coolify Projects MCP Server")
parser = argparse.ArgumentParser(description="MCP Hub Server")
parser.add_argument(
"--transport",
type=str,