feat: v3.1.0 — Live Platform Foundation (Track E.1-E.3)
Major release introducing the Live Platform architecture:
- SQLite database backend with async operations and migrations (E.1)
- AES-256-GCM credential encryption with HKDF key derivation (E.1)
- OAuth Social Login with GitHub and Google (E.2)
- Site management API with encrypted credential storage (E.3)
- Per-user MCP endpoints at /u/{user_id}/{alias}/mcp (E.3)
- User API keys with bcrypt hashing (E.3)
- Auto-generated config snippets for 5 MCP clients (E.3)
- Dashboard: dark/light mode, RBAC, My Sites, Connect page
- Active background health checks
- 452 tests (up from 303), all passing
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
115
core/config_snippets.py
Normal file
115
core/config_snippets.py
Normal file
@@ -0,0 +1,115 @@
|
||||
"""MCP client configuration snippet generation (Track E.3).
|
||||
|
||||
Generates copy-paste configuration snippets for connecting AI clients
|
||||
(Claude Desktop, Claude Code, Cursor, VS Code, ChatGPT) to per-user
|
||||
MCP endpoints.
|
||||
|
||||
Usage:
|
||||
from core.config_snippets import generate_config, get_supported_clients
|
||||
|
||||
snippet = generate_config(
|
||||
base_url="https://mcp.example.com",
|
||||
user_id="abc123",
|
||||
alias="myblog",
|
||||
api_key="mhu_...",
|
||||
client_type="claude_desktop",
|
||||
)
|
||||
"""
|
||||
|
||||
import json
|
||||
|
||||
# Supported MCP client types
|
||||
SUPPORTED_CLIENTS = [
|
||||
{
|
||||
"id": "claude_desktop",
|
||||
"label": "Claude Desktop",
|
||||
"description": "Anthropic's desktop app for Claude",
|
||||
},
|
||||
{
|
||||
"id": "claude_code",
|
||||
"label": "Claude Code",
|
||||
"description": "Anthropic's CLI for Claude",
|
||||
},
|
||||
{
|
||||
"id": "cursor",
|
||||
"label": "Cursor",
|
||||
"description": "AI-first code editor",
|
||||
},
|
||||
{
|
||||
"id": "vscode",
|
||||
"label": "VS Code",
|
||||
"description": "Visual Studio Code with MCP extension",
|
||||
},
|
||||
{
|
||||
"id": "chatgpt",
|
||||
"label": "ChatGPT",
|
||||
"description": "OpenAI ChatGPT (URL-based)",
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
def get_supported_clients() -> list[dict[str, str]]:
|
||||
"""Return the list of supported MCP client types."""
|
||||
return SUPPORTED_CLIENTS
|
||||
|
||||
|
||||
def generate_config(
|
||||
base_url: str,
|
||||
user_id: str,
|
||||
alias: str,
|
||||
api_key: str,
|
||||
client_type: str,
|
||||
) -> str:
|
||||
"""Generate a configuration snippet for the given MCP client.
|
||||
|
||||
Args:
|
||||
base_url: Public URL of the MCP Hub instance (no trailing slash).
|
||||
user_id: User UUID.
|
||||
alias: Site alias.
|
||||
api_key: User API key (``mhu_...``).
|
||||
client_type: One of the supported client type IDs.
|
||||
|
||||
Returns:
|
||||
JSON configuration string ready for copy-paste.
|
||||
|
||||
Raises:
|
||||
ValueError: If client_type is not supported.
|
||||
"""
|
||||
base_url = base_url.rstrip("/")
|
||||
endpoint_url = f"{base_url}/u/{user_id}/{alias}/mcp"
|
||||
server_name = f"mcphub-{alias}"
|
||||
|
||||
if client_type in ("claude_desktop", "claude_code"):
|
||||
config = {
|
||||
"mcpServers": {
|
||||
server_name: {
|
||||
"url": endpoint_url,
|
||||
"headers": {
|
||||
"Authorization": f"Bearer {api_key}",
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
return json.dumps(config, indent=2)
|
||||
|
||||
elif client_type in ("cursor", "vscode"):
|
||||
config = {
|
||||
"mcp": {
|
||||
"servers": {
|
||||
server_name: {
|
||||
"url": endpoint_url,
|
||||
"headers": {
|
||||
"Authorization": f"Bearer {api_key}",
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return json.dumps(config, indent=2)
|
||||
|
||||
elif client_type == "chatgpt":
|
||||
return endpoint_url
|
||||
|
||||
else:
|
||||
valid = [c["id"] for c in SUPPORTED_CLIENTS]
|
||||
raise ValueError(f"Unsupported client type '{client_type}'. Valid: {valid}")
|
||||
Reference in New Issue
Block a user