diff --git a/CLAUDE.md b/CLAUDE.md
index 92f4648..9ac1008 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -179,7 +179,7 @@ Types: `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore`
- Test files exist in both `tests/` (proper) and root directory (legacy `test_*.py`). Run `pytest tests/` for organized tests only.
- `server_multi.py` is the alternative multi-endpoint entry point; `server.py` is the primary
-- `wordpress-plugin/` contains companion WP plugins (openpanel, seo-api-bridge) — these are PHP, not Python
+- `wordpress-plugin/` contains companion WP plugins (openpanel, airano-mcp-seo-bridge) — these are PHP, not Python
- `env.example` has "FUTURE" labels for Supabase/Gitea but both are fully implemented
- Dashboard templates live in `core/templates/` (included in pip package as `package_data`)
- `ruff` config uses top-level `select` key in pyproject.toml (not `[tool.ruff.lint]` nested format)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 75323df..efef8ad 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -120,7 +120,7 @@ Then register in `plugins/__init__.py` and add tests.
core/ # Core system (auth, site manager, tool registry, dashboard)
plugins/ # Plugin system (9 plugins, each with handlers + schemas)
core/templates/ # Jinja2 templates (dashboard + OAuth)
-tests/ # Test suite (290 tests)
+tests/ # Test suite (481 tests)
scripts/ # Setup & deployment scripts
docs/ # Documentation
```
diff --git a/DOCKER_README.md b/DOCKER_README.md
index add523e..7059788 100644
--- a/DOCKER_README.md
+++ b/DOCKER_README.md
@@ -4,6 +4,8 @@
596 tools across 9 plugins. Connect your sites, stores, repos, and databases — manage them all through Claude, ChatGPT, Cursor, or any MCP client.
+> **Don't want to self-host?** Try the hosted instance at **[mcp.palebluedot.live](https://mcp.palebluedot.live)** — log in with GitHub or Google, add your sites, and connect your AI client in minutes.
+
## Quick Start
### 1. Create a `.env` file
@@ -91,6 +93,7 @@ Use the most specific endpoint for your use case:
| Endpoint | Tools | `site` param? | Best for |
|----------|------:|:-------------:|----------|
+| `/u/{user_id}/{alias}/mcp` | 22-100 | No (pre-scoped) | Hosted/OAuth users |
| `/project/{alias}/mcp` | 22-100 | No (pre-scoped) | Single-site workflow |
| `/{plugin}/mcp` | 23-101 | Yes | Multi-site management |
| `/mcp` | 596 | Yes | Admin & discovery only |
@@ -131,7 +134,7 @@ docker compose up -d
| URL | Description |
|-----|-------------|
| `http://localhost:8000/health` | Health check & status |
-| `http://localhost:8000/dashboard` | Web dashboard (manage API keys, view sites, health) |
+| `http://localhost:8000/dashboard` | Web dashboard (manage sites, API keys, OAuth clients, health monitoring). Login via MASTER_API_KEY or GitHub/Google OAuth |
| `http://localhost:8000/mcp` | MCP endpoint (connect AI clients here) |
## Environment Variables
@@ -146,11 +149,19 @@ docker compose up -d
| `WORDPRESS_SITE1_CONTAINER` | For WP-CLI | Docker container name of your WordPress site (enables cache/db/system tools) |
| `OAUTH_JWT_SECRET_KEY` | For OAuth | JWT secret for ChatGPT auto-registration (not needed for Claude/Cursor) |
| `OAUTH_BASE_URL` | For OAuth | Public URL of your server (not needed for Claude/Cursor) |
+| `GITHUB_CLIENT_ID` | For Social Login | GitHub OAuth App client ID |
+| `GITHUB_CLIENT_SECRET` | For Social Login | GitHub OAuth App client secret |
+| `GOOGLE_CLIENT_ID` | For Social Login | Google OAuth client ID |
+| `GOOGLE_CLIENT_SECRET` | For Social Login | Google OAuth client secret |
+| `PUBLIC_URL` | For Social Login | Public URL for OAuth callbacks (e.g., `https://mcp.example.com`) |
+| `ENCRYPTION_KEY` | For Multi-user | AES-256 key for encrypting user site credentials. Generate: `python -c "import os, base64; print(base64.b64encode(os.urandom(32)).decode())"` |
> **CONTAINER**: Required for WP-CLI tools (cache flush, database export, system info) and **all** WordPress Advanced tools. Find your container name: `docker ps --filter name=wordpress`. Also requires Docker socket mount.
> **OAuth**: Only needed for ChatGPT Remote MCP auto-registration. For Claude Desktop, Claude Code, Cursor, and VS Code — just use `MASTER_API_KEY` with Bearer token auth.
+> **Social Login**: Enable GitHub/Google login for multi-user mode. Users can add sites via the dashboard and get personal MCP endpoints (`/u/{user_id}/{alias}/mcp`).
+
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
diff --git a/README.md b/README.md
index f8c3952..44b4658 100644
--- a/README.md
+++ b/README.md
@@ -13,7 +13,7 @@ Connect your sites, stores, repos, and databases — manage them all through Cla
[](https://www.python.org/)
[](https://pypi.org/project/mcphub-server/)
[](https://hub.docker.com/r/airano/mcphub)
-[]()
+[]()
[]()
[](https://github.com/airano-ir/mcphub/actions/workflows/ci.yml)
@@ -108,7 +108,20 @@ 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.
+You should see the login page. Log in with your `MASTER_API_KEY` or via **GitHub/Google OAuth** (if configured).
+
+### Try It Now (No Setup Required)
+
+**Don't want to self-host?** Use the hosted instance at **[mcp.example.com](https://mcp.example.com)**:
+
+1. Log in with **GitHub** or **Google**
+2. Add your sites via the dashboard (My Sites → Add Service)
+3. Go to **Connect** page — generate config for your AI client
+4. Copy-paste the config into Claude Desktop, VS Code, or Claude Code
+
+Your personal MCP endpoint: `https://mcp.example.com/u/{your-user-id}/{alias}/mcp`
+
+---
### Configure Your Sites
@@ -297,12 +310,14 @@ MCP Hub supports **Open Dynamic Client Registration** (RFC 7591). ChatGPT can au
/appwrite/mcp → Appwrite tools (100 tools)
/directus/mcp → Directus tools (100 tools)
/project/{alias}/mcp → Per-project endpoint (auto-injects site)
+/u/{user_id}/{alias}/mcp → Per-user endpoint (hosted/OAuth users)
```
**Recommendation**: Use plugin-specific endpoints instead of `/mcp` (596 tools) to minimize token usage.
| Endpoint | Use Case | Tools |
|----------|----------|------:|
+| `/u/{user_id}/{alias}/mcp` | Hosted users (OAuth login) | 22-100 |
| `/project/{alias}/mcp` | Single-site workflow (recommended) | 22-100 |
| `/{plugin}/mcp` | Multi-site management | 23-101 |
| `/mcp` | Admin & discovery only | 596 |
@@ -323,7 +338,7 @@ Some MCP Hub tools require companion WordPress plugins:
| Tools | Requirement |
|-------|-------------|
-| SEO tools (`wordpress_get_post_seo`, etc.) | [SEO API Bridge](wordpress-plugin/seo-api-bridge/) ([Download ZIP](wordpress-plugin/seo-api-bridge.zip)) + Rank Math or Yoast SEO |
+| SEO tools (`wordpress_get_post_seo`, etc.) | [Airano MCP SEO Bridge](https://wordpress.org/plugins/airano-mcp-seo-bridge/) ([GitHub](wordpress-plugin/airano-mcp-seo-bridge/)) + Rank Math or Yoast SEO |
| WP-CLI tools (15 tools: `wp_cache_*`, `wp_db_*`, etc.) | Docker socket + `CONTAINER` env var |
| WordPress Advanced database/system tools | Docker socket + `CONTAINER` env var |
| OpenPanel analytics integration | [OpenPanel Self-Hosted](wordpress-plugin/openpanel-self-hosted/) ([Download ZIP](wordpress-plugin/openpanel-self-hosted.zip)) |
@@ -363,7 +378,7 @@ Without Docker socket, WP-CLI tools return "not available" but all REST API tool
# Install with dev dependencies
pip install -e ".[dev]"
-# Run tests (290 tests)
+# Run tests (481 tests)
pytest
# Format and lint
diff --git a/core/config_snippets.py b/core/config_snippets.py
index c05703f..8d48ede 100644
--- a/core/config_snippets.py
+++ b/core/config_snippets.py
@@ -79,10 +79,14 @@ def generate_config(
endpoint_url = f"{base_url}/u/{user_id}/{alias}/mcp"
server_name = f"mcphub-{alias}"
+ # Claude Desktop uses streamableHttp; Claude Code, VS Code, Cursor use http
+ transport_type = "streamableHttp" if client_type == "claude_desktop" else "http"
+
if client_type in ("claude_desktop", "claude_code"):
config = {
"mcpServers": {
server_name: {
+ "type": transport_type,
"url": endpoint_url,
"headers": {
"Authorization": f"Bearer {api_key}",
@@ -97,6 +101,7 @@ def generate_config(
"mcp": {
"servers": {
server_name: {
+ "type": transport_type,
"url": endpoint_url,
"headers": {
"Authorization": f"Bearer {api_key}",
diff --git a/core/templates/dashboard/connect.html b/core/templates/dashboard/connect.html
index 712a0ee..dcb4a11 100644
--- a/core/templates/dashboard/connect.html
+++ b/core/templates/dashboard/connect.html
@@ -127,6 +127,32 @@
Select a site and client to generate configuration...
+
+
+
+
+ {% if lang == 'fa' %}
+ نکته: تنظیمات بالا شامل نوع اتصال (streamableHttp برای Claude Desktop و http برای VS Code/Claude Code) میباشد. از sse استفاده نکنید — باعث خطای 400 Bad Request میشود.
+ {% else %}
+ Note: Config above includes the correct transport type (streamableHttp for Claude Desktop, http for VS Code/Claude Code). Do not use sse — it will cause 400 Bad Request errors.
+ {% endif %}
+
+
+
+
+
+
+ {% if lang == 'fa' %}
+ وردپرس: برای استفاده از ابزارهای SEO، افزونه
+ Airano MCP SEO Bridge
+ را روی سایت وردپرسی خود نصب کنید. همچنین یک Application Password در وردپرس (Users → Profile) ایجاد و هنگام افزودن سایت وارد کنید.
+ {% else %}
+ WordPress: For SEO tools, install the
+ Airano MCP SEO Bridge
+ plugin on your WordPress site. Also create an Application Password in WordPress (Users → Profile) and enter it when adding your site.
+ {% endif %}
+
+
{% endif %}
{% endblock %}
diff --git a/docs/getting-started.md b/docs/getting-started.md
index 462619d..41f6a94 100644
--- a/docs/getting-started.md
+++ b/docs/getting-started.md
@@ -42,6 +42,27 @@ For each WordPress site you want to manage:
## Installation
+### Option 0: Use Hosted Version (No Setup Required)
+
+The fastest way to try MCP Hub — no installation needed:
+
+1. Visit **[mcp.example.com](https://mcp.example.com)**
+2. Log in with **GitHub** or **Google**
+3. Add your sites via the dashboard (**My Sites → Add Service**)
+4. Go to **Connect** page to generate your AI client config
+5. Copy-paste into Claude Desktop, VS Code, or Claude Code
+
+Your personal MCP endpoint:
+```
+https://mcp.example.com/u/{your-user-id}/{alias}/mcp
+```
+
+**WordPress users:** Install the [Airano MCP SEO Bridge](https://wordpress.org/plugins/airano-mcp-seo-bridge/) plugin for SEO tools, and create an [Application Password](https://make.wordpress.org/core/2020/11/05/application-passwords-integration-guide/) (Users → Profile) for authentication.
+
+> If you prefer self-hosting, continue with the options below.
+
+---
+
### Option 1: Docker (Recommended)
```bash
@@ -162,6 +183,21 @@ GITEA_REPO1_ALIAS=mygitea
OAUTH_JWT_SECRET_KEY=your-jwt-secret
OAUTH_BASE_URL=https://your-server:8000
+# ============================================
+# Social Login (GitHub/Google OAuth — for hosted/multi-user)
+# ============================================
+GITHUB_CLIENT_ID=your-github-oauth-app-id
+GITHUB_CLIENT_SECRET=your-github-oauth-app-secret
+GOOGLE_CLIENT_ID=your-google-oauth-client-id
+GOOGLE_CLIENT_SECRET=your-google-oauth-client-secret
+PUBLIC_URL=https://your-server:8000
+
+# ============================================
+# Encryption (required for storing user site credentials)
+# ============================================
+# Generate: python -c "import os, base64; print(base64.b64encode(os.urandom(32)).decode())"
+ENCRYPTION_KEY=your-base64-encoded-32-byte-key
+
# ============================================
# Optional
# ============================================
@@ -327,13 +363,15 @@ curl http://localhost:8000/health
**2. Open the web dashboard:**
-Open **http://localhost:8000/dashboard** in your browser. Log in with your `MASTER_API_KEY`.
+Open **http://localhost:8000/dashboard** in your browser. Log in with your `MASTER_API_KEY` or via **GitHub/Google OAuth** (if configured).
The dashboard lets you:
- View all connected sites and their health status
+- **Add, edit, delete, and test sites** via the My Sites page (OAuth users)
- Create and manage per-project API keys
-- View audit logs
-- Monitor rate limits
+- **Generate AI client configs** on the Connect page (with correct transport type per client)
+- View audit logs and monitor rate limits
+- **Per-user MCP endpoints**: OAuth users get personal endpoints at `/u/{user_id}/{alias}/mcp` with `mhu_` API keys
**3. Check container status (Docker only):**
diff --git a/plugins/wordpress/client.py b/plugins/wordpress/client.py
index a243146..185ccde 100644
--- a/plugins/wordpress/client.py
+++ b/plugins/wordpress/client.py
@@ -127,7 +127,7 @@ class WordPressClient:
"""
# Build URL based on endpoint type
if use_custom_namespace:
- # For custom namespaces like seo-api-bridge/v1
+ # For custom namespaces like airano-mcp-seo-bridge/v1
url = f"{self.site_url}/wp-json/{endpoint}"
elif use_woocommerce:
# For WooCommerce endpoints
diff --git a/plugins/wordpress/handlers/seo.py b/plugins/wordpress/handlers/seo.py
index 8b74093..65da8f2 100644
--- a/plugins/wordpress/handlers/seo.py
+++ b/plugins/wordpress/handlers/seo.py
@@ -188,7 +188,7 @@ class SEOHandler:
# First, try to use the new health check endpoint (v1.1.0+)
try:
status_result = await self.client.get(
- "seo-api-bridge/v1/status", use_custom_namespace=True
+ "airano-mcp-seo-bridge/v1/status", use_custom_namespace=True
)
if status_result and isinstance(status_result, dict):
@@ -383,7 +383,7 @@ class SEOHandler:
try:
# Use SEO API Bridge endpoint for products (same as update_product_seo)
result = await self.client.get(
- f"seo-api-bridge/v1/products/{product_id}/seo", use_custom_namespace=True
+ f"airano-mcp-seo-bridge/v1/products/{product_id}/seo", use_custom_namespace=True
)
return json.dumps(result, indent=2)
@@ -592,7 +592,7 @@ class SEOHandler:
# Use SEO API Bridge endpoint for products
await self.client.post(
- f"seo-api-bridge/v1/products/{product_id}/seo",
+ f"airano-mcp-seo-bridge/v1/products/{product_id}/seo",
json_data=data,
use_custom_namespace=True,
)
diff --git a/tests/test_config_snippets.py b/tests/test_config_snippets.py
index a45e9c8..a7bb0d3 100644
--- a/tests/test_config_snippets.py
+++ b/tests/test_config_snippets.py
@@ -60,16 +60,18 @@ class TestClaudeFormat:
assert server_name in config["mcpServers"]
server = config["mcpServers"][server_name]
assert server["url"] == EXPECTED_ENDPOINT
+ assert server["type"] == "streamableHttp"
assert f"Bearer {API_KEY}" in server["headers"]["Authorization"]
@pytest.mark.unit
def test_claude_code_format(self):
- """Claude Code config should use the same mcpServers format."""
+ """Claude Code config should use the same mcpServers format with http type."""
snippet = generate_config(BASE_URL, USER_ID, ALIAS, API_KEY, "claude_code")
config = json.loads(snippet)
assert "mcpServers" in config
server_name = f"mcphub-{ALIAS}"
assert server_name in config["mcpServers"]
+ assert config["mcpServers"][server_name]["type"] == "http"
# ── Cursor / VS Code Format ─────────────────────────────────
@@ -80,7 +82,7 @@ class TestCursorVSCodeFormat:
@pytest.mark.unit
def test_cursor_format(self):
- """Cursor config should be valid JSON with mcp.servers."""
+ """Cursor config should be valid JSON with mcp.servers and http type."""
snippet = generate_config(BASE_URL, USER_ID, ALIAS, API_KEY, "cursor")
config = json.loads(snippet)
assert "mcp" in config
@@ -89,15 +91,18 @@ class TestCursorVSCodeFormat:
assert server_name in config["mcp"]["servers"]
server = config["mcp"]["servers"][server_name]
assert server["url"] == EXPECTED_ENDPOINT
+ assert server["type"] == "http"
assert f"Bearer {API_KEY}" in server["headers"]["Authorization"]
@pytest.mark.unit
def test_vscode_format(self):
- """VS Code config should use the same mcp.servers format as Cursor."""
+ """VS Code config should use mcp.servers format with http type."""
snippet = generate_config(BASE_URL, USER_ID, ALIAS, API_KEY, "vscode")
config = json.loads(snippet)
assert "mcp" in config
assert "servers" in config["mcp"]
+ server_name = f"mcphub-{ALIAS}"
+ assert config["mcp"]["servers"][server_name]["type"] == "http"
# ── ChatGPT Format ───────────────────────────────────────────
diff --git a/wordpress-plugin/airano-mcp-seo-bridge/README.md b/wordpress-plugin/airano-mcp-seo-bridge/README.md
index abb3b9a..8f2d92d 100644
--- a/wordpress-plugin/airano-mcp-seo-bridge/README.md
+++ b/wordpress-plugin/airano-mcp-seo-bridge/README.md
@@ -1,4 +1,4 @@
-# SEO API Bridge - WordPress Plugin
+# Airano MCP SEO Bridge - WordPress Plugin
**Version:** 1.3.0
**Requires:** WordPress 5.0+, PHP 7.4+
@@ -72,23 +72,23 @@ SEO API Bridge is a comprehensive WordPress plugin that exposes Rank Math SEO an
### Method 1: Upload via WordPress Admin
-1. Download `seo-api-bridge.zip` from [Releases](https://github.com/airano-ir/mcphub)
+1. Download `airano-mcp-seo-bridge.zip` from [Releases](https://github.com/airano-ir/mcphub)
2. Go to WordPress Admin > Plugins > Add New > Upload Plugin
3. Upload the ZIP file and click "Install Now"
4. Click "Activate Plugin"
### Method 2: FTP/SSH Upload
-1. Upload the `seo-api-bridge` folder to `/wp-content/plugins/`
+1. Upload the `airano-mcp-seo-bridge` folder to `/wp-content/plugins/`
2. Go to WordPress Admin > Plugins
-3. Find "SEO API Bridge" and click "Activate"
+3. Find "Airano MCP SEO Bridge" and click "Activate"
### Method 3: WP-CLI
```bash
cd /var/www/html/wp-content/plugins/
# Copy the plugin folder here
-wp plugin activate seo-api-bridge
+wp plugin activate airano-mcp-seo-bridge
```
## REST API Endpoints
@@ -97,10 +97,10 @@ All endpoints require **WordPress Application Password** authentication.
### Status Endpoint
-**GET** `/wp-json/seo-api-bridge/v1/status`
+**GET** `/wp-json/airano-mcp-seo-bridge/v1/status`
```bash
-curl -X GET "https://yoursite.com/wp-json/seo-api-bridge/v1/status" \
+curl -X GET "https://yoursite.com/wp-json/airano-mcp-seo-bridge/v1/status" \
-u "username:application_password"
```
@@ -121,17 +121,17 @@ curl -X GET "https://yoursite.com/wp-json/seo-api-bridge/v1/status" \
### Post SEO Endpoints
-**GET** `/wp-json/seo-api-bridge/v1/posts/{id}/seo` — Get SEO metadata for a post
+**GET** `/wp-json/airano-mcp-seo-bridge/v1/posts/{id}/seo` — Get SEO metadata for a post
-**POST** `/wp-json/seo-api-bridge/v1/posts/{id}/seo` — Update SEO metadata for a post
+**POST** `/wp-json/airano-mcp-seo-bridge/v1/posts/{id}/seo` — Update SEO metadata for a post
```bash
# Get post SEO
-curl -X GET "https://yoursite.com/wp-json/seo-api-bridge/v1/posts/123/seo" \
+curl -X GET "https://yoursite.com/wp-json/airano-mcp-seo-bridge/v1/posts/123/seo" \
-u "username:application_password"
# Update post SEO
-curl -X POST "https://yoursite.com/wp-json/seo-api-bridge/v1/posts/123/seo" \
+curl -X POST "https://yoursite.com/wp-json/airano-mcp-seo-bridge/v1/posts/123/seo" \
-u "username:application_password" \
-H "Content-Type: application/json" \
-d '{"focus_keyword": "wordpress", "seo_title": "My Title"}'
@@ -139,18 +139,18 @@ curl -X POST "https://yoursite.com/wp-json/seo-api-bridge/v1/posts/123/seo" \
### Page SEO Endpoints
-**GET** `/wp-json/seo-api-bridge/v1/pages/{id}/seo`
+**GET** `/wp-json/airano-mcp-seo-bridge/v1/pages/{id}/seo`
-**POST** `/wp-json/seo-api-bridge/v1/pages/{id}/seo`
+**POST** `/wp-json/airano-mcp-seo-bridge/v1/pages/{id}/seo`
### Product SEO Endpoints (WooCommerce)
-**GET** `/wp-json/seo-api-bridge/v1/products/{id}/seo`
+**GET** `/wp-json/airano-mcp-seo-bridge/v1/products/{id}/seo`
-**POST** `/wp-json/seo-api-bridge/v1/products/{id}/seo`
+**POST** `/wp-json/airano-mcp-seo-bridge/v1/products/{id}/seo`
```bash
-curl -X POST "https://yoursite.com/wp-json/seo-api-bridge/v1/products/1217/seo" \
+curl -X POST "https://yoursite.com/wp-json/airano-mcp-seo-bridge/v1/products/1217/seo" \
-u "username:application_password" \
-H "Content-Type: application/json" \
-d '{"focus_keyword": "product keyword", "seo_title": "Product Title"}'
@@ -223,7 +223,7 @@ result = await mcp.call_tool(
2. **Status Endpoint:**
```bash
-curl -X GET "https://your-site.com/wp-json/seo-api-bridge/v1/status" \
+curl -X GET "https://your-site.com/wp-json/airano-mcp-seo-bridge/v1/status" \
-u "username:application_password"
```
@@ -248,7 +248,7 @@ curl -X GET "https://your-site.com/wp-json/wp/v2/posts/1" \
1. Upgrade to v1.1.0+ (has dedicated health check endpoint)
2. Restart MCP server
-3. Test endpoint: `curl "https://your-site.com/wp-json/seo-api-bridge/v1/status" -u "user:pass"`
+3. Test endpoint: `curl "https://your-site.com/wp-json/airano-mcp-seo-bridge/v1/status" -u "user:pass"`
### SEO Plugin Not Detected
@@ -285,7 +285,7 @@ curl -X GET "https://your-site.com/wp-json/wp/v2/posts/1" \
- Improved MariaDB compatibility for meta field queries
### 1.1.0 (2025-01-10)
-- Added health check REST API endpoint `/seo-api-bridge/v1/status`
+- Added health check REST API endpoint `/airano-mcp-seo-bridge/v1/status`
- Direct plugin detection without requiring posts/products
- Better compatibility with sites that have no content
- Returns SEO plugin versions in status endpoint