Skip to main content
Glama
websocket.test.ts4.06 kB
import { describe, it, expect, afterEach, beforeEach } from 'vitest'; import { WebSocket } from 'ws'; import { WebSocketServerTransport } from '../../src/server/transport/websocket'; import { JSONRPCMessage } from '@modelcontextprotocol/sdk/types.js'; describe('WebSocket Transport', () => { let transport: WebSocketServerTransport; let client: WebSocket; const PORT = 3002; // Use a different port for testing beforeEach(async () => { transport = new WebSocketServerTransport(PORT); await transport.start(); }); afterEach(async () => { if (client && client.readyState === WebSocket.OPEN) { client.close(); } await transport.close(); }); it('should accept connections and handle messages', async () => { return new Promise<void>((resolve, reject) => { client = new WebSocket(`ws://localhost:${PORT}`); client.on('open', async () => { try { // Send a message from client to server const message: JSONRPCMessage = { jsonrpc: '2.0', id: 1, method: 'ping', params: {} }; // Mock server handling transport.onmessage = (msg) => { try { expect(msg).toEqual(message); // Send response back transport.send({ jsonrpc: '2.0', id: 1, result: { message: 'pong' } }); } catch (e) { reject(e); } }; client.send(JSON.stringify(message)); } catch (e) { reject(e); } }); client.on('message', (data) => { try { const response = JSON.parse(data.toString()); expect(response).toEqual({ jsonrpc: '2.0', id: 1, result: { message: 'pong' } }); resolve(); } catch (e) { reject(e); } }); client.on('error', reject); }); }); it('should broadcast notifications to all clients', async () => { const client2 = new WebSocket(`ws://localhost:${PORT}`); client = new WebSocket(`ws://localhost:${PORT}`); const notification: JSONRPCMessage = { jsonrpc: '2.0', method: 'notifications/test', params: { data: 'hello' } }; const waitForNotification = (ws: WebSocket) => { return new Promise<void>((resolve, reject) => { ws.on('message', (data) => { try { const msg = JSON.parse(data.toString()); expect(msg).toEqual(notification); resolve(); } catch (e) { reject(e); } }); }); }; await new Promise<void>((resolve) => { let connected = 0; const checkConnected = () => { connected++; if (connected === 2) resolve(); }; if (client.readyState === WebSocket.OPEN) checkConnected(); else client.on('open', checkConnected); if (client2.readyState === WebSocket.OPEN) checkConnected(); else client2.on('open', checkConnected); }); const p1 = waitForNotification(client); const p2 = waitForNotification(client2); transport.broadcast(notification); await Promise.all([p1, p2]); client2.close(); }); });

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/Mnehmos/rpg-mcp'

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