import { describe, expect, it } from "vitest"; import { MCP_HTTP_ACCEPT, mcpHttpRequestHeaders, parseMcpHttpResponseBody } from "../services/mcp-http.js"; describe("mcpHttpRequestHeaders", () => { it("advertises both JSON and SSE on every request", () => { expect(mcpHttpRequestHeaders()).toMatchObject({ "content-type": "application/json", accept: "application/json, text/event-stream", }); expect(MCP_HTTP_ACCEPT).toBe("application/json, text/event-stream"); }); it("preserves caller-supplied headers while keeping the required Accept value", () => { expect(mcpHttpRequestHeaders({ Authorization: "Bearer x", accept: "application/json" })).toMatchObject({ accept: "application/json, text/event-stream", Authorization: "Bearer x", }); }); }); describe("parseMcpHttpResponseBody", () => { it("parses a plain application/json body", () => { const payload = { jsonrpc: "2.0", id: "1", result: { tools: [] } }; expect(parseMcpHttpResponseBody(JSON.stringify(payload), "application/json")).toEqual(payload); }); it("parses an SSE-framed body, extracting the JSON-RPC message", () => { const payload = { jsonrpc: "2.0", id: "1", result: { tools: [{ name: "kv_get" }] } }; const body = `event: message\ndata: ${JSON.stringify(payload)}\n\n`; expect(parseMcpHttpResponseBody(body, "text/event-stream; charset=utf-8")).toEqual(payload); }); it("skips non-JSON-RPC SSE events and returns the response message", () => { const ping = "event: ping\ndata: {\"type\":\"ping\"}"; const message = { jsonrpc: "2.0", id: "1", result: { ok: true } }; const body = `${ping}\n\nevent: message\ndata: ${JSON.stringify(message)}\n\n`; expect(parseMcpHttpResponseBody(body, "text/event-stream")).toEqual(message); }); it("handles multi-line SSE data fields", () => { const payload = { jsonrpc: "2.0", id: "1", result: { note: "line" } }; const json = JSON.stringify(payload, null, 2); const body = `data: ${json.split("\n").join("\ndata: ")}\n\n`; expect(parseMcpHttpResponseBody(body, "text/event-stream")).toEqual(payload); }); it("throws when an SSE stream carries no data events", () => { expect(() => parseMcpHttpResponseBody("event: ping\n\n", "text/event-stream")).toThrow(); }); });