UNPKG

onerios-mcp-server

Version:

OneriosMCP server providing memory, backlog management, file operations, and utility functions for enhanced AI assistant capabilities

323 lines (322 loc) 12.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.dataAnalysis = exports.DataAnalysis = void 0; const zod_1 = require("zod"); class DataAnalysis { constructor() { this.tools = [ { name: 'parse_json', description: 'Parse and validate JSON data', inputSchema: zod_1.z.object({ json_string: zod_1.z.string().describe('JSON string to parse'), validate_schema: zod_1.z.boolean().optional().default(false).describe('Whether to validate the JSON structure'), }), }, { name: 'format_json', description: 'Format JSON with proper indentation', inputSchema: zod_1.z.object({ json_string: zod_1.z.string().describe('JSON string to format'), indent: zod_1.z.number().optional().default(2).describe('Number of spaces for indentation'), sort_keys: zod_1.z.boolean().optional().default(false).describe('Whether to sort object keys'), }), }, { name: 'json_query', description: 'Query JSON data using JSONPath-like syntax', inputSchema: zod_1.z.object({ json_string: zod_1.z.string().describe('JSON string to query'), path: zod_1.z.string().describe('Object path to extract (e.g., "data.users[0].name")'), }), }, { name: 'csv_to_json', description: 'Convert CSV data to JSON format', inputSchema: zod_1.z.object({ csv_data: zod_1.z.string().describe('CSV data as string'), delimiter: zod_1.z.string().optional().default(',').describe('CSV delimiter'), has_header: zod_1.z.boolean().optional().default(true).describe('Whether first row contains headers'), }), }, { name: 'json_to_csv', description: 'Convert JSON array to CSV format', inputSchema: zod_1.z.object({ json_string: zod_1.z.string().describe('JSON array string to convert'), delimiter: zod_1.z.string().optional().default(',').describe('CSV delimiter to use'), include_header: zod_1.z.boolean().optional().default(true).describe('Whether to include header row'), }), }, { name: 'analyze_data_structure', description: 'Analyze the structure of JSON data', inputSchema: zod_1.z.object({ json_string: zod_1.z.string().describe('JSON string to analyze'), max_depth: zod_1.z.number().optional().default(10).describe('Maximum depth to analyze'), }), }, ]; } getTools() { return this.tools; } hasHandler(name) { return this.tools.some(tool => tool.name === name); } async handleTool(name, args) { switch (name) { case 'parse_json': return this.parseJson(args); case 'format_json': return this.formatJson(args); case 'json_query': return this.jsonQuery(args); case 'csv_to_json': return this.csvToJson(args); case 'json_to_csv': return this.jsonToCsv(args); case 'analyze_data_structure': return this.analyzeDataStructure(args); default: throw new Error(`Unknown tool: ${name}`); } } async parseJson(args) { try { const parsed = JSON.parse(args.json_string); let result = 'JSON parsing successful!\n'; result += `Type: ${Array.isArray(parsed) ? 'Array' : typeof parsed}\n`; if (Array.isArray(parsed)) { result += `Length: ${parsed.length}\n`; } else if (typeof parsed === 'object' && parsed !== null) { result += `Keys: ${Object.keys(parsed).length}\n`; } if (args.validate_schema) { result += '\nStructure Analysis:\n'; result += this.getStructureInfo(parsed, 0, 3); } return { content: [{ type: 'text', text: result, }], }; } catch (error) { throw new Error(`Invalid JSON: ${error}`); } } async formatJson(args) { try { let parsed = JSON.parse(args.json_string); if (args.sort_keys) { parsed = this.sortObjectKeys(parsed); } const formatted = JSON.stringify(parsed, null, args.indent); return { content: [{ type: 'text', text: formatted, }], }; } catch (error) { throw new Error(`Failed to format JSON: ${error}`); } } async jsonQuery(args) { try { const data = JSON.parse(args.json_string); const result = this.getNestedValue(data, args.path); return { content: [{ type: 'text', text: result !== undefined ? JSON.stringify(result, null, 2) : 'Path not found', }], }; } catch (error) { throw new Error(`Failed to query JSON: ${error}`); } } async csvToJson(args) { try { const lines = args.csv_data.trim().split('\n'); if (lines.length === 0) { throw new Error('Empty CSV data'); } const delimiter = args.delimiter || ','; let headers; let dataLines; if (args.has_header) { headers = this.parseCsvLine(lines[0], delimiter); dataLines = lines.slice(1); } else { // Generate generic headers const firstLine = this.parseCsvLine(lines[0], delimiter); headers = firstLine.map((_, index) => `column_${index + 1}`); dataLines = lines; } const result = dataLines.map(line => { const values = this.parseCsvLine(line, delimiter); const obj = {}; headers.forEach((header, index) => { obj[header] = values[index] || ''; }); return obj; }); return { content: [{ type: 'text', text: JSON.stringify(result, null, 2), }], }; } catch (error) { throw new Error(`Failed to convert CSV to JSON: ${error}`); } } async jsonToCsv(args) { try { const data = JSON.parse(args.json_string); if (!Array.isArray(data)) { throw new Error('JSON must be an array of objects'); } if (data.length === 0) { return { content: [{ type: 'text', text: 'Empty array', }], }; } const delimiter = args.delimiter || ','; const headers = Object.keys(data[0]); let csv = ''; if (args.include_header) { csv += headers.map(header => this.escapeCsvValue(header, delimiter)).join(delimiter) + '\n'; } csv += data.map(row => headers.map(header => this.escapeCsvValue(String(row[header] || ''), delimiter)).join(delimiter)).join('\n'); return { content: [{ type: 'text', text: csv, }], }; } catch (error) { throw new Error(`Failed to convert JSON to CSV: ${error}`); } } async analyzeDataStructure(args) { try { const data = JSON.parse(args.json_string); const analysis = this.getStructureInfo(data, 0, args.max_depth || 10); return { content: [{ type: 'text', text: `Data Structure Analysis:\n${analysis}`, }], }; } catch (error) { throw new Error(`Failed to analyze data structure: ${error}`); } } // Helper methods getStructureInfo(obj, depth, maxDepth) { if (depth >= maxDepth) { return `${' '.repeat(depth)}[Max depth reached]\n`; } if (obj === null) { return `${' '.repeat(depth)}null\n`; } if (Array.isArray(obj)) { let result = `${' '.repeat(depth)}Array[${obj.length}]\n`; if (obj.length > 0) { result += this.getStructureInfo(obj[0], depth + 1, maxDepth); if (obj.length > 1) { result += `${' '.repeat(depth + 1)}... (${obj.length - 1} more items)\n`; } } return result; } if (typeof obj === 'object') { const keys = Object.keys(obj); let result = `${' '.repeat(depth)}Object {${keys.length} keys}\n`; keys.slice(0, 5).forEach(key => { result += `${' '.repeat(depth + 1)}${key}: `; result += this.getStructureInfo(obj[key], depth + 1, maxDepth); }); if (keys.length > 5) { result += `${' '.repeat(depth + 1)}... (${keys.length - 5} more keys)\n`; } return result; } return `${' '.repeat(depth)}${typeof obj}: ${String(obj).slice(0, 50)}${String(obj).length > 50 ? '...' : ''}\n`; } sortObjectKeys(obj) { if (Array.isArray(obj)) { return obj.map(item => this.sortObjectKeys(item)); } if (typeof obj === 'object' && obj !== null) { const sorted = {}; Object.keys(obj).sort().forEach(key => { sorted[key] = this.sortObjectKeys(obj[key]); }); return sorted; } return obj; } getNestedValue(obj, path) { return path.split('.').reduce((current, key) => { if (current === null || current === undefined) { return undefined; } // Handle array indices const arrayMatch = key.match(/^(\w+)\[(\d+)\]$/); if (arrayMatch) { const [, arrayKey, index] = arrayMatch; return current[arrayKey] ? current[arrayKey][parseInt(index)] : undefined; } return current[key]; }, obj); } parseCsvLine(line, delimiter) { const result = []; let current = ''; let inQuotes = false; for (let i = 0; i < line.length; i++) { const char = line[i]; if (char === '"') { if (inQuotes && line[i + 1] === '"') { current += '"'; i++; // Skip next quote } else { inQuotes = !inQuotes; } } else if (char === delimiter && !inQuotes) { result.push(current); current = ''; } else { current += char; } } result.push(current); return result; } escapeCsvValue(value, delimiter) { if (value.includes(delimiter) || value.includes('"') || value.includes('\n')) { return `"${value.replace(/"/g, '""')}"`; } return value; } } exports.DataAnalysis = DataAnalysis; exports.dataAnalysis = new DataAnalysis();