Skip to main content
Glama
proxyServer.test.ts4.88 kB
import { Client } from "@modelcontextprotocol/sdk/client/index.js"; import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js"; import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js"; import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { McpError } from "@modelcontextprotocol/sdk/types.js"; import { EventSource } from "eventsource"; import { getRandomPort } from "get-port-please"; import { describe, expect, it } from "vitest"; import { proxyServer } from "./proxyServer.js"; import { startHTTPServer } from "./startHTTPServer.js"; if (!("EventSource" in global)) { // @ts-expect-error - figure out how to use --experimental-eventsource with vitest global.EventSource = EventSource; } interface TestConfig { requestTimeout?: number; serverDelay?: string; serverFixture?: string; } interface TestEnvironment { cleanup: () => Promise<void>; httpServer: { close: () => Promise<void> }; stdioClient: Client; streamClient: Client; } async function createTestEnvironment( config: TestConfig = {}, ): Promise<TestEnvironment> { const { requestTimeout, serverDelay, serverFixture = "simple-stdio-server.ts", } = config; const stdioTransport = new StdioClientTransport({ args: [`src/fixtures/${serverFixture}`], command: "tsx", env: serverDelay ? ({ ...process.env, RESPONSE_DELAY: serverDelay } as Record< string, string >) : (process.env as Record<string, string>), }); const stdioClient = new Client( { name: "mcp-proxy-test", version: "1.0.0" }, { capabilities: {} }, ); await stdioClient.connect(stdioTransport); const serverVersion = stdioClient.getServerVersion() as { name: string; version: string; }; const serverCapabilities = stdioClient.getServerCapabilities() as { capabilities: Record<string, unknown>; }; const port = await getRandomPort(); const httpServer = await startHTTPServer({ createServer: async () => { const mcpServer = new Server(serverVersion, { capabilities: serverCapabilities, }); await proxyServer({ client: stdioClient, requestTimeout, server: mcpServer, serverCapabilities, }); return mcpServer; }, port, }); const streamClient = new Client( { name: "stream-client", version: "1.0.0" }, { capabilities: {} }, ); const transport = new StreamableHTTPClientTransport( new URL(`http://localhost:${port}/mcp`), ); await streamClient.connect(transport); return { cleanup: async () => { await streamClient.close(); await stdioClient.close(); }, httpServer, stdioClient, streamClient, }; } describe("proxyServer timeout functionality", () => { it("should respect custom timeout settings", async () => { const { cleanup, streamClient } = await createTestEnvironment({ requestTimeout: 1000, serverDelay: "500", serverFixture: "slow-stdio-server.ts", }); // This should succeed as timeout (1s) > delay (500ms) const result = await streamClient.listResources(); expect(result.resources).toHaveLength(1); expect(result.resources[0].name).toBe("Slow Resource"); await cleanup(); }, 10000); it("should timeout when request takes longer than configured timeout", async () => { const { cleanup, streamClient } = await createTestEnvironment({ requestTimeout: 500, serverDelay: "1000", serverFixture: "slow-stdio-server.ts", }); // This should throw a timeout error as delay (1s) > timeout (500ms) await expect(streamClient.listResources()).rejects.toThrow(McpError); await cleanup(); }, 10000); it("should use default SDK timeout when no custom timeout is provided", async () => { const { cleanup, streamClient } = await createTestEnvironment(); // This should succeed with default timeout const result = await streamClient.listResources(); expect(result.resources).toBeDefined(); await cleanup(); }, 10000); it("should handle resource reads with custom timeout", async () => { const { cleanup, streamClient } = await createTestEnvironment({ requestTimeout: 600, serverDelay: "300", serverFixture: "slow-stdio-server.ts", }); // First get the resources const resources = await streamClient.listResources(); expect(resources.resources).toHaveLength(1); // Resource read should succeed as timeout (600ms) > delay (300ms) const resourceContent = await streamClient.readResource({ uri: resources.resources[0].uri, }); expect(resourceContent.contents).toBeDefined(); expect((resourceContent.contents[0] as { text: string }).text).toContain( "300ms delay", ); await cleanup(); }, 10000); });

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/Valerio357/bet-mcp'

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