Skip to main content
Glama
portel-dev

NCP - Natural Context Provider

by portel-dev
parameter-prompter.ts4.74 kB
/** * Interactive parameter prompting system * Guides users through tool parameters with intelligent prompts */ import * as readline from 'readline'; import chalk from 'chalk'; export interface ParameterInfo { name: string; type: string; required: boolean; description?: string; } export class ParameterPrompter { private rl: readline.Interface; constructor() { this.rl = readline.createInterface({ input: process.stdin, output: process.stdout }); } /** * Prompt user for all tool parameters interactively */ async promptForParameters( toolName: string, parameters: ParameterInfo[], predictor: any, toolContext: string ): Promise<any> { console.log(chalk.blue(`📝 Tool "${toolName}" requires parameters. Let me guide you through them:\n`)); const result: any = {}; // Sort parameters: required first, then optional const sortedParams = [...parameters].sort((a, b) => { if (a.required && !b.required) return -1; if (!a.required && b.required) return 1; return 0; }); for (const param of sortedParams) { const value = await this.promptForParameter(param, predictor, toolContext, toolName); if (value !== null && value !== undefined && value !== '') { result[param.name] = this.convertValue(value, param.type); } } return result; } /** * Prompt for a single parameter */ private async promptForParameter( param: ParameterInfo, predictor: any, toolContext: string, toolName: string ): Promise<string | null> { const icon = param.required ? '📄' : '📔'; const status = param.required ? 'Required' : 'Optional'; const typeInfo = chalk.cyan(`(${param.type})`); console.log(`${icon} ${chalk.bold(param.name)} ${typeInfo} - ${chalk.yellow(status)}`); if (param.description) { console.log(` ${chalk.gray(param.description)}`); } // Generate intelligent suggestion const suggestion = predictor.predictValue( param.name, param.type, toolContext, param.description, toolName ); let prompt = ' Enter value'; if (!param.required) { prompt += ' (press Enter to skip)'; } if (suggestion && typeof suggestion === 'string' && suggestion !== 'example') { prompt += ` [${chalk.green(suggestion)}]`; } prompt += ': '; const input = await this.question(prompt); // If user pressed Enter and we have a suggestion, use it if (input === '' && suggestion && param.required) { console.log(` ${chalk.gray(`Using suggested value: ${suggestion}`)}`); return String(suggestion); } // If optional and empty, skip if (input === '' && !param.required) { console.log(` ${chalk.gray('Skipped')}`); return null; } // If required but empty, use suggestion or ask again if (input === '' && param.required) { if (suggestion) { console.log(` ${chalk.gray(`Using suggested value: ${suggestion}`)}`); return String(suggestion); } else { console.log(chalk.red(' This parameter is required. Please provide a value.')); return await this.promptForParameter(param, predictor, toolContext, toolName); } } console.log(); // Add spacing return input; } /** * Convert string input to appropriate type */ private convertValue(value: string, type: string): any { if (value === '') return undefined; switch (type) { case 'number': case 'integer': const num = Number(value); return isNaN(num) ? value : num; case 'boolean': const lower = value.toLowerCase(); if (lower === 'true' || lower === 'yes' || lower === '1') return true; if (lower === 'false' || lower === 'no' || lower === '0') return false; return Boolean(value); case 'array': try { // Try to parse as JSON array first if (value.startsWith('[')) { return JSON.parse(value); } // Otherwise split by comma return value.split(',').map(s => s.trim()); } catch { return value.split(',').map(s => s.trim()); } case 'object': try { return JSON.parse(value); } catch { return { value }; } default: return value; } } /** * Prompt user with a question */ private question(prompt: string): Promise<string> { return new Promise((resolve) => { this.rl.question(prompt, (answer) => { resolve(answer.trim()); }); }); } /** * Close the readline interface */ close(): void { this.rl.close(); } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/portel-dev/ncp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server