/**
* MCP Server Tests v2.0.0
*
* Tests for the consolidated MCP tool layer.
* CoolifyClient methods are fully tested in coolify-client.test.ts (174 tests).
* These tests verify MCP server instantiation and structure.
*/
import { describe, it, expect, beforeEach } from '@jest/globals';
import { CoolifyMcpServer, truncateLogs } from '../lib/mcp-server.js';
describe('CoolifyMcpServer v2', () => {
let server: CoolifyMcpServer;
beforeEach(() => {
server = new CoolifyMcpServer({
baseUrl: 'http://localhost:3000',
accessToken: 'test-token',
});
});
describe('constructor', () => {
it('should create server instance', () => {
expect(server).toBeInstanceOf(CoolifyMcpServer);
});
it('should be an MCP server with connect method', () => {
expect(typeof server.connect).toBe('function');
});
});
describe('client', () => {
it('should have client instance', () => {
const client = server['client'];
expect(client).toBeDefined();
});
it('should have all required client methods', () => {
const client = server['client'];
// Core methods
expect(typeof client.getVersion).toBe('function');
// Server operations
expect(typeof client.listServers).toBe('function');
expect(typeof client.getServer).toBe('function');
expect(typeof client.getServerResources).toBe('function');
expect(typeof client.getServerDomains).toBe('function');
expect(typeof client.validateServer).toBe('function');
// Project operations
expect(typeof client.listProjects).toBe('function');
expect(typeof client.getProject).toBe('function');
expect(typeof client.createProject).toBe('function');
expect(typeof client.updateProject).toBe('function');
expect(typeof client.deleteProject).toBe('function');
// Environment operations
expect(typeof client.listProjectEnvironments).toBe('function');
expect(typeof client.getProjectEnvironment).toBe('function');
expect(typeof client.createProjectEnvironment).toBe('function');
expect(typeof client.deleteProjectEnvironment).toBe('function');
// Application operations
expect(typeof client.listApplications).toBe('function');
expect(typeof client.getApplication).toBe('function');
expect(typeof client.createApplicationPublic).toBe('function');
expect(typeof client.createApplicationPrivateGH).toBe('function');
expect(typeof client.createApplicationPrivateKey).toBe('function');
expect(typeof client.createApplicationDockerImage).toBe('function');
expect(typeof client.updateApplication).toBe('function');
expect(typeof client.deleteApplication).toBe('function');
expect(typeof client.getApplicationLogs).toBe('function');
// Control operations
expect(typeof client.startApplication).toBe('function');
expect(typeof client.stopApplication).toBe('function');
expect(typeof client.restartApplication).toBe('function');
expect(typeof client.startDatabase).toBe('function');
expect(typeof client.stopDatabase).toBe('function');
expect(typeof client.restartDatabase).toBe('function');
expect(typeof client.startService).toBe('function');
expect(typeof client.stopService).toBe('function');
expect(typeof client.restartService).toBe('function');
// Database operations
expect(typeof client.listDatabases).toBe('function');
expect(typeof client.getDatabase).toBe('function');
expect(typeof client.deleteDatabase).toBe('function');
expect(typeof client.createPostgresql).toBe('function');
expect(typeof client.createMysql).toBe('function');
expect(typeof client.createMariadb).toBe('function');
expect(typeof client.createMongodb).toBe('function');
expect(typeof client.createRedis).toBe('function');
expect(typeof client.createKeydb).toBe('function');
expect(typeof client.createClickhouse).toBe('function');
expect(typeof client.createDragonfly).toBe('function');
// Service operations
expect(typeof client.listServices).toBe('function');
expect(typeof client.getService).toBe('function');
expect(typeof client.createService).toBe('function');
expect(typeof client.updateService).toBe('function');
expect(typeof client.deleteService).toBe('function');
// Environment variable operations
expect(typeof client.listApplicationEnvVars).toBe('function');
expect(typeof client.createApplicationEnvVar).toBe('function');
expect(typeof client.updateApplicationEnvVar).toBe('function');
expect(typeof client.deleteApplicationEnvVar).toBe('function');
expect(typeof client.listServiceEnvVars).toBe('function');
expect(typeof client.createServiceEnvVar).toBe('function');
expect(typeof client.deleteServiceEnvVar).toBe('function');
// Deployment operations
expect(typeof client.listDeployments).toBe('function');
expect(typeof client.getDeployment).toBe('function');
expect(typeof client.deployByTagOrUuid).toBe('function');
expect(typeof client.listApplicationDeployments).toBe('function');
expect(typeof client.cancelDeployment).toBe('function');
// Private key operations
expect(typeof client.listPrivateKeys).toBe('function');
expect(typeof client.getPrivateKey).toBe('function');
expect(typeof client.createPrivateKey).toBe('function');
expect(typeof client.updatePrivateKey).toBe('function');
expect(typeof client.deletePrivateKey).toBe('function');
// GitHub App operations
expect(typeof client.listGitHubApps).toBe('function');
expect(typeof client.createGitHubApp).toBe('function');
expect(typeof client.updateGitHubApp).toBe('function');
expect(typeof client.deleteGitHubApp).toBe('function');
// Backup operations
expect(typeof client.listDatabaseBackups).toBe('function');
expect(typeof client.getDatabaseBackup).toBe('function');
expect(typeof client.createDatabaseBackup).toBe('function');
expect(typeof client.updateDatabaseBackup).toBe('function');
expect(typeof client.deleteDatabaseBackup).toBe('function');
expect(typeof client.listBackupExecutions).toBe('function');
expect(typeof client.getBackupExecution).toBe('function');
// Diagnostic operations
expect(typeof client.diagnoseApplication).toBe('function');
expect(typeof client.diagnoseServer).toBe('function');
expect(typeof client.findInfrastructureIssues).toBe('function');
// Batch operations
expect(typeof client.restartProjectApps).toBe('function');
expect(typeof client.bulkEnvUpdate).toBe('function');
expect(typeof client.stopAllApps).toBe('function');
expect(typeof client.redeployProjectApps).toBe('function');
});
});
describe('server configuration', () => {
it('should store baseUrl and accessToken in client', () => {
const client = server['client'];
// CoolifyClient stores base URL without /api/v1 suffix
expect(client['baseUrl']).toBe('http://localhost:3000');
expect(client['accessToken']).toBe('test-token');
});
});
});
describe('truncateLogs', () => {
it('should return logs unchanged when within limits', () => {
const logs = 'line1\nline2\nline3';
const result = truncateLogs(logs, 200, 50000);
expect(result).toBe(logs);
});
it('should truncate to last N lines', () => {
const logs = 'line1\nline2\nline3\nline4\nline5';
const result = truncateLogs(logs, 3, 50000);
expect(result).toBe('line3\nline4\nline5');
});
it('should truncate by character limit when lines are huge', () => {
const hugeLine = 'x'.repeat(100);
const logs = `${hugeLine}\n${hugeLine}\n${hugeLine}`;
const result = truncateLogs(logs, 200, 50);
expect(result.length).toBeLessThanOrEqual(50);
expect(result.startsWith('...[truncated]...')).toBe(true);
});
it('should not add truncation prefix when under char limit', () => {
const logs = 'line1\nline2\nline3';
const result = truncateLogs(logs, 200, 50000);
expect(result.startsWith('...[truncated]...')).toBe(false);
});
it('should handle empty logs', () => {
const result = truncateLogs('', 200, 50000);
expect(result).toBe('');
});
it('should use default limits when not specified', () => {
const logs = 'line1\nline2';
const result = truncateLogs(logs);
expect(result).toBe(logs);
});
it('should respect custom line limit', () => {
const lines = Array.from({ length: 300 }, (_, i) => `line${i + 1}`).join('\n');
const result = truncateLogs(lines, 50, 50000);
const resultLines = result.split('\n');
expect(resultLines.length).toBe(50);
expect(resultLines[0]).toBe('line251');
expect(resultLines[49]).toBe('line300');
});
it('should respect custom char limit', () => {
const logs = 'x'.repeat(1000);
const result = truncateLogs(logs, 200, 100);
expect(result.length).toBe(100);
});
});