@quantakrypto/mcp
Advanced tools
+1
-1
@@ -183,3 +183,3 @@ #!/usr/bin/env node | ||
| const header = (authorizationHeader ?? "").trim(); | ||
| const match = /^Bearer\s+(.+)$/i.exec(header); | ||
| const match = /^Bearer\s+(\S.*)$/i.exec(header); | ||
| const presented = match?.[1]?.trim(); | ||
@@ -186,0 +186,0 @@ if (!presented) { |
+1
-1
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n/**\n * quantakrypto MCP — hostable HTTP transport (Streamable-HTTP-style JSON-RPC).\n *\n * A zero-dependency {@link node:http} server that exposes the same\n * {@link McpServer} over HTTP so the quantakrypto MCP can run as a remote service:\n *\n * POST /mcp — body is a single JSON-RPC 2.0 message; the JSON-RPC\n * response is returned as the 200 response body\n * (`application/json`). Notifications get HTTP 202 with no body.\n * GET /health — liveness probe, returns `{ status: \"ok\", ... }`.\n *\n * This is the minimal-but-working core of the MCP Streamable HTTP transport.\n * The full spec also supports an SSE response (`text/event-stream`) for\n * server-initiated messages; this server speaks the JSON request/response half,\n * which is sufficient for stateless tool calls. See HOSTING.md for the\n * production design (auth, multi-tenant sessions, rate limiting, scaling).\n *\n * SAFE-BY-DEFAULT POSTURE (P0-1). Unlike the stdio transport — which trusts the\n * local user and stays fully featured — the HTTP transport is hardened because a\n * hosted endpoint is reachable by untrusted peers:\n *\n * - Binds to 127.0.0.1 by default (NOT 0.0.0.0). Override with QUANTAKRYPTO_MCP_HOST.\n * - Bearer-token auth: when QUANTAKRYPTO_MCP_TOKEN is set, every /mcp request must\n * send `Authorization: Bearer <token>` (else 401). Binding to a non-loopback\n * host WITHOUT a token is refused at startup (it would be an open relay).\n * - The filesystem tools (scan_path, inventory_crypto, generate_cbom) read\n * arbitrary server paths and are DISABLED over HTTP unless QUANTAKRYPTO_MCP_ALLOW_FS=1\n * (security audit Q-01). The networked probe_endpoint tool is likewise DISABLED\n * over HTTP unless QUANTAKRYPTO_MCP_ALLOW_NETWORK=1 (a hosted server should not\n * probe arbitrary hosts). The knowledge tools (explain_finding, suggest_hybrid,\n * list_rules) are always available. Gating is enforced by registering only the\n * permitted tools, so tools/list and tools/call both reflect it.\n * - Per-request timeout (QUANTAKRYPTO_MCP_TIMEOUT_MS) and a response-size cap\n * (QUANTAKRYPTO_MCP_MAX_RESPONSE_BYTES), in addition to the 1 MiB request-body cap.\n *\n * Run with `node dist/http.js` (PORT/QUANTAKRYPTO_MCP_* from env).\n */\n\nimport { createServer } from \"node:http\";\nimport type { IncomingMessage, Server, ServerResponse } from \"node:http\";\nimport { createHash, randomUUID, timingSafeEqual } from \"node:crypto\";\nimport { realpathSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\nimport process from \"node:process\";\n\nimport { createQuantakryptoServer } from \"./index.js\";\nimport { ErrorCode, makeFailure } from \"./protocol.js\";\nimport type { JsonRpcResponse, ToolDefinition } from \"./protocol.js\";\nimport { quantakryptoTools, FS_TOOL_NAMES, NETWORK_TOOL_NAMES } from \"./tools.js\";\nimport type { McpServer } from \"./server.js\";\n\n/** Header carrying the MCP session id (per the Streamable HTTP transport). */\nconst SESSION_HEADER = \"mcp-session-id\";\n\n/** Maximum accepted request body size (1 MiB) — a basic abuse guard. */\nconst MAX_BODY_BYTES = 1024 * 1024;\n\n/** Default per-request tool-execution deadline (ms). */\nconst DEFAULT_TIMEOUT_MS = 30_000;\n\n/** Default cap on the serialized response body (4 MiB). */\nconst DEFAULT_MAX_RESPONSE_BYTES = 4 * 1024 * 1024;\n\n/** Loopback hosts that are safe to bind without authentication. */\nconst LOOPBACK_HOSTS = new Set([\"127.0.0.1\", \"::1\", \"localhost\"]);\n\ninterface HttpServerOptions {\n /** Port to listen on. Defaults to env PORT or 3000. */\n port?: number;\n /** Host/interface to bind. Defaults to QUANTAKRYPTO_MCP_HOST / HOST or \"127.0.0.1\". */\n host?: string;\n /** Bearer token required on /mcp. Defaults to QUANTAKRYPTO_MCP_TOKEN (empty = none). */\n token?: string;\n /** Expose the filesystem tools over HTTP. Defaults to QUANTAKRYPTO_MCP_ALLOW_FS=1. */\n allowFs?: boolean;\n /**\n * Expose the networked probe_endpoint tool over HTTP. Off by default (a hosted\n * server should not probe arbitrary hosts); enable only on a trusted deployment.\n * Defaults to QUANTAKRYPTO_MCP_ALLOW_NETWORK=1.\n */\n allowNetwork?: boolean;\n /** Per-request tool-execution timeout (ms). Defaults to QUANTAKRYPTO_MCP_TIMEOUT_MS. */\n timeoutMs?: number;\n /** Response-body size cap (bytes). Defaults to QUANTAKRYPTO_MCP_MAX_RESPONSE_BYTES. */\n maxResponseBytes?: number;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Pure policy (P0-1) — host/auth/tool-gating decisions, fully unit-testable. */\n/* -------------------------------------------------------------------------- */\n\n/** A minimal env shape so the config resolver is pure and testable. */\ntype HttpEnv = Record<string, string | undefined>;\n\n/** Resolved, validated HTTP transport configuration. */\ninterface HttpConfig {\n host: string;\n port: number;\n /** The bearer token, or \"\" when auth is disabled. */\n token: string;\n /** Whether the filesystem tools are exposed over HTTP. */\n allowFs: boolean;\n /** Whether the networked probe_endpoint tool is exposed over HTTP (default off). */\n allowNetwork: boolean;\n timeoutMs: number;\n maxResponseBytes: number;\n /** True when the host is a loopback interface (safe without auth). */\n loopback: boolean;\n /**\n * Extra origin hosts to allow on `POST /mcp` (lower-cased hostnames), beyond\n * the implicit loopback set and the bind host. From QUANTAKRYPTO_MCP_ALLOW_ORIGIN.\n */\n allowedOrigins: string[];\n}\n\n/**\n * Resolve the HTTP transport config from env + explicit overrides. Pure: does\n * no I/O and never reads `process` directly. Overrides win over env.\n */\nexport function resolveHttpConfig(env: HttpEnv, options: HttpServerOptions = {}): HttpConfig {\n const host = options.host ?? env.QUANTAKRYPTO_MCP_HOST ?? env.HOST ?? \"127.0.0.1\";\n const port = options.port ?? toInt(env.PORT, 3000);\n const token = (options.token ?? env.QUANTAKRYPTO_MCP_TOKEN ?? \"\").trim();\n const allowFs =\n options.allowFs ??\n (env.QUANTAKRYPTO_MCP_ALLOW_FS === \"1\" || env.QUANTAKRYPTO_MCP_ALLOW_FS === \"true\");\n const allowNetwork =\n options.allowNetwork ??\n (env.QUANTAKRYPTO_MCP_ALLOW_NETWORK === \"1\" || env.QUANTAKRYPTO_MCP_ALLOW_NETWORK === \"true\");\n const timeoutMs = options.timeoutMs ?? toInt(env.QUANTAKRYPTO_MCP_TIMEOUT_MS, DEFAULT_TIMEOUT_MS);\n const maxResponseBytes =\n options.maxResponseBytes ??\n toInt(env.QUANTAKRYPTO_MCP_MAX_RESPONSE_BYTES, DEFAULT_MAX_RESPONSE_BYTES);\n const allowedOrigins = parseOriginList(env.QUANTAKRYPTO_MCP_ALLOW_ORIGIN);\n return {\n host,\n port,\n token,\n allowFs,\n allowNetwork,\n timeoutMs,\n maxResponseBytes,\n loopback: isLoopbackHost(host),\n allowedOrigins,\n };\n}\n\n/**\n * Parse the comma-separated origin allow-list into lower-cased hostnames. Each\n * entry may be a bare host or a full origin URL; either way only the hostname is\n * retained (the value compared against `new URL(Origin).hostname`).\n */\nfunction parseOriginList(value: string | undefined): string[] {\n const out = new Set<string>();\n for (const raw of (value ?? \"\").split(\",\")) {\n const entry = raw.trim().toLowerCase();\n if (entry.length === 0) continue;\n try {\n out.add(new URL(entry).hostname);\n } catch {\n out.add(entry); // bare hostname (no scheme).\n }\n }\n return [...out];\n}\n\n/** Parse a positive integer from an env string, falling back on bad input. */\nfunction toInt(value: string | undefined, fallback: number): number {\n if (value === undefined) return fallback;\n const n = Number(value);\n return Number.isFinite(n) && n > 0 ? Math.floor(n) : fallback;\n}\n\n/** True when binding to `host` keeps the server private to this machine. */\nexport function isLoopbackHost(host: string): boolean {\n return LOOPBACK_HOSTS.has(host.trim().toLowerCase());\n}\n\n/**\n * Decide whether a non-loopback bind is permitted. A server reachable from the\n * network MUST require auth; binding wide-open without a token would be an open,\n * unauthenticated arbitrary-tool relay. Pure decision used at startup.\n */\nexport function startupDecision(config: HttpConfig): {\n ok: boolean;\n reason?: string;\n} {\n if (!config.loopback && config.token.length === 0) {\n return {\n ok: false,\n reason:\n `refusing to bind to non-loopback host \"${config.host}\" without a token. ` +\n `Set QUANTAKRYPTO_MCP_TOKEN to require Bearer auth, or bind to 127.0.0.1.`,\n };\n }\n return { ok: true };\n}\n\n/**\n * Decide whether a request's `Origin` / `Host` is acceptable, to defend the\n * default no-token loopback config against DNS-rebinding and localhost-CSRF: a\n * malicious web page can POST to `http://127.0.0.1:<port>/mcp`, but the browser\n * stamps a foreign `Origin` we can reject. Pure and testable.\n *\n * Policy:\n * - No `Origin` header (curl, a native MCP client, same-origin GET) → allow;\n * the header is a browser artifact and absence is not an attack signal here.\n * - An `Origin` present → its host must be a configured loopback host (or a\n * host explicitly added to the allow-list). A foreign origin is rejected.\n * - When the server itself binds a non-loopback interface, a token is already\n * mandatory (see {@link startupDecision}); the loopback allow-list still\n * applies but auth is the primary control there.\n */\nexport function originDecision(\n allowedHosts: ReadonlySet<string>,\n originHeader: string | undefined,\n): { ok: boolean; reason?: string } {\n const origin = (originHeader ?? \"\").trim();\n if (origin.length === 0) return { ok: true }; // non-browser client; nothing to check.\n if (origin.toLowerCase() === \"null\") {\n return { ok: false, reason: \"opaque/null Origin is not allowed\" };\n }\n let host: string;\n try {\n host = new URL(origin).hostname.toLowerCase();\n } catch {\n return { ok: false, reason: \"malformed Origin header\" };\n }\n if (allowedHosts.has(host)) return { ok: true };\n return { ok: false, reason: `Origin host \"${host}\" is not in the allow-list` };\n}\n\n/** The hosts an `Origin` may name. Loopback by default, plus the bind host. */\nexport function allowedOriginHosts(config: HttpConfig): Set<string> {\n const hosts = new Set<string>([\"127.0.0.1\", \"::1\", \"localhost\"]);\n // Allow the interface the server is actually bound to (e.g. a LAN address with\n // a token), so a same-host browser client keeps working.\n hosts.add(config.host.trim().toLowerCase());\n for (const extra of config.allowedOrigins) hosts.add(extra);\n return hosts;\n}\n\n/** A request-authorization outcome. */\ninterface AuthDecision {\n authorized: boolean;\n /** HTTP status to use when not authorized. */\n status?: number;\n message?: string;\n}\n\n/**\n * Decide whether a request is authorized given the configured token and the\n * incoming Authorization header. When no token is configured, all requests are\n * allowed (the loopback / trusted-edge case). Pure and testable.\n */\nexport function authorizeRequest(\n token: string,\n authorizationHeader: string | undefined,\n): AuthDecision {\n if (token.length === 0) return { authorized: true };\n const header = (authorizationHeader ?? \"\").trim();\n const match = /^Bearer\\s+(.+)$/i.exec(header);\n const presented = match?.[1]?.trim();\n if (!presented) {\n return { authorized: false, status: 401, message: \"missing bearer token\" };\n }\n if (!timingSafeEqualStr(presented, token)) {\n return { authorized: false, status: 401, message: \"invalid bearer token\" };\n }\n return { authorized: true };\n}\n\n/**\n * Constant-time string compare. Both inputs are hashed with the same algorithm\n * to fixed-length digests before {@link timingSafeEqual}, so the comparison runs\n * over equal-length buffers and the early length-mismatch return (which leaked\n * the configured token's length) is gone. The hashing is a domain-separation /\n * length-equalization step, not a secrecy measure: `timingSafeEqual` still does\n * the constant-time work and rejects unequal digests.\n */\nexport function timingSafeEqualStr(a: string, b: string): boolean {\n const ha = createHash(\"sha256\").update(a, \"utf8\").digest();\n const hb = createHash(\"sha256\").update(b, \"utf8\").digest();\n // Same algorithm ⇒ identical digest length ⇒ timingSafeEqual never throws.\n return timingSafeEqual(ha, hb);\n}\n\n/**\n * Select the tools to expose over HTTP for a given policy. The knowledge tools\n * are always returned; the filesystem tools are included only when `allowFs` is\n * true, and the networked probe tool only when `allowNetwork` is true (both off by\n * default). Pure function of its inputs — the single source of truth for HTTP tool\n * gating, so tools/list and tools/call stay consistent.\n */\nexport function gateHttpTools(\n tools: readonly ToolDefinition[],\n allowFs: boolean,\n allowNetwork = false,\n): ToolDefinition[] {\n const fsNames = new Set(FS_TOOL_NAMES);\n const networkNames = new Set(NETWORK_TOOL_NAMES);\n return tools.filter(\n (t) =>\n (allowNetwork || !networkNames.has(t.name)) && // networked tools: opt-in on HTTP\n (allowFs || !fsNames.has(t.name)), // fs tools: opt-in on HTTP\n );\n}\n\n/* -------------------------------------------------------------------------- */\n/* HTTP plumbing */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Error thrown by {@link readBody} when the request body exceeds the size cap.\n * Distinguished from a transport/I/O error so the caller can map it to HTTP 413\n * specifically, while genuine read failures map to 400/500 (M1).\n */\nexport class BodyTooLargeError extends Error {\n override readonly name = \"BodyTooLargeError\";\n constructor(message = \"request body too large\") {\n super(message);\n }\n}\n\n/**\n * Read a request body fully, enforcing the size cap. Resolves to the raw string.\n * Rejects with a {@link BodyTooLargeError} when the cap is exceeded, and with the\n * original transport error (an I/O failure) otherwise — the two are mapped to\n * different HTTP statuses by the caller (M1).\n */\nfunction readBody(req: IncomingMessage): Promise<string> {\n return new Promise((resolve, reject) => {\n let size = 0;\n let done = false;\n const chunks: Buffer[] = [];\n req.on(\"data\", (chunk: Buffer) => {\n if (done) return;\n size += chunk.length;\n if (size > MAX_BODY_BYTES) {\n // Stop consuming and reject. We deliberately do NOT destroy the socket\n // here: the caller still needs to flush a 413 response, so it owns the\n // teardown (resume-and-drain) once that response is written.\n done = true;\n req.pause();\n reject(new BodyTooLargeError());\n return;\n }\n chunks.push(chunk);\n });\n req.on(\"end\", () => {\n if (!done) resolve(Buffer.concat(chunks).toString(\"utf8\"));\n });\n req.on(\"error\", (err: Error) => {\n if (!done) {\n done = true;\n reject(err);\n }\n });\n });\n}\n\n/** Write a JSON response with the given status and optional extra headers. */\nfunction sendJson(\n res: ServerResponse,\n status: number,\n body: unknown,\n headers: Record<string, string> = {},\n): void {\n const payload = JSON.stringify(body);\n res.writeHead(status, {\n \"content-type\": \"application/json; charset=utf-8\",\n \"content-length\": Buffer.byteLength(payload).toString(),\n ...headers,\n });\n res.end(payload);\n}\n\n/** Error raised by {@link withTimeout} when the request deadline elapses. */\nclass RequestTimeoutError extends Error {\n override readonly name = \"RequestTimeoutError\";\n constructor(message = \"request timed out\") {\n super(message);\n }\n}\n\n/**\n * Race a handler against a deadline. On timeout the returned promise rejects with\n * a {@link RequestTimeoutError} AND the supplied {@link AbortController} is\n * aborted, so the in-flight work (a `scan()` wired to `controller.signal`) stops\n * cooperatively instead of running unbounded in the background after the 504.\n *\n * The controller is always aborted once the race settles (success, failure, or\n * timeout) so no scan keeps running past its response.\n */\nfunction withTimeout<T>(promise: Promise<T>, ms: number, controller: AbortController): Promise<T> {\n if (!(ms > 0)) return promise;\n return new Promise<T>((resolve, reject) => {\n const timer = setTimeout(() => {\n controller.abort(); // cancel the underlying scan — no leaked background work.\n reject(new RequestTimeoutError());\n }, ms);\n timer.unref?.();\n promise.then(\n (value) => {\n clearTimeout(timer);\n controller.abort(); // settle the signal so nothing lingers post-response.\n resolve(value);\n },\n (err: unknown) => {\n clearTimeout(timer);\n controller.abort();\n reject(err instanceof Error ? err : new Error(String(err)));\n },\n );\n });\n}\n\n/**\n * Build (but do not start) the HTTP server wrapping an {@link McpServer}.\n * Exposed for testing and for embedding in a larger process. The `config`\n * carries the resolved auth / timeout / response-cap policy.\n */\nexport function createHttpServer(server: McpServer, config: HttpConfig): Server {\n return createServer((req, res) => {\n void handleRequest(server, config, req, res).catch((err: unknown) => {\n // Last-resort handler: log the detail locally, return a generic message so\n // a remote caller never sees server internals (paths, stack traces).\n logServerError(\"unhandled request error\", err);\n if (!res.headersSent) {\n sendJson(res, 500, makeFailure(null, ErrorCode.InternalError, \"internal error\"));\n } else {\n res.end();\n }\n });\n });\n}\n\n/** Log a server-side error detail to stderr (never sent to the remote caller). */\nfunction logServerError(context: string, err: unknown): void {\n const detail = err instanceof Error ? (err.stack ?? err.message) : String(err);\n process.stderr.write(`quantakrypto MCP (http): ${context}: ${detail}\\n`);\n}\n\n/** Extract the (single) `Origin` request header, if present. */\nfunction originHeader(req: IncomingMessage): string | undefined {\n const value = req.headers.origin;\n return Array.isArray(value) ? value[0] : value;\n}\n\n/** Route and handle a single HTTP request. */\nasync function handleRequest(\n server: McpServer,\n config: HttpConfig,\n req: IncomingMessage,\n res: ServerResponse,\n): Promise<void> {\n const url = req.url ?? \"/\";\n const method = req.method ?? \"GET\";\n const path = url.split(\"?\")[0];\n\n if (method === \"GET\" && path === \"/health\") {\n sendJson(res, 200, { status: \"ok\", server: \"quantakrypto\", transport: \"http\" });\n return;\n }\n\n if (path === \"/mcp\") {\n if (method !== \"POST\") {\n // The full transport also allows GET for an SSE stream; we don't here.\n sendJson(res, 405, makeFailure(null, ErrorCode.InvalidRequest, \"method not allowed\"), {\n allow: \"POST\",\n });\n return;\n }\n // DNS-rebinding / localhost-CSRF guard: reject a foreign browser Origin\n // BEFORE auth/body, so the default no-token loopback config is not a\n // confused deputy for a malicious web page. (P0 — origin validation.)\n const origin = originDecision(allowedOriginHosts(config), originHeader(req));\n if (!origin.ok) {\n sendJson(\n res,\n 403,\n makeFailure(null, ErrorCode.InvalidRequest, origin.reason ?? \"forbidden origin\"),\n );\n return;\n }\n // Authenticate BEFORE reading the body or dispatching (Q-02).\n const auth = authorizeRequest(config.token, req.headers.authorization);\n if (!auth.authorized) {\n sendJson(\n res,\n auth.status ?? 401,\n makeFailure(null, ErrorCode.InvalidRequest, auth.message ?? \"unauthorized\"),\n { \"www-authenticate\": \"Bearer\" },\n );\n return;\n }\n await handleMcpPost(server, config, req, res);\n return;\n }\n\n sendJson(res, 404, makeFailure(null, ErrorCode.MethodNotFound, \"not found\"));\n}\n\n/** Handle `POST /mcp`: parse one JSON-RPC message, dispatch, return the result. */\nasync function handleMcpPost(\n server: McpServer,\n config: HttpConfig,\n req: IncomingMessage,\n res: ServerResponse,\n): Promise<void> {\n // Session handling (stateless here): echo a provided session id, else mint one.\n // A production server would look this up in a session store — see HOSTING.md.\n const incomingSession = req.headers[SESSION_HEADER];\n const sessionId =\n (Array.isArray(incomingSession) ? incomingSession[0] : incomingSession) ?? randomUUID();\n const sessionHeaders = { [SESSION_HEADER]: sessionId };\n\n let raw: string;\n try {\n raw = await readBody(req);\n } catch (err) {\n // M1: only the size-cap rejection is a 413. A genuine transport/I/O error\n // (the client aborted, a socket reset) is a 400 — it is the request that\n // failed, not a server fault — and never echoes the raw error text.\n if (err instanceof BodyTooLargeError) {\n // Flush the 413 first, then tear down the connection so a still-uploading\n // client stops sending. Destroying on `finish` guarantees the response is\n // written before the socket goes away (avoids a connection-reset race).\n res.on(\"finish\", () => req.destroy());\n sendJson(res, 413, makeFailure(null, ErrorCode.InvalidRequest, \"request body too large\"), {\n ...sessionHeaders,\n connection: \"close\",\n });\n } else {\n logServerError(\"error reading request body\", err);\n sendJson(\n res,\n 400,\n makeFailure(null, ErrorCode.InvalidRequest, \"error reading request body\"),\n sessionHeaders,\n );\n }\n return;\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n sendJson(res, 400, makeFailure(null, ErrorCode.ParseError, \"parse error\"), sessionHeaders);\n return;\n }\n\n // Cancellation: the controller's signal is threaded into the tool handler (and\n // thus into `scan()`); withTimeout aborts it on deadline so a timed-out\n // request stops the underlying work instead of leaking it (P0 — timeout/abort).\n const controller = new AbortController();\n let response: JsonRpcResponse | null;\n try {\n response = await withTimeout(\n server.handle(parsed, { signal: controller.signal }),\n config.timeoutMs,\n controller,\n );\n } catch (err) {\n if (err instanceof RequestTimeoutError) {\n sendJson(\n res,\n 504,\n makeFailure(null, ErrorCode.InternalError, \"request timed out\"),\n sessionHeaders,\n );\n } else {\n // server.handle never rejects in practice (it catches internally), but be\n // defensive and never leak a raw message.\n logServerError(\"error dispatching request\", err);\n sendJson(\n res,\n 500,\n makeFailure(null, ErrorCode.InternalError, \"internal error\"),\n sessionHeaders,\n );\n }\n return;\n }\n\n if (response === null) {\n // Notification — acknowledge with 202 and no body.\n res.writeHead(202, sessionHeaders);\n res.end();\n return;\n }\n\n // Enforce the response-size cap (Q-03): never stream back an unbounded body.\n const serialized = JSON.stringify(response);\n if (Buffer.byteLength(serialized) > config.maxResponseBytes) {\n sendJson(\n res,\n 500,\n makeFailure(null, ErrorCode.InternalError, \"response too large\"),\n sessionHeaders,\n );\n return;\n }\n sendJson(res, 200, response, sessionHeaders);\n}\n\n/**\n * Build the HTTP-facing {@link McpServer}: the same server used over stdio but\n * with the filesystem tools gated per policy. Exposed for tests.\n */\nexport function createHttpMcpServer(config: HttpConfig): McpServer {\n return createQuantakryptoServer({\n tools: gateHttpTools(quantakryptoTools, config.allowFs, config.allowNetwork),\n });\n}\n\n/** Start the HTTP server, resolving once it is listening. */\nfunction startHttpServer(options: HttpServerOptions = {}): Promise<Server> {\n const config = resolveHttpConfig(process.env, options);\n\n const decision = startupDecision(config);\n if (!decision.ok) {\n return Promise.reject(new Error(decision.reason ?? \"refusing to start\"));\n }\n if (!config.loopback) {\n process.stderr.write(\n `quantakrypto MCP (http): WARNING binding to non-loopback host ${config.host}; ` +\n `Bearer auth is required and active.\\n`,\n );\n }\n\n const mcp = createHttpMcpServer(config);\n const httpServer = createHttpServer(mcp, config);\n return new Promise((resolve) => {\n httpServer.listen(config.port, config.host, () => {\n const auth = config.token ? \"bearer-auth\" : \"no-auth\";\n const fs = config.allowFs ? \"fs-tools:on\" : \"fs-tools:off\";\n const probe = config.allowNetwork ? \"probe:on\" : \"probe:off\";\n process.stderr.write(\n `quantakrypto MCP server (http) listening on http://${config.host}:${config.port} ` +\n `[${auth}, ${fs}, ${probe}]\\n`,\n );\n process.stderr.write(\n ` POST http://${config.host}:${config.port}/mcp ` +\n `GET http://${config.host}:${config.port}/health\\n`,\n );\n resolve(httpServer);\n });\n });\n}\n\n/** Entry point when run directly. */\nfunction main(): void {\n startHttpServer().catch((err: unknown) => {\n const messageText = err instanceof Error ? err.message : String(err);\n process.stderr.write(`quantakrypto MCP (http) failed to start: ${messageText}\\n`);\n process.exitCode = 1;\n });\n}\n\n/** True when this module is the program's entry point (handles symlinks). */\nfunction isMainModule(): boolean {\n const argv1 = process.argv[1];\n if (!argv1) return false;\n const thisPath = fileURLToPath(import.meta.url);\n try {\n return realpathSync(argv1) === realpathSync(thisPath);\n } catch {\n return argv1 === thisPath;\n }\n}\n\n// Only auto-run when invoked as a script, not when imported by tests.\nif (isMainModule()) {\n main();\n}\n"]} | ||
| {"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n/**\n * quantakrypto MCP — hostable HTTP transport (Streamable-HTTP-style JSON-RPC).\n *\n * A zero-dependency {@link node:http} server that exposes the same\n * {@link McpServer} over HTTP so the quantakrypto MCP can run as a remote service:\n *\n * POST /mcp — body is a single JSON-RPC 2.0 message; the JSON-RPC\n * response is returned as the 200 response body\n * (`application/json`). Notifications get HTTP 202 with no body.\n * GET /health — liveness probe, returns `{ status: \"ok\", ... }`.\n *\n * This is the minimal-but-working core of the MCP Streamable HTTP transport.\n * The full spec also supports an SSE response (`text/event-stream`) for\n * server-initiated messages; this server speaks the JSON request/response half,\n * which is sufficient for stateless tool calls. See HOSTING.md for the\n * production design (auth, multi-tenant sessions, rate limiting, scaling).\n *\n * SAFE-BY-DEFAULT POSTURE (P0-1). Unlike the stdio transport — which trusts the\n * local user and stays fully featured — the HTTP transport is hardened because a\n * hosted endpoint is reachable by untrusted peers:\n *\n * - Binds to 127.0.0.1 by default (NOT 0.0.0.0). Override with QUANTAKRYPTO_MCP_HOST.\n * - Bearer-token auth: when QUANTAKRYPTO_MCP_TOKEN is set, every /mcp request must\n * send `Authorization: Bearer <token>` (else 401). Binding to a non-loopback\n * host WITHOUT a token is refused at startup (it would be an open relay).\n * - The filesystem tools (scan_path, inventory_crypto, generate_cbom) read\n * arbitrary server paths and are DISABLED over HTTP unless QUANTAKRYPTO_MCP_ALLOW_FS=1\n * (security audit Q-01). The networked probe_endpoint tool is likewise DISABLED\n * over HTTP unless QUANTAKRYPTO_MCP_ALLOW_NETWORK=1 (a hosted server should not\n * probe arbitrary hosts). The knowledge tools (explain_finding, suggest_hybrid,\n * list_rules) are always available. Gating is enforced by registering only the\n * permitted tools, so tools/list and tools/call both reflect it.\n * - Per-request timeout (QUANTAKRYPTO_MCP_TIMEOUT_MS) and a response-size cap\n * (QUANTAKRYPTO_MCP_MAX_RESPONSE_BYTES), in addition to the 1 MiB request-body cap.\n *\n * Run with `node dist/http.js` (PORT/QUANTAKRYPTO_MCP_* from env).\n */\n\nimport { createServer } from \"node:http\";\nimport type { IncomingMessage, Server, ServerResponse } from \"node:http\";\nimport { createHash, randomUUID, timingSafeEqual } from \"node:crypto\";\nimport { realpathSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\nimport process from \"node:process\";\n\nimport { createQuantakryptoServer } from \"./index.js\";\nimport { ErrorCode, makeFailure } from \"./protocol.js\";\nimport type { JsonRpcResponse, ToolDefinition } from \"./protocol.js\";\nimport { quantakryptoTools, FS_TOOL_NAMES, NETWORK_TOOL_NAMES } from \"./tools.js\";\nimport type { McpServer } from \"./server.js\";\n\n/** Header carrying the MCP session id (per the Streamable HTTP transport). */\nconst SESSION_HEADER = \"mcp-session-id\";\n\n/** Maximum accepted request body size (1 MiB) — a basic abuse guard. */\nconst MAX_BODY_BYTES = 1024 * 1024;\n\n/** Default per-request tool-execution deadline (ms). */\nconst DEFAULT_TIMEOUT_MS = 30_000;\n\n/** Default cap on the serialized response body (4 MiB). */\nconst DEFAULT_MAX_RESPONSE_BYTES = 4 * 1024 * 1024;\n\n/** Loopback hosts that are safe to bind without authentication. */\nconst LOOPBACK_HOSTS = new Set([\"127.0.0.1\", \"::1\", \"localhost\"]);\n\ninterface HttpServerOptions {\n /** Port to listen on. Defaults to env PORT or 3000. */\n port?: number;\n /** Host/interface to bind. Defaults to QUANTAKRYPTO_MCP_HOST / HOST or \"127.0.0.1\". */\n host?: string;\n /** Bearer token required on /mcp. Defaults to QUANTAKRYPTO_MCP_TOKEN (empty = none). */\n token?: string;\n /** Expose the filesystem tools over HTTP. Defaults to QUANTAKRYPTO_MCP_ALLOW_FS=1. */\n allowFs?: boolean;\n /**\n * Expose the networked probe_endpoint tool over HTTP. Off by default (a hosted\n * server should not probe arbitrary hosts); enable only on a trusted deployment.\n * Defaults to QUANTAKRYPTO_MCP_ALLOW_NETWORK=1.\n */\n allowNetwork?: boolean;\n /** Per-request tool-execution timeout (ms). Defaults to QUANTAKRYPTO_MCP_TIMEOUT_MS. */\n timeoutMs?: number;\n /** Response-body size cap (bytes). Defaults to QUANTAKRYPTO_MCP_MAX_RESPONSE_BYTES. */\n maxResponseBytes?: number;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Pure policy (P0-1) — host/auth/tool-gating decisions, fully unit-testable. */\n/* -------------------------------------------------------------------------- */\n\n/** A minimal env shape so the config resolver is pure and testable. */\ntype HttpEnv = Record<string, string | undefined>;\n\n/** Resolved, validated HTTP transport configuration. */\ninterface HttpConfig {\n host: string;\n port: number;\n /** The bearer token, or \"\" when auth is disabled. */\n token: string;\n /** Whether the filesystem tools are exposed over HTTP. */\n allowFs: boolean;\n /** Whether the networked probe_endpoint tool is exposed over HTTP (default off). */\n allowNetwork: boolean;\n timeoutMs: number;\n maxResponseBytes: number;\n /** True when the host is a loopback interface (safe without auth). */\n loopback: boolean;\n /**\n * Extra origin hosts to allow on `POST /mcp` (lower-cased hostnames), beyond\n * the implicit loopback set and the bind host. From QUANTAKRYPTO_MCP_ALLOW_ORIGIN.\n */\n allowedOrigins: string[];\n}\n\n/**\n * Resolve the HTTP transport config from env + explicit overrides. Pure: does\n * no I/O and never reads `process` directly. Overrides win over env.\n */\nexport function resolveHttpConfig(env: HttpEnv, options: HttpServerOptions = {}): HttpConfig {\n const host = options.host ?? env.QUANTAKRYPTO_MCP_HOST ?? env.HOST ?? \"127.0.0.1\";\n const port = options.port ?? toInt(env.PORT, 3000);\n const token = (options.token ?? env.QUANTAKRYPTO_MCP_TOKEN ?? \"\").trim();\n const allowFs =\n options.allowFs ??\n (env.QUANTAKRYPTO_MCP_ALLOW_FS === \"1\" || env.QUANTAKRYPTO_MCP_ALLOW_FS === \"true\");\n const allowNetwork =\n options.allowNetwork ??\n (env.QUANTAKRYPTO_MCP_ALLOW_NETWORK === \"1\" || env.QUANTAKRYPTO_MCP_ALLOW_NETWORK === \"true\");\n const timeoutMs = options.timeoutMs ?? toInt(env.QUANTAKRYPTO_MCP_TIMEOUT_MS, DEFAULT_TIMEOUT_MS);\n const maxResponseBytes =\n options.maxResponseBytes ??\n toInt(env.QUANTAKRYPTO_MCP_MAX_RESPONSE_BYTES, DEFAULT_MAX_RESPONSE_BYTES);\n const allowedOrigins = parseOriginList(env.QUANTAKRYPTO_MCP_ALLOW_ORIGIN);\n return {\n host,\n port,\n token,\n allowFs,\n allowNetwork,\n timeoutMs,\n maxResponseBytes,\n loopback: isLoopbackHost(host),\n allowedOrigins,\n };\n}\n\n/**\n * Parse the comma-separated origin allow-list into lower-cased hostnames. Each\n * entry may be a bare host or a full origin URL; either way only the hostname is\n * retained (the value compared against `new URL(Origin).hostname`).\n */\nfunction parseOriginList(value: string | undefined): string[] {\n const out = new Set<string>();\n for (const raw of (value ?? \"\").split(\",\")) {\n const entry = raw.trim().toLowerCase();\n if (entry.length === 0) continue;\n try {\n out.add(new URL(entry).hostname);\n } catch {\n out.add(entry); // bare hostname (no scheme).\n }\n }\n return [...out];\n}\n\n/** Parse a positive integer from an env string, falling back on bad input. */\nfunction toInt(value: string | undefined, fallback: number): number {\n if (value === undefined) return fallback;\n const n = Number(value);\n return Number.isFinite(n) && n > 0 ? Math.floor(n) : fallback;\n}\n\n/** True when binding to `host` keeps the server private to this machine. */\nexport function isLoopbackHost(host: string): boolean {\n return LOOPBACK_HOSTS.has(host.trim().toLowerCase());\n}\n\n/**\n * Decide whether a non-loopback bind is permitted. A server reachable from the\n * network MUST require auth; binding wide-open without a token would be an open,\n * unauthenticated arbitrary-tool relay. Pure decision used at startup.\n */\nexport function startupDecision(config: HttpConfig): {\n ok: boolean;\n reason?: string;\n} {\n if (!config.loopback && config.token.length === 0) {\n return {\n ok: false,\n reason:\n `refusing to bind to non-loopback host \"${config.host}\" without a token. ` +\n `Set QUANTAKRYPTO_MCP_TOKEN to require Bearer auth, or bind to 127.0.0.1.`,\n };\n }\n return { ok: true };\n}\n\n/**\n * Decide whether a request's `Origin` / `Host` is acceptable, to defend the\n * default no-token loopback config against DNS-rebinding and localhost-CSRF: a\n * malicious web page can POST to `http://127.0.0.1:<port>/mcp`, but the browser\n * stamps a foreign `Origin` we can reject. Pure and testable.\n *\n * Policy:\n * - No `Origin` header (curl, a native MCP client, same-origin GET) → allow;\n * the header is a browser artifact and absence is not an attack signal here.\n * - An `Origin` present → its host must be a configured loopback host (or a\n * host explicitly added to the allow-list). A foreign origin is rejected.\n * - When the server itself binds a non-loopback interface, a token is already\n * mandatory (see {@link startupDecision}); the loopback allow-list still\n * applies but auth is the primary control there.\n */\nexport function originDecision(\n allowedHosts: ReadonlySet<string>,\n originHeader: string | undefined,\n): { ok: boolean; reason?: string } {\n const origin = (originHeader ?? \"\").trim();\n if (origin.length === 0) return { ok: true }; // non-browser client; nothing to check.\n if (origin.toLowerCase() === \"null\") {\n return { ok: false, reason: \"opaque/null Origin is not allowed\" };\n }\n let host: string;\n try {\n host = new URL(origin).hostname.toLowerCase();\n } catch {\n return { ok: false, reason: \"malformed Origin header\" };\n }\n if (allowedHosts.has(host)) return { ok: true };\n return { ok: false, reason: `Origin host \"${host}\" is not in the allow-list` };\n}\n\n/** The hosts an `Origin` may name. Loopback by default, plus the bind host. */\nexport function allowedOriginHosts(config: HttpConfig): Set<string> {\n const hosts = new Set<string>([\"127.0.0.1\", \"::1\", \"localhost\"]);\n // Allow the interface the server is actually bound to (e.g. a LAN address with\n // a token), so a same-host browser client keeps working.\n hosts.add(config.host.trim().toLowerCase());\n for (const extra of config.allowedOrigins) hosts.add(extra);\n return hosts;\n}\n\n/** A request-authorization outcome. */\ninterface AuthDecision {\n authorized: boolean;\n /** HTTP status to use when not authorized. */\n status?: number;\n message?: string;\n}\n\n/**\n * Decide whether a request is authorized given the configured token and the\n * incoming Authorization header. When no token is configured, all requests are\n * allowed (the loopback / trusted-edge case). Pure and testable.\n */\nexport function authorizeRequest(\n token: string,\n authorizationHeader: string | undefined,\n): AuthDecision {\n if (token.length === 0) return { authorized: true };\n const header = (authorizationHeader ?? \"\").trim();\n const match = /^Bearer\\s+(\\S.*)$/i.exec(header);\n const presented = match?.[1]?.trim();\n if (!presented) {\n return { authorized: false, status: 401, message: \"missing bearer token\" };\n }\n if (!timingSafeEqualStr(presented, token)) {\n return { authorized: false, status: 401, message: \"invalid bearer token\" };\n }\n return { authorized: true };\n}\n\n/**\n * Constant-time string compare. Both inputs are hashed with the same algorithm\n * to fixed-length digests before {@link timingSafeEqual}, so the comparison runs\n * over equal-length buffers and the early length-mismatch return (which leaked\n * the configured token's length) is gone. The hashing is a domain-separation /\n * length-equalization step, not a secrecy measure: `timingSafeEqual` still does\n * the constant-time work and rejects unequal digests.\n */\nexport function timingSafeEqualStr(a: string, b: string): boolean {\n const ha = createHash(\"sha256\").update(a, \"utf8\").digest();\n const hb = createHash(\"sha256\").update(b, \"utf8\").digest();\n // Same algorithm ⇒ identical digest length ⇒ timingSafeEqual never throws.\n return timingSafeEqual(ha, hb);\n}\n\n/**\n * Select the tools to expose over HTTP for a given policy. The knowledge tools\n * are always returned; the filesystem tools are included only when `allowFs` is\n * true, and the networked probe tool only when `allowNetwork` is true (both off by\n * default). Pure function of its inputs — the single source of truth for HTTP tool\n * gating, so tools/list and tools/call stay consistent.\n */\nexport function gateHttpTools(\n tools: readonly ToolDefinition[],\n allowFs: boolean,\n allowNetwork = false,\n): ToolDefinition[] {\n const fsNames = new Set(FS_TOOL_NAMES);\n const networkNames = new Set(NETWORK_TOOL_NAMES);\n return tools.filter(\n (t) =>\n (allowNetwork || !networkNames.has(t.name)) && // networked tools: opt-in on HTTP\n (allowFs || !fsNames.has(t.name)), // fs tools: opt-in on HTTP\n );\n}\n\n/* -------------------------------------------------------------------------- */\n/* HTTP plumbing */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Error thrown by {@link readBody} when the request body exceeds the size cap.\n * Distinguished from a transport/I/O error so the caller can map it to HTTP 413\n * specifically, while genuine read failures map to 400/500 (M1).\n */\nexport class BodyTooLargeError extends Error {\n override readonly name = \"BodyTooLargeError\";\n constructor(message = \"request body too large\") {\n super(message);\n }\n}\n\n/**\n * Read a request body fully, enforcing the size cap. Resolves to the raw string.\n * Rejects with a {@link BodyTooLargeError} when the cap is exceeded, and with the\n * original transport error (an I/O failure) otherwise — the two are mapped to\n * different HTTP statuses by the caller (M1).\n */\nfunction readBody(req: IncomingMessage): Promise<string> {\n return new Promise((resolve, reject) => {\n let size = 0;\n let done = false;\n const chunks: Buffer[] = [];\n req.on(\"data\", (chunk: Buffer) => {\n if (done) return;\n size += chunk.length;\n if (size > MAX_BODY_BYTES) {\n // Stop consuming and reject. We deliberately do NOT destroy the socket\n // here: the caller still needs to flush a 413 response, so it owns the\n // teardown (resume-and-drain) once that response is written.\n done = true;\n req.pause();\n reject(new BodyTooLargeError());\n return;\n }\n chunks.push(chunk);\n });\n req.on(\"end\", () => {\n if (!done) resolve(Buffer.concat(chunks).toString(\"utf8\"));\n });\n req.on(\"error\", (err: Error) => {\n if (!done) {\n done = true;\n reject(err);\n }\n });\n });\n}\n\n/** Write a JSON response with the given status and optional extra headers. */\nfunction sendJson(\n res: ServerResponse,\n status: number,\n body: unknown,\n headers: Record<string, string> = {},\n): void {\n const payload = JSON.stringify(body);\n res.writeHead(status, {\n \"content-type\": \"application/json; charset=utf-8\",\n \"content-length\": Buffer.byteLength(payload).toString(),\n ...headers,\n });\n res.end(payload);\n}\n\n/** Error raised by {@link withTimeout} when the request deadline elapses. */\nclass RequestTimeoutError extends Error {\n override readonly name = \"RequestTimeoutError\";\n constructor(message = \"request timed out\") {\n super(message);\n }\n}\n\n/**\n * Race a handler against a deadline. On timeout the returned promise rejects with\n * a {@link RequestTimeoutError} AND the supplied {@link AbortController} is\n * aborted, so the in-flight work (a `scan()` wired to `controller.signal`) stops\n * cooperatively instead of running unbounded in the background after the 504.\n *\n * The controller is always aborted once the race settles (success, failure, or\n * timeout) so no scan keeps running past its response.\n */\nfunction withTimeout<T>(promise: Promise<T>, ms: number, controller: AbortController): Promise<T> {\n if (!(ms > 0)) return promise;\n return new Promise<T>((resolve, reject) => {\n const timer = setTimeout(() => {\n controller.abort(); // cancel the underlying scan — no leaked background work.\n reject(new RequestTimeoutError());\n }, ms);\n timer.unref?.();\n promise.then(\n (value) => {\n clearTimeout(timer);\n controller.abort(); // settle the signal so nothing lingers post-response.\n resolve(value);\n },\n (err: unknown) => {\n clearTimeout(timer);\n controller.abort();\n reject(err instanceof Error ? err : new Error(String(err)));\n },\n );\n });\n}\n\n/**\n * Build (but do not start) the HTTP server wrapping an {@link McpServer}.\n * Exposed for testing and for embedding in a larger process. The `config`\n * carries the resolved auth / timeout / response-cap policy.\n */\nexport function createHttpServer(server: McpServer, config: HttpConfig): Server {\n return createServer((req, res) => {\n void handleRequest(server, config, req, res).catch((err: unknown) => {\n // Last-resort handler: log the detail locally, return a generic message so\n // a remote caller never sees server internals (paths, stack traces).\n logServerError(\"unhandled request error\", err);\n if (!res.headersSent) {\n sendJson(res, 500, makeFailure(null, ErrorCode.InternalError, \"internal error\"));\n } else {\n res.end();\n }\n });\n });\n}\n\n/** Log a server-side error detail to stderr (never sent to the remote caller). */\nfunction logServerError(context: string, err: unknown): void {\n const detail = err instanceof Error ? (err.stack ?? err.message) : String(err);\n process.stderr.write(`quantakrypto MCP (http): ${context}: ${detail}\\n`);\n}\n\n/** Extract the (single) `Origin` request header, if present. */\nfunction originHeader(req: IncomingMessage): string | undefined {\n const value = req.headers.origin;\n return Array.isArray(value) ? value[0] : value;\n}\n\n/** Route and handle a single HTTP request. */\nasync function handleRequest(\n server: McpServer,\n config: HttpConfig,\n req: IncomingMessage,\n res: ServerResponse,\n): Promise<void> {\n const url = req.url ?? \"/\";\n const method = req.method ?? \"GET\";\n const path = url.split(\"?\")[0];\n\n if (method === \"GET\" && path === \"/health\") {\n sendJson(res, 200, { status: \"ok\", server: \"quantakrypto\", transport: \"http\" });\n return;\n }\n\n if (path === \"/mcp\") {\n if (method !== \"POST\") {\n // The full transport also allows GET for an SSE stream; we don't here.\n sendJson(res, 405, makeFailure(null, ErrorCode.InvalidRequest, \"method not allowed\"), {\n allow: \"POST\",\n });\n return;\n }\n // DNS-rebinding / localhost-CSRF guard: reject a foreign browser Origin\n // BEFORE auth/body, so the default no-token loopback config is not a\n // confused deputy for a malicious web page. (P0 — origin validation.)\n const origin = originDecision(allowedOriginHosts(config), originHeader(req));\n if (!origin.ok) {\n sendJson(\n res,\n 403,\n makeFailure(null, ErrorCode.InvalidRequest, origin.reason ?? \"forbidden origin\"),\n );\n return;\n }\n // Authenticate BEFORE reading the body or dispatching (Q-02).\n const auth = authorizeRequest(config.token, req.headers.authorization);\n if (!auth.authorized) {\n sendJson(\n res,\n auth.status ?? 401,\n makeFailure(null, ErrorCode.InvalidRequest, auth.message ?? \"unauthorized\"),\n { \"www-authenticate\": \"Bearer\" },\n );\n return;\n }\n await handleMcpPost(server, config, req, res);\n return;\n }\n\n sendJson(res, 404, makeFailure(null, ErrorCode.MethodNotFound, \"not found\"));\n}\n\n/** Handle `POST /mcp`: parse one JSON-RPC message, dispatch, return the result. */\nasync function handleMcpPost(\n server: McpServer,\n config: HttpConfig,\n req: IncomingMessage,\n res: ServerResponse,\n): Promise<void> {\n // Session handling (stateless here): echo a provided session id, else mint one.\n // A production server would look this up in a session store — see HOSTING.md.\n const incomingSession = req.headers[SESSION_HEADER];\n const sessionId =\n (Array.isArray(incomingSession) ? incomingSession[0] : incomingSession) ?? randomUUID();\n const sessionHeaders = { [SESSION_HEADER]: sessionId };\n\n let raw: string;\n try {\n raw = await readBody(req);\n } catch (err) {\n // M1: only the size-cap rejection is a 413. A genuine transport/I/O error\n // (the client aborted, a socket reset) is a 400 — it is the request that\n // failed, not a server fault — and never echoes the raw error text.\n if (err instanceof BodyTooLargeError) {\n // Flush the 413 first, then tear down the connection so a still-uploading\n // client stops sending. Destroying on `finish` guarantees the response is\n // written before the socket goes away (avoids a connection-reset race).\n res.on(\"finish\", () => req.destroy());\n sendJson(res, 413, makeFailure(null, ErrorCode.InvalidRequest, \"request body too large\"), {\n ...sessionHeaders,\n connection: \"close\",\n });\n } else {\n logServerError(\"error reading request body\", err);\n sendJson(\n res,\n 400,\n makeFailure(null, ErrorCode.InvalidRequest, \"error reading request body\"),\n sessionHeaders,\n );\n }\n return;\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n sendJson(res, 400, makeFailure(null, ErrorCode.ParseError, \"parse error\"), sessionHeaders);\n return;\n }\n\n // Cancellation: the controller's signal is threaded into the tool handler (and\n // thus into `scan()`); withTimeout aborts it on deadline so a timed-out\n // request stops the underlying work instead of leaking it (P0 — timeout/abort).\n const controller = new AbortController();\n let response: JsonRpcResponse | null;\n try {\n response = await withTimeout(\n server.handle(parsed, { signal: controller.signal }),\n config.timeoutMs,\n controller,\n );\n } catch (err) {\n if (err instanceof RequestTimeoutError) {\n sendJson(\n res,\n 504,\n makeFailure(null, ErrorCode.InternalError, \"request timed out\"),\n sessionHeaders,\n );\n } else {\n // server.handle never rejects in practice (it catches internally), but be\n // defensive and never leak a raw message.\n logServerError(\"error dispatching request\", err);\n sendJson(\n res,\n 500,\n makeFailure(null, ErrorCode.InternalError, \"internal error\"),\n sessionHeaders,\n );\n }\n return;\n }\n\n if (response === null) {\n // Notification — acknowledge with 202 and no body.\n res.writeHead(202, sessionHeaders);\n res.end();\n return;\n }\n\n // Enforce the response-size cap (Q-03): never stream back an unbounded body.\n const serialized = JSON.stringify(response);\n if (Buffer.byteLength(serialized) > config.maxResponseBytes) {\n sendJson(\n res,\n 500,\n makeFailure(null, ErrorCode.InternalError, \"response too large\"),\n sessionHeaders,\n );\n return;\n }\n sendJson(res, 200, response, sessionHeaders);\n}\n\n/**\n * Build the HTTP-facing {@link McpServer}: the same server used over stdio but\n * with the filesystem tools gated per policy. Exposed for tests.\n */\nexport function createHttpMcpServer(config: HttpConfig): McpServer {\n return createQuantakryptoServer({\n tools: gateHttpTools(quantakryptoTools, config.allowFs, config.allowNetwork),\n });\n}\n\n/** Start the HTTP server, resolving once it is listening. */\nfunction startHttpServer(options: HttpServerOptions = {}): Promise<Server> {\n const config = resolveHttpConfig(process.env, options);\n\n const decision = startupDecision(config);\n if (!decision.ok) {\n return Promise.reject(new Error(decision.reason ?? \"refusing to start\"));\n }\n if (!config.loopback) {\n process.stderr.write(\n `quantakrypto MCP (http): WARNING binding to non-loopback host ${config.host}; ` +\n `Bearer auth is required and active.\\n`,\n );\n }\n\n const mcp = createHttpMcpServer(config);\n const httpServer = createHttpServer(mcp, config);\n return new Promise((resolve) => {\n httpServer.listen(config.port, config.host, () => {\n const auth = config.token ? \"bearer-auth\" : \"no-auth\";\n const fs = config.allowFs ? \"fs-tools:on\" : \"fs-tools:off\";\n const probe = config.allowNetwork ? \"probe:on\" : \"probe:off\";\n process.stderr.write(\n `quantakrypto MCP server (http) listening on http://${config.host}:${config.port} ` +\n `[${auth}, ${fs}, ${probe}]\\n`,\n );\n process.stderr.write(\n ` POST http://${config.host}:${config.port}/mcp ` +\n `GET http://${config.host}:${config.port}/health\\n`,\n );\n resolve(httpServer);\n });\n });\n}\n\n/** Entry point when run directly. */\nfunction main(): void {\n startHttpServer().catch((err: unknown) => {\n const messageText = err instanceof Error ? err.message : String(err);\n process.stderr.write(`quantakrypto MCP (http) failed to start: ${messageText}\\n`);\n process.exitCode = 1;\n });\n}\n\n/** True when this module is the program's entry point (handles symlinks). */\nfunction isMainModule(): boolean {\n const argv1 = process.argv[1];\n if (!argv1) return false;\n const thisPath = fileURLToPath(import.meta.url);\n try {\n return realpathSync(argv1) === realpathSync(thisPath);\n } catch {\n return argv1 === thisPath;\n }\n}\n\n// Only auto-run when invoked as a script, not when imported by tests.\nif (isMainModule()) {\n main();\n}\n"]} |
+1
-1
@@ -19,3 +19,3 @@ /** | ||
| /** The version reported by the server (kept in sync with @quantakrypto/core). */ | ||
| export declare const SERVER_VERSION = "0.5.0"; | ||
| export declare const SERVER_VERSION = "0.6.0"; | ||
| export interface CreateServerOptions { | ||
@@ -22,0 +22,0 @@ /** Override the advertised server version (defaults to @quantakrypto/core VERSION). */ |
+1
-1
@@ -60,3 +60,3 @@ /** | ||
| /** The core version these tools are built against (re-exported for diagnostics). */ | ||
| export declare const CORE_VERSION = "0.5.0"; | ||
| export declare const CORE_VERSION = "0.6.0"; | ||
| /** Exposed for tests and advanced callers. */ | ||
@@ -63,0 +63,0 @@ export declare const __test: { |
+3
-3
| { | ||
| "name": "@quantakrypto/mcp", | ||
| "version": "0.5.2", | ||
| "version": "0.6.0", | ||
| "mcpName": "io.github.quantakrypto/pqc-tools", | ||
@@ -42,4 +42,4 @@ "description": "quantakrypto MCP — post-quantum readiness for AI coding agents via the Model Context Protocol. Zero runtime dependencies (stdio JSON-RPC implemented in-house).", | ||
| "dependencies": { | ||
| "@quantakrypto/core": "0.5.0", | ||
| "@quantakrypto/qprobe": "0.5.0" | ||
| "@quantakrypto/core": "0.6.0", | ||
| "@quantakrypto/qprobe": "0.6.0" | ||
| }, | ||
@@ -46,0 +46,0 @@ "scripts": { |
404605
0+ Added
+ Added
- Removed
- Removed
Updated
Updated