Skip to main content
Glama
mcp-client.ts5.94 kB
// MCP Client for FakeStore API operations // Browser-compatible client that communicates with MCP server via HTTP import { User, Cart, Product } from '@/lib/types' class MCPClientManager { private baseUrl = '/api/mcp' private authToken: string | null = null private currentUser: User | null = null private sessionId: string | null = null private requestId = 0 setAuth(token: string, user: User) { this.authToken = token this.currentUser = user } clearAuth() { this.authToken = null this.currentUser = null // Preserve sessionId to retain cart session across logouts until TTL expires } private async callRpc<T>(toolName: string, args: any = {}): Promise<T> { const id = ++this.requestId const body = { jsonrpc: '2.0', id, method: 'tools/call', params: { name: toolName, arguments: args } } const headers: Record<string, string> = { 'Content-Type': 'application/json', 'MCP-Protocol-Version': '2025-06-18' } if (this.authToken) headers.Authorization = `Bearer ${this.authToken}` if (this.sessionId) headers['Mcp-Session-Id'] = this.sessionId const res = await fetch(this.baseUrl, { method: 'POST', body: JSON.stringify(body), headers }) if (!res.ok) throw new Error(`MCP call failed: ${res.status} ${res.statusText}`) const newSid = res.headers.get('Mcp-Session-Id') if (newSid) this.sessionId = newSid const rpc = await res.json() if (rpc.error) throw new Error(rpc.error.message || 'Unknown RPC error') const content = rpc.result.content as Array<{ type: string; text: string }> const payload = JSON.parse(content[0].text) return payload as T } async login(username: string, password: string): Promise<{ success: boolean; user?: User; token?: string; error?: string }> { try { const result = await this.callRpc<{ success: boolean; user?: User; token?: string; error?: string }>( 'login', { username, password } ) if (result.success && result.user && result.token) this.setAuth(result.token, result.user) return result } catch (error) { return { success: false, error: error instanceof Error ? error.message : 'Login failed' } } } async logout(): Promise<{ success: boolean }> { try { const result = await this.callRpc<{ success: boolean }>('logout') this.clearAuth() return result } catch (error) { this.clearAuth() return { success: false } } } async getUsers(): Promise<{ success: boolean; users?: User[]; error?: string }> { try { return await this.callRpc<{ success: boolean; users?: User[]; error?: string }>('get_users') } catch (error) { return { success: false, error: error instanceof Error ? error.message : 'Failed to get users' } } } async getProducts(category?: string, limit?: number): Promise<{ success: boolean; products?: Product[]; count?: number; error?: string }> { try { const args: any = {} if (category) args.category = category if (limit) args.limit = limit return await this.callRpc<{ success: boolean; products?: Product[]; count?: number; error?: string }>( 'get_products', args ) } catch (error) { return { success: false, error: error instanceof Error ? error.message : 'Failed to get products' } } } async getProduct(productId: number): Promise<{ success: boolean; product?: Product; error?: string }> { try { return await this.callRpc<{ success: boolean; product?: Product; error?: string }>( 'get_product', { productId } ) } catch (error) { return { success: false, error: error instanceof Error ? error.message : 'Failed to get product' } } } async getCategories(): Promise<{ success: boolean; categories?: string[]; error?: string }> { try { return await this.callRpc<{ success: boolean; categories?: string[]; error?: string }>('get_categories') } catch (error) { return { success: false, error: error instanceof Error ? error.message : 'Failed to get categories' } } } async addToCart(productId: number, quantity = 1): Promise<{ success: boolean; message?: string; product?: Product; quantity?: number; error?: string }> { try { return await this.callRpc<{ success: boolean; message?: string; product?: Product; quantity?: number; error?: string }>( 'add_to_cart', { productId, quantity } ) } catch (error) { return { success: false, error: error instanceof Error ? error.message : 'Failed to add to cart' } } } async removeFromCart(productId: number): Promise<{ success: boolean; message?: string; error?: string }> { try { return await this.callRpc<{ success: boolean; message?: string; error?: string }>( 'remove_from_cart', { productId } ) } catch (error) { return { success: false, error: error instanceof Error ? error.message : 'Failed to remove from cart' } } } async getCart(): Promise<{ success: boolean; cart?: Cart; message?: string; error?: string }> { try { return await this.callRpc<{ success: boolean; cart?: Cart; message?: string; error?: string }>('get_cart') } catch (error) { return { success: false, error: error instanceof Error ? error.message : 'Failed to get cart' } } } async clearCart(): Promise<{ success: boolean; message?: string; error?: string }> { try { return await this.callRpc<{ success: boolean; message?: string; error?: string }>('clear_cart') } catch (error) { return { success: false, error: error instanceof Error ? error.message : 'Failed to clear cart' } } } getCurrentUser(): User | null { return this.currentUser } isAuthenticated(): boolean { return !!this.authToken && !!this.currentUser } } // Singleton instance export const mcpClient = new MCPClientManager()

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/Mithgroth/fakestore-mcp'

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