#!/usr/bin/env node
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
import { fileURLToPath } from 'url';
import { dirname, join } from 'path';
import { existsSync } from 'fs';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
// Determine if running in Docker or locally
const isDocker =
process.env.NODE_ENV === 'production' ||
process.env.DOCKER === 'true' ||
existsSync('/.dockerenv') ||
existsSync('/app/build/index.js') ||
(typeof process.env.HOME === 'undefined' || process.env.HOME === '/app');
async function testMCP() {
console.log('π Starting Sys8 MCP Server Tests\n');
console.log(`Environment: ${isDocker ? 'Docker' : 'Local'}\n`);
const client = new Client({
name: 'test-client',
version: '1.0.0',
}, {
capabilities: {},
});
// Determine server path based on environment
let serverPath;
let command;
let args;
if (isDocker) {
// Running in Docker - use compiled JavaScript
serverPath = join('/app', 'build', 'index.js');
command = 'node';
args = [serverPath];
} else {
// Running locally - use TypeScript with tsx
serverPath = join(__dirname, 'src', 'index.ts');
command = 'npx';
args = ['tsx', serverPath];
}
const transport = new StdioClientTransport({
command,
args,
});
try {
await client.connect(transport);
console.log('β
Connected to MCP server\n');
// Test 1: get_current_datetime - Check all formats
console.log('π Test 1: get_current_datetime - All formats');
try {
const result1 = await client.callTool({
name: 'get_current_datetime',
arguments: {},
});
const data = JSON.parse(result1.content[0].text);
console.log('Result:', result1.content[0].text);
// Verify all required formats are present
const requiredFields = [
'utc', 'date', 'time', 'datetime',
'unix_timestamp_seconds', 'unix_timestamp_milliseconds',
'human_readable_utc0', 'human_readable_utc2', 'human_readable_utc3'
];
const missingFields = requiredFields.filter(field => !(field in data));
if (missingFields.length > 0) {
throw new Error(`Missing fields: ${missingFields.join(', ')}`);
}
console.log('β
get_current_datetime: PASSED (all formats present)\n');
} catch (error) {
console.error('β get_current_datetime: FAILED', error);
}
// Test 2: get_os_version - Check user information
console.log('π» Test 2: get_os_version - User information');
try {
const result2 = await client.callTool({
name: 'get_os_version',
arguments: {},
});
const data = JSON.parse(result2.content[0].text);
console.log('Result:', result2.content[0].text);
// Verify user information fields
const requiredFields = ['username', 'homedir', 'hostname'];
const missingFields = requiredFields.filter(field => !(field in data));
if (missingFields.length > 0) {
throw new Error(`Missing fields: ${missingFields.join(', ')}`);
}
console.log('β
get_os_version: PASSED (user info present)\n');
} catch (error) {
console.error('β get_os_version: FAILED', error);
}
// Test 3: calculate_math_expression - Simple arithmetic
console.log('π’ Test 3: calculate_math_expression - Simple arithmetic');
try {
const result3 = await client.callTool({
name: 'calculate_math_expression',
arguments: { expression: '2 + 2' },
});
const data = JSON.parse(result3.content[0].text);
if (data.result !== 4) {
throw new Error(`Expected 4, got ${data.result}`);
}
console.log('Result (2 + 2):', result3.content[0].text);
console.log('β
calculate_math_expression (simple): PASSED\n');
} catch (error) {
console.error('β calculate_math_expression (simple): FAILED', error);
}
// Test 4: calculate_math_expression - Complex expression
console.log('π’ Test 4: calculate_math_expression - Complex expression');
try {
const result4 = await client.callTool({
name: 'calculate_math_expression',
arguments: { expression: '(10 + 5) * 3 / 2' },
});
const data = JSON.parse(result4.content[0].text);
if (data.result !== 22.5) {
throw new Error(`Expected 22.5, got ${data.result}`);
}
console.log('Result ((10 + 5) * 3 / 2):', result4.content[0].text);
console.log('β
calculate_math_expression (complex): PASSED\n');
} catch (error) {
console.error('β calculate_math_expression (complex): FAILED', error);
}
// Test 5: calculate_math_expression - Functions
console.log('π’ Test 5: calculate_math_expression - Functions');
try {
const result5 = await client.callTool({
name: 'calculate_math_expression',
arguments: { expression: 'sqrt(16)' },
});
const data = JSON.parse(result5.content[0].text);
if (data.result !== 4) {
throw new Error(`Expected 4, got ${data.result}`);
}
console.log('Result (sqrt(16)):', result5.content[0].text);
console.log('β
calculate_math_expression (functions): PASSED\n');
} catch (error) {
console.error('β calculate_math_expression (functions): FAILED', error);
}
// Test 6: calculate_math_expression - Division by zero (error case)
console.log('π’ Test 6: calculate_math_expression - Division by zero (error case)');
try {
const result6 = await client.callTool({
name: 'calculate_math_expression',
arguments: { expression: '5 / 0' },
});
console.log('Result (5 / 0):', result6.content[0].text);
console.log('β οΈ calculate_math_expression (division by zero): Should have failed but did not\n');
} catch (error) {
console.log('β
calculate_math_expression (division by zero): Correctly failed');
console.log('Error message:', error.message);
console.log('');
}
// Test 7: calculate_math_expression - Invalid syntax (error case)
console.log('π’ Test 7: calculate_math_expression - Invalid syntax (error case)');
try {
const result7 = await client.callTool({
name: 'calculate_math_expression',
arguments: { expression: '2 +' },
});
console.log('Result (2 +):', result7.content[0].text);
console.log('β οΈ calculate_math_expression (invalid syntax): Should have failed but did not\n');
} catch (error) {
console.log('β
calculate_math_expression (invalid syntax): Correctly failed');
console.log('Error message:', error.message);
console.log('');
}
// Test 8: generate_random - Hex (all lengths)
console.log('π² Test 8: generate_random - Hex (all lengths)');
try {
const result8 = await client.callTool({
name: 'generate_random',
arguments: { type: 'hex' },
});
const data = JSON.parse(result8.content[0].text);
console.log('Result:', result8.content[0].text);
// Verify hex fields are present
if (!data.hex || typeof data.hex !== 'object') {
throw new Error('Missing or invalid hex field');
}
const hexFields = Object.keys(data.hex);
if (hexFields.length === 0) {
throw new Error('No hex values generated');
}
console.log('β
generate_random (hex): PASSED\n');
} catch (error) {
console.error('β generate_random (hex): FAILED', error);
}
// Test 8b: generate_random - UUID
console.log('π Test 8b: generate_random - UUID');
try {
const result8b = await client.callTool({
name: 'generate_random',
arguments: { type: 'uuid' },
});
const data = JSON.parse(result8b.content[0].text);
console.log('Result:', result8b.content[0].text);
// Verify UUID fields are present
if (!data.uuid || typeof data.uuid !== 'object') {
throw new Error('Missing or invalid uuid field');
}
const requiredUuidFields = ['standard', 'uppercase', 'without_dashes'];
const missingFields = requiredUuidFields.filter(field => !(field in data.uuid));
if (missingFields.length > 0) {
throw new Error(`Missing UUID fields: ${missingFields.join(', ')}`);
}
// Verify UUID format
const uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
if (!uuidPattern.test(data.uuid.standard)) {
throw new Error(`Invalid UUID format: ${data.uuid.standard}`);
}
console.log('β
generate_random (uuid): PASSED\n');
} catch (error) {
console.error('β generate_random (uuid): FAILED', error);
}
// Test 9: hash_string - Simple hash
console.log('π Test 9: hash_string - Simple hash');
try {
const result9 = await client.callTool({
name: 'hash_string',
arguments: { input: 'test string' },
});
const data = JSON.parse(result9.content[0].text);
console.log('Result:', result9.content[0].text);
// Verify all hash formats are present
const requiredFields = [
'input', 'sha256_hex', 'sha256_base64', 'sha512_hex', 'sha512_base64'
];
const missingFields = requiredFields.filter(field => !(field in data));
if (missingFields.length > 0) {
throw new Error(`Missing fields: ${missingFields.join(', ')}`);
}
// Verify hash format (hex should be 64 chars for SHA256, 128 for SHA512)
if (data.sha256_hex.length !== 64) {
throw new Error(`SHA256 hex should be 64 chars, got ${data.sha256_hex.length}`);
}
if (data.sha512_hex.length !== 128) {
throw new Error(`SHA512 hex should be 128 chars, got ${data.sha512_hex.length}`);
}
console.log('β
hash_string: PASSED\n');
} catch (error) {
console.error('β hash_string: FAILED', error);
}
// Test 10: hash_string - Empty input (error case)
console.log('π Test 10: hash_string - Empty input (error case)');
try {
const result10 = await client.callTool({
name: 'hash_string',
arguments: { input: '' },
});
console.log('Result (empty):', result10.content[0].text);
console.log('β οΈ hash_string (empty input): Should have failed but did not\n');
} catch (error) {
console.log('β
hash_string (empty input): Correctly failed');
console.log('Error message:', error.message);
console.log('');
}
// Test 11: validate_data - JSON
console.log('β
Test 11: validate_data - JSON');
try {
const result11 = await client.callTool({
name: 'validate_data',
arguments: { input: '{"key":"value","number":123}', type: 'json' },
});
const data = JSON.parse(result11.content[0].text);
console.log('Result:', result11.content[0].text);
if (!data.valid) {
throw new Error('Valid JSON was marked as invalid');
}
if (!data.normalized || typeof data.normalized !== 'string') {
throw new Error('Missing or invalid normalized field');
}
console.log('β
validate_data (json): PASSED\n');
} catch (error) {
console.error('β validate_data (json): FAILED', error);
}
// Test 11b: validate_data - Invalid JSON
console.log('β
Test 11b: validate_data - Invalid JSON');
try {
const result11b = await client.callTool({
name: 'validate_data',
arguments: { input: '{"key":invalid}', type: 'json' },
});
const data = JSON.parse(result11b.content[0].text);
console.log('Result:', result11b.content[0].text);
if (data.valid) {
throw new Error('Invalid JSON was marked as valid');
}
if (!data.error) {
throw new Error('Missing error message for invalid JSON');
}
console.log('β
validate_data (invalid json): PASSED\n');
} catch (error) {
console.error('β validate_data (invalid json): FAILED', error);
}
// Test 12: encode_base64
console.log('π¦ Test 12: encode_base64');
try {
const result12 = await client.callTool({
name: 'encode_base64',
arguments: { input: 'Hello World!' },
});
const data = JSON.parse(result12.content[0].text);
console.log('Result:', result12.content[0].text);
if (!data.encoded || typeof data.encoded !== 'string') {
throw new Error('Missing or invalid encoded field');
}
// Verify it's valid base64
const base64Pattern = /^[A-Za-z0-9+/]*={0,2}$/;
if (!base64Pattern.test(data.encoded)) {
throw new Error(`Invalid Base64 format: ${data.encoded}`);
}
console.log('β
encode_base64: PASSED\n');
} catch (error) {
console.error('β encode_base64: FAILED', error);
}
// Test 13: decode_base64
console.log('π¦ Test 13: decode_base64');
try {
const result13 = await client.callTool({
name: 'decode_base64',
arguments: { input: 'SGVsbG8gV29ybGQh' },
});
const data = JSON.parse(result13.content[0].text);
console.log('Result:', result13.content[0].text);
if (data.decoded !== 'Hello World!') {
throw new Error(`Expected 'Hello World!', got '${data.decoded}'`);
}
console.log('β
decode_base64: PASSED\n');
} catch (error) {
console.error('β decode_base64: FAILED', error);
}
// Test 14: format_text_case
console.log('π Test 14: format_text_case');
try {
const result14 = await client.callTool({
name: 'format_text_case',
arguments: { input: 'hello world example' },
});
const data = JSON.parse(result14.content[0].text);
console.log('Result:', result14.content[0].text);
// Verify all formats are present
const requiredFields = [
'input', 'camelCase', 'PascalCase', 'kebab-case', 'snake_case',
'CONSTANT_CASE', 'Title Case', 'lowercase', 'UPPERCASE'
];
const missingFields = requiredFields.filter(field => !(field in data));
if (missingFields.length > 0) {
throw new Error(`Missing fields: ${missingFields.join(', ')}`);
}
// Verify some expected values
if (data.camelCase !== 'helloWorldExample') {
throw new Error(`Expected 'helloWorldExample', got '${data.camelCase}'`);
}
if (data['kebab-case'] !== 'hello-world-example') {
throw new Error(`Expected 'hello-world-example', got '${data['kebab-case']}'`);
}
console.log('β
format_text_case: PASSED\n');
} catch (error) {
console.error('β format_text_case: FAILED', error);
}
// Test 15: validate_data - Email
console.log('β
Test 15: validate_data - Email');
try {
const result15 = await client.callTool({
name: 'validate_data',
arguments: { input: 'user@example.com', type: 'email' },
});
const data = JSON.parse(result15.content[0].text);
console.log('Result:', result15.content[0].text);
if (!data.valid) {
throw new Error('Valid email was marked as invalid');
}
console.log('β
validate_data (email): PASSED\n');
} catch (error) {
console.error('β validate_data (email): FAILED', error);
}
// Test 16: validate_data - Invalid email
console.log('β
Test 16: validate_data - Invalid email');
try {
const result16 = await client.callTool({
name: 'validate_data',
arguments: { input: 'not-an-email', type: 'email' },
});
const data = JSON.parse(result16.content[0].text);
console.log('Result:', result16.content[0].text);
if (data.valid) {
throw new Error('Invalid email was marked as valid');
}
console.log('β
validate_data (invalid email): PASSED\n');
} catch (error) {
console.error('β validate_data (invalid email): FAILED', error);
}
// Test 17: format_json - Format
console.log('π Test 17: format_json - Format');
try {
const result17 = await client.callTool({
name: 'format_json',
arguments: { input: '{"key":"value","number":123}', action: 'format' },
});
const data = JSON.parse(result17.content[0].text);
console.log('Result:', result17.content[0].text);
if (!data.valid) {
throw new Error('Valid JSON was marked as invalid');
}
if (!data.formatted || typeof data.formatted !== 'string') {
throw new Error('Missing or invalid formatted field');
}
console.log('β
format_json (format): PASSED\n');
} catch (error) {
console.error('β format_json (format): FAILED', error);
}
// Test 18: format_json - Invalid JSON
console.log('π Test 18: format_json - Invalid JSON');
try {
const result18 = await client.callTool({
name: 'format_json',
arguments: { input: '{"key":invalid}', action: 'validate' },
});
const data = JSON.parse(result18.content[0].text);
console.log('Result:', result18.content[0].text);
if (data.valid) {
throw new Error('Invalid JSON was marked as valid');
}
if (!data.error) {
throw new Error('Missing error message for invalid JSON');
}
console.log('β
format_json (invalid): PASSED\n');
} catch (error) {
console.error('β format_json (invalid): FAILED', error);
}
// Test 19: generate_password - Default
console.log('π Test 19: generate_password - Default');
try {
const result19 = await client.callTool({
name: 'generate_password',
arguments: {},
});
const data = JSON.parse(result19.content[0].text);
console.log('Result:', result19.content[0].text);
if (!data.password || typeof data.password !== 'string') {
throw new Error('Missing or invalid password field');
}
if (data.password.length !== 16) {
throw new Error(`Expected password length 16, got ${data.password.length}`);
}
if (!['weak', 'medium', 'strong', 'very-strong'].includes(data.strength)) {
throw new Error(`Invalid strength value: ${data.strength}`);
}
console.log('β
generate_password (default): PASSED\n');
} catch (error) {
console.error('β generate_password (default): FAILED', error);
}
// Test 20: generate_password - Custom
console.log('π Test 20: generate_password - Custom');
try {
const result20 = await client.callTool({
name: 'generate_password',
arguments: {
length: 20,
include_symbols: false,
exclude_similar: true,
},
});
const data = JSON.parse(result20.content[0].text);
console.log('Result:', result20.content[0].text);
if (data.password.length !== 20) {
throw new Error(`Expected password length 20, got ${data.password.length}`);
}
// Check that similar characters are excluded
if (/[il1Lo0O]/.test(data.password)) {
throw new Error('Password contains excluded similar characters');
}
console.log('β
generate_password (custom): PASSED\n');
} catch (error) {
console.error('β generate_password (custom): FAILED', error);
}
// Test 21: format_bytes - Binary
console.log('π Test 21: format_bytes - Binary');
try {
const result21 = await client.callTool({
name: 'format_bytes',
arguments: {
bytes: 1048576,
format: 'binary',
},
});
const data = JSON.parse(result21.content[0].text);
console.log('Result:', result21.content[0].text);
if (!data.formatted || typeof data.formatted !== 'string') {
throw new Error('Missing or invalid formatted field');
}
if (!data.formatted.includes('MB')) {
throw new Error(`Expected MB in formatted string, got: ${data.formatted}`);
}
if (data.megabytes !== 1) {
throw new Error(`Expected 1 MB, got ${data.megabytes}`);
}
console.log('β
format_bytes (binary): PASSED\n');
} catch (error) {
console.error('β format_bytes (binary): FAILED', error);
}
// Test 22: format_bytes - Decimal
console.log('π Test 22: format_bytes - Decimal');
try {
const result22 = await client.callTool({
name: 'format_bytes',
arguments: {
bytes: 1000000,
format: 'decimal',
precision: 1,
},
});
const data = JSON.parse(result22.content[0].text);
console.log('Result:', result22.content[0].text);
if (!data.formatted_decimal || typeof data.formatted_decimal !== 'string') {
throw new Error('Missing or invalid formatted_decimal field');
}
console.log('β
format_bytes (decimal): PASSED\n');
} catch (error) {
console.error('β format_bytes (decimal): FAILED', error);
}
// Test 23: format_number - Currency
console.log('π° Test 23: format_number - Currency');
try {
const result23 = await client.callTool({
name: 'format_number',
arguments: {
number: 1234.56,
format: 'currency',
currency: 'USD',
},
});
const data = JSON.parse(result23.content[0].text);
console.log('Result:', result23.content[0].text);
if (!data.formatted || typeof data.formatted !== 'string') {
throw new Error('Missing or invalid formatted field');
}
if (!data.formatted.includes('$')) {
throw new Error('Currency format should include $ symbol');
}
console.log('β
format_number (currency): PASSED\n');
} catch (error) {
console.error('β format_number (currency): FAILED', error);
}
// Test 24: format_number - Percentage
console.log('π Test 24: format_number - Percentage');
try {
const result24 = await client.callTool({
name: 'format_number',
arguments: {
number: 75.5,
format: 'percentage',
},
});
const data = JSON.parse(result24.content[0].text);
console.log('Result:', result24.content[0].text);
if (!data.formatted || typeof data.formatted !== 'string') {
throw new Error('Missing or invalid formatted field');
}
if (!data.formatted.includes('%')) {
throw new Error('Percentage format should include % symbol');
}
console.log('β
format_number (percentage): PASSED\n');
} catch (error) {
console.error('β format_number (percentage): FAILED', error);
}
// Test 25: convert_color - Hex to RGB
console.log('π¨ Test 25: convert_color - Hex to RGB');
try {
const result25 = await client.callTool({
name: 'convert_color',
arguments: {
input: '#FF5733',
from: 'hex',
to: 'rgb',
},
});
const data = JSON.parse(result25.content[0].text);
console.log('Result:', result25.content[0].text);
if (!data.hex || !data.rgb || !data.hsl) {
throw new Error('Missing color format fields');
}
if (!data.rgb_array || !Array.isArray(data.rgb_array) || data.rgb_array.length !== 3) {
throw new Error('Invalid rgb_array format');
}
// Verify RGB values for #FF5733 (255, 87, 51)
if (data.rgb_array[0] !== 255 || data.rgb_array[1] !== 87 || data.rgb_array[2] !== 51) {
throw new Error(`Expected RGB [255, 87, 51], got [${data.rgb_array.join(', ')}]`);
}
console.log('β
convert_color (hex to rgb): PASSED\n');
} catch (error) {
console.error('β convert_color (hex to rgb): FAILED', error);
}
// Test 26: convert_timezone
console.log('π Test 26: convert_timezone');
try {
const result26 = await client.callTool({
name: 'convert_timezone',
arguments: {
datetime: '2025-12-06T12:00:00Z',
from_timezone: 'UTC',
to_timezone: 'America/New_York',
},
});
const data = JSON.parse(result26.content[0].text);
console.log('Result:', result26.content[0].text);
if (!data.converted_datetime || typeof data.converted_datetime !== 'string') {
throw new Error('Missing or invalid converted_datetime field');
}
if (!data.iso_string || typeof data.iso_string !== 'string') {
throw new Error('Missing or invalid iso_string field');
}
if (typeof data.unix_timestamp !== 'number') {
throw new Error('Missing or invalid unix_timestamp field');
}
console.log('β
convert_timezone: PASSED\n');
} catch (error) {
console.error('β convert_timezone: FAILED', error);
}
// Test 27: analyze_logs - Check for errors and warnings
console.log('π Test 27: analyze_logs - Error and warning detection');
try {
const testLog = `
npm ERR! code EACCES
npm ERR! permission denied, mkdir '/usr/local/lib/node_modules'
npm WARN deprecated package@1.0.0
error TS2304: Cannot find name 'undefined'.
docker: error response from daemon
WARNING: This is a warning message
[ERROR] Something went wrong
build failed
`;
const result27 = await client.callTool({
name: 'analyze_logs',
arguments: {
text: testLog,
},
});
const data = JSON.parse(result27.content[0].text);
console.log('Result:', result27.content[0].text);
if (typeof data.error_count !== 'number' || data.error_count < 0) {
throw new Error('Missing or invalid error_count field');
}
if (typeof data.warning_count !== 'number' || data.warning_count < 0) {
throw new Error('Missing or invalid warning_count field');
}
if (!Array.isArray(data.errors)) {
throw new Error('Missing or invalid errors array');
}
if (!Array.isArray(data.warnings)) {
throw new Error('Missing or invalid warnings array');
}
if (data.error_count === 0) {
throw new Error('Expected to find at least one error in test log');
}
if (data.warning_count === 0) {
throw new Error('Expected to find at least one warning in test log');
}
console.log(`β
analyze_logs: PASSED (found ${data.error_count} errors, ${data.warning_count} warnings)\n`);
} catch (error) {
console.error('β analyze_logs: FAILED', error);
}
// Test 28: analyze_logs - Empty text
console.log('π Test 28: analyze_logs - Empty text');
try {
const result28 = await client.callTool({
name: 'analyze_logs',
arguments: {
text: '',
},
});
const data = JSON.parse(result28.content[0].text);
if (data.error_count !== 0 || data.warning_count !== 0) {
throw new Error('Empty text should return zero counts');
}
console.log('β
analyze_logs (empty): PASSED\n');
} catch (error) {
console.error('β analyze_logs (empty): FAILED', error);
}
// Test 29: analyze_logs - Real compilation error example
console.log('π Test 29: analyze_logs - Real compilation error');
try {
const realErrorLog = `
src/index.ts:45:12 - error TS2304: Cannot find name 'undefined'.
45 const x = undefined;
~~~~~~~~
npm ERR! code EACCES
npm ERR! permission denied
docker build failed
`;
const result29 = await client.callTool({
name: 'analyze_logs',
arguments: {
text: realErrorLog,
},
});
const data = JSON.parse(result29.content[0].text);
console.log(`Found ${data.error_count} errors, ${data.warning_count} warnings`);
if (data.errors.length > 0) {
console.log('Sample error:', data.errors[0]);
}
if (data.error_count === 0) {
throw new Error('Expected to find errors in compilation log');
}
console.log('β
analyze_logs (real error): PASSED\n');
} catch (error) {
console.error('β analyze_logs (real error): FAILED', error);
}
// Test 30: analyze_language - English text
console.log('π Test 30: analyze_language - English text');
try {
const englishText = 'Hello World! This is a test. 123';
const result30 = await client.callTool({
name: 'analyze_language',
arguments: {
text: englishText,
},
});
const data = JSON.parse(result30.content[0].text);
console.log('Result:', JSON.stringify(data, null, 2));
if (typeof data.total_characters !== 'number') {
throw new Error('Missing or invalid total_characters field');
}
if (!data.languages || typeof data.languages.english !== 'object') {
throw new Error('Missing or invalid languages.english field');
}
if (typeof data.languages.english.count !== 'number' || typeof data.languages.english.percentage !== 'number') {
throw new Error('Missing or invalid languages.english count/percentage');
}
if (!data.categories || typeof data.categories.digits !== 'object') {
throw new Error('Missing or invalid categories.digits field');
}
if (data.languages.english.count === 0) {
throw new Error('Expected to find English characters in test text');
}
console.log(`β
analyze_language (English): PASSED (${data.total_characters} chars, ${data.languages.english.percentage}% English)\n`);
} catch (error) {
console.error('β analyze_language (English): FAILED', error);
}
// Test 31: analyze_language - Mixed languages
console.log('π Test 31: analyze_language - Mixed languages');
try {
const mixedText = 'Hello δ½ ε₯½ ΠΡΠΈΠ²Π΅Ρ γγγ«γ‘γ― 123!';
const result31 = await client.callTool({
name: 'analyze_language',
arguments: {
text: mixedText,
},
});
const data = JSON.parse(result31.content[0].text);
console.log(`Total: ${data.total_characters}, English: ${data.languages.english.percentage}%, Chinese: ${data.languages.chinese.percentage}%, Russian: ${data.languages.russian.percentage}%, Japanese: ${data.languages.japanese.percentage}%`);
if (data.total_characters === 0) {
throw new Error('Expected to find characters in mixed text');
}
console.log('β
analyze_language (Mixed): PASSED\n');
} catch (error) {
console.error('β analyze_language (Mixed): FAILED', error);
}
// Test 32: analyze_language - Empty text
console.log('π Test 32: analyze_language - Empty text');
try {
const result32 = await client.callTool({
name: 'analyze_language',
arguments: {
text: '',
},
});
const data = JSON.parse(result32.content[0].text);
if (data.total_characters !== 0) {
throw new Error('Empty text should return zero total_characters');
}
if (data.languages.english.count !== 0 || data.categories.digits.count !== 0) {
throw new Error('Empty text should return zero counts');
}
console.log('β
analyze_language (empty): PASSED\n');
} catch (error) {
console.error('β analyze_language (empty): FAILED', error);
}
// List all tools
console.log('π Listing all available tools:');
const tools = await client.listTools();
console.log('Available tools:', tools.tools.map(t => `- ${t.name}: ${t.description}`).join('\n'));
console.log('');
await client.close();
console.log('β
All tests completed!');
process.exit(0);
} catch (error) {
console.error('β Test failed:', error);
await client.close();
process.exit(1);
}
}
testMCP().catch(console.error);