docs: add architecture doc

This commit is contained in:
2026-05-31 12:40:56 +00:00
parent 262bcb0daf
commit 289f611f11
+177
View File
@@ -0,0 +1,177 @@
# Architecture
## Directory Structure
```
advanced-mcp-plugin/
├── advanced-mcp-plugin.php ← Entry point, autoloader, boot
├── docs/ ← This documentation
└── includes/
├── Core/
│ ├── Auth.php ← Bearer token auth, HTTPS, rate limit, scope
│ ├── AdminMenu.php ← WP Admin UI (API Keys, Settings, Audit Log tabs)
│ ├── TokenManager.php ← HMAC-SHA256 JWT, JTI revocation, secret rotation
│ └── Installer.php ← DB table creation on activation
├── MCP/
│ ├── Server.php ← MCP protocol: initialize / tools/list / tools/call
│ └── Registry.php ← Maps tool names → handlers + schemas
├── Tools/
│ ├── PostTools.php
│ ├── PageTools.php
│ ├── MediaTools.php
│ ├── UserTools.php
│ ├── CommentTools.php
│ ├── MenuTools.php
│ ├── TaxonomyTools.php
│ ├── OptionTools.php
│ ├── SiteTools.php
│ ├── PluginTools.php
│ ├── ThemeTools.php
│ ├── ThemeDiscoveryTools.php
│ ├── SeoTools.php
│ ├── WooTools.php
│ ├── EmailTools.php
│ ├── FileManagerTools.php
│ ├── CliTools.php
│ ├── RawSqlTools.php
│ ├── TransientTools.php
│ ├── WidgetTools.php
│ ├── ToolHandlers.php ← Master registry: all 123 tools with schemas + scopes
│ └── WooTools.php
└── Elementor/
├── Abilities/
│ └── ElementorTools.php ← All 30 Elementor build tools
└── Data/
└── ElementorData.php ← Read/write Elementor JSON — critical CLI fix
```
---
## Request Flow
```
MCP Client (Claude)
│
▼
POST /wp-json/asktam-mcp/v1/mcp
│
▼
Server.php::handle()
├── Auth::validate() ← Bearer JWT + scope + rate limit
│ ├── extract token from Authorization header
│ ├── TokenManager::verify() — HMAC-SHA256, exp, iss, jti
│ ├── scope check against requested tool's required scope
│ └── rate limit via transient (60 req/min default)
│
├── method = "initialize" → return server info
├── method = "tools/list" → Registry::getTools()
└── method = "tools/call"
│
▼
Registry::getHandler($tool_name)
│
▼
Tool class method($args)
│
▼
JSON response
```
---
## Authentication Detail
Every request requires:
```
Authorization: Bearer <jwt_token>
```
**JWT payload:**
```json
{
"key_id": 3,
"iss": "https://mainwp.asktam.net",
"exp": 1234567890,
"jti": "unique-token-id"
}
```
**Signing:** HMAC-SHA256 with 64-char hex secret stored in `wp_options.asktam_mcp_jwt_secret`.
**Verification (TokenManager.php):**
1. Split JWT into header.payload.signature
2. Recompute HMAC and compare with `hash_equals()` (timing-safe)
3. Check `exp` > `time()`
4. Check `iss` matches `get_site_url()`
5. Check `jti` not in revocation list
6. Load API key from DB by `key_id`, confirm `is_active = 1`
**API Keys** stored in `mwp_asktam_mcp_keys`:
```sql
id, name, key_hash (bcrypt), scopes (comma-separated), is_active, created_at, last_used
```
---
## Scopes
| Scope | Access |
|---|---|
| `read` | GET / list operations |
| `write` | Create, update, delete |
| `admin` | Plugin management, raw SQL, CLI, options |
| `elementor` | All Elementor builder tools |
| `woo` | WooCommerce tools |
Each tool in `ToolHandlers.php` declares a required scope. Auth.php enforces it before dispatch.
---
## DB Tables Created on Activation
```sql
-- API keys
CREATE TABLE mwp_asktam_mcp_keys (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
key_hash VARCHAR(255) NOT NULL,
scopes VARCHAR(500) DEFAULT 'read',
is_active TINYINT(1) DEFAULT 1,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
last_used DATETIME DEFAULT NULL
);
-- Audit log
CREATE TABLE mwp_asktam_mcp_log (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
key_id BIGINT UNSIGNED DEFAULT NULL,
tool_name VARCHAR(100) NOT NULL,
ip_address VARCHAR(45) DEFAULT NULL,
status VARCHAR(20) DEFAULT 'success',
duration FLOAT DEFAULT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
```
---
## WP Admin Panel
**Location:** WP Admin → AskTam MCP (top-level menu)
| Tab | Purpose |
|---|---|
| API Keys | Generate JWT tokens, set scopes, revoke keys |
| Settings | HTTPS enforcement, rate limit, request logging, raw SQL toggle |
| Audit Log | Last 1000 tool calls: key_id, tool, IP, timestamp |
---
## Namespace
`AskTamMCP\` — PSR-4 autoloader registered in `advanced-mcp-plugin.php`.
All classes map to `includes/` directory:
- `AskTamMCP\Core\Auth` → `includes/Core/Auth.php`
- `AskTamMCP\Tools\PostTools` → `includes/Tools/PostTools.php`
- `AskTamMCP\Elementor\Abilities\ElementorTools` → `includes/Elementor/Abilities/ElementorTools.php`