fix(ux): improve new user onboarding experience
- Show full temporary API key in logs (not masked) so users can log in - Redirect root URL / to /dashboard (was 404) - Add setup guidance and docs link to login page - Make footer version dynamic (read from pyproject.toml) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -27,11 +27,14 @@ class AuthManager:
|
||||
if not self.master_api_key:
|
||||
# Generate a random key if not provided (dev mode)
|
||||
self.master_api_key = secrets.token_urlsafe(32)
|
||||
self._is_temporary_key = True
|
||||
logger.warning(
|
||||
"No MASTER_API_KEY environment variable found. "
|
||||
f"Generated temporary key: {self.master_api_key[:8]}***{self.master_api_key[-4:]} "
|
||||
f"Generated temporary key: {self.master_api_key} "
|
||||
"(set MASTER_API_KEY in .env for production use)"
|
||||
)
|
||||
else:
|
||||
self._is_temporary_key = False
|
||||
|
||||
# Project-specific keys (future feature)
|
||||
self.project_keys = {}
|
||||
|
||||
@@ -334,6 +334,7 @@ async def dashboard_login_page(request: Request) -> Response:
|
||||
"t": t,
|
||||
"error": error,
|
||||
"next_url": next_url,
|
||||
"version": _get_project_version(),
|
||||
},
|
||||
)
|
||||
|
||||
@@ -1984,6 +1985,19 @@ def get_registered_plugins() -> list:
|
||||
return plugins
|
||||
|
||||
|
||||
def _get_project_version() -> str:
|
||||
"""Read version from pyproject.toml."""
|
||||
try:
|
||||
toml_path = os.path.join(os.path.dirname(os.path.dirname(TEMPLATES_DIR)), "pyproject.toml")
|
||||
with open(toml_path) as f:
|
||||
for line in f:
|
||||
if line.strip().startswith("version"):
|
||||
return line.split("=")[1].strip().strip('"').strip("'")
|
||||
except Exception:
|
||||
pass
|
||||
return "3.0.0"
|
||||
|
||||
|
||||
def get_about_info() -> dict:
|
||||
"""Get about information."""
|
||||
import sys
|
||||
@@ -1998,7 +2012,7 @@ def get_about_info() -> dict:
|
||||
pass
|
||||
|
||||
return {
|
||||
"version": "1.0.0",
|
||||
"version": _get_project_version(),
|
||||
"mcp_version": "2024-11-05",
|
||||
"python_version": f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}",
|
||||
"tools_count": tools_count,
|
||||
|
||||
@@ -108,15 +108,22 @@
|
||||
<svg class="w-5 h-5 text-blue-400 {% if lang == 'fa' %}ml-2{% else %}mr-2{% endif %} mt-0.5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
|
||||
</svg>
|
||||
<p class="text-sm text-blue-300">
|
||||
<div class="text-sm text-blue-300">
|
||||
{% if lang == 'fa' %}
|
||||
برای دسترسی به داشبورد به Master API Key یا یک API Key با scope=admin نیاز دارید.
|
||||
<p>برای دسترسی به داشبورد به Master API Key نیاز دارید.</p>
|
||||
<p class="mt-2 text-blue-400">کلید API خود را در متغیر محیطی <code class="bg-gray-700 px-1 rounded">MASTER_API_KEY</code> تنظیم کنید.</p>
|
||||
{% else %}
|
||||
You need a Master API Key or an API Key with scope=admin to access the dashboard.
|
||||
<p>Enter your <code class="bg-gray-700 px-1 rounded">MASTER_API_KEY</code> to access the dashboard.</p>
|
||||
<p class="mt-2 text-blue-400">Don't have one? Set it in your <code class="bg-gray-700 px-1 rounded">.env</code> file, or check the server logs for the temporary key.</p>
|
||||
{% endif %}
|
||||
<p class="mt-2">
|
||||
<a href="https://github.com/airano-ir/mcphub#quick-start" target="_blank" class="text-purple-400 hover:text-purple-300 underline">
|
||||
{% if lang == 'fa' %}راهنمای شروع{% else %}Setup Guide{% endif %}
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Language Toggle -->
|
||||
<div class="mt-6 text-center">
|
||||
@@ -131,7 +138,7 @@
|
||||
|
||||
<!-- Footer -->
|
||||
<p class="text-center text-gray-500 text-sm mt-6">
|
||||
MCP Hub v3.0.0
|
||||
MCP Hub v{{ version|default('3.0.0') }}
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
11
server.py
11
server.py
@@ -274,6 +274,9 @@ logger.info("=" * 60)
|
||||
logger.info("MCP Hub Server - Initialized")
|
||||
logger.info("=" * 60)
|
||||
_mk = auth_manager.get_master_key()
|
||||
if auth_manager._is_temporary_key:
|
||||
logger.info(f"Master API Key (temporary): {_mk}")
|
||||
else:
|
||||
logger.info(f"Master API Key: {_mk[:8]}***{_mk[-4:]}")
|
||||
logger.info(f"Discovered {len(project_manager.projects)} per-site project instances (legacy)")
|
||||
logger.info(
|
||||
@@ -4182,12 +4185,18 @@ def create_multi_endpoint_app(transport: str = "streamable-http"):
|
||||
except Exception as e:
|
||||
logger.warning(f"Error during lifespan cleanup for {name}: {e}")
|
||||
|
||||
# Root redirect: / → /dashboard (so users don't see 404)
|
||||
async def root_redirect(request):
|
||||
return RedirectResponse(url="/dashboard", status_code=302)
|
||||
|
||||
# Build routes
|
||||
# Note: Order matters! More specific routes first
|
||||
routes = [
|
||||
# Health check
|
||||
Route("/health", health_check, methods=["GET"]),
|
||||
# Dashboard routes (Phase K.1)
|
||||
# Root redirect
|
||||
Route("/", root_redirect, methods=["GET"]),
|
||||
# Dashboard routes
|
||||
Route("/dashboard/login", dashboard_login_page, methods=["GET"]),
|
||||
Route("/dashboard/login", dashboard_login_submit, methods=["POST"]),
|
||||
Route("/dashboard/logout", dashboard_logout, methods=["GET", "POST"]),
|
||||
|
||||
Reference in New Issue
Block a user