/** * sh-mcp-finance application assembly. * * Same shared host as ops, but the registry holds finance-tier tools — so every * call is audited and redacted on egress by the shared dispatcher (design.md * §2.5, §7.3). Exported separately from `index.ts` for tests. */ import { ConsoleAuditLogger, InMemoryRateLimiter, createApp, type DispatchDeps, } from '@sh-mcp/shared'; import type { Express } from 'express'; import { buildFinanceRegistry } from './registry.js'; import { buildFinanceAuthProvider } from './auth.js'; import { loadFinanceConfig, type FinanceConfig } from './config.js'; export interface BuildAppResult { app: Express; config: FinanceConfig; } export function buildFinanceApp(configOverride?: FinanceConfig): BuildAppResult { const config = configOverride ?? loadFinanceConfig(); const registry = buildFinanceRegistry(config); const authProvider = buildFinanceAuthProvider(config); const deps: DispatchDeps = { auditLogger: new ConsoleAuditLogger(), // Finance is read-only and lower-volume; cap tighter than ops. rateLimiter: new InMemoryRateLimiter({ sessionCap: 100, perToolLimit: 30, windowMs: 60_000, }), }; const app = createApp({ registry, authProvider, deps, mcpInfo: { name: 'sh-mcp-finance', version: '0.1.0' }, openApi: { info: { title: 'Sea Haven MCP — Finance', version: '0.1.0', description: 'Finance-tier tools (sensitive, read-only, audited). design.md §3.', }, servers: [{ url: `http://localhost:${config.port}`, description: 'local' }], }, }); return { app, config }; }