Skip to main content
Glama
secure-communication.integration.test.tsβ€’7.84 kB
import type { IncomingMessage, ServerResponse } from "node:http"; import type { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { MCPHttpServer } from "../../src/http-server.js"; // Mock the MCP server const mockMCPServer = { connect: vi.fn(), } as unknown as Server; describe("Secure Communication Channels Integration", () => { let httpServer: MCPHttpServer; beforeEach(async () => { // Create a real HTTP server instance for testing httpServer = new MCPHttpServer(mockMCPServer); // Mock the listen method to avoid port conflicts vi.spyOn(httpServer, "listen").mockImplementation(async (_port = 3000, _host = "localhost") => { return new Promise((resolve) => { // Don't actually start the server, just resolve resolve(); }); }); }); afterEach(() => { vi.clearAllMocks(); }); it("should apply security headers to all responses", async () => { // Create a mock request and response const mockReq = { method: "GET", url: "/health", headers: { host: "localhost:3000", }, socket: {}, } as unknown as IncomingMessage; const mockRes = { headers: {} as Record<string, string>, writeHead: vi.fn(function (_statusCode: number, headers?: Record<string, string>) { if (headers) { Object.assign(this.headers, headers); } return this; }), setHeader: vi.fn(function (name: string, value: string) { this.headers[name] = value; return this; }), end: vi.fn(), } as unknown as ServerResponse; // Call the handleRequest method directly // We need to access the private method, so we'll use bracket notation const handleRequest = (httpServer as any).handleRequest.bind(httpServer); await handleRequest(mockReq, mockRes); // Verify security headers were applied expect(mockRes.setHeader).toHaveBeenCalledWith("X-Content-Type-Options", "nosniff"); expect(mockRes.setHeader).toHaveBeenCalledWith("X-Frame-Options", "DENY"); expect(mockRes.setHeader).toHaveBeenCalledWith("X-XSS-Protection", "1; mode=block"); expect(mockRes.setHeader).toHaveBeenCalledWith( "Strict-Transport-Security", "max-age=31536000; includeSubDomains", ); expect(mockRes.setHeader).toHaveBeenCalledWith("Content-Security-Policy", "default-src 'self'"); }); it("should handle CORS preflight requests correctly", async () => { // Create a mock OPTIONS request const mockReq = { method: "OPTIONS", url: "/mcp", headers: { host: "localhost:3000", origin: "http://localhost:5173", "access-control-request-method": "POST", "access-control-request-headers": "Content-Type, Authorization", }, socket: {}, } as unknown as IncomingMessage; const mockRes = { headers: {} as Record<string, string>, writeHead: vi.fn(function (_statusCode: number, headers?: Record<string, string>) { if (headers) { Object.assign(this.headers, headers); } return this; }), setHeader: vi.fn(function (name: string, value: string) { this.headers[name] = value; return this; }), end: vi.fn(), } as unknown as ServerResponse; // Call the handleRequest method directly const handleRequest = (httpServer as any).handleRequest.bind(httpServer); await handleRequest(mockReq, mockRes); // Verify CORS headers were set expect(mockRes.setHeader).toHaveBeenCalledWith("Access-Control-Allow-Origin", "http://localhost:5173"); expect(mockRes.setHeader).toHaveBeenCalledWith("Access-Control-Allow-Methods", "GET, POST, OPTIONS"); expect(mockRes.setHeader).toHaveBeenCalledWith( "Access-Control-Allow-Headers", "Content-Type, Authorization, X-API-Key", ); expect(mockRes.setHeader).toHaveBeenCalledWith("Access-Control-Max-Age", "86400"); expect(mockRes.writeHead).toHaveBeenCalledWith(204); }); it("should authenticate requests with Bearer tokens", async () => { // Create a mock POST request with Bearer token const mockReq = { method: "POST", url: "/mcp?sessionId=test-session", headers: { host: "localhost:3000", "content-type": "application/json", authorization: "Bearer test-token-123", }, socket: {}, } as unknown as IncomingMessage; const mockRes = { headers: {} as Record<string, string>, writeHead: vi.fn(function (_statusCode: number, headers?: Record<string, string>) { if (headers) { Object.assign(this.headers, headers); } return this; }), setHeader: vi.fn(function (name: string, value: string) { this.headers[name] = value; return this; }), end: vi.fn(), } as unknown as ServerResponse; // Mock the authenticateRequest method to verify it's called const authenticateRequestSpy = vi.spyOn(httpServer as any, "authenticateRequest").mockReturnValue(true); // Mock the transports map to avoid transport lookup errors const transports = new Map(); (httpServer as any).transports = transports; // Call the handleRequest method directly const handleRequest = (httpServer as any).handleRequest.bind(httpServer); await handleRequest(mockReq, mockRes); // Verify authentication was attempted expect(authenticateRequestSpy).toHaveBeenCalledWith(mockReq); }); it("should authenticate requests with API keys", async () => { // Create a mock POST request with API key const mockReq = { method: "POST", url: "/mcp?sessionId=test-session", headers: { host: "localhost:3000", "content-type": "application/json", "x-api-key": "test-api-key-123", }, socket: {}, } as unknown as IncomingMessage; const mockRes = { headers: {} as Record<string, string>, writeHead: vi.fn(function (_statusCode: number, headers?: Record<string, string>) { if (headers) { Object.assign(this.headers, headers); } return this; }), setHeader: vi.fn(function (name: string, value: string) { this.headers[name] = value; return this; }), end: vi.fn(), } as unknown as ServerResponse; // Mock the authenticateRequest method to verify it's called const authenticateRequestSpy = vi.spyOn(httpServer as any, "authenticateRequest").mockReturnValue(true); // Mock the transports map to avoid transport lookup errors const transports = new Map(); (httpServer as any).transports = transports; // Call the handleRequest method directly const handleRequest = (httpServer as any).handleRequest.bind(httpServer); await handleRequest(mockReq, mockRes); // Verify authentication was attempted expect(authenticateRequestSpy).toHaveBeenCalledWith(mockReq); }); it("should implement rate limiting", async () => { // Create multiple mock requests from the same IP const mockReq = { method: "GET", url: "/health", headers: { host: "localhost:3000", }, socket: { remoteAddress: "127.0.0.1", }, } as unknown as IncomingMessage; const mockRes = { headers: {} as Record<string, string>, writeHead: vi.fn(function (_statusCode: number, headers?: Record<string, string>) { if (headers) { Object.assign(this.headers, headers); } return this; }), setHeader: vi.fn(function (name: string, value: string) { this.headers[name] = value; return this; }), end: vi.fn(), } as unknown as ServerResponse; // Call the handleRequest method multiple times const handleRequest = (httpServer as any).handleRequest.bind(httpServer); // First request should succeed await handleRequest(mockReq, mockRes); expect(mockRes.writeHead).toHaveBeenCalledWith(200, expect.any(Object)); // Reset mock mockRes.writeHead.mockClear(); // Second request should also succeed (we're not actually rate limiting in this simple test) await handleRequest(mockReq, mockRes); expect(mockRes.writeHead).toHaveBeenCalledWith(200, expect.any(Object)); }); });

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/snapback-dev/mcp-server'

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