@toolrelay/cli 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/config-loader.ts","../src/audit-logger.ts","../src/oauth-handler.ts","../src/session-store.ts","../src/mcp-server.ts","../src/ui-html.ts","../src/ui-server.ts","../src/wizard.ts","../src/index.ts"],"names":["BOLD","DIM","RESET","RED","GREEN","YELLOW","resolve","existsSync","writeFileSync","randomUUID","readFileSync","sessions","CYAN","MAGENTA","WHITE","createSession","crypto","elapsed","createServer","appSlug","openBrowser","exec","__dirname","join"],"mappings":"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A;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAA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","file":"index.js","sourcesContent":["import { readFileSync } from 'node:fs';\nimport { z } from 'zod';\nimport { AuthType, HttpMethod, PermissionLevel, TOOL_NAME_REGEX, TOOL_NAME_MESSAGE, SLUG_REGEX, SLUG_MESSAGE, mcpAnnotationsSchema } from '@toolrelay/shared';\nimport type { CliConfig } from './types.js';\n\n// ─── Zod schemas for config validation ──────────────────────────────────────\n\nconst parameterMappingSchema = z.object({\n name: z.string().min(1),\n type: z.enum(['string', 'number', 'boolean', 'object', 'array']),\n required: z.boolean(),\n description: z.string().optional(),\n target: z.enum(['path', 'query', 'body', 'header']),\n backend_key: z.string().optional(),\n default_value: z.unknown().optional(),\n});\n\nconst appConfigSchema = z.object({\n name: z.string().min(1),\n description: z.string().max(500).optional(),\n slug: z.string().regex(SLUG_REGEX, SLUG_MESSAGE).optional(),\n base_url: z.string().url(),\n auth_type: z.nativeEnum(AuthType),\n auth_config: z.record(z.unknown()).optional(),\n global_headers: z.record(z.string(), z.string()).optional(),\n});\n\nconst toolConfigSchema = z.object({\n name: z.string().min(1).regex(TOOL_NAME_REGEX, TOOL_NAME_MESSAGE),\n description: z.string().optional(),\n http_method: z.nativeEnum(HttpMethod),\n endpoint_path: z.string().min(1),\n parameter_mapping: z.array(parameterMappingSchema).default([]),\n permission_level: z.nativeEnum(PermissionLevel).optional(),\n headers_template: z.record(z.string()).optional(),\n request_schema: z.record(z.unknown()).optional(),\n response_schema: z.record(z.unknown()).optional(),\n mcp_annotations: mcpAnnotationsSchema.optional(),\n});\n\nconst cliConfigSchema = z.object({\n app: appConfigSchema,\n tools: z.array(toolConfigSchema).min(1, 'At least one tool is required'),\n});\n\n// ─── Environment variable interpolation ──────────────────────────────────────\n//\n// Supports ${VAR_NAME} syntax in string values throughout the config.\n// This allows secrets (client_id, client_secret, tokens) to be kept in env\n// vars rather than committed to the config file.\n//\n// Example: \"client_secret\": \"${OAUTH_CLIENT_SECRET}\"\n\nconst ENV_VAR_PATTERN = /\\$\\{([^}]+)\\}/g;\n\n/**\n * Recursively walk a parsed JSON value and replace `${VAR}` references in\n * strings with the corresponding environment variable. Unresolved references\n * are collected into the `missing` set so the caller can report them.\n */\nfunction interpolateEnvVars(value: unknown, missing: Set<string>): unknown {\n if (typeof value === 'string') {\n return value.replace(ENV_VAR_PATTERN, (_match, varName: string) => {\n const envVal = process.env[varName];\n if (envVal === undefined) {\n missing.add(varName);\n return ''; // placeholder — will fail validation if required\n }\n return envVal;\n });\n }\n if (Array.isArray(value)) {\n return value.map((item) => interpolateEnvVars(item, missing));\n }\n if (value !== null && typeof value === 'object') {\n const result: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(value as Record<string, unknown>)) {\n result[key] = interpolateEnvVars(val, missing);\n }\n return result;\n }\n return value;\n}\n\n// ─── Config loading ─────────────────────────────────────────────────────────\n\nexport interface ConfigLoadResult {\n success: boolean;\n config?: CliConfig;\n errors: ConfigError[];\n}\n\nexport interface ConfigError {\n path: string;\n message: string;\n}\n\nexport function loadConfig(filePath: string): ConfigLoadResult {\n let raw: string;\n try {\n raw = readFileSync(filePath, 'utf-8');\n } catch (err) {\n return {\n success: false,\n errors: [{ path: filePath, message: `Cannot read file: ${(err as Error).message}` }],\n };\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (err) {\n return {\n success: false,\n errors: [{ path: filePath, message: `Invalid JSON: ${(err as Error).message}` }],\n };\n }\n\n // Resolve ${VAR} references before schema validation\n const missingEnvVars = new Set<string>();\n parsed = interpolateEnvVars(parsed, missingEnvVars);\n\n if (missingEnvVars.size > 0) {\n const vars = [...missingEnvVars].join(', ');\n return {\n success: false,\n errors: [{ path: filePath, message: `Missing environment variables: ${vars}` }],\n };\n }\n\n const result = cliConfigSchema.safeParse(parsed);\n if (!result.success) {\n const errors: ConfigError[] = result.error.issues.map((issue) => ({\n path: issue.path.join('.'),\n message: issue.message,\n }));\n return { success: false, errors };\n }\n\n const config = result.data as CliConfig;\n\n // Cross-validation: check path parameters have matching placeholders\n const toolNames = new Set(config.tools.map((t) => t.name));\n const crossErrors: ConfigError[] = [];\n for (const tool of config.tools) {\n const pathParams = tool.parameter_mapping.filter((p) => p.target === 'path');\n for (const param of pathParams) {\n const key = param.backend_key ?? param.name;\n if (!tool.endpoint_path.includes(`{${key}}`)) {\n crossErrors.push({\n path: `tools[name=\"${tool.name}\"].parameter_mapping[name=\"${param.name}\"]`,\n message: `Path parameter \"${key}\" has no matching {${key}} placeholder in endpoint_path \"${tool.endpoint_path}\"`,\n });\n }\n }\n\n // Check for unreplaced placeholders with no matching path param\n const placeholderRegex = /\\{([^}]+)\\}/g;\n let match;\n while ((match = placeholderRegex.exec(tool.endpoint_path)) !== null) {\n const placeholder = match[1]!;\n const hasParam = pathParams.some((p) => (p.backend_key ?? p.name) === placeholder);\n if (!hasParam) {\n crossErrors.push({\n path: `tools[name=\"${tool.name}\"].endpoint_path`,\n message: `Placeholder {${placeholder}} in endpoint has no matching path parameter mapping`,\n });\n }\n }\n }\n\n if (crossErrors.length > 0) {\n return { success: false, config, errors: crossErrors };\n }\n\n return { success: true, config, errors: [] };\n}\n","import { writeFileSync, appendFileSync, existsSync } from 'node:fs';\nimport { randomUUID } from 'node:crypto';\nimport type {\n AuditEntry,\n AuditSummary,\n AuditError,\n ParameterResolution,\n ValidationResult,\n} from './types.js';\nimport type { HttpMethod, ParameterMapping } from '@toolrelay/shared';\n\n// ─── ANSI color helpers (no dependencies) ───────────────────────────────────\n\nconst RESET = '\\x1b[0m';\nconst BOLD = '\\x1b[1m';\nconst DIM = '\\x1b[2m';\nconst RED = '\\x1b[31m';\nconst GREEN = '\\x1b[32m';\nconst YELLOW = '\\x1b[33m';\nconst BLUE = '\\x1b[34m';\nconst MAGENTA = '\\x1b[35m';\nconst CYAN = '\\x1b[36m';\nconst GRAY = '\\x1b[90m';\nconst WHITE = '\\x1b[37m';\nconst BG_RED = '\\x1b[41m';\nconst BG_GREEN = '\\x1b[42m';\nconst BG_YELLOW = '\\x1b[43m';\nconst BG_BLUE = '\\x1b[44m';\n\n// ─── Public API ─────────────────────────────────────────────────────────────\n\nexport class AuditLogger {\n private entries: AuditEntry[] = [];\n private outputPath: string | undefined;\n private verbose: boolean;\n\n constructor(options: { outputPath?: string; verbose?: boolean } = {}) {\n this.outputPath = options.outputPath;\n this.verbose = options.verbose ?? false;\n\n if (this.outputPath) {\n // Initialize JSONL file with empty content (overwrite if exists)\n writeFileSync(this.outputPath, '');\n }\n }\n\n /**\n * Create a new audit entry builder for an invocation.\n */\n startInvocation(toolName: string, toolMethod: HttpMethod, toolEndpoint: string): AuditEntryBuilder {\n return new AuditEntryBuilder(this, toolName, toolMethod, toolEndpoint);\n }\n\n /**\n * Called by AuditEntryBuilder when an invocation is complete.\n * Stores the entry, prints it, and optionally writes to file.\n */\n recordEntry(entry: AuditEntry): void {\n this.entries.push(entry);\n this.printEntry(entry);\n\n if (this.outputPath) {\n appendFileSync(this.outputPath, JSON.stringify(entry) + '\\n');\n }\n }\n\n /**\n * Print a final summary of all recorded invocations.\n */\n printSummary(): AuditSummary {\n const summary = this.buildSummary();\n this.renderSummary(summary);\n return summary;\n }\n\n getEntries(): readonly AuditEntry[] {\n return this.entries;\n }\n\n // ─── Terminal rendering ─────────────────────────────────────────────────\n\n private printEntry(entry: AuditEntry): void {\n const statusColor = entry.success ? GREEN : RED;\n const statusIcon = entry.success ? '\\u2713' : '\\u2717';\n const statusBg = entry.success ? BG_GREEN : BG_RED;\n\n const border = '\\u2500'.repeat(68);\n const topBorder = `\\u250C${border}`;\n const midBorder = `\\u251C${border}`;\n const botBorder = `\\u2514${border}`;\n\n console.log('');\n console.log(`${statusColor}${topBorder}${RESET}`);\n console.log(`${statusColor}\\u2502${RESET} ${statusBg}${BOLD}${WHITE} ${statusIcon} ${RESET} ${BOLD}${entry.tool_name}${RESET} ${DIM}${entry.invocation_id}${RESET}`);\n console.log(`${statusColor}\\u2502${RESET} ${DIM}${entry.timestamp}${RESET} ${DIM}\\u2022${RESET} ${BOLD}${entry.total_time_ms}ms${RESET}`);\n\n // ── Input ──────────────────────────────────────────────────────────\n console.log(`${statusColor}${midBorder}${RESET}`);\n console.log(`${statusColor}\\u2502${RESET} ${CYAN}${BOLD}INPUT${RESET}`);\n console.log(`${statusColor}\\u2502${RESET} ${this.formatJson(entry.raw_input, 4)}`);\n\n // ── Parameter Resolution ──────────────────────────────────────────\n if (entry.parameter_resolutions.length > 0) {\n console.log(`${statusColor}${midBorder}${RESET}`);\n console.log(`${statusColor}\\u2502${RESET} ${MAGENTA}${BOLD}PARAMETER RESOLUTION${RESET}`);\n for (const p of entry.parameter_resolutions) {\n const sourceTag = p.source === 'default' ? ` ${YELLOW}(default)${RESET}` : p.source === 'missing' ? ` ${RED}(missing)${RESET}` : '';\n const reqTag = p.required ? ` ${DIM}required${RESET}` : '';\n const keyInfo = p.backend_key !== p.name ? ` ${DIM}\\u2192 ${p.backend_key}${RESET}` : '';\n console.log(`${statusColor}\\u2502${RESET} ${DIM}\\u2022${RESET} ${BOLD}${p.name}${RESET}${keyInfo} \\u2192 ${BLUE}${p.target}${RESET} ${DIM}=${RESET} ${this.formatValue(p.value)}${sourceTag}${reqTag}`);\n }\n }\n\n // ── Input Validation ──────────────────────────────────────────────\n if (entry.input_validation) {\n this.renderValidation(statusColor, 'INPUT VALIDATION', entry.input_validation);\n }\n\n // ── Built Request ─────────────────────────────────────────────────\n console.log(`${statusColor}${midBorder}${RESET}`);\n console.log(`${statusColor}\\u2502${RESET} ${BLUE}${BOLD}REQUEST${RESET}`);\n console.log(`${statusColor}\\u2502${RESET} ${BOLD}${entry.request_method}${RESET} ${entry.request_url}`);\n console.log(`${statusColor}\\u2502${RESET} ${DIM}Headers:${RESET}`);\n for (const [key, value] of Object.entries(entry.request_headers)) {\n const masked = this.maybeMask(key, value);\n console.log(`${statusColor}\\u2502${RESET} ${DIM}${key}:${RESET} ${masked}`);\n }\n if (entry.request_body !== undefined) {\n console.log(`${statusColor}\\u2502${RESET} ${DIM}Body:${RESET}`);\n console.log(`${statusColor}\\u2502${RESET} ${this.formatJson(entry.request_body, 6)}`);\n }\n\n // ── Response ──────────────────────────────────────────────────────\n if (entry.response_status !== undefined) {\n console.log(`${statusColor}${midBorder}${RESET}`);\n console.log(`${statusColor}\\u2502${RESET} ${this.statusColor(entry.response_status)}${BOLD}RESPONSE${RESET} ${this.statusBadge(entry.response_status, entry.response_status_text)}`);\n console.log(`${statusColor}\\u2502${RESET} ${DIM}Size:${RESET} ${entry.response_body_size_bytes ?? 0} bytes ${DIM}\\u2022${RESET} ${DIM}Time:${RESET} ${entry.total_time_ms}ms`);\n\n if (this.verbose && entry.response_headers) {\n console.log(`${statusColor}\\u2502${RESET} ${DIM}Headers:${RESET}`);\n for (const [key, value] of Object.entries(entry.response_headers)) {\n console.log(`${statusColor}\\u2502${RESET} ${DIM}${key}:${RESET} ${value}`);\n }\n }\n\n if (entry.response_body !== undefined) {\n console.log(`${statusColor}\\u2502${RESET} ${DIM}Body:${RESET}`);\n console.log(`${statusColor}\\u2502${RESET} ${this.formatJson(entry.response_body, 6)}`);\n } else if (entry.response_body_raw !== undefined) {\n console.log(`${statusColor}\\u2502${RESET} ${DIM}Body (raw):${RESET}`);\n const truncated = entry.response_body_raw.length > 2000\n ? entry.response_body_raw.slice(0, 2000) + `\\n${DIM}... truncated (${entry.response_body_raw.length} bytes total)${RESET}`\n : entry.response_body_raw;\n console.log(`${statusColor}\\u2502${RESET} ${truncated}`);\n }\n }\n\n // ── Response Validation ───────────────────────────────────────────\n if (entry.response_validation) {\n this.renderValidation(statusColor, 'RESPONSE VALIDATION', entry.response_validation);\n }\n\n // ── Error ─────────────────────────────────────────────────────────\n if (entry.error) {\n console.log(`${statusColor}${midBorder}${RESET}`);\n console.log(`${statusColor}\\u2502${RESET} ${BG_RED}${WHITE}${BOLD} ERROR ${RESET} ${DIM}phase:${RESET} ${entry.error.phase}`);\n console.log(`${statusColor}\\u2502${RESET} ${RED}${entry.error.message}${RESET}`);\n if (entry.error.details) {\n console.log(`${statusColor}\\u2502${RESET} ${DIM}${entry.error.details}${RESET}`);\n }\n }\n\n // ── Diagnostics ───────────────────────────────────────────────────\n if (entry.diagnostics.length > 0) {\n console.log(`${statusColor}${midBorder}${RESET}`);\n console.log(`${statusColor}\\u2502${RESET} ${YELLOW}${BOLD}DIAGNOSTICS${RESET}`);\n for (const diag of entry.diagnostics) {\n console.log(`${statusColor}\\u2502${RESET} ${YELLOW}\\u26A0${RESET} ${diag}`);\n }\n }\n\n console.log(`${statusColor}${botBorder}${RESET}`);\n }\n\n private renderValidation(statusColor: string, label: string, validation: ValidationResult): void {\n const icon = validation.valid ? `${GREEN}\\u2713${RESET}` : `${RED}\\u2717${RESET}`;\n console.log(`${statusColor}\\u2502${RESET}`);\n console.log(`${statusColor}\\u2502${RESET} ${icon} ${DIM}${label}${RESET}`);\n if (!validation.valid) {\n for (const err of validation.errors) {\n console.log(`${statusColor}\\u2502${RESET} ${RED}\\u2022 ${err}${RESET}`);\n }\n }\n }\n\n private renderSummary(summary: AuditSummary): void {\n const border = '\\u2550'.repeat(68);\n console.log('');\n console.log(`${BOLD}\\u2554${border}\\u2557${RESET}`);\n console.log(`${BOLD}\\u2551${RESET} ${BOLD}AUDIT SUMMARY${RESET}${' '.repeat(55)}${BOLD}\\u2551${RESET}`);\n console.log(`${BOLD}\\u2560${border}\\u2563${RESET}`);\n\n const passRate = summary.total_calls > 0 ? Math.round((summary.passed / summary.total_calls) * 100) : 0;\n const passColor = passRate === 100 ? GREEN : passRate >= 50 ? YELLOW : RED;\n\n console.log(`${BOLD}\\u2551${RESET} Total calls: ${BOLD}${summary.total_calls}${RESET}${' '.repeat(52 - String(summary.total_calls).length)}${BOLD}\\u2551${RESET}`);\n console.log(`${BOLD}\\u2551${RESET} ${GREEN}Passed:${RESET} ${BOLD}${summary.passed}${RESET}${' '.repeat(52 - String(summary.passed).length)}${BOLD}\\u2551${RESET}`);\n console.log(`${BOLD}\\u2551${RESET} ${RED}Failed:${RESET} ${BOLD}${summary.failed}${RESET}${' '.repeat(52 - String(summary.failed).length)}${BOLD}\\u2551${RESET}`);\n console.log(`${BOLD}\\u2551${RESET} Pass rate: ${passColor}${BOLD}${passRate}%${RESET}${' '.repeat(52 - String(passRate).length - 1)}${BOLD}\\u2551${RESET}`);\n console.log(`${BOLD}\\u2551${RESET} Avg latency: ${BOLD}${summary.avg_response_time_ms}ms${RESET}${' '.repeat(50 - String(summary.avg_response_time_ms).length)}${BOLD}\\u2551${RESET}`);\n\n if (Object.keys(summary.errors_by_phase).length > 0) {\n console.log(`${BOLD}\\u2560${border}\\u2563${RESET}`);\n console.log(`${BOLD}\\u2551${RESET} ${RED}${BOLD}Errors by phase:${RESET}${' '.repeat(52)}${BOLD}\\u2551${RESET}`);\n for (const [phase, count] of Object.entries(summary.errors_by_phase)) {\n const padLen = 52 - phase.length - String(count).length - 2;\n console.log(`${BOLD}\\u2551${RESET} ${phase}: ${RED}${count}${RESET}${' '.repeat(Math.max(0, padLen))}${BOLD}\\u2551${RESET}`);\n }\n }\n\n console.log(`${BOLD}\\u255A${border}\\u255D${RESET}`);\n\n if (this.outputPath) {\n console.log(`\\n${DIM}Full audit log written to: ${this.outputPath}${RESET}`);\n }\n }\n\n private buildSummary(): AuditSummary {\n const total = this.entries.length;\n const passed = this.entries.filter((e) => e.success).length;\n const failed = total - passed;\n const avgTime = total > 0\n ? Math.round(this.entries.reduce((sum, e) => sum + e.total_time_ms, 0) / total)\n : 0;\n\n const errorsByPhase: Record<string, number> = {};\n for (const entry of this.entries) {\n if (entry.error) {\n errorsByPhase[entry.error.phase] = (errorsByPhase[entry.error.phase] ?? 0) + 1;\n }\n }\n\n return {\n total_calls: total,\n passed,\n failed,\n avg_response_time_ms: avgTime,\n errors_by_phase: errorsByPhase,\n entries: this.entries,\n };\n }\n\n // ─── Formatting helpers ─────────────────────────────────────────────────\n\n private formatJson(value: unknown, indent: number): string {\n const indentStr = ' '.repeat(indent);\n const raw = JSON.stringify(value, null, 2);\n return raw.split('\\n').join(`\\n${indentStr}`);\n }\n\n private formatValue(value: unknown): string {\n if (value === undefined) return `${DIM}undefined${RESET}`;\n if (value === null) return `${DIM}null${RESET}`;\n if (typeof value === 'string') return `${GREEN}\"${value}\"${RESET}`;\n if (typeof value === 'number') return `${CYAN}${value}${RESET}`;\n if (typeof value === 'boolean') return `${YELLOW}${value}${RESET}`;\n return this.formatJson(value, 0);\n }\n\n private maybeMask(headerName: string, value: string): string {\n const sensitive = ['authorization', 'x-api-key', 'cookie', 'x-toolrelay-verify'];\n if (sensitive.includes(headerName.toLowerCase())) {\n if (value.length <= 12) return `${DIM}***masked***${RESET}`;\n return `${value.slice(0, 12)}${DIM}...masked${RESET}`;\n }\n return value;\n }\n\n private statusColor(status: number): string {\n if (status >= 200 && status < 300) return GREEN;\n if (status >= 300 && status < 400) return YELLOW;\n if (status >= 400 && status < 500) return RED;\n return RED;\n }\n\n private statusBadge(status: number, statusText?: string): string {\n const text = statusText ?? '';\n if (status >= 200 && status < 300) return `${BG_GREEN}${WHITE}${BOLD} ${status} ${text} ${RESET}`;\n if (status >= 300 && status < 400) return `${BG_YELLOW}${WHITE}${BOLD} ${status} ${text} ${RESET}`;\n return `${BG_RED}${WHITE}${BOLD} ${status} ${text} ${RESET}`;\n }\n}\n\n// ─── Builder for constructing audit entries step-by-step ────────────────────\n\nexport class AuditEntryBuilder {\n private logger: AuditLogger;\n private entry: AuditEntry;\n private startTime: number;\n\n constructor(logger: AuditLogger, toolName: string, toolMethod: HttpMethod, toolEndpoint: string) {\n this.logger = logger;\n this.startTime = performance.now();\n this.entry = {\n invocation_id: randomUUID().slice(0, 8),\n timestamp: new Date().toISOString(),\n tool_name: toolName,\n tool_method: toolMethod,\n tool_endpoint: toolEndpoint,\n raw_input: {},\n parameter_resolutions: [],\n request_url: '',\n request_method: toolMethod,\n request_headers: {},\n request_body: undefined,\n total_time_ms: 0,\n success: false,\n diagnostics: [],\n };\n }\n\n setInput(input: Record<string, unknown>): this {\n this.entry.raw_input = input;\n return this;\n }\n\n /**\n * Record how each parameter was resolved — the mapping from input to request.\n */\n recordParameterResolutions(mappings: ParameterMapping[], input: Record<string, unknown>): this {\n this.entry.parameter_resolutions = mappings.map((m): ParameterResolution => {\n const hasValue = m.name in input;\n const hasDefault = m.default_value !== undefined;\n let source: 'input' | 'default' | 'missing';\n let value: unknown;\n\n if (hasValue) {\n source = 'input';\n value = input[m.name];\n } else if (hasDefault) {\n source = 'default';\n value = m.default_value;\n } else {\n source = 'missing';\n value = undefined;\n }\n\n return {\n name: m.name,\n target: m.target,\n backend_key: m.backend_key ?? m.name,\n value,\n source,\n required: m.required,\n };\n });\n return this;\n }\n\n setRequest(url: string, method: HttpMethod, headers: Record<string, string>, body?: unknown): this {\n this.entry.request_url = url;\n this.entry.request_method = method;\n this.entry.request_headers = { ...headers };\n this.entry.request_body = body;\n return this;\n }\n\n setResponse(status: number, statusText: string, headers: Record<string, string>, body: unknown, bodyRaw: string): this {\n this.entry.response_status = status;\n this.entry.response_status_text = statusText;\n this.entry.response_headers = headers;\n this.entry.response_body = body;\n this.entry.response_body_raw = bodyRaw;\n this.entry.response_body_size_bytes = Buffer.byteLength(bodyRaw, 'utf-8');\n return this;\n }\n\n setInputValidation(result: ValidationResult): this {\n this.entry.input_validation = result;\n return this;\n }\n\n setResponseValidation(result: ValidationResult): this {\n this.entry.response_validation = result;\n return this;\n }\n\n setError(error: AuditError): this {\n this.entry.error = error;\n this.entry.success = false;\n return this;\n }\n\n addDiagnostic(message: string): this {\n this.entry.diagnostics.push(message);\n return this;\n }\n\n /**\n * Finalize the entry, record timing, and send to the logger.\n */\n finish(success?: boolean): AuditEntry {\n this.entry.total_time_ms = Math.round(performance.now() - this.startTime);\n if (success !== undefined) {\n this.entry.success = success;\n } else {\n // Auto-determine success from response status and error presence\n this.entry.success = !this.entry.error\n && this.entry.response_status !== undefined\n && this.entry.response_status >= 200\n && this.entry.response_status < 400;\n }\n\n // Auto-generate diagnostics for common issues\n this.autoDiagnose();\n\n this.logger.recordEntry(this.entry);\n return this.entry;\n }\n\n // ─── Auto-diagnosis ───────────────────────────────────────────────────\n\n private autoDiagnose(): void {\n // Missing required params\n for (const p of this.entry.parameter_resolutions) {\n if (p.required && p.source === 'missing') {\n this.entry.diagnostics.push(\n `Required parameter \"${p.name}\" was not provided and has no default value`\n );\n }\n }\n\n // Slow response\n if (this.entry.total_time_ms > 5000) {\n this.entry.diagnostics.push(\n `Response took ${this.entry.total_time_ms}ms — consider backend optimization or check network`\n );\n }\n\n // Large response body\n if (this.entry.response_body_size_bytes && this.entry.response_body_size_bytes > 1_000_000) {\n this.entry.diagnostics.push(\n `Response body is ${(this.entry.response_body_size_bytes / 1_000_000).toFixed(1)}MB — large responses increase latency for AI agents`\n );\n }\n\n // Non-JSON response for non-GET\n if (this.entry.response_headers\n && !this.entry.response_headers['content-type']?.includes('application/json')\n && this.entry.response_status !== undefined\n && this.entry.response_status < 300) {\n this.entry.diagnostics.push(\n `Response Content-Type is \"${this.entry.response_headers['content-type'] ?? 'missing'}\" — MCP tools work best with JSON responses`\n );\n }\n\n // 4xx with hints\n if (this.entry.response_status === 401 || this.entry.response_status === 403) {\n this.entry.diagnostics.push(\n 'Authentication rejected by backend — verify auth_config credentials are correct'\n );\n }\n\n if (this.entry.response_status === 404) {\n this.entry.diagnostics.push(\n `Backend returned 404 for ${this.entry.request_method} ${this.entry.request_url} — verify endpoint_path is correct`\n );\n }\n\n if (this.entry.response_status === 405) {\n this.entry.diagnostics.push(\n `Backend returned 405 Method Not Allowed — the endpoint may not accept ${this.entry.request_method} requests`\n );\n }\n\n if (this.entry.response_status === 422 || this.entry.response_status === 400) {\n this.entry.diagnostics.push(\n 'Backend rejected the request body — check parameter_mapping targets and backend_key values match what the backend expects'\n );\n }\n\n // Unresolved path placeholders\n if (this.entry.request_url.includes('{') && this.entry.request_url.includes('}')) {\n const unresolved = this.entry.request_url.match(/\\{[^}]+\\}/g);\n if (unresolved) {\n this.entry.diagnostics.push(\n `URL contains unresolved placeholders: ${unresolved.join(', ')} — add path parameter mappings for these`\n );\n }\n }\n\n // Connection errors\n if (this.entry.error?.phase === 'network') {\n if (this.entry.error.message.includes('ECONNREFUSED')) {\n this.entry.diagnostics.push(\n 'Connection refused — is the backend server running?'\n );\n }\n if (this.entry.error.message.includes('ENOTFOUND')) {\n this.entry.diagnostics.push(\n 'DNS resolution failed — check base_url hostname'\n );\n }\n }\n\n if (this.entry.error?.phase === 'timeout') {\n this.entry.diagnostics.push(\n 'Request timed out — backend may be overloaded or endpoint may be hanging'\n );\n }\n }\n}\n","import { createServer } from 'node:http';\nimport type { Server } from 'node:http';\nimport crypto from 'node:crypto';\nimport { exec } from 'node:child_process';\n\n// ─── Types ──────────────────────────────────────────────────────────────────\n\nexport interface OAuthConfig {\n authorize_url: string;\n token_url: string;\n client_id: string;\n client_secret: string;\n scopes: string;\n use_pkce?: boolean; // default true — set false for providers that reject PKCE params (e.g., Cognito confidential clients)\n}\n\ninterface TokenSet {\n access_token: string;\n refresh_token?: string;\n expires_at: number; // epoch ms, 0 = no expiry known\n}\n\n// ANSI helpers (match mcp-server.ts)\nconst BOLD = '\\x1b[1m';\nconst DIM = '\\x1b[2m';\nconst RESET = '\\x1b[0m';\nconst RED = '\\x1b[31m';\nconst GREEN = '\\x1b[32m';\nconst YELLOW = '\\x1b[33m';\n\n// ─── PKCE helpers ───────────────────────────────────────────────────────────\n\nfunction generateCodeVerifier(): string {\n return crypto.randomBytes(32).toString('base64url');\n}\n\nfunction generateCodeChallenge(verifier: string): string {\n return crypto.createHash('sha256').update(verifier).digest('base64url');\n}\n\n// ─── OAuthTokenStore (in-memory, session-scoped) ────────────────────────────\n\nconst REFRESH_BUFFER_MS = 60_000; // refresh 60s before expiry\n\nexport class OAuthTokenStore {\n private tokens: TokenSet | null = null;\n\n isAuthenticated(): boolean {\n if (!this.tokens) return false;\n if (this.tokens.expires_at === 0) return true; // no expiry info\n return Date.now() < this.tokens.expires_at;\n }\n\n needsRefresh(): boolean {\n if (!this.tokens) return false;\n if (this.tokens.expires_at === 0) return false; // no expiry info — assume valid\n return Date.now() >= this.tokens.expires_at - REFRESH_BUFFER_MS;\n }\n\n getTokens(): TokenSet | null {\n return this.tokens;\n }\n\n setTokens(tokens: TokenSet): void {\n this.tokens = tokens;\n }\n\n clear(): void {\n this.tokens = null;\n }\n}\n\n// ─── Browser opener ─────────────────────────────────────────────────────────\n\nfunction openBrowser(url: string): void {\n const cmd =\n process.platform === 'darwin'\n ? 'open'\n : process.platform === 'win32'\n ? 'start \"\"'\n : 'xdg-open';\n\n exec(`${cmd} \"${url}\"`, (err) => {\n if (err) {\n console.log(`${YELLOW}${BOLD}[OAuth]${RESET} Could not open browser automatically.`);\n console.log(`${YELLOW}${BOLD}[OAuth]${RESET} Open this URL in your browser:\\n`);\n console.log(` ${url}\\n`);\n }\n });\n}\n\n// ─── Success page HTML ──────────────────────────────────────────────────────\n\nconst SUCCESS_HTML = `<!DOCTYPE html>\n<html><head><title>ToolRelay — OAuth Complete</title>\n<style>body{font-family:system-ui,sans-serif;display:flex;justify-content:center;align-items:center;height:100vh;margin:0;background:#f9fafb}\n.card{text-align:center;padding:2rem 3rem;border-radius:12px;background:#fff;box-shadow:0 2px 8px rgba(0,0,0,.08)}\nh1{color:#16a34a;margin:0 0 .5rem}p{color:#6b7280;margin:0}</style></head>\n<body><div class=\"card\"><h1>Authenticated</h1><p>You can close this tab and return to the terminal.</p></div></body></html>`;\n\nfunction escapeHtml(s: string): string {\n return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;');\n}\n\nconst ERROR_HTML = (msg: string) => `<!DOCTYPE html>\n<html><head><title>ToolRelay — OAuth Error</title>\n<style>body{font-family:system-ui,sans-serif;display:flex;justify-content:center;align-items:center;height:100vh;margin:0;background:#f9fafb}\n.card{text-align:center;padding:2rem 3rem;border-radius:12px;background:#fff;box-shadow:0 2px 8px rgba(0,0,0,.08)}\nh1{color:#dc2626;margin:0 0 .5rem}p{color:#6b7280;margin:0}</style></head>\n<body><div class=\"card\"><h1>Authentication Failed</h1><p>${escapeHtml(msg)}</p></div></body></html>`;\n\n// ─── Token exchange ─────────────────────────────────────────────────────────\n\nasync function exchangeCodeForTokens(\n config: OAuthConfig,\n code: string,\n redirectUri: string,\n codeVerifier: string | null,\n): Promise<TokenSet> {\n const body = new URLSearchParams({\n grant_type: 'authorization_code',\n code,\n redirect_uri: redirectUri,\n });\n\n // Only include client credentials if provided (public client PKCE model\n // doesn't require them, matching the onboarding wizard validation).\n if (config.client_id) body.set('client_id', config.client_id);\n if (config.client_secret) body.set('client_secret', config.client_secret);\n if (codeVerifier) body.set('code_verifier', codeVerifier);\n\n const res = await fetch(config.token_url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: body.toString(),\n });\n\n if (!res.ok) {\n const text = await res.text();\n throw new Error(`Token exchange failed (${res.status}): ${text}`);\n }\n\n const data = (await res.json()) as Record<string, unknown>;\n const access_token = data.access_token as string;\n if (!access_token) {\n throw new Error('Token response missing access_token');\n }\n\n const expires_in = data.expires_in as number | undefined;\n return {\n access_token,\n refresh_token: (data.refresh_token as string | undefined) ?? undefined,\n expires_at: expires_in ? Date.now() + expires_in * 1000 : 0,\n };\n}\n\nasync function refreshAccessToken(\n config: OAuthConfig,\n refreshToken: string,\n): Promise<TokenSet> {\n const body = new URLSearchParams({\n grant_type: 'refresh_token',\n refresh_token: refreshToken,\n });\n\n if (config.client_id) body.set('client_id', config.client_id);\n if (config.client_secret) body.set('client_secret', config.client_secret);\n\n const res = await fetch(config.token_url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: body.toString(),\n });\n\n if (!res.ok) {\n const text = await res.text();\n throw new Error(`Token refresh failed (${res.status}): ${text}`);\n }\n\n const data = (await res.json()) as Record<string, unknown>;\n const access_token = data.access_token as string;\n if (!access_token) {\n throw new Error('Refresh response missing access_token');\n }\n\n const expires_in = data.expires_in as number | undefined;\n return {\n access_token,\n // Some providers return a new refresh token; keep the old one if not\n refresh_token: (data.refresh_token as string | undefined) ?? refreshToken,\n expires_at: expires_in ? Date.now() + expires_in * 1000 : 0,\n };\n}\n\n// ─── OAuth flow (authorization code, optionally with PKCE) ───────────────────\n\nconst FLOW_TIMEOUT_MS = 300_000; // 5 minutes\n\nexport async function startOAuthFlow(\n store: OAuthTokenStore,\n config: OAuthConfig,\n callbackPort?: number,\n): Promise<void> {\n const usePkce = config.use_pkce !== false; // default true\n const codeVerifier = usePkce ? generateCodeVerifier() : null;\n const codeChallenge = codeVerifier ? generateCodeChallenge(codeVerifier) : null;\n const state = crypto.randomBytes(16).toString('hex');\n\n return new Promise((resolve, reject) => {\n const callbackServer: Server = createServer(async (req, res) => {\n const url = new URL(req.url ?? '/', `http://localhost`);\n\n if (url.pathname !== '/callback') {\n res.writeHead(404);\n res.end('Not found');\n return;\n }\n\n // Validate state\n const returnedState = url.searchParams.get('state');\n if (returnedState !== state) {\n res.writeHead(400, { 'Content-Type': 'text/html' });\n res.end(ERROR_HTML('Invalid state parameter — possible CSRF attack.'));\n cleanup();\n reject(new Error('OAuth state mismatch'));\n return;\n }\n\n // Check for error\n const error = url.searchParams.get('error');\n if (error) {\n const desc = url.searchParams.get('error_description') ?? error;\n res.writeHead(400, { 'Content-Type': 'text/html' });\n res.end(ERROR_HTML(desc));\n cleanup();\n reject(new Error(`OAuth error: ${desc}`));\n return;\n }\n\n // Extract authorization code\n const code = url.searchParams.get('code');\n if (!code) {\n res.writeHead(400, { 'Content-Type': 'text/html' });\n res.end(ERROR_HTML('Missing authorization code.'));\n cleanup();\n reject(new Error('Missing authorization code'));\n return;\n }\n\n // Exchange code for tokens\n const redirectUri = `http://localhost:${(callbackServer.address() as { port: number }).port}/callback`;\n try {\n const tokens = await exchangeCodeForTokens(config, code, redirectUri, codeVerifier);\n store.setTokens(tokens);\n res.writeHead(200, { 'Content-Type': 'text/html' });\n res.end(SUCCESS_HTML);\n cleanup();\n resolve();\n } catch (err) {\n const msg = (err as Error).message;\n res.writeHead(500, { 'Content-Type': 'text/html' });\n res.end(ERROR_HTML(msg));\n cleanup();\n reject(err);\n }\n });\n\n // Timeout\n const timer = setTimeout(() => {\n cleanup();\n reject(new Error('OAuth flow timed out — no callback received within 5 minutes'));\n }, FLOW_TIMEOUT_MS);\n\n function cleanup(): void {\n clearTimeout(timer);\n callbackServer.close();\n }\n\n // Listen on requested port or let OS pick\n callbackServer.listen(callbackPort ?? 0, '127.0.0.1', () => {\n const actualPort = (callbackServer.address() as { port: number }).port;\n const redirectUri = `http://localhost:${actualPort}/callback`;\n\n // Build authorize URL — only include client_id/scope if non-empty\n // (public client PKCE model may not require them).\n const params = new URLSearchParams({\n response_type: 'code',\n redirect_uri: redirectUri,\n state,\n });\n\n if (config.client_id) params.set('client_id', config.client_id);\n if (config.scopes) params.set('scope', config.scopes);\n\n if (codeChallenge) {\n params.set('code_challenge', codeChallenge);\n params.set('code_challenge_method', 'S256');\n }\n\n const authorizeUrl = `${config.authorize_url}?${params.toString()}`;\n\n console.log(`${YELLOW}${BOLD}[OAuth]${RESET} Opening browser for authorization...`);\n console.log(`${DIM} Callback listening on http://localhost:${actualPort}/callback${RESET}`);\n\n openBrowser(authorizeUrl);\n });\n });\n}\n\n// ─── Get a valid access token (refreshing if needed) ────────────────────────\n\n// Mutex to prevent concurrent refresh storms\nlet refreshPromise: Promise<string | null> | null = null;\n\nexport async function getAccessToken(\n store: OAuthTokenStore,\n config: OAuthConfig,\n): Promise<string | null> {\n const tokens = store.getTokens();\n\n if (!tokens) return null;\n\n // Token still valid and doesn't need refresh\n if (store.isAuthenticated() && !store.needsRefresh()) {\n return tokens.access_token;\n }\n\n // Need to refresh — deduplicate concurrent calls\n if (!tokens.refresh_token) {\n // No refresh token, can't auto-refresh\n if (!store.isAuthenticated()) {\n store.clear();\n return null;\n }\n return tokens.access_token;\n }\n\n // Deduplicate concurrent refresh attempts\n if (refreshPromise) {\n return refreshPromise;\n }\n\n refreshPromise = (async () => {\n try {\n console.log(`${DIM}[OAuth] Refreshing access token...${RESET}`);\n const newTokens = await refreshAccessToken(config, tokens.refresh_token!);\n store.setTokens(newTokens);\n console.log(`${GREEN}${BOLD}[OAuth]${RESET} Token refreshed successfully`);\n return newTokens.access_token;\n } catch (err) {\n console.error(`${RED}${BOLD}[OAuth]${RESET} Token refresh failed: ${(err as Error).message}`);\n store.clear();\n return null;\n } finally {\n refreshPromise = null;\n }\n })();\n\n return refreshPromise;\n}\n","import { mkdirSync, writeFileSync, readFileSync, readdirSync, existsSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\nimport { randomUUID } from 'node:crypto';\nimport type { AuditEntry, AuditSummary } from './types.js';\n\n// ─── Session file types ─────────────────────────────────────────────────────\n\nexport interface SessionTimelineEntry {\n seq: number;\n timestamp: string;\n tool_name: string;\n arguments: Record<string, unknown>;\n success: boolean;\n status: number | null;\n elapsed_ms: number;\n gap_since_last_ms: number | null;\n error: string | null;\n}\n\nexport interface SessionFile {\n id: string;\n type: 'serve' | 'test';\n app_name: string;\n started_at: string;\n finished_at: string | null;\n config_path: string;\n base_url: string;\n tools: string[];\n\n // Timeline (tool call sequence)\n timeline: SessionTimelineEntry[];\n\n // Full audit entries (detailed per-call traces)\n audit_entries: AuditEntry[];\n\n // Summary stats\n summary: {\n total_calls: number;\n passed: number;\n failed: number;\n avg_response_time_ms: number;\n errors_by_phase: Record<string, number>;\n } | null;\n}\n\n// ─── Storage paths ──────────────────────────────────────────────────────────\n\nconst STORE_DIR_NAME = '.toolrelay';\nconst SESSIONS_DIR_NAME = 'sessions';\n\n/**\n * Resolve the .toolrelay/sessions directory. Searches upward from cwd for an\n * existing .toolrelay dir (co-located with a toolrelay.json or project root).\n * Falls back to cwd/.toolrelay/sessions.\n */\nexport function getSessionsDir(): string {\n const cwd = process.cwd();\n return join(cwd, STORE_DIR_NAME, SESSIONS_DIR_NAME);\n}\n\nfunction ensureSessionsDir(): string {\n const dir = getSessionsDir();\n mkdirSync(dir, { recursive: true });\n\n // Add .gitignore to .toolrelay/ so sessions don't get committed\n const storeDir = resolve(dir, '..');\n const gitignorePath = join(storeDir, '.gitignore');\n if (!existsSync(gitignorePath)) {\n writeFileSync(gitignorePath, '*\\n');\n }\n\n return dir;\n}\n\n// ─── Session lifecycle ──────────────────────────────────────────────────────\n\nexport function createSession(opts: {\n type: 'serve' | 'test';\n appName: string;\n configPath: string;\n baseUrl: string;\n tools: string[];\n}): SessionFile {\n return {\n id: randomUUID().slice(0, 12),\n type: opts.type,\n app_name: opts.appName,\n started_at: new Date().toISOString(),\n finished_at: null,\n config_path: opts.configPath,\n base_url: opts.baseUrl,\n tools: opts.tools,\n timeline: [],\n audit_entries: [],\n summary: null,\n };\n}\n\nexport function addTimelineEntry(\n session: SessionFile,\n entry: Omit<SessionTimelineEntry, 'seq' | 'gap_since_last_ms'>,\n): void {\n const lastEntry = session.timeline[session.timeline.length - 1];\n let gap: number | null = null;\n if (lastEntry) {\n gap = new Date(entry.timestamp).getTime() - new Date(lastEntry.timestamp).getTime();\n }\n\n session.timeline.push({\n ...entry,\n seq: session.timeline.length + 1,\n gap_since_last_ms: gap,\n });\n}\n\nexport function finalizeSession(\n session: SessionFile,\n auditEntries: readonly AuditEntry[],\n summary: AuditSummary,\n): void {\n session.finished_at = new Date().toISOString();\n session.audit_entries = [...auditEntries];\n session.summary = {\n total_calls: summary.total_calls,\n passed: summary.passed,\n failed: summary.failed,\n avg_response_time_ms: summary.avg_response_time_ms,\n errors_by_phase: summary.errors_by_phase,\n };\n}\n\n// ─── File I/O ───────────────────────────────────────────────────────────────\n\nexport function saveSession(session: SessionFile): string {\n const dir = ensureSessionsDir();\n // Filename: timestamp-id.json for natural sort order\n const dateSlug = session.started_at.replace(/[:.]/g, '-').slice(0, 19);\n const filename = `${dateSlug}_${session.id}.json`;\n const filepath = join(dir, filename);\n writeFileSync(filepath, JSON.stringify(session, null, 2) + '\\n');\n return filepath;\n}\n\nexport function loadSession(filepath: string): SessionFile {\n const raw = readFileSync(filepath, 'utf-8');\n return JSON.parse(raw) as SessionFile;\n}\n\nexport function listSessions(): Array<{ path: string; session: SessionFile }> {\n const dir = getSessionsDir();\n if (!existsSync(dir)) return [];\n\n const files = readdirSync(dir)\n .filter((f) => f.endsWith('.json'))\n .sort()\n .reverse(); // newest first\n\n const sessions: Array<{ path: string; session: SessionFile }> = [];\n for (const file of files) {\n const filepath = join(dir, file);\n try {\n const session = loadSession(filepath);\n sessions.push({ path: filepath, session });\n } catch {\n // Skip corrupted files\n }\n }\n return sessions;\n}\n","import { createServer } from 'node:http';\nimport type { IncomingMessage, ServerResponse } from 'node:http';\nimport crypto from 'node:crypto';\nimport { buildBackendRequest, AuthType, HttpMethod, PermissionLevel } from '@toolrelay/shared';\nimport type { App, Tool, BackendRequest, ParameterMapping, McpToolAnnotations } from '@toolrelay/shared';\nimport { AuditLogger } from './audit-logger.js';\nimport type { CliConfig, CliToolConfig, ServeOptions } from './types.js';\nimport { OAuthTokenStore, startOAuthFlow, getAccessToken } from './oauth-handler.js';\nimport type { OAuthConfig } from './oauth-handler.js';\nimport {\n createSession as createStoredSession,\n addTimelineEntry as addStoredTimelineEntry,\n finalizeSession,\n saveSession,\n} from './session-store.js';\nimport type { SessionFile } from './session-store.js';\n\n// ─── Constants ──────────────────────────────────────────────────────────────\n\nconst MCP_PROTOCOL_VERSION = '2025-03-26';\n\n// ANSI helpers\nconst BOLD = '\\x1b[1m';\nconst DIM = '\\x1b[2m';\nconst RESET = '\\x1b[0m';\nconst RED = '\\x1b[31m';\nconst GREEN = '\\x1b[32m';\nconst YELLOW = '\\x1b[33m';\nconst BLUE = '\\x1b[34m';\nconst CYAN = '\\x1b[36m';\nconst MAGENTA = '\\x1b[35m';\nconst WHITE = '\\x1b[37m';\nconst BG_BLUE = '\\x1b[44m';\n\n// ─── JSON-RPC types ─────────────────────────────────────────────────────────\n\ninterface JsonRpcRequest {\n jsonrpc: '2.0';\n id?: string | number | null;\n method: string;\n params?: Record<string, unknown>;\n}\n\ninterface JsonRpcResponse {\n jsonrpc: '2.0';\n id: string | number | null;\n result?: unknown;\n error?: { code: number; message: string; data?: unknown };\n}\n\nfunction jsonRpcError(id: string | number | null, code: number, message: string): JsonRpcResponse {\n return { jsonrpc: '2.0', id, error: { code, message } };\n}\n\nfunction jsonRpcResult(id: string | number | null, result: unknown): JsonRpcResponse {\n return { jsonrpc: '2.0', id, result };\n}\n\nconst PARSE_ERROR = -32700;\nconst INVALID_REQUEST = -32600;\nconst METHOD_NOT_FOUND = -32601;\nconst INVALID_PARAMS = -32602;\nconst INTERNAL_ERROR = -32603;\n\n// ─── Session management (in-memory for local use) ───────────────────────────\n\ninterface McpSession {\n id: string;\n initialized: boolean;\n createdAt: number;\n}\n\nconst sessions = new Map<string, McpSession>();\n\nfunction createSession(): McpSession {\n const id = crypto.randomBytes(16).toString('hex');\n const session: McpSession = { id, initialized: false, createdAt: Date.now() };\n sessions.set(id, session);\n return session;\n}\n\n// ─── Call timeline (tracks sequence of all tool invocations) ─────────────────\n\ninterface CallTimelineEntry {\n seq: number;\n timestamp: string;\n session_id: string | null;\n tool_name: string;\n arguments: Record<string, unknown>;\n success: boolean;\n status: number | null;\n elapsed_ms: number;\n gap_since_last_ms: number | null;\n error: string | null;\n}\n\nconst callTimeline: CallTimelineEntry[] = [];\nlet lastCallTime: number | null = null;\nlet activeStoredSession: SessionFile | null = null;\n\nfunction recordTimelineEntry(entry: Omit<CallTimelineEntry, 'seq' | 'gap_since_last_ms'>): void {\n const now = Date.now();\n const gap = lastCallTime !== null ? now - lastCallTime : null;\n callTimeline.push({\n ...entry,\n seq: callTimeline.length + 1,\n gap_since_last_ms: gap,\n });\n lastCallTime = now;\n\n // Also persist to stored session\n if (activeStoredSession) {\n addStoredTimelineEntry(activeStoredSession, entry);\n }\n}\n\nfunction printTimeline(): void {\n if (callTimeline.length === 0) {\n console.log(`\\n${DIM}No tool calls were made during this session.${RESET}`);\n return;\n }\n\n const border = '\\u2550'.repeat(68);\n console.log('');\n console.log(`${BOLD}\\u2554${border}\\u2557${RESET}`);\n console.log(`${BOLD}\\u2551${RESET} ${BG_BLUE}${WHITE}${BOLD} CALL TIMELINE ${RESET}${' '.repeat(53)}${BOLD}\\u2551${RESET}`);\n console.log(`${BOLD}\\u2560${border}\\u2563${RESET}`);\n\n // Group by session for clarity\n for (const entry of callTimeline) {\n const icon = entry.success ? `${GREEN}\\u2713${RESET}` : `${RED}\\u2717${RESET}`;\n const gapStr = entry.gap_since_last_ms !== null\n ? `${DIM}+${formatDuration(entry.gap_since_last_ms)} gap${RESET} `\n : '';\n\n const statusStr = entry.status !== null ? `${entry.status}` : 'ERR';\n const statusColor = entry.success ? GREEN : RED;\n\n console.log(`${BOLD}\\u2551${RESET} ${DIM}#${entry.seq}${RESET} ${icon} ${BOLD}${entry.tool_name}${RESET}`);\n console.log(`${BOLD}\\u2551${RESET} ${gapStr}${statusColor}${statusStr}${RESET} in ${BOLD}${entry.elapsed_ms}ms${RESET} ${DIM}${entry.timestamp}${RESET}`);\n\n // Show arguments (compact, one line)\n const argKeys = Object.keys(entry.arguments);\n if (argKeys.length > 0) {\n const argStr = argKeys.map((k) => {\n const v = entry.arguments[k];\n const display = typeof v === 'string'\n ? (v.length > 30 ? `\"${v.slice(0, 30)}...\"` : `\"${v}\"`)\n : JSON.stringify(v);\n return `${k}=${display}`;\n }).join(', ');\n console.log(`${BOLD}\\u2551${RESET} ${DIM}args: ${argStr}${RESET}`);\n }\n\n if (entry.error) {\n console.log(`${BOLD}\\u2551${RESET} ${RED}${entry.error}${RESET}`);\n }\n\n console.log(`${BOLD}\\u2551${RESET}`);\n }\n\n // Summary stats\n const totalTime = callTimeline.reduce((s, e) => s + e.elapsed_ms, 0);\n const successCount = callTimeline.filter((e) => e.success).length;\n const failCount = callTimeline.length - successCount;\n const avgGap = callTimeline\n .filter((e) => e.gap_since_last_ms !== null)\n .reduce((s, e) => s + e.gap_since_last_ms!, 0);\n const gapCount = callTimeline.filter((e) => e.gap_since_last_ms !== null).length;\n\n // Tool frequency\n const toolFreq: Record<string, number> = {};\n for (const e of callTimeline) {\n toolFreq[e.tool_name] = (toolFreq[e.tool_name] ?? 0) + 1;\n }\n\n console.log(`${BOLD}\\u2560${border}\\u2563${RESET}`);\n console.log(`${BOLD}\\u2551${RESET} ${BOLD}Total calls:${RESET} ${callTimeline.length} (${GREEN}${successCount} passed${RESET}, ${failCount > 0 ? RED : DIM}${failCount} failed${RESET})`);\n console.log(`${BOLD}\\u2551${RESET} ${BOLD}Total time:${RESET} ${formatDuration(totalTime)} (execution only)`);\n if (gapCount > 0) {\n console.log(`${BOLD}\\u2551${RESET} ${BOLD}Avg AI think:${RESET} ${formatDuration(Math.round(avgGap / gapCount))} between calls`);\n }\n console.log(`${BOLD}\\u2551${RESET} ${BOLD}Tools used:${RESET}`);\n for (const [tool, count] of Object.entries(toolFreq).sort((a, b) => b[1] - a[1])) {\n console.log(`${BOLD}\\u2551${RESET} ${DIM}-${RESET} ${tool}: ${BOLD}${count}x${RESET}`);\n }\n\n console.log(`${BOLD}\\u255A${border}\\u255D${RESET}`);\n}\n\nfunction formatDuration(ms: number): string {\n if (ms < 1000) return `${ms}ms`;\n if (ms < 60_000) return `${(ms / 1000).toFixed(1)}s`;\n return `${Math.floor(ms / 60_000)}m${Math.round((ms % 60_000) / 1000)}s`;\n}\n\n// ─── Schema helpers (matching production MCP server) ────────────────────────\n\ninterface JsonSchemaObject {\n type?: string;\n properties?: Record<string, JsonSchemaObject>;\n required?: string[];\n items?: JsonSchemaObject;\n description?: string;\n additionalProperties?: boolean | JsonSchemaObject;\n [key: string]: unknown;\n}\n\nfunction paramTypeToSchema(param: ParameterMapping): JsonSchemaObject {\n const schema: JsonSchemaObject = {};\n switch (param.type) {\n case 'string': schema.type = 'string'; break;\n case 'number': schema.type = 'number'; break;\n case 'boolean': schema.type = 'boolean'; break;\n case 'object': schema.type = 'object'; schema.additionalProperties = true; break;\n case 'array': schema.type = 'array'; schema.items = { type: 'string' }; break;\n default: schema.type = 'string'; break;\n }\n if (param.description) schema.description = param.description;\n return schema;\n}\n\nfunction buildInputSchema(toolConfig: CliToolConfig): JsonSchemaObject {\n if (toolConfig.request_schema && Object.keys(toolConfig.request_schema).length > 0) {\n return toolConfig.request_schema as JsonSchemaObject;\n }\n const properties: Record<string, JsonSchemaObject> = {};\n const required: string[] = [];\n for (const param of toolConfig.parameter_mapping) {\n properties[param.name] = paramTypeToSchema(param);\n if (param.required) required.push(param.name);\n }\n const schema: JsonSchemaObject = { type: 'object', properties };\n if (required.length > 0) schema.required = required;\n return schema;\n}\n\n// ─── Bridge CLI config to shared types ──────────────────────────────────────\n\nfunction toApp(config: CliConfig, baseUrlOverride?: string): App {\n return {\n id: 'local-mcp',\n user_id: 'local-mcp',\n name: config.app.name,\n slug: config.app.name.toLowerCase().replace(/[^a-z0-9]+/g, '-'),\n description: '',\n base_url: baseUrlOverride ?? config.app.base_url,\n auth_type: config.app.auth_type,\n auth_config: config.app.auth_config ?? {},\n is_published: true,\n auto_approve_keys: false,\n default_key_tier: 'free' as App['default_key_tier'],\n enable_cli_access: true,\n global_headers: config.app.global_headers,\n x402_enabled: false,\n x402_bazaar_listed: false,\n created_at: new Date(),\n updated_at: new Date(),\n };\n}\n\nfunction toTool(toolConfig: CliToolConfig): Tool {\n return {\n id: `local-${toolConfig.name}`,\n app_id: 'local-mcp',\n name: toolConfig.name,\n slug: toolConfig.name.toLowerCase().replace(/[^a-z0-9]+/g, '-'),\n description: toolConfig.description ?? '',\n http_method: toolConfig.http_method,\n endpoint_path: toolConfig.endpoint_path,\n request_schema: toolConfig.request_schema ?? {},\n response_schema: toolConfig.response_schema,\n parameter_mapping: toolConfig.parameter_mapping,\n headers_template: toolConfig.headers_template,\n permission_level: (toolConfig.permission_level ?? 'read') as Tool['permission_level'],\n mcp_annotations: toolConfig.mcp_annotations,\n cache_ttl_seconds: 0,\n sort_order: 0,\n is_active: true,\n created_at: new Date(),\n updated_at: new Date(),\n };\n}\n\n// ─── Tool execution with audit logging ──────────────────────────────────────\n\nasync function executeToolCall(\n app: App,\n tool: Tool,\n toolConfig: CliToolConfig,\n args: Record<string, unknown>,\n logger: AuditLogger,\n timeout: number,\n consumerToken?: string,\n): Promise<{ isError: boolean; text: string; status: number | null; elapsedMs: number; errorMessage: string | null }> {\n const audit = logger.startInvocation(tool.name, tool.http_method, tool.endpoint_path);\n audit.setInput(args);\n audit.recordParameterResolutions(tool.parameter_mapping, args);\n\n const startTime = performance.now();\n\n // Build request\n let request: BackendRequest;\n try {\n request = buildBackendRequest(tool, app, args, consumerToken);\n } catch (err) {\n audit.setError({\n phase: 'request_build',\n message: (err as Error).message,\n details: 'buildBackendRequest() threw — check parameter_mapping and auth_config',\n });\n audit.finish(false);\n const elapsed = Math.round(performance.now() - startTime);\n return { isError: true, text: (err as Error).message, status: null, elapsedMs: elapsed, errorMessage: (err as Error).message };\n }\n\n audit.setRequest(request.url, request.method, request.headers, request.body);\n\n // Execute HTTP request\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n let response: Response;\n try {\n response = await fetch(request.url, {\n method: request.method,\n headers: request.headers,\n body: request.body !== undefined ? JSON.stringify(request.body) : undefined,\n signal: controller.signal,\n redirect: 'follow',\n });\n } catch (err) {\n clearTimeout(timeoutId);\n const error = err as Error;\n if (error.name === 'AbortError') {\n audit.setError({ phase: 'timeout', message: `Request timed out after ${timeout}ms` });\n } else {\n audit.setError({ phase: 'network', message: error.message });\n }\n audit.finish(false);\n const elapsed = Math.round(performance.now() - startTime);\n return { isError: true, text: error.message, status: null, elapsedMs: elapsed, errorMessage: error.message };\n } finally {\n clearTimeout(timeoutId);\n }\n\n // Parse response\n let responseBodyRaw: string;\n try {\n responseBodyRaw = await response.text();\n } catch (err) {\n audit.setError({ phase: 'response_parse', message: `Failed to read response: ${(err as Error).message}` });\n audit.finish(false);\n const elapsed = Math.round(performance.now() - startTime);\n return { isError: true, text: (err as Error).message, status: response.status, elapsedMs: elapsed, errorMessage: (err as Error).message };\n }\n\n let responseBody: unknown;\n const contentType = response.headers.get('content-type') ?? '';\n if (contentType.includes('application/json')) {\n try {\n responseBody = JSON.parse(responseBodyRaw);\n } catch {\n audit.addDiagnostic('Response has Content-Type application/json but body is not valid JSON');\n }\n }\n\n const responseHeaders: Record<string, string> = {};\n response.headers.forEach((value, key) => { responseHeaders[key] = value; });\n\n audit.setResponse(\n response.status,\n response.statusText,\n responseHeaders,\n responseBody ?? responseBodyRaw,\n responseBodyRaw,\n );\n\n // Validate response schema\n if (toolConfig.response_schema && Object.keys(toolConfig.response_schema).length > 0 && responseBody !== undefined) {\n // Lightweight check\n const errors: string[] = [];\n const schema = toolConfig.response_schema;\n if (schema['type'] === 'object' && typeof responseBody === 'object' && responseBody !== null) {\n const required = schema['required'] as string[] | undefined;\n if (required) {\n for (const field of required) {\n if (!(field in (responseBody as Record<string, unknown>))) {\n errors.push(`Missing required field: \"${field}\"`);\n }\n }\n }\n }\n audit.setResponseValidation({ valid: errors.length === 0, errors });\n }\n\n const isSuccess = response.status >= 200 && response.status < 400;\n audit.finish(isSuccess);\n const elapsed = Math.round(performance.now() - startTime);\n\n if (!isSuccess) {\n const truncated = responseBodyRaw.length > 500 ? responseBodyRaw.slice(0, 500) + '...' : responseBodyRaw;\n return { isError: true, text: `Backend returned ${response.status}: ${truncated}`, status: response.status, elapsedMs: elapsed, errorMessage: `Backend returned ${response.status}` };\n }\n\n // Return pretty-printed JSON if possible, else raw\n if (responseBody !== undefined) {\n return { isError: false, text: JSON.stringify(responseBody, null, 2), status: response.status, elapsedMs: elapsed, errorMessage: null };\n }\n return { isError: false, text: responseBodyRaw, status: response.status, elapsedMs: elapsed, errorMessage: null };\n}\n\n// ─── MCP method handlers ────────────────────────────────────────────────────\n\nfunction handleInitialize(rpc: JsonRpcRequest, config: CliConfig): JsonRpcResponse {\n return jsonRpcResult(rpc.id ?? null, {\n protocolVersion: MCP_PROTOCOL_VERSION,\n capabilities: {\n tools: { listChanged: false },\n },\n serverInfo: {\n name: `${config.app.name} (local)`,\n version: '0.1.0',\n },\n });\n}\n\nfunction inferAnnotations(toolConfig: CliToolConfig): McpToolAnnotations {\n const method = toolConfig.http_method;\n const isReadOnly =\n (toolConfig.permission_level ?? 'read') === PermissionLevel.read ||\n method === HttpMethod.GET;\n return {\n readOnlyHint: isReadOnly,\n destructiveHint: method === HttpMethod.DELETE,\n idempotentHint: method === HttpMethod.GET || method === HttpMethod.PUT,\n openWorldHint: true,\n };\n}\n\nfunction handleToolsList(rpc: JsonRpcRequest, config: CliConfig): JsonRpcResponse {\n const appSlug = config.app.name.toLowerCase().replace(/[^a-z0-9]+/g, '-');\n const mcpTools = config.tools.map((toolConfig) => {\n const toolSlug = toolConfig.name.toLowerCase().replace(/[^a-z0-9]+/g, '-');\n return {\n name: `${appSlug}_${toolSlug}`,\n description: toolConfig.description ?? toolConfig.name,\n inputSchema: buildInputSchema(toolConfig),\n annotations: toolConfig.mcp_annotations ?? inferAnnotations(toolConfig),\n };\n });\n\n return jsonRpcResult(rpc.id ?? null, { tools: mcpTools });\n}\n\nasync function handleToolsCall(\n rpc: JsonRpcRequest,\n config: CliConfig,\n app: App,\n logger: AuditLogger,\n timeout: number,\n sessionId: string | null,\n oauthStore?: OAuthTokenStore | null,\n oauthConfig?: OAuthConfig | null,\n): Promise<JsonRpcResponse> {\n const params = rpc.params ?? {};\n const toolName = params.name as string | undefined;\n const args = (params.arguments ?? {}) as Record<string, unknown>;\n\n if (!toolName) {\n return jsonRpcError(rpc.id ?? null, INVALID_PARAMS, 'Missing required parameter: name');\n }\n\n // Tool names are namespaced as {appSlug}_{toolSlug}\n const appSlug = config.app.name.toLowerCase().replace(/[^a-z0-9]+/g, '-');\n const prefix = `${appSlug}_`;\n const lookupSlug = toolName.startsWith(prefix)\n ? toolName.slice(prefix.length)\n : toolName;\n\n const toolConfig = config.tools.find((t) => {\n const slug = t.name.toLowerCase().replace(/[^a-z0-9]+/g, '-');\n return slug === lookupSlug || t.name === lookupSlug;\n });\n\n if (!toolConfig) {\n return jsonRpcError(rpc.id ?? null, INVALID_PARAMS, `Tool not found: ${toolName}`);\n }\n\n // Resolve OAuth consumer token if applicable\n let consumerToken: string | undefined;\n if (oauthStore && oauthConfig) {\n const token = await getAccessToken(oauthStore, oauthConfig);\n if (token) {\n consumerToken = token;\n } else {\n return jsonRpcError(\n rpc.id ?? null,\n INVALID_REQUEST,\n 'OAuth2 authentication required. Visit /oauth/start to authenticate.',\n );\n }\n }\n\n const tool = toTool(toolConfig);\n const result = await executeToolCall(app, tool, toolConfig, args, logger, timeout, consumerToken);\n\n // Record in call timeline\n recordTimelineEntry({\n timestamp: new Date().toISOString(),\n session_id: sessionId,\n tool_name: toolName,\n arguments: args,\n success: !result.isError,\n status: result.status,\n elapsed_ms: result.elapsedMs,\n error: result.errorMessage,\n });\n\n return jsonRpcResult(rpc.id ?? null, {\n content: [{ type: 'text', text: result.text }],\n isError: result.isError,\n });\n}\n\n// ─── HTTP request body parser ───────────────────────────────────────────────\n\nfunction readBody(req: IncomingMessage): Promise<string> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n req.on('data', (chunk: Buffer) => chunks.push(chunk));\n req.on('end', () => resolve(Buffer.concat(chunks).toString('utf-8')));\n req.on('error', reject);\n });\n}\n\n// ─── SSE helpers ────────────────────────────────────────────────────────────\n\nfunction sendSseEvent(res: ServerResponse, event: string, data: unknown): void {\n res.write(`event: ${event}\\ndata: ${JSON.stringify(data)}\\n\\n`);\n}\n\n// ─── Public API ─────────────────────────────────────────────────────────────\n\nexport function startMcpServer(\n config: CliConfig,\n options: ServeOptions & { configPath?: string },\n): void {\n const app = toApp(config, options.baseUrl);\n const logger = new AuditLogger({\n outputPath: undefined,\n verbose: options.verbose,\n });\n\n // Create a persistent session for this run\n const appSlug = config.app.name.toLowerCase().replace(/[^a-z0-9]+/g, '-');\n const storedSession: SessionFile = createStoredSession({\n type: 'serve',\n appName: config.app.name,\n configPath: options.configPath ?? 'unknown',\n baseUrl: options.baseUrl ?? config.app.base_url,\n tools: config.tools.map(\n (t) => `${appSlug}_${t.name.toLowerCase().replace(/[^a-z0-9]+/g, '-')}`,\n ),\n });\n\n // Make session available to recordTimelineEntry\n activeStoredSession = storedSession;\n\n const timeout = 30_000;\n let callCount = 0;\n\n // Initialize OAuth token store if app uses OAuth2\n let oauthTokenStore: OAuthTokenStore | null = null;\n let oauthConfig: OAuthConfig | null = null;\n\n if (config.app.auth_type === AuthType.oauth2 && config.app.auth_config) {\n const ac = config.app.auth_config;\n // Only authorize_url and token_url are required — client_id/client_secret\n // are optional (public client PKCE model), matching the onboarding wizard.\n if (ac.authorize_url && ac.token_url) {\n oauthConfig = {\n authorize_url: ac.authorize_url as string,\n token_url: ac.token_url as string,\n client_id: (ac.client_id as string) ?? '',\n client_secret: (ac.client_secret as string) ?? '',\n scopes: (ac.scopes as string) ?? '',\n use_pkce: ac.use_pkce !== false, // default true\n };\n oauthTokenStore = new OAuthTokenStore();\n }\n }\n\n const server = createServer(async (req, res) => {\n // CORS for browser-based MCP clients\n res.setHeader('Access-Control-Allow-Origin', '*');\n res.setHeader('Access-Control-Allow-Methods', 'GET, POST, DELETE, OPTIONS');\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, Mcp-Session-Id, Accept');\n res.setHeader('Access-Control-Expose-Headers', 'Mcp-Session-Id');\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204);\n res.end();\n return;\n }\n\n const url = new URL(req.url ?? '/', `http://localhost:${options.port}`);\n\n // ── GET /health ──────────────────────────────────────────────────\n if (req.method === 'GET' && url.pathname === '/health') {\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({\n status: 'ok',\n tools: config.tools.length,\n calls: callCount,\n oauth: oauthTokenStore\n ? { enabled: true, authenticated: oauthTokenStore.isAuthenticated() }\n : { enabled: false },\n }));\n return;\n }\n\n // ── GET /timeline ─────────────────────────────────────────────────\n if (req.method === 'GET' && url.pathname === '/timeline') {\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ calls: callTimeline }, null, 2));\n return;\n }\n\n // ── GET /mcp (SSE stream) ────────────────────────────────────────\n if (req.method === 'GET' && url.pathname === '/mcp') {\n const sessionId = req.headers['mcp-session-id'] as string | undefined;\n if (!sessionId || !sessions.has(sessionId)) {\n res.writeHead(400, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: 'Missing or invalid Mcp-Session-Id' }));\n return;\n }\n\n res.writeHead(200, {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n 'Connection': 'keep-alive',\n 'Mcp-Session-Id': sessionId,\n });\n\n const keepAlive = setInterval(() => { res.write(': keep-alive\\n\\n'); }, 30_000);\n req.on('close', () => { clearInterval(keepAlive); });\n return;\n }\n\n // ── DELETE /mcp (session termination) ─────────────────────────────\n if (req.method === 'DELETE' && url.pathname === '/mcp') {\n const sessionId = req.headers['mcp-session-id'] as string | undefined;\n if (sessionId) sessions.delete(sessionId);\n res.writeHead(204);\n res.end();\n return;\n }\n\n // ── POST /mcp (JSON-RPC) ─────────────────────────────────────────\n if (req.method === 'POST' && url.pathname === '/mcp') {\n let body: string;\n try {\n body = await readBody(req);\n } catch {\n res.writeHead(400, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(jsonRpcError(null, PARSE_ERROR, 'Failed to read request body')));\n return;\n }\n\n let rpc: JsonRpcRequest;\n try {\n const parsed = JSON.parse(body);\n if (!parsed || parsed.jsonrpc !== '2.0' || !parsed.method) {\n throw new Error('Invalid JSON-RPC');\n }\n rpc = parsed as JsonRpcRequest;\n } catch {\n res.writeHead(400, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(jsonRpcError(null, PARSE_ERROR, 'Invalid JSON-RPC 2.0 request')));\n return;\n }\n\n const isNotification = rpc.id === undefined || rpc.id === null;\n\n // Session management\n let session: McpSession | undefined;\n const sessionId = req.headers['mcp-session-id'] as string | undefined;\n\n if (rpc.method === 'initialize') {\n session = createSession();\n } else if (sessionId) {\n session = sessions.get(sessionId);\n if (!session) {\n res.writeHead(400, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(jsonRpcError(rpc.id ?? null, INVALID_REQUEST, 'Invalid or expired session')));\n return;\n }\n }\n\n // Handle notifications\n if (isNotification) {\n if (rpc.method === 'notifications/initialized' && session) {\n session.initialized = true;\n }\n res.writeHead(202);\n res.end();\n return;\n }\n\n // Check if client wants SSE\n const acceptHeader = req.headers['accept'] ?? '';\n const wantsSse = acceptHeader.includes('text/event-stream');\n\n // Dispatch\n let response: JsonRpcResponse;\n try {\n switch (rpc.method) {\n case 'initialize':\n response = handleInitialize(rpc, config);\n console.log(`${CYAN}${BOLD}[MCP]${RESET} Session initialized: ${session?.id ?? 'unknown'}`);\n break;\n\n case 'tools/list':\n response = handleToolsList(rpc, config);\n console.log(`${MAGENTA}${BOLD}[MCP]${RESET} tools/list — returned ${config.tools.length} tool(s)`);\n break;\n\n case 'tools/call': {\n callCount++;\n const toolName = (rpc.params ?? {}).name as string | undefined;\n console.log(`\\n${YELLOW}${BOLD}[MCP]${RESET} tools/call #${callCount} — ${toolName ?? 'unknown'}`);\n\n if (wantsSse) {\n const sseHeaders: Record<string, string> = {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n 'Connection': 'keep-alive',\n };\n if (session) sseHeaders['Mcp-Session-Id'] = session.id;\n res.writeHead(200, sseHeaders);\n\n // Progress notification\n sendSseEvent(res, 'message', {\n jsonrpc: '2.0',\n method: 'notifications/progress',\n params: { progressToken: rpc.id, progress: 0, total: 1 },\n });\n\n const toolResponse = await handleToolsCall(rpc, config, app, logger, timeout, session?.id ?? null, oauthTokenStore, oauthConfig);\n sendSseEvent(res, 'message', toolResponse);\n res.end();\n return;\n }\n\n response = await handleToolsCall(rpc, config, app, logger, timeout, session?.id ?? null, oauthTokenStore, oauthConfig);\n break;\n }\n\n case 'ping':\n response = jsonRpcResult(rpc.id ?? null, {});\n break;\n\n default:\n response = jsonRpcError(rpc.id ?? null, METHOD_NOT_FOUND, `Method not found: ${rpc.method}`);\n break;\n }\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : 'Internal error';\n response = jsonRpcError(rpc.id ?? null, INTERNAL_ERROR, message);\n }\n\n // Set session header\n if (session) {\n res.setHeader('Mcp-Session-Id', session.id);\n }\n\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(response));\n return;\n }\n\n // ── GET /oauth/start — trigger OAuth flow ─────────────────────\n if (req.method === 'GET' && url.pathname === '/oauth/start') {\n if (!oauthTokenStore || !oauthConfig) {\n res.writeHead(400, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: 'This app does not use OAuth2 authentication' }));\n return;\n }\n\n if (oauthTokenStore.isAuthenticated() && !oauthTokenStore.needsRefresh()) {\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ status: 'already_authenticated' }));\n return;\n }\n\n try {\n await startOAuthFlow(oauthTokenStore, oauthConfig);\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ status: 'authenticated' }));\n console.log(`${GREEN}${BOLD}[OAuth]${RESET} Successfully authenticated with upstream provider`);\n } catch (err) {\n res.writeHead(500, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: (err as Error).message }));\n console.error(`${RED}${BOLD}[OAuth]${RESET} Authentication failed: ${(err as Error).message}`);\n }\n return;\n }\n\n // ── GET /oauth/status — check OAuth state ───────────────────────\n if (req.method === 'GET' && url.pathname === '/oauth/status') {\n if (!oauthTokenStore) {\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ oauth_enabled: false }));\n return;\n }\n\n const tokens = oauthTokenStore.getTokens();\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({\n oauth_enabled: true,\n authenticated: oauthTokenStore.isAuthenticated(),\n expires_at: tokens?.expires_at ?? null,\n has_refresh_token: !!tokens?.refresh_token,\n }));\n return;\n }\n\n // ── 404 for everything else ──────────────────────────────────────\n res.writeHead(404, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: 'Not found. MCP endpoint is POST /mcp' }));\n });\n\n server.listen(options.port, '127.0.0.1', () => {\n const appSlug = config.app.name.toLowerCase().replace(/[^a-z0-9]+/g, '-');\n const toolSlugs = config.tools.map(\n (t) => `${appSlug}_${t.name.toLowerCase().replace(/[^a-z0-9]+/g, '-')}`,\n );\n\n console.log('');\n console.log(`${GREEN}${BOLD}ToolRelay MCP Server running${RESET}`);\n console.log(`${DIM}${'─'.repeat(60)}${RESET}`);\n console.log(` ${BOLD}MCP endpoint:${RESET} http://localhost:${options.port}/mcp`);\n console.log(` ${BOLD}Health check:${RESET} http://localhost:${options.port}/health`);\n console.log(` ${BOLD}Timeline:${RESET} http://localhost:${options.port}/timeline`);\n console.log(` ${BOLD}Backend:${RESET} ${app.base_url}`);\n console.log(` ${BOLD}Auth:${RESET} ${app.auth_type}`);\n if (oauthTokenStore) {\n console.log(` ${BOLD}OAuth start:${RESET} http://localhost:${options.port}/oauth/start`);\n console.log(` ${BOLD}OAuth status:${RESET} http://localhost:${options.port}/oauth/status`);\n }\n console.log(` ${BOLD}Tools (${config.tools.length}):${RESET}`);\n for (const slug of toolSlugs) {\n console.log(` ${DIM}-${RESET} ${slug}`);\n }\n console.log(`${DIM}${'─'.repeat(60)}${RESET}`);\n console.log('');\n console.log(`${BOLD}Claude Desktop config:${RESET}`);\n console.log(` Add to ~/Library/Application Support/Claude/claude_desktop_config.json:`);\n console.log('');\n console.log(` ${DIM}{${RESET}`);\n console.log(` ${DIM} \"mcpServers\": {${RESET}`);\n console.log(` ${DIM} \"${appSlug}-local\": {${RESET}`);\n console.log(` ${DIM} \"url\": \"http://localhost:${options.port}/mcp\"${RESET}`);\n console.log(` ${DIM} }${RESET}`);\n console.log(` ${DIM} }${RESET}`);\n console.log(` ${DIM}}${RESET}`);\n console.log('');\n console.log(`${DIM}Every tools/call will produce a full audit trace below.${RESET}`);\n console.log(`${DIM}Press Ctrl+C to stop.${RESET}`);\n console.log('');\n\n // Auto-trigger OAuth flow for OAuth2 apps (skip in non-interactive environments)\n if (oauthTokenStore && oauthConfig && process.stdout.isTTY) {\n console.log(`${YELLOW}${BOLD}[OAuth]${RESET} This app requires OAuth2 authentication.`);\n console.log(`${DIM}Starting OAuth flow — your browser will open...${RESET}\\n`);\n\n startOAuthFlow(oauthTokenStore, oauthConfig).then(() => {\n console.log(`${GREEN}${BOLD}[OAuth]${RESET} Authenticated successfully. Tool calls will use your OAuth token.\\n`);\n }).catch((err: unknown) => {\n console.error(`${RED}${BOLD}[OAuth]${RESET} Auto-authentication failed: ${(err as Error).message}`);\n console.error(`${DIM}You can retry by visiting: http://localhost:${options.port}/oauth/start${RESET}\\n`);\n });\n } else if (oauthTokenStore && oauthConfig) {\n console.log(`${YELLOW}${BOLD}[OAuth]${RESET} This app requires OAuth2 authentication.`);\n console.log(`${DIM}Visit http://localhost:${options.port}/oauth/start to authenticate.${RESET}\\n`);\n }\n });\n\n // Graceful shutdown\n const shutdown = () => {\n console.log(`\\n${DIM}Shutting down...${RESET}`);\n printTimeline();\n const summary = logger.printSummary();\n\n // Persist session to .toolrelay/sessions/\n finalizeSession(storedSession, logger.getEntries(), summary);\n const sessionPath = saveSession(storedSession);\n console.log(`\\n${DIM}Session saved: ${sessionPath}${RESET}`);\n console.log(`${DIM}View all sessions: npx @toolrelay/cli ui${RESET}`);\n\n activeStoredSession = null;\n server.close();\n process.exit(summary.failed > 0 ? 1 : 0);\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n}\n","/**\n * Embedded HTML for the ToolRelay session viewer UI.\n * Single-file, no external dependencies — vanilla JS + CSS.\n *\n * The HTML uses a {{SESSIONS_JSON}} placeholder that the UI server replaces\n * with the actual session data at serve time.\n */\nexport function buildHtml(sessionsJson: string): string {\n return HTML_TEMPLATE.replace('{{SESSIONS_JSON}}', sessionsJson);\n}\n\nconst HTML_TEMPLATE = /* html */ `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<title>ToolRelay — Session Viewer</title>\n<style>\n :root {\n --bg: #0f1117;\n --surface: #1a1d27;\n --surface-2: #242837;\n --border: #2e3348;\n --text: #e1e4ed;\n --text-dim: #8b8fa7;\n --accent: #6c8aff;\n --accent-dim: #3d5199;\n --green: #34d399;\n --green-bg: rgba(52, 211, 153, 0.1);\n --red: #f87171;\n --red-bg: rgba(248, 113, 113, 0.1);\n --yellow: #fbbf24;\n --yellow-bg: rgba(251, 191, 36, 0.1);\n --mono: 'SF Mono', 'Cascadia Code', 'Fira Code', 'JetBrains Mono', monospace;\n --sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n }\n\n * { margin: 0; padding: 0; box-sizing: border-box; }\n\n body {\n font-family: var(--sans);\n background: var(--bg);\n color: var(--text);\n line-height: 1.5;\n min-height: 100vh;\n }\n\n /* ── Header ────────────────────────────────────────── */\n .header {\n border-bottom: 1px solid var(--border);\n padding: 16px 24px;\n display: flex;\n align-items: center;\n gap: 12px;\n background: var(--surface);\n }\n .header h1 {\n font-size: 16px;\n font-weight: 600;\n letter-spacing: -0.01em;\n }\n .header .subtitle {\n color: var(--text-dim);\n font-size: 13px;\n }\n .header .count-badge {\n background: var(--accent-dim);\n color: var(--accent);\n font-size: 11px;\n font-weight: 600;\n padding: 2px 8px;\n border-radius: 10px;\n margin-left: auto;\n }\n\n /* ── Layout ────────────────────────────────────────── */\n .layout {\n display: flex;\n height: calc(100vh - 53px);\n }\n .sidebar {\n width: 340px;\n min-width: 340px;\n border-right: 1px solid var(--border);\n overflow-y: auto;\n background: var(--surface);\n }\n .main {\n flex: 1;\n overflow-y: auto;\n padding: 24px;\n }\n\n /* ── Session list ──────────────────────────────────── */\n .session-item {\n padding: 12px 16px;\n border-bottom: 1px solid var(--border);\n cursor: pointer;\n transition: background 0.15s;\n }\n .session-item:hover { background: var(--surface-2); }\n .session-item.active {\n background: var(--surface-2);\n border-left: 3px solid var(--accent);\n padding-left: 13px;\n }\n .session-item .row {\n display: flex;\n align-items: center;\n gap: 8px;\n margin-bottom: 4px;\n }\n .session-item .app-name {\n font-weight: 600;\n font-size: 14px;\n }\n .session-item .type-badge {\n font-size: 10px;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n font-weight: 700;\n padding: 1px 6px;\n border-radius: 3px;\n }\n .type-badge.serve { background: rgba(108, 138, 255, 0.15); color: var(--accent); }\n .type-badge.test { background: var(--yellow-bg); color: var(--yellow); }\n .session-item .meta {\n font-size: 12px;\n color: var(--text-dim);\n display: flex;\n gap: 12px;\n }\n .session-item .stats {\n display: flex;\n gap: 10px;\n margin-top: 6px;\n font-size: 12px;\n font-family: var(--mono);\n }\n .stat-pass { color: var(--green); }\n .stat-fail { color: var(--red); }\n .stat-time { color: var(--text-dim); }\n\n /* ── Empty states ──────────────────────────────────── */\n .empty-state {\n text-align: center;\n padding: 80px 24px;\n color: var(--text-dim);\n }\n .empty-state h2 { font-size: 18px; margin-bottom: 8px; color: var(--text); }\n .empty-state p { font-size: 14px; max-width: 400px; margin: 0 auto; }\n .empty-state code {\n display: inline-block;\n margin-top: 16px;\n background: var(--surface-2);\n padding: 8px 16px;\n border-radius: 6px;\n font-family: var(--mono);\n font-size: 13px;\n color: var(--accent);\n }\n\n /* ── Session detail ────────────────────────────────── */\n .detail-header {\n margin-bottom: 24px;\n padding-bottom: 16px;\n border-bottom: 1px solid var(--border);\n }\n .detail-header h2 {\n font-size: 20px;\n font-weight: 600;\n margin-bottom: 4px;\n }\n .detail-header .detail-meta {\n font-size: 13px;\n color: var(--text-dim);\n display: flex;\n flex-wrap: wrap;\n gap: 16px;\n }\n\n /* ── Summary cards ─────────────────────────────────── */\n .summary-cards {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n gap: 12px;\n margin-bottom: 24px;\n }\n .card {\n background: var(--surface);\n border: 1px solid var(--border);\n border-radius: 8px;\n padding: 14px 16px;\n }\n .card .card-label {\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--text-dim);\n margin-bottom: 4px;\n }\n .card .card-value {\n font-size: 24px;\n font-weight: 700;\n font-family: var(--mono);\n }\n .card .card-value.green { color: var(--green); }\n .card .card-value.red { color: var(--red); }\n .card .card-value.accent { color: var(--accent); }\n\n /* ── Tabs ───────────────────────────────────────────── */\n .tabs {\n display: flex;\n gap: 0;\n border-bottom: 1px solid var(--border);\n margin-bottom: 20px;\n }\n .tab {\n padding: 8px 16px;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n color: var(--text-dim);\n border-bottom: 2px solid transparent;\n transition: all 0.15s;\n background: none;\n border-top: none;\n border-left: none;\n border-right: none;\n }\n .tab:hover { color: var(--text); }\n .tab.active {\n color: var(--accent);\n border-bottom-color: var(--accent);\n }\n\n /* ── Timeline ──────────────────────────────────────── */\n .timeline { list-style: none; }\n .timeline-entry {\n display: flex;\n gap: 12px;\n padding: 10px 0;\n border-bottom: 1px solid var(--border);\n cursor: pointer;\n transition: background 0.15s;\n border-radius: 4px;\n padding-left: 8px;\n padding-right: 8px;\n }\n .timeline-entry:hover { background: var(--surface-2); }\n .timeline-entry.active { background: var(--surface-2); }\n .timeline-entry .seq {\n font-family: var(--mono);\n font-size: 11px;\n color: var(--text-dim);\n min-width: 28px;\n text-align: right;\n padding-top: 2px;\n }\n .timeline-entry .icon {\n font-size: 14px;\n padding-top: 1px;\n }\n .timeline-entry .icon.pass { color: var(--green); }\n .timeline-entry .icon.fail { color: var(--red); }\n .timeline-entry .content { flex: 1; min-width: 0; }\n .timeline-entry .tool-name {\n font-weight: 600;\n font-size: 13px;\n }\n .timeline-entry .entry-meta {\n font-size: 12px;\n color: var(--text-dim);\n display: flex;\n gap: 10px;\n margin-top: 2px;\n }\n .timeline-entry .gap-badge {\n font-size: 10px;\n background: var(--surface-2);\n padding: 1px 6px;\n border-radius: 3px;\n color: var(--text-dim);\n }\n .timeline-entry .status-badge {\n font-family: var(--mono);\n font-size: 11px;\n font-weight: 600;\n padding: 1px 6px;\n border-radius: 3px;\n }\n .status-badge.s2xx { background: var(--green-bg); color: var(--green); }\n .status-badge.s4xx { background: var(--red-bg); color: var(--red); }\n .status-badge.s5xx { background: var(--red-bg); color: var(--red); }\n .status-badge.serr { background: var(--red-bg); color: var(--red); }\n .timeline-entry .timing {\n font-family: var(--mono);\n font-size: 11px;\n color: var(--text-dim);\n min-width: 60px;\n text-align: right;\n padding-top: 2px;\n }\n\n /* ── Call detail panel ─────────────────────────────── */\n .call-detail {\n background: var(--surface);\n border: 1px solid var(--border);\n border-radius: 8px;\n margin-top: 20px;\n }\n .call-detail-header {\n padding: 14px 16px;\n border-bottom: 1px solid var(--border);\n display: flex;\n align-items: center;\n gap: 8px;\n }\n .call-detail-header h3 {\n font-size: 14px;\n font-weight: 600;\n }\n .call-detail-section {\n padding: 14px 16px;\n border-bottom: 1px solid var(--border);\n }\n .call-detail-section:last-child { border-bottom: none; }\n .call-detail-section h4 {\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n color: var(--text-dim);\n margin-bottom: 8px;\n }\n pre.code-block {\n background: var(--bg);\n border-radius: 6px;\n padding: 12px;\n font-family: var(--mono);\n font-size: 12px;\n line-height: 1.6;\n overflow-x: auto;\n white-space: pre-wrap;\n word-break: break-all;\n color: var(--text);\n }\n .param-table {\n width: 100%;\n font-size: 13px;\n border-collapse: collapse;\n }\n .param-table th {\n text-align: left;\n font-weight: 500;\n color: var(--text-dim);\n padding: 4px 8px 4px 0;\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.04em;\n }\n .param-table td {\n padding: 4px 8px 4px 0;\n font-family: var(--mono);\n font-size: 12px;\n }\n .param-table tr { border-bottom: 1px solid var(--border); }\n .param-table tr:last-child { border-bottom: none; }\n\n /* ── Diagnostics ───────────────────────────────────── */\n .diagnostic {\n padding: 8px 12px;\n background: var(--yellow-bg);\n border-radius: 6px;\n font-size: 13px;\n margin-bottom: 6px;\n color: var(--yellow);\n }\n .error-block {\n padding: 8px 12px;\n background: var(--red-bg);\n border-radius: 6px;\n font-size: 13px;\n color: var(--red);\n }\n\n /* ── Scrollbar ─────────────────────────────────────── */\n ::-webkit-scrollbar { width: 6px; height: 6px; }\n ::-webkit-scrollbar-track { background: transparent; }\n ::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }\n ::-webkit-scrollbar-thumb:hover { background: var(--text-dim); }\n</style>\n</head>\n<body>\n\n<div class=\"header\">\n <h1>ToolRelay</h1>\n <span class=\"subtitle\">Session Viewer</span>\n <span class=\"count-badge\" id=\"session-count\"></span>\n</div>\n\n<div class=\"layout\">\n <div class=\"sidebar\" id=\"sidebar\"></div>\n <div class=\"main\" id=\"main\">\n <div class=\"empty-state\">\n <h2>No sessions yet</h2>\n <p>Run the MCP server or test suite to generate session data.</p>\n <code>npx @toolrelay/cli serve toolrelay.json</code>\n </div>\n </div>\n</div>\n\n<script>\nconst SESSIONS = {{SESSIONS_JSON}};\n\nlet activeSessionIdx = null;\nlet activeTab = 'timeline';\nlet activeCallIdx = null;\n\n// ── Render sidebar ──────────────────────────────────\nfunction renderSidebar() {\n const el = document.getElementById('sidebar');\n document.getElementById('session-count').textContent = SESSIONS.length + ' session' + (SESSIONS.length !== 1 ? 's' : '');\n\n if (SESSIONS.length === 0) {\n el.innerHTML = '<div class=\"empty-state\"><p>No sessions found</p></div>';\n return;\n }\n\n el.innerHTML = SESSIONS.map((s, i) => {\n const date = new Date(s.started_at);\n const timeStr = date.toLocaleDateString() + ' ' + date.toLocaleTimeString();\n const passed = s.summary?.passed ?? 0;\n const failed = s.summary?.failed ?? 0;\n const avgMs = s.summary?.avg_response_time_ms ?? 0;\n const active = i === activeSessionIdx ? ' active' : '';\n return '<div class=\"session-item' + active + '\" onclick=\"selectSession(' + i + ')\">' +\n '<div class=\"row\">' +\n '<span class=\"app-name\">' + esc(s.app_name) + '</span>' +\n '<span class=\"type-badge ' + s.type + '\">' + s.type + '</span>' +\n '</div>' +\n '<div class=\"meta\">' +\n '<span>' + timeStr + '</span>' +\n '<span>' + s.timeline.length + ' calls</span>' +\n '</div>' +\n '<div class=\"stats\">' +\n (passed > 0 ? '<span class=\"stat-pass\">' + passed + ' passed</span>' : '') +\n (failed > 0 ? '<span class=\"stat-fail\">' + failed + ' failed</span>' : '') +\n '<span class=\"stat-time\">' + avgMs + 'ms avg</span>' +\n '</div>' +\n '</div>';\n }).join('');\n}\n\n// ── Render main panel ───────────────────────────────\nfunction selectSession(idx) {\n activeSessionIdx = idx;\n activeCallIdx = null;\n renderSidebar();\n renderMain();\n}\n\nfunction renderMain() {\n const el = document.getElementById('main');\n if (activeSessionIdx === null) {\n el.innerHTML = '<div class=\"empty-state\"><h2>Select a session</h2><p>Click a session from the left panel to view its details.</p></div>';\n return;\n }\n\n const s = SESSIONS[activeSessionIdx];\n const date = new Date(s.started_at);\n const endDate = s.finished_at ? new Date(s.finished_at) : null;\n const duration = endDate ? formatMs(endDate.getTime() - date.getTime()) : 'running';\n\n let html = '<div class=\"detail-header\">' +\n '<h2>' + esc(s.app_name) + '</h2>' +\n '<div class=\"detail-meta\">' +\n '<span>Started: ' + date.toLocaleString() + '</span>' +\n '<span>Duration: ' + duration + '</span>' +\n '<span>Base URL: ' + esc(s.base_url) + '</span>' +\n '<span>Config: ' + esc(s.config_path) + '</span>' +\n '</div>' +\n '</div>';\n\n // Summary cards\n const summary = s.summary;\n if (summary) {\n html += '<div class=\"summary-cards\">' +\n card('Total Calls', summary.total_calls, 'accent') +\n card('Passed', summary.passed, 'green') +\n card('Failed', summary.failed, summary.failed > 0 ? 'red' : '') +\n card('Avg Latency', summary.avg_response_time_ms + 'ms', '') +\n '</div>';\n }\n\n // Tabs\n html += '<div class=\"tabs\">' +\n tabBtn('timeline', 'Timeline (' + s.timeline.length + ')') +\n tabBtn('audit', 'Audit Log (' + s.audit_entries.length + ')') +\n tabBtn('tools', 'Tools (' + s.tools.length + ')') +\n '</div>';\n\n // Tab content\n if (activeTab === 'timeline') {\n html += renderTimeline(s);\n } else if (activeTab === 'audit') {\n html += renderAuditLog(s);\n } else if (activeTab === 'tools') {\n html += renderTools(s);\n }\n\n el.innerHTML = html;\n}\n\nfunction renderTimeline(s) {\n if (s.timeline.length === 0) {\n return '<div class=\"empty-state\"><p>No tool calls recorded in this session.</p></div>';\n }\n\n let html = '<ul class=\"timeline\">';\n for (let i = 0; i < s.timeline.length; i++) {\n const t = s.timeline[i];\n const isActive = i === activeCallIdx ? ' active' : '';\n const iconClass = t.success ? 'pass' : 'fail';\n const icon = t.success ? '\\\\u2713' : '\\\\u2717';\n const statusClass = t.status === null ? 'serr' : t.status < 300 ? 's2xx' : t.status < 500 ? 's4xx' : 's5xx';\n const statusText = t.status !== null ? t.status : 'ERR';\n const gap = t.gap_since_last_ms !== null ? '<span class=\"gap-badge\">+' + formatMs(t.gap_since_last_ms) + ' gap</span>' : '';\n\n html += '<li class=\"timeline-entry' + isActive + '\" onclick=\"selectCall(' + i + ')\">' +\n '<span class=\"seq\">#' + t.seq + '</span>' +\n '<span class=\"icon ' + iconClass + '\">' + icon + '</span>' +\n '<div class=\"content\">' +\n '<div class=\"tool-name\">' + esc(t.tool_name) + '</div>' +\n '<div class=\"entry-meta\">' +\n '<span class=\"status-badge ' + statusClass + '\">' + statusText + '</span>' +\n gap +\n (t.error ? '<span style=\"color:var(--red);font-size:12px\">' + esc(t.error) + '</span>' : '') +\n '</div>' +\n '</div>' +\n '<span class=\"timing\">' + t.elapsed_ms + 'ms</span>' +\n '</li>';\n }\n html += '</ul>';\n\n // Call detail panel\n if (activeCallIdx !== null && s.audit_entries[activeCallIdx]) {\n html += renderCallDetail(s.audit_entries[activeCallIdx], s.timeline[activeCallIdx]);\n }\n\n return html;\n}\n\nfunction renderCallDetail(audit, timeline) {\n let html = '<div class=\"call-detail\">';\n\n // Header\n html += '<div class=\"call-detail-header\">' +\n '<h3>' + esc(audit.tool_name) + '</h3>' +\n '<span class=\"status-badge ' + (audit.success ? 's2xx' : 's4xx') + '\">' + (audit.success ? 'PASS' : 'FAIL') + '</span>' +\n '<span style=\"color:var(--text-dim);font-size:12px;margin-left:auto\">' + audit.total_time_ms + 'ms</span>' +\n '</div>';\n\n // Input\n html += '<div class=\"call-detail-section\"><h4>Input Arguments</h4>' +\n '<pre class=\"code-block\">' + esc(JSON.stringify(audit.raw_input, null, 2)) + '</pre></div>';\n\n // Parameter resolution\n if (audit.parameter_resolutions && audit.parameter_resolutions.length > 0) {\n html += '<div class=\"call-detail-section\"><h4>Parameter Resolution</h4><table class=\"param-table\">' +\n '<tr><th>Name</th><th>Target</th><th>Backend Key</th><th>Value</th><th>Source</th></tr>';\n for (const p of audit.parameter_resolutions) {\n const sourceColor = p.source === 'missing' ? 'var(--red)' : p.source === 'default' ? 'var(--yellow)' : 'var(--green)';\n html += '<tr><td>' + esc(p.name) + '</td><td>' + p.target + '</td><td>' + esc(p.backend_key) + '</td>' +\n '<td>' + esc(JSON.stringify(p.value)) + '</td><td style=\"color:' + sourceColor + '\">' + p.source + '</td></tr>';\n }\n html += '</table></div>';\n }\n\n // Request\n html += '<div class=\"call-detail-section\"><h4>Request</h4>' +\n '<pre class=\"code-block\">' + esc(audit.request_method + ' ' + audit.request_url) + '</pre>';\n if (audit.request_body !== undefined) {\n html += '<pre class=\"code-block\" style=\"margin-top:8px\">' + esc(JSON.stringify(audit.request_body, null, 2)) + '</pre>';\n }\n html += '</div>';\n\n // Response\n if (audit.response_status !== undefined) {\n html += '<div class=\"call-detail-section\"><h4>Response ' + audit.response_status + ' ' + (audit.response_status_text || '') + '</h4>';\n if (audit.response_body !== undefined) {\n const bodyStr = typeof audit.response_body === 'string'\n ? audit.response_body\n : JSON.stringify(audit.response_body, null, 2);\n const truncated = bodyStr.length > 5000 ? bodyStr.slice(0, 5000) + '\\\\n... truncated' : bodyStr;\n html += '<pre class=\"code-block\">' + esc(truncated) + '</pre>';\n }\n html += '</div>';\n }\n\n // Diagnostics\n if (audit.diagnostics && audit.diagnostics.length > 0) {\n html += '<div class=\"call-detail-section\"><h4>Diagnostics</h4>';\n for (const d of audit.diagnostics) {\n html += '<div class=\"diagnostic\">' + esc(d) + '</div>';\n }\n html += '</div>';\n }\n\n // Error\n if (audit.error) {\n html += '<div class=\"call-detail-section\"><h4>Error</h4>' +\n '<div class=\"error-block\"><strong>Phase:</strong> ' + esc(audit.error.phase) +\n '<br>' + esc(audit.error.message) +\n (audit.error.details ? '<br><span style=\"opacity:0.7\">' + esc(audit.error.details) + '</span>' : '') +\n '</div></div>';\n }\n\n html += '</div>';\n return html;\n}\n\nfunction renderAuditLog(s) {\n if (s.audit_entries.length === 0) {\n return '<div class=\"empty-state\"><p>No audit entries recorded.</p></div>';\n }\n\n let html = '<div style=\"font-family:var(--mono);font-size:12px\">';\n for (const entry of s.audit_entries) {\n const icon = entry.success ? '<span style=\"color:var(--green)\">\\\\u2713</span>' : '<span style=\"color:var(--red)\">\\\\u2717</span>';\n const status = entry.response_status ?? 'ERR';\n html += '<div style=\"padding:8px 0;border-bottom:1px solid var(--border)\">' +\n icon + ' <strong>' + esc(entry.tool_name) + '</strong> ' +\n '<span style=\"color:var(--text-dim)\">' + entry.request_method + ' ' + esc(entry.request_url) + '</span> ' +\n '<span style=\"color:' + (entry.success ? 'var(--green)' : 'var(--red)') + '\">' + status + '</span> ' +\n '<span style=\"color:var(--text-dim)\">' + entry.total_time_ms + 'ms</span>' +\n '</div>';\n }\n html += '</div>';\n return html;\n}\n\nfunction renderTools(s) {\n let html = '<div>';\n for (const tool of s.tools) {\n const callCount = s.timeline.filter(t => t.tool_name === tool).length;\n const failCount = s.timeline.filter(t => t.tool_name === tool && !t.success).length;\n html += '<div style=\"padding:10px 0;border-bottom:1px solid var(--border);display:flex;align-items:center;gap:12px\">' +\n '<span style=\"font-weight:600;font-size:14px\">' + esc(tool) + '</span>' +\n '<span style=\"font-family:var(--mono);font-size:12px;color:var(--text-dim)\">' + callCount + ' calls</span>' +\n (failCount > 0 ? '<span style=\"font-family:var(--mono);font-size:12px;color:var(--red)\">' + failCount + ' failed</span>' : '') +\n '</div>';\n }\n html += '</div>';\n return html;\n}\n\n// ── Actions ─────────────────────────────────────────\nfunction selectCall(idx) {\n activeCallIdx = activeCallIdx === idx ? null : idx;\n renderMain();\n}\n\nfunction switchTab(tab) {\n activeTab = tab;\n activeCallIdx = null;\n renderMain();\n}\n\n// ── Helpers ─────────────────────────────────────────\nfunction card(label, value, colorClass) {\n return '<div class=\"card\"><div class=\"card-label\">' + label + '</div>' +\n '<div class=\"card-value ' + colorClass + '\">' + value + '</div></div>';\n}\n\nfunction tabBtn(id, label) {\n return '<button class=\"tab' + (activeTab === id ? ' active' : '') + '\" onclick=\"switchTab(\\\\'' + id + '\\\\')\">' + label + '</button>';\n}\n\nfunction formatMs(ms) {\n if (ms < 1000) return ms + 'ms';\n if (ms < 60000) return (ms / 1000).toFixed(1) + 's';\n return Math.floor(ms / 60000) + 'm' + Math.round((ms % 60000) / 1000) + 's';\n}\n\nfunction esc(str) {\n if (str === null || str === undefined) return '';\n return String(str).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;');\n}\n\n// ── Init ────────────────────────────────────────────\nrenderSidebar();\nif (SESSIONS.length > 0) {\n selectSession(0);\n} else {\n renderMain();\n}\n</script>\n</body>\n</html>`;\n","import { createServer } from 'node:http';\nimport { exec } from 'node:child_process';\nimport { listSessions, getSessionsDir } from './session-store.js';\nimport { buildHtml } from './ui-html.js';\n\n// ANSI helpers\nconst BOLD = '\\x1b[1m';\nconst DIM = '\\x1b[2m';\nconst RESET = '\\x1b[0m';\nconst GREEN = '\\x1b[32m';\nconst CYAN = '\\x1b[36m';\n\nexport interface UiOptions {\n port: number;\n open: boolean;\n}\n\nexport function startUiServer(options: UiOptions): void {\n const server = createServer((req, res) => {\n const url = new URL(req.url ?? '/', `http://localhost:${options.port}`);\n\n // ── API: list sessions as JSON ──────────────────────────────────\n if (req.method === 'GET' && url.pathname === '/api/sessions') {\n const sessions = listSessions().map((s) => s.session);\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(sessions));\n return;\n }\n\n // ── Main HTML page ──────────────────────────────────────────────\n if (req.method === 'GET' && (url.pathname === '/' || url.pathname === '/index.html')) {\n const sessions = listSessions().map((s) => s.session);\n const html = buildHtml(JSON.stringify(sessions));\n res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });\n res.end(html);\n return;\n }\n\n res.writeHead(404, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: 'Not found' }));\n });\n\n server.listen(options.port, '127.0.0.1', () => {\n const sessionsDir = getSessionsDir();\n const sessionCount = listSessions().length;\n\n console.log('');\n console.log(`${GREEN}${BOLD}ToolRelay Session Viewer${RESET}`);\n console.log(`${DIM}${'─'.repeat(50)}${RESET}`);\n console.log(` ${BOLD}UI:${RESET} ${CYAN}http://localhost:${options.port}${RESET}`);\n console.log(` ${BOLD}API:${RESET} http://localhost:${options.port}/api/sessions`);\n console.log(` ${BOLD}Sessions:${RESET} ${sessionCount} found in ${sessionsDir}`);\n console.log(`${DIM}${'─'.repeat(50)}${RESET}`);\n console.log(`${DIM}Press Ctrl+C to stop.${RESET}`);\n console.log('');\n\n if (options.open) {\n openBrowser(`http://localhost:${options.port}`);\n }\n });\n\n process.on('SIGINT', () => {\n server.close();\n process.exit(0);\n });\n process.on('SIGTERM', () => {\n server.close();\n process.exit(0);\n });\n}\n\nfunction openBrowser(url: string): void {\n const platform = process.platform;\n const cmd = platform === 'darwin' ? 'open' : platform === 'win32' ? 'start' : 'xdg-open';\n exec(`${cmd} ${url}`, () => {\n // Ignore errors — browser open is best-effort\n });\n}\n","import { createInterface } from 'node:readline';\nimport { emitKeypressEvents } from 'node:readline';\nimport { AuthType, HttpMethod, PermissionLevel } from '@toolrelay/shared';\nimport type { CliConfig, CliToolConfig } from './types.js';\n\n// ─── ANSI helpers ───────────────────────────────────────────────────────────\n\nconst BOLD = '\\x1b[1m';\nconst DIM = '\\x1b[2m';\nconst CYAN = '\\x1b[36m';\nconst GREEN = '\\x1b[32m';\nconst YELLOW = '\\x1b[33m';\nconst RESET = '\\x1b[0m';\nconst HIDE_CURSOR = '\\x1b[?25l';\nconst SHOW_CURSOR = '\\x1b[?25h';\n\n// ─── Readline prompt helpers ────────────────────────────────────────────────\n\nexport interface ReadlineInterface {\n question(query: string, callback: (answer: string) => void): void;\n close(): void;\n}\n\nlet rl: ReadlineInterface;\nlet usingInjectedRl = false;\n\nfunction initReadline(injectedRl?: ReadlineInterface): void {\n if (injectedRl) {\n rl = injectedRl;\n usingInjectedRl = true;\n } else {\n rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n usingInjectedRl = false;\n }\n}\n\nfunction closeReadline(): void {\n rl.close();\n}\n\nfunction ask(question: string, defaultValue?: string): Promise<string> {\n const suffix = defaultValue ? ` ${DIM}(${defaultValue})${RESET}` : '';\n return new Promise((resolve) => {\n rl.question(` ${question}${suffix}: `, (answer) => {\n resolve(answer.trim() || defaultValue || '');\n });\n });\n}\n\n// ─── Interactive arrow-key selector ─────────────────────────────────────────\n\nfunction askSelectInteractive(question: string, choices: string[], defaultIdx = 0): Promise<string> {\n return new Promise((resolve) => {\n let selected = defaultIdx;\n\n function render(): void {\n // Move cursor up to overwrite previous render (except first time)\n process.stdout.write(`\\x1b[${choices.length}A`);\n for (let i = 0; i < choices.length; i++) {\n const isSelected = i === selected;\n const marker = isSelected ? `${GREEN}${BOLD}> ${RESET}${GREEN}${choices[i]}${RESET}` : ` ${DIM}${choices[i]}${RESET}`;\n process.stdout.write(`\\x1b[2K ${marker}\\n`);\n }\n }\n\n // Print question and initial choices\n console.log(` ${question}`);\n process.stdout.write(HIDE_CURSOR);\n for (let i = 0; i < choices.length; i++) {\n const isSelected = i === selected;\n const marker = isSelected ? `${GREEN}${BOLD}> ${RESET}${GREEN}${choices[i]}${RESET}` : ` ${DIM}${choices[i]}${RESET}`;\n process.stdout.write(` ${marker}\\n`);\n }\n\n // Temporarily close the readline so we can use raw mode\n rl.close();\n\n const stdin = process.stdin;\n emitKeypressEvents(stdin);\n if (stdin.isTTY) stdin.setRawMode(true);\n stdin.resume();\n\n function onKeypress(_ch: string | undefined, key: { name?: string; ctrl?: boolean } | undefined): void {\n if (!key) return;\n\n if (key.ctrl && key.name === 'c') {\n // Restore terminal state and exit\n process.stdout.write(SHOW_CURSOR);\n if (stdin.isTTY) stdin.setRawMode(false);\n stdin.removeListener('keypress', onKeypress);\n stdin.pause();\n process.exit(0);\n }\n\n if (key.name === 'up' || key.name === 'k') {\n selected = (selected - 1 + choices.length) % choices.length;\n render();\n } else if (key.name === 'down' || key.name === 'j') {\n selected = (selected + 1) % choices.length;\n render();\n } else if (key.name === 'return') {\n // Clean up\n process.stdout.write(SHOW_CURSOR);\n if (stdin.isTTY) stdin.setRawMode(false);\n stdin.removeListener('keypress', onKeypress);\n stdin.pause();\n\n // Re-create readline for subsequent prompts\n rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n resolve(choices[selected]!);\n }\n }\n\n stdin.on('keypress', onKeypress);\n });\n}\n\n// ─── Fallback number-based selector (tests / non-TTY) ───────────────────────\n\nfunction askSelectFallback(question: string, choices: string[], defaultIdx = 0): Promise<string> {\n console.log(` ${question}`);\n for (let i = 0; i < choices.length; i++) {\n const marker = i === defaultIdx ? `${GREEN}>${RESET}` : ' ';\n console.log(` ${marker} ${CYAN}${i + 1}${RESET}) ${choices[i]}`);\n }\n return new Promise((resolve) => {\n rl.question(` ${DIM}Pick [1-${choices.length}]${RESET} (${defaultIdx + 1}): `, (answer) => {\n const idx = answer.trim() ? parseInt(answer.trim(), 10) - 1 : defaultIdx;\n resolve(choices[idx >= 0 && idx < choices.length ? idx : defaultIdx]!);\n });\n });\n}\n\nfunction askSelect(question: string, choices: string[], defaultIdx = 0): Promise<string> {\n // Use interactive arrow-key selector when running in a real TTY\n if (!usingInjectedRl && process.stdin.isTTY) {\n return askSelectInteractive(question, choices, defaultIdx);\n }\n return askSelectFallback(question, choices, defaultIdx);\n}\n\nfunction askConfirm(question: string, defaultYes = true): Promise<boolean> {\n const hint = defaultYes ? 'Y/n' : 'y/N';\n return new Promise((resolve) => {\n rl.question(` ${question} ${DIM}(${hint})${RESET}: `, (answer) => {\n const a = answer.trim().toLowerCase();\n if (a === '') resolve(defaultYes);\n else resolve(a === 'y' || a === 'yes');\n });\n });\n}\n\n// ─── Wizard steps ───────────────────────────────────────────────────────────\n\nfunction toSlug(name: string): string {\n return name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '');\n}\n\nasync function promptApp(): Promise<CliConfig['app']> {\n console.log(`\\n${BOLD}App configuration${RESET}`);\n console.log(`${DIM}Tell us about your backend API.${RESET}\\n`);\n\n const name = await ask('App name', 'My API');\n const description = await ask('Description (what does your API do?)');\n const defaultSlug = toSlug(name);\n const slug = await ask('Slug (URL-safe identifier)', defaultSlug);\n const base_url = await ask('Base URL (your production API)', 'https://api.example.com');\n console.log(` ${DIM}Tip: For local testing, keep your production URL here and use${RESET}`);\n console.log(` ${DIM}${CYAN}toolrelay serve config.json --base-url http://localhost:3000${RESET}${DIM} to override at runtime.${RESET}`);\n\n const authTypes = Object.values(AuthType);\n const authLabels: Record<string, string> = {\n none: 'none — No authentication',\n static_token: 'static_token — Bearer token in Authorization header',\n api_key_relay: 'api_key_relay — Consumer API keys relayed to backend',\n custom_header: 'custom_header — Custom header with a static value',\n oauth2: 'oauth2 — OAuth 2.0 flow (authorize + token URLs)',\n };\n const authChoices = authTypes.map((t) => authLabels[t] ?? t);\n const authChoice = await askSelect('Authentication type?', authChoices, 0);\n const auth_type = authTypes[authChoices.indexOf(authChoice)]!;\n\n const auth_config = await promptAuthConfig(auth_type);\n\n // Global headers\n let global_headers: Record<string, string> | undefined;\n const wantHeaders = await askConfirm('Add global headers (sent on every backend request)?', false);\n if (wantHeaders) {\n global_headers = {};\n let more = true;\n while (more) {\n const headerName = await ask('Header name');\n const headerValue = await ask('Header value');\n if (headerName) global_headers[headerName] = headerValue;\n more = await askConfirm('Add another header?', false);\n }\n }\n\n return {\n name,\n description: description || undefined,\n slug: slug || undefined,\n base_url,\n auth_type,\n auth_config,\n global_headers,\n };\n}\n\nasync function promptAuthConfig(authType: AuthType): Promise<Record<string, unknown>> {\n if (authType === AuthType.none) return {};\n\n console.log(`\\n ${DIM}Configuring ${authType} credentials...${RESET}`);\n\n if (authType === AuthType.static_token) {\n const token = await ask('Bearer token');\n return { token };\n }\n\n if (authType === AuthType.custom_header) {\n const header_name = await ask('Header name', 'X-API-Key');\n const header_value = await ask('Header value');\n return { headers: { [header_name]: header_value } };\n }\n\n if (authType === AuthType.api_key_relay) {\n const header_name = await ask('Header name for relayed key', 'X-API-Key');\n return { header_name };\n }\n\n if (authType === AuthType.oauth2) {\n const authorize_url = await ask('OAuth authorize URL');\n const token_url = await ask('OAuth token URL');\n const client_id = await ask('Client ID (leave blank for public client PKCE)', '');\n const client_secret = client_id ? await ask('Client secret') : '';\n const scopes = await ask('Scopes (comma-separated, optional)', '');\n const config: Record<string, unknown> = {\n authorize_url,\n token_url,\n scopes: scopes ? scopes.split(',').map((s) => s.trim()).join(' ') : '',\n use_pkce: true,\n };\n if (client_id) config.client_id = client_id;\n if (client_secret) config.client_secret = client_secret;\n return config;\n }\n\n return {};\n}\n\nasync function promptTool(): Promise<CliToolConfig> {\n console.log(`\\n${BOLD}New tool${RESET}`);\n\n const name = await ask('Tool name (snake_case, e.g. get_users)', 'get_resource');\n const description = await ask('Description', '');\n const methodChoices = Object.values(HttpMethod);\n const http_method = await askSelect('HTTP method?', methodChoices, 0) as HttpMethod;\n\n const endpoint_path = await ask(\n 'Endpoint path',\n '/api/resource',\n );\n\n // Detect path placeholders and auto-create params\n const placeholders = [...endpoint_path.matchAll(/\\{([^}]+)\\}/g)].map((m) => m[1]!);\n const parameter_mapping: CliToolConfig['parameter_mapping'] = [];\n\n if (placeholders.length > 0) {\n console.log(`\\n ${DIM}Detected path parameters: ${placeholders.map((p) => `{${p}}`).join(', ')}${RESET}`);\n for (const ph of placeholders) {\n parameter_mapping.push({\n name: ph,\n type: 'string',\n required: true,\n description: `The ${ph}`,\n target: 'path',\n });\n }\n }\n\n // Additional parameters\n const wantParams = await askConfirm('Add query/body/header parameters?', false);\n if (wantParams) {\n let more = true;\n while (more) {\n const param = await promptParameter(http_method);\n parameter_mapping.push(param);\n more = await askConfirm('Add another parameter?', false);\n }\n }\n\n // Permission level\n const permChoices = [\n 'read — Read-only access',\n 'write — Can modify data',\n 'admin — Full access',\n ];\n const permChoice = await askSelect('Permission level?', permChoices, 0);\n const permValues = Object.values(PermissionLevel);\n const permission_level = permValues[permChoices.indexOf(permChoice)]!;\n\n return {\n name,\n description: description || undefined,\n http_method,\n endpoint_path,\n parameter_mapping,\n permission_level,\n };\n}\n\nasync function promptParameter(method: HttpMethod): Promise<CliToolConfig['parameter_mapping'][number]> {\n console.log('');\n const name = await ask('Parameter name');\n const typeChoices = ['string', 'number', 'boolean', 'object', 'array'];\n const type = await askSelect('Type?', typeChoices, 0) as 'string' | 'number' | 'boolean' | 'object' | 'array';\n\n // Default target based on HTTP method\n const targetDefault = method === 'GET' || method === 'DELETE' ? 'query' : 'body';\n const targetChoices = ['path', 'query', 'body', 'header'];\n const target = await askSelect('Maps to?', targetChoices, targetChoices.indexOf(targetDefault)) as 'path' | 'query' | 'body' | 'header';\n\n const required = await askConfirm('Required?', true);\n const description = await ask('Description', '');\n const backend_key = await ask('Backend key (leave blank if same as name)', '');\n const default_value = await ask('Default value (leave blank for none)', '');\n\n const param: CliToolConfig['parameter_mapping'][number] = {\n name,\n type,\n required,\n description: description || undefined,\n target,\n };\n if (backend_key) param.backend_key = backend_key;\n if (default_value) param.default_value = default_value;\n return param;\n}\n\n// ─── Main wizard ────────────────────────────────────────────────────────────\n\nexport async function runWizard(injectedRl?: ReadlineInterface): Promise<CliConfig> {\n console.log(`\\n${BOLD}${GREEN}ToolRelay Init${RESET}`);\n console.log(`${DIM}Set up your API config — this generates a toolrelay.json you can`);\n console.log(`use with ${CYAN}validate${RESET}${DIM}, ${CYAN}test${RESET}${DIM}, ${CYAN}serve${RESET}${DIM}, and later import into ToolRelay Cloud.${RESET}\\n`);\n\n initReadline(injectedRl);\n\n try {\n // Step 1: App config\n const app = await promptApp();\n\n // Step 2: Tools\n console.log(`\\n${BOLD}Tools${RESET}`);\n console.log(`${DIM}Define the HTTP endpoints you want to expose as AI-callable tools.${RESET}`);\n\n const tools: CliToolConfig[] = [];\n let addMore = true;\n while (addMore) {\n const tool = await promptTool();\n tools.push(tool);\n console.log(` ${GREEN}\\u2713${RESET} Added tool: ${BOLD}${tool.name}${RESET} (${tool.http_method} ${tool.endpoint_path})`);\n addMore = await askConfirm('Add another tool?', false);\n }\n\n return {\n app,\n tools,\n };\n } finally {\n closeReadline();\n }\n}\n\n// ─── Static template (for --yes / non-interactive) ──────────────────────────\n\nexport function buildTemplate(): CliConfig {\n return {\n app: {\n name: 'My API',\n description: 'A sample API for getting started with ToolRelay',\n slug: 'my-api',\n base_url: 'https://api.example.com',\n auth_type: AuthType.none,\n auth_config: {},\n },\n tools: [\n {\n name: 'get_users',\n description: 'List all users',\n http_method: HttpMethod.GET,\n endpoint_path: '/api/users',\n parameter_mapping: [],\n permission_level: PermissionLevel.read,\n },\n {\n name: 'get_user',\n description: 'Get a user by ID',\n http_method: HttpMethod.GET,\n endpoint_path: '/api/users/{id}',\n parameter_mapping: [\n {\n name: 'id',\n type: 'string',\n required: true,\n description: 'The user ID',\n target: 'path',\n },\n ],\n permission_level: PermissionLevel.read,\n },\n ],\n };\n}\n","import { readFileSync } from 'node:fs';\nimport { fileURLToPath } from 'node:url';\nimport { dirname, join } from 'node:path';\nimport { Command } from 'commander';\nimport { loadConfig } from './config-loader.js';\nimport { startMcpServer } from './mcp-server.js';\nimport { startUiServer } from './ui-server.js';\nimport { runWizard, buildTemplate } from './wizard.js';\n\n// Read version from package.json so it stays in sync\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf-8')) as { version: string };\n\nconst program = new Command();\n\nprogram\n .name('toolrelay')\n .description('CLI for ToolRelay — validate configs, serve local MCP servers, and publish to the cloud')\n .version(pkg.version);\n\n// ─── validate ───────────────────────────────────────────────────────────────\n\nprogram\n .command('validate')\n .description('Validate a toolrelay.json config file (no HTTP calls)')\n .argument('<config>', 'Path to toolrelay config JSON file')\n .action((configPath: string) => {\n const result = loadConfig(configPath);\n\n if (!result.success) {\n console.error('\\nConfig validation failed:\\n');\n for (const err of result.errors) {\n console.error(` \\u2717 ${err.path ? `[${err.path}] ` : ''}${err.message}`);\n }\n process.exit(1);\n }\n\n console.log(`\\n\\u2713 Config is valid: ${result.config!.tools.length} tool(s) defined\\n`);\n });\n\n// ─── init ───────────────────────────────────────────────────────────────────\n\nprogram\n .command('init')\n .description('Interactive wizard to generate a toolrelay.json config file')\n .option('-o, --output <path>', 'Output file path (default: <slug>.toolrelay.json)')\n .option('-y, --yes', 'Skip prompts and generate a starter template', false)\n .action(async (opts: { output?: string; yes: boolean }) => {\n const { writeFileSync, existsSync } = await import('node:fs');\n\n let config: ReturnType<typeof buildTemplate>;\n\n if (opts.yes) {\n config = buildTemplate();\n } else {\n config = await runWizard();\n }\n\n // Derive filename from slug (matches UI export pattern: <slug>.toolrelay.json)\n const outputPath = opts.output ?? `${config.app.slug ?? 'toolrelay'}.toolrelay.json`;\n\n if (existsSync(outputPath)) {\n console.error(`Error: ${outputPath} already exists. Remove it first or use -o to specify a different path.`);\n process.exit(1);\n }\n\n writeFileSync(outputPath, JSON.stringify(config, null, 2) + '\\n');\n\n console.log(`\\n\\u2713 Created ${outputPath} (${config.tools.length} tool(s))`);\n console.log(`\\nNext steps:`);\n console.log(` npx @toolrelay/cli validate ${outputPath} ${'\\x1b[2m'}# Check config${'\\x1b[0m'}`);\n console.log(` npx @toolrelay/cli serve ${outputPath} ${'\\x1b[2m'}# Start MCP server${'\\x1b[0m'}`);\n console.log(` npx @toolrelay/cli publish ${outputPath} ${'\\x1b[2m'}# Deploy to ToolRelay${'\\x1b[0m'}`);\n console.log(`\\n${'\\x1b[2m'}Local testing? Override base_url at runtime:${'\\x1b[0m'}`);\n console.log(` npx @toolrelay/cli serve ${outputPath} --base-url http://localhost:3000`);\n console.log('');\n });\n\n// ─── serve ──────────────────────────────────────────────────────────────────\n\nprogram\n .command('serve')\n .description('Start a local MCP Streamable HTTP server — connect Claude Desktop or any MCP client and get audit traces on every tool call')\n .argument('<config>', 'Path to toolrelay config JSON file')\n .option('--base-url <url>', 'Override base_url from config')\n .option('-p, --port <number>', 'Port to listen on', '8787')\n .option('-v, --verbose', 'Show response headers and extra detail', false)\n .action((configPath: string, opts: { baseUrl?: string; port: string; verbose: boolean }) => {\n const result = loadConfig(configPath);\n\n if (!result.success) {\n console.error('\\nConfig validation failed:\\n');\n for (const err of result.errors) {\n console.error(` \\u2717 ${err.path ? `[${err.path}] ` : ''}${err.message}`);\n }\n process.exit(1);\n }\n\n startMcpServer(result.config!, {\n baseUrl: opts.baseUrl,\n port: parseInt(opts.port, 10),\n verbose: opts.verbose,\n configPath: configPath,\n });\n });\n\n// ─── publish ────────────────────────────────────────────────────────────────\n\nprogram\n .command('publish')\n .description('Deploy your toolrelay.json config to ToolRelay — creates or updates the app and tools')\n .argument('<config>', 'Path to toolrelay config JSON file')\n .option('--dry-run', 'Show what would change without making any changes', false)\n .option('--prune', 'Delete remote tools that are not in the config file', false)\n .action(async (configPath: string, opts: { dryRun: boolean; prune: boolean }) => {\n const result = loadConfig(configPath);\n\n if (!result.success) {\n console.error('\\nConfig validation failed:\\n');\n for (const err of result.errors) {\n console.error(` \\u2717 ${err.path ? `[${err.path}] ` : ''}${err.message}`);\n }\n process.exit(1);\n }\n\n const { publish } = await import('./publish.js');\n const publishResult = await publish(result.config!, {\n dryRun: opts.dryRun,\n prune: opts.prune,\n });\n\n process.exit(publishResult.success ? 0 : 1);\n });\n\n// ─── login ──────────────────────────────────────────────────────────────────\n\nprogram\n .command('login')\n .description('Authenticate with ToolRelay — opens a browser to log in')\n .action(async () => {\n const { loginFlow } = await import('./auth-flow.js');\n try {\n await loginFlow();\n } catch (err) {\n console.error(`\\nLogin failed: ${(err as Error).message}\\n`);\n process.exit(1);\n }\n });\n\n// ─── logout ─────────────────────────────────────────────────────────────────\n\nprogram\n .command('logout')\n .description('Remove stored credentials')\n .action(async () => {\n const { clearCredentials } = await import('./credentials.js');\n if (clearCredentials()) {\n console.log('\\n\\u2713 Logged out. Credentials removed from ~/.toolrelay/credentials.json\\n');\n } else {\n console.log('\\nNo stored credentials found.\\n');\n }\n });\n\n// ─── whoami ─────────────────────────────────────────────────────────────────\n\nprogram\n .command('whoami')\n .description('Show the currently authenticated user')\n .action(async () => {\n const { resolveAuth } = await import('./credentials.js');\n const { ToolRelayApiClient } = await import('./api-client.js');\n\n const auth = resolveAuth();\n if (!auth) {\n console.error('\\nNot authenticated. Run `toolrelay login` or set TOOLRELAY_DEPLOY_TOKEN.\\n');\n process.exit(1);\n }\n\n try {\n const client = new ToolRelayApiClient(auth);\n const user = await client.whoami();\n console.log(`\\n Email: ${user.email}`);\n console.log(` Name: ${user.name}`);\n console.log(` Tier: ${user.tier}`);\n console.log(` Auth: ${auth.source === 'env' ? 'TOOLRELAY_DEPLOY_TOKEN' : '~/.toolrelay/credentials.json'}`);\n console.log(` API: ${auth.api_url}\\n`);\n } catch (err) {\n const apiErr = err as { status?: number; message?: string };\n if (apiErr.status === 401) {\n console.error('\\nToken is invalid or expired. Run `toolrelay login` to re-authenticate.\\n');\n } else {\n console.error(`\\nFailed to verify credentials: ${apiErr.message ?? err}\\n`);\n }\n process.exit(1);\n }\n });\n\n// ─── ui ──────────────────────────────────────────────────────────────────────\n\nprogram\n .command('ui')\n .description('Open a local web UI to browse past session logs — like Playwright\\'s HTML reporter for MCP tool calls')\n .option('-p, --port <number>', 'Port to listen on', '8788')\n .option('--no-open', 'Don\\'t auto-open the browser')\n .action((opts: { port: string; open: boolean }) => {\n startUiServer({\n port: parseInt(opts.port, 10),\n open: opts.open,\n });\n });\n\nprogram.parse();\n"]}