()
| 2360 | } |
| 2361 | |
| 2362 | export async function readClientSecret(): Promise<string> { |
| 2363 | const envSecret = process.env.MCP_CLIENT_SECRET |
| 2364 | if (envSecret) { |
| 2365 | return envSecret |
| 2366 | } |
| 2367 | |
| 2368 | if (!process.stdin.isTTY) { |
| 2369 | throw new Error( |
| 2370 | 'No TTY available to prompt for client secret. Set MCP_CLIENT_SECRET env var instead.', |
| 2371 | ) |
| 2372 | } |
| 2373 | |
| 2374 | return new Promise((resolve, reject) => { |
| 2375 | process.stderr.write('Enter OAuth client secret: ') |
| 2376 | process.stdin.setRawMode?.(true) |
| 2377 | let secret = '' |
| 2378 | const onData = (ch: Buffer) => { |
| 2379 | const c = ch.toString() |
| 2380 | if (c === '\n' || c === '\r') { |
| 2381 | process.stdin.setRawMode?.(false) |
| 2382 | process.stdin.removeListener('data', onData) |
| 2383 | process.stderr.write('\n') |
| 2384 | resolve(secret) |
| 2385 | } else if (c === '\u0003') { |
| 2386 | process.stdin.setRawMode?.(false) |
| 2387 | process.stdin.removeListener('data', onData) |
| 2388 | reject(new Error('Cancelled')) |
| 2389 | } else if (c === '\u007F' || c === '\b') { |
| 2390 | secret = secret.slice(0, -1) |
| 2391 | } else { |
| 2392 | secret += c |
| 2393 | } |
| 2394 | } |
| 2395 | process.stdin.on('data', onData) |
| 2396 | }) |
| 2397 | } |
| 2398 | |
| 2399 | export function saveMcpClientSecret( |
| 2400 | serverName: string, |
no test coverage detected