Skip to main content
Glama
Overview.tsx7.59 kB
import React from 'react' import { useQuery } from '@tanstack/react-query' import { Activity, Users, Terminal, Globe, Database } from 'lucide-react' import { format } from 'date-fns' // API functions const fetchSessions = async () => { const response = await fetch('/sessions') if (!response.ok) throw new Error('Failed to fetch sessions') return response.json() } const fetchRecentLogs = async () => { const response = await fetch('/logs?limit=10') if (!response.ok) throw new Error('Failed to fetch logs') return response.json() } const fetchTools = async () => { const response = await fetch('/tools') if (!response.ok) throw new Error('Failed to fetch tools') return response.json() } export default function Overview() { const { data: sessionsData } = useQuery({ queryKey: ['sessions'], queryFn: fetchSessions, refetchInterval: 5000 }) const { data: logsData } = useQuery({ queryKey: ['logs'], queryFn: fetchRecentLogs, refetchInterval: 2000 }) const { data: toolsData } = useQuery({ queryKey: ['tools'], queryFn: fetchTools }) const stats = [ { name: 'Active Sessions', value: sessionsData?.stats?.active_sessions || 0, icon: Users, color: 'text-blue-600', bgColor: 'bg-blue-100 dark:bg-blue-900/20' }, { name: 'Total Tools', value: toolsData?.tools?.length || 0, icon: Terminal, color: 'text-green-600', bgColor: 'bg-green-100 dark:bg-green-900/20' }, { name: 'Static Tools', value: sessionsData?.stats?.static_tools || 0, icon: Activity, color: 'text-purple-600', bgColor: 'bg-purple-100 dark:bg-purple-900/20' }, { name: 'Session Tools', value: sessionsData?.stats?.session_tools || 0, icon: Globe, color: 'text-orange-600', bgColor: 'bg-orange-100 dark:bg-orange-900/20' } ] return ( <div className="px-4 sm:px-6 lg:px-8"> <div className="sm:flex sm:items-center"> <div className="sm:flex-auto"> <h1 className="text-2xl font-semibold text-gray-900 dark:text-white">Overview</h1> <p className="mt-2 text-sm text-gray-700 dark:text-gray-300"> Monitor your MCP server status, sessions, and tool activity. </p> </div> </div> {/* Stats Grid */} <div className="mt-8 grid grid-cols-1 gap-5 sm:grid-cols-2 lg:grid-cols-4"> {stats.map((stat) => ( <div key={stat.name} className="bg-white dark:bg-gray-800 overflow-hidden shadow rounded-lg border dark:border-gray-700" > <div className="p-5"> <div className="flex items-center"> <div className="flex-shrink-0"> <div className={`w-8 h-8 rounded-md ${stat.bgColor} flex items-center justify-center`}> <stat.icon className={`w-5 h-5 ${stat.color}`} /> </div> </div> <div className="ml-5 w-0 flex-1"> <dl> <dt className="text-sm font-medium text-gray-500 dark:text-gray-400 truncate"> {stat.name} </dt> <dd className="text-lg font-semibold text-gray-900 dark:text-white"> {stat.value} </dd> </dl> </div> </div> </div> </div> ))} </div> {/* Recent Activity */} <div className="mt-8 grid grid-cols-1 lg:grid-cols-2 gap-8"> {/* Recent Tool Calls */} <div className="bg-white dark:bg-gray-800 shadow rounded-lg border dark:border-gray-700"> <div className="px-6 py-4 border-b dark:border-gray-700"> <h3 className="text-lg font-medium text-gray-900 dark:text-white">Recent Tool Calls</h3> </div> <div className="p-6"> {logsData?.logs?.length > 0 ? ( <div className="space-y-4"> {logsData.logs.slice(0, 5).map((log: any, index: number) => ( <div key={log.id || index} className="flex items-start space-x-3"> <div className="flex-shrink-0"> <div className={`w-2 h-2 mt-2 rounded-full ${ log.error ? 'bg-red-500' : 'bg-green-500' }`} /> </div> <div className="min-w-0 flex-1"> <div className="text-sm font-medium text-gray-900 dark:text-white"> {log.tool_name} </div> <div className="text-xs text-gray-500 dark:text-gray-400"> {format(new Date(log.timestamp), 'MMM d, h:mm:ss a')} • {log.duration_ms}ms </div> {log.error && ( <div className="mt-1 text-xs text-red-600 dark:text-red-400"> {log.error.message} </div> )} </div> </div> ))} </div> ) : ( <div className="text-center py-4"> <Terminal className="mx-auto h-8 w-8 text-gray-400" /> <p className="mt-2 text-sm text-gray-500 dark:text-gray-400">No recent tool calls</p> </div> )} </div> </div> {/* Active Sessions */} <div className="bg-white dark:bg-gray-800 shadow rounded-lg border dark:border-gray-700"> <div className="px-6 py-4 border-b dark:border-gray-700"> <h3 className="text-lg font-medium text-gray-900 dark:text-white">Active Sessions</h3> </div> <div className="p-6"> {sessionsData?.sessions?.length > 0 ? ( <div className="space-y-4"> {sessionsData.sessions.map((session: any) => ( <div key={session.id} className="flex items-start space-x-3"> <div className="flex-shrink-0"> <div className="w-8 h-8 rounded-full bg-indigo-100 dark:bg-indigo-900/20 flex items-center justify-center"> {session.type === 'browser' ? ( <Globe className="w-4 h-4 text-indigo-600" /> ) : ( <Database className="w-4 h-4 text-indigo-600" /> )} </div> </div> <div className="min-w-0 flex-1"> <div className="text-sm font-medium text-gray-900 dark:text-white"> {session.type} session </div> <div className="text-xs text-gray-500 dark:text-gray-400"> ID: {session.id.slice(0, 8)}... </div> <div className="text-xs text-gray-500 dark:text-gray-400"> Created: {format(new Date(session.created_at), 'MMM d, h:mm a')} </div> </div> </div> ))} </div> ) : ( <div className="text-center py-4"> <Users className="mx-auto h-8 w-8 text-gray-400" /> <p className="mt-2 text-sm text-gray-500 dark:text-gray-400">No active sessions</p> </div> )} </div> </div> </div> </div> ) }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/JacobFV/mcp-fullstack'

If you have feedback or need assistance with the MCP directory API, please join our Discord server