mirror of
https://github.com/samanhappy/mcphub.git
synced 2025-12-24 02:39:19 -05:00
fix: standardize naming to MCPHub across documentation and UI (#271)
Co-authored-by: samanhappy@qq.com <my6051199> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -48,11 +48,11 @@ MCPHub 已内置多个常用 MCP 服务,如高德地图、GitHub、Slack、Fet
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
点击保存后,MCP Hub 将自动重启高德地图的 MCP 服务,使新配置生效。
|
点击保存后,MCPHub 将自动重启高德地图的 MCP 服务,使新配置生效。
|
||||||
|
|
||||||
### 配置 MCP Hub SSE
|
### 配置 MCPHub SSE
|
||||||
|
|
||||||
MCP Hub 提供了单一聚合的 MCP Server SSE 端点:`http://localhost:3000/sse`,可在任意支持 MCP 的客户端中配置使用。这里我们选择开源的 Cherry Studio 进行演示。
|
MCPHub 提供了单一聚合的 MCP Server SSE 端点:`http://localhost:3000/sse`,可在任意支持 MCP 的客户端中配置使用。这里我们选择开源的 Cherry Studio 进行演示。
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>MCP Hub Dashboard</title>
|
<title>MCPHub Dashboard</title>
|
||||||
<link rel="icon" type="image/x-icon" href="/favicon.ico">
|
<link rel="icon" type="image/x-icon" href="/favicon.ico">
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
|||||||
@@ -41,67 +41,119 @@ const LoginPage: React.FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen flex items-center justify-center bg-gray-50 dark:bg-gray-900 py-12 px-4 sm:px-6 lg:px-8 login-container">
|
<div className="relative min-h-screen w-full overflow-hidden bg-gray-50 dark:bg-gray-950">
|
||||||
<div className="absolute top-4 right-4 w-full max-w-xs flex justify-end">
|
{/* Top-right controls */}
|
||||||
|
<div className="absolute top-4 right-4 z-20 flex items-center gap-2">
|
||||||
<ThemeSwitch />
|
<ThemeSwitch />
|
||||||
<LanguageSwitch />
|
<LanguageSwitch />
|
||||||
</div>
|
</div>
|
||||||
<div className="max-w-md w-full space-y-8 login-card p-8">
|
|
||||||
<div>
|
{/* Tech background layer */}
|
||||||
<h2 className="mt-6 text-center text-3xl font-extrabold text-gray-900 dark:text-white">
|
<div
|
||||||
{t('auth.loginTitle')}
|
className="pointer-events-none absolute inset-0 -z-10 opacity-60 dark:opacity-70"
|
||||||
</h2>
|
style={{
|
||||||
|
backgroundImage:
|
||||||
|
'radial-gradient(60rem 60rem at 20% -10%, rgba(99,102,241,0.25), transparent), radial-gradient(50rem 50rem at 120% 10%, rgba(168,85,247,0.15), transparent)',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<div className="pointer-events-none absolute inset-0 -z-10">
|
||||||
|
<svg className="h-full w-full opacity-[0.08] dark:opacity-[0.12]" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<defs>
|
||||||
|
<pattern id="grid" width="32" height="32" patternUnits="userSpaceOnUse">
|
||||||
|
<path d="M 32 0 L 0 0 0 32" fill="none" stroke="currentColor" strokeWidth="0.5" />
|
||||||
|
</pattern>
|
||||||
|
</defs>
|
||||||
|
<rect width="100%" height="100%" fill="url(#grid)" className="text-gray-400 dark:text-gray-300" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Main content */}
|
||||||
|
<div className="relative mx-auto grid min-h-screen w-full max-w-7xl grid-cols-1 items-center gap-8 px-6 py-16 md:grid-cols-2 lg:gap-16">
|
||||||
|
{/* Left: brand + slogan */}
|
||||||
|
<div className="order-2 space-y-6 md:order-1">
|
||||||
|
<div className="inline-flex items-center gap-2 rounded-full border border-indigo-500/20 bg-indigo-500/10 px-3 py-1 text-xs font-medium text-indigo-700 shadow-sm backdrop-blur dark:text-indigo-300">
|
||||||
|
<span className="h-2 w-2 animate-pulse rounded-full bg-indigo-500" />
|
||||||
|
{t('app.name')}
|
||||||
|
</div>
|
||||||
|
<h1 className="text-4xl font-extrabold leading-tight tracking-tight text-gray-900 dark:text-white sm:text-5xl">
|
||||||
|
<span className="bg-gradient-to-r from-indigo-400 via-cyan-400 to-emerald-400 bg-clip-text text-transparent">
|
||||||
|
{t('auth.slogan')}
|
||||||
|
</span>
|
||||||
|
</h1>
|
||||||
|
<p className="max-w-xl text-base text-gray-600 dark:text-gray-300">
|
||||||
|
{t('auth.subtitle')}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div className="flex flex-wrap gap-3 pt-2 text-xs text-gray-500 dark:text-gray-400">
|
||||||
|
<span className="rounded-md border border-white/10 bg-white/5 px-2 py-1 backdrop-blur">MCP</span>
|
||||||
|
<span className="rounded-md border border-white/10 bg-white/5 px-2 py-1 backdrop-blur">Group</span>
|
||||||
|
<span className="rounded-md border border-white/10 bg-white/5 px-2 py-1 backdrop-blur">Market</span>
|
||||||
|
<span className="rounded-md border border-white/10 bg-white/5 px-2 py-1 backdrop-blur">Logging</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<form className="mt-8 space-y-6" onSubmit={handleSubmit}>
|
|
||||||
<div className="space-y-4">
|
|
||||||
<div>
|
|
||||||
<label htmlFor="username" className="sr-only">
|
|
||||||
{t('auth.username')}
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
id="username"
|
|
||||||
name="username"
|
|
||||||
type="text"
|
|
||||||
autoComplete="username"
|
|
||||||
required
|
|
||||||
className="appearance-none relative block w-full px-3 py-3 border border-gray-300 dark:border-gray-600 placeholder-gray-500 dark:placeholder-gray-400 text-gray-900 dark:text-white dark:bg-gray-800 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 focus:z-10 sm:text-sm transition-all duration-200 form-input shadow-sm"
|
|
||||||
placeholder={t('auth.username')}
|
|
||||||
value={username}
|
|
||||||
onChange={(e) => setUsername(e.target.value)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label htmlFor="password" className="sr-only">
|
|
||||||
{t('auth.password')}
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
id="password"
|
|
||||||
name="password"
|
|
||||||
type="password"
|
|
||||||
autoComplete="current-password"
|
|
||||||
required
|
|
||||||
className="appearance-none relative block w-full px-3 py-3 border border-gray-300 dark:border-gray-600 placeholder-gray-500 dark:placeholder-gray-400 text-gray-900 dark:text-white dark:bg-gray-800 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 focus:z-10 sm:text-sm login-input transition-all duration-200 form-input shadow-sm"
|
|
||||||
placeholder={t('auth.password')}
|
|
||||||
value={password}
|
|
||||||
onChange={(e) => setPassword(e.target.value)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{error && (
|
{/* Right: login card */}
|
||||||
<div className="text-red-500 dark:text-red-400 text-sm text-center error-box p-2 rounded">{error}</div>
|
<div className="order-1 md:order-2">
|
||||||
)}
|
<div className="login-card relative w-full max-w-md rounded-2xl border border-white/10 bg-white/60 p-8 shadow-xl backdrop-blur-md transition dark:border-white/10 dark:bg-gray-900/60">
|
||||||
|
<div className="absolute -top-24 right-12 h-40 w-40 -translate-y-6 rounded-full bg-indigo-500/30 blur-3xl" />
|
||||||
|
<div className="absolute -bottom-24 -left-12 h-40 w-40 translate-y-6 rounded-full bg-cyan-500/20 blur-3xl" />
|
||||||
|
<h2 className="text-center text-2xl font-bold text-gray-900 dark:text-white">
|
||||||
|
{t('auth.loginTitle')}
|
||||||
|
</h2>
|
||||||
|
<form className="mt-8 space-y-6" onSubmit={handleSubmit}>
|
||||||
|
<div className="space-y-4">
|
||||||
|
<div>
|
||||||
|
<label htmlFor="username" className="sr-only">
|
||||||
|
{t('auth.username')}
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
id="username"
|
||||||
|
name="username"
|
||||||
|
type="text"
|
||||||
|
autoComplete="username"
|
||||||
|
required
|
||||||
|
className="login-input appearance-none relative block w-full rounded-md border border-gray-300/60 bg-white/70 px-3 py-3 text-gray-900 shadow-sm outline-none ring-0 transition-all placeholder:text-gray-500 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-500 dark:border-gray-700/60 dark:bg-gray-800/70 dark:text-white dark:placeholder:text-gray-400"
|
||||||
|
placeholder={t('auth.username')}
|
||||||
|
value={username}
|
||||||
|
onChange={(e) => setUsername(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label htmlFor="password" className="sr-only">
|
||||||
|
{t('auth.password')}
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
id="password"
|
||||||
|
name="password"
|
||||||
|
type="password"
|
||||||
|
autoComplete="current-password"
|
||||||
|
required
|
||||||
|
className="login-input appearance-none relative block w-full rounded-md border border-gray-300/60 bg-white/70 px-3 py-3 text-gray-900 shadow-sm outline-none ring-0 transition-all placeholder:text-gray-500 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-500 dark:border-gray-700/60 dark:bg-gray-800/70 dark:text-white dark:placeholder:text-gray-400"
|
||||||
|
placeholder={t('auth.password')}
|
||||||
|
value={password}
|
||||||
|
onChange={(e) => setPassword(e.target.value)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div>
|
{error && (
|
||||||
<button
|
<div className="error-box rounded border border-red-500/20 bg-red-500/10 p-2 text-center text-sm text-red-600 dark:text-red-400">
|
||||||
type="submit"
|
{error}
|
||||||
disabled={loading}
|
</div>
|
||||||
className="group relative w-full flex justify-center py-2 px-4 border border-transparent text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 login-button transition-all duration-200 btn-primary"
|
)}
|
||||||
>
|
|
||||||
{loading ? t('auth.loggingIn') : t('auth.login')}
|
<div>
|
||||||
</button>
|
<button
|
||||||
|
type="submit"
|
||||||
|
disabled={loading}
|
||||||
|
className="login-button btn-primary group relative flex w-full items-center justify-center rounded-md border border-transparent bg-indigo-600 px-4 py-2 text-sm font-medium text-white transition-all hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-70"
|
||||||
|
>
|
||||||
|
{loading ? t('auth.loggingIn') : t('auth.login')}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"app": {
|
"app": {
|
||||||
"title": "MCP Hub Dashboard",
|
"title": "MCPHub Dashboard",
|
||||||
"error": "Error",
|
"error": "Error",
|
||||||
"closeButton": "Close",
|
"closeButton": "Close",
|
||||||
"noServers": "No MCP servers available",
|
"noServers": "No MCP servers available",
|
||||||
@@ -10,11 +10,11 @@
|
|||||||
"changePassword": "Change Password",
|
"changePassword": "Change Password",
|
||||||
"toggleSidebar": "Toggle Sidebar",
|
"toggleSidebar": "Toggle Sidebar",
|
||||||
"welcomeUser": "Welcome, {{username}}",
|
"welcomeUser": "Welcome, {{username}}",
|
||||||
"name": "MCP Hub"
|
"name": "MCPHub"
|
||||||
},
|
},
|
||||||
"about": {
|
"about": {
|
||||||
"title": "About",
|
"title": "About",
|
||||||
"versionInfo": "MCP Hub Version: {{version}}",
|
"versionInfo": "MCPHub Version: {{version}}",
|
||||||
"newVersion": "New version available!",
|
"newVersion": "New version available!",
|
||||||
"currentVersion": "Current version",
|
"currentVersion": "Current version",
|
||||||
"newVersionAvailable": "New version {{version}} is available",
|
"newVersionAvailable": "New version {{version}} is available",
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
"label": "Sponsor",
|
"label": "Sponsor",
|
||||||
"title": "Support the Project",
|
"title": "Support the Project",
|
||||||
"rewardAlt": "Reward QR Code",
|
"rewardAlt": "Reward QR Code",
|
||||||
"supportMessage": "Support the development of MCP Hub by buying me a coffee!",
|
"supportMessage": "Support the development of MCPHub by buying me a coffee!",
|
||||||
"supportButton": "Support on Ko-fi"
|
"supportButton": "Support on Ko-fi"
|
||||||
},
|
},
|
||||||
"wechat": {
|
"wechat": {
|
||||||
@@ -52,7 +52,9 @@
|
|||||||
},
|
},
|
||||||
"auth": {
|
"auth": {
|
||||||
"login": "Login",
|
"login": "Login",
|
||||||
"loginTitle": "Login to MCP Hub",
|
"loginTitle": "Login to MCPHub",
|
||||||
|
"slogan": "The Unified Hub for MCP Servers",
|
||||||
|
"subtitle": "Centralized management platform for Model Context Protocol servers. Organize, monitor, and scale multiple MCP servers with flexible routing strategies.",
|
||||||
"username": "Username",
|
"username": "Username",
|
||||||
"password": "Password",
|
"password": "Password",
|
||||||
"loggingIn": "Logging in...",
|
"loggingIn": "Logging in...",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"app": {
|
"app": {
|
||||||
"title": "MCP Hub 控制面板",
|
"title": "MCPHub 控制面板",
|
||||||
"error": "错误",
|
"error": "错误",
|
||||||
"closeButton": "关闭",
|
"closeButton": "关闭",
|
||||||
"noServers": "没有可用的 MCP 服务器",
|
"noServers": "没有可用的 MCP 服务器",
|
||||||
@@ -10,11 +10,11 @@
|
|||||||
"changePassword": "修改密码",
|
"changePassword": "修改密码",
|
||||||
"toggleSidebar": "切换侧边栏",
|
"toggleSidebar": "切换侧边栏",
|
||||||
"welcomeUser": "欢迎, {{username}}",
|
"welcomeUser": "欢迎, {{username}}",
|
||||||
"name": "MCP Hub"
|
"name": "MCPHub"
|
||||||
},
|
},
|
||||||
"about": {
|
"about": {
|
||||||
"title": "关于",
|
"title": "关于",
|
||||||
"versionInfo": "MCP Hub 版本: {{version}}",
|
"versionInfo": "MCPHub 版本: {{version}}",
|
||||||
"newVersion": "有新版本可用!",
|
"newVersion": "有新版本可用!",
|
||||||
"currentVersion": "当前版本",
|
"currentVersion": "当前版本",
|
||||||
"newVersionAvailable": "新版本 {{version}} 已发布",
|
"newVersionAvailable": "新版本 {{version}} 已发布",
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
"label": "赞助",
|
"label": "赞助",
|
||||||
"title": "支持项目",
|
"title": "支持项目",
|
||||||
"rewardAlt": "赞赏码",
|
"rewardAlt": "赞赏码",
|
||||||
"supportMessage": "通过捐赠支持 MCP Hub 的开发!",
|
"supportMessage": "通过捐赠支持 MCPHub 的开发!",
|
||||||
"supportButton": "在 Ko-fi 上支持"
|
"supportButton": "在 Ko-fi 上支持"
|
||||||
},
|
},
|
||||||
"wechat": {
|
"wechat": {
|
||||||
@@ -52,7 +52,9 @@
|
|||||||
},
|
},
|
||||||
"auth": {
|
"auth": {
|
||||||
"login": "登录",
|
"login": "登录",
|
||||||
"loginTitle": "登录 MCP Hub",
|
"loginTitle": "登录 MCPHub",
|
||||||
|
"slogan": "统一的 MCP 服务器管理平台",
|
||||||
|
"subtitle": "模型上下文协议服务器的集中管理平台,通过灵活的路由策略组织、监控和扩展多个 MCP 服务器。",
|
||||||
"username": "用户名",
|
"username": "用户名",
|
||||||
"password": "密码",
|
"password": "密码",
|
||||||
"loggingIn": "登录中...",
|
"loggingIn": "登录中...",
|
||||||
|
|||||||
Reference in New Issue
Block a user