import { describe, expect, it } from "bun:test"; import express, { type Request } from "express"; import { mkdtemp, rm } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { config } from "../../src/config.js"; import { attachTrustedAgentContext, getLocalAgentContext, ProductContextError } from "../../src/context/localContext.js"; import { registerMcpPolicyBridge, registerMcpStatusRoutes } from "../../src/routes/mcpRoutes.js"; import { removeRuntimeSessionContext, setRuntimeSessionContext } from "../../src/runtime/sessionContext.js"; import { SessionMetadataStore } from "../../src/sessions/metadataStore.js"; describe("MCP routes", () => { it("protects the internal policy bridge against browser and context injection", async () => { const app = express(); app.use(express.json()); let builds = 0; registerMcpPolicyBridge(app, { internalToken: "MCP_TEST_ONLY", runtime: { mcpReadonlyTools: () => { builds++; return ["mcp_fixture_read"]; } } }); const server = app.listen(0, "127.0.0.1"); await new Promise((resolve) => server.once("listening", resolve)); const url = `http://127.0.0.1:${(server.address() as { port: number }).port}/internal/mcp/session-policy`; const sessionID = "mcp-route-test"; setRuntimeSessionContext({ sessionId: sessionID, clientSessionId: sessionID, actorKey: "PRIVATE_ACTOR", projectKey: "PRIVATE_PROJECT", traceId: "test", purpose: "task_execution" }); const post = (body: unknown, headers: Record = {}) => fetch(url, { method: "POST", headers: { "Content-Type": "application/json", "x-agent-internal-token": "MCP_TEST_ONLY", ...headers }, body: JSON.stringify(body) }); try { expect((await post({ session_id: sessionID }, { "x-agent-internal-token": "wrong" })).status).toBe(403); expect((await post({ session_id: sessionID }, { Origin: "https://browser" })).status).toBe(403); expect((await post({ session_id: sessionID }, { "Sec-Fetch-Site": "same-origin" })).status).toBe(403); expect((await post({ session_id: sessionID, project_id: "other" })).status).toBe(400); expect((await post({ session_id: "missing" })).status).toBe(404); expect(await (await post({ session_id: sessionID })).json()).toEqual({ mode: "readonly", readonly_tools: ["mcp_fixture_read"], query_tools: [] }); expect(builds).toBe(1); } finally { removeRuntimeSessionContext(sessionID); await new Promise((resolve) => server.close(() => resolve())); } }); it("requires verified session ownership and returns constant errors without credentials", async () => { const originalFetch = globalThis.fetch; const previousEnv = config.NODE_ENV; const root = await mkdtemp(join(tmpdir(), "mcp-status-test-")); const store = new SessionMetadataStore(root); const app = express(); let calls = 0; let failed = false; globalThis.fetch = (async (input: Parameters[0], init: Parameters[1]) => { if (String(input).endsWith("/api/v1/agent-auth-context")) { const headers = new Headers(init?.headers); return Response.json({ user_id: headers.get("Authorization") === "Bearer OWNER" ? "owner" : "other", project_id: headers.get("X-Project-Id"), network: "supply" }); } return originalFetch(input, init); }) as typeof fetch; config.NODE_ENV = "production"; const owner = { header: (name: string) => ({ authorization: "Bearer OWNER", "x-project-id": "project" })[name.toLowerCase() as "authorization" | "x-project-id"] } as Request; await attachTrustedAgentContext(owner); await store.ensure({ ...getLocalAgentContext(owner), sessionId: "private-session" }); const router = express.Router(); router.use(async (req, res, next) => { try { await attachTrustedAgentContext(req); next(); } catch (error) { res.status(error instanceof ProductContextError ? error.status : 503).json({ message: "authentication failed" }); } }); registerMcpStatusRoutes(router, { sessionMetadataStore: store, runtime: { mcpStatus: async () => { calls++; if (failed) throw new Error("SECRET_URL_AND_TOKEN"); return { configuration_errors: [], servers: [{ name: "mcp_fixture", type: "remote", status: "needs_auth", configured_protocol: "auto", tools: [] }] }; } } }); app.use("/api/v1", router); const server = app.listen(0, "127.0.0.1"); await new Promise((resolve) => server.once("listening", resolve)); const url = `http://127.0.0.1:${(server.address() as { port: number }).port}/api/v1/session/private-session/mcp`; try { expect((await originalFetch(url)).status).toBe(401); const headers = { Authorization: "Bearer OWNER", "X-Project-Id": "project" }; expect((await originalFetch(url, { headers: { ...headers, Authorization: "Bearer OTHER" } })).status).toBe(404); expect((await originalFetch(url, { headers: { ...headers, "X-Project-Id": "other" } })).status).toBe(404); expect(calls).toBe(0); expect(await (await originalFetch(url, { headers })).json()).toEqual({ servers: [{ name: "mcp_fixture", type: "remote", status: "needs_auth", configured_protocol: "auto", tools: [] }] }); failed = true; const error = await originalFetch(url, { headers }); expect(error.status).toBe(503); expect(await error.json()).toEqual({ message: "MCP runtime unavailable" }); } finally { globalThis.fetch = originalFetch; config.NODE_ENV = previousEnv; await new Promise((resolve) => server.close(() => resolve())); await rm(root, { recursive: true }); } }); });