Skip to main content
Glama
Sessions.tsx8.59 kB
import React from 'react' import { useQuery } from '@tanstack/react-query' import { Globe, Database, Calendar, Clock } from 'lucide-react' import { format } from 'date-fns' const fetchSessions = async () => { const response = await fetch('/sessions') if (!response.ok) throw new Error('Failed to fetch sessions') return response.json() } export default function Sessions() { const { data: sessionsData, isLoading } = useQuery({ queryKey: ['sessions'], queryFn: fetchSessions, refetchInterval: 3000 }) if (isLoading) { return ( <div className="px-4 sm:px-6 lg:px-8"> <div className="animate-pulse"> <div className="h-8 bg-gray-300 dark:bg-gray-700 rounded w-1/4 mb-4"></div> <div className="space-y-3"> {[...Array(3)].map((_, i) => ( <div key={i} className="h-20 bg-gray-300 dark:bg-gray-700 rounded"></div> ))} </div> </div> </div> ) } const sessions = sessionsData?.sessions || [] 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">Sessions</h1> <p className="mt-2 text-sm text-gray-700 dark:text-gray-300"> Manage active browser and database sessions. </p> </div> </div> {/* Sessions Stats */} <div className="mt-8 grid grid-cols-1 gap-5 sm:grid-cols-3"> <div 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"> <Globe className="w-6 h-6 text-blue-600" /> </div> <div className="ml-5 w-0 flex-1"> <dl> <dt className="text-sm font-medium text-gray-500 dark:text-gray-400 truncate"> Browser Sessions </dt> <dd className="text-lg font-semibold text-gray-900 dark:text-white"> {sessions.filter((s: any) => s.type === 'browser').length} </dd> </dl> </div> </div> </div> </div> <div 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"> <Database className="w-6 h-6 text-green-600" /> </div> <div className="ml-5 w-0 flex-1"> <dl> <dt className="text-sm font-medium text-gray-500 dark:text-gray-400 truncate"> Database Sessions </dt> <dd className="text-lg font-semibold text-gray-900 dark:text-white"> {sessions.filter((s: any) => s.type === 'db').length} </dd> </dl> </div> </div> </div> </div> <div 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"> <Clock className="w-6 h-6 text-purple-600" /> </div> <div className="ml-5 w-0 flex-1"> <dl> <dt className="text-sm font-medium text-gray-500 dark:text-gray-400 truncate"> Total Tools </dt> <dd className="text-lg font-semibold text-gray-900 dark:text-white"> {sessionsData?.stats?.session_tools || 0} </dd> </dl> </div> </div> </div> </div> </div> {/* Sessions List */} <div className="mt-8"> {sessions.length > 0 ? ( <div className="bg-white dark:bg-gray-800 shadow overflow-hidden sm:rounded-md border dark:border-gray-700"> <ul className="divide-y divide-gray-200 dark:divide-gray-700"> {sessions.map((session: any) => ( <li key={session.id}> <div className="px-4 py-4 sm:px-6"> <div className="flex items-center justify-between"> <div className="flex items-center"> <div className="flex-shrink-0"> <div className="w-10 h-10 rounded-full bg-indigo-100 dark:bg-indigo-900/20 flex items-center justify-center"> {session.type === 'browser' ? ( <Globe className="w-5 h-5 text-indigo-600" /> ) : ( <Database className="w-5 h-5 text-indigo-600" /> )} </div> </div> <div className="ml-4"> <div className="flex items-center"> <p className="text-sm font-medium text-indigo-600 dark:text-indigo-400 truncate"> {session.type.charAt(0).toUpperCase() + session.type.slice(1)} Session </p> <span className="ml-2 inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800 dark:bg-green-900/20 dark:text-green-300"> Active </span> </div> <div className="mt-1 flex items-center text-sm text-gray-500 dark:text-gray-400"> <span className="font-mono">{session.id}</span> </div> </div> </div> <div className="ml-2 flex-shrink-0 flex"> <div className="text-right"> <div className="flex items-center text-sm text-gray-500 dark:text-gray-400"> <Calendar className="w-4 h-4 mr-1" /> Created: {format(new Date(session.created_at), 'MMM d, h:mm a')} </div> <div className="flex items-center text-sm text-gray-500 dark:text-gray-400 mt-1"> <Clock className="w-4 h-4 mr-1" /> Last used: {format(new Date(session.last_used), 'MMM d, h:mm a')} </div> </div> </div> </div> {/* Session Tools */} <div className="mt-4"> <div className="text-xs font-medium text-gray-500 dark:text-gray-400 mb-2"> Session Tools ({sessionsData?.stats?.tools_by_session?.[session.id] || 0}) </div> <div className="flex flex-wrap gap-1"> {Object.entries(sessionsData?.stats?.tools_by_session || {}) .filter(([sessionId]) => sessionId === session.id) .map(([, count]) => ( <span key={session.id} className="inline-flex items-center px-2 py-1 rounded text-xs font-medium bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-200" > {count} tools available </span> )) } </div> </div> </div> </li> ))} </ul> </div> ) : ( <div className="text-center py-12"> <div className="w-12 h-12 mx-auto bg-gray-100 dark:bg-gray-800 rounded-full flex items-center justify-center mb-4"> <Globe className="w-6 h-6 text-gray-400" /> </div> <h3 className="text-sm font-medium text-gray-900 dark:text-white mb-1">No active sessions</h3> <p className="text-sm text-gray-500 dark:text-gray-400"> Sessions will appear here when tools create them. </p> </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