Skip to main content
Glama
httpServer.test.ts4.2 kB
import type { AddressInfo } from "node:net"; import { startStreamableHttpServer, parseCliOptions, normalizeHttpPath } from "../index.js"; import os from "node:os"; const handleRequestMock = jest.fn( async (_req: unknown, res: any, _body?: unknown) => { if (!res.writableEnded) { res.writeHead(200).end("ok"); } } ); const startMock = jest.fn(); const closeTransportMock = jest.fn(); let lastSessionId = "mock-session"; jest.mock("@modelcontextprotocol/sdk/server/streamableHttp.js", () => ({ __esModule: true, StreamableHTTPServerTransport: class { sessionId?: string; onclose?: () => void; onerror?: (error: Error) => void; onmessage?: (message: unknown) => void; constructor(options: { sessionIdGenerator?: () => string; onsessioninitialized?: (sessionId: string) => void }) { lastSessionId = options.sessionIdGenerator?.() ?? "mock-session"; this.sessionId = lastSessionId; options.onsessioninitialized?.(this.sessionId); } async start() { startMock(); } async handleRequest(req: unknown, res: any, body?: unknown) { await handleRequestMock(req, res, body); if (!res.writableEnded) { res.writeHead(200).end("ok"); } } async close() { closeTransportMock(); this.onclose?.(); } async send() { // no-op for tests } }, })); const initializeRequest = { jsonrpc: "2.0", id: "1", method: "initialize", params: { protocolVersion: "2025-03-26", capabilities: {}, clientInfo: { name: "jest", version: "1.0.0", }, }, }; describe("CLI options", () => { test("uses defaults without flags", () => { expect(parseCliOptions([])).toEqual({ http: false, port: 8000, path: "/mcp", resourceTtlSeconds: 600, hostName: os.hostname(), insecure: false, listen: "0.0.0.0", staticUserAgent: false, }); }); test("parses http flags with normalization", () => { expect( parseCliOptions(["--http", "--port", "9001", "--path", "custom/"]) ).toEqual({ http: true, port: 9001, path: "/custom", resourceTtlSeconds: 600, hostName: os.hostname(), insecure: false, listen: "0.0.0.0", staticUserAgent: false, }); expect(normalizeHttpPath("/nested/path/")).toBe("/nested/path"); }); }); describe("Streamable HTTP server", () => { let cleanup: (() => Promise<void>) | null = null; beforeEach(() => { jest.clearAllMocks(); }); afterEach(async () => { jest.restoreAllMocks(); if (cleanup) { await cleanup(); cleanup = null; } }); test("accepts initialization and reuses the same session", async () => { const { server, close } = await startStreamableHttpServer({ port: 0, path: "/mcp", }); cleanup = close; const address = server.address() as AddressInfo; const baseUrl = `http://127.0.0.1:${address.port}`; const initResponse = await fetch(`${baseUrl}/mcp`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify(initializeRequest), }); expect(initResponse.status).toBe(200); expect(handleRequestMock).toHaveBeenCalledWith( expect.anything(), expect.anything(), initializeRequest ); handleRequestMock.mockClear(); const sessionId = lastSessionId; const getResponse = await fetch(`${baseUrl}/mcp`, { method: "GET", headers: { "mcp-session-id": sessionId }, }); expect(getResponse.status).toBe(200); expect(handleRequestMock).toHaveBeenCalledWith( expect.anything(), expect.anything(), undefined ); }); test("rejects requests without a session", async () => { const { server, close } = await startStreamableHttpServer({ port: 0, path: "/mcp", }); cleanup = close; const address = server.address() as AddressInfo; const baseUrl = `http://127.0.0.1:${address.port}`; const response = await fetch(`${baseUrl}/mcp`, { method: "GET" }); expect(response.status).toBe(400); expect(handleRequestMock).not.toHaveBeenCalled(); }); });

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/aakashH242/mcp-playwright'

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