97 lines
3.8 KiB
TypeScript
97 lines
3.8 KiB
TypeScript
import React, { useState, useEffect } from 'react';
|
|
import { Header } from './components/Header';
|
|
import { OverviewTab } from './components/OverviewTab';
|
|
import { MCPHubTab } from './components/MCPHubTab';
|
|
import { AIToolStudioTab } from './components/AIToolStudioTab';
|
|
import { WorkflowsTab } from './components/WorkflowsTab';
|
|
import { SecurityGatewayTab } from './components/SecurityGatewayTab';
|
|
import { AnalyticsTab } from './components/AnalyticsTab';
|
|
import { MCPGuideTab } from './components/MCPGuideTab';
|
|
import { ToolPlaygroundTab } from './components/ToolPlaygroundTab';
|
|
import { MemoryVaultTab } from './components/MemoryVaultTab';
|
|
import { ActivityLogsTab } from './components/ActivityLogsTab';
|
|
import { SettingsTab } from './components/SettingsTab';
|
|
import { ServerStats, MCPServerDefinition } from './types';
|
|
|
|
export default function App() {
|
|
const [activeTab, setActiveTab] = useState<string>('mcp-hub');
|
|
const [stats, setStats] = useState<ServerStats | null>(null);
|
|
|
|
const fetchStats = async () => {
|
|
try {
|
|
const res = await fetch('/api/v1/system/status');
|
|
if (res.ok) {
|
|
const data = await res.json();
|
|
setStats(data);
|
|
}
|
|
} catch (err) {
|
|
console.error('Failed to fetch server stats:', err);
|
|
}
|
|
};
|
|
|
|
const handleRegisterServerFromStudio = async (server: Omit<MCPServerDefinition, 'id' | 'createdAt'>) => {
|
|
const res = await fetch('/api/v1/mcp/servers', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(server),
|
|
});
|
|
if (!res.ok) {
|
|
const err = await res.json();
|
|
throw new Error(err.error || 'Failed to register server');
|
|
}
|
|
await fetchStats();
|
|
};
|
|
|
|
useEffect(() => {
|
|
fetchStats();
|
|
const interval = setInterval(fetchStats, 5000);
|
|
return () => clearInterval(interval);
|
|
}, []);
|
|
|
|
return (
|
|
<div className="min-h-screen bg-slate-50 text-slate-900 font-sans flex flex-col antialiased selection:bg-indigo-500 selection:text-white">
|
|
<Header activeTab={activeTab} setActiveTab={setActiveTab} stats={stats} />
|
|
|
|
<main className="flex-1 max-w-7xl w-full mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
|
{activeTab === 'overview' && <OverviewTab stats={stats} setActiveTab={setActiveTab} />}
|
|
{activeTab === 'mcp-hub' && (
|
|
<MCPHubTab
|
|
stats={stats}
|
|
onRefreshStats={fetchStats}
|
|
onNavigateToStudio={() => setActiveTab('mcp-studio')}
|
|
/>
|
|
)}
|
|
{activeTab === 'mcp-studio' && (
|
|
<AIToolStudioTab
|
|
onRegisterServer={handleRegisterServerFromStudio}
|
|
onNavigateToHub={() => setActiveTab('mcp-hub')}
|
|
/>
|
|
)}
|
|
{activeTab === 'workflows' && <WorkflowsTab />}
|
|
{activeTab === 'security' && <SecurityGatewayTab />}
|
|
{activeTab === 'analytics' && <AnalyticsTab stats={stats} />}
|
|
{activeTab === 'mcp-guide' && <MCPGuideTab />}
|
|
{activeTab === 'playground' && <ToolPlaygroundTab />}
|
|
{activeTab === 'memory' && <MemoryVaultTab />}
|
|
{activeTab === 'logs' && <ActivityLogsTab />}
|
|
{activeTab === 'settings' && <SettingsTab stats={stats} />}
|
|
</main>
|
|
|
|
<footer className="border-t border-slate-200 bg-white py-6 mt-12">
|
|
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 flex flex-col sm:flex-row items-center justify-between text-xs text-slate-500 space-y-2 sm:space-y-0 font-mono">
|
|
<div>
|
|
<span>Do Everything MCP Hub & Proxy Server v1.0.0</span>
|
|
<span className="mx-2 text-slate-300">•</span>
|
|
<span>JSON-RPC 2.0 / SSE Enabled</span>
|
|
</div>
|
|
<div>
|
|
<span>Status: Healthy</span>
|
|
<span className="mx-2 text-slate-300">•</span>
|
|
<span>Host: 0.0.0.0:3000</span>
|
|
</div>
|
|
</div>
|
|
</footer>
|
|
</div>
|
|
);
|
|
}
|