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
JavaScript
;
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();