mirror of
https://github.com/samanhappy/mcphub.git
synced 2025-12-24 02:39:19 -05:00
feat: add server toggle functionality
This commit is contained in:
@@ -275,6 +275,34 @@ const Dashboard = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleServerToggle = async (server: Server, enabled: boolean) => {
|
||||||
|
try {
|
||||||
|
const token = localStorage.getItem('mcphub_token');
|
||||||
|
const response = await fetch(`/api/servers/${server.name}/toggle`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'x-auth-token': token || ''
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ enabled }),
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = await response.json();
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
console.error('Failed to toggle server:', result);
|
||||||
|
setError(t('server.toggleError', { serverName: server.name }));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the UI immediately to reflect the change
|
||||||
|
setRefreshKey(prevKey => prevKey + 1);
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Error toggling server:', err);
|
||||||
|
setError(err instanceof Error ? err.message : String(err));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const handleLogout = () => {
|
const handleLogout = () => {
|
||||||
logout()
|
logout()
|
||||||
navigate('/login')
|
navigate('/login')
|
||||||
@@ -333,6 +361,7 @@ const Dashboard = () => {
|
|||||||
server={server}
|
server={server}
|
||||||
onRemove={handleServerRemove}
|
onRemove={handleServerRemove}
|
||||||
onEdit={handleServerEdit}
|
onEdit={handleServerEdit}
|
||||||
|
onToggle={handleServerToggle}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -10,12 +10,14 @@ interface ServerCardProps {
|
|||||||
server: Server
|
server: Server
|
||||||
onRemove: (serverName: string) => void
|
onRemove: (serverName: string) => void
|
||||||
onEdit: (server: Server) => void
|
onEdit: (server: Server) => void
|
||||||
|
onToggle?: (server: Server, enabled: boolean) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const ServerCard = ({ server, onRemove, onEdit }: ServerCardProps) => {
|
const ServerCard = ({ server, onRemove, onEdit, onToggle }: ServerCardProps) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const [isExpanded, setIsExpanded] = useState(false)
|
const [isExpanded, setIsExpanded] = useState(false)
|
||||||
const [showDeleteDialog, setShowDeleteDialog] = useState(false)
|
const [showDeleteDialog, setShowDeleteDialog] = useState(false)
|
||||||
|
const [isToggling, setIsToggling] = useState(false)
|
||||||
|
|
||||||
const handleRemove = (e: React.MouseEvent) => {
|
const handleRemove = (e: React.MouseEvent) => {
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
@@ -27,6 +29,19 @@ const ServerCard = ({ server, onRemove, onEdit }: ServerCardProps) => {
|
|||||||
onEdit(server)
|
onEdit(server)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleToggle = async (e: React.MouseEvent) => {
|
||||||
|
e.stopPropagation()
|
||||||
|
if (isToggling || !onToggle) return
|
||||||
|
|
||||||
|
setIsToggling(true)
|
||||||
|
try {
|
||||||
|
// Toggle the server's enabled status
|
||||||
|
await onToggle(server, !(server.enabled !== false))
|
||||||
|
} finally {
|
||||||
|
setIsToggling(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const handleConfirmDelete = () => {
|
const handleConfirmDelete = () => {
|
||||||
onRemove(server.name)
|
onRemove(server.name)
|
||||||
setShowDeleteDialog(false)
|
setShowDeleteDialog(false)
|
||||||
@@ -55,6 +70,26 @@ const ServerCard = ({ server, onRemove, onEdit }: ServerCardProps) => {
|
|||||||
>
|
>
|
||||||
{t('server.delete')}
|
{t('server.delete')}
|
||||||
</button>
|
</button>
|
||||||
|
<div className="flex items-center">
|
||||||
|
<button
|
||||||
|
onClick={handleToggle}
|
||||||
|
className={`px-3 py-1 text-sm rounded transition-colors ${
|
||||||
|
isToggling
|
||||||
|
? 'bg-gray-200 text-gray-500'
|
||||||
|
: server.enabled !== false
|
||||||
|
? 'bg-green-100 text-green-800 hover:bg-green-200'
|
||||||
|
: 'bg-gray-100 text-gray-800 hover:bg-gray-200'
|
||||||
|
}`}
|
||||||
|
disabled={isToggling}
|
||||||
|
>
|
||||||
|
{isToggling
|
||||||
|
? t('common.processing')
|
||||||
|
: server.enabled !== false
|
||||||
|
? t('server.disable')
|
||||||
|
: t('server.enable')
|
||||||
|
}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
<button className="text-gray-400 hover:text-gray-600">
|
<button className="text-gray-400 hover:text-gray-600">
|
||||||
{isExpanded ? <ChevronDown size={18} /> : <ChevronRight size={18} />}
|
{isExpanded ? <ChevronDown size={18} /> : <ChevronRight size={18} />}
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"title": "MCP Hub Dashboard",
|
"title": "MCP Hub Dashboard",
|
||||||
"error": "Error",
|
"error": "Error",
|
||||||
"closeButton": "Close",
|
"closeButton": "Close",
|
||||||
"noServers": "No MCP servers available",
|
"noServers": "No servers found. Add a new server to get started.",
|
||||||
"loading": "Loading...",
|
"loading": "Loading...",
|
||||||
"logout": "Logout",
|
"logout": "Logout",
|
||||||
"profile": "Profile",
|
"profile": "Profile",
|
||||||
@@ -24,7 +24,14 @@
|
|||||||
"passwordsNotMatch": "New password and confirmation do not match",
|
"passwordsNotMatch": "New password and confirmation do not match",
|
||||||
"changePasswordSuccess": "Password changed successfully",
|
"changePasswordSuccess": "Password changed successfully",
|
||||||
"changePasswordError": "Failed to change password",
|
"changePasswordError": "Failed to change password",
|
||||||
"changePassword": "Change Password"
|
"changePassword": "Change Password",
|
||||||
|
"confirmNewPassword": "Confirm New Password",
|
||||||
|
"loginButton": "Login",
|
||||||
|
"changePasswordTitle": "Change Password",
|
||||||
|
"changePasswordButton": "Change Password",
|
||||||
|
"passwordsMustMatch": "Passwords must match",
|
||||||
|
"changeSuccess": "Password changed successfully",
|
||||||
|
"invalidCredentials": "Invalid username or password"
|
||||||
},
|
},
|
||||||
"server": {
|
"server": {
|
||||||
"addServer": "Add Server",
|
"addServer": "Add Server",
|
||||||
@@ -33,25 +40,34 @@
|
|||||||
"delete": "Delete",
|
"delete": "Delete",
|
||||||
"confirmDelete": "Are you sure you want to delete this server?",
|
"confirmDelete": "Are you sure you want to delete this server?",
|
||||||
"status": "Status",
|
"status": "Status",
|
||||||
"tools": "Tools",
|
"tools": "Available Tools",
|
||||||
"name": "Server Name",
|
"name": "Name",
|
||||||
"url": "Server URL",
|
"url": "URL",
|
||||||
"apiKey": "API Key",
|
"apiKey": "API Key",
|
||||||
"save": "Save Changes",
|
"save": "Save",
|
||||||
"cancel": "Cancel",
|
"cancel": "Cancel",
|
||||||
"invalidConfig": "Could not find configuration data for {{serverName}}",
|
"invalidConfig": "Failed to get configuration for '{{serverName}}'",
|
||||||
"addError": "Failed to add server",
|
"addError": "Failed to add server",
|
||||||
"editError": "Failed to edit server {{serverName}}",
|
"editError": "Failed to edit server {{serverName}}",
|
||||||
"deleteError": "Failed to delete server {{serverName}}",
|
"deleteError": "Failed to delete server {{serverName}}",
|
||||||
"updateError": "Failed to update server",
|
"updateError": "Failed to update server '{{serverName}}'",
|
||||||
"editTitle": "Edit Server: {{serverName}}",
|
"editTitle": "Edit Server: {{serverName}}",
|
||||||
"type": "Server Type",
|
"type": "Type",
|
||||||
"command": "Command",
|
"command": "Command",
|
||||||
"arguments": "Arguments",
|
"arguments": "Arguments",
|
||||||
"envVars": "Environment Variables",
|
"envVars": "Environment Variables",
|
||||||
"key": "key",
|
"key": "Key",
|
||||||
"value": "value",
|
"value": "Value",
|
||||||
"remove": "Remove"
|
"remove": "Remove",
|
||||||
|
"deleteTitle": "Delete Server",
|
||||||
|
"deleteConfirm": "Are you sure you want to delete {{serverName}}?",
|
||||||
|
"deleteWarning": "This action cannot be undone.",
|
||||||
|
"enable": "Enable",
|
||||||
|
"disable": "Disable",
|
||||||
|
"toggleError": "Failed to toggle server: {{serverName}}",
|
||||||
|
"invalidData": "Invalid server data",
|
||||||
|
"alreadyExists": "Server '{{serverName}}' already exists",
|
||||||
|
"notFound": "Server '{{serverName}}' not found"
|
||||||
},
|
},
|
||||||
"status": {
|
"status": {
|
||||||
"online": "Online",
|
"online": "Online",
|
||||||
@@ -59,16 +75,17 @@
|
|||||||
"connecting": "Connecting"
|
"connecting": "Connecting"
|
||||||
},
|
},
|
||||||
"errors": {
|
"errors": {
|
||||||
"general": "Something went wrong",
|
"general": "An error occurred",
|
||||||
"network": "Network connection error. Please check your internet connection",
|
"network": "Network connection error. Please check your internet connection.",
|
||||||
"serverConnection": "Unable to connect to the server. Please check if the server is running",
|
"serverConnection": "Could not connect to server. Please try again later.",
|
||||||
"serverAdd": "Failed to add server. Please check the server status",
|
"serverAdd": "Failed to add server.",
|
||||||
"serverUpdate": "Failed to edit server {{serverName}}. Please check the server status",
|
"serverUpdate": "Failed to update server '{{serverName}}'.",
|
||||||
"serverFetch": "Failed to retrieve server data. Please try again later",
|
"serverFetch": "Failed to fetch servers data.",
|
||||||
"initialStartup": "The server might be starting up. Please wait a moment as this process can take some time on first launch..."
|
"initialStartup": "Server is starting up. Please wait..."
|
||||||
},
|
},
|
||||||
"common": {
|
"common": {
|
||||||
"save": "Save",
|
"save": "Save",
|
||||||
"cancel": "Cancel"
|
"cancel": "Cancel",
|
||||||
|
"processing": "Processing..."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
"title": "MCP Hub 控制面板",
|
"title": "MCP Hub 控制面板",
|
||||||
"error": "错误",
|
"error": "错误",
|
||||||
"closeButton": "关闭",
|
"closeButton": "关闭",
|
||||||
"noServers": "没有可用的 MCP 服务器",
|
"noServers": "未找到服务器。添加新服务器以开始使用。",
|
||||||
"loading": "加载中...",
|
"loading": "加载中...",
|
||||||
"logout": "退出登录",
|
"logout": "退出登录",
|
||||||
"profile": "个人资料",
|
"profile": "个人资料",
|
||||||
@@ -14,44 +14,60 @@
|
|||||||
"loginTitle": "登录 MCP Hub",
|
"loginTitle": "登录 MCP Hub",
|
||||||
"username": "用户名",
|
"username": "用户名",
|
||||||
"password": "密码",
|
"password": "密码",
|
||||||
"loggingIn": "登录中...",
|
"loggingIn": "正在登录...",
|
||||||
"emptyFields": "用户名和密码不能为空",
|
"emptyFields": "用户名和密码不能为空",
|
||||||
"loginFailed": "登录失败,请检查用户名和密码",
|
"loginFailed": "登录失败,请检查用户名和密码",
|
||||||
"loginError": "登录过程中出现错误",
|
"loginError": "登录时发生错误",
|
||||||
"currentPassword": "当前密码",
|
"currentPassword": "当前密码",
|
||||||
"newPassword": "新密码",
|
"newPassword": "新密码",
|
||||||
"confirmPassword": "确认密码",
|
"confirmPassword": "确认密码",
|
||||||
"passwordsNotMatch": "新密码与确认密码不一致",
|
"passwordsNotMatch": "新密码和确认密码不匹配",
|
||||||
"changePasswordSuccess": "密码修改成功",
|
"changePasswordSuccess": "密码修改成功",
|
||||||
"changePasswordError": "修改密码失败",
|
"changePasswordError": "密码修改失败",
|
||||||
"changePassword": "修改密码"
|
"changePassword": "修改密码",
|
||||||
|
"confirmNewPassword": "确认新密码",
|
||||||
|
"loginButton": "登录",
|
||||||
|
"changePasswordTitle": "修改密码",
|
||||||
|
"changePasswordButton": "修改密码",
|
||||||
|
"passwordsMustMatch": "密码必须匹配",
|
||||||
|
"changeSuccess": "密码修改成功",
|
||||||
|
"invalidCredentials": "用户名或密码无效"
|
||||||
},
|
},
|
||||||
"server": {
|
"server": {
|
||||||
"addServer": "添加服务器",
|
"addServer": "添加服务器",
|
||||||
"add": "添加",
|
"add": "添加",
|
||||||
"edit": "编辑",
|
"edit": "编辑",
|
||||||
"delete": "删除",
|
"delete": "删除",
|
||||||
"confirmDelete": "您确定要删除此服务器吗?",
|
"confirmDelete": "确定要删除此服务器吗?",
|
||||||
"status": "状态",
|
"status": "状态",
|
||||||
"tools": "工具",
|
"tools": "可用工具",
|
||||||
"name": "服务器名称",
|
"name": "名称",
|
||||||
"url": "服务器 URL",
|
"url": "URL",
|
||||||
"apiKey": "API 密钥",
|
"apiKey": "API 密钥",
|
||||||
"save": "保存更改",
|
"save": "保存",
|
||||||
"cancel": "取消",
|
"cancel": "取消",
|
||||||
|
"invalidConfig": "获取 '{{serverName}}' 的配置失败",
|
||||||
"addError": "添加服务器失败",
|
"addError": "添加服务器失败",
|
||||||
"editError": "编辑服务器 {{serverName}} 失败",
|
"editError": "编辑服务器 {{serverName}} 失败",
|
||||||
"invalidConfig": "无法找到 {{serverName}} 的配置数据",
|
|
||||||
"deleteError": "删除服务器 {{serverName}} 失败",
|
"deleteError": "删除服务器 {{serverName}} 失败",
|
||||||
"updateError": "更新服务器失败",
|
"updateError": "更新服务器 '{{serverName}}' 失败",
|
||||||
"editTitle": "编辑服务器: {{serverName}}",
|
"editTitle": "编辑服务器: {{serverName}}",
|
||||||
"type": "服务器类型",
|
"type": "类型",
|
||||||
"command": "命令",
|
"command": "命令",
|
||||||
"arguments": "参数",
|
"arguments": "参数",
|
||||||
"envVars": "环境变量",
|
"envVars": "环境变量",
|
||||||
"key": "键",
|
"key": "键",
|
||||||
"value": "值",
|
"value": "值",
|
||||||
"remove": "移除"
|
"remove": "移除",
|
||||||
|
"deleteTitle": "删除服务器",
|
||||||
|
"deleteConfirm": "您确定要删除 {{serverName}} 吗?",
|
||||||
|
"deleteWarning": "此操作无法撤销。",
|
||||||
|
"enable": "启用",
|
||||||
|
"disable": "禁用",
|
||||||
|
"toggleError": "切换服务器 {{serverName}} 状态失败",
|
||||||
|
"invalidData": "无效的服务器数据",
|
||||||
|
"alreadyExists": "服务器 '{{serverName}}' 已存在",
|
||||||
|
"notFound": "未找到服务器 '{{serverName}}'"
|
||||||
},
|
},
|
||||||
"status": {
|
"status": {
|
||||||
"online": "在线",
|
"online": "在线",
|
||||||
@@ -60,15 +76,16 @@
|
|||||||
},
|
},
|
||||||
"errors": {
|
"errors": {
|
||||||
"general": "发生错误",
|
"general": "发生错误",
|
||||||
"network": "网络连接错误,请检查您的互联网连接",
|
"network": "网络连接错误。请检查您的互联网连接。",
|
||||||
"serverConnection": "无法连接到服务器,请检查服务器是否正在运行",
|
"serverConnection": "无法连接到服务器。请稍后再试。",
|
||||||
"serverAdd": "添加服务器失败,请检查服务器状态",
|
"serverAdd": "添加服务器失败。",
|
||||||
"serverUpdate": "编辑服务器 {{serverName}} 失败,请检查服务器状态",
|
"serverUpdate": "更新服务器 '{{serverName}}' 失败。",
|
||||||
"serverFetch": "获取服务器数据失败,请稍后重试",
|
"serverFetch": "获取服务器数据失败。",
|
||||||
"initialStartup": "服务器可能正在启动中。首次启动可能需要一些时间,请耐心等候..."
|
"initialStartup": "服务器正在启动。请稍候..."
|
||||||
},
|
},
|
||||||
"common": {
|
"common": {
|
||||||
"save": "保存",
|
"save": "保存",
|
||||||
"cancel": "取消"
|
"cancel": "取消",
|
||||||
|
"processing": "处理中..."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -30,6 +30,7 @@ export interface Server {
|
|||||||
status: ServerStatus;
|
status: ServerStatus;
|
||||||
tools?: Tool[];
|
tools?: Tool[];
|
||||||
config?: ServerConfig;
|
config?: ServerConfig;
|
||||||
|
enabled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 环境变量类型
|
// 环境变量类型
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
removeServer,
|
removeServer,
|
||||||
updateMcpServer,
|
updateMcpServer,
|
||||||
recreateMcpServer,
|
recreateMcpServer,
|
||||||
|
toggleServerStatus,
|
||||||
} from '../services/mcpService.js';
|
} from '../services/mcpService.js';
|
||||||
import { loadSettings } from '../config/index.js';
|
import { loadSettings } from '../config/index.js';
|
||||||
|
|
||||||
@@ -207,3 +208,46 @@ export const getServerConfig = (req: Request, res: Response): void => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const toggleServer = async (req: Request, res: Response): Promise<void> => {
|
||||||
|
try {
|
||||||
|
const { name } = req.params;
|
||||||
|
const { enabled } = req.body;
|
||||||
|
|
||||||
|
if (!name) {
|
||||||
|
res.status(400).json({
|
||||||
|
success: false,
|
||||||
|
message: 'Server name is required',
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof enabled !== 'boolean') {
|
||||||
|
res.status(400).json({
|
||||||
|
success: false,
|
||||||
|
message: 'Enabled status must be a boolean',
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await toggleServerStatus(name, enabled);
|
||||||
|
|
||||||
|
if (result.success) {
|
||||||
|
recreateMcpServer();
|
||||||
|
res.json({
|
||||||
|
success: true,
|
||||||
|
message: result.message || `Server ${enabled ? 'enabled' : 'disabled'} successfully`,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
res.status(404).json({
|
||||||
|
success: false,
|
||||||
|
message: result.message || 'Server not found or failed to toggle status',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
res.status(500).json({
|
||||||
|
success: false,
|
||||||
|
message: 'Internal server error',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
createServer,
|
createServer,
|
||||||
updateServer,
|
updateServer,
|
||||||
deleteServer,
|
deleteServer,
|
||||||
|
toggleServer,
|
||||||
} from '../controllers/serverController.js';
|
} from '../controllers/serverController.js';
|
||||||
import {
|
import {
|
||||||
login,
|
login,
|
||||||
@@ -24,6 +25,7 @@ export const initRoutes = (app: express.Application): void => {
|
|||||||
router.post('/servers', createServer);
|
router.post('/servers', createServer);
|
||||||
router.put('/servers/:name', updateServer);
|
router.put('/servers/:name', updateServer);
|
||||||
router.delete('/servers/:name', deleteServer);
|
router.delete('/servers/:name', deleteServer);
|
||||||
|
router.post('/servers/:name/toggle', toggleServer);
|
||||||
|
|
||||||
// Auth routes (these will NOT be protected by auth middleware)
|
// Auth routes (these will NOT be protected by auth middleware)
|
||||||
app.post('/auth/login', [
|
app.post('/auth/login', [
|
||||||
|
|||||||
@@ -44,12 +44,28 @@ export const initializeClientsFromSettings = (): ServerInfo[] => {
|
|||||||
serverInfos = [];
|
serverInfos = [];
|
||||||
|
|
||||||
for (const [name, conf] of Object.entries(settings.mcpServers)) {
|
for (const [name, conf] of Object.entries(settings.mcpServers)) {
|
||||||
|
// Skip disabled servers
|
||||||
|
if (conf.enabled === false) {
|
||||||
|
console.log(`Skipping disabled server: ${name}`);
|
||||||
|
serverInfos.push({
|
||||||
|
name,
|
||||||
|
status: 'disconnected',
|
||||||
|
tools: [],
|
||||||
|
createTime: Date.now(),
|
||||||
|
enabled: false
|
||||||
|
});
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if server is already connected
|
// Check if server is already connected
|
||||||
const existingServer = existingServerInfos.find(
|
const existingServer = existingServerInfos.find(
|
||||||
(s) => s.name === name && s.status === 'connected',
|
(s) => s.name === name && s.status === 'connected',
|
||||||
);
|
);
|
||||||
if (existingServer) {
|
if (existingServer) {
|
||||||
serverInfos.push(existingServer);
|
serverInfos.push({
|
||||||
|
...existingServer,
|
||||||
|
enabled: conf.enabled === undefined ? true : conf.enabled
|
||||||
|
});
|
||||||
console.log(`Server '${name}' is already connected.`);
|
console.log(`Server '${name}' is already connected.`);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -160,12 +176,18 @@ export const registerAllTools = async (server: McpServer, forceInit: boolean): P
|
|||||||
|
|
||||||
// Get all server information
|
// Get all server information
|
||||||
export const getServersInfo = (): Omit<ServerInfo, 'client' | 'transport'>[] => {
|
export const getServersInfo = (): Omit<ServerInfo, 'client' | 'transport'>[] => {
|
||||||
return serverInfos.map(({ name, status, tools, createTime }) => ({
|
const settings = loadSettings();
|
||||||
name,
|
return serverInfos.map(({ name, status, tools, createTime }) => {
|
||||||
status,
|
const serverConfig = settings.mcpServers[name];
|
||||||
tools,
|
const enabled = serverConfig ? (serverConfig.enabled !== false) : true;
|
||||||
createTime,
|
return {
|
||||||
}));
|
name,
|
||||||
|
status,
|
||||||
|
tools,
|
||||||
|
createTime,
|
||||||
|
enabled,
|
||||||
|
};
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get server information by name
|
// Get server information by name
|
||||||
@@ -252,6 +274,51 @@ export const updateMcpServer = async (
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Toggle server enabled status
|
||||||
|
export const toggleServerStatus = async (
|
||||||
|
name: string,
|
||||||
|
enabled: boolean
|
||||||
|
): Promise<{ success: boolean; message?: string }> => {
|
||||||
|
try {
|
||||||
|
const settings = loadSettings();
|
||||||
|
if (!settings.mcpServers[name]) {
|
||||||
|
return { success: false, message: 'Server not found' };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the enabled status in settings
|
||||||
|
settings.mcpServers[name].enabled = enabled;
|
||||||
|
|
||||||
|
if (!saveSettings(settings)) {
|
||||||
|
return { success: false, message: 'Failed to save settings' };
|
||||||
|
}
|
||||||
|
|
||||||
|
// If disabling, disconnect the server and remove from active servers
|
||||||
|
if (!enabled) {
|
||||||
|
const serverInfo = serverInfos.find((serverInfo) => serverInfo.name === name);
|
||||||
|
if (serverInfo && serverInfo.client && serverInfo.transport) {
|
||||||
|
serverInfo.client.close();
|
||||||
|
serverInfo.transport.close();
|
||||||
|
console.log(`Closed client and transport for server: ${name}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the server info to show as disconnected and disabled
|
||||||
|
const index = serverInfos.findIndex(s => s.name === name);
|
||||||
|
if (index !== -1) {
|
||||||
|
serverInfos[index] = {
|
||||||
|
...serverInfos[index],
|
||||||
|
status: 'disconnected',
|
||||||
|
enabled: false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { success: true, message: `Server ${enabled ? 'enabled' : 'disabled'} successfully` };
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Failed to toggle server status: ${name}`, error);
|
||||||
|
return { success: false, message: 'Failed to toggle server status' };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Create McpServer instance
|
// Create McpServer instance
|
||||||
export const createMcpServer = (name: string, version: string): McpServer => {
|
export const createMcpServer = (name: string, version: string): McpServer => {
|
||||||
return new McpServer({ name, version });
|
return new McpServer({ name, version });
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ export interface ServerConfig {
|
|||||||
command?: string; // Command to execute for stdio-based servers
|
command?: string; // Command to execute for stdio-based servers
|
||||||
args?: string[]; // Arguments for the command
|
args?: string[]; // Arguments for the command
|
||||||
env?: Record<string, string>; // Environment variables
|
env?: Record<string, string>; // Environment variables
|
||||||
|
enabled?: boolean; // Flag to enable/disable the server
|
||||||
}
|
}
|
||||||
|
|
||||||
// Information about a server's status and tools
|
// Information about a server's status and tools
|
||||||
@@ -33,6 +34,7 @@ export interface ServerInfo {
|
|||||||
client?: Client; // Client instance for communication
|
client?: Client; // Client instance for communication
|
||||||
transport?: SSEClientTransport | StdioClientTransport; // Transport mechanism used
|
transport?: SSEClientTransport | StdioClientTransport; // Transport mechanism used
|
||||||
createTime: number; // Timestamp of when the server was created
|
createTime: number; // Timestamp of when the server was created
|
||||||
|
enabled?: boolean; // Flag to indicate if the server is enabled
|
||||||
}
|
}
|
||||||
|
|
||||||
// Details about a tool available on the server
|
// Details about a tool available on the server
|
||||||
|
|||||||
Reference in New Issue
Block a user