fix(qa): health check, admin notice, docs, logo, Coolify port
- WP Advanced health_check uses aiohttp to /wp-json/ directly - SEO Bridge admin notice only on Plugins page - SEO Bridge README.md consolidated, changelog complete - OpenPanel Self-Hosted README.md created - Dashboard sidebar uses actual logo.svg - docker-compose: expose instead of ports for Coolify - README: version badge, wordpress_advanced endpoint, env var table - Docs: SSE references fixed to streamable-http Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
49
README.md
49
README.md
@@ -6,6 +6,7 @@
|
||||
|
||||
Connect your sites, stores, repos, and databases — manage them all through Claude, ChatGPT, Cursor, or any MCP client.
|
||||
|
||||
[](https://github.com/airano-ir/mcphub/releases)
|
||||
[](LICENSE)
|
||||
[](https://www.python.org/)
|
||||
[](https://pypi.org/project/mcphub-server/)
|
||||
@@ -133,6 +134,53 @@ GITEA_REPO1_TOKEN=your_gitea_token
|
||||
GITEA_REPO1_ALIAS=mygitea
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary><b>Full Environment Variable Reference</b></summary>
|
||||
|
||||
**System Configuration:**
|
||||
|
||||
| Variable | Required | Default | Description |
|
||||
|----------|----------|---------|-------------|
|
||||
| `MASTER_API_KEY` | Recommended | Auto-generated | Master API key for admin access |
|
||||
| `LOG_LEVEL` | No | `INFO` | Logging level (DEBUG, INFO, WARNING, ERROR) |
|
||||
| `OAUTH_JWT_SECRET_KEY` | For OAuth | — | JWT signing secret for OAuth tokens |
|
||||
| `OAUTH_BASE_URL` | For OAuth | — | Public URL (e.g., `https://mcp.example.com`) |
|
||||
| `OAUTH_JWT_ALGORITHM` | No | `HS256` | JWT algorithm |
|
||||
| `OAUTH_ACCESS_TOKEN_TTL` | No | `3600` | Access token TTL in seconds |
|
||||
| `OAUTH_REFRESH_TOKEN_TTL` | No | `604800` | Refresh token TTL in seconds |
|
||||
| `OAUTH_STORAGE_TYPE` | No | `json` | Token storage type |
|
||||
| `OAUTH_STORAGE_PATH` | No | `/app/data` | Data directory path |
|
||||
|
||||
**Plugin Site Configuration** — Pattern: `{PLUGIN_TYPE}_{SITE_ID}_{KEY}`
|
||||
|
||||
| Plugin | Required Keys | Optional Keys |
|
||||
|--------|--------------|---------------|
|
||||
| `WORDPRESS` | `URL`, `USERNAME`, `APP_PASSWORD` | `ALIAS`, `CONTAINER` |
|
||||
| `WOOCOMMERCE` | `URL`, `CONSUMER_KEY`, `CONSUMER_SECRET` | `ALIAS` |
|
||||
| `WORDPRESS_ADVANCED` | `URL`, `USERNAME`, `APP_PASSWORD`, `CONTAINER` | `ALIAS` |
|
||||
| `GITEA` | `URL`, `TOKEN` | `ALIAS` |
|
||||
| `N8N` | `URL`, `API_KEY` | `ALIAS` |
|
||||
| `SUPABASE` | `URL`, `SERVICE_ROLE_KEY` | `ALIAS` |
|
||||
| `OPENPANEL` | `URL`, `CLIENT_ID`, `CLIENT_SECRET` | `ALIAS` |
|
||||
| `APPWRITE` | `URL`, `API_KEY`, `PROJECT_ID` | `ALIAS` |
|
||||
| `DIRECTUS` | `URL`, `TOKEN` | `ALIAS` |
|
||||
|
||||
**Example** — Multiple WordPress sites:
|
||||
|
||||
```bash
|
||||
WORDPRESS_BLOG_URL=https://blog.example.com
|
||||
WORDPRESS_BLOG_USERNAME=admin
|
||||
WORDPRESS_BLOG_APP_PASSWORD=xxxx xxxx xxxx xxxx
|
||||
WORDPRESS_BLOG_ALIAS=blog
|
||||
|
||||
WORDPRESS_SHOP_URL=https://shop.example.com
|
||||
WORDPRESS_SHOP_USERNAME=admin
|
||||
WORDPRESS_SHOP_APP_PASSWORD=yyyy yyyy yyyy yyyy
|
||||
WORDPRESS_SHOP_ALIAS=shop
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### Connect Your AI Client
|
||||
|
||||
All MCP clients use **Bearer token** authentication: `Authorization: Bearer YOUR_API_KEY`
|
||||
@@ -235,6 +283,7 @@ MCP Hub supports **Open Dynamic Client Registration** (RFC 7591). ChatGPT can au
|
||||
/system/mcp → System tools only (24 tools)
|
||||
/wordpress/mcp → WordPress tools (67 tools)
|
||||
/woocommerce/mcp → WooCommerce tools (28 tools)
|
||||
/wordpress_advanced/mcp → WordPress Advanced tools (22 tools)
|
||||
/gitea/mcp → Gitea tools (56 tools)
|
||||
/n8n/mcp → n8n tools (56 tools)
|
||||
/supabase/mcp → Supabase tools (70 tools)
|
||||
|
||||
@@ -120,13 +120,12 @@
|
||||
<!-- Logo -->
|
||||
<div class="flex items-center justify-between h-16 px-4 border-b border-gray-700">
|
||||
<div class="flex items-center" x-show="sidebarOpen">
|
||||
<div class="w-8 h-8 bg-primary-600 rounded-lg flex items-center justify-center">
|
||||
<svg class="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<img src="/static/logo.svg" alt="MCP Hub" class="w-8 h-8">
|
||||
<span class="{% if lang == 'fa' %}mr-3{% else %}ml-3{% endif %} font-bold text-lg">MCP Hub</span>
|
||||
</div>
|
||||
<div x-show="!sidebarOpen" class="flex items-center justify-center">
|
||||
<img src="/static/logo.svg" alt="MCP Hub" class="w-8 h-8">
|
||||
</div>
|
||||
<button
|
||||
@click="sidebarOpen = !sidebarOpen"
|
||||
class="p-2 rounded-lg hover:bg-gray-700 transition-colors"
|
||||
|
||||
@@ -7,8 +7,10 @@
|
||||
# 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.
|
||||
# Port mapping:
|
||||
# - Coolify: Do NOT use 'ports' — Coolify's reverse proxy handles routing.
|
||||
# The 'expose' directive below is sufficient.
|
||||
# - Standalone Docker: Uncomment the 'ports' section below to bind to host.
|
||||
# ===================================
|
||||
|
||||
services:
|
||||
@@ -19,8 +21,14 @@ services:
|
||||
container_name: mcphub
|
||||
restart: unless-stopped
|
||||
|
||||
ports:
|
||||
- "8000:8000"
|
||||
# Container exposes port 8000 to linked services / Coolify proxy
|
||||
expose:
|
||||
- "8000"
|
||||
|
||||
# Standalone Docker: Uncomment below to access at http://localhost:8000
|
||||
# Coolify: Leave commented — Coolify's reverse proxy handles routing
|
||||
# ports:
|
||||
# - "8000:8000"
|
||||
|
||||
# Environment variables
|
||||
environment:
|
||||
|
||||
@@ -302,7 +302,7 @@ DIRECTUS_SITE1_ALIAS=my-directus # Recommended
|
||||
|
||||
## Running the Server
|
||||
|
||||
### SSE Transport (for remote AI clients)
|
||||
### Streamable HTTP Transport (for remote AI clients)
|
||||
|
||||
```bash
|
||||
python server.py --transport streamable-http --port 8000
|
||||
|
||||
@@ -112,11 +112,23 @@ class WordPressAdvancedPlugin(BasePlugin):
|
||||
Dict with health status and WP-CLI availability
|
||||
"""
|
||||
try:
|
||||
# Test REST API access (primary health indicator — most tools use REST)
|
||||
# Test REST API access by hitting /wp-json/ directly
|
||||
# NOTE: self.client.get("/") hits /wp-json/wp/v2/ which doesn't
|
||||
# return a "name" field. We need /wp-json/ for the site index.
|
||||
rest_api_available = False
|
||||
try:
|
||||
site_info = await self.client.get("/")
|
||||
rest_api_available = bool(site_info.get("name"))
|
||||
import aiohttp
|
||||
|
||||
site_url = self.client.site_url
|
||||
async with aiohttp.ClientSession() as session:
|
||||
async with session.get(
|
||||
f"{site_url}/wp-json/",
|
||||
timeout=aiohttp.ClientTimeout(total=10),
|
||||
ssl=False,
|
||||
) as resp:
|
||||
if resp.status == 200:
|
||||
data = await resp.json()
|
||||
rest_api_available = bool(data.get("name"))
|
||||
except Exception as e:
|
||||
self.logger.warning(f"REST API check failed: {e}")
|
||||
|
||||
|
||||
Binary file not shown.
106
wordpress-plugin/openpanel-self-hosted/README.md
Normal file
106
wordpress-plugin/openpanel-self-hosted/README.md
Normal file
@@ -0,0 +1,106 @@
|
||||
# OpenPanel Self-Hosted - WordPress Plugin
|
||||
|
||||
**Version:** 1.1.1
|
||||
**Requires:** WordPress 5.8+, PHP 7.4+
|
||||
**License:** GPLv2 or later
|
||||
|
||||
## Description
|
||||
|
||||
**OpenPanel Self-Hosted** is a fork of the [official OpenPanel WordPress plugin](https://wordpress.org/plugins/openpanel/) with full **Self-Hosted instance support**. [OpenPanel](https://openpanel.dev) is an open-source web and product analytics platform — a privacy-friendly alternative to Google Analytics.
|
||||
|
||||
This plugin seamlessly integrates OpenPanel (Cloud or Self-Hosted) with your WordPress site while maximizing reliability and avoiding ad-blocker interference.
|
||||
|
||||
Designed to work with [MCP Hub](https://github.com/airano-ir/mcphub) for AI-powered analytics management.
|
||||
|
||||
## Key Features
|
||||
|
||||
- **Self-Hosted Support**: Works with both OpenPanel Cloud and your own Self-Hosted instance
|
||||
- **Ad-Blocker Resistant**: Serves analytics scripts and API calls from your own domain
|
||||
- **Real-Time Analytics**: Instant insights without processing delays
|
||||
- **Privacy-Friendly**: Cookie-less tracking — no cookie banners needed
|
||||
- **Performance Optimized**: Local script caching and efficient proxying
|
||||
- **Product Analytics**: Funnel analysis, retention tracking, conversion metrics
|
||||
- **Web Analytics**: Visitors, referrals, top pages, devices, sessions, bounce rates
|
||||
|
||||
## How It Works
|
||||
|
||||
1. **Inlines** `op1.js` directly into your pages (cached locally for 1 week)
|
||||
2. **Bootstraps** the OpenPanel SDK with your Client ID automatically
|
||||
3. **Proxies** all SDK requests through WordPress REST API (`/wp-json/openpanel/`)
|
||||
4. **Preserves** all request methods, headers, query parameters, and body data
|
||||
|
||||
Serving scripts and data from your own domain origin avoids third-party blocking and improves tracking reliability.
|
||||
|
||||
## Installation
|
||||
|
||||
### Method 1: Upload via WordPress Admin
|
||||
|
||||
1. Download `openpanel-self-hosted.zip` from [Releases](https://github.com/airano-ir/mcphub)
|
||||
2. Go to WordPress Admin > Plugins > Add New > Upload Plugin
|
||||
3. Upload the ZIP and click "Install Now"
|
||||
4. Activate the plugin
|
||||
|
||||
### Method 2: Manual Upload
|
||||
|
||||
1. Upload the `openpanel-self-hosted` folder to `/wp-content/plugins/`
|
||||
2. Activate via WordPress Admin > Plugins
|
||||
|
||||
## Configuration
|
||||
|
||||
### Cloud Mode (openpanel.dev)
|
||||
|
||||
1. Sign up at [OpenPanel.dev](https://openpanel.dev) and create a project
|
||||
2. Go to **Settings > OpenPanel** in WordPress admin
|
||||
3. Select **Cloud (openpanel.dev)** as hosting mode
|
||||
4. Paste your **Client ID** (starts with `op_client_`)
|
||||
5. Enable desired auto-tracking features
|
||||
|
||||
### Self-Hosted Mode
|
||||
|
||||
1. Go to **Settings > OpenPanel** in WordPress admin
|
||||
2. Select **Self-Hosted** as hosting mode
|
||||
3. Enter your **API URL** (e.g., `https://api.openpanel.yourdomain.com`)
|
||||
4. Enter your **Dashboard URL** (e.g., `https://openpanel.yourdomain.com`)
|
||||
5. Paste your **Client ID** from your self-hosted instance
|
||||
6. Enable desired auto-tracking features
|
||||
|
||||
| Setting | Example Value |
|
||||
|---------|---------------|
|
||||
| API URL | `https://api.openpanel.yourdomain.com` |
|
||||
| Dashboard URL | `https://openpanel.yourdomain.com` |
|
||||
| Client ID | Your project's client ID from OpenPanel |
|
||||
|
||||
## Privacy
|
||||
|
||||
- **No Cookie Banners Required**: Cookie-less tracking technology
|
||||
- **GDPR Friendly**: Compliant without requiring user consent for basic analytics
|
||||
- **Data Ownership**: Full control over your analytics data
|
||||
- **No PII Collection**: Tracks behavior patterns without personal information
|
||||
|
||||
## Changelog
|
||||
|
||||
### 1.1.1
|
||||
- Fixed op1.js loading for self-hosted instances (was always loading from CDN)
|
||||
- Both inline cache and external fallback now use the correct self-hosted URL
|
||||
|
||||
### 1.1.0
|
||||
- Full self-hosted OpenPanel instance support
|
||||
- Hosting mode selector: Cloud vs Self-Hosted
|
||||
- Configurable API URL and Dashboard URL
|
||||
- Dynamic proxy validation for custom domains
|
||||
|
||||
### 1.0.0
|
||||
- Initial release with OpenPanel Cloud integration
|
||||
- Automatic script inlining with local caching
|
||||
- REST API proxy for ad-blocker resistant tracking
|
||||
- Auto-tracking: page views, outgoing links, page attributes
|
||||
|
||||
## Support
|
||||
|
||||
- **Plugin issues:** [GitHub Issues](https://github.com/airano-ir/mcphub/issues)
|
||||
- **OpenPanel platform:** [OpenPanel.dev](https://openpanel.dev)
|
||||
- **MCP Hub:** [MCP Hub Documentation](https://github.com/airano-ir/mcphub)
|
||||
|
||||
## License
|
||||
|
||||
GPLv2 or later - See [LICENSE](https://www.gnu.org/licenses/gpl-2.0.html) for details
|
||||
Binary file not shown.
@@ -10,94 +10,82 @@ SEO API Bridge is a comprehensive WordPress plugin that exposes Rank Math SEO an
|
||||
|
||||
## What's New in 1.3.0
|
||||
|
||||
✨ **Full REST API Endpoints** - GET and POST operations for all post types
|
||||
✨ **Product SEO Support** - Complete WooCommerce product SEO management
|
||||
✨ **Simplified Integration** - Direct API calls instead of meta field manipulation
|
||||
✨ **Better Error Handling** - Proper validation and error responses
|
||||
- **Full REST API Endpoints** - GET and POST operations for all post types
|
||||
- **Product SEO Support** - Complete WooCommerce product SEO management
|
||||
- **Simplified Integration** - Direct API calls instead of meta field manipulation
|
||||
- **Better Error Handling** - Proper validation and error responses
|
||||
|
||||
## Features
|
||||
|
||||
- ✅ **Rank Math SEO Support** - Full access to all Rank Math meta fields
|
||||
- ✅ **Yoast SEO Support** - Full access to all Yoast SEO meta fields
|
||||
- ✅ **WooCommerce Compatible** - Works with product post types
|
||||
- ✅ **Secure** - Requires proper authentication and edit_posts capability
|
||||
- ✅ **Auto-Detection** - Automatically detects which SEO plugin is active
|
||||
- ✅ **Health Check Endpoint** - NEW! Dedicated API endpoint for plugin detection
|
||||
- ✅ **Zero Configuration** - Works out of the box after activation
|
||||
- **Rank Math SEO Support** - Full access to all Rank Math meta fields
|
||||
- **Yoast SEO Support** - Full access to all Yoast SEO meta fields
|
||||
- **WooCommerce Compatible** - Works with product post types
|
||||
- **Secure** - Requires proper authentication and edit_posts capability
|
||||
- **Auto-Detection** - Automatically detects which SEO plugin is active
|
||||
- **Health Check Endpoint** - Dedicated API endpoint for plugin detection
|
||||
- **Zero Configuration** - Works out of the box after activation
|
||||
|
||||
## Supported SEO Fields
|
||||
|
||||
### Rank Math SEO
|
||||
|
||||
#### Core Fields
|
||||
- `rank_math_focus_keyword` - Focus keyword
|
||||
- `rank_math_title` - Meta title
|
||||
- `rank_math_description` - Meta description
|
||||
- `rank_math_additional_keywords` - Additional keywords
|
||||
|
||||
#### Advanced Fields
|
||||
- `rank_math_canonical_url` - Canonical URL
|
||||
- `rank_math_robots` - Robots meta directives
|
||||
- `rank_math_breadcrumb_title` - Breadcrumb title
|
||||
|
||||
#### Open Graph (Facebook)
|
||||
- `rank_math_facebook_title` - OG title
|
||||
- `rank_math_facebook_description` - OG description
|
||||
- `rank_math_facebook_image` - OG image URL
|
||||
- `rank_math_facebook_image_id` - OG image ID
|
||||
|
||||
#### Twitter Card
|
||||
- `rank_math_twitter_title` - Twitter title
|
||||
- `rank_math_twitter_description` - Twitter description
|
||||
- `rank_math_twitter_image` - Twitter image URL
|
||||
- `rank_math_twitter_image_id` - Twitter image ID
|
||||
- `rank_math_twitter_card_type` - Card type (summary, summary_large_image)
|
||||
| Category | Field | Description |
|
||||
|----------|-------|-------------|
|
||||
| Core | `rank_math_focus_keyword` | Focus keyword |
|
||||
| Core | `rank_math_title` | Meta title |
|
||||
| Core | `rank_math_description` | Meta description |
|
||||
| Core | `rank_math_additional_keywords` | Additional keywords |
|
||||
| Advanced | `rank_math_canonical_url` | Canonical URL |
|
||||
| Advanced | `rank_math_robots` | Robots meta directives |
|
||||
| Advanced | `rank_math_breadcrumb_title` | Breadcrumb title |
|
||||
| Open Graph | `rank_math_facebook_title` | OG title |
|
||||
| Open Graph | `rank_math_facebook_description` | OG description |
|
||||
| Open Graph | `rank_math_facebook_image` | OG image URL |
|
||||
| Open Graph | `rank_math_facebook_image_id` | OG image ID |
|
||||
| Twitter | `rank_math_twitter_title` | Twitter title |
|
||||
| Twitter | `rank_math_twitter_description` | Twitter description |
|
||||
| Twitter | `rank_math_twitter_image` | Twitter image URL |
|
||||
| Twitter | `rank_math_twitter_image_id` | Twitter image ID |
|
||||
| Twitter | `rank_math_twitter_card_type` | Card type (summary, summary_large_image) |
|
||||
|
||||
### Yoast SEO
|
||||
|
||||
#### Core Fields
|
||||
- `_yoast_wpseo_focuskw` - Focus keyword
|
||||
- `_yoast_wpseo_title` - Meta title
|
||||
- `_yoast_wpseo_metadesc` - Meta description
|
||||
|
||||
#### Advanced Fields
|
||||
- `_yoast_wpseo_canonical` - Canonical URL
|
||||
- `_yoast_wpseo_meta-robots-noindex` - Noindex setting
|
||||
- `_yoast_wpseo_meta-robots-nofollow` - Nofollow setting
|
||||
- `_yoast_wpseo_bctitle` - Breadcrumb title
|
||||
|
||||
#### Open Graph
|
||||
- `_yoast_wpseo_opengraph-title` - OG title
|
||||
- `_yoast_wpseo_opengraph-description` - OG description
|
||||
- `_yoast_wpseo_opengraph-image` - OG image URL
|
||||
- `_yoast_wpseo_opengraph-image-id` - OG image ID
|
||||
|
||||
#### Twitter Card
|
||||
- `_yoast_wpseo_twitter-title` - Twitter title
|
||||
- `_yoast_wpseo_twitter-description` - Twitter description
|
||||
- `_yoast_wpseo_twitter-image` - Twitter image URL
|
||||
- `_yoast_wpseo_twitter-image-id` - Twitter image ID
|
||||
| Category | Field | Description |
|
||||
|----------|-------|-------------|
|
||||
| Core | `_yoast_wpseo_focuskw` | Focus keyword |
|
||||
| Core | `_yoast_wpseo_title` | Meta title |
|
||||
| Core | `_yoast_wpseo_metadesc` | Meta description |
|
||||
| Advanced | `_yoast_wpseo_canonical` | Canonical URL |
|
||||
| Advanced | `_yoast_wpseo_meta-robots-noindex` | Noindex setting |
|
||||
| Advanced | `_yoast_wpseo_meta-robots-nofollow` | Nofollow setting |
|
||||
| Advanced | `_yoast_wpseo_bctitle` | Breadcrumb title |
|
||||
| Open Graph | `_yoast_wpseo_opengraph-title` | OG title |
|
||||
| Open Graph | `_yoast_wpseo_opengraph-description` | OG description |
|
||||
| Open Graph | `_yoast_wpseo_opengraph-image` | OG image URL |
|
||||
| Open Graph | `_yoast_wpseo_opengraph-image-id` | OG image ID |
|
||||
| Twitter | `_yoast_wpseo_twitter-title` | Twitter title |
|
||||
| Twitter | `_yoast_wpseo_twitter-description` | Twitter description |
|
||||
| Twitter | `_yoast_wpseo_twitter-image` | Twitter image URL |
|
||||
| Twitter | `_yoast_wpseo_twitter-image-id` | Twitter image ID |
|
||||
|
||||
## Installation
|
||||
|
||||
### Method 1: Manual Upload via WordPress Admin
|
||||
### Method 1: Upload via WordPress Admin
|
||||
|
||||
1. Download the plugin folder
|
||||
2. Create a ZIP file: `seo-api-bridge.zip`
|
||||
3. Go to WordPress Admin → Plugins → Add New → Upload Plugin
|
||||
4. Upload the ZIP file and click "Install Now"
|
||||
5. Click "Activate Plugin"
|
||||
1. Download `seo-api-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/`
|
||||
2. Go to WordPress Admin → Plugins
|
||||
2. Go to WordPress Admin > Plugins
|
||||
3. Find "SEO API Bridge" and click "Activate"
|
||||
|
||||
### Method 3: WP-CLI
|
||||
|
||||
```bash
|
||||
# Via SSH to your WordPress container
|
||||
cd /var/www/html/wp-content/plugins/
|
||||
# Copy the plugin folder here
|
||||
wp plugin activate seo-api-bridge
|
||||
@@ -105,28 +93,46 @@ wp plugin activate seo-api-bridge
|
||||
|
||||
## REST API Endpoints
|
||||
|
||||
All endpoints require **WordPress Application Password** authentication.
|
||||
|
||||
### Status Endpoint
|
||||
|
||||
**GET** `/wp-json/seo-api-bridge/v1/status`
|
||||
|
||||
Check plugin status and detected SEO plugins.
|
||||
|
||||
```bash
|
||||
curl https://yoursite.com/wp-json/seo-api-bridge/v1/status
|
||||
curl -X GET "https://yoursite.com/wp-json/seo-api-bridge/v1/status" \
|
||||
-u "username:application_password"
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"plugin": "SEO API Bridge",
|
||||
"version": "1.3.0",
|
||||
"active": true,
|
||||
"seo_plugins": {
|
||||
"rank_math": { "active": true, "version": "1.0.257" },
|
||||
"yoast": { "active": false, "version": null }
|
||||
},
|
||||
"supported_post_types": ["post", "page", "product"],
|
||||
"message": "SEO API Bridge is active and working with Rank Math SEO."
|
||||
}
|
||||
```
|
||||
|
||||
### Post SEO Endpoints
|
||||
|
||||
**GET** `/wp-json/seo-api-bridge/v1/posts/{id}/seo`
|
||||
**GET** `/wp-json/seo-api-bridge/v1/posts/{id}/seo` — Get SEO metadata for a post
|
||||
|
||||
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/seo-api-bridge/v1/posts/{id}/seo` — Update SEO metadata for a post
|
||||
|
||||
```bash
|
||||
curl -X POST https://yoursite.com/wp-json/seo-api-bridge/v1/posts/123/seo \
|
||||
# Get post SEO
|
||||
curl -X GET "https://yoursite.com/wp-json/seo-api-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" \
|
||||
-u "username:application_password" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"focus_keyword": "wordpress", "seo_title": "My Title"}'
|
||||
```
|
||||
@@ -141,19 +147,38 @@ curl -X POST https://yoursite.com/wp-json/seo-api-bridge/v1/posts/123/seo \
|
||||
|
||||
**GET** `/wp-json/seo-api-bridge/v1/products/{id}/seo`
|
||||
|
||||
Get SEO metadata for a WooCommerce product.
|
||||
|
||||
**POST** `/wp-json/seo-api-bridge/v1/products/{id}/seo`
|
||||
|
||||
Update SEO metadata for a WooCommerce product.
|
||||
|
||||
```bash
|
||||
curl -X POST https://yoursite.com/wp-json/seo-api-bridge/v1/products/1217/seo \
|
||||
curl -X POST "https://yoursite.com/wp-json/seo-api-bridge/v1/products/1217/seo" \
|
||||
-u "username:application_password" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"focus_keyword": "product keyword", "seo_title": "Product Title"}'
|
||||
```
|
||||
|
||||
## Usage with MCP Servers
|
||||
### Alternative: Standard WordPress REST API
|
||||
|
||||
The plugin also registers all SEO meta fields on standard WordPress REST API endpoints. You can read/write SEO data directly via:
|
||||
|
||||
- `GET/POST /wp-json/wp/v2/posts/{id}` — SEO fields in the `meta` object
|
||||
- `GET/POST /wp-json/wp/v2/pages/{id}`
|
||||
- `GET/POST /wp-json/wp/v2/products/{id}` (WooCommerce)
|
||||
|
||||
```bash
|
||||
# Read SEO fields via standard endpoint
|
||||
curl -X GET "https://yoursite.com/wp-json/wp/v2/posts/123" \
|
||||
-u "username:application_password"
|
||||
|
||||
# Update SEO via standard endpoint
|
||||
curl -X POST "https://yoursite.com/wp-json/wp/v2/posts/123" \
|
||||
-u "username:application_password" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"meta": {"rank_math_focus_keyword": "wordpress optimization"}}'
|
||||
```
|
||||
|
||||
## Usage with MCP Hub
|
||||
|
||||
This plugin is designed to work with [MCP Hub](https://github.com/airano-ir/mcphub).
|
||||
|
||||
```javascript
|
||||
// Get product SEO
|
||||
@@ -172,244 +197,98 @@ await mcp.wordpress_update_product_seo({
|
||||
});
|
||||
```
|
||||
|
||||
**Benefits of this approach:**
|
||||
1. ✅ **WordPress Best Practice** - Uses recommended core REST API functionality
|
||||
2. ✅ **Zero Maintenance** - Leverages WordPress built-in features
|
||||
3. ✅ **Universal Compatibility** - Works with all WordPress REST API clients
|
||||
4. ✅ **Inherits Security** - Uses WordPress authentication and permissions
|
||||
5. ✅ **Simpler Code** - No custom endpoints to maintain
|
||||
|
||||
**Standard Endpoints:**
|
||||
- Posts/Pages: `/wp-json/wp/v2/posts/{id}` or `/wp-json/wp/v2/pages/{id}`
|
||||
- Products: `/wp-json/wp/v2/products/{id}` (WooCommerce custom post type)
|
||||
|
||||
**SEO data is in the `meta` object:**
|
||||
```json
|
||||
{
|
||||
"id": 123,
|
||||
"title": {"rendered": "My Post"},
|
||||
"meta": {
|
||||
"rank_math_focus_keyword": "wordpress seo",
|
||||
"rank_math_title": "Complete SEO Guide",
|
||||
"rank_math_description": "Learn WordPress SEO best practices..."
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Reading SEO Data
|
||||
|
||||
**Get Post with SEO Fields:**
|
||||
```bash
|
||||
GET /wp-json/wp/v2/posts/{id}
|
||||
```
|
||||
|
||||
**Response includes:**
|
||||
```json
|
||||
{
|
||||
"id": 123,
|
||||
"title": {"rendered": "My Post"},
|
||||
"meta": {
|
||||
"rank_math_focus_keyword": "wordpress seo",
|
||||
"rank_math_title": "Complete WordPress SEO Guide",
|
||||
"rank_math_description": "Learn how to optimize your WordPress site...",
|
||||
"rank_math_facebook_title": "SEO Guide for Facebook",
|
||||
"rank_math_twitter_card_type": "summary_large_image"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Writing SEO Data
|
||||
|
||||
**Update Post SEO Fields:**
|
||||
```bash
|
||||
POST /wp-json/wp/v2/posts/{id}
|
||||
Authorization: Basic [base64(username:application_password)]
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"meta": {
|
||||
"rank_math_focus_keyword": "wordpress optimization",
|
||||
"rank_math_title": "WordPress Optimization Tips",
|
||||
"rank_math_description": "Discover the best practices for WordPress optimization"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### WooCommerce Products
|
||||
|
||||
**Get Product with SEO:**
|
||||
```bash
|
||||
GET /wp-json/wp/v2/products/{id}
|
||||
```
|
||||
|
||||
**Update Product SEO:**
|
||||
```bash
|
||||
POST /wp-json/wp/v2/products/{id}
|
||||
{
|
||||
"meta": {
|
||||
"rank_math_focus_keyword": "premium widget",
|
||||
"rank_math_description": "Buy the best premium widget online"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Usage with MCP Server
|
||||
|
||||
This plugin is designed to work with the [MCP Hub](https://github.com/airano-ir/mcphub).
|
||||
|
||||
### Example MCP Tool Usage
|
||||
|
||||
```python
|
||||
# Get post SEO data
|
||||
result = await mcp.call_tool(
|
||||
"wordpress_site1_get_post_seo",
|
||||
{"post_id": 123}
|
||||
"wordpress_get_post_seo",
|
||||
{"site": "yoursite", "post_id": 123}
|
||||
)
|
||||
|
||||
# Update post SEO
|
||||
result = await mcp.call_tool(
|
||||
"wordpress_site1_update_post_seo",
|
||||
"wordpress_update_post_seo",
|
||||
{
|
||||
"site": "yoursite",
|
||||
"post_id": 123,
|
||||
"focus_keyword": "wordpress seo",
|
||||
"seo_title": "Complete SEO Guide",
|
||||
"meta_description": "Learn WordPress SEO..."
|
||||
}
|
||||
)
|
||||
|
||||
# Update WooCommerce product SEO
|
||||
result = await mcp.call_tool(
|
||||
"wordpress_site1_update_product_seo",
|
||||
{
|
||||
"product_id": 456,
|
||||
"focus_keyword": "premium widget",
|
||||
"meta_description": "Buy the best widget"
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## Verification
|
||||
|
||||
### Check if Plugin is Working
|
||||
1. **Admin Notice:** After activation, visit the Plugins page to see a status notice indicating which SEO plugin was detected.
|
||||
|
||||
1. **Admin Notice:** After activation, you should see a success notice indicating which SEO plugin was detected
|
||||
|
||||
2. **Health Check Endpoint (v1.1.0+):**
|
||||
2. **Status Endpoint:**
|
||||
```bash
|
||||
# Check plugin status directly
|
||||
curl -X GET "https://your-site.com/wp-json/seo-api-bridge/v1/status" \
|
||||
-u "username:application_password"
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"plugin": "SEO API Bridge",
|
||||
"version": "1.1.0",
|
||||
"active": true,
|
||||
"seo_plugins": {
|
||||
"rank_math": {
|
||||
"active": true,
|
||||
"version": "1.0.257"
|
||||
},
|
||||
"yoast": {
|
||||
"active": false,
|
||||
"version": null
|
||||
}
|
||||
},
|
||||
"supported_post_types": ["post", "page", "product"],
|
||||
"message": "SEO API Bridge is active and working with Rank Math SEO."
|
||||
}
|
||||
```
|
||||
|
||||
3. **REST API Test:**
|
||||
```bash
|
||||
# Get any post and check if meta fields are present
|
||||
curl -X GET "https://your-site.com/wp-json/wp/v2/posts/1" \
|
||||
-u "username:application_password"
|
||||
```
|
||||
|
||||
4. **MCP Health Check:** The MCP server will automatically detect the plugin using the new endpoint
|
||||
4. **MCP Health Check:** The MCP server automatically detects the plugin using the status endpoint.
|
||||
|
||||
## Security
|
||||
|
||||
- ✅ All meta fields require authentication via Application Passwords
|
||||
- ✅ Write access requires `edit_posts` capability
|
||||
- ✅ Read access follows WordPress post visibility rules
|
||||
- ✅ No sensitive data exposed without proper permissions
|
||||
- All meta fields require authentication via Application Passwords
|
||||
- Write access requires `edit_posts` capability
|
||||
- Read access follows WordPress post visibility rules
|
||||
- No sensitive data exposed without proper permissions
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### MCP Server Cannot Detect Plugin
|
||||
|
||||
**Issue:** MCP reports "SEO API Bridge plugin not detected" even though plugin is active
|
||||
|
||||
**Solution for v1.1.0+:**
|
||||
1. **Upgrade to v1.1.0** - This version adds a dedicated health check endpoint
|
||||
2. **Restart MCP server** - New detection logic will be used
|
||||
3. **Test endpoint directly:**
|
||||
```bash
|
||||
curl "https://your-site.com/wp-json/seo-api-bridge/v1/status" -u "user:pass"
|
||||
```
|
||||
|
||||
**Solution for v1.0.0 (legacy):**
|
||||
1. Create at least one post or product with SEO metadata set
|
||||
2. The old detection requires checking actual content meta fields
|
||||
3. Upgrade to v1.1.0 to avoid this requirement
|
||||
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"`
|
||||
|
||||
### SEO Plugin Not Detected
|
||||
|
||||
**Issue:** Admin notice says "Neither Rank Math SEO nor Yoast SEO is detected"
|
||||
|
||||
**Solution:**
|
||||
1. Verify Rank Math or Yoast SEO is installed and activated
|
||||
2. Try deactivating and reactivating SEO API Bridge
|
||||
3. Check PHP error logs for any warnings
|
||||
2. Deactivate and reactivate SEO API Bridge
|
||||
3. Check PHP error logs for warnings
|
||||
|
||||
### Meta Fields Not Appearing in REST API
|
||||
|
||||
**Issue:** `/wp-json/wp/v2/posts/{id}` doesn't show `meta` object
|
||||
|
||||
**Solution:**
|
||||
1. Ensure you're authenticated (use Application Password)
|
||||
2. Check that you have `edit_posts` permission
|
||||
2. Check user has `edit_posts` permission
|
||||
3. Verify the post type is supported (post, page, product)
|
||||
|
||||
### Fields Are Read-Only
|
||||
|
||||
**Issue:** Can read SEO fields but cannot update them
|
||||
|
||||
**Solution:**
|
||||
1. Verify authentication credentials
|
||||
2. Check user has `edit_posts` capability
|
||||
3. Ensure you're using POST/PUT request, not GET
|
||||
|
||||
## Compatibility
|
||||
|
||||
- ✅ WordPress 5.0+
|
||||
- ✅ PHP 7.4+
|
||||
- ✅ Rank Math SEO 1.0+
|
||||
- ✅ Yoast SEO 14.0+
|
||||
- ✅ WooCommerce 5.0+ (for product support)
|
||||
- ✅ Classic Editor & Gutenberg
|
||||
- ✅ Multisite compatible
|
||||
|
||||
## Support
|
||||
|
||||
For issues related to:
|
||||
- **This plugin:** [GitHub Issues](https://github.com/airano-ir/mcphub/issues)
|
||||
- **MCP Server:** [MCP Server Documentation](https://github.com/airano-ir/mcphub)
|
||||
- **Rank Math SEO:** [Rank Math Support](https://rankmath.com/support/)
|
||||
- **Yoast SEO:** [Yoast Support](https://yoast.com/help/)
|
||||
- WordPress 5.0+
|
||||
- PHP 7.4+
|
||||
- Rank Math SEO 1.0+
|
||||
- Yoast SEO 14.0+
|
||||
- WooCommerce 5.0+ (for product support)
|
||||
- Classic Editor & Gutenberg
|
||||
- Multisite compatible
|
||||
|
||||
## Changelog
|
||||
|
||||
### 1.3.0 (2025-02-18)
|
||||
- Added REST API endpoints for posts, pages, and products (GET/POST operations)
|
||||
- Added authentication requirement for all endpoints
|
||||
- Fixed `rank_math_title` meta key registration
|
||||
- Fixed output escaping for WordPress.org compliance
|
||||
|
||||
### 1.2.0 (2025-02-15)
|
||||
- Enhanced WooCommerce product support
|
||||
- Improved MariaDB compatibility for meta field queries
|
||||
|
||||
### 1.1.0 (2025-01-10)
|
||||
- 🎉 **NEW:** Health check REST API endpoint `/seo-api-bridge/v1/status`
|
||||
- 🎉 **NEW:** Direct plugin detection without requiring posts/products
|
||||
- 🎉 **IMPROVEMENT:** Better compatibility with sites that have no content
|
||||
- 🎉 **IMPROVEMENT:** Returns SEO plugin versions in status endpoint
|
||||
- 🎉 **FIX:** MCP server can now detect plugin even with zero posts
|
||||
- Added health check REST API endpoint `/seo-api-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
|
||||
|
||||
### 1.0.0 (2025-01-10)
|
||||
- Initial release
|
||||
@@ -417,12 +296,14 @@ For issues related to:
|
||||
- Yoast SEO support (15 meta fields)
|
||||
- WooCommerce product support
|
||||
- Auto-detection of active SEO plugins
|
||||
- Admin notices for status
|
||||
|
||||
## Support
|
||||
|
||||
- **Plugin issues:** [GitHub Issues](https://github.com/airano-ir/mcphub/issues)
|
||||
- **MCP Server:** [MCP Hub Documentation](https://github.com/airano-ir/mcphub)
|
||||
- **Rank Math SEO:** [Rank Math Support](https://rankmath.com/support/)
|
||||
- **Yoast SEO:** [Yoast Support](https://yoast.com/help/)
|
||||
|
||||
## License
|
||||
|
||||
GPLv2 or later - See [LICENSE](https://www.gnu.org/licenses/gpl-2.0.html) for details
|
||||
|
||||
## Credits
|
||||
|
||||
Developed for use with MCP Hub to enable AI-powered SEO content management.
|
||||
|
||||
@@ -674,13 +674,19 @@ class SEO_API_Bridge {
|
||||
* Display admin notices
|
||||
*/
|
||||
public function admin_notices() {
|
||||
// Only show notices on the Plugins page to avoid clutter on every admin page
|
||||
$screen = get_current_screen();
|
||||
if ( ! $screen || $screen->id !== 'plugins' ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$rank_math_active = $this->is_rank_math_active();
|
||||
$yoast_active = $this->is_yoast_active();
|
||||
$woocommerce_active = $this->is_woocommerce_active();
|
||||
|
||||
if (!$rank_math_active && !$yoast_active) {
|
||||
echo '<div class="notice notice-warning is-dismissible">';
|
||||
echo '<p><strong>SEO API Bridge:</strong> Neither Rank Math SEO nor Yoast SEO is detected. Please install and activate one of these plugins to enable SEO meta field access via REST API.</p>';
|
||||
echo '<p><strong>SEO API Bridge:</strong> ' . esc_html__( 'Neither Rank Math SEO nor Yoast SEO is detected. Please install and activate one of these plugins to enable SEO meta field access via REST API.', 'seo-api-bridge' ) . '</p>';
|
||||
echo '</div>';
|
||||
} else {
|
||||
$active_plugins = [];
|
||||
@@ -691,10 +697,10 @@ class SEO_API_Bridge {
|
||||
|
||||
echo '<div class="notice notice-success is-dismissible">';
|
||||
echo '<p><strong>SEO API Bridge v' . esc_html( self::VERSION ) . ':</strong> ' . esc_html( sprintf( 'Successfully registered meta fields for %s.', implode( ' and ', $active_plugins ) ) ) . '</p>';
|
||||
echo '<p><strong>Supported post types:</strong> ' . esc_html( $supported_types ) . '</p>';
|
||||
echo '<p><strong>' . esc_html__( 'Supported post types:', 'seo-api-bridge' ) . '</strong> ' . esc_html( $supported_types ) . '</p>';
|
||||
|
||||
if ($woocommerce_active) {
|
||||
echo '<p><strong>WooCommerce:</strong> Detected and supported. Product SEO fields are available via REST API.</p>';
|
||||
echo '<p><strong>WooCommerce:</strong> ' . esc_html__( 'Detected and supported. Product SEO fields are available via REST API.', 'seo-api-bridge' ) . '</p>';
|
||||
}
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user