{"version":3,"sources":["../src/server-sizing.ts"],"sourcesContent":["export type McpServerSize =\n  | 'tiny'\n  | 'small'\n  | 'standard'\n  | 'large'\n  | 'xlarge'\n  | 'laptop'\n  | 'jetson'\n  | 'vast'\n  | 'fleet';\n\nexport type McpServerTransportHint = 'stdio' | 'streamable-http' | 'streamable-http+sse';\n\nexport interface McpServerSizing {\n  profile: McpServerSize;\n  useCase: string;\n  recommendedConsumer: string;\n  transport: McpServerTransportHint;\n  requestBodyMaxBytes: number;\n  postgresPoolMax: number;\n  oauthRateLimit: number;\n  publicAnonRateLimit: number;\n  consumerGenRateLimit: number;\n  consumerGenDailyQuota: number;\n  maxConcurrentToolCalls: number;\n  toolTimeoutMs: number;\n  cacheMaxEntries: number;\n  memoryBudgetMb: number;\n}\n\nexport type McpServerSizingInput = Record<string, string | undefined>;\n\ntype McpServerSizingProfile = Omit<McpServerSizing, 'profile'>;\n\nconst MIB = 1024 * 1024;\nconst MIN_REQUEST_BODY_BYTES = 16 * 1024;\nconst MAX_REQUEST_BODY_BYTES = 100 * MIB;\nconst MIN_TOOL_TIMEOUT_MS = 1_000;\nconst MAX_TOOL_TIMEOUT_MS = 10 * 60_000;\n\nexport const MCP_SERVER_SIZING_PROFILES: Record<McpServerSize, McpServerSizingProfile> = {\n  tiny: {\n    useCase: 'constrained local smoke tests and throwaway stdio probes',\n    recommendedConsumer: 'laptop-windows',\n    transport: 'stdio',\n    requestBodyMaxBytes: 1 * MIB,\n    postgresPoolMax: 2,\n    oauthRateLimit: 30,\n    publicAnonRateLimit: 10,\n    consumerGenRateLimit: 2,\n    consumerGenDailyQuota: 5,\n    maxConcurrentToolCalls: 1,\n    toolTimeoutMs: 15_000,\n    cacheMaxEntries: 128,\n    memoryBudgetMb: 384,\n  },\n  small: {\n    useCase: 'legacy low-traffic local HTTP deployment',\n    recommendedConsumer: 'laptop-windows',\n    transport: 'streamable-http',\n    requestBodyMaxBytes: 5 * MIB,\n    postgresPoolMax: 5,\n    oauthRateLimit: 60,\n    publicAnonRateLimit: 20,\n    consumerGenRateLimit: 3,\n    consumerGenDailyQuota: 10,\n    maxConcurrentToolCalls: 2,\n    toolTimeoutMs: 30_000,\n    cacheMaxEntries: 512,\n    memoryBudgetMb: 768,\n  },\n  standard: {\n    useCase: 'backward-compatible hosted default',\n    recommendedConsumer: 'hosted-service',\n    transport: 'streamable-http',\n    requestBodyMaxBytes: 10 * MIB,\n    postgresPoolMax: 10,\n    oauthRateLimit: 100,\n    publicAnonRateLimit: 30,\n    consumerGenRateLimit: 5,\n    consumerGenDailyQuota: 20,\n    maxConcurrentToolCalls: 4,\n    toolTimeoutMs: 45_000,\n    cacheMaxEntries: 1024,\n    memoryBudgetMb: 1536,\n  },\n  large: {\n    useCase: 'legacy high-traffic HTTP deployment',\n    recommendedConsumer: 'hosted-service',\n    transport: 'streamable-http',\n    requestBodyMaxBytes: 20 * MIB,\n    postgresPoolMax: 20,\n    oauthRateLimit: 250,\n    publicAnonRateLimit: 90,\n    consumerGenRateLimit: 15,\n    consumerGenDailyQuota: 100,\n    maxConcurrentToolCalls: 8,\n    toolTimeoutMs: 90_000,\n    cacheMaxEntries: 4096,\n    memoryBudgetMb: 4096,\n  },\n  xlarge: {\n    useCase: 'legacy maximum HTTP deployment',\n    recommendedConsumer: 'hosted-service',\n    transport: 'streamable-http+sse',\n    requestBodyMaxBytes: 50 * MIB,\n    postgresPoolMax: 40,\n    oauthRateLimit: 500,\n    publicAnonRateLimit: 180,\n    consumerGenRateLimit: 30,\n    consumerGenDailyQuota: 250,\n    maxConcurrentToolCalls: 16,\n    toolTimeoutMs: 120_000,\n    cacheMaxEntries: 8192,\n    memoryBudgetMb: 8192,\n  },\n  laptop: {\n    useCase: 'founder laptop and HoloShell local agent tooling',\n    recommendedConsumer: 'laptop-windows',\n    transport: 'streamable-http+sse',\n    requestBodyMaxBytes: 10 * MIB,\n    postgresPoolMax: 6,\n    oauthRateLimit: 120,\n    publicAnonRateLimit: 40,\n    consumerGenRateLimit: 6,\n    consumerGenDailyQuota: 30,\n    maxConcurrentToolCalls: 4,\n    toolTimeoutMs: 60_000,\n    cacheMaxEntries: 2048,\n    memoryBudgetMb: 2048,\n  },\n  jetson: {\n    useCase: 'owned-metal Jetson edge node with tighter memory and fewer DB connections',\n    recommendedConsumer: 'jetson-orin',\n    transport: 'streamable-http',\n    requestBodyMaxBytes: 8 * MIB,\n    postgresPoolMax: 4,\n    oauthRateLimit: 80,\n    publicAnonRateLimit: 20,\n    consumerGenRateLimit: 3,\n    consumerGenDailyQuota: 15,\n    maxConcurrentToolCalls: 2,\n    toolTimeoutMs: 60_000,\n    cacheMaxEntries: 768,\n    memoryBudgetMb: 2048,\n  },\n  vast: {\n    useCase: 'single Vast.ai GPU worker or render/inference utility node',\n    recommendedConsumer: 'vast-linux-gpu',\n    transport: 'streamable-http',\n    requestBodyMaxBytes: 25 * MIB,\n    postgresPoolMax: 16,\n    oauthRateLimit: 300,\n    publicAnonRateLimit: 90,\n    consumerGenRateLimit: 20,\n    consumerGenDailyQuota: 150,\n    maxConcurrentToolCalls: 8,\n    toolTimeoutMs: 120_000,\n    cacheMaxEntries: 4096,\n    memoryBudgetMb: 8192,\n  },\n  fleet: {\n    useCase: 'public coordinator or multi-worker fleet gateway',\n    recommendedConsumer: 'hosted-service',\n    transport: 'streamable-http+sse',\n    requestBodyMaxBytes: 50 * MIB,\n    postgresPoolMax: 40,\n    oauthRateLimit: 500,\n    publicAnonRateLimit: 180,\n    consumerGenRateLimit: 30,\n    consumerGenDailyQuota: 250,\n    maxConcurrentToolCalls: 16,\n    toolTimeoutMs: 180_000,\n    cacheMaxEntries: 8192,\n    memoryBudgetMb: 16384,\n  },\n};\n\nconst PROFILE_NAMES = new Set(Object.keys(MCP_SERVER_SIZING_PROFILES));\n\nfunction parseServerSize(env: McpServerSizingInput): McpServerSize {\n  const raw = (env.MCP_SERVER_SIZE || env.HOLOSCRIPT_MCP_SERVER_SIZE || 'standard')\n    .trim()\n    .toLowerCase();\n  if (PROFILE_NAMES.has(raw)) return raw as McpServerSize;\n  return 'standard';\n}\n\nfunction parsePositiveInt(\n  raw: string | undefined,\n  fallback: number,\n  options: { min?: number; max?: number } = {}\n): number {\n  if (!raw) return fallback;\n  const trimmed = raw.trim();\n  if (!/^\\d+$/.test(trimmed)) return fallback;\n  const parsed = Number.parseInt(trimmed, 10);\n  if (!Number.isFinite(parsed)) return fallback;\n  const min = options.min ?? 1;\n  const max = options.max ?? Number.MAX_SAFE_INTEGER;\n  if (parsed < min || parsed > max) return fallback;\n  return parsed;\n}\n\nexport function getMcpServerSizing(env: McpServerSizingInput = process.env): McpServerSizing {\n  const profile = parseServerSize(env);\n  const base = MCP_SERVER_SIZING_PROFILES[profile];\n\n  return {\n    profile,\n    useCase: base.useCase,\n    recommendedConsumer: base.recommendedConsumer,\n    transport: base.transport,\n    requestBodyMaxBytes: parsePositiveInt(\n      env.MCP_REQUEST_BODY_MAX_BYTES || env.MCP_MAX_REQUEST_BODY_BYTES,\n      base.requestBodyMaxBytes,\n      { min: MIN_REQUEST_BODY_BYTES, max: MAX_REQUEST_BODY_BYTES }\n    ),\n    postgresPoolMax: parsePositiveInt(\n      env.MCP_POSTGRES_POOL_MAX || env.PGPOOL_MAX,\n      base.postgresPoolMax,\n      { min: 1, max: 100 }\n    ),\n    oauthRateLimit: parsePositiveInt(env.OAUTH_RATE_LIMIT, base.oauthRateLimit),\n    publicAnonRateLimit: parsePositiveInt(env.PUBLIC_ANON_RATE_LIMIT, base.publicAnonRateLimit),\n    consumerGenRateLimit: parsePositiveInt(\n      env.HOLOSCRIPT_CONSUMER_GEN_RATE_LIMIT,\n      base.consumerGenRateLimit\n    ),\n    consumerGenDailyQuota: parsePositiveInt(\n      env.HOLOSCRIPT_CONSUMER_GEN_DAILY_QUOTA,\n      base.consumerGenDailyQuota\n    ),\n    maxConcurrentToolCalls: parsePositiveInt(\n      env.MCP_MAX_CONCURRENT_TOOL_CALLS,\n      base.maxConcurrentToolCalls,\n      { min: 1, max: 256 }\n    ),\n    toolTimeoutMs: parsePositiveInt(env.MCP_TOOL_TIMEOUT_MS, base.toolTimeoutMs, {\n      min: MIN_TOOL_TIMEOUT_MS,\n      max: MAX_TOOL_TIMEOUT_MS,\n    }),\n    cacheMaxEntries: parsePositiveInt(env.MCP_CACHE_MAX_ENTRIES, base.cacheMaxEntries, {\n      min: 1,\n      max: 1_000_000,\n    }),\n    memoryBudgetMb: parsePositiveInt(env.MCP_MEMORY_BUDGET_MB, base.memoryBudgetMb, {\n      min: 128,\n      max: 1_048_576,\n    }),\n  };\n}\n"],"mappings":"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","names":[]}