Skip to main content
Glama

Streamable HTTP Bridge

by masx200
Mulan Permissive Software License, Version 2
2
  • Linux
  • Apple
WebSocketClientTransport.js4.16 kB
import { JSONRPCMessageSchema, } from "@modelcontextprotocol/sdk/types.js"; import { WebSocket } from "ws"; const SUBPROTOCOL = "mcp"; /** * Client transport for WebSocket: this will connect to a server over the WebSocket protocol. */ export class WebSocketClientTransport { url; options; _socket; _url; //这里不能先设定sessionId,否则会影响初始化 sessionId; onclose; onerror; //@ts-ignore onmessage; constructor(url, options) { this.url = url; this.options = options; this._url = url; } async start() { if (this._socket) { throw new Error("WebSocketClientTransport already started! If using Client class, note that connect() calls start() automatically."); } return new Promise((resolve, reject) => { this._socket = new WebSocket(this._url, this.options?.protocols ?? SUBPROTOCOL, this.options); this._socket.onerror = (event) => { const error = "error" in event ? event.error : new Error(`WebSocket error: ${JSON.stringify(event)}`); reject(error); this.onerror?.(error); this.options?.onError?.(error); }; this._socket.onopen = () => { //@ts-ignore this.options?.onOpen?.(this._socket); resolve(); }; this._socket.onclose = () => { this.onclose?.(); //@ts-ignore this.options?.onClose?.(this._socket); }; this._socket.onmessage = (event) => { console.log("WebSocketClientTransport message", event.data.toString()); try { if (typeof event.data !== "string") { throw new Error("WebSocket message must be a string"); } } catch (error) { this.onerror?.(error); this.options?.onError?.(error); return; } let message; try { message = Object.assign(JSONRPCMessageSchema.parse(JSON.parse(event.data))); // if ( // message?.sessionId !== undefined && // message?.sessionId !== this.sessionId // ) { // this.sessionId = message.sessionId; // } } catch (error) { console.error("WebSocketClientTransport message error", error); this.onerror?.(error); this.options?.onError?.(error); return; } this.options?.onMessage?.(message, { // sessionId: message.sessionId, //@ts-ignore requestInfo: { headers: this.options?.headers ?? {} }, }); this.onmessage?.(message, { // sessionId: message.sessionId, //@ts-ignore requestInfo: { headers: this.options?.headers ?? {} }, }); }; }); } async close() { this._socket?.close(); } send(message, options) { console.log("send WebSocketClientTransport", JSON.stringify(message, null, 4)); return new Promise((resolve, reject) => { if (!this._socket) { reject(new Error("Not connected")); return; } if (this._socket.readyState !== WebSocket.OPEN) { reject(new Error("WebSocket is not open")); return; } this._socket?.send(JSON.stringify(Object.assign(message, { // sessionId: options?.relatedRequestId ?? this.sessionId, }))); console.log("send WebSocketClientTransport", JSON.stringify(message, null, 4)); resolve(); }); } } //# sourceMappingURL=WebSocketClientTransport.js.map

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/masx200/mcp-demo-streamable-http-bridge'

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