Initial commit: MCP Hub Community Edition v3.0.0

Community edition generated from private repo via sync pipeline.
Includes 9 plugins (WordPress, WooCommerce, WP Advanced, Gitea, n8n,
Supabase, OpenPanel, Appwrite, Directus) with ~587 tools.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
airano
2026-02-17 08:34:44 +03:30
commit cf62e65c55
237 changed files with 87596 additions and 0 deletions

585
docs/API_KEYS_GUIDE.md Normal file
View File

@@ -0,0 +1,585 @@
# 🔐 API Keys Management Guide
Complete guide for managing API keys in MCP Hub.
---
## Table of Contents
- [Overview](#overview)
- [Key Types](#key-types)
- [Scopes & Permissions](#scopes--permissions)
- [Creating Keys](#creating-keys)
- [Managing Keys](#managing-keys)
- [Best Practices](#best-practices)
- [Examples](#examples)
- [Troubleshooting](#troubleshooting)
---
## Overview
MCP Hub supports two types of API keys for authentication:
1. **Master API Key** - Full access to all operations and projects
2. **Per-Project API Keys** - Scoped access with granular permissions
Per-project keys provide:
-**Project-level isolation** - Limit access to specific projects
-**Scope-based permissions** - Control read/write/admin operations
-**Expiration support** - Automatic key rotation
-**Usage tracking** - Monitor key usage and last access
-**Audit trail** - All key operations are logged
-**Easy rotation** - Rotate all keys for a project with one command
---
## Key Types
### Master API Key
- **Source**: `MASTER_API_KEY` environment variable
- **Access Level**: Full admin access to all projects
- **Use Case**: Server administration, initial setup
- **Lifetime**: Permanent (until manually changed)
- **Format**: Any string (recommended: 32+ characters)
**Example**:
```bash
MASTER_API_KEY=your_secure_master_key_here
```
### Per-Project API Keys
- **Storage**: JSON file (`data/api_keys.json`)
- **Access Level**: Configurable per key (read/write/admin)
- **Use Case**: Application integration, team access, CI/CD
- **Lifetime**: Optional expiration (days)
- **Format**: `cmp_` prefix + random string
**Example**:
```
cmp_AQECAHhoZXJlIGlzIGEgcmFuZG9tIGtleQ
```
---
## Scopes & Permissions
### Read Scope
**Per-Project Keys** (`project_id` specific):
- ✅ List and get operations for assigned project
- ✅ Read WordPress content (posts, pages, comments, media)
- ✅ Read WooCommerce data (products, orders, customers)
- ✅ Read taxonomies, menus, and settings
- ❌ Cannot access system tools (requires global key)
- ❌ Cannot create, update, or delete
**Tools Allowed**:
- `wordpress_list_posts`, `wordpress_get_post`
- `wordpress_list_products`, `wordpress_get_product`
- `wordpress_list_orders`, `wordpress_get_order`
- All WordPress/WooCommerce `get_*` and `list_*` tools
**Global Keys** (`project_id="*"`):
- ✅ All per-project permissions for ALL projects
- ✅ System tools: `list_projects`, `get_project_info`
- ✅ Monitoring: `check_all_projects_health`, `get_system_metrics`
- ✅ Rate limits: `get_rate_limit_stats`
- ✅ API Keys: `manage_api_keys_list` (read-only)
**Use Cases**:
- **Per-Project**: Client access to their specific site
- **Global**: Admin dashboards, monitoring, analytics
### Write Scope
**Per-Project Keys**:
- ✅ All read operations for assigned project
- ✅ Create, update, delete content
- ✅ Upload and modify media
- ✅ Manage products, orders, customers
- ❌ Cannot access system tools (requires global key)
- ❌ Cannot manage API keys or system settings
**Tools Allowed**:
- All read scope tools for the project, plus:
- `wordpress_create_post`, `wordpress_update_post`, `wordpress_delete_post`
- `wordpress_create_product`, `wordpress_update_product`
- `wordpress_create_order`, `wordpress_update_order_status`
- `wordpress_upload_media_from_url`
- All `create_*`, `update_*`, `delete_*` tools for the project
**Global Keys** (`project_id="*"`):
- ✅ All per-project permissions for ALL projects
- ✅ System tools access (read-only)
**Use Cases**:
- **Per-Project**: Client content management for their site
- **Global**: Multi-site management, automated publishing
### Admin Scope
**Per-Project Keys**:
- ✅ All read and write operations for assigned project
- ✅ Advanced WordPress management (WP-CLI tools)
- ✅ Database operations (check, optimize, export)
- ❌ Cannot access system tools (requires global key)
- ❌ Cannot manage API keys (requires global key)
**Global Keys** (`project_id="*"`):
- ✅ All per-project permissions for ALL projects
- ✅ Full system access: `manage_api_keys_*`, `reset_rate_limit`
- ✅ System monitoring and administration
- ✅ Health metrics export
**Tools Allowed**:
- All read and write scope tools, plus:
- `manage_api_keys_*` tools (global keys only)
- `reset_rate_limit` (global keys only)
- `export_health_metrics`
- WP-CLI tools: `wp_cache_flush`, `wp_db_optimize`, etc.
**Use Cases**:
- **Per-Project**: Full site administration for specific client
- **Global**: Platform administration, multi-tenant management
- System maintenance
---
## Creating Keys
### Basic Key Creation
Create a read-only key for a specific project:
```python
result = manage_api_keys_create(
project_id="wordpress_site1",
scope="read"
)
# Save the key - it won't be shown again!
api_key = result["key"] # cmp_...
key_id = result["key_id"] # key_...
```
### Key with Description
Add a description for better organization:
```python
result = manage_api_keys_create(
project_id="wordpress_site1",
scope="write",
description="CI/CD pipeline key for automated deployments"
)
```
### Expiring Key
Create a temporary key that expires after 30 days:
```python
result = manage_api_keys_create(
project_id="wordpress_site2",
scope="read",
expires_in_days=30,
description="Temporary access for contractor"
)
```
### Global Key
Create a key that works for all projects:
```python
result = manage_api_keys_create(
project_id="*", # All projects
scope="admin",
description="Backup admin key"
)
```
---
## Managing Keys
### List All Keys
```python
result = manage_api_keys_list()
print(f"Total keys: {result['total']}")
for key in result['keys']:
print(f"- {key['key_id']}: {key['project_id']} ({key['scope']})")
```
### List Keys for Specific Project
```python
result = manage_api_keys_list(
project_id="wordpress_site1"
)
```
### Include Revoked Keys
```python
result = manage_api_keys_list(
include_revoked=True
)
```
### Get Key Information
```python
result = manage_api_keys_get_info(
key_id="key_abc123"
)
if result['success']:
key_info = result['key']
print(f"Project: {key_info['project_id']}")
print(f"Scope: {key_info['scope']}")
print(f"Created: {key_info['created_at']}")
print(f"Last used: {key_info['last_used_at']}")
print(f"Usage count: {key_info['usage_count']}")
print(f"Valid: {key_info['valid']}")
```
### Revoke a Key
Soft delete (can view in history):
```python
result = manage_api_keys_revoke(
key_id="key_abc123"
)
```
### Delete a Key
Permanent deletion:
```python
result = manage_api_keys_delete(
key_id="key_abc123"
)
```
### Rotate All Project Keys
Create new keys and revoke old ones:
```python
result = manage_api_keys_rotate(
project_id="wordpress_site1"
)
# Save the new keys!
for new_key in result['new_keys']:
print(f"New key: {new_key['key']}")
print(f"Scope: {new_key['scope']}")
```
---
## Best Practices
### 1. Use Principle of Least Privilege
**❌ Don't**:
```python
# Giving admin access when read is enough
manage_api_keys_create("wordpress_site1", scope="admin")
```
**✅ Do**:
```python
# Use minimal required scope
manage_api_keys_create("wordpress_site1", scope="read")
```
### 2. Set Expiration for Temporary Access
**❌ Don't**:
```python
# Permanent key for temporary contractor
manage_api_keys_create("wordpress_site1", scope="write")
```
**✅ Do**:
```python
# Expiring key for contractor
manage_api_keys_create(
"wordpress_site1",
scope="write",
expires_in_days=90,
description="Q4 contractor access"
)
```
### 3. Use Descriptive Names
**❌ Don't**:
```python
manage_api_keys_create("wordpress_site1", "write")
```
**✅ Do**:
```python
manage_api_keys_create(
"wordpress_site1",
scope="write",
description="Production deployment key for CI/CD pipeline"
)
```
### 4. Regular Key Rotation
Rotate keys quarterly or after team changes:
```python
# Every 3 months
result = manage_api_keys_rotate("wordpress_site1")
# Update all integrations with new keys
for key in result['new_keys']:
# Update CI/CD, monitoring tools, etc.
update_integration(key['key'])
```
### 5. Monitor Key Usage
```python
# Check if keys are being used
result = manage_api_keys_list()
for key in result['keys']:
if key['usage_count'] == 0:
print(f"Warning: Key {key['key_id']} has never been used")
if key['last_used_at']:
# Check if key hasn't been used in 30+ days
# Consider revoking inactive keys
pass
```
### 6. Revoke Compromised Keys Immediately
```python
# If a key is compromised
manage_api_keys_revoke("key_compromised")
# Create a new key
new_key = manage_api_keys_create(
"wordpress_site1",
scope="write",
description="Replacement for compromised key"
)
```
---
## Examples
### Example 1: CI/CD Pipeline
```python
# 1. Create a write-scoped key for CI/CD
result = manage_api_keys_create(
project_id="wordpress_site1",
scope="write",
description="GitHub Actions deployment key"
)
ci_key = result['key']
# 2. Add to GitHub Secrets as MCP_API_KEY
# 3. Use in workflow:
# headers = {"Authorization": f"Bearer {os.getenv('MCP_API_KEY')}"}
```
### Example 2: Monitoring Dashboard
```python
# Create read-only key for monitoring
result = manage_api_keys_create(
project_id="*", # All projects
scope="read",
description="Grafana monitoring dashboard"
)
monitoring_key = result['key']
# Use for health checks, metrics collection
```
### Example 3: Team Member Access
```python
# Create keys for team members
team_keys = {}
for member in ["alice", "bob", "charlie"]:
result = manage_api_keys_create(
project_id="wordpress_site1",
scope="write",
description=f"Key for {member}"
)
team_keys[member] = result['key']
# Distribute keys securely (1Password, etc.)
```
### Example 4: Temporary Contractor Access
```python
# 90-day expiring key for contractor
result = manage_api_keys_create(
project_id="wordpress_site2",
scope="read",
expires_in_days=90,
description="Contractor access - expires Q1 2026"
)
contractor_key = result['key']
# Key automatically becomes invalid after 90 days
```
### Example 5: Key Rotation Schedule
```python
# Quarterly rotation script
import schedule
def rotate_all_projects():
projects = ["wordpress_site1", "wordpress_site2", "wordpress_site3"]
for project in projects:
result = manage_api_keys_rotate(project)
print(f"Rotated {result['rotated_count']} keys for {project}")
# Email new keys to team
notify_team(project, result['new_keys'])
# Run every 90 days
schedule.every(90).days.do(rotate_all_projects)
```
---
## Troubleshooting
### Key Not Working
**Problem**: API key returns "Authentication failed"
**Solutions**:
1. Check if key is revoked:
```python
info = manage_api_keys_get_info("key_abc123")
if info['key']['revoked']:
print("Key has been revoked")
```
2. Check if key expired:
```python
if info['key']['expired']:
print("Key has expired")
```
3. Verify scope matches operation:
```python
# Read-only key cannot write
if info['key']['scope'] == 'read':
print("Cannot use read key for write operations")
```
### Key Not Found
**Problem**: "Key not found: key_abc123"
**Solution**: List all keys to find correct ID:
```python
result = manage_api_keys_list(include_revoked=True)
for key in result['keys']:
print(f"{key['key_id']}: {key['description']}")
```
### Permission Denied
**Problem**: "Insufficient scope"
**Solution**: Check required scope for operation:
```python
# Operation requires 'write' but key has 'read'
# Create new key with correct scope:
manage_api_keys_create(project_id="site1", scope="write")
```
### Storage File Issues
**Problem**: "Failed to load keys" or "Failed to save keys"
**Solutions**:
1. Check file permissions:
```bash
ls -l data/api_keys.json
chmod 600 data/api_keys.json # Read/write for owner only
```
2. Check directory exists:
```bash
mkdir -p data
```
3. Validate JSON format:
```bash
python -m json.tool data/api_keys.json
```
---
## Security Considerations
### Storage Security
- API keys are stored as SHA256 hashes
- Only the key hash is saved, not the actual key
- Storage file should have restricted permissions (600)
- Consider encrypting the storage file at rest
### Network Security
- Always use HTTPS for API requests
- Never log API keys in plain text
- Use secure channels to distribute keys (1Password, Vault)
### Audit & Compliance
- All key operations are logged in audit.log
- Track key usage via `usage_count` and `last_used_at`
- Regular review of active keys
- Compliance with GDPR, SOC 2, ISO 27001
---
## Related Documentation
- [Authentication Guide](AUTH_GUIDE.md)
- [Security Policy](../SECURITY.md)
- [Audit Logging](AUDIT_LOGGING.md)
- [Rate Limiting](RATE_LIMITING.md)
---
**Version**: 1.0.0
**Last Updated**: 2025-11-11
**Maintained by**: Airano (https://mcphub.dev)

721
docs/GITEA_GUIDE.md Normal file
View File

@@ -0,0 +1,721 @@
# 🦊 Gitea Plugin Guide
**Complete guide for Gitea integration in MCP Hub**
Version: 1.0.0 (Phase C)
Last Updated: 2025-11-19
---
## 📋 Table of Contents
- [Overview](#overview)
- [Features](#features)
- [Installation](#installation)
- [Configuration](#configuration)
- [Tool Categories](#tool-categories)
- [Usage Examples](#usage-examples)
- [OAuth Integration](#oauth-integration)
- [API Reference](#api-reference)
- [Troubleshooting](#troubleshooting)
- [Best Practices](#best-practices)
---
## 🎯 Overview
The Gitea Plugin provides comprehensive Git repository management through Gitea's REST API. It enables AI assistants (like Claude) to manage repositories, issues, pull requests, and more directly from ChatGPT or other MCP-enabled clients.
### What is Gitea?
Gitea is a lightweight, self-hosted Git service similar to GitHub/GitLab. It provides:
- Git repository hosting
- Issue tracking
- Pull requests
- Code review
- Webhooks
- Organizations and teams
### Why This Plugin?
**Git Workflow Automation** - Manage repositories from ChatGPT
**CI/CD Integration** - Trigger deployments with PR merges
**Issue Management** - AI-assisted issue triaging and responses
**Code Review** - Automated PR reviews and suggestions
**OAuth Support** - Seamless ChatGPT integration
**Multi-Site** - Manage multiple Gitea instances
---
## ✨ Features
### 📦 Repository Management (15 Tools)
- **CRUD Operations**: Create, read, update, delete repositories
- **Branch Management**: List, create, delete branches
- **Tag Management**: Create and manage tags
- **File Operations**: Read, create, update files in repository
### 🐛 Issue Tracking (12 Tools)
- **Issue Management**: Create, update, close, reopen issues
- **Labels**: Create and manage issue labels
- **Milestones**: Track project milestones
- **Comments**: Add comments to issues
### 🔀 Pull Requests (15 Tools)
- **PR Operations**: Create, update, merge pull requests
- **Code Review**: Review PRs, request changes, approve
- **PR Details**: View commits, files, diff
- **Reviewers**: Request reviewers for PRs
### 👥 User & Organization (8 Tools)
- **User Management**: Get user info, list repositories
- **Organizations**: Manage organizations and teams
- **Teams**: List team members
- **Search**: Search for users
### 🔗 Webhooks (5 Tools)
- **Webhook Setup**: Create, list, delete webhooks
- **Event Configuration**: Configure webhook events
- **Testing**: Test webhook delivery
**Total: 55 Tools**
---
## 📦 Installation
### Prerequisites
- Gitea instance (self-hosted or managed)
- Gitea personal access token OR OAuth setup
- MCP Hub installed
### 1. Enable Gitea Plugin
The Gitea plugin is built-in. No additional installation needed.
### 2. Configure Environment
Edit `.env` file:
```bash
# Site 1 - Token Authentication
GITEA_SITE1_URL=https://gitea.mcphub.dev
GITEA_SITE1_TOKEN=your_personal_access_token_here
GITEA_SITE1_ALIAS=mygitea
# Site 2 - OAuth Authentication (for ChatGPT)
GITEA_SITE2_URL=https://git.company.com
GITEA_SITE2_OAUTH_ENABLED=true
GITEA_SITE2_ALIAS=workgit
```
### 3. Generate Personal Access Token
#### In Gitea:
1. Log in to your Gitea instance
2. Go to **Settings → Applications**
3. Click **Generate New Token**
4. Enter token name: `MCP Server`
5. Select permissions:
-**repo** (all) - Full repository access
-**write:org** - Manage organizations
-**read:user** - Read user information
-**write:issue** - Create/edit issues and PRs
6. Click **Generate Token**
7. **Copy the token** (shown only once!)
8. Add to `.env` as `GITEA_SITE1_TOKEN`
### 4. Restart Server
```bash
# If running locally
python server.py
# If running in Docker
docker-compose restart
# If deployed in Coolify
# Restart the service from Coolify dashboard
```
### 5. Verify Installation
Check server logs for:
```
✅ Gitea plugin loaded: gitea_site1 (mygitea)
```
Or use health check tool:
```
check_project_health(project_id="gitea_site1")
```
---
## ⚙️ Configuration
### Environment Variables
| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `GITEA_SITEX_URL` | ✅ Yes | - | Gitea instance URL |
| `GITEA_SITEX_TOKEN` | ⚠️ Conditional | - | Personal access token (required if not using OAuth) |
| `GITEA_SITEX_ALIAS` | ❌ No | - | Friendly site name |
| `GITEA_SITEX_OAUTH_ENABLED` | ❌ No | `false` | Enable OAuth instead of token |
### Multiple Sites
You can configure unlimited Gitea instances:
```bash
# Personal Gitea
GITEA_SITE1_URL=https://gitea.mcphub.dev
GITEA_SITE1_TOKEN=token1
GITEA_SITE1_ALIAS=personal
# Work Gitea
GITEA_SITE2_URL=https://git.company.com
GITEA_SITE2_TOKEN=token2
GITEA_SITE2_ALIAS=work
# Client Gitea
GITEA_SITE3_URL=https://git.client.com
GITEA_SITE3_TOKEN=token3
GITEA_SITE3_ALIAS=client
```
### OAuth vs Token Authentication
#### Token Authentication (Recommended for Scripts)
**Pros:**
- Simple setup
- No user interaction needed
- Suitable for automation
**Cons:**
- Tokens can expire
- Manual renewal needed
- Less secure if leaked
#### OAuth Authentication (Recommended for ChatGPT)
**Pros:**
- User-approved access
- More secure
- Automatic token refresh
- Better for third-party apps
**Cons:**
- Requires OAuth setup
- More complex configuration
---
## 🧰 Tool Categories
### 1. Repository Tools
#### List Repositories
```
gitea_list_repositories(site, owner?, type?, page?, limit?)
```
Example:
```
# List all my repositories
gitea_list_repositories(site="mygitea")
# List user's repositories
gitea_list_repositories(site="mygitea", owner="username")
```
#### Create Repository
```
gitea_create_repository(site, name, description?, private?, auto_init?)
```
Example:
```
gitea_create_repository(
site="mygitea",
name="awesome-project",
description="My awesome project",
private=False,
auto_init=True
)
```
#### Manage Branches
```
gitea_list_branches(site, owner, repo)
gitea_create_branch(site, owner, repo, new_branch_name, old_branch_name?)
gitea_delete_branch(site, owner, repo, branch)
```
#### File Operations
```
gitea_get_file(site, owner, repo, path, ref?)
gitea_create_file(site, owner, repo, path, content, message)
gitea_update_file(site, owner, repo, path, content, sha, message)
```
### 2. Issue Tools
#### Manage Issues
```
gitea_list_issues(site, owner, repo, state?, labels?, q?)
gitea_create_issue(site, owner, repo, title, body?, labels?)
gitea_update_issue(site, owner, repo, issue_number, ...)
gitea_close_issue(site, owner, repo, issue_number)
```
#### Labels & Milestones
```
gitea_list_labels(site, owner, repo)
gitea_create_label(site, owner, repo, name, color, description?)
gitea_list_milestones(site, owner, repo, state?)
gitea_create_milestone(site, owner, repo, title, due_on?)
```
### 3. Pull Request Tools
#### Manage PRs
```
gitea_create_pull_request(site, owner, repo, title, head, base, body?)
gitea_merge_pull_request(site, owner, repo, pr_number, method?)
gitea_list_pr_commits(site, owner, repo, pr_number)
gitea_list_pr_files(site, owner, repo, pr_number)
```
#### Code Review
```
gitea_create_pr_review(site, owner, repo, pr_number, event, body?)
gitea_request_pr_reviewers(site, owner, repo, pr_number, reviewers)
```
### 4. User & Organization Tools
```
gitea_get_user(site, username)
gitea_list_user_repos(site, username)
gitea_list_organizations(site)
gitea_list_org_teams(site, org)
```
### 5. Webhook Tools
```
gitea_list_webhooks(site, owner, repo)
gitea_create_webhook(site, owner, repo, url, events)
gitea_test_webhook(site, owner, repo, webhook_id)
```
---
## 💡 Usage Examples
### Example 1: Create a Repository
```
# Create a new repository with README
gitea_create_repository(
site="mygitea",
name="my-new-project",
description="A new project for testing",
private=False,
auto_init=True,
license="MIT"
)
```
### Example 2: Create an Issue
```
# Create an issue
gitea_create_issue(
site="mygitea",
owner="myuser",
repo="my-project",
title="Bug: Login not working",
body="## Description\n\nUsers cannot log in after the latest update.\n\n## Steps to Reproduce\n1. Go to login page\n2. Enter credentials\n3. Click login\n\n## Expected\nShould log in successfully\n\n## Actual\nError message displayed",
labels=[1, 3] # bug, high-priority
)
```
### Example 3: Create a Pull Request
```
# Create feature branch
gitea_create_branch(
site="mygitea",
owner="myuser",
repo="my-project",
new_branch_name="feature/user-authentication",
old_branch_name="main"
)
# Make changes to files
gitea_update_file(
site="mygitea",
owner="myuser",
repo="my-project",
path="src/auth.js",
content="// Updated authentication code\n...",
sha="abc123",
message="Add OAuth support",
branch="feature/user-authentication"
)
# Create pull request
gitea_create_pull_request(
site="mygitea",
owner="myuser",
repo="my-project",
title="Add OAuth Authentication",
head="feature/user-authentication",
base="main",
body="This PR adds OAuth support for Google and GitHub authentication."
)
```
### Example 4: Review and Merge PR
```
# List open PRs
gitea_list_pull_requests(
site="mygitea",
owner="myuser",
repo="my-project",
state="open"
)
# Review the PR
gitea_create_pr_review(
site="mygitea",
owner="myuser",
repo="my-project",
pr_number=5,
event="APPROVED",
body="LGTM! Great work on the OAuth implementation."
)
# Merge the PR
gitea_merge_pull_request(
site="mygitea",
owner="myuser",
repo="my-project",
pr_number=5,
method="squash",
delete_branch_after_merge=True
)
```
### Example 5: Setup Webhook for CI/CD
```
# Create webhook for Coolify deployment
gitea_create_webhook(
site="mygitea",
owner="myuser",
repo="my-project",
url="https://coolify.example.com/webhooks/deploy",
events=["push", "pull_request"],
content_type="json",
secret="webhook_secret_here"
)
```
---
## 🔐 OAuth Integration
### Setup OAuth for ChatGPT
#### 1. Configure Server
In `.env`:
```bash
# Enable OAuth for Gitea site
GITEA_SITE1_URL=https://gitea.mcphub.dev
GITEA_SITE1_OAUTH_ENABLED=true
GITEA_SITE1_ALIAS=mygitea
# OAuth settings (if not already set)
OAUTH_JWT_SECRET_KEY=your_jwt_secret_here
OAUTH_AUTH_MODE=trusted_domains
OAUTH_TRUSTED_DOMAINS=chatgpt.com,chat.openai.com,openai.com
```
#### 2. Create GPT Action
In ChatGPT GPTs:
1. Go to **Configure → Actions**
2. Click **Create new action**
3. Import OpenAPI schema from: `https://your-server.com/.well-known/oauth-authorization-server`
4. Set OAuth:
- **Client ID**: Auto-registered via dynamic registration
- **Authorization URL**: `https://your-server.com/oauth/authorize`
- **Token URL**: `https://your-server.com/oauth/token`
#### 3. Use from ChatGPT
```
User: "Create a new repository called 'test-repo' in my Gitea"
Claude: Sure! I'll create a new repository.
[Calls gitea_create_repository with OAuth token]
```
### API Key with OAuth
For additional security, you can require API Keys even with OAuth:
```bash
OAUTH_AUTH_MODE=required
```
Then users must provide API Key in authorization URL:
```
/oauth/authorize?client_id=xxx&...&api_key=cmp_your_key_here
```
---
## 📚 API Reference
### Tool Naming Convention
All Gitea tools follow this pattern:
```
gitea_<action>_<resource>(site, ...params)
```
Examples:
- `gitea_create_repository`
- `gitea_list_issues`
- `gitea_merge_pull_request`
### Common Parameters
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `site` | string | ✅ | Site ID or alias (e.g., "mygitea") |
| `owner` | string | ✅ | Repository owner username/org |
| `repo` | string | ✅ | Repository name |
| `page` | integer | ❌ | Page number (default: 1) |
| `limit` | integer | ❌ | Items per page (default: 30, max: 100) |
### Response Format
All tools return consistent response format:
**Success:**
```json
{
"success": true,
"message": "Operation completed",
"data": { ... }
}
```
**Error:**
```json
{
"error": true,
"message": "Error description",
"code": "ERROR_CODE"
}
```
---
## 🔧 Troubleshooting
### Common Issues
#### 1. "Authentication failed"
**Cause**: Invalid or expired token
**Solution**:
- Regenerate personal access token in Gitea
- Update `GITEA_SITEX_TOKEN` in `.env`
- Restart server
#### 2. "Repository not found"
**Cause**: Incorrect owner or repo name
**Solution**:
- Verify repository exists in Gitea
- Check spelling of owner/repo
- Ensure user has access to repository
#### 3. "Permission denied"
**Cause**: Token lacks required permissions
**Solution**:
- Regenerate token with correct permissions:
- `repo` (all)
- `write:org`
- `read:user`
- `write:issue`
#### 4. "Webhook creation failed"
**Cause**: Invalid webhook URL or insufficient permissions
**Solution**:
- Verify webhook URL is accessible
- Ensure user has admin access to repository
- Check webhook events are valid
### Debug Mode
Enable debug logging:
```bash
LOG_LEVEL=DEBUG
```
Check logs:
```bash
tail -f logs/audit.log | jq
```
### Health Check
Test Gitea connectivity:
```
check_project_health(project_id="gitea_site1")
```
Expected response:
```json
{
"healthy": true,
"message": "Gitea instance is accessible"
}
```
---
## ✅ Best Practices
### 1. Security
- ✅ Use **personal access tokens** with minimal required permissions
- ✅ Enable **OAuth** for third-party access (ChatGPT)
- ✅ Rotate tokens regularly
- ✅ Use **private repositories** for sensitive code
- ✅ Enable **webhook secrets** for webhook security
- ✅ Use **per-project API keys** instead of master key
### 2. Git Workflow
- ✅ Create **feature branches** for new features
- ✅ Use **pull requests** for code review
- ✅ Add **meaningful commit messages**
- ✅ Use **labels** for issue categorization
- ✅ Set **milestones** for project planning
-**Squash merge** to keep history clean
### 3. Automation
- ✅ Setup **webhooks** for CI/CD integration
- ✅ Auto-close issues when PR is merged
- ✅ Use **labels** to trigger automation
- ✅ Create **templates** for issues and PRs
### 4. Performance
- ✅ Use **pagination** for large result sets
- ✅ Cache repository information when possible
- ✅ Use **search** instead of listing all items
- ✅ Batch operations when possible
---
## 🎯 Use Cases
### 1. Automated Issue Triage
```
# AI assistant automatically:
1. Lists open issues
2. Analyzes issue content
3. Adds appropriate labels
4. Assigns to team members
5. Sets milestone
```
### 2. AI Code Review
```
# AI assistant reviews PRs:
1. Lists open PRs
2. Gets PR diff
3. Analyzes code changes
4. Adds review comments
5. Approves or requests changes
```
### 3. Automated Releases
```
# Create release workflow:
1. Create release branch
2. Update version numbers
3. Generate changelog
4. Create pull request
5. After merge: create tag and release
```
### 4. Documentation Updates
```
# Keep docs in sync:
1. Detect code changes
2. Update corresponding documentation
3. Create PR for doc updates
4. Request review from maintainers
```
---
## 📖 Related Documentation
- [OAuth Guide](OAUTH_GUIDE.md) - Complete OAuth 2.1 setup
- [API Keys Guide](API_KEYS_USAGE.md) - API key management
- [Gitea API Docs](https://docs.gitea.io/en-us/api-usage/) - Official Gitea API
---
## 🆘 Support
### Need Help?
- 📧 **Email**: hello@mcphub.dev
- 🐛 **Issues**: [GitHub Issues](https://github.com/airano-ir/mcphub/issues)
- 📚 **Docs**: [Full Documentation](../README.md)
### Contributing
Contributions welcome! See [CONTRIBUTING.md](../CONTRIBUTING.md)
---
**Version**: 3.0.0

View File

@@ -0,0 +1,344 @@
# Multi-Endpoint Architecture Guide
> Solving the Tool Visibility Problem
---
## The Problem
### Before (Single Endpoint)
```
Client connects to /mcp
Sees ALL 188 tools
API key for site4 can see:
- ✅ WordPress tools (but for all sites!)
- ❌ Gitea tools (shouldn't see)
- ❌ System tools (shouldn't see)
- ❌ API key management (security risk!)
```
### Issue
- Users saw tools they couldn't use
- Wasted AI context on irrelevant tools
- Security concern: tool enumeration
- Confusing UX
---
## The Solution
### After (Multi-Endpoint)
```
Client connects to /mcp/wordpress
Sees ONLY 92 WordPress tools
Clean, focused, secure
```
---
## Endpoint Overview
| Endpoint | Tools | Requires | Use Case |
|----------|-------|----------|----------|
| `/mcp` | 188 | Master Key | Admin operations |
| `/mcp/wordpress` | 92 | API Key | WordPress management |
| `/mcp/wordpress-advanced` | 22 | Admin Key | DB/Bulk/System ops |
| `/mcp/gitea` | 55 | API Key | Git management |
| `/mcp/project/{id}` | Varies | Project Key | Single project |
---
## Migration Guide
### For Existing Users
**Before (v1.x)**
```json
{
"mcpServers": {
"coolify": {
"url": "https://mcp.example.com/mcp",
"headers": {
"Authorization": "Bearer cmp_xxx"
}
}
}
}
```
**After (v2.0)**
```json
{
"mcpServers": {
"wordpress": {
"url": "https://mcp.example.com/mcp/wordpress",
"headers": {
"Authorization": "Bearer cmp_xxx"
}
},
"gitea": {
"url": "https://mcp.example.com/mcp/gitea",
"headers": {
"Authorization": "Bearer cmp_yyy"
}
}
}
}
```
### Benefits After Migration
- Faster tool discovery
- Less AI context used
- Better security
- Clearer access control
---
## API Key Configuration
### Creating WordPress-Only Key
```bash
# Using admin endpoint with Master Key
curl -X POST https://mcp.example.com/mcp \
-H "Authorization: Bearer sk-master-key" \
-H "Content-Type: application/json" \
-d '{
"tool": "manage_api_keys_create",
"arguments": {
"project_id": "wordpress_site1",
"scope": "write",
"name": "Site1 Editor"
}
}'
```
### Key Scopes
| Scope | Permissions |
|-------|-------------|
| `read` | Read-only operations |
| `write` | Read + create/update |
| `admin` | Full access + system tools |
---
## Endpoint Details
### `/mcp` - Admin Endpoint
**Access**: Master API Key (`sk-*`) only
**Tools**: All 188 tools including:
- WordPress Core (92)
- WordPress Advanced (22)
- Gitea (55)
- System tools (19)
- API key management
- OAuth management
**Use Cases**:
- Initial setup
- Creating API keys
- System monitoring
- OAuth client management
---
### `/mcp/wordpress` - WordPress Endpoint
**Access**: Any valid API key
**Tools**: 92 WordPress tools
- Posts & Pages
- Media
- Taxonomy
- Comments
- Users
- WooCommerce
- SEO
**Blacklisted Tools**:
- `manage_api_keys_*`
- `oauth_*`
- System tools
**Use Cases**:
- Content management
- WooCommerce operations
- SEO management
---
### `/mcp/wordpress-advanced` - Advanced WordPress Endpoint
**Access**: Admin scope required
**Tools**: 22 advanced tools
- Database operations
- Bulk operations
- System operations
**Use Cases**:
- Database backup/restore
- Bulk content updates
- System maintenance
---
### `/mcp/gitea` - Gitea Endpoint
**Access**: Any valid API key (with gitea project)
**Tools**: 55 Gitea tools
- Repository management
- Issue tracking
- Pull requests
- Webhooks
**Use Cases**:
- Git operations
- Issue management
- PR reviews
---
### `/mcp/project/{id}` - Project Endpoint
**Access**: API key matching project_id
**Tools**: Plugin tools filtered to single project
**Example**: `/mcp/project/wordpress_site1`
- Only WordPress tools
- Site parameter auto-set to `site1`
**Use Cases**:
- Single-site management
- Restricted access per client
---
## Security Considerations
### Tool Blacklisting
System and admin tools are blacklisted from non-admin endpoints:
```python
tool_blacklist = {
"manage_api_keys_create",
"manage_api_keys_delete",
"manage_api_keys_rotate",
"oauth_register_client",
"oauth_revoke_client",
}
```
### API Key Validation
Each endpoint validates:
1. Token format and validity
2. Scope requirements
3. Plugin type matching
4. Tool-level access
### Audit Logging
All tool calls are logged with:
- Endpoint path
- Tool name
- API key ID
- Timestamp
- Success/failure
---
## Running the Server
### Development
```bash
# Install dependencies
pip install -r requirements.txt
# Run multi-endpoint server
python server_multi.py --port 8000
```
### Production (Docker)
```bash
# Build
docker-compose build
# Run
docker-compose up -d
```
### Environment Variables
```bash
# Required
MASTER_API_KEY=sk-your-secure-key
# WordPress
WORDPRESS_SITE1_URL=https://example.com
WORDPRESS_SITE1_USERNAME=admin
WORDPRESS_SITE1_PASSWORD=app_password
# Gitea
GITEA_SITE1_URL=https://gitea.example.com
GITEA_SITE1_TOKEN=your-token
```
---
## Testing Endpoints
### Check Available Endpoints
```bash
curl http://localhost:8000/endpoints
```
### Check Health
```bash
curl http://localhost:8000/health
```
### Test WordPress Endpoint
```bash
curl -X POST http://localhost:8000/mcp/wordpress \
-H "Authorization: Bearer cmp_xxx" \
-H "Content-Type: application/json" \
-d '{"tool": "wordpress_list_posts", "arguments": {"site": "site1"}}'
```
---
## Troubleshooting
### "Endpoint requires master API key"
- Use `/mcp` endpoint with Master Key for admin operations
- Or use appropriate plugin endpoint with project API key
### "API key cannot access this endpoint"
- API key project_id must match endpoint plugin type
- Example: `wordpress_site1` key works on `/mcp/wordpress`, not `/mcp/gitea`
### "Access denied to tool"
- Tool may be blacklisted for this endpoint
- Check if admin scope is required
---
## Future Improvements
- [ ] Per-project endpoints (`/mcp/project/{id}`)
- [ ] Dynamic endpoint creation
- [ ] Custom tool whitelists
- [ ] Endpoint-level rate limiting
- [ ] Endpoint usage analytics
---
**Last Updated**: 2025-11-24

1025
docs/OAUTH_GUIDE.md Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

448
docs/getting-started.md Normal file
View File

@@ -0,0 +1,448 @@
# 🚀 Getting Started with MCP Hub
---
## Table of Contents
1. [Prerequisites](#prerequisites)
2. [Installation](#installation)
3. [Configuration](#configuration)
4. [Running the Server](#running-the-server)
5. [Testing Your Setup](#testing-your-setup)
6. [Using MCP Tools](#using-mcp-tools)
7. [Docker Deployment](#docker-deployment)
8. [Coolify Deployment](#coolify-deployment)
9. [Next Steps](#next-steps)
---
## Prerequisites
Before you begin, ensure you have the following installed:
### Required
- **Python 3.11+**: [Download Python](https://www.python.org/downloads/)
- **Git**: [Download Git](https://git-scm.com/downloads)
### Optional (for Docker deployment)
- **Docker**: [Download Docker Desktop](https://www.docker.com/products/docker-desktop)
- **Docker Compose**: Included with Docker Desktop
### WordPress Requirements
For each WordPress site you want to manage:
- WordPress 5.0+
- **Application Passwords** enabled (WordPress 5.6+)
- **WooCommerce** 3.0+ (if using WooCommerce tools)
- **Rank Math** or **Yoast SEO** (if using SEO tools)
- HTTPS enabled (recommended)
---
## Installation
### Option 1: Automated Setup (Recommended)
#### Linux/Mac
```bash
# Clone the repository
git clone https://github.com/mcphub/mcphub.git
cd mcphub
# Run setup script
chmod +x scripts/setup.sh
./scripts/setup.sh
```
#### Windows (PowerShell)
```powershell
# Clone the repository
git clone https://github.com/mcphub/mcphub.git
cd mcphub
# Run setup script
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process
.\scripts\setup.ps1
```
### Option 2: Manual Setup
```bash
# 1. Clone repository
git clone https://github.com/mcphub/mcphub.git
cd mcphub
# 2. Create virtual environment
python3 -m venv venv
# 3. Activate virtual environment
# Linux/Mac:
source venv/bin/activate
# Windows:
.\venv\Scripts\Activate.ps1
# 4. Install dependencies
pip install --upgrade pip
pip install -r requirements.txt
# 5. Copy environment template
cp .env.example .env
```
---
## Configuration
### Step 1: Generate WordPress Application Passwords
For each WordPress site:
1. Log in to WordPress admin
2. Navigate to: **Users → Your Profile**
3. Scroll to **Application Passwords** section
4. Enter name: `MCP Server`
5. Click **Add New Application Password**
6. Copy the generated password (format: `xxxx xxxx xxxx xxxx xxxx xxxx`)
**Important**: Save this password immediately. You cannot retrieve it later.
### Step 2: Generate WooCommerce API Keys
If using WooCommerce tools:
1. Go to: **WooCommerce → Settings → Advanced → REST API**
2. Click **Add Key**
3. Fill in:
- **Description**: `MCP Server`
- **User**: Select admin user
- **Permissions**: `Read/Write`
4. Click **Generate API Key**
5. Copy **Consumer Key** and **Consumer Secret**
### Step 3: Configure Environment Variables
Edit `.env` file:
```bash
# Basic Configuration
MCP_SERVER_NAME=mcphub
MCP_SERVER_VERSION=1.0.0
# Site 1 - Main WordPress Site
WORDPRESS_SITE1_URL=https://example.com
WORDPRESS_SITE1_USERNAME=admin
WORDPRESS_SITE1_APP_PASSWORD=xxxx xxxx xxxx xxxx xxxx xxxx
WORDPRESS_SITE1_WC_CONSUMER_KEY=ck_xxxxxxxxxxxxx
WORDPRESS_SITE1_WC_CONSUMER_SECRET=cs_xxxxxxxxxxxxx
WORDPRESS_SITE1_ALIAS=mainsite
# Site 2 - E-commerce Site (Optional)
WORDPRESS_SITE2_URL=https://shop.example.com
WORDPRESS_SITE2_USERNAME=admin
WORDPRESS_SITE2_APP_PASSWORD=yyyy yyyy yyyy yyyy yyyy yyyy
WORDPRESS_SITE2_WC_CONSUMER_KEY=ck_yyyyyyyyyyyyy
WORDPRESS_SITE2_WC_CONSUMER_SECRET=cs_yyyyyyyyyyyyy
WORDPRESS_SITE2_ALIAS=shop
# Site 3 - Blog Site (Optional)
WORDPRESS_SITE3_URL=https://blog.example.com
WORDPRESS_SITE3_USERNAME=admin
WORDPRESS_SITE3_APP_PASSWORD=zzzz zzzz zzzz zzzz zzzz zzzz
WORDPRESS_SITE3_ALIAS=blog
# Rate Limiting (Optional)
RATE_LIMIT_PER_MINUTE=60
RATE_LIMIT_PER_HOUR=1000
RATE_LIMIT_PER_DAY=10000
# Logging (Optional)
LOG_LEVEL=INFO
```
### Configuration Tips
- **Site Aliases**: Use friendly names like `mainsite`, `shop`, or `blog`
- **Minimal WooCommerce**: Only configure WooCommerce keys if you need e-commerce tools
- **Testing**: Start with one site, verify it works, then add more
- **Security**: Never commit `.env` file to git
---
## Running the Server
### Development Mode
```bash
# Activate virtual environment (if not already active)
source venv/bin/activate # Linux/Mac
.\venv\Scripts\Activate.ps1 # Windows
# Run server
python src/main.py
# Or use the dev script
./scripts/dev.sh # Linux/Mac
```
### Verify Server is Running
Check logs for:
```
INFO: MCP Server initialized
INFO: Registered 390 tools
INFO: Server ready
```
---
## Testing Your Setup
### Quick Health Check
Run the test script:
```bash
./scripts/test.sh quick
```
### Manual Testing
```bash
# Run all tests
pytest
# Run with coverage
pytest --cov
# Run specific test
pytest tests/test_wordpress_plugin.py
```
### Verify Tool Registration
Check that tools are registered:
```bash
python -c "
from src.main import app
tools = app.list_tools()
print(f'Total tools: {len(tools)}')
"
```
Expected output: `Total tools: 390` (for 3 configured sites)
---
## Using MCP Tools
### Tool Naming Convention
#### Per-Site Tools (Legacy)
```
wordpress_{site}_action
```
Examples:
- `wordpress_site1_list_posts`
- `wordpress_site2_get_product`
- `wordpress_site3_create_page`
#### Unified Tools (Recommended)
```
wordpress_action(site="site_id", ...)
```
Examples:
- `wordpress_list_posts(site="site1")`
- `wordpress_get_product(site="shop", product_id=123)`
- `wordpress_create_page(site="blog", title="Hello", content="...")`
### Using Site Aliases
If you configured `WORDPRESS_SITE2_ALIAS=shop`:
```python
# Both work the same
wordpress_list_products(site="site2")
wordpress_list_products(site="shop")
```
### Example: List Posts
**Using Per-Site Tools**:
```python
result = wordpress_site1_list_posts(per_page=10, status="publish")
```
**Using Unified Tools**:
```python
result = wordpress_list_posts(site="mainsite", per_page=10, status="publish")
```
### Example: Create Product
```python
result = wordpress_create_product(
site="shop",
name="New Product",
type="simple",
regular_price="29.99",
description="Product description",
status="publish"
)
```
### Example: Update Page
```python
result = wordpress_update_page(
site="blog",
page_id=42,
title="Updated Title",
content="<p>Updated content</p>",
status="publish"
)
```
---
## Docker Deployment
### Quick Start
```bash
# Deploy with Docker
./scripts/deploy.sh
# Or manually
docker compose up -d
```
### Docker Commands
```bash
# View logs
docker compose logs -f
# Check status
docker compose ps
# Restart
docker compose restart
# Stop
docker compose down
# Rebuild
docker compose up --build -d
```
### Health Check
```bash
# Check container health
docker compose ps
# Test API endpoint
curl http://localhost:8000/health
```
---
## Coolify Deployment
### Prerequisites
- Coolify instance running
- Docker registry access (optional)
### Step 1: Create New Resource
1. Log in to Coolify dashboard
2. Click **+ New Resource**
3. Select **Docker Compose**
### Step 2: Configure Repository
1. **Git Repository**: `https://github.com/mcphub/mcphub.git`
2. **Branch**: `main`
3. **Build Pack**: `Docker Compose`
### Step 3: Configure Environment Variables
Add all required environment variables from `.env.example`:
```
WORDPRESS_SITE1_URL=https://example.com
WORDPRESS_SITE1_USERNAME=admin
WORDPRESS_SITE1_APP_PASSWORD=xxxx xxxx xxxx xxxx xxxx xxxx
...
```
### Step 4: Configure Health Check
- **Path**: `/health`
- **Port**: `8000`
- **Interval**: `30s`
- **Timeout**: `10s`
- **Retries**: `3`
### Step 5: Deploy
1. Click **Deploy**
2. Wait for build to complete
3. Check logs for successful startup
### Coolify-Specific Configuration
Add to `docker-compose.yml` if needed:
```yaml
services:
mcp-server:
labels:
- "coolify.managed=true"
- "coolify.port=8000"
- "coolify.health_check=/health"
```
---
## Next Steps
### 1. Explore Available Tools
Check the [README](../README.md) for complete tool listing.
### 2. Configure Monitoring
- View health metrics: Use `check_all_projects_health` tool
- Check rate limits: Use `get_rate_limit_stats` tool
- Review audit logs: `tail -f logs/audit.log`
### 3. Customize Configuration
- Adjust rate limits in `.env`
- Configure log levels
- Add more WordPress sites
### 4. Read Documentation
- [Troubleshooting Guide](troubleshooting.md)
- [Security Policy](../SECURITY.md)
- [Contributing Guide](../CONTRIBUTING.md)
### 5. Join Community
- **Repository**: [github.com/mcphub/mcphub](https://github.com/mcphub/mcphub)
- **Contact**: hello@mcphub.dev
- **Website**: [mcphub.dev](https://mcphub.dev)
---
---

669
docs/n8n-plugin-design.md Normal file
View File

@@ -0,0 +1,669 @@
# n8n Automation Plugin Design
> **Phase I: n8n Automation Plugin**
> **Priority**: High (Upgraded from Medium)
> **Estimated Tools**: 55-60
---
## Overview
The n8n plugin provides comprehensive automation workflow management through n8n's REST API. This enables AI assistants to create, manage, execute, and monitor automation workflows programmatically.
### Key Capabilities
- Complete workflow lifecycle management (CRUD + activate/deactivate/execute)
- Execution monitoring and history
- Credential management for third-party integrations
- Project and user management (Enterprise/Pro features)
- Environment variables management
- Security audit and source control integration
---
## Architecture
### Plugin Structure
```
plugins/n8n/
├── __init__.py
├── plugin.py # N8nPlugin class
├── client.py # N8nClient (REST API communication)
└── handlers/
├── __init__.py
├── workflows.py # Workflow management (14 tools)
├── executions.py # Execution monitoring (8 tools)
├── credentials.py # Credential management (8 tools)
├── tags.py # Tag management (6 tools)
├── users.py # User management (6 tools)
├── projects.py # Project management (8 tools)
├── variables.py # Variable management (6 tools)
└── system.py # Audit & Source Control (4 tools)
```
### Authentication
n8n uses API Key authentication via `X-N8N-API-KEY` header.
```python
# Environment Variables
N8N_SITE1_URL=https://n8n.example.com
N8N_SITE1_API_KEY=your-api-key
N8N_SITE1_ALIAS=myautomation # Optional friendly name
```
---
## Tool Specifications (55-60 Tools)
### 1. Workflows Handler (14 tools)
| Tool | Method | Scope | Description |
|------|--------|-------|-------------|
| `list_workflows` | GET | read | List all workflows with filters (active, tags, name) |
| `get_workflow` | GET | read | Get workflow details by ID |
| `create_workflow` | POST | write | Create new workflow from JSON definition |
| `update_workflow` | PUT | write | Update existing workflow |
| `delete_workflow` | DELETE | admin | Delete a workflow |
| `activate_workflow` | POST | write | Activate a workflow |
| `deactivate_workflow` | POST | write | Deactivate a workflow |
| `execute_workflow` | POST | write | Manually execute a workflow |
| `execute_workflow_with_data` | POST | write | Execute with custom input data |
| `duplicate_workflow` | POST | write | Duplicate an existing workflow |
| `export_workflow` | GET | read | Export workflow as JSON |
| `import_workflow` | POST | write | Import workflow from JSON |
| `get_workflow_tags` | GET | read | Get tags assigned to a workflow |
| `set_workflow_tags` | PUT | write | Assign tags to a workflow |
#### Tool Specification Example
```python
{
"name": "list_workflows",
"method_name": "list_workflows",
"description": "List all n8n workflows with optional filters. Returns workflow ID, name, active status, and metadata.",
"schema": {
"type": "object",
"properties": {
"active": {
"type": "boolean",
"description": "Filter by active/inactive status"
},
"tags": {
"anyOf": [{"type": "string"}, {"type": "null"}],
"description": "Filter by tag name(s), comma-separated"
},
"name": {
"anyOf": [{"type": "string"}, {"type": "null"}],
"description": "Filter by workflow name (partial match)"
},
"limit": {
"type": "integer",
"description": "Maximum workflows to return",
"default": 50,
"minimum": 1,
"maximum": 250
},
"cursor": {
"anyOf": [{"type": "string"}, {"type": "null"}],
"description": "Pagination cursor for next page"
}
}
},
"scope": "read"
}
```
```python
{
"name": "execute_workflow",
"method_name": "execute_workflow",
"description": "Manually execute a workflow and return execution ID. Use get_execution to check status.",
"schema": {
"type": "object",
"properties": {
"workflow_id": {
"type": "string",
"description": "Workflow ID to execute",
"minLength": 1
},
"wait": {
"type": "boolean",
"description": "Wait for execution to complete (max 5 minutes)",
"default": False
}
},
"required": ["workflow_id"]
},
"scope": "write"
}
```
```python
{
"name": "execute_workflow_with_data",
"method_name": "execute_workflow_with_data",
"description": "Execute workflow with custom input data. Useful for workflows with webhook/manual triggers.",
"schema": {
"type": "object",
"properties": {
"workflow_id": {
"type": "string",
"description": "Workflow ID to execute",
"minLength": 1
},
"data": {
"type": "object",
"description": "Input data to pass to workflow trigger node"
},
"wait": {
"type": "boolean",
"description": "Wait for execution to complete",
"default": False
}
},
"required": ["workflow_id", "data"]
},
"scope": "write"
}
```
---
### 2. Executions Handler (8 tools)
| Tool | Method | Scope | Description |
|------|--------|-------|-------------|
| `list_executions` | GET | read | List workflow executions with filters |
| `get_execution` | GET | read | Get execution details and data |
| `delete_execution` | DELETE | write | Delete a single execution |
| `delete_executions` | DELETE | write | Bulk delete executions |
| `stop_execution` | POST | write | Stop a running execution |
| `retry_execution` | POST | write | Retry a failed execution |
| `get_execution_data` | GET | read | Get full execution data including node outputs |
| `wait_for_execution` | GET | read | Poll until execution completes |
#### Tool Specification Examples
```python
{
"name": "list_executions",
"method_name": "list_executions",
"description": "List workflow executions with filters by status, workflow, date range. Returns execution history.",
"schema": {
"type": "object",
"properties": {
"workflow_id": {
"anyOf": [{"type": "string"}, {"type": "null"}],
"description": "Filter by workflow ID"
},
"status": {
"anyOf": [{"type": "string", "enum": ["success", "error", "waiting", "running", "new"]}, {"type": "null"}],
"description": "Filter by execution status"
},
"include_data": {
"type": "boolean",
"description": "Include full execution data",
"default": False
},
"limit": {
"type": "integer",
"description": "Maximum results",
"default": 20,
"minimum": 1,
"maximum": 250
},
"cursor": {
"anyOf": [{"type": "string"}, {"type": "null"}],
"description": "Pagination cursor"
}
}
},
"scope": "read"
}
```
```python
{
"name": "get_execution",
"method_name": "get_execution",
"description": "Get detailed information about a specific execution including status, timing, and optionally full data.",
"schema": {
"type": "object",
"properties": {
"execution_id": {
"type": "string",
"description": "Execution ID",
"minLength": 1
},
"include_data": {
"type": "boolean",
"description": "Include full node execution data",
"default": True
}
},
"required": ["execution_id"]
},
"scope": "read"
}
```
---
### 3. Credentials Handler (8 tools)
| Tool | Method | Scope | Description |
|------|--------|-------|-------------|
| `list_credentials` | GET | read | List all credentials (without sensitive data) |
| `get_credential` | GET | read | Get credential metadata |
| `create_credential` | POST | admin | Create new credential |
| `update_credential` | PUT | admin | Update credential |
| `delete_credential` | DELETE | admin | Delete a credential |
| `get_credential_schema` | GET | read | Get schema for credential type |
| `list_credential_types` | GET | read | List available credential types |
| `transfer_credential` | POST | admin | Transfer credential to another project |
#### Tool Specification Examples
```python
{
"name": "list_credentials",
"method_name": "list_credentials",
"description": "List all stored credentials. Returns metadata only (no sensitive values).",
"schema": {
"type": "object",
"properties": {
"limit": {
"type": "integer",
"description": "Maximum results",
"default": 100,
"minimum": 1,
"maximum": 250
},
"cursor": {
"anyOf": [{"type": "string"}, {"type": "null"}],
"description": "Pagination cursor"
}
}
},
"scope": "read"
}
```
```python
{
"name": "create_credential",
"method_name": "create_credential",
"description": "Create a new credential for use in workflows. Use get_credential_schema to see required fields.",
"schema": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Credential display name",
"minLength": 1
},
"type": {
"type": "string",
"description": "Credential type (e.g., 'githubApi', 'slackApi')",
"minLength": 1
},
"data": {
"type": "object",
"description": "Credential data matching the schema for this type"
}
},
"required": ["name", "type", "data"]
},
"scope": "admin"
}
```
---
### 4. Tags Handler (6 tools)
| Tool | Method | Scope | Description |
|------|--------|-------|-------------|
| `list_tags` | GET | read | List all tags |
| `get_tag` | GET | read | Get tag details |
| `create_tag` | POST | write | Create a new tag |
| `update_tag` | PUT | write | Update tag name |
| `delete_tag` | DELETE | write | Delete a tag |
| `delete_tags` | DELETE | write | Bulk delete tags |
---
### 5. Users Handler (6 tools)
| Tool | Method | Scope | Description |
|------|--------|-------|-------------|
| `list_users` | GET | admin | List all users |
| `get_user` | GET | admin | Get user details |
| `create_user` | POST | admin | Invite/create new user |
| `delete_user` | DELETE | admin | Delete a user |
| `change_user_role` | PUT | admin | Change user's global role |
| `get_current_user` | GET | read | Get current authenticated user |
---
### 6. Projects Handler (8 tools) - Enterprise/Pro
| Tool | Method | Scope | Description |
|------|--------|-------|-------------|
| `list_projects` | GET | read | List all projects |
| `get_project` | GET | read | Get project details |
| `create_project` | POST | admin | Create a new project |
| `update_project` | PUT | admin | Update project metadata |
| `delete_project` | DELETE | admin | Delete a project |
| `add_project_users` | POST | admin | Add users to project with roles |
| `change_project_user_role` | PUT | admin | Change user's role in project |
| `remove_project_user` | DELETE | admin | Remove user from project |
---
### 7. Variables Handler (6 tools)
| Tool | Method | Scope | Description |
|------|--------|-------|-------------|
| `list_variables` | GET | read | List all environment variables |
| `get_variable` | GET | read | Get variable value by key |
| `create_variable` | POST | admin | Create new variable |
| `update_variable` | PUT | admin | Update variable value |
| `delete_variable` | DELETE | admin | Delete a variable |
| `set_variables` | POST | admin | Bulk set multiple variables |
---
### 8. System Handler (4 tools)
| Tool | Method | Scope | Description |
|------|--------|-------|-------------|
| `run_security_audit` | POST | admin | Run security audit on instance |
| `source_control_pull` | POST | admin | Pull workflows from Git repository |
| `get_instance_info` | GET | read | Get n8n instance version and status |
| `health_check` | GET | read | Check n8n instance health |
---
## API Client Design
### N8nClient Class
```python
class N8nClient:
"""
n8n REST API client for HTTP communication.
Handles authentication, request formatting, and error handling
for all n8n API endpoints.
"""
def __init__(self, site_url: str, api_key: str):
"""
Initialize n8n API client.
Args:
site_url: n8n instance URL (e.g., https://n8n.example.com)
api_key: n8n API key for authentication
"""
self.site_url = site_url.rstrip('/')
self.api_base = f"{self.site_url}/api/v1"
self.api_key = api_key
def _get_headers(self) -> Dict[str, str]:
"""Get request headers with API key authentication."""
return {
"Content-Type": "application/json",
"Accept": "application/json",
"X-N8N-API-KEY": self.api_key
}
async def request(
self,
method: str,
endpoint: str,
params: Optional[Dict] = None,
json_data: Optional[Dict] = None
) -> Any:
"""Make authenticated request to n8n REST API."""
# Implementation similar to GiteaClient
```
---
## Endpoint Reference
### Base URL
```
{N8N_URL}/api/v1
```
### Workflows
```
GET /workflows - List workflows
POST /workflows - Create workflow
GET /workflows/{id} - Get workflow
PUT /workflows/{id} - Update workflow
DELETE /workflows/{id} - Delete workflow
POST /workflows/{id}/activate - Activate workflow
POST /workflows/{id}/deactivate - Deactivate workflow
POST /workflows/{id}/run - Execute workflow
```
### Executions
```
GET /executions - List executions
GET /executions/{id} - Get execution
DELETE /executions/{id} - Delete execution
```
### Credentials
```
GET /credentials - List credentials
POST /credentials - Create credential
GET /credentials/{id} - Get credential
DELETE /credentials/{id} - Delete credential
GET /credentials/schema/{type} - Get credential schema
POST /credentials/{id}/transfer - Transfer credential
```
### Tags
```
GET /tags - List tags
POST /tags - Create tag
GET /tags/{id} - Get tag
PUT /tags/{id} - Update tag
DELETE /tags/{id} - Delete tag
```
### Users
```
GET /users - List users
POST /users - Create/invite user
GET /users/{id} - Get user
DELETE /users/{id} - Delete user
PATCH /users/{id}/role - Change user role
```
### Projects (Enterprise/Pro)
```
GET /projects - List projects
POST /projects - Create project
GET /projects/{id} - Get project
PUT /projects/{id} - Update project
DELETE /projects/{id} - Delete project
POST /projects/{id}/users - Add users to project
```
### Variables
```
GET /variables - List variables
POST /variables - Create variable
GET /variables/{key} - Get variable
PUT /variables/{key} - Update variable
DELETE /variables/{key} - Delete variable
```
### System
```
POST /audit - Run security audit
POST /source-control/pull - Pull from Git
GET /health - Health check
```
---
## Multi-Endpoint Integration
### Endpoint Configuration
```python
# core/endpoints/config.py
ENDPOINT_CONFIGS = {
# ... existing configs ...
"n8n": EndpointConfig(
path="/n8n/mcp",
name="n8n Automation",
plugin_types=["n8n"],
description="Workflow automation management",
tools_count=55
)
}
```
### Per-Project Endpoint
```
/project/{alias}/mcp - Site-specific n8n endpoint
/project/myautomation/mcp
```
---
## Environment Configuration
```bash
# Single n8n instance
N8N_SITE1_URL=https://n8n.example.com
N8N_SITE1_API_KEY=your-api-key-here
N8N_SITE1_ALIAS=automation
# Multiple instances
N8N_SITE2_URL=https://n8n-staging.example.com
N8N_SITE2_API_KEY=staging-api-key
N8N_SITE2_ALIAS=automation-staging
```
---
## Use Cases
### 1. Workflow Management
```
User: "Create a new workflow that sends Slack notifications when a GitHub issue is created"
AI Assistant:
1. create_workflow with workflow JSON definition
2. activate_workflow to enable it
3. list_credentials to verify Slack/GitHub credentials exist
```
### 2. Execution Monitoring
```
User: "Show me failed executions from the last 24 hours"
AI Assistant:
1. list_executions with status="error" filter
2. get_execution for each to see error details
3. Provide summary and suggestions
```
### 3. Credential Management
```
User: "Set up new API credentials for OpenAI"
AI Assistant:
1. get_credential_schema for "openAiApi" type
2. create_credential with required fields
3. Confirm credential is ready for use
```
### 4. Security Audit
```
User: "Run a security audit on our n8n instance"
AI Assistant:
1. run_security_audit
2. Parse and summarize findings
3. Provide recommendations
```
---
## Implementation Priority
### Phase 1 (Core - Must Have)
1. Workflows handler (14 tools)
2. Executions handler (8 tools)
3. Client implementation
4. Plugin class
### Phase 2 (Extended - Should Have)
1. Credentials handler (8 tools)
2. Tags handler (6 tools)
3. Variables handler (6 tools)
### Phase 3 (Advanced - Nice to Have)
1. Users handler (6 tools)
2. Projects handler (8 tools)
3. System handler (4 tools)
---
## Security Considerations
1. **API Key Protection**: Store API keys securely, never log them
2. **Credential Handling**: Never expose credential values in responses
3. **Scope Enforcement**: Admin-level tools require admin scope
4. **Rate Limiting**: Respect n8n API rate limits
5. **Audit Logging**: Log all write/admin operations
---
## Testing Strategy
1. **Unit Tests**: Test each handler function independently
2. **Integration Tests**: Test against a local n8n instance
3. **Mock Tests**: Use mocked API responses for CI/CD
---
## Documentation Links
- [n8n Public REST API](https://docs.n8n.io/api/)
- [n8n API Reference](https://docs.n8n.io/api/api-reference/)
- [n8n Authentication](https://docs.n8n.io/api/authentication/)
---
## Summary
| Category | Tools | Priority |
|----------|-------|----------|
| Workflows | 14 | Phase 1 |
| Executions | 8 | Phase 1 |
| Credentials | 8 | Phase 2 |
| Tags | 6 | Phase 2 |
| Variables | 6 | Phase 2 |
| Users | 6 | Phase 3 |
| Projects | 8 | Phase 3 |
| System | 4 | Phase 3 |
| **Total** | **60** | - |
---
**Created**: 2025-11-27
**Author**: AI Assistant
**Status**: Design Document - Awaiting Implementation

View File

@@ -0,0 +1,922 @@
# OpenPanel Plugin Design - Phase H
> **MCP Plugin for OpenPanel Analytics Management (Self-Hosted)**
**Version**: v1.0.0 (Design)
**Priority**: Highest
**Estimated Tools**: 72-78
---
## Why OpenPanel over Plausible?
### Comparison Summary
| Feature | Plausible | OpenPanel | Winner |
|---------|-----------|-----------|--------|
| Web Analytics | Yes | Yes | Tie |
| Product Analytics | No | Yes (Funnels, Cohorts) | OpenPanel |
| User Profiles | No | Yes | OpenPanel |
| A/B Testing | No | Yes | OpenPanel |
| Retention Analysis | No | Yes | OpenPanel |
| Session Recording | No | Yes | OpenPanel |
| Multi-platform | Web only | Web, Mobile, Server | OpenPanel |
| API Completeness | Stats API only | Track + Export + Management | OpenPanel |
| Custom Dashboards | Limited | Full flexibility | OpenPanel |
| Self-Hosted | Yes | Yes | Tie |
| Privacy (GDPR) | Yes | Yes | Tie |
**Decision**: **OpenPanel** - More comprehensive analytics with Product Analytics features that Plausible lacks.
### Key OpenPanel Advantages
1. **Product Analytics** - Funnels, cohorts, user profiles, retention
2. **A/B Testing** - Built-in variant testing
3. **Multi-platform** - Web, iOS, Android, Server-side SDKs
4. **Comprehensive API** - Track, Export, and Management APIs
5. **Custom Dashboards** - Flexible chart creation
6. **Self-Hosted on Coolify** - Full data control
Sources:
- [OpenPanel](https://openpanel.dev/)
- [OpenPanel GitHub](https://github.com/Openpanel-dev/openpanel)
- [Coolify OpenPanel Docs](https://coolify.io/docs/services/openpanel)
---
## Overview
Plugin for managing **OpenPanel Self-Hosted** instances deployed on Coolify.
### Architecture Overview
```
┌─────────────────────────────────────────────────────────────────┐
│ OpenPanel Self-Hosted Architecture │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ OpenPanel Stack │ │
│ ├─────────────────────────────────────────────────────────┤ │
│ │ │ │
│ │ Next.js Dashboard (:3000) │ │
│ │ └── tRPC API (internal management) │ │
│ │ │ │
│ │ Fastify Event API (:3333) │ │
│ │ └── /track - Event ingestion │ │
│ │ └── /export - Data export │ │
│ │ │ │
│ │ PostgreSQL - Metadata & config │ │
│ │ ClickHouse - Event storage (high-volume) │ │
│ │ Redis - Cache, pub/sub, queues │ │
│ │ BullMQ - Job processing │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
```
---
## Authentication
### API Authentication
```
┌─────────────────────────────────────────────────────────────────┐
│ OpenPanel Authentication │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Required Headers: │
│ ├── openpanel-client-id: YOUR_CLIENT_ID │
│ └── openpanel-client-secret: YOUR_CLIENT_SECRET │
│ │
│ Client Modes: │
│ ├── write - Can send events (tracking) │
│ ├── read - Can read data (export) │
│ └── root - Full access (management + read + write) │
│ │
│ For Self-Hosted: Create clients via Dashboard or API │
│ │
└─────────────────────────────────────────────────────────────────┘
```
### Environment Variables
```bash
# OpenPanel Self-Hosted Instance (Required)
OPENPANEL_SITE1_URL=https://analytics.example.com
OPENPANEL_SITE1_CLIENT_ID=your-client-id
OPENPANEL_SITE1_CLIENT_SECRET=your-client-secret
OPENPANEL_SITE1_PROJECT_ID=your-project-id # Required for Export/Read APIs
OPENPANEL_SITE1_ALIAS=myanalytics
# Optional: Multiple Instances
OPENPANEL_SITE2_URL=https://analytics-staging.example.com
OPENPANEL_SITE2_CLIENT_ID=client-id-staging
OPENPANEL_SITE2_CLIENT_SECRET=client-secret-staging
OPENPANEL_SITE2_PROJECT_ID=staging-project-id
OPENPANEL_SITE2_ALIAS=staging
```
**Finding Your Project ID:**
1. Log in to your OpenPanel Dashboard
2. Go to Project Settings
3. Copy the Project ID
**Note:**
- `CLIENT_ID` and `CLIENT_SECRET` are used for authentication
- `PROJECT_ID` is required for Export/Read APIs (get_event_count, export_events, etc.)
- Track APIs (identify_user, track_event) work without PROJECT_ID
---
## API Endpoints
### Track API (Fastify - /api)
Primary endpoint for event ingestion:
```
POST /track
Headers:
openpanel-client-id: YOUR_CLIENT_ID
openpanel-client-secret: YOUR_CLIENT_SECRET
x-client-ip: CLIENT_IP (optional, for geo)
user-agent: USER_AGENT (optional, for device info)
```
**Operation Types:**
| Type | Description | Use Case |
|------|-------------|----------|
| `track` | Track custom event | Page view, button click, purchase |
| `identify` | Identify user | Set user profile properties |
| `increment` | Increment property | Visit count, purchase count |
| `decrement` | Decrement property | Credits used, inventory |
| `alias` | Alias profile ID | Link anonymous to authenticated |
### Export API (Fastify - /export)
```
GET /export/events
- Retrieve raw event data
- Filters: projectId, profileId, event, start, end
- Pagination: page, limit
- Includes: profile, meta
GET /export/charts
- Retrieve aggregated chart data
- Events with breakdowns
- Intervals: minute, hour, day, week, month
- Ranges: 30min, today, 7d, 30d, 6m, 12m, etc.
```
### Dashboard tRPC API (Next.js - /api/trpc)
Internal API for dashboard management:
```
Projects:
- project.list, project.get, project.create, project.update, project.delete
Dashboards:
- dashboard.list, dashboard.get, dashboard.create, dashboard.update, dashboard.delete
Charts:
- chart.create, chart.update, chart.delete
Clients:
- client.list, client.create, client.delete, client.regenerate
Funnels:
- funnel.list, funnel.get, funnel.create, funnel.update, funnel.delete
Reports:
- report.overview, report.retention, report.paths
Users/Profiles:
- profile.list, profile.get, profile.events
```
---
## Plugin Architecture
### Project Structure
```
plugins/openpanel/
├── __init__.py # Export: OpenPanelPlugin, OpenPanelClient
├── plugin.py # Main OpenPanelPlugin class
├── client.py # OpenPanelClient (unified client)
└── handlers/
├── __init__.py
├── events.py # Event tracking (10 tools)
├── export.py # Data export (10 tools)
├── projects.py # Project management (8 tools)
├── dashboards.py # Dashboard management (10 tools)
├── funnels.py # Funnel analytics (8 tools)
├── profiles.py # User profiles (8 tools)
├── clients.py # API client management (6 tools)
├── reports.py # Analytics reports (8 tools)
└── system.py # Health & stats (6 tools)
```
### Client Architecture
```python
class OpenPanelClient:
"""
Unified client for OpenPanel Self-Hosted APIs
Handles both Track/Export API (Fastify) and
Dashboard tRPC API (Next.js) where available.
"""
def __init__(
self,
base_url: str, # e.g., https://analytics.example.com
client_id: str, # Client ID for authentication
client_secret: str, # Client Secret for authentication
):
self.base_url = base_url.rstrip('/')
self.api_url = f"{self.base_url}/api"
self.client_id = client_id
self.client_secret = client_secret
def _get_headers(self, include_ip: str = None) -> Dict[str, str]:
"""Get authentication headers"""
headers = {
"Content-Type": "application/json",
"openpanel-client-id": self.client_id,
"openpanel-client-secret": self.client_secret
}
if include_ip:
headers["x-client-ip"] = include_ip
return headers
async def track(
self,
event_type: str,
payload: Dict[str, Any],
client_ip: str = None
) -> Dict[str, Any]:
"""Send tracking request to /track endpoint"""
...
async def export_events(
self,
project_id: str,
**filters
) -> Dict[str, Any]:
"""Export events from /export/events"""
...
```
---
## Tool Categories
### 1. Events Handler (10 tools)
Event tracking and ingestion operations.
| Tool | Type | Scope | Description |
|------|------|-------|-------------|
| `track_event` | track | write | Track custom event with properties |
| `track_page_view` | track | write | Track page view event |
| `track_screen_view` | track | write | Track screen view (mobile) |
| `identify_user` | identify | write | Identify user with profile data |
| `set_user_properties` | identify | write | Update user properties |
| `increment_property` | increment | write | Increment numeric property |
| `decrement_property` | decrement | write | Decrement numeric property |
| `alias_user` | alias | write | Link two profile IDs |
| `track_revenue` | track | write | Track revenue/purchase event |
| `track_batch` | track | write | Track multiple events in batch |
```python
# Example: track_event
{
"name": "track_event",
"method_name": "track_event",
"description": "Track a custom event with properties. Events can have any custom properties.",
"schema": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Event name (e.g., 'button_clicked', 'purchase_completed')"
},
"properties": {
"type": "object",
"description": "Custom properties for the event"
},
"profile_id": {
"type": "string",
"description": "User/profile ID to associate with event"
},
"timestamp": {
"type": "string",
"format": "date-time",
"description": "Event timestamp (ISO 8601, defaults to now)"
}
},
"required": ["name"]
},
"scope": "write"
}
```
### 2. Export Handler (10 tools)
Data export and retrieval operations.
| Tool | Type | Scope | Description |
|------|------|-------|-------------|
| `export_events` | GET | read | Export raw event data |
| `export_events_csv` | GET | read | Export events as CSV |
| `export_chart_data` | GET | read | Export aggregated chart data |
| `get_event_count` | GET | read | Get event counts with filters |
| `get_unique_users` | GET | read | Get unique user count |
| `get_page_views` | GET | read | Get page view statistics |
| `get_top_pages` | GET | read | Get top pages by views |
| `get_top_referrers` | GET | read | Get top traffic sources |
| `get_geo_data` | GET | read | Get geographic distribution |
| `get_device_data` | GET | read | Get device/browser breakdown |
```python
# Example: export_events
{
"name": "export_events",
"method_name": "export_events",
"description": "Export raw event data with filters and pagination",
"schema": {
"type": "object",
"properties": {
"project_id": {
"type": "string",
"description": "Project ID to export from"
},
"event": {
"anyOf": [{"type": "string"}, {"type": "array", "items": {"type": "string"}}],
"description": "Event name(s) to filter"
},
"profile_id": {
"type": "string",
"description": "Filter by user/profile ID"
},
"start": {
"type": "string",
"format": "date",
"description": "Start date (YYYY-MM-DD)"
},
"end": {
"type": "string",
"format": "date",
"description": "End date (YYYY-MM-DD)"
},
"limit": {
"type": "integer",
"default": 50,
"maximum": 1000
},
"page": {
"type": "integer",
"default": 1
},
"includes": {
"type": "array",
"items": {"type": "string", "enum": ["profile", "meta"]},
"description": "Additional data to include"
}
},
"required": ["project_id"]
},
"scope": "read"
}
```
### 3. Projects Handler (8 tools)
Project management operations.
| Tool | Method | Scope | Description |
|------|--------|-------|-------------|
| `list_projects` | GET | read | List all projects |
| `get_project` | GET | read | Get project details |
| `create_project` | POST | admin | Create new project |
| `update_project` | PUT | admin | Update project settings |
| `delete_project` | DELETE | admin | Delete project |
| `get_project_stats` | GET | read | Get project statistics |
| `get_project_settings` | GET | read | Get project configuration |
| `update_project_settings` | PUT | admin | Update project configuration |
### 4. Dashboards Handler (10 tools)
Dashboard and chart management.
| Tool | Method | Scope | Description |
|------|--------|-------|-------------|
| `list_dashboards` | GET | read | List all dashboards |
| `get_dashboard` | GET | read | Get dashboard with charts |
| `create_dashboard` | POST | write | Create new dashboard |
| `update_dashboard` | PUT | write | Update dashboard |
| `delete_dashboard` | DELETE | write | Delete dashboard |
| `add_chart` | POST | write | Add chart to dashboard |
| `update_chart` | PUT | write | Update chart configuration |
| `delete_chart` | DELETE | write | Remove chart from dashboard |
| `duplicate_dashboard` | POST | write | Clone existing dashboard |
| `share_dashboard` | POST | write | Generate shareable link |
### 5. Funnels Handler (8 tools)
Funnel analysis operations.
| Tool | Method | Scope | Description |
|------|--------|-------|-------------|
| `list_funnels` | GET | read | List all funnels |
| `get_funnel` | GET | read | Get funnel with conversion data |
| `create_funnel` | POST | write | Create new funnel |
| `update_funnel` | PUT | write | Update funnel steps |
| `delete_funnel` | DELETE | write | Delete funnel |
| `get_funnel_conversion` | GET | read | Get conversion rates |
| `get_funnel_breakdown` | GET | read | Get breakdown by segment |
| `compare_funnels` | GET | read | Compare multiple funnels |
```python
# Example: create_funnel
{
"name": "create_funnel",
"method_name": "create_funnel",
"description": "Create a funnel to track user journey through steps",
"schema": {
"type": "object",
"properties": {
"project_id": {
"type": "string",
"description": "Project ID"
},
"name": {
"type": "string",
"description": "Funnel name"
},
"steps": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {"type": "string"},
"event": {"type": "string"},
"filters": {"type": "array"}
},
"required": ["name", "event"]
},
"description": "Funnel steps (events in sequence)",
"minItems": 2
},
"window_days": {
"type": "integer",
"default": 14,
"description": "Conversion window in days"
}
},
"required": ["project_id", "name", "steps"]
},
"scope": "write"
}
```
### 6. Profiles Handler (8 tools)
User profile management.
| Tool | Method | Scope | Description |
|------|--------|-------|-------------|
| `list_profiles` | GET | read | List user profiles |
| `get_profile` | GET | read | Get profile details |
| `search_profiles` | GET | read | Search profiles by property |
| `get_profile_events` | GET | read | Get events for profile |
| `get_profile_sessions` | GET | read | Get sessions for profile |
| `delete_profile` | DELETE | admin | Delete profile data (GDPR) |
| `merge_profiles` | POST | admin | Merge duplicate profiles |
| `export_profile_data` | GET | read | Export all profile data (GDPR) |
### 7. Clients Handler (6 tools)
API client/key management.
| Tool | Method | Scope | Description |
|------|--------|-------|-------------|
| `list_clients` | GET | read | List API clients |
| `get_client` | GET | read | Get client details |
| `create_client` | POST | admin | Create new API client |
| `delete_client` | DELETE | admin | Delete API client |
| `regenerate_secret` | POST | admin | Regenerate client secret |
| `update_client_mode` | PUT | admin | Update client permissions |
### 8. Reports Handler (8 tools)
Analytics and reporting.
| Tool | Method | Scope | Description |
|------|--------|-------|-------------|
| `get_overview_report` | GET | read | Get overview statistics |
| `get_retention_report` | GET | read | Get retention analysis |
| `get_cohort_report` | GET | read | Get cohort analysis |
| `get_paths_report` | GET | read | Get user flow paths |
| `get_realtime_stats` | GET | read | Get real-time visitors |
| `get_ab_test_results` | GET | read | Get A/B test results |
| `create_report` | POST | write | Create scheduled report |
| `export_report` | GET | read | Export report as PDF/CSV |
### 9. System Handler (6 tools)
System health and management.
| Tool | Method | Scope | Description |
|------|--------|-------|-------------|
| `health_check` | GET | read | Check service health |
| `get_instance_info` | GET | read | Get instance information |
| `get_usage_stats` | GET | read | Get usage statistics |
| `get_storage_stats` | GET | read | Get storage usage (ClickHouse) |
| `test_connection` | GET | read | Test API connection |
| `get_rate_limit_status` | GET | read | Check rate limit status |
---
## Tool Summary
| Handler | Tools | Description |
|---------|-------|-------------|
| Events | 10 | Event tracking & ingestion |
| Export | 10 | Data export & retrieval |
| Projects | 8 | Project management |
| Dashboards | 10 | Dashboard & chart management |
| Funnels | 8 | Funnel analysis |
| Profiles | 8 | User profile management |
| Clients | 6 | API client management |
| Reports | 8 | Analytics & reporting |
| System | 6 | Health & instance info |
| **Total** | **74** | |
---
## Implementation Phases
### Phase H.1: Core (Required)
**Goal**: Basic event tracking and data export
1. **OpenPanelPlugin** class
2. **OpenPanelClient** (unified)
3. **Events Handler** (10 tools)
4. **Export Handler** (10 tools)
5. **System Handler** (6 tools)
**Tools**: 26
### Phase H.2: Analytics (Recommended)
**Goal**: Advanced analytics features
1. **Reports Handler** (8 tools)
2. **Funnels Handler** (8 tools)
3. **Profiles Handler** (8 tools)
**Tools**: 24 (Total: 50)
### Phase H.3: Management (Complete)
**Goal**: Full dashboard and project management
1. **Projects Handler** (8 tools)
2. **Dashboards Handler** (10 tools)
3. **Clients Handler** (6 tools)
**Tools**: 24 (Total: 74)
---
## Export API Reference
### Event Segmentation Types
| Segment | Description |
|---------|-------------|
| `event` | Count total events |
| `user` | Count unique users |
| `session` | Count unique sessions |
| `user_average` | Average per user |
| `one_event_per_user` | First event per user |
| `property_sum` | Sum of property values |
| `property_average` | Average of property values |
| `property_min` | Minimum property value |
| `property_max` | Maximum property value |
### Filter Operators
| Operator | Description |
|----------|-------------|
| `is` | Exact match |
| `isNot` | Not equal |
| `contains` | Contains substring |
| `doesNotContain` | Does not contain |
| `startsWith` | Starts with |
| `endsWith` | Ends with |
| `regex` | Regular expression |
| `isNull` | Is null/undefined |
| `isNotNull` | Is not null |
### Breakdown Dimensions
| Dimension | Description |
|-----------|-------------|
| `country` | Country |
| `region` | Region/State |
| `city` | City |
| `device` | Device type |
| `browser` | Browser name |
| `os` | Operating system |
| `referrer` | Traffic source |
| `path` | Page path |
### Date Ranges
```
30min, lastHour, today, yesterday
7d, 30d, 6m, 12m
monthToDate, lastMonth
yearToDate, lastYear
```
---
## Error Handling
### HTTP Status Codes
| Code | Description | Action |
|------|-------------|--------|
| 200 | Success | Return data |
| 400 | Bad Request | Validate input |
| 401 | Unauthorized | Check credentials |
| 403 | Forbidden | Check client mode |
| 404 | Not Found | Resource doesn't exist |
| 429 | Rate Limited | Implement backoff |
| 500 | Server Error | Retry with backoff |
### Rate Limiting
```
Limit: 100 requests per 10 seconds per client
Backoff: Exponential (1s, 2s, 4s, 8s...)
Headers:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1699999999
```
---
## Security Considerations
### Client Secret Protection
```
┌─────────────────────────────────────────────────────────────────┐
│ Client Security │
├─────────────────────────────────────────────────────────────────┤
│ │
│ write mode client: │
│ ├── Can send events only │
│ ├── Cannot read data │
│ └── Safe for client-side (with domain restrictions) │
│ │
│ read mode client: │
│ ├── Can export data │
│ ├── Cannot send events │
│ └── Server-side only │
│ │
│ root mode client: │
│ ├── Full access │
│ ├── Can manage projects, clients │
│ └── ⚠️ Server-side only - Never expose! │
│ │
└─────────────────────────────────────────────────────────────────┘
```
### Best Practices
1. **Use appropriate client mode** - write for tracking, read for export
2. **Never expose root clients** - Server-side only
3. **Implement rate limiting** - Respect API limits
4. **GDPR compliance** - Use profile deletion tools
5. **Audit data exports** - Log who exports what
---
## Example Usage
### Track Event
```json
{
"tool": "track_event",
"args": {
"site": "myanalytics",
"name": "purchase_completed",
"properties": {
"product_id": "prod_123",
"amount": 99.99,
"currency": "USD",
"category": "electronics"
},
"profile_id": "user_456"
}
}
```
### Identify User
```json
{
"tool": "identify_user",
"args": {
"site": "myanalytics",
"profile_id": "user_456",
"properties": {
"firstName": "John",
"lastName": "Doe",
"email": "john@example.com",
"plan": "premium",
"company": "Acme Inc"
}
}
}
```
### Export Events
```json
{
"tool": "export_events",
"args": {
"site": "myanalytics",
"project_id": "proj_abc",
"event": "purchase_completed",
"start": "2025-11-01",
"end": "2025-11-30",
"limit": 100,
"includes": ["profile"]
}
}
```
### Create Funnel
```json
{
"tool": "create_funnel",
"args": {
"site": "myanalytics",
"project_id": "proj_abc",
"name": "Checkout Flow",
"steps": [
{"name": "View Product", "event": "product_viewed"},
{"name": "Add to Cart", "event": "cart_added"},
{"name": "Start Checkout", "event": "checkout_started"},
{"name": "Complete Purchase", "event": "purchase_completed"}
],
"window_days": 7
}
}
```
### Get Retention Report
```json
{
"tool": "get_retention_report",
"args": {
"site": "myanalytics",
"project_id": "proj_abc",
"start_event": "signup_completed",
"return_event": "app_opened",
"period": "week",
"cohorts": 12
}
}
```
---
## Coolify Deployment Notes
### OpenPanel Services
```yaml
# OpenPanel services in Coolify
services:
dashboard: # Next.js - port 3000
api: # Fastify Event API - port 3333
worker: # BullMQ worker
postgres: # PostgreSQL - metadata
clickhouse: # ClickHouse - events
redis: # Redis - cache/queue
```
### Environment Variables (Coolify)
```bash
# Required
NEXT_PUBLIC_DASHBOARD_URL=https://analytics.example.com
DATABASE_URL=postgresql://...
CLICKHOUSE_URL=http://clickhouse:8123
REDIS_URL=redis://redis:6379
# Optional
RESEND_API_KEY=re_...
OPENAI_API_KEY=sk-... # For AI features
ANTHROPIC_API_KEY=sk-...
```
### Finding Credentials
1. **URL**: Coolify Dashboard → Project → OpenPanel → Domain
2. **Client ID/Secret**: OpenPanel Dashboard → Settings → Clients
---
## Endpoint Registration
### Endpoint Config
```python
# core/endpoints/config.py
EndpointType.OPENPANEL: EndpointConfig(
path="/openpanel",
name="OpenPanel Analytics",
description="OpenPanel product analytics management (events, funnels, dashboards)",
endpoint_type=EndpointType.OPENPANEL,
plugin_types=["openpanel"],
require_master_key=False,
allowed_scopes={"read", "write", "admin"},
tool_blacklist={
"manage_api_keys_create",
"manage_api_keys_delete",
"oauth_register_client",
"oauth_revoke_client",
},
max_tools=80,
),
```
---
## Testing Checklist
### Unit Tests
- [ ] OpenPanelClient authentication
- [ ] Track API operations (track, identify, increment)
- [ ] Export API operations (events, charts)
- [ ] Error handling for all endpoints
- [ ] Rate limiting behavior
### Integration Tests
- [ ] Track event and verify in export
- [ ] Create funnel and get conversion data
- [ ] Create dashboard with charts
- [ ] Profile identification and merging
- [ ] GDPR data export and deletion
---
## Comparison with Other Plugins
| Aspect | Supabase | n8n | OpenPanel |
|--------|----------|-----|-----------|
| Primary Focus | Database/Backend | Automation | Analytics |
| Auth Method | JWT Keys | API Key | Client ID/Secret |
| Main APIs | PostgREST, GoTrue | REST API | Track, Export |
| Tools | 70 | 56 | 74 |
| Phases | 3 | 1 | 3 |
---
## References
- [OpenPanel Documentation](https://openpanel.dev/docs)
- [OpenPanel GitHub](https://github.com/Openpanel-dev/openpanel)
- [Track API Reference](https://openpanel.dev/docs/api/track)
- [Export API Reference](https://openpanel.dev/docs/api/export)
- [Coolify OpenPanel](https://coolify.io/docs/services/openpanel)
---
**Created**: 2025-11-30
**Author**: Claude AI Assistant
**Status**: Design Phase

View File

@@ -0,0 +1,721 @@
# Supabase Plugin Design - Phase G
> **MCP Plugin برای مدیریت Supabase Self-Hosted روی Coolify**
**Version**: v1.1.0 (طراحی - Self-Hosted)
**Priority**: High
**Estimated Tools**: 70-75
---
## Overview
پلاگین Supabase برای مدیریت **Supabase Self-Hosted** روی Coolify طراحی شده است.
### تفاوت Self-Hosted با Cloud
```
┌─────────────────────────────────────────────────────────────────┐
│ Supabase Self-Hosted vs Cloud │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ✅ موجود در Self-Hosted: │
│ ├── Database API (PostgREST) - /rest/v1/ │
│ ├── Auth API (GoTrue) - /auth/v1/ │
│ ├── Storage API - /storage/v1/ │
│ ├── Edge Functions - /functions/v1/ │
│ ├── postgres-meta (DB Admin) - /pg/ │
│ └── Realtime - /realtime/v1/ (WebSocket) │
│ │
│ ❌ فقط در Cloud: │
│ ├── Management API (api.supabase.com) │
│ ├── Projects & Organizations │
│ ├── Database Branches │
│ ├── Platform Analytics │
│ └── Secrets Management (platform-level) │
│ │
└─────────────────────────────────────────────────────────────────┘
```
**نکته مهم**: در Self-Hosted، هر instance یک پروژه است. Management API وجود ندارد.
---
## Authentication
### سطح واحد احراز هویت
```
┌─────────────────────────────────────────────────────────────────┐
│ Supabase Self-Hosted Auth │
├─────────────────────────────────────────────────────────────────┤
│ │
│ API Keys (JWT-based): │
│ ├── anon_key │
│ │ ├── Public/client-safe │
│ │ ├── Protected by RLS policies │
│ │ └── role: "anon" in JWT │
│ │ │
│ └── service_role_key │
│ ├── ⚠️ SERVER-ONLY - Never expose! │
│ ├── Bypasses ALL RLS policies │
│ └── role: "service_role" in JWT │
│ │
│ All keys signed with JWT_SECRET from .env │
│ │
└─────────────────────────────────────────────────────────────────┘
```
### Environment Variables
```bash
# Supabase Self-Hosted Instance (Required)
SUPABASE_SITE1_URL=https://supabase.example.com
SUPABASE_SITE1_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
SUPABASE_SITE1_SERVICE_ROLE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
SUPABASE_SITE1_ALIAS=mysupabase
# Optional: Direct database access for postgres-meta
SUPABASE_SITE1_DB_HOST=db.supabase.example.com
SUPABASE_SITE1_DB_PORT=5432
SUPABASE_SITE1_DB_NAME=postgres
SUPABASE_SITE1_DB_USER=postgres
SUPABASE_SITE1_DB_PASSWORD=your-db-password
# Multiple Instances
SUPABASE_SITE2_URL=https://supabase-staging.example.com
SUPABASE_SITE2_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
SUPABASE_SITE2_SERVICE_ROLE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
SUPABASE_SITE2_ALIAS=staging
```
---
## API Endpoints (Kong Gateway)
تمام API ها از طریق Kong API Gateway (پورت 8000) در دسترس هستند:
```
Base URL: https://supabase.example.com (یا http://localhost:8000)
Database (PostgREST):
GET/POST/PATCH/DELETE /rest/v1/{table}
POST /rest/v1/rpc/{function}
Auth (GoTrue):
POST /auth/v1/signup
POST /auth/v1/token
GET /auth/v1/user
POST /auth/v1/admin/users
...
Storage:
GET/POST/DELETE /storage/v1/bucket
GET/POST/DELETE /storage/v1/object/{bucket}/{path}
...
Edge Functions:
POST /functions/v1/{function_name}
postgres-meta (Admin):
GET /pg/tables
GET /pg/columns
GET /pg/policies
...
```
---
## Architecture
### Project Structure
```
plugins/supabase/
├── __init__.py # Export: SupabasePlugin, SupabaseClient
├── plugin.py # کلاس اصلی SupabasePlugin
├── client.py # SupabaseClient (unified client)
└── handlers/
├── __init__.py
├── database.py # Database operations (18 tools)
├── auth.py # User management (14 tools)
├── storage.py # File management (12 tools)
├── functions.py # Edge Functions (8 tools)
├── admin.py # postgres-meta admin (12 tools)
└── system.py # Health & info (6 tools)
```
### Client Architecture
```python
class SupabaseClient:
"""
Unified client for Supabase Self-Hosted APIs
All requests go through Kong gateway on single base URL.
"""
def __init__(
self,
base_url: str, # e.g., https://supabase.example.com
anon_key: str, # For public/RLS-protected operations
service_role_key: str, # For admin operations (bypasses RLS)
):
self.base_url = base_url.rstrip('/')
self.anon_key = anon_key
self.service_role_key = service_role_key
async def request(
self,
method: str,
endpoint: str,
use_service_role: bool = False,
**kwargs
) -> Any:
"""Make authenticated request to Supabase API"""
key = self.service_role_key if use_service_role else self.anon_key
headers = {
"apikey": key,
"Authorization": f"Bearer {key}",
"Content-Type": "application/json"
}
url = f"{self.base_url}{endpoint}"
# ... request logic
```
---
## Tool Categories
### 1. Database Handler (18 tools)
عملیات CRUD روی دیتابیس PostgreSQL از طریق PostgREST
| Tool | Method | Scope | Description |
|------|--------|-------|-------------|
| `list_tables` | GET | read | لیست جداول (via postgres-meta) |
| `get_table_schema` | GET | read | ساختار جدول |
| `query_table` | GET | read | کوئری SELECT با فیلتر |
| `insert_rows` | POST | write | درج رکوردها |
| `update_rows` | PATCH | write | به‌روزرسانی رکوردها |
| `upsert_rows` | POST | write | درج/به‌روزرسانی |
| `delete_rows` | DELETE | write | حذف رکوردها |
| `execute_rpc` | POST | write | اجرای stored procedure |
| `count_rows` | GET | read | شمارش رکوردها |
| `get_row_by_id` | GET | read | دریافت یک رکورد با ID |
| `bulk_insert` | POST | write | درج دسته‌ای |
| `bulk_update` | PATCH | write | به‌روزرسانی دسته‌ای |
| `bulk_delete` | DELETE | write | حذف دسته‌ای |
| `search_text` | GET | read | جستجوی Full-text |
| `get_foreign_tables` | GET | read | جداول مرتبط |
| `execute_sql` | POST | admin | اجرای SQL مستقیم (via postgres-meta) |
| `create_table` | POST | admin | ایجاد جدول جدید |
| `drop_table` | DELETE | admin | حذف جدول |
```python
# Query Table Example
{
"name": "supabase_query_table",
"description": "Query data from a Supabase table with filters and pagination",
"schema": {
"type": "object",
"properties": {
"site": {
"type": "string",
"description": "Supabase instance alias or site ID"
},
"table": {
"type": "string",
"description": "Table name"
},
"select": {
"type": "string",
"description": "Columns to select (e.g., 'id,name,email' or '*')",
"default": "*"
},
"filters": {
"type": "array",
"items": {
"type": "object",
"properties": {
"column": {"type": "string"},
"operator": {
"type": "string",
"enum": ["eq", "neq", "gt", "gte", "lt", "lte",
"like", "ilike", "in", "is", "cs", "cd"]
},
"value": {}
}
},
"description": "PostgREST filter conditions"
},
"order": {
"type": "string",
"description": "Order by (e.g., 'created_at.desc')"
},
"limit": {
"type": "integer",
"default": 100,
"maximum": 1000
},
"offset": {
"type": "integer",
"default": 0
}
},
"required": ["table"]
},
"scope": "read"
}
```
### 2. Auth Handler (14 tools)
مدیریت کاربران از طریق GoTrue Admin API
| Tool | Method | Scope | Description |
|------|--------|-------|-------------|
| `list_users` | GET | admin | لیست کاربران |
| `get_user` | GET | read | جزئیات کاربر |
| `create_user` | POST | admin | ایجاد کاربر |
| `update_user` | PUT | admin | به‌روزرسانی کاربر |
| `delete_user` | DELETE | admin | حذف کاربر |
| `invite_user` | POST | admin | ارسال دعوت‌نامه |
| `generate_link` | POST | admin | تولید magic/recovery link |
| `ban_user` | PUT | admin | مسدود کردن کاربر |
| `unban_user` | PUT | admin | رفع مسدودیت |
| `list_factors` | GET | read | لیست MFA factors |
| `delete_factor` | DELETE | admin | حذف MFA factor |
| `get_audit_logs` | GET | read | لاگ‌های auth |
| `verify_otp` | POST | write | تایید OTP |
| `resend_otp` | POST | write | ارسال مجدد OTP |
```python
# Create User Example
{
"name": "supabase_create_user",
"description": "Create a new user in Supabase Auth",
"schema": {
"type": "object",
"properties": {
"site": {"type": "string"},
"email": {
"type": "string",
"format": "email"
},
"password": {
"type": "string",
"minLength": 6
},
"phone": {
"type": "string",
"description": "Phone number (E.164 format)"
},
"email_confirm": {
"type": "boolean",
"default": false,
"description": "Auto-confirm email"
},
"user_metadata": {
"type": "object",
"description": "Custom user metadata"
},
"app_metadata": {
"type": "object",
"description": "App-specific metadata"
}
},
"required": ["email", "password"]
},
"scope": "admin"
}
```
### 3. Storage Handler (12 tools)
مدیریت فایل‌ها و bucket ها
| Tool | Method | Scope | Description |
|------|--------|-------|-------------|
| `list_buckets` | GET | read | لیست bucket ها |
| `get_bucket` | GET | read | جزئیات bucket |
| `create_bucket` | POST | admin | ایجاد bucket |
| `update_bucket` | PUT | admin | به‌روزرسانی bucket |
| `delete_bucket` | DELETE | admin | حذف bucket |
| `empty_bucket` | POST | admin | خالی کردن bucket |
| `list_files` | GET | read | لیست فایل‌ها در مسیر |
| `upload_file` | POST | write | آپلود فایل |
| `download_file` | GET | read | دانلود فایل (base64) |
| `delete_files` | DELETE | write | حذف فایل‌ها |
| `move_file` | POST | write | انتقال/تغییر نام فایل |
| `get_public_url` | GET | read | دریافت URL عمومی |
### 4. Functions Handler (8 tools)
مدیریت و اجرای Edge Functions
| Tool | Method | Scope | Description |
|------|--------|-------|-------------|
| `list_functions` | GET | read | لیست functions موجود |
| `invoke_function` | POST | write | اجرای function |
| `invoke_function_get` | GET | read | اجرای function با GET |
| `get_function_body` | GET | read | دریافت کد function |
| `deploy_function` | POST | admin | deploy function جدید |
| `delete_function` | DELETE | admin | حذف function |
| `get_function_logs` | GET | read | لاگ‌های اخیر |
| `update_function_secrets` | PATCH | admin | تنظیم secrets |
**نکته**: در Self-Hosted، functions در `volumes/functions/` ذخیره می‌شوند.
### 5. Admin Handler (12 tools)
عملیات مدیریتی دیتابیس از طریق postgres-meta
| Tool | Method | Scope | Description |
|------|--------|-------|-------------|
| `list_schemas` | GET | read | لیست schemas |
| `list_extensions` | GET | read | لیست extensions |
| `enable_extension` | POST | admin | فعال‌سازی extension |
| `disable_extension` | DELETE | admin | غیرفعال‌سازی extension |
| `list_policies` | GET | read | لیست RLS policies |
| `create_policy` | POST | admin | ایجاد RLS policy |
| `update_policy` | PATCH | admin | به‌روزرسانی policy |
| `delete_policy` | DELETE | admin | حذف policy |
| `list_roles` | GET | read | لیست database roles |
| `list_triggers` | GET | read | لیست triggers |
| `list_functions_db` | GET | read | لیست DB functions |
| `get_database_size` | GET | read | سایز دیتابیس |
### 6. System Handler (6 tools)
سلامت و اطلاعات سیستم
| Tool | Method | Scope | Description |
|------|--------|-------|-------------|
| `health_check` | GET | read | بررسی سلامت |
| `get_config` | GET | read | تنظیمات فعلی |
| `get_version` | GET | read | نسخه سرویس‌ها |
| `test_connection` | GET | read | تست اتصال |
| `get_stats` | GET | read | آمار سرویس‌ها |
| `ping` | GET | read | Ping ساده |
---
## Tool Summary
| Handler | Tools | Description |
|---------|-------|-------------|
| Database | 18 | PostgREST CRUD + SQL |
| Auth | 14 | GoTrue user management |
| Storage | 12 | File & bucket management |
| Functions | 8 | Edge Functions |
| Admin | 12 | postgres-meta DB admin |
| System | 6 | Health & info |
| **Total** | **70** | |
---
## Implementation Phases
### Phase G.1: Core (Required)
**هدف**: دسترسی اولیه به Supabase Self-Hosted
1. **SupabasePlugin** class
2. **SupabaseClient** (unified)
3. **Database Handler** (18 tools)
4. **System Handler** (6 tools)
**ابزارها**: 24
### Phase G.2: Auth & Storage (Recommended)
**هدف**: مدیریت کاربران و فایل‌ها
1. **Auth Handler** (14 tools)
2. **Storage Handler** (12 tools)
**ابزارها**: 26 (جمع: 50)
### Phase G.3: Advanced (Complete)
**هدف**: قابلیت‌های پیشرفته
1. **Functions Handler** (8 tools)
2. **Admin Handler** (12 tools)
**ابزارها**: 20 (جمع: 70)
---
## PostgREST Operators Reference
| Operator | Description | Example |
|----------|-------------|---------|
| `eq` | Equal | `?column=eq.value` |
| `neq` | Not equal | `?column=neq.value` |
| `gt` | Greater than | `?column=gt.5` |
| `gte` | Greater or equal | `?column=gte.5` |
| `lt` | Less than | `?column=lt.10` |
| `lte` | Less or equal | `?column=lte.10` |
| `like` | LIKE (case-sensitive) | `?column=like.*pattern*` |
| `ilike` | LIKE (case-insensitive) | `?column=ilike.*pattern*` |
| `in` | IN array | `?column=in.(a,b,c)` |
| `is` | IS (null, true, false) | `?column=is.null` |
| `cs` | Contains (arrays) | `?column=cs.{a,b}` |
| `cd` | Contained by | `?column=cd.{a,b,c}` |
| `fts` | Full-text search | `?column=fts.query` |
---
## Error Handling
### PostgREST Errors
```python
async def handle_postgrest_error(response):
data = await response.json()
if response.status == 400:
# Validation error
raise ValidationError(data.get("message", "Invalid request"))
elif response.status == 401:
raise AuthError("Invalid API key")
elif response.status == 403:
# RLS policy violation
raise RLSError(f"Row Level Security: {data.get('message')}")
elif response.status == 404:
raise NotFoundError("Resource not found")
elif response.status == 409:
raise ConflictError("Unique constraint violation")
elif response.status == 406:
raise NotAcceptableError("Invalid Accept header")
```
### GoTrue Errors
```python
async def handle_gotrue_error(response):
data = await response.json()
error_code = data.get("error_code") or data.get("code")
message = data.get("msg") or data.get("message") or data.get("error_description")
if error_code == "user_not_found":
raise UserNotFoundError(message)
elif error_code == "email_exists":
raise DuplicateError("Email already registered")
# ... more error codes
```
---
## Security Considerations
### Key Security
```
┌─────────────────────────────────────────────────────────────────┐
│ API Key Security │
├─────────────────────────────────────────────────────────────────┤
│ │
│ anon_key: │
│ ├── ✅ Safe for client-side │
│ ├── ✅ Protected by RLS policies │
│ ├── ⚠️ Always enable RLS on tables │
│ └── Used for: read operations, authenticated user actions │
│ │
│ service_role_key: │
│ ├── ❌ NEVER expose to client │
│ ├── ❌ Bypasses ALL RLS policies │
│ ├── ✅ Server-side only │
│ └── Used for: admin operations, background jobs │
│ │
└─────────────────────────────────────────────────────────────────┘
```
### Best Practices
1. **Always use RLS** - حتی با service_role_key، RLS را فعال نگه دارید
2. **Minimal service_role usage** - فقط وقتی واقعاً نیاز است
3. **Never log keys** - حتی در error messages
4. **Validate input** - قبل از اجرای SQL
5. **Audit admin operations** - تمام عملیات admin لاگ شود
---
## Example Usage
### Query Database
```json
{
"tool": "supabase_query_table",
"args": {
"site": "mysupabase",
"table": "users",
"select": "id,email,created_at",
"filters": [
{"column": "role", "operator": "eq", "value": "admin"}
],
"order": "created_at.desc",
"limit": 50
}
}
```
### Create User
```json
{
"tool": "supabase_create_user",
"args": {
"site": "mysupabase",
"email": "user@example.com",
"password": "secure-password",
"email_confirm": true,
"user_metadata": {
"name": "John Doe",
"role": "editor"
}
}
}
```
### Upload File
```json
{
"tool": "supabase_upload_file",
"args": {
"site": "mysupabase",
"bucket": "avatars",
"path": "users/123/profile.png",
"content_base64": "iVBORw0KGgoAAAANSUhEUgAA...",
"content_type": "image/png",
"upsert": true
}
}
```
### Invoke Edge Function
```json
{
"tool": "supabase_invoke_function",
"args": {
"site": "mysupabase",
"function_name": "send-notification",
"body": {
"user_id": "123",
"message": "Hello from AI!"
}
}
}
```
---
## Coolify Deployment Notes
### Finding Supabase Credentials
در Coolify، بعد از deploy کردن Supabase:
1. **URL**: از Coolify dashboard → Project → Supabase → Domain
2. **Keys**: در Environment Variables:
- `ANON_KEY` - کلید عمومی
- `SERVICE_ROLE_KEY` - کلید ادمین
- `JWT_SECRET` - برای verify کردن tokens
### Kong Gateway Port
```
Default: 8000
HTTPS: 8443 (اگر SSL فعال باشد)
Coolify معمولاً reverse proxy می‌کند:
https://supabase.example.com → Kong:8000
```
### Docker Compose Services
```yaml
# Supabase services on Coolify
services:
kong: # API Gateway - port 8000
auth: # GoTrue - /auth/v1/
rest: # PostgREST - /rest/v1/
storage: # Storage API - /storage/v1/
meta: # postgres-meta - /pg/
functions: # Edge Functions - /functions/v1/
db: # PostgreSQL
realtime: # Realtime WebSocket
```
---
## Endpoint Registration
### Endpoint Config
```python
# core/endpoints/config.py
EndpointType.SUPABASE: EndpointConfig(
path="/supabase",
name="Supabase Manager",
description="Supabase Self-Hosted management (database, auth, storage, functions)",
endpoint_type=EndpointType.SUPABASE,
plugin_types=["supabase"],
require_master_key=False,
allowed_scopes={"read", "write", "admin"},
tool_blacklist={
"manage_api_keys_create",
"manage_api_keys_delete",
"manage_api_keys_rotate",
"oauth_register_client",
"oauth_revoke_client",
},
max_tools=80,
),
```
---
## Testing Checklist
### Unit Tests
- [ ] SupabaseClient authentication
- [ ] PostgREST CRUD operations
- [ ] PostgREST filtering and pagination
- [ ] GoTrue user operations
- [ ] Storage file operations
- [ ] Error handling for all endpoints
### Integration Tests
- [ ] Query and modify database
- [ ] Create and authenticate user
- [ ] Upload and download file
- [ ] Invoke Edge Function
- [ ] RLS policy enforcement
- [ ] Service role bypass
---
## References
- [Supabase Self-Hosting Docker](https://supabase.com/docs/guides/self-hosting/docker)
- [PostgREST Documentation](https://postgrest.org/en/stable/)
- [GoTrue API Reference](https://github.com/supabase/auth)
- [Supabase Storage API](https://supabase.com/docs/guides/storage)
- [Kong API Gateway](https://docs.konghq.com/)
- [postgres-meta](https://github.com/supabase/postgres-meta)
---
**Created**: 2025-11-29
**Updated**: 2025-11-29 (Self-Hosted version)
**Author**: Claude AI Assistant
**Status**: Design Phase

676
docs/troubleshooting.md Normal file
View File

@@ -0,0 +1,676 @@
# 🔧 Troubleshooting Guide
---
## Table of Contents
1. [Common Errors](#common-errors)
2. [Connection Issues](#connection-issues)
3. [Authentication Problems](#authentication-problems)
4. [Rate Limiting Issues](#rate-limiting-issues)
5. [Docker Problems](#docker-problems)
6. [Performance Issues](#performance-issues)
7. [Tool Registration Issues](#tool-registration-issues)
8. [Logging and Debugging](#logging-and-debugging)
9. [Getting Help](#getting-help)
---
## Common Errors
### Error: "No module named 'fastmcp'"
**Cause**: Dependencies not installed or virtual environment not activated.
**Solution**:
```bash
# Activate virtual environment
source venv/bin/activate # Linux/Mac
.\venv\Scripts\Activate.ps1 # Windows
# Install dependencies
pip install -r requirements.txt
```
### Error: "KeyError: 'WORDPRESS_SITE1_URL'"
**Cause**: Environment variables not configured.
**Solution**:
```bash
# Check if .env file exists
ls -la .env
# If not, create from template
cp .env.example .env
# Edit with your credentials
nano .env # Linux/Mac
notepad .env # Windows
```
### Error: "ModuleNotFoundError: No module named 'core'"
**Cause**: Running from wrong directory or Python path issue.
**Solution**:
```bash
# Make sure you're in project root
cd /path/to/mcphub
# Run the server directly
python server.py
# Or add to .env
echo "PYTHONPATH=." >> .env
```
---
## Connection Issues
### WordPress Site Not Accessible
**Symptoms**: `Connection timeout`, `Connection refused`, `Name or service not known`
**Diagnosis**:
```bash
# Test site accessibility
curl -I https://your-wordpress-site.com
# Check DNS resolution
nslocalhost your-wordpress-site.com
# Test with timeout
timeout 5 curl https://your-wordpress-site.com
```
**Solutions**:
1. **Check URL format**:
```bash
# Correct
WORDPRESS_SITE1_URL=https://example.com
# Incorrect
WORDPRESS_SITE1_URL=example.com # Missing https://
WORDPRESS_SITE1_URL=https://example.com/ # Extra trailing slash
```
2. **Verify HTTPS certificate**:
```bash
curl -v https://your-site.com 2>&1 | grep SSL
```
3. **Check firewall rules**:
- Ensure port 443 (HTTPS) is open
- Check if IP is whitelisted (if using server firewall)
4. **Test from different network**:
- Try from different IP address
- Check if WordPress site blocks data center IPs
### WordPress REST API Not Available
**Symptoms**: `404 Not Found` on `/wp-json/`
**Diagnosis**:
```bash
curl https://your-site.com/wp-json/
```
**Solutions**:
1. **Check permalink settings**:
- Go to: WordPress Admin → Settings → Permalinks
- Select any option except "Plain"
- Click "Save Changes"
2. **Check .htaccess**:
```apache
# Must have these rules
RewriteEngine On
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
```
3. **Check nginx configuration** (if using nginx):
```nginx
location / {
try_files $uri $uri/ /index.php?$args;
}
```
---
## Authentication Problems
### Error: "Invalid username or password"
**Cause**: Application Password not configured correctly.
**Solution**:
1. **Verify Application Password is enabled**:
- WordPress 5.6+ only
- Go to: Users → Your Profile
- Look for "Application Passwords" section
2. **Generate new Application Password**:
```
Name: MCP Server
Click: Add New Application Password
Copy password (format: xxxx xxxx xxxx xxxx xxxx xxxx)
```
3. **Update .env file**:
```bash
WORDPRESS_SITE1_APP_PASSWORD=xxxx xxxx xxxx xxxx xxxx xxxx
```
4. **Important notes**:
- Include spaces in password
- Password is one-time display only
- Each application needs unique password
### Error: "Application Passwords not available"
**Cause**: WordPress version < 5.6 or disabled by plugin/filter.
**Solutions**:
1. **Update WordPress**:
```bash
# Via WP-CLI
wp core update
```
2. **Check if disabled by plugin/filter**:
- Some security plugins disable Application Passwords
- Check: Security Plugins → Settings → Application Passwords
3. **Enable via code** (add to `functions.php`):
```php
// Remove filter that may disable it
add_filter('wp_is_application_passwords_available', '__return_true');
```
### WooCommerce Authentication Failed
**Cause**: Invalid Consumer Key/Secret.
**Solution**:
1. **Regenerate API keys**:
- WooCommerce → Settings → Advanced → REST API
- Add Key
- Permissions: Read/Write
- Copy both Consumer Key and Consumer Secret
2. **Verify format in .env**:
```bash
WORDPRESS_SITE1_WC_CONSUMER_KEY=ck_xxxxxxxxxxxxxxxxxxxx
WORDPRESS_SITE1_WC_CONSUMER_SECRET=cs_xxxxxxxxxxxxxxxxxxxx
```
3. **Check permissions**:
- User must have `manage_woocommerce` capability
- Keys must be for admin user
---
## Rate Limiting Issues
### Error: "Rate limit exceeded"
**Symptoms**: HTTP 429, "Too many requests"
**Diagnosis**:
```bash
# Check rate limit stats
python -c "
from src.core.rate_limiter import RateLimiter
limiter = RateLimiter()
print(limiter.get_stats())
"
```
**Solutions**:
1. **Adjust rate limits** in `.env`:
```bash
RATE_LIMIT_PER_MINUTE=120 # Increase from 60
RATE_LIMIT_PER_HOUR=2000 # Increase from 1000
RATE_LIMIT_PER_DAY=20000 # Increase from 10000
```
2. **Reset rate limiter**:
```bash
# Via MCP tool
reset_rate_limit()
# Or restart server
docker compose restart # If using Docker
```
3. **Distribute requests**:
- Add delays between bulk operations
- Use batching for large operations
### Rate Limit Not Working
**Symptoms**: No rate limiting being applied.
**Solution**:
Check rate limiter initialization in logs:
```bash
grep "Rate limiter" logs/audit.log
```
Ensure rate limiter is enabled:
```python
# In .env
RATE_LIMITING_ENABLED=true
```
---
## Docker Problems
### Container Won't Start
**Symptoms**: `docker compose up` fails, container exits immediately.
**Diagnosis**:
```bash
# Check container logs
docker compose logs
# Check container exit code
docker compose ps -a
```
**Common Solutions**:
1. **Port already in use**:
```bash
# Check what's using port 8000
lsof -i :8000 # Linux/Mac
netstat -ano | findstr :8000 # Windows
# Change port in docker-compose.yml
ports:
- "8080:8000" # Use 8080 instead
```
2. **Invalid environment variables**:
```bash
# Validate .env file
docker compose config
```
3. **Permission issues**:
```bash
# Fix permissions
sudo chown -R 1000:1000 logs/
```
### Container Running but Not Accessible
**Symptoms**: Container status shows "Up" but health check fails.
**Diagnosis**:
```bash
# Check container health
docker compose ps
# Test from inside container
docker compose exec mcp-server curl localhost:8000/health
# Check container network
docker compose exec mcp-server cat /etc/hosts
```
**Solutions**:
1. **Check binding address**:
- Should bind to `0.0.0.0`, not `127.0.0.1`
- Update `server.py` if needed
2. **Check firewall**:
```bash
# Allow Docker network
sudo ufw allow from 172.0.0.0/8
```
### High Memory Usage
**Symptoms**: Container using excessive RAM.
**Solutions**:
1. **Set memory limits** in `docker-compose.yml`:
```yaml
services:
mcp-server:
deploy:
resources:
limits:
memory: 512M
```
2. **Optimize logging**:
```bash
# Reduce log level
LOG_LEVEL=WARNING
```
3. **Clear cache**:
```bash
docker system prune -a
```
---
## Performance Issues
### Slow Response Times
**Symptoms**: Tools taking > 5 seconds to respond.
**Diagnosis**:
```bash
# Check health metrics
python -c "
from core.health import HealthMonitor
monitor = HealthMonitor()
print(monitor.get_all_health())
"
```
**Solutions**:
1. **Check WordPress site performance**:
```bash
# Test direct WordPress API
time curl https://your-site.com/wp-json/wp/v2/posts
```
2. **Enable caching** on WordPress:
- Install caching plugin (WP Super Cache, W3 Total Cache)
- Enable object caching (Redis/Memcached)
3. **Optimize database**:
```bash
# Use WP-CLI tool
wordpress_wp_db_optimize(site="site1")
```
4. **Reduce payload size**:
```python
# Request fewer items
wordpress_list_posts(site="site1", per_page=10) # Instead of 100
```
### High CPU Usage
**Symptoms**: Server using 100% CPU.
**Solutions**:
1. **Check for infinite loops** in logs:
```bash
tail -f logs/audit.log | grep ERROR
```
2. **Limit concurrent requests**:
```bash
# In .env
MAX_CONCURRENT_REQUESTS=5
```
3. **Optimize queries**:
- Use pagination
- Filter results
- Cache responses
---
## Tool Registration Issues
### Error: "Tool not found"
**Symptoms**: MCP reports tool doesn't exist.
**Diagnosis**:
```bash
# List all registered tools
python -c "
from server import mcp
tools = app.list_tools()
for tool in tools:
print(tool['name'])
"
```
**Solutions**:
1. **Check site configuration**:
```bash
# Ensure site is configured in .env
grep "WORDPRESS_SITE1" .env
```
2. **Verify plugin loaded**:
```bash
# Check logs for plugin initialization
grep "plugin loaded" logs/audit.log
```
3. **Restart server**:
```bash
# Tools are registered at startup
docker compose restart
```
### Duplicate Tools
**Symptoms**: Same tool name registered multiple times.
**Cause**: Multiple plugins or sites with same alias.
**Solution**:
1. **Check for duplicate aliases**:
```bash
grep "ALIAS" .env | sort
```
2. **Ensure unique aliases**:
```bash
WORDPRESS_SITE1_ALIAS=mainsite
WORDPRESS_SITE2_ALIAS=shop # Not mainsite
```
---
## Logging and Debugging
### Enable Debug Logging
```bash
# In .env
LOG_LEVEL=DEBUG
# Restart server
docker compose restart
```
### View Real-time Logs
```bash
# Audit logs
tail -f logs/audit.log
# Application logs
docker compose logs -f
# Filter for errors
grep ERROR logs/audit.log
# Filter for specific site
grep "site1" logs/audit.log
```
### Common Log Patterns
**Successful request**:
```json
{
"timestamp": "2025-11-11T10:30:00Z",
"event_type": "tool_execution",
"level": "INFO",
"event": "wordpress_list_posts",
"details": {
"site": "site1",
"status": "success"
}
}
```
**Failed request**:
```json
{
"timestamp": "2025-11-11T10:30:00Z",
"event_type": "tool_execution",
"level": "ERROR",
"event": "wordpress_list_posts",
"details": {
"site": "site1",
"error": "Connection timeout",
"status": "failed"
}
}
```
### Debugging Tips
1. **Test with curl**:
```bash
# Test WordPress directly
curl -u "admin:xxxx xxxx xxxx xxxx xxxx xxxx" \
https://your-site.com/wp-json/wp/v2/posts
```
2. **Check environment loading**:
```python
python -c "
from dotenv import load_dotenv
import os
load_dotenv()
print(os.getenv('WORDPRESS_SITE1_URL'))
"
```
3. **Test individual components**:
```bash
# Test WordPress plugin
pytest tests/test_wordpress_plugin.py -v
# Test rate limiter
pytest tests/test_rate_limiter.py -v
```
---
## Getting Help
### Before Asking for Help
1. **Check logs**:
```bash
tail -50 logs/audit.log
```
2. **Run health check**:
```bash
python -c "
from core.health import HealthMonitor
monitor = HealthMonitor()
print(monitor.check_all_projects())
"
```
3. **Verify configuration**:
```bash
# Mask sensitive data
grep -v "PASSWORD\|KEY\|SECRET" .env
```
4. **Test connectivity**:
```bash
curl -I https://your-wordpress-site.com
```
### What to Include in Bug Reports
1. **Environment information**:
- Python version: `python --version`
- Docker version: `docker --version`
- OS: `uname -a` (Linux/Mac) or `systeminfo` (Windows)
2. **Error messages**:
- Full error output
- Stack trace if available
- Relevant log entries
3. **Configuration** (mask sensitive data):
- Relevant .env variables
- docker-compose.yml modifications
- WordPress/WooCommerce versions
4. **Steps to reproduce**:
- Exact commands run
- Expected vs actual behavior
- Frequency (always, sometimes, once)
### Contact Information
**Email**: hello@mcphub.dev
**Subject format**: `[BUG] Brief description`
**Example**:
```
Subject: [BUG] wordpress_list_posts returns 403 error
Environment:
- Python 3.11.5
- Docker 24.0.6
- WordPress 6.4
- Ubuntu 22.04
Issue:
wordpress_list_posts(site="site1") returns 403 Forbidden
Steps to reproduce:
1. Configure WORDPRESS_SITE1_* in .env
2. Run python server.py
3. Call wordpress_list_posts(site="site1", per_page=10)
4. Receive 403 error
Logs:
[Include relevant log entries]
Configuration:
WORDPRESS_SITE1_URL=https://example.com
WORDPRESS_SITE1_USERNAME=admin
[Application password masked]
```
---
---