// ABOUTME: Load and validate runtime configuration for the MCP server.
// ABOUTME: Provides helpers for token requirements and URL normalization.
export class ConfigError extends Error {
constructor(message: string) {
super(message);
this.name = "ConfigError";
}
}
export type Config = {
baseUrl: string;
bearerToken?: string;
requestTimeoutMs: number;
};
const DEFAULT_TIMEOUT_MS = 10_000;
function normalizeBaseUrl(raw: string): string {
const trimmed = raw.trim();
if (!trimmed) {
throw new ConfigError("MINESWEEPER_BASE_URL is required");
}
return trimmed.endsWith("/") ? trimmed.slice(0, -1) : trimmed;
}
function parseTimeout(raw?: string): number {
if (!raw) {
return DEFAULT_TIMEOUT_MS;
}
const parsed = Number(raw);
if (!Number.isFinite(parsed) || parsed <= 0) {
throw new ConfigError("REQUEST_TIMEOUT_MS must be a positive number");
}
return parsed;
}
export function loadConfig(env: NodeJS.ProcessEnv): Config {
const baseUrl = normalizeBaseUrl(env.MINESWEEPER_BASE_URL ?? "");
const bearerToken = env.MINESWEEPER_BEARER_TOKEN?.trim();
const requestTimeoutMs = parseTimeout(env.REQUEST_TIMEOUT_MS);
return {
baseUrl,
bearerToken: bearerToken ? bearerToken : undefined,
requestTimeoutMs,
};
}
export function requireBearerToken(config: Config): string {
if (!config.bearerToken) {
throw new ConfigError("MINESWEEPER_BEARER_TOKEN is required for this action");
}
return config.bearerToken;
}