@aurracloud/mcp-cli
Version:
A command-line tool to install, manage, and setup MCP (Model Context Protocol) servers with Docker support
296 lines • 9.87 kB
JavaScript
;
/**
* MCP Server Configuration Parser
*
* Parses and normalizes MCP server configurations from package.json files.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseMcpServerConfig = parseMcpServerConfig;
exports.extractEnvironmentVariables = extractEnvironmentVariables;
exports.extractCommandLineArguments = extractCommandLineArguments;
exports.extractConfigurationFiles = extractConfigurationFiles;
exports.generateStartCommand = generateStartCommand;
exports.requiresEnvironmentSetup = requiresEnvironmentSetup;
exports.requiresFileSetup = requiresFileSetup;
exports.getSensitiveItems = getSensitiveItems;
exports.createConfigSummary = createConfigSummary;
exports.validateConfigurationValues = validateConfigurationValues;
const validator_1 = require("./validator");
/**
* Resolves default values for configuration items
*/
function resolveConfigDefaults(section) {
return {
required: section?.required || {},
optional: section?.optional || {}
};
}
/**
* Resolves default values for file configuration
*/
function resolveFileDefaults(section) {
return {
required: section?.required || {},
optional: section?.optional || {}
};
}
/**
* Normalizes author field from package.json
*/
function normalizeAuthor(author) {
if (!author)
return undefined;
if (typeof author === 'string')
return author;
let result = author.name;
if (author.email)
result += ` <${author.email}>`;
if (author.url)
result += ` (${author.url})`;
return result;
}
/**
* Normalizes repository field from package.json
*/
function normalizeRepository(repository) {
if (!repository)
return undefined;
if (typeof repository === 'string')
return repository;
return repository.url;
}
/**
* Parses MCP server configuration from package.json
*/
function parseMcpServerConfig(packageJson, options = (0, validator_1.createDefaultParseOptions)()) {
// Validate first
const validation = (0, validator_1.validatePackageJsonWithMcp)(packageJson, options);
if (!validation.valid && options.strict) {
return { config: null, validation };
}
// Extract and normalize package metadata
const name = packageJson.name;
const version = packageJson.version;
const description = packageJson.mcpServer?.description || packageJson.description || '';
const author = normalizeAuthor(packageJson.author);
const license = packageJson.license;
const repository = normalizeRepository(packageJson.repository);
const homepage = packageJson.homepage;
const keywords = packageJson.keywords || [];
// Parse MCP server configuration
const mcpConfig = packageJson.mcpServer;
// Connection configuration with defaults
const connection = {
type: mcpConfig.connection.type,
command: mcpConfig.connection.command,
args: mcpConfig.connection.args || [],
url: mcpConfig.connection.url,
timeout: mcpConfig.connection.timeout || 30000,
headers: mcpConfig.connection.headers || {}
};
// Environment configuration
const environment = resolveConfigDefaults(mcpConfig.config?.environment);
// Arguments configuration
const args = resolveConfigDefaults(mcpConfig.config?.arguments);
// Files configuration
const files = resolveFileDefaults(mcpConfig.config?.files);
// Capabilities with defaults
const capabilities = {
tools: mcpConfig.capabilities?.tools || false,
resources: mcpConfig.capabilities?.resources || false,
prompts: mcpConfig.capabilities?.prompts || false
};
// Metadata with defaults
const metadata = {
keywords: mcpConfig.metadata?.keywords || keywords,
category: mcpConfig.metadata?.category,
requires_extras: mcpConfig.metadata?.requires_extras || []
};
const config = {
name,
version,
description,
author,
license,
repository,
homepage,
keywords,
connection,
environment,
arguments: args,
files,
capabilities,
metadata
};
return { config, validation };
}
/**
* Extracts environment variable names from configuration
*/
function extractEnvironmentVariables(config) {
const required = Object.keys(config.environment.required);
const optional = Object.keys(config.environment.optional);
const sensitive = [];
// Check required environment variables for sensitive flag
Object.entries(config.environment.required).forEach(([key, item]) => {
if (item.sensitive) {
sensitive.push(key);
}
});
// Check optional environment variables for sensitive flag
Object.entries(config.environment.optional).forEach(([key, item]) => {
if (item.sensitive) {
sensitive.push(key);
}
});
return { required, optional, sensitive };
}
/**
* Extracts command line arguments from configuration
*/
function extractCommandLineArguments(config) {
const required = Object.entries(config.arguments.required).map(([name, item]) => ({
name,
aliases: item.alias || [],
description: item.description
}));
const optional = Object.entries(config.arguments.optional).map(([name, item]) => ({
name,
aliases: item.alias || [],
description: item.description,
default: item.default
}));
return { required, optional };
}
/**
* Extracts configuration files from configuration
*/
function extractConfigurationFiles(config) {
const required = Object.entries(config.files.required).map(([name, file]) => ({
name,
path: file.path,
description: file.description,
format: file.format,
sensitive: file.sensitive || false
}));
const optional = Object.entries(config.files.optional).map(([name, file]) => ({
name,
path: file.path,
description: file.description,
format: file.format,
sensitive: file.sensitive || false,
default: file.default
}));
return { required, optional };
}
/**
* Generates command line for starting the MCP server
*/
function generateStartCommand(config) {
const { connection } = config;
if (connection.type === 'stdio') {
const command = connection.command || 'node';
const args = connection.args || [];
return `${command} ${args.join(' ')}`.trim();
}
else if (connection.type === 'http' || connection.type === 'sse') {
return `curl ${connection.url}`;
}
return '';
}
/**
* Checks if the configuration requires environment setup
*/
function requiresEnvironmentSetup(config) {
return Object.keys(config.environment.required).length > 0 ||
Object.keys(config.environment.optional).length > 0;
}
/**
* Checks if the configuration requires file setup
*/
function requiresFileSetup(config) {
return Object.keys(config.files.required).length > 0 ||
Object.keys(config.files.optional).length > 0;
}
/**
* Gets all sensitive configuration items
*/
function getSensitiveItems(config) {
const environment = [];
const files = [];
// Check environment variables
Object.entries(config.environment.required).forEach(([key, item]) => {
if (item.sensitive)
environment.push(key);
});
Object.entries(config.environment.optional).forEach(([key, item]) => {
if (item.sensitive)
environment.push(key);
});
// Check files
Object.entries(config.files.required).forEach(([key, file]) => {
if (file.sensitive)
files.push(key);
});
Object.entries(config.files.optional).forEach(([key, file]) => {
if (file.sensitive)
files.push(key);
});
return { environment, files };
}
/**
* Creates a summary of the MCP server configuration
*/
function createConfigSummary(config) {
const capabilities = [];
if (config.capabilities.tools)
capabilities.push('tools');
if (config.capabilities.resources)
capabilities.push('resources');
if (config.capabilities.prompts)
capabilities.push('prompts');
const sensitiveItems = getSensitiveItems(config);
const hasSensitiveData = sensitiveItems.environment.length > 0 || sensitiveItems.files.length > 0;
return {
name: config.name,
version: config.version,
description: config.description,
connectionType: config.connection.type,
capabilities,
category: config.metadata.category,
requiresSetup: requiresEnvironmentSetup(config) || requiresFileSetup(config),
hasSensitiveData
};
}
/**
* Validates configuration values against their schemas
*/
function validateConfigurationValues(config, values) {
const errors = [];
const warnings = [];
// Validate environment variable values
Object.entries(values).forEach(([key, value]) => {
const requiredConfig = config.environment.required[key];
const optionalConfig = config.environment.optional[key];
const configItem = requiredConfig || optionalConfig;
if (configItem) {
// Type validation
const expectedType = configItem.type;
const actualType = Array.isArray(value) ? 'array' : typeof value;
if (actualType !== expectedType) {
errors.push({
path: key,
message: `Expected type '${expectedType}' but got '${actualType}'`,
value
});
}
// Additional validations would go here (pattern, range, etc.)
}
});
return {
valid: errors.length === 0,
errors,
warnings
};
}
//# sourceMappingURL=parser.js.map