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 # Multi-stage build for optimized image size
# Production-ready with security best practices # 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 git clone https://github.com/airano-ir/mcphub.git
cd mcphub cd mcphub
cp env.example .env 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 docker compose up -d
``` ```
### Option 2: PyPI ### Option 2: Docker Hub (No Clone)
```bash ```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 ### Option 3: From Source
@@ -93,6 +94,19 @@ cp env.example .env
python server.py --transport sse --port 8000 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 ### Configure Your Sites
Add site credentials to `.env`: Add site credentials to `.env`:

View File

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

View File

@@ -48,14 +48,18 @@ For each WordPress site you want to manage:
git clone https://github.com/airano-ir/mcphub.git git clone https://github.com/airano-ir/mcphub.git
cd mcphub cd mcphub
cp env.example .env 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 docker compose up -d
``` ```
### Option 2: PyPI After starting, see [Verify Installation](#verify-installation) below.
### Option 2: Docker Hub (No Clone)
```bash ```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 ### Option 3: From Source
@@ -190,22 +194,48 @@ python server.py --transport sse --port 8000
python server.py 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:
``` **1. Check health:**
INFO: MCP Hub initialized
INFO: Registered 589 tools
INFO: Server ready
```
Or test the health endpoint:
```bash ```bash
curl http://localhost:8000/health 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 ## Connect Your AI Client
@@ -334,34 +364,40 @@ Use specific endpoints to limit tool access:
docker compose up -d 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 ### Docker Commands
```bash ```bash
# View logs # View logs
docker compose logs -f docker compose logs -f mcphub
# Check status # Check status (look for "healthy")
docker compose ps docker compose ps
# Restart # Restart (needed after .env changes)
docker compose restart docker compose restart
# Stop # Stop
docker compose down docker compose down
# Rebuild # Rebuild (after code changes)
docker compose up --build -d docker compose up --build -d
``` ```
### Health Check ### Adding Sites After Startup
```bash 1. Edit your `.env` file to add new site credentials
# Check container health 2. Restart the container: `docker compose restart`
docker compose ps 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
# Test API endpoint
curl http://localhost:8000/health
```
--- ---

View File

@@ -1,9 +1,9 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
""" """
Coolify Projects MCP Server MCP Hub Server
Universal MCP server for managing Coolify projects through plugins. Universal MCP server for managing self-hosted services through plugins.
Supports WordPress, Supabase, Gitea, and custom project types. Supports WordPress, WooCommerce, Gitea, n8n, Supabase, OpenPanel, Appwrite, and Directus.
Usage: Usage:
# With stdio transport (Claude Desktop) # 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)}") logger.info(f"OAuth Trusted Domains: {', '.join(OAUTH_TRUSTED_DOMAINS)}")
# Initialize MCP server # Initialize MCP server
mcp = FastMCP("Coolify Projects Manager") mcp = FastMCP("MCP Hub")
# Initialize Jinja2 templates (Phase E - OAuth Authorization Page) # Initialize Jinja2 templates (Phase E - OAuth Authorization Page)
templates = Jinja2Templates(directory="templates") templates = Jinja2Templates(directory="templates")
@@ -261,7 +261,7 @@ tool_registry = get_tool_registry()
tool_generator = ToolGenerator(site_manager) tool_generator = ToolGenerator(site_manager)
logger.info("=" * 60) logger.info("=" * 60)
logger.info("Coolify Projects MCP Server - Option B Clean Architecture") logger.info("MCP Hub Server - Initialized")
logger.info("=" * 60) logger.info("=" * 60)
_mk = auth_manager.get_master_key() _mk = auth_manager.get_master_key()
logger.info(f"Master API Key: {_mk[:8]}***{_mk[-4:]}") 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: Returns:
Plugin type string or None for system tools 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 clean_name = tool_name
if tool_name.startswith("mcp__coolify-projects__"): if tool_name.startswith("mcp__") and "__" in tool_name[5:]:
clean_name = tool_name.replace("mcp__coolify-projects__", "") # Strip "mcp__{server-name}__" prefix
clean_name = tool_name.split("__", 2)[-1]
# Check for plugin types (order matters - check more specific first) # Check for plugin types (order matters - check more specific first)
# wordpress_advanced must be checked before wordpress # wordpress_advanced must be checked before wordpress
@@ -683,15 +684,15 @@ class UserAuthMiddleware(Middleware):
else: else:
# All plugin tools that have a 'site' parameter are unified tools # All plugin tools that have a 'site' parameter are unified tools
# They defer project access check to execution time # 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 = ( is_unified_tool = (
tool_name.startswith("wordpress_") check_name.startswith("wordpress_")
or tool_name.startswith("wordpress_advanced_") or check_name.startswith("wordpress_advanced_")
or tool_name.startswith("woocommerce_") or check_name.startswith("woocommerce_")
or tool_name.startswith("gitea_") or check_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_")
) )
logger.debug( logger.debug(
@@ -992,9 +993,11 @@ class RateLimitMiddleware(Middleware):
tool_name = params.name if hasattr(params, "name") else "unknown" tool_name = params.name if hasattr(params, "name") else "unknown"
# Determine plugin type from tool name # Determine plugin type from tool name
if tool_name.startswith("wordpress_") or tool_name.startswith( # Clean any MCP namespace prefix
"mcp__coolify-projects__wordpress_" 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" plugin_type = "wordpress"
elif tool_name.startswith("woocommerce_"): elif tool_name.startswith("woocommerce_"):
plugin_type = "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 # Create signature
sig = inspect.Signature(params) sig = inspect.Signature(params)
@@ -4313,7 +4322,7 @@ def main():
import uvicorn import uvicorn
# Parse command line arguments for transport configuration # 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( parser.add_argument(
"--transport", "--transport",
type=str, type=str,