Skip to main content
Glama
useMCP.ts3.34 kB
import { useCallback, useEffect } from 'react' import { useRequest, useSSE } from 'alova/client' import { getMCPServiceHealth, getMCPServiceStatus, controlMCPService } from '../api/mcp' import { logger } from '@/utils/logger' import { type MCPStatus, MCPControlAction } from '@/api/types' import { toast } from 'sonner' import { useLanguage } from '@/contexts/language-context' import { toastConfig } from '@/lib/utils' type Position = | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'top-center' | 'bottom-center' export const useMCPControl = (action: MCPControlAction) => { const { t } = useLanguage() const loadingToastConfig = { id: `mcp-control-${action}-loading`, duration: 0, position: 'top-center' as Position, } const loadingMessage = (() => { switch (action) { case 'start': return t('common.toast.starting') case 'stop': return t('common.toast.stopping') case 'restart': return t('common.toast.restarting') } })() const successMessage = (() => { switch (action) { case 'start': return t('common.toast.started') case 'stop': return t('common.toast.stopped') case 'restart': return t('common.toast.restarted') } })() const { send, loading } = useRequest(() => controlMCPService({ action }), { immediate: false, debounce: 500, onSuccess: () => { toast.success(successMessage, toastConfig) }, onError: () => { toast.error('Failed to control MCP service', toastConfig) }, }) useEffect(() => { if (loading) { toast.loading(loadingMessage, loadingToastConfig) } else { toast.dismiss(loadingToastConfig.id) } }, [loading]) return { handleControl: send } } export const useMCPHealth = () => { const { loading, data, error } = useRequest(() => getMCPServiceHealth(), { immediate: true, }) return { loading, status: data?.status, error, } } export const useMCPStatusStream = (statusSetter?: (status: MCPStatus) => void) => { const { eventSource, readyState, onMessage, onError, onOpen, send, close } = useSSE( getMCPServiceStatus(), { immediate: true, interceptByGlobalResponded: false, } ) onMessage(({ data: messageData }) => { try { const eventData = typeof messageData === 'string' ? JSON.parse(messageData) : messageData if (eventData && eventData.status) { if (statusSetter) { statusSetter(eventData.status) } } } catch (error) { logger.error('Failed to parse status event data:', error) } }) onOpen(() => { logger.log('Status SSE connection opened') }) onError(({ error }) => { logger.error('Status SSE error:', error) setTimeout(() => { if (readyState === 2) { // EventSource.CLOSED connect() } }, 3000) }) const connect = useCallback(() => { send() }, [send]) const disconnect = useCallback(() => { close() logger.log('Status SSE connection closed') }, [close]) return { isConnected: readyState === 1, // EventSource.OPEN connectionError: readyState === 2 ? 'Status Connection lost. Attempting to reconnect...' : null, readyState, eventSource, connect, disconnect, } }

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/itcook/graphiti-mcp-pro'

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