/**
* 应用程序配置文件
* 管理各种配置选项和环境变量
*/
import dotenv from 'dotenv';
import path from 'path';
import { fileURLToPath } from 'url';
import os from 'os';
dotenv.config();
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
class Config {
constructor() {
this.env = process.env.NODE_ENV || 'development';
this.loadConfig();
}
/**
* 加载配置
*/
loadConfig() {
// 服务器配置
this.server = {
name: process.env.SERVER_NAME || 'yijing-bazi-mcp-server',
version: process.env.SERVER_VERSION || '1.0.0',
port: parseInt(process.env.PORT) || 3000,
host: process.env.HOST || 'localhost',
timeout: parseInt(process.env.TIMEOUT) || 30000,
maxRequestSize: process.env.MAX_REQUEST_SIZE || '10mb'
};
// MCP配置
this.mcp = {
protocol: {
version: '2024-11-05',
capabilities: {
tools: {},
logging: {},
prompts: {},
resources: {}
}
},
transport: {
type: process.env.MCP_TRANSPORT || 'stdio',
options: {}
}
};
// 日志配置
this.logging = {
level: process.env.LOG_LEVEL || 'info',
dir: process.env.LOG_DIR || path.join(process.cwd(), 'logs'),
maxFiles: parseInt(process.env.LOG_MAX_FILES) || 5,
maxSize: process.env.LOG_MAX_SIZE || '10m',
console: process.env.LOG_CONSOLE !== 'false',
file: process.env.LOG_FILE !== 'false'
};
// 易经配置
this.yijing = {
// 占卜方法配置
divination: {
defaultMethod: process.env.YIJING_DEFAULT_METHOD || 'coin',
methods: {
coin: {
enabled: true,
description: '铜钱占卜法',
accuracy: 'high'
},
yarrow: {
enabled: true,
description: '蓍草占卜法',
accuracy: 'highest'
},
number: {
enabled: true,
description: '数字占卜法',
accuracy: 'medium'
},
time: {
enabled: true,
description: '时间占卜法',
accuracy: 'medium'
}
}
},
// 解释配置
interpretation: {
includeChangedLines: true,
includeRelatedHexagrams: true,
includeSeasonalInfluence: true,
includeElementalAnalysis: true,
maxInterpretationLength: 2000
},
// 建议配置
advice: {
includeActionItems: true,
includeTimingGuidance: true,
includeWarnings: true,
maxAdviceLength: 1500
}
};
// 八字配置
this.bazi = {
// 计算配置
calculation: {
defaultTimezone: process.env.BAZI_DEFAULT_TIMEZONE || 'Asia/Shanghai',
includeMajorLuck: true,
includeAnnualLuck: true,
includeMonthlyLuck: true,
majorLuckPeriods: 8,
forecastYears: 10
},
// 分析配置
analysis: {
includePersonality: true,
includeCareer: true,
includeWealth: true,
includeRelationship: true,
includeHealth: true,
includeSpirits: true,
includePatterns: true,
maxAnalysisLength: 3000
},
// 预测配置
forecast: {
defaultPeriod: 'yearly',
includeMonthlyDetails: true,
includeAdvice: true,
includeWarnings: true,
maxForecastLength: 2500
}
};
// 综合分析配置
this.combined = {
// 分析权重
weights: {
bazi: 0.6,
yijing: 0.4
},
// 分析深度
depth: {
personality: 'comprehensive',
career: 'detailed',
relationship: 'detailed',
health: 'basic',
wealth: 'detailed'
},
// 输出配置
output: {
includeMethodology: true,
includeConfidenceLevel: true,
includeLimitations: true,
maxCombinedLength: 4000
}
};
// 知识库配置
this.knowledge = {
// 学习配置
learning: {
supportedTopics: [
'yijing_basics',
'hexagram_interpretation',
'bazi_basics',
'ten_gods',
'five_elements',
'spirits',
'patterns',
'forecasting'
],
supportedLevels: ['beginner', 'intermediate', 'advanced'],
supportedStyles: ['theoretical', 'practical', 'case_study', 'interactive'],
maxContentLength: 5000
},
// 案例研究配置
caseStudy: {
maxCases: 100,
includeComparison: true,
includeAnalysis: true,
includeLessons: true,
maxCaseLength: 3000
}
};
// 安全配置
this.security = {
// 输入验证
validation: {
maxInputLength: 10000,
allowedCharacters: /^[\u4e00-\u9fa5\w\s\-_.,!?()\[\]{}:;"']+$/,
sanitizeInput: true,
preventXSS: true
},
// 速率限制
rateLimit: {
enabled: process.env.RATE_LIMIT_ENABLED !== 'false',
windowMs: parseInt(process.env.RATE_LIMIT_WINDOW) || 60000, // 1分钟
maxRequests: parseInt(process.env.RATE_LIMIT_MAX) || 100,
skipSuccessfulRequests: false
},
// CORS配置
cors: {
enabled: process.env.CORS_ENABLED !== 'false',
origin: process.env.CORS_ORIGIN || '*',
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
allowedHeaders: ['Content-Type', 'Authorization']
}
};
// 性能配置
this.performance = {
// 缓存配置
cache: {
enabled: process.env.CACHE_ENABLED !== 'false',
ttl: parseInt(process.env.CACHE_TTL) || 3600, // 1小时
maxSize: parseInt(process.env.CACHE_MAX_SIZE) || 1000,
checkPeriod: parseInt(process.env.CACHE_CHECK_PERIOD) || 600 // 10分钟
},
// 并发配置
concurrency: {
maxConcurrentRequests: parseInt(process.env.MAX_CONCURRENT_REQUESTS) || 10,
queueTimeout: parseInt(process.env.QUEUE_TIMEOUT) || 30000,
retryAttempts: parseInt(process.env.RETRY_ATTEMPTS) || 3,
retryDelay: parseInt(process.env.RETRY_DELAY) || 1000
},
// 监控配置
monitoring: {
enabled: process.env.MONITORING_ENABLED !== 'false',
metricsInterval: parseInt(process.env.METRICS_INTERVAL) || 60000,
healthCheckInterval: parseInt(process.env.HEALTH_CHECK_INTERVAL) || 30000
}
};
// 数据库配置(如果需要)
this.database = {
// 文件存储配置
fileStorage: {
enabled: process.env.FILE_STORAGE_ENABLED !== 'false',
dataDir: process.env.DATA_DIR || path.join(process.cwd(), 'data'),
backupDir: process.env.BACKUP_DIR || path.join(process.cwd(), 'backups'),
autoBackup: process.env.AUTO_BACKUP !== 'false',
backupInterval: parseInt(process.env.BACKUP_INTERVAL) || 86400000 // 24小时
}
};
// 开发配置
this.development = {
debug: process.env.DEBUG === 'true',
verbose: process.env.VERBOSE === 'true',
mockData: process.env.MOCK_DATA === 'true',
hotReload: process.env.HOT_RELOAD !== 'false',
profiling: process.env.PROFILING === 'true'
};
// 生产配置
this.production = {
compression: process.env.COMPRESSION !== 'false',
clustering: process.env.CLUSTERING === 'true',
workers: parseInt(process.env.WORKERS) || os.cpus().length,
gracefulShutdown: process.env.GRACEFUL_SHUTDOWN !== 'false',
shutdownTimeout: parseInt(process.env.SHUTDOWN_TIMEOUT) || 10000
};
}
/**
* 获取环境特定配置
* @param {string} key - 配置键
* @returns {*} 配置值
*/
get(key) {
const keys = key.split('.');
let value = this;
for (const k of keys) {
if (value && typeof value === 'object' && k in value) {
value = value[k];
} else {
return undefined;
}
}
return value;
}
/**
* 设置配置值
* @param {string} key - 配置键
* @param {*} value - 配置值
*/
set(key, value) {
const keys = key.split('.');
let target = this;
for (let i = 0; i < keys.length - 1; i++) {
const k = keys[i];
if (!(k in target) || typeof target[k] !== 'object') {
target[k] = {};
}
target = target[k];
}
target[keys[keys.length - 1]] = value;
}
/**
* 检查是否为开发环境
* @returns {boolean}
*/
isDevelopment() {
return this.env === 'development';
}
/**
* 检查是否为生产环境
* @returns {boolean}
*/
isProduction() {
return this.env === 'production';
}
/**
* 检查是否为测试环境
* @returns {boolean}
*/
isTest() {
return this.env === 'test';
}
/**
* 获取完整配置对象
* @returns {Object} 配置对象
*/
getAll() {
return {
env: this.env,
server: this.server,
mcp: this.mcp,
logging: this.logging,
yijing: this.yijing,
bazi: this.bazi,
combined: this.combined,
knowledge: this.knowledge,
security: this.security,
performance: this.performance,
database: this.database,
development: this.development,
production: this.production
};
}
/**
* 验证配置
* @returns {Object} 验证结果
*/
validate() {
const errors = [];
const warnings = [];
// 验证必需配置
if (!this.server.name) {
errors.push('服务器名称未配置');
}
if (!this.server.port || this.server.port < 1 || this.server.port > 65535) {
errors.push('无效的服务器端口');
}
if (!this.logging.dir) {
errors.push('日志目录未配置');
}
// 验证易经配置
if (!this.yijing.divination.defaultMethod) {
warnings.push('未设置默认占卜方法');
}
// 验证八字配置
if (!this.bazi.calculation.defaultTimezone) {
warnings.push('未设置默认时区');
}
// 验证安全配置
if (this.isProduction() && this.security.cors.origin === '*') {
warnings.push('生产环境建议限制CORS来源');
}
return {
isValid: errors.length === 0,
errors,
warnings
};
}
/**
* 打印配置摘要
*/
printSummary() {
console.log('\n=== 易经八字MCP服务器配置 ===');
console.log(`环境: ${this.env}`);
console.log(`服务器: ${this.server.name} v${this.server.version}`);
console.log(`端口: ${this.server.port}`);
console.log(`日志级别: ${this.logging.level}`);
console.log(`默认时区: ${this.bazi.calculation.defaultTimezone}`);
console.log(`缓存: ${this.performance.cache.enabled ? '启用' : '禁用'}`);
console.log(`速率限制: ${this.security.rateLimit.enabled ? '启用' : '禁用'}`);
console.log('==============================\n');
}
/**
* 导出配置到文件
* @param {string} filePath - 文件路径
*/
async exportToFile(filePath) {
const fs = await import('fs');
const configData = JSON.stringify(this.getAll(), null, 2);
fs.writeFileSync(filePath, configData, 'utf8');
}
/**
* 从文件导入配置
* @param {string} filePath - 文件路径
*/
async importFromFile(filePath) {
const fs = await import('fs');
if (fs.existsSync(filePath)) {
const configData = JSON.parse(fs.readFileSync(filePath, 'utf8'));
Object.assign(this, configData);
}
}
}
// 创建配置实例
const config = new Config();
export default config;
export { Config };