Skip to main content
Glama
http-transport.ts3.11 kB
import { Transport } from './transport.js'; import { JSONRPCMessage, JSONRPCRequest } from '@modelcontextprotocol/sdk/types.js'; import { Request, Response } from 'express'; import { z } from 'zod'; /** * HTTP transport implementation for MCP servers */ export class HTTPServerTransport implements Transport { private messageHandlers: ((message: JSONRPCMessage) => void)[] = []; private errorHandlers: ((error: Error) => void)[] = []; private closeHandlers: (() => void)[] = []; private running: boolean = false; constructor() { // Initialize without dependencies } async start(): Promise<void> { if (this.running) { return; } this.running = true; } async stop(): Promise<void> { if (!this.running) { return; } this.running = false; } async send(message: JSONRPCMessage): Promise<void> { if (!this.running) { throw new Error('Transport not running'); } // Messages are sent via handleRequest } isRunning(): boolean { return this.running; } on(type: 'message', handler: (message: JSONRPCMessage) => void): void; on(type: 'error', handler: (error: Error) => void): void; on(type: 'close', handler: (code?: number) => void): void; on(type: string, handler: (...args: any[]) => void): void { switch (type) { case 'message': this.messageHandlers.push(handler as (message: JSONRPCMessage) => void); break; case 'error': this.errorHandlers.push(handler as (error: Error) => void); break; case 'close': this.closeHandlers.push(handler as () => void); break; } } removeListener(type: 'message', handler: (message: JSONRPCMessage) => void): void; removeListener(type: 'error', handler: (error: Error) => void): void; removeListener(type: 'close', handler: (code?: number) => void): void; removeListener(type: string, handler: (...args: any[]) => void): void { switch (type) { case 'message': this.messageHandlers = this.messageHandlers.filter(h => h !== handler); break; case 'error': this.errorHandlers = this.errorHandlers.filter(h => h !== handler); break; case 'close': this.closeHandlers = this.closeHandlers.filter(h => h !== handler); break; } } async close(): Promise<void> { await this.stop(); } /** * Handle an HTTP request */ async handleRequest(req: Request, res: Response): Promise<void> { try { const message = req.body as JSONRPCRequest; this.messageHandlers.forEach(handler => handler(message)); // Let the message handlers process the request // The response will be sent by the server res.json({ jsonrpc: '2.0', result: null, id: message.id || null, }); } catch (error) { const err = error as Error; this.errorHandlers.forEach(handler => handler(err)); res.status(500).json({ jsonrpc: '2.0', error: { code: -32000, message: err.message, }, id: null, }); } } }

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/metcalfc/atrax'

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