Skip to main content
Glama
smatiolids
by smatiolids
page.tsx3.91 kB
'use client'; import { useState, useEffect } from 'react'; import ThemeToggle from '@/components/ThemeToggle'; import ToolList from '@/components/ToolList'; import ToolEditor from '@/components/ToolEditor'; import { Tool } from '@/lib/astraClient'; export default function Home() { const [tools, setTools] = useState<Tool[]>([]); const [selectedTool, setSelectedTool] = useState<Tool | null>(null); const [loading, setLoading] = useState(true); const [error, setError] = useState<string | null>(null); useEffect(() => { loadTools(); }, []); const loadTools = async (showLoading = true) => { try { if (showLoading) { setLoading(true); } setError(null); const response = await fetch('/api/tools'); const data = await response.json(); if (!response.ok || !data.success) { throw new Error(data.error || 'Failed to load tools'); } const loadedTools = data.tools || []; // Sort tools alphabetically by name (case-insensitive) const sortedTools = loadedTools.sort((a: Tool, b: Tool) => { const nameA = (a.name || '').toLowerCase(); const nameB = (b.name || '').toLowerCase(); return nameA.localeCompare(nameB); }); setTools(sortedTools); // Update selected tool if it still exists if (selectedTool) { const updatedTool = sortedTools.find( (t: Tool) => (t._id && t._id === selectedTool._id) || t.name === selectedTool.name ); if (updatedTool) { setSelectedTool(updatedTool); } } } catch (err) { setError(err instanceof Error ? err.message : 'Failed to load tools'); console.error('Error loading tools:', err); } finally { if (showLoading) { setLoading(false); } } }; const handleToolSave = async (savedTool: Tool) => { // Refresh the tools list without showing loading screen await loadTools(false); // Update selected tool with the saved data setSelectedTool(savedTool); }; if (loading) { return ( <div className="h-screen flex items-center justify-center bg-white dark:bg-gray-800"> <div className="text-center"> <div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600 mx-auto mb-4"></div> <p className="text-gray-600 dark:text-gray-400">Loading tools...</p> </div> </div> ); } if (error) { return ( <div className="h-screen flex items-center justify-center bg-white dark:bg-gray-800"> <div className="text-center max-w-md mx-auto p-6"> <div className="text-red-600 dark:text-red-400 mb-4"> <svg className="w-16 h-16 mx-auto" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" /> </svg> </div> <h2 className="text-xl font-semibold text-gray-800 dark:text-gray-200 mb-2">Error Loading Tools</h2> <p className="text-gray-600 dark:text-gray-400 mb-4">{error}</p> <button onClick={() => loadTools()} className="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors" > Retry </button> </div> </div> ); } const handleNewTool = () => { setSelectedTool({ type: 'tool', name: '', collection_name: '', table_name: '', db_name: '', enabled: true, } as Tool); }; return ( <div className="h-screen flex bg-white dark:bg-gray-800"> <ThemeToggle /> <ToolList tools={tools} selectedTool={selectedTool} onSelectTool={setSelectedTool} onNewTool={handleNewTool} /> <ToolEditor tool={selectedTool} onSave={handleToolSave} /> </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/smatiolids/astra-mcp-server'

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