Skip to main content
Glama
nlp-tools.ts11 kB
/** * Natural Language Processing Tools * Provides natural language interface to MCP operations * Part of Jaxon Digital Optimizely DXP MCP Server */ import NLPParser from '../nlp-parser'; import ResponseBuilder from '../response-builder'; import ErrorHandler from '../error-handler'; /** * Tool manager interface (minimal - only methods we use) */ interface ToolManager { hasToolAsync(toolName: string): boolean; getAvailableTools(): string[]; executeToolAsync(toolName: string, args: any): Promise<any>; } /** * NLP parser interface (minimal - only methods we use) */ interface NLPParserInstance { parseWithContext(command: string, context: { currentProject?: string }): NLPParseResult; parse(command: string): NLPParseResult; getConfidenceScore(parsed: NLPParseResult): number; getExamples(): NLPExamples; } /** * NLP parse result */ interface NLPParseResult { tool?: string; arguments?: any; category?: string; error?: string; message?: string; suggestions?: string[]; metadata?: { parsedAt?: string; issues?: string[]; }; } /** * NLP examples by category */ interface NLPExamples { deployment: string[]; database: string[]; download: string[]; [category: string]: string[]; } /** * Parse and execute arguments */ export interface ParseAndExecuteArgs { command: string; projectName?: string; } /** * Batch execute arguments */ export interface BatchExecuteArgs { commands: string | string[]; projectName?: string; } /** * Get help arguments */ export interface GetHelpArgs { category?: string; } /** * Analyze command arguments */ export interface AnalyzeCommandArgs { command: string; } /** * Batch command result */ interface BatchCommandResult { command: string; success: boolean; result: any; } /** * Batch error result */ interface BatchErrorResult { command: string; error: string; } /** * NLP metadata attached to results */ interface NLPMetadata { originalCommand: string; interpretedAs: string; confidence: string; parsedAt?: string; } class NLPTools { private toolManager: ToolManager; private parser: NLPParserInstance; constructor(toolManager: ToolManager) { this.toolManager = toolManager; this.parser = new NLPParser() as unknown as NLPParserInstance; } /** * Parse and execute natural language command */ async parseAndExecute(args: ParseAndExecuteArgs): Promise<any> { try { const { command, projectName } = args; if (!command) { return ResponseBuilder.error('No command provided', { suggestions: this.parser.getExamples().deployment.slice(0, 3) }); } // Parse the natural language command const parsed = this.parser.parseWithContext(command, { currentProject: projectName }); // Handle parse errors if (parsed.error) { // Special handling for ambiguous download command if (parsed.error === 'Ambiguous download command') { let message = '# 🤔 What Would You Like to Download?\n\n'; message += parsed.message + '\n\n'; message += '## Available Download Options:\n\n'; for (const suggestion of parsed.suggestions || []) { const [cmd, desc] = suggestion.split(' - '); message += `• **${cmd}** - ${desc}\n`; } message += '\n## 💡 Examples:\n'; message += '```bash\n'; message += '"download database from production"\n'; message += '"download blobs from staging"\n'; message += '"download application logs daysBack: 7"\n'; message += '```\n\n'; message += '**Please specify what you want to download.**'; return ResponseBuilder.success(message); } return ResponseBuilder.error(parsed.error, { originalCommand: command, suggestions: parsed.suggestions || this.getDefaultSuggestions() }); } // Get confidence score const confidence = this.parser.getConfidenceScore(parsed); // If low confidence, ask for confirmation if (confidence < 50) { return ResponseBuilder.successWithStructuredData({ interpreted: { tool: parsed.tool, arguments: parsed.arguments }, confidence: `${confidence}%`, suggestions: parsed.suggestions || [`Try being more specific, e.g., "deploy from staging to production"`], originalCommand: command }, '⚠️ Low confidence in command interpretation'); } // Check if tool exists const toolExists = this.toolManager.hasToolAsync(parsed.tool!); if (!toolExists) { return ResponseBuilder.error(`Tool '${parsed.tool}' not found`, { availableTools: this.toolManager.getAvailableTools(), originalCommand: command }); } // Execute the parsed command const result = await this.toolManager.executeToolAsync(parsed.tool!, parsed.arguments); // Add metadata about NLP parsing if (result && typeof result === 'object') { (result as any).nlpMetadata = { originalCommand: command, interpretedAs: parsed.tool, confidence: `${confidence}%`, parsedAt: parsed.metadata?.parsedAt } as NLPMetadata; } return result; } catch (error: any) { return ErrorHandler.handleError(error, 'parseAndExecute'); } } /** * Get suggestions for common commands */ getDefaultSuggestions(): string[] { return [ 'deploy to production', 'backup database', 'check deployment status', 'test connection', 'rollback production' ]; } /** * Batch execute multiple natural language commands */ async batchExecute(args: BatchExecuteArgs): Promise<any> { try { const { commands, projectName } = args; // Parse batch commands const commandList = Array.isArray(commands) ? commands : commands.split(/[,;]\s*/); const results: BatchCommandResult[] = []; const errors: BatchErrorResult[] = []; for (const command of commandList) { try { const result = await this.parseAndExecute({ command: command.trim(), projectName }); results.push({ command: command.trim(), success: !result.error, result }); } catch (error: any) { errors.push({ command: command.trim(), error: error.message }); } } return ResponseBuilder.successWithStructuredData({ totalCommands: commandList.length, successful: results.filter(r => r.success).length, failed: results.filter(r => !r.success).length + errors.length, results, errors: errors.length > 0 ? errors : undefined }, 'Batch execution completed'); } catch (error: any) { return ErrorHandler.handleError(error, 'batchExecute'); } } /** * Get help for natural language commands */ getHelp(args: GetHelpArgs = {}): any { const { category } = args; const examples = this.parser.getExamples(); if (category && examples[category]) { return ResponseBuilder.successWithStructuredData({ category, examples: examples[category], tip: 'You can combine these with project names, e.g., "deploy to production for ACME"' }, `${category} command examples`); } return ResponseBuilder.successWithStructuredData({ description: 'You can use natural language to control DXP operations', categories: Object.keys(examples), examples: { basic: [ 'deploy to production', 'backup database', 'check status' ], advanced: [ 'deploy from staging to prod code only', 'backup production database and auto-download', 'copy content from prod to staging for ACME' ] }, allExamples: examples, tips: [ 'Environment aliases work: prod, staging, dev, etc.', 'Add project context: "for ProjectName" or "using ProjectName"', 'Combine options: "deploy to prod dry-run with maintenance page"', 'Batch commands: "deploy to prod, backup database, check status"' ] }, 'Natural Language Command Help'); } /** * Analyze natural language command without executing */ analyzeCommand(args: AnalyzeCommandArgs): any { try { const { command } = args; if (!command) { return ResponseBuilder.error('No command provided'); } const parsed = this.parser.parse(command); const confidence = this.parser.getConfidenceScore(parsed); return ResponseBuilder.successWithStructuredData({ originalCommand: command, interpretation: { tool: parsed.tool || 'unknown', arguments: parsed.arguments || {}, category: parsed.category || 'unknown' }, confidence: { score: confidence, level: confidence >= 80 ? 'high' : confidence >= 50 ? 'medium' : 'low' }, validation: parsed.metadata?.issues || [], suggestions: parsed.suggestions || [], wouldExecute: parsed.tool && !parsed.error }, 'Command analysis'); } catch (error: any) { return ErrorHandler.handleError(error, 'analyzeCommand'); } } } export default NLPTools;

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/JaxonDigital/optimizely-dxp-mcp'

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