/** * Startup config self-check (#368, first slice) + Cloudflare Access service * token pairing rule (#373). * * Both entry points run this before serving anything, because most "the MCP * is broken" reports are the environment handing us garbage and saying * nothing: a macOS Keychain that stored the literal string * `${COOLIFY_ACCESS_TOKEN}` cost one team their whole integration * (pedrorezendefig/hospital-reunioes#312) when a single stderr line would * have kept them. * * Iron rule: messages name the variable and describe the shape of the * problem. They never contain the value — a malformed token is still a * token. */ export interface StartupCheckResult { /** Fatal: the server must refuse to start and print these. */ errors: string[]; /** Suspicious but survivable: print to stderr and carry on. */ warnings: string[]; } /** * The env vars whose values we sanity-check, per transport. Secrets among * them are only ever described, never echoed. MCP_PUBLIC_URL and MCP_HOST * are HTTP-only: stdio never reads them, so a broken value there (say, a * shared .env with an unexpanded Coolify magic var) must not stop a stdio * server that would run fine. */ declare const CHECKED_VARS: { readonly stdio: readonly ["COOLIFY_BASE_URL", "COOLIFY_ACCESS_TOKEN", "CF_ACCESS_CLIENT_ID", "CF_ACCESS_CLIENT_SECRET"]; readonly http: readonly ["COOLIFY_BASE_URL", "COOLIFY_ACCESS_TOKEN", "MCP_PUBLIC_URL", "MCP_HOST", "MCP_REQUEST_STATE_KEY", "CF_ACCESS_CLIENT_ID", "CF_ACCESS_CLIENT_SECRET"]; }; export type Transport = keyof typeof CHECKED_VARS; export declare function checkStartupConfig(env: NodeJS.ProcessEnv, transport: Transport): StartupCheckResult; /** Where HTTP mode keeps OAuth state unless `MCP_OAUTH_STATE_FILE` says otherwise. */ export declare const DEFAULT_OAUTH_STATE_FILE = "/data/oauth-state.json"; /** * Make sure the OAuth state file can actually be written (#417), or say why not. * * The default path lives under `/data`, which the image creates and mounts as * a volume. Run `dist/http.js` on a workstation instead and that directory * does not exist, or exists and belongs to root. Nothing noticed until the * first client registration, when the debounced write threw from a timer * and took the process with it: `POST /register` had already answered 201. * * This asks the same question at boot, and it asks it for real: the * directory is created if missing (the write path has always done that), and * the temp file the provider writes is written and removed. A real write * rather than access(2) because a stale `.tmp` left by another user passes * an access check and fails every write, and because access(2) disagrees * with ACLs, NFS and Windows. The one side effect is the directory, which is * left behind even when boot then fails for another reason; every problem * still reports in one boot, which matters more. * * Returns the problem to list with the other reasons the server cannot * start, or undefined when the path is usable. `configured` picks the * message: the operator who typed the path is told the path, the one who * typed nothing is told where the default comes from. */ export declare function ensureStateFileWritable(file: string, configured: boolean): string | undefined; /** * The Cloudflare Access service-token headers (#373), when configured. * * These must only ever ride on requests to the Coolify base URL. They are * returned as customHeaders for CoolifyClient — which by construction talks * only to the base URL — and handed to the tier-2 proof-of-access fetch, * which targets the same host. Never attach them to any other fetch. */ export declare function cfAccessHeaders(env: NodeJS.ProcessEnv): Record | undefined; /** * Merge env-derived CF Access headers with CLI `--header` flags, CLI winning. * * Header names are case-insensitive on the wire, so the override has to be * too: without this, `--header "cf-access-client-id: x"` would produce a * second distinct key and fetch would send both values comma-joined — * rejected by Access with no indication why. */ export declare function mergeCfAccessHeaders(env: NodeJS.ProcessEnv, cliHeaders: Record): Record; export {};