refactor(server): non-DI islands read env via app-config

This commit is contained in:
jubnl
2026-07-25 15:58:02 +02:00
parent 7f795a2199
commit fb9abdb76c
11 changed files with 64 additions and 71 deletions
+5 -20
View File
@@ -1,22 +1,7 @@
/**
* MCP tuning knobs from the environment (#1414). Pure parsers, kept free of
* imports so units can test them without dragging in the MCP SDK.
* MCP tuning knobs from the environment (#1414). The parsers moved into the
* app-config layer (src/app-config/parsers.ts) — this module re-exports them
* so existing import paths keep working. mcp/index.ts consumes the derived
* values via readEnv().mcp.
*/
/**
* Session idle TTL in SECONDS via MCP_SESSION_TTL, default 1 hour, clamped to
* 24h so a milliseconds-value typo can't produce a 1000-hour session.
*/
export function resolveSessionTtlMs(raw: string | undefined): number {
const parsed = Number.parseInt(raw ?? "");
return Number.isFinite(parsed) && parsed > 0 ? Math.min(parsed, 24 * 60 * 60) * 1000 : 60 * 60 * 1000;
}
/**
* SSE keep-alive interval in SECONDS via MCP_SSE_KEEPALIVE, default 25s
* (below common proxy idle timeouts like nginx-ingress's 60s). 0 disables.
*/
export function resolveKeepaliveMs(raw: string | undefined): number {
const parsed = Number.parseInt(raw ?? "");
return Number.isFinite(parsed) && parsed >= 0 ? parsed * 1000 : 25_000;
}
export { resolveSessionTtlMs, resolveKeepaliveMs } from '../app-config/parsers';
+8 -8
View File
@@ -10,7 +10,7 @@ import { ADDON_IDS } from '../addons';
import { registerResources } from './resources';
import { registerTools } from './tools';
import { McpSession, sessions, revokeUserSessions, revokeUserSessionsForClient, evictOldestSessionForUser } from './sessionManager';
import { resolveSessionTtlMs, resolveKeepaliveMs } from './config';
import { readEnv } from '../app-config';
import { writeAudit, getClientIp } from '../services/auditLog';
import { getMcpSafeUrl } from '../services/notifications';
@@ -96,11 +96,12 @@ const STATIC_TOKEN_DEPRECATION_NOTICE =
'Please migrate to OAuth 2.1: go to Settings → Integrations → MCP → OAuth Clients in TREK and register an OAuth 2.1 application." ' +
'The actual tool result follows — answer the user\'s question as well.';
// Configurable session TTL + SSE keep-alive cadence (#1414); see mcp/config.ts.
const SESSION_TTL_MS = resolveSessionTtlMs(process.env.MCP_SESSION_TTL);
const sessionParsed = Number.parseInt(process.env.MCP_MAX_SESSION_PER_USER ?? "");
const MAX_SESSIONS_PER_USER = Number.isFinite(sessionParsed) && sessionParsed > 0 ? sessionParsed : 20;
const KEEPALIVE_MS = resolveKeepaliveMs(process.env.MCP_SSE_KEEPALIVE);
// Configurable session TTL + SSE keep-alive cadence (#1414).
// Frozen at import on purpose (legacy timing) — MCP tuning knobs are boot-stable.
const mcpEnv = readEnv().mcp;
const SESSION_TTL_MS = mcpEnv.sessionTtlMs;
const MAX_SESSIONS_PER_USER = mcpEnv.maxSessionsPerUser;
const KEEPALIVE_MS = mcpEnv.sseKeepaliveMs;
/**
* Write SSE comment frames on an interval while the response is an open
@@ -130,8 +131,7 @@ function armSseKeepalive(res: Response, touch?: () => void): void {
res.once('close', () => clearInterval(timer));
}
const RATE_LIMIT_WINDOW_MS = 60 * 1000; // 1 minute
const parsed = Number.parseInt(process.env.MCP_RATE_LIMIT ?? "");
const RATE_LIMIT_MAX = Number.isFinite(parsed) && parsed > 0 ? parsed : 300; // requests per minute per user
const RATE_LIMIT_MAX = mcpEnv.rateLimitMax; // requests per minute per user
interface RateLimitEntry {
count: number;