diff --git a/public/js/app.js b/public/js/app.js index d09d3c2..9d7f223 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -46,8 +46,8 @@ function ServerCard({ server, onRemove }) { const [isExpanded, setIsExpanded] = useState(false); const handleRemove = (e) => { - e.stopPropagation(); // 防止展开/收起行为 - if (confirm(`确定要删除服务器 ${server.name} 吗?`)) { + e.stopPropagation(); + if (confirm(`Are you sure you want to delete server ${server.name}?`)) { onRemove(server.name); } }; @@ -67,7 +67,7 @@ function ServerCard({ server, onRemove }) { onClick={handleRemove} className="px-3 py-1 bg-red-100 text-red-800 rounded hover:bg-red-200 text-sm" > - 删除 + Delete @@ -104,7 +104,6 @@ function AddServerForm({ onAdd }) { const handleArgsChange = (value) => { try { - // 尝试解析为数组,如果不是有效的 JSON 格式,则作为单个字符串处理 let args; if (value.trim().startsWith('[')) { args = JSON.parse(value); @@ -113,7 +112,6 @@ function AddServerForm({ onAdd }) { } setFormData({ ...formData, args }); } catch (err) { - // 如果解析失败,使用默认值 setFormData({ ...formData, args: ['-y', value] }); } }; @@ -126,29 +124,29 @@ function AddServerForm({ onAdd }) { const handleSubmit = async (e) => { e.preventDefault(); setError(null); - + try { const payload = { name: formData.name, - config: serverType === 'url' - ? { url: formData.url } - : { command: formData.command, args: formData.args } + config: + serverType === 'url' + ? { url: formData.url } + : { command: formData.command, args: formData.args }, }; const response = await fetch('/api/servers', { method: 'POST', headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(payload) + body: JSON.stringify(payload), }); const result = await response.json(); - + if (!response.ok) { - setError(result.message || '添加服务器失败'); + setError(result.message || 'Failed to add server'); return; } - // 重置表单 setFormData({ name: '', url: '', @@ -156,11 +154,10 @@ function AddServerForm({ onAdd }) { args: ['-y', ''], }); setFormVisible(false); - - // 通知父组件 + onAdd(); } catch (err) { - setError('发生错误: ' + err.message); + setError('Error: ' + err.message); } }; @@ -171,30 +168,23 @@ function AddServerForm({ onAdd }) { onClick={toggleForm} className="w-full bg-blue-500 hover:bg-blue-600 text-white font-medium py-2 px-4 rounded" > - 添加新服务器 + Add New Server ) : (
-

添加新服务器

-
- - {error && ( -
- {error} -
- )} - + + {error &&
{error}
} +
- +
- +
- + {serverType === 'url' ? (
@@ -260,7 +248,7 @@ function AddServerForm({ onAdd }) {
handleArgsChange(e.target.value)} className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" - placeholder="例如: time-mcp" + placeholder="e.g., time-mcp" required={serverType === 'command'} />

- 将自动添加 "-y" 参数 + "-y" argument will be added automatically

)} - +
@@ -339,26 +327,25 @@ function App() { }, [refreshKey]); const handleServerAdd = () => { - setRefreshKey(prevKey => prevKey + 1); // 强制重新加载 + setRefreshKey((prevKey) => prevKey + 1); }; const handleServerRemove = async (serverName) => { try { const response = await fetch(`/api/servers/${serverName}`, { - method: 'DELETE' + method: 'DELETE', }); - + const result = await response.json(); - + if (!response.ok) { - setError(result.message || `删除服务器 ${serverName} 失败`); + setError(result.message || `Failed to delete server ${serverName}`); return; } - - // 刷新服务器列表 - setRefreshKey(prevKey => prevKey + 1); + + setRefreshKey((prevKey) => prevKey + 1); } catch (err) { - setError('发生错误: ' + err.message); + setError('Error: ' + err.message); } }; @@ -373,7 +360,7 @@ function App() { onClick={() => setError(null)} className="mt-4 bg-red-100 text-red-800 py-1 px-3 rounded hover:bg-red-200" > - 关闭 + Close
@@ -385,9 +372,9 @@ function App() {

MCP Hub Dashboard

- + - + {servers.length === 0 ? (

No MCP servers available

@@ -404,6 +391,5 @@ function App() { ); } -// 使用 React 18 的 createRoot API const root = ReactDOM.createRoot(document.getElementById('root')); root.render(); diff --git a/src/server.ts b/src/server.ts index 2162497..3f3fb3f 100644 --- a/src/server.ts +++ b/src/server.ts @@ -74,7 +74,6 @@ function initializeClientsFromSettings(): { if (config.url) { transport = new SSEClientTransport(new URL(config.url)); } else if (config.command && config.args) { - // add PATH to env const env = config.env || {}; env.PATH = process.env.PATH || ''; transport = new StdioClientTransport({ @@ -122,7 +121,6 @@ export const registerAllTools = async (server: McpServer) => { try { await client.connect(transports[index]); const tools = await client.listTools(); - // Transform the tools to match our ToolInfo interface clientTools[index] = tools.tools.map((tool) => ({ name: tool.name, description: tool.description || '', @@ -167,33 +165,30 @@ export function getServersSettings(): McpSettings { } // Add function to add a new server -export async function addServer(mcpServer: McpServer, name: string, config: { url?: string; command?: string; args?: string[]; env?: Record }): Promise { +export async function addServer( + mcpServer: McpServer, + name: string, + config: { url?: string; command?: string; args?: string[]; env?: Record }, +): Promise { try { - // Load current settings const settings = loadSettings(); - - // Check if server with this name already exists if (settings.mcpServers[name]) { return false; } - - // Add new server to settings + settings.mcpServers[name] = config; - - // Save updated settings + if (!saveSettings(settings)) { return false; } - - // Re-initialize clients with updated settings + const result = initializeClientsFromSettings(); servers = result.servers; clients = result.clients; transports = result.transports; - - // Register tools for the new server + await registerAllTools(mcpServer); - + return true; } catch (error) { console.error(`Failed to add server: ${name}`, error); @@ -201,31 +196,35 @@ export async function addServer(mcpServer: McpServer, name: string, config: { ur } } -// 修改返回类型 -export function removeServer(name: string): { success: boolean; newServers?: string[]; newClients?: Client[]; newTransports?: (SSEClientTransport | StdioClientTransport)[] } { +export function removeServer(name: string): { + success: boolean; + newServers?: string[]; + newClients?: Client[]; + newTransports?: (SSEClientTransport | StdioClientTransport)[]; +} { try { const settings = loadSettings(); - + if (!settings.mcpServers[name]) { return { success: false }; } - + delete settings.mcpServers[name]; - + if (!saveSettings(settings)) { return { success: false }; } - + const result = initializeClientsFromSettings(); servers = result.servers; clients = result.clients; transports = result.transports; - + return { success: true, newServers: result.servers, newClients: result.clients, - newTransports: result.transports + newTransports: result.transports, }; } catch (error) { console.error(`Failed to remove server: ${name}`, error);