UNPKG

@geekmai/anteey-mcp-client

Version:

Anteey MCP 客户端 - 连接外部 AI 工具与 Anteey 笔记应用

248 lines (219 loc) 5.63 kB
#!/usr/bin/env node /** * @file config.js * @description Anteey MCP 客户端配置管理 */ const fs = require('fs-extra') const path = require('path') const os = require('os') const chalk = require('chalk') const inquirer = require('inquirer') // 配置文件路径 const CONFIG_DIR = path.join(os.homedir(), '.anteey-mcp') const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json') // 默认配置 const DEFAULT_CONFIG = { apiKey: '', serverUrl: 'http://localhost:43211/api/mcp', timeout: 30000, retries: 3, logLevel: 'info' } /** * 确保配置目录存在 */ async function ensureConfigDir() { try { await fs.ensureDir(CONFIG_DIR) } catch (error) { console.error(chalk.red('创建配置目录失败:'), error.message) process.exit(1) } } /** * 加载配置 */ async function loadConfig() { try { await ensureConfigDir() if (await fs.pathExists(CONFIG_FILE)) { const configData = await fs.readJson(CONFIG_FILE) return { ...DEFAULT_CONFIG, ...configData } } return DEFAULT_CONFIG } catch (error) { console.error(chalk.red('加载配置失败:'), error.message) return DEFAULT_CONFIG } } /** * 保存配置 */ async function saveConfig(config) { try { await ensureConfigDir() await fs.writeJson(CONFIG_FILE, config, { spaces: 2 }) console.log(chalk.green('配置已保存')) } catch (error) { console.error(chalk.red('保存配置失败:'), error.message) process.exit(1) } } /** * 显示当前配置 */ async function showConfig() { const config = await loadConfig() console.log(chalk.cyan('\n📋 当前配置:')) console.log(chalk.yellow('API 密钥:'), config.apiKey || chalk.gray('(未设置)')) console.log(chalk.yellow('服务器地址:'), config.serverUrl) console.log(chalk.yellow('超时时间:'), `${config.timeout}ms`) console.log(chalk.yellow('重试次数:'), config.retries) console.log(chalk.yellow('日志级别:'), config.logLevel) console.log(chalk.yellow('配置文件位置:'), CONFIG_FILE) console.log('') } /** * 交互式配置 */ async function interactiveConfig() { const config = await loadConfig() console.log(chalk.cyan('\n🛠️ 配置 Anteey MCP 客户端\n')) const questions = [ { type: 'input', name: 'apiKey', message: 'API 密钥:', default: config.apiKey, validate: (input) => { if (!input.trim()) { return '请输入有效的 API 密钥' } if (!input.startsWith('anteey_')) { return 'API 密钥应该以 "anteey_" 开头' } return true } }, { type: 'input', name: 'serverUrl', message: '服务器地址:', default: config.serverUrl, validate: (input) => { try { new URL(input) return true } catch { return '请输入有效的服务器地址 (例如: http://localhost:43211/api/mcp)' } } }, { type: 'number', name: 'timeout', message: '请求超时时间 (毫秒):', default: config.timeout, validate: (input) => input > 0 || '超时时间必须大于 0' }, { type: 'number', name: 'retries', message: '重试次数:', default: config.retries, validate: (input) => input >= 0 || '重试次数不能为负数' }, { type: 'list', name: 'logLevel', message: '日志级别:', choices: ['error', 'warn', 'info', 'debug'], default: config.logLevel } ] const answers = await inquirer.prompt(questions) const newConfig = { ...config, ...answers } await saveConfig(newConfig) console.log(chalk.green('\n✅ 配置完成!')) console.log(chalk.gray('使用 "anteey-mcp test" 测试连接\n')) } /** * 处理配置命令 */ async function handleConfig(options) { try { // 如果只是列出配置 if (options.list) { await showConfig() return } // 如果有命令行参数,直接设置 if (options.apiKey || options.server) { const config = await loadConfig() if (options.apiKey) { if (!options.apiKey.startsWith('anteey_')) { console.error(chalk.red('错误: API 密钥应该以 "anteey_" 开头')) process.exit(1) } config.apiKey = options.apiKey } if (options.server) { try { new URL(options.server) config.serverUrl = options.server } catch { console.error(chalk.red('错误: 无效的服务器地址')) process.exit(1) } } await saveConfig(config) await showConfig() return } // 交互式配置 await interactiveConfig() } catch (error) { console.error(chalk.red('配置时出错:'), error.message) process.exit(1) } } /** * 获取配置 */ function getConfig() { return loadConfig() } /** * 重置配置 */ async function resetConfig() { try { await saveConfig(DEFAULT_CONFIG) console.log(chalk.green('配置已重置为默认值')) } catch (error) { console.error(chalk.red('重置配置失败:'), error.message) process.exit(1) } } // 如果直接运行此文件 if (require.main === module) { const args = process.argv.slice(2) if (args.includes('--list') || args.includes('-l')) { showConfig() } else if (args.includes('--reset')) { resetConfig() } else { interactiveConfig() } } module.exports = { loadConfig, saveConfig, showConfig, interactiveConfig, handleConfig, getConfig, resetConfig, CONFIG_FILE, CONFIG_DIR }