diff --git a/CHANGELOG.md b/CHANGELOG.md index e5a7026..42f43e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,7 +30,7 @@ After 2-month hiatus (Dec 2025 - Feb 2026), updated all dependencies and verifie - All 54 tests now pass (previously 5 were failing) #### Verified -- All 589 tools generate correctly +- All 596 tools generate correctly - Middleware API stable (Middleware, MiddlewareContext, get_http_headers) - 30+ custom routes operational (dashboard + OAuth) - Multi-endpoint architecture functional diff --git a/CLAUDE.md b/CLAUDE.md index d1b7dc2..0a04393 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ## Project Overview -**MCP Hub** — a Python MCP (Model Context Protocol) server that manages multiple self-hosted projects through a unified plugin architecture. Supports 9 plugin types (WordPress, WooCommerce, WordPress Advanced, Gitea, n8n, Supabase, OpenPanel, Appwrite, Directus) with ~589 tools total. The tool count stays constant regardless of how many sites are configured. +**MCP Hub** — a Python MCP (Model Context Protocol) server that manages multiple self-hosted services through a unified plugin architecture. Supports 9 plugin types (WordPress, WooCommerce, WordPress Advanced, Gitea, n8n, Supabase, OpenPanel, Appwrite, Directus) with 596 tools total. The tool count stays constant regardless of how many sites are configured. ## Quick Setup diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 23cd273..1568d44 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -119,8 +119,8 @@ 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) -templates/ # Jinja2 templates (dashboard + OAuth) -tests/ # Test suite (289 tests) +core/templates/ # Jinja2 templates (dashboard + OAuth) +tests/ # Test suite (290 tests) scripts/ # Setup & deployment scripts docs/ # Documentation ``` diff --git a/DOCKER_README.md b/DOCKER_README.md index 6b8f4a5..e6f698a 100644 --- a/DOCKER_README.md +++ b/DOCKER_README.md @@ -2,7 +2,7 @@ **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. +596 tools across 9 plugins. Connect your sites, stores, repos, and databases — manage them all through Claude, ChatGPT, Cursor, or any MCP client. ## Quick Start diff --git a/README.md b/README.md index 019d891..fec8ef1 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Connect your sites, stores, repos, and databases — manage them all through Cla [![PyPI](https://img.shields.io/pypi/v/mcphub-server.svg)](https://pypi.org/project/mcphub-server/) [![Docker](https://img.shields.io/docker/v/airano/mcphub?label=docker)](https://hub.docker.com/r/airano/mcphub) [![Tests: 289 passing](https://img.shields.io/badge/tests-289%20passing-brightgreen.svg)]() -[![Tools: 589](https://img.shields.io/badge/tools-589-orange.svg)]() +[![Tools: 596](https://img.shields.io/badge/tools-596-orange.svg)]() [![CI](https://github.com/airano-ir/mcphub/actions/workflows/ci.yml/badge.svg)](https://github.com/airano-ir/mcphub/actions/workflows/ci.yml) @@ -46,7 +46,7 @@ MCP Hub is the first MCP server that lets you manage WordPress, WooCommerce, and --- -## 589 Tools Across 9 Plugins +## 596 Tools Across 9 Plugins | Plugin | Tools | What You Can Do | |--------|-------|-----------------| @@ -59,8 +59,8 @@ MCP Hub is the first MCP server that lets you manage WordPress, WooCommerce, and | **OpenPanel** | 73 | Events, funnels, profiles, dashboards, projects | | **Appwrite** | 100 | Databases, auth, storage, functions, teams, messaging | | **Directus** | 100 | Collections, items, users, files, flows, permissions | -| **System** | 17 | Health monitoring, API keys, project discovery | -| **Total** | **589** | Constant count — scales to unlimited sites | +| **System** | 24 | Health monitoring, API keys, OAuth management, audit | +| **Total** | **596** | Constant count — scales to unlimited sites | --- @@ -224,8 +224,8 @@ MCP Hub supports **Open Dynamic Client Registration** (RFC 7591). ChatGPT can au ## Architecture ``` -/mcp → Admin endpoint (all 589 tools) -/system/mcp → System tools only (17 tools) +/mcp → Admin endpoint (all 596 tools) +/system/mcp → System tools only (24 tools) /wordpress/mcp → WordPress tools (67 tools) /woocommerce/mcp → WooCommerce tools (28 tools) /gitea/mcp → Gitea tools (56 tools) diff --git a/core/dashboard/routes.py b/core/dashboard/routes.py index 90e85d1..d95161b 100644 --- a/core/dashboard/routes.py +++ b/core/dashboard/routes.py @@ -157,15 +157,10 @@ DASHBOARD_TRANSLATIONS = { def detect_language(accept_language: str | None, query_lang: str | None = None) -> str: - """Detect language from Accept-Language header or query parameter.""" + """Detect language from query parameter. Default is English.""" if query_lang and query_lang in DASHBOARD_TRANSLATIONS: return query_lang - if accept_language: - # Check for Persian/Farsi - if "fa" in accept_language.lower() or "fa-ir" in accept_language.lower(): - return "fa" - return "en" diff --git a/core/endpoints/config.py b/core/endpoints/config.py index ce39d4d..e929a5c 100644 --- a/core/endpoints/config.py +++ b/core/endpoints/config.py @@ -107,7 +107,7 @@ ENDPOINT_CONFIGS = { allowed_scopes={"admin"}, max_tools=400, ), - # System endpoint - system tools only (17 tools) - Phase X.3 + # System endpoint - system tools only (24 tools) # For API key management, OAuth, rate limiting without loading all plugins EndpointType.SYSTEM: EndpointConfig( path="/system", diff --git a/core/templates/oauth/error.html b/core/templates/oauth/error.html index 4968441..8082fdb 100644 --- a/core/templates/oauth/error.html +++ b/core/templates/oauth/error.html @@ -79,7 +79,7 @@

{{ t.need_help }} - {{ t.documentation }} + {{ t.documentation }}

diff --git a/docs/getting-started.md b/docs/getting-started.md index a6a0f89..10ec351 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -202,7 +202,7 @@ After starting (via Docker or locally), wait ~30 seconds for the server to initi ```bash curl http://localhost:8000/health -# Expected: {"status": "ok", "tools_loaded": 589, ...} +# Expected: {"status": "ok", "tools_loaded": 596, ...} ``` **2. Open the web dashboard:** @@ -313,7 +313,7 @@ MCP Hub supports **Open Dynamic Client Registration** (RFC 7591). ChatGPT can au ## Using MCP Tools -### 589 Tools Across 9 Plugins +### 596 Tools Across 9 Plugins | Plugin | Tools | Env Prefix | |--------|-------|------------| @@ -326,7 +326,7 @@ MCP Hub supports **Open Dynamic Client Registration** (RFC 7591). ChatGPT can au | OpenPanel | 73 | `OPENPANEL_` | | Appwrite | 100 | `APPWRITE_` | | Directus | 100 | `DIRECTUS_` | -| System | 17 | (no config needed) | +| System | 24 | (no config needed) | ### Unified Tool Pattern @@ -346,8 +346,8 @@ The `site` parameter accepts either a **site_id** (e.g., `site1`) or an **alias* Use specific endpoints to limit tool access: ``` -/mcp → All 589 tools (Master API Key) -/system/mcp → System tools only (17 tools) +/mcp → All 596 tools (Master API Key) +/system/mcp → System tools only (24 tools) /wordpress/mcp → WordPress tools (67 tools) /woocommerce/mcp → WooCommerce tools (28 tools) /gitea/mcp → Gitea tools (56 tools) @@ -448,7 +448,7 @@ The server auto-discovers all `WORDPRESS_*`, `WOOCOMMERCE_*`, `GITEA_*`, and oth ## Next Steps -1. **Explore the full tool list**: See the [README](../README.md) for all 589 tools +1. **Explore the full tool list**: See the [README](../README.md) for all 596 tools 2. **Set up API keys**: [API Keys Guide](API_KEYS_GUIDE.md) for per-project access control 3. **Configure OAuth**: [OAuth Guide](OAUTH_GUIDE.md) for Claude/ChatGPT auto-registration 4. **Monitor health**: Use `check_all_projects_health` tool or visit the web dashboard diff --git a/server.py b/server.py index f7d49d7..056f5a0 100644 --- a/server.py +++ b/server.py @@ -1804,10 +1804,12 @@ def register_project_tools(): logger.info("=" * 60) - # System tools count (health + rate limit + API keys): - # - 10 system/health/rate limit tools + # System tools count: + # - 10 health/monitoring/rate-limit tools + # - 4 system config tools (endpoints, system_info, audit_log, set_rate_limit_config) # - 6 API key management tools - system_tools_count = 16 + # - 4 OAuth management tools + system_tools_count = 24 total_tools = tool_registry.get_count() + system_tools_count logger.info( @@ -3338,7 +3340,7 @@ def create_system_mcp(): """ from fastmcp import FastMCP - system_instructions = """This is the System Management endpoint (17 tools). + system_instructions = """This is the System Management endpoint (24 tools). Available tools: • API Key Management: create, list, get_info, revoke, delete, rotate @@ -3455,7 +3457,7 @@ Use get_endpoints() to see all available MCP endpoints.""" requests_per_minute, requests_per_hour, requests_per_day ) - logger.info("Created System endpoint with 17 tools") + logger.info("Created System endpoint with 24 tools") return system_mcp @@ -4277,21 +4279,21 @@ def create_multi_endpoint_app(transport: str = "streamable-http"): app = Starlette(routes=routes, lifespan=combined_lifespan, middleware=middleware) logger.info("=" * 60) - logger.info("Multi-Endpoint Architecture (Phase K) Active") + logger.info("Multi-Endpoint Architecture Active") logger.info("=" * 60) - logger.info("Dashboard: /dashboard") # Phase K + logger.info("Dashboard: /dashboard") logger.info("Endpoints:") - logger.info(" /mcp - Admin (all 589 tools)") - logger.info(" /system/mcp - System (17 tools)") + logger.info(f" /mcp - Admin (all {_total_tool_count} tools)") + logger.info(" /system/mcp - System (24 tools)") logger.info(" /wordpress/mcp - WordPress Core (67 tools)") - logger.info(" /woocommerce/mcp - WooCommerce (28 tools)") # Phase D.1 + logger.info(" /woocommerce/mcp - WooCommerce (28 tools)") logger.info(" /wordpress-advanced/mcp - WordPress Advanced (22 tools)") logger.info(" /gitea/mcp - Gitea (56 tools)") - logger.info(" /n8n/mcp - n8n Automation (56 tools)") # Phase F - logger.info(" /supabase/mcp - Supabase (70 tools)") # Phase G - logger.info(" /openpanel/mcp - OpenPanel Analytics (73 tools)") # Phase H - logger.info(" /appwrite/mcp - Appwrite Backend (100 tools)") # Phase I - logger.info(" /directus/mcp - Directus CMS (100 tools)") # Phase J + logger.info(" /n8n/mcp - n8n Automation (56 tools)") + logger.info(" /supabase/mcp - Supabase (70 tools)") + logger.info(" /openpanel/mcp - OpenPanel Analytics (73 tools)") + logger.info(" /appwrite/mcp - Appwrite Backend (100 tools)") + logger.info(" /directus/mcp - Directus CMS (100 tools)") # Log per-project endpoints if project_apps: diff --git a/tests/test_dashboard.py b/tests/test_dashboard.py index 4be9fdd..229b2c6 100644 --- a/tests/test_dashboard.py +++ b/tests/test_dashboard.py @@ -64,22 +64,18 @@ class TestPluginDisplayNames: class TestLanguageDetection: - """Test language detection from headers and query params.""" + """Test language detection from query params (default English).""" def test_default_english(self): """Should default to English.""" assert detect_language(None) == "en" - def test_detect_farsi_from_header(self): - """Should detect Farsi from Accept-Language header.""" - assert detect_language("fa-IR,fa;q=0.9,en;q=0.8") == "fa" + def test_header_ignored(self): + """Accept-Language header should be ignored (always default to English).""" + assert detect_language("fa-IR,fa;q=0.9,en;q=0.8") == "en" - def test_detect_farsi_short(self): - """Should detect 'fa' in Accept-Language.""" - assert detect_language("fa") == "fa" - - def test_query_param_overrides_header(self): - """Query parameter should override Accept-Language header.""" + def test_query_param_farsi(self): + """Should detect Farsi from explicit query parameter.""" assert detect_language("en-US", query_lang="fa") == "fa" def test_query_param_english(self): @@ -87,8 +83,8 @@ class TestLanguageDetection: assert detect_language("fa-IR", query_lang="en") == "en" def test_invalid_query_lang_ignored(self): - """Invalid query lang should be ignored, fall back to header.""" - assert detect_language("fa-IR", query_lang="de") == "fa" + """Invalid query lang should be ignored, default to English.""" + assert detect_language("fa-IR", query_lang="de") == "en" def test_english_header(self): """Should return English for English header."""