Files
reverse-engineering-anything/tests/boundary/mcp/mcpHttpOptions.test.ts
T
Edgar ArakelyanandClaude Fable 5.1 46dd8f0e2b feat(mcp): serve the MCP server over streamable HTTP
Add rea mcp --http [--host] [--port]: the same server rea speaks over stdio,
served over MCP Streamable HTTP on a loopback listener by default, using the
SDK's web-standard transport already in the pinned @modelcontextprotocol/server
behind a small node:http bridge. One client and one session at a time; DELETE
ends the session without running provider teardown, a new client's initialize
replaces a session left open, foreign Host headers are refused on loopback
binds, and shutdown is signals-only. Stdio stays the default and registered
transport; server.json and client registrations are unchanged.

Refs morluto/rea#4933

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-17 21:05:10 -07:00

119 lines
4.3 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { parseMcpHttpEndpoint } from "../../../src/config/mcpHttpEndpoint.js";
import { projectAnalysisError } from "../../../src/domain/analysisErrorProjection.js";
import { runMcpHttpEntrypoint } from "../../../src/main.js";
import {
parseMcpHttpArguments,
renderMcpHttpHelp,
} from "../../../src/main/mcpHttpArguments.js";
describe("rea mcp --http arguments", () => {
it("accepts --http with optional host and port in either flag spelling", () => {
expect(parseMcpHttpArguments(["--http"])).toEqual({ ok: true });
expect(
parseMcpHttpArguments(["--http", "--host", "::1", "--port=8080"]),
).toEqual({ ok: true, host: "::1", port: 8080 });
expect(parseMcpHttpArguments(["--port", "0", "--http"])).toEqual({
ok: true,
port: 0,
});
});
it("answers help only in flag position and names the rejected argument", () => {
expect(parseMcpHttpArguments(["--http", "-h"])).toEqual({
ok: false,
help: true,
});
expect(parseMcpHttpArguments(["--http", "--host", "--help"])).toEqual({
ok: false,
help: false,
message: "Missing value for --host",
});
expect(parseMcpHttpArguments(["--http", "add"])).toMatchObject({
ok: false,
message: "Unknown mcp --http argument: add",
});
expect(parseMcpHttpArguments(["--port", "1"])).toMatchObject({
ok: false,
message: "--host and --port require --http",
});
for (const port of ["70000", "08", "-1", "http"])
expect(parseMcpHttpArguments(["--http", `--port=${port}`])).toMatchObject(
{ ok: false, message: expect.stringContaining("Invalid --port") },
);
expect(parseMcpHttpArguments(["--http", "--host", " "])).toMatchObject({
ok: false,
message: expect.stringContaining("--host must be"),
});
});
it("renders help from the option schema without Incur global options", () => {
const help = renderMcpHttpHelp();
expect(help).toContain("rea mcp --http");
expect(help).toContain("--host");
expect(help).toContain("--port");
expect(help).toContain("MCP_PORT");
expect(help).not.toContain("--filter-output");
});
it("writes help as one newline-terminated stdout block and rejections to stderr", async () => {
const io = () => {
const stdout: string[] = [];
const stderr: string[] = [];
const exitCodes: number[] = [];
return {
stdout,
stderr,
exitCodes,
writeStdout: (text: string) => void stdout.push(text),
writeStderr: (text: string) => void stderr.push(text),
setExitCode: (code: number) => void exitCodes.push(code),
};
};
const help = io();
await runMcpHttpEntrypoint(["--http", "--help"], help);
expect(help.stdout).toEqual([`${renderMcpHttpHelp()}\n`]);
expect(help.stderr).toEqual([]);
expect(help.exitCodes).toEqual([0]);
const rejected = io();
await runMcpHttpEntrypoint(["--http", "add"], rejected);
expect(rejected.stdout).toEqual([]);
expect(rejected.stderr).toEqual(["Unknown mcp --http argument: add\n"]);
expect(rejected.exitCodes).toEqual([1]);
});
});
describe("MCP_HOST and MCP_PORT", () => {
it("defaults to loopback and an ephemeral port", () => {
expect(parseMcpHttpEndpoint({})).toEqual({
ok: true,
value: { host: "127.0.0.1", port: 0 },
});
});
it("reads the environment snapshot and lets explicit values win", () => {
expect(
parseMcpHttpEndpoint({ MCP_HOST: "192.0.2.10", MCP_PORT: "8080" }),
).toEqual({ ok: true, value: { host: "192.0.2.10", port: 8080 } });
expect(
parseMcpHttpEndpoint(
{ MCP_HOST: " ", MCP_PORT: "nope" },
{ host: "::1", port: 1 },
),
).toEqual({ ok: true, value: { host: "::1", port: 1 } });
});
it("rejects malformed values by setting name without echoing them", () => {
const result = parseMcpHttpEndpoint({ MCP_HOST: " ", MCP_PORT: "65536" });
if (result.ok) throw new Error("Expected a configuration error");
expect(result.error.settings.map(({ setting }) => setting)).toEqual([
"MCP_HOST",
"MCP_PORT",
]);
const projected = JSON.stringify(projectAnalysisError(result.error));
expect(projected).toContain("MCP_PORT must be a decimal integer");
expect(projected).not.toContain("65536");
});
});