From fd78e7b17bdf27a0299ddd8fd349a29868f4e6b5 Mon Sep 17 00:00:00 2001 From: zgaetano Date: Tue, 31 Mar 2026 15:32:59 -0400 Subject: [PATCH] Remove mcp-gateway/OPENUI_OAUTH_FIX.md --- mcp-gateway/OPENUI_OAUTH_FIX.md | 218 -------------------------------- 1 file changed, 218 deletions(-) delete mode 100644 mcp-gateway/OPENUI_OAUTH_FIX.md diff --git a/mcp-gateway/OPENUI_OAUTH_FIX.md b/mcp-gateway/OPENUI_OAUTH_FIX.md deleted file mode 100644 index a175cfa..0000000 --- a/mcp-gateway/OPENUI_OAUTH_FIX.md +++ /dev/null @@ -1,218 +0,0 @@ -# OpenUI OAuth "Client not registered" Fix - -## Problem - -When connecting MCP Gateway to Open-UI, you get: -``` -{"error":"invalid_client","error_description":"Client not registered."} -``` - -Even though it works fine in Claude.ai. - -## Root Cause - -Your gateway uses **in-memory OAuth client registration** (`REGISTERED_CLIENTS` dict). This means: - -1. Each client (Claude.ai, Open-UI, etc.) registers itself via `/oauth/register` -2. The registration is stored in RAM only -3. When the gateway restarts → all registrations are lost -4. Open-UI's client ID is no longer recognized during token exchange - -Additionally, there are **two separate OAuth flows** happening: -- Claude.ai uses one client ID -- Open-UI registers and gets a different client ID -- If the gateway restarts between registration and first use, Open-UI's ID is gone - -## Solution Options - -### Option A: Persistent OAuth Client Storage (Recommended) -Store OAuth clients in a file or database instead of RAM. - -**File**: `gateway-proxy/oauth_storage.py` (to be created) - -```python -import json -import os -from typing import dict - -OAUTH_STORAGE_FILE = os.environ.get("OAUTH_STORAGE_FILE", "/data/oauth_clients.json") - -def load_oauth_clients() -> dict: - """Load OAuth clients from persistent storage""" - if os.path.exists(OAUTH_STORAGE_FILE): - try: - with open(OAUTH_STORAGE_FILE, 'r') as f: - return json.load(f) - except Exception as e: - logger.error(f"Failed to load OAuth clients: {e}") - return {} - return {} - -def save_oauth_clients(clients: dict) -> None: - """Save OAuth clients to persistent storage""" - try: - os.makedirs(os.path.dirname(OAUTH_STORAGE_FILE), exist_ok=True) - with open(OAUTH_STORAGE_FILE, 'w') as f: - json.dump(clients, f, indent=2) - except Exception as e: - logger.error(f"Failed to save OAuth clients: {e}") - -def register_client(client_info: dict) -> None: - """Register a new OAuth client""" - clients = load_oauth_clients() - client_id = client_info["client_id"] - clients[client_id] = client_info - save_oauth_clients(clients) -``` - -**Changes to gateway_proxy.py:** -```python -# At startup, replace: -# REGISTERED_CLIENTS: dict[str, dict] = {} -# with: -from .oauth_storage import load_oauth_clients, save_oauth_clients -REGISTERED_CLIENTS = load_oauth_clients() - -# In oauth_register function, after adding client: -REGISTERED_CLIENTS[client_id] = client_info -save_oauth_clients(REGISTERED_CLIENTS) # Add this line -``` - -**docker-compose.yml update:** -```yaml -gateway-proxy: - volumes: - - gateway-data:/data # Persist OAuth clients -``` - -### Option B: Pre-register Known Clients (Quick Fix) -Hardcode known clients (Claude.ai, Open-UI) so they don't need dynamic registration. - -**In .env:** -```bash -# Pre-registered OAuth clients (JSON format) -OAUTH_CLIENTS='{"claude-app":{"client_id":"claude-app","client_secret":"YOUR_SECRET","client_name":"Claude.ai"},"openui":{"client_id":"openui","client_secret":"YOUR_SECRET","client_name":"Open-UI"}}' -``` - -**In gateway_proxy.py:** -```python -import json - -def load_oauth_clients() -> dict: - """Load pre-registered clients from env""" - clients_json = os.environ.get("OAUTH_CLIENTS", "{}") - try: - return json.loads(clients_json) - except: - return {} - -REGISTERED_CLIENTS = load_oauth_clients() -``` - -### Option C: Disable Client Validation (Development Only) -For testing, skip client ID validation in token endpoint: - -**In oauth_token function, around line 520:** -```python -# Change this check: -client_info = REGISTERED_CLIENTS.get(client_id) -if not client_info: - return JSONResponse({"error": "invalid_client"}, status_code=400) - -# To this (development only): -client_info = REGISTERED_CLIENTS.get(client_id) -if not client_info: - logger.warning(f"Client {client_id} not registered, allowing anyway (DEV MODE)") - # Allow unregistered clients for testing -``` - -## Recommended Implementation - -**Use Option A** (persistent storage) because: -- ✅ Works across gateway restarts -- ✅ Supports multiple clients (Claude.ai, Open-UI, others) -- ✅ Secure (OAuth flow still requires proper credentials) -- ✅ Production-ready -- ✅ No hardcoded secrets - -## Implementation Steps - -### Step 1: Create oauth_storage.py -Save to `gateway-proxy/oauth_storage.py` (content provided above) - -### Step 2: Update gateway_proxy.py - -Around line 27 (imports), add: -```python -from .oauth_storage import load_oauth_clients, save_oauth_clients -``` - -Around line 52, replace: -```python -# REGISTERED_CLIENTS: dict[str, dict] = {} -REGISTERED_CLIENTS = load_oauth_clients() -``` - -In `oauth_register()` function, after line 383: -```python -REGISTERED_CLIENTS[client_id] = client_info -save_oauth_clients(REGISTERED_CLIENTS) # ADD THIS LINE -``` - -### Step 3: Update docker-compose.yml - -Add volume to gateway-proxy service: -```yaml -gateway-proxy: - volumes: - - gateway-data:/data - -volumes: - gateway-data: -``` - -### Step 4: Set environment variable (optional) -In `.env`: -```bash -OAUTH_STORAGE_FILE=/data/oauth_clients.json -``` - -### Step 5: Restart -```bash -docker-compose down -docker-compose up -d -``` - -## Testing - -1. Register with Open-UI (should succeed) -2. Restart gateway: `docker-compose restart gateway-proxy` -3. Try to use Open-UI again (should work - client is persisted) -4. Check `/data/oauth_clients.json` file exists with registration - -## Debugging - -Check if clients are saved: -```bash -docker exec mcp-gateway cat /data/oauth_clients.json | jq '.' -``` - -Check gateway logs for registration: -```bash -docker logs mcp-gateway | grep "DCR:" -``` - -If you still get "Client not registered": -1. Verify oauth_storage.py is in gateway-proxy/ -2. Check that save_oauth_clients() is being called -3. Check file permissions on /data/ volume -4. Check docker logs for save errors - -## Alternative: Use Redis or Database - -For production with multiple gateway instances, consider storing OAuth clients in: -- Redis (fast, distributed) -- PostgreSQL (persistent, queryable) -- MongoDB (flexible schema) - -This ensures clients are available across all instances.