@aurracloud/mcp-cli
Version:
A command-line tool to install, manage, and setup MCP (Model Context Protocol) servers with Docker support
283 lines • 9.8 kB
JavaScript
;
/**
* MCP Server Configuration Utilities
*
* Utility functions for working with MCP server configurations.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.loadMcpConfigFromFile = loadMcpConfigFromFile;
exports.findMcpConfigs = findMcpConfigs;
exports.createMcpConfigTemplate = createMcpConfigTemplate;
exports.validateMcpServerDirectory = validateMcpServerDirectory;
exports.generateEnvSetupInstructions = generateEnvSetupInstructions;
exports.checkEnvironmentCompatibility = checkEnvironmentCompatibility;
exports.formatValidationResults = formatValidationResults;
const fs_1 = require("fs");
const path_1 = require("path");
const parser_1 = require("./parser");
const validator_1 = require("./validator");
/**
* Loads and parses package.json file with MCP server configuration
*/
async function loadMcpConfigFromFile(packageJsonPath, options = (0, validator_1.createDefaultParseOptions)()) {
try {
const content = await fs_1.promises.readFile(packageJsonPath, 'utf-8');
const packageJson = JSON.parse(content);
const result = (0, parser_1.parseMcpServerConfig)(packageJson, options);
return {
...result,
path: packageJsonPath
};
}
catch (error) {
return {
config: null,
validation: {
valid: false,
errors: [{
path: packageJsonPath,
message: `Failed to load or parse package.json: ${error instanceof Error ? error.message : 'Unknown error'}`
}],
warnings: []
},
path: packageJsonPath
};
}
}
/**
* Finds package.json files with MCP server configurations in a directory
*/
async function findMcpConfigs(searchPath, recursive = false) {
const results = [];
try {
const entries = await fs_1.promises.readdir(searchPath, { withFileTypes: true });
for (const entry of entries) {
const fullPath = (0, path_1.join)(searchPath, entry.name);
if (entry.isFile() && entry.name === 'package.json') {
try {
const content = await fs_1.promises.readFile(fullPath, 'utf-8');
const packageJson = JSON.parse(content);
if (packageJson.mcpServer) {
results.push(fullPath);
}
}
catch {
// Ignore invalid JSON files
}
}
else if (entry.isDirectory() && recursive && !entry.name.startsWith('.')) {
const subResults = await findMcpConfigs(fullPath, recursive);
results.push(...subResults);
}
}
}
catch {
// Ignore directories that can't be read
}
return results;
}
/**
* Creates a template package.json with MCP server configuration
*/
function createMcpConfigTemplate(options) {
const { name, version = '1.0.0', description = '', author = '', license = 'ISC', connectionType = 'stdio', command = 'node', args = ['dist/index.js'], url } = options;
const connection = {
type: connectionType,
timeout: 30000
};
if (connectionType === 'stdio') {
connection.command = command;
connection.args = args;
}
else {
connection.url = url || 'http://localhost:3000';
}
return {
name,
version,
description,
author,
license,
main: 'dist/index.js',
scripts: {
build: 'tsc',
start: 'node dist/index.js'
},
mcpServer: {
description: description || `MCP server: ${name}`,
connection,
config: {
$schema: 'https://schemas.aurracloud.com/server-config-v1.json',
environment: {
optional: {
DEBUG: {
type: 'boolean',
description: 'Enable debug logging',
default: false
}
}
}
},
capabilities: {
tools: false,
resources: false,
prompts: false
},
metadata: {
keywords: ['mcp', 'server'],
category: 'utility'
}
}
};
}
/**
* Validates that a directory contains a valid MCP server configuration
*/
async function validateMcpServerDirectory(directoryPath) {
const errors = [];
const packageJsonPath = (0, path_1.join)(directoryPath, 'package.json');
try {
// Check if package.json exists
await fs_1.promises.access(packageJsonPath);
}
catch {
errors.push('package.json not found');
return { valid: false, errors };
}
// Load and validate the configuration
const result = await loadMcpConfigFromFile(packageJsonPath);
if (!result.validation.valid) {
errors.push(...result.validation.errors.map(err => err.message));
}
return {
valid: result.validation.valid,
packageJsonPath,
config: result.config || undefined,
validation: result.validation,
errors
};
}
/**
* Generates environment variable setup instructions
*/
function generateEnvSetupInstructions(config) {
const required = Object.entries(config.environment.required).map(([name, item]) => ({
name,
description: item.description,
sensitive: item.sensitive || false
}));
const optional = Object.entries(config.environment.optional).map(([name, item]) => ({
name,
description: item.description,
default: item.default,
sensitive: item.sensitive || false
}));
// Generate bash script
const bashLines = ['#!/bin/bash', '# MCP Server Environment Setup', ''];
required.forEach(({ name, description, sensitive }) => {
bashLines.push(`# ${description}`);
if (sensitive) {
bashLines.push(`read -s -p "Enter ${name}: " ${name}`);
bashLines.push('echo');
}
else {
bashLines.push(`read -p "Enter ${name}: " ${name}`);
}
bashLines.push(`export ${name}`);
bashLines.push('');
});
optional.forEach(({ name, description, default: defaultValue }) => {
bashLines.push(`# ${description}`);
if (defaultValue !== undefined) {
bashLines.push(`export ${name}="${defaultValue}"`);
}
else {
bashLines.push(`# export ${name}="your_value_here"`);
}
bashLines.push('');
});
// Generate Windows script
const windowsLines = ['@echo off', 'REM MCP Server Environment Setup', ''];
required.forEach(({ name, description }) => {
windowsLines.push(`REM ${description}`);
windowsLines.push(`set /p ${name}=Enter ${name}: `);
windowsLines.push('');
});
optional.forEach(({ name, description, default: defaultValue }) => {
windowsLines.push(`REM ${description}`);
if (defaultValue !== undefined) {
windowsLines.push(`set ${name}=${defaultValue}`);
}
else {
windowsLines.push(`REM set ${name}=your_value_here`);
}
windowsLines.push('');
});
return {
required,
optional,
bashScript: bashLines.join('\n'),
windowsScript: windowsLines.join('\n')
};
}
/**
* Checks if a configuration is compatible with the current environment
*/
function checkEnvironmentCompatibility(config) {
const issues = [];
const recommendations = [];
// Check Node.js for stdio connections
if (config.connection.type === 'stdio' && config.connection.command === 'node') {
try {
// This would need to be implemented with actual Node.js version checking
recommendations.push('Ensure Node.js is installed and accessible in PATH');
}
catch {
issues.push('Node.js not found in PATH');
}
}
// Check for Python connections
if (config.connection.type === 'stdio' && config.connection.command === 'python') {
recommendations.push('Ensure Python is installed and accessible in PATH');
}
// Check for required files
Object.entries(config.files.required).forEach(([name, file]) => {
recommendations.push(`Ensure required file exists: ${file.path}`);
});
// Check for sensitive data handling
const sensitiveItems = Object.entries(config.environment.required)
.concat(Object.entries(config.environment.optional))
.filter(([, item]) => item.sensitive);
if (sensitiveItems.length > 0) {
recommendations.push('Use secure methods to store sensitive environment variables');
recommendations.push('Consider using .env files or environment variable managers');
}
return {
compatible: issues.length === 0,
issues,
recommendations
};
}
/**
* Formats validation results for display
*/
function formatValidationResults(validation) {
const lines = [];
if (validation.valid) {
lines.push('✅ Configuration is valid');
}
else {
lines.push('❌ Configuration has errors:');
validation.errors.forEach(error => {
lines.push(` • ${error.path}: ${error.message}`);
});
}
if (validation.warnings.length > 0) {
lines.push('⚠️ Warnings:');
validation.warnings.forEach(warning => {
lines.push(` • ${warning.path}: ${warning.message}`);
});
}
return lines.join('\n');
}
//# sourceMappingURL=utils.js.map