sync: v3.2.0 pre-release audit — namespace fix, config types, docs update
- fix(seo): REST API namespace seo-api-bridge/v1 → airano-mcp-seo-bridge/v1 - fix(config): add transport type field (streamableHttp/http) to config snippets - feat(dashboard): support section for OAuth users, connect page guidance - docs: hosted option, test count 481, WP plugin link, OAuth env vars, per-user endpoints Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
```
|
||||
|
||||
@@ -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
|
||||
|
||||
23
README.md
23
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
|
||||
|
||||
@@ -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}",
|
||||
|
||||
@@ -127,6 +127,32 @@
|
||||
<pre id="config-output" class="bg-gray-100 dark:bg-gray-900 rounded-lg p-4 text-sm text-gray-700 dark:text-gray-300 overflow-x-auto border border-gray-200 dark:border-gray-700 min-h-[120px]">Select a site and client to generate configuration...</pre>
|
||||
<button onclick="copyConfig()" class="absolute top-2 {{ 'left-2' if lang == 'fa' else 'right-2' }} text-xs bg-gray-200 dark:bg-gray-700 hover:bg-gray-300 dark:hover:bg-gray-600 text-gray-600 dark:text-gray-300 px-3 py-1 rounded transition-colors" id="copy-config-btn">{{ t['copy'] }}</button>
|
||||
</div>
|
||||
|
||||
<!-- Transport type info -->
|
||||
<div class="mt-4 bg-blue-50 dark:bg-blue-500/10 border border-blue-200 dark:border-blue-500/30 rounded-lg p-4">
|
||||
<p class="text-sm text-blue-700 dark:text-blue-400">
|
||||
{% if lang == 'fa' %}
|
||||
<strong>نکته:</strong> تنظیمات بالا شامل نوع اتصال (<code>streamableHttp</code> برای Claude Desktop و <code>http</code> برای VS Code/Claude Code) میباشد. از <code>sse</code> استفاده نکنید — باعث خطای <code>400 Bad Request</code> میشود.
|
||||
{% else %}
|
||||
<strong>Note:</strong> Config above includes the correct transport type (<code>streamableHttp</code> for Claude Desktop, <code>http</code> for VS Code/Claude Code). Do not use <code>sse</code> — it will cause <code>400 Bad Request</code> errors.
|
||||
{% endif %}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- WordPress plugin requirement -->
|
||||
<div class="mt-3 bg-amber-50 dark:bg-amber-500/10 border border-amber-200 dark:border-amber-500/30 rounded-lg p-4">
|
||||
<p class="text-sm text-amber-700 dark:text-amber-400">
|
||||
{% if lang == 'fa' %}
|
||||
<strong>وردپرس:</strong> برای استفاده از ابزارهای SEO، افزونه
|
||||
<a href="https://wordpress.org/plugins/airano-mcp-seo-bridge/" target="_blank" class="underline">Airano MCP SEO Bridge</a>
|
||||
را روی سایت وردپرسی خود نصب کنید. همچنین یک <strong>Application Password</strong> در وردپرس (Users → Profile) ایجاد و هنگام افزودن سایت وارد کنید.
|
||||
{% else %}
|
||||
<strong>WordPress:</strong> For SEO tools, install the
|
||||
<a href="https://wordpress.org/plugins/airano-mcp-seo-bridge/" target="_blank" class="underline">Airano MCP SEO Bridge</a>
|
||||
plugin on your WordPress site. Also create an <strong>Application Password</strong> in WordPress (Users → Profile) and enter it when adding your site.
|
||||
{% endif %}
|
||||
</p>
|
||||
</div>
|
||||
{% else %}
|
||||
<p class="text-gray-500 dark:text-gray-400 text-sm">{{ t.no_sites }}. <a href="/dashboard/sites/add{% if lang and lang != 'en' %}?lang={{ lang }}{% endif %}" class="text-blue-600 dark:text-blue-400 hover:text-blue-500 dark:hover:text-blue-300">{{ t.add_site }}</a></p>
|
||||
{% endif %}
|
||||
|
||||
@@ -439,6 +439,34 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Support / Donate (User Dashboard) -->
|
||||
<div class="bg-gradient-to-br from-primary-900/40 to-gray-800 rounded-xl border border-primary-700/30">
|
||||
<div class="p-6 text-center">
|
||||
<div class="w-10 h-10 bg-primary-500/20 rounded-full flex items-center justify-center mx-auto mb-3">
|
||||
<svg class="w-5 h-5 text-primary-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<h3 class="text-sm font-semibold text-white mb-1">
|
||||
{% if lang == 'fa' %}حمایت از پروژه{% else %}Support MCP Hub{% endif %}
|
||||
</h3>
|
||||
<p class="text-xs text-gray-400 mb-4">
|
||||
{% if lang == 'fa' %}با حمایت مالی به توسعه این پروژه کمک کنید{% else %}Help us keep this project alive and growing{% endif %}
|
||||
</p>
|
||||
<a
|
||||
href="https://nowpayments.io/donation/airano"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="inline-flex items-center px-4 py-2 text-sm font-medium text-white bg-primary-600 hover:bg-primary-500 rounded-lg transition-colors"
|
||||
>
|
||||
<svg class="w-4 h-4 {% if lang == 'fa' %}ml-2{% else %}mr-2{% endif %}" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
|
||||
</svg>
|
||||
{% if lang == 'fa' %}حمایت با رمزارز{% else %}Donate with Crypto{% endif %}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
@@ -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):**
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
)
|
||||
|
||||
@@ -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 ───────────────────────────────────────────
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user