Skip to main content
Glama
config.ts6.98 kB
/** * Configuration Management * * 加载和验证 MCP Server 配置 * * 支持所有 MCP 客户端的配置方式: * - Claude Desktop: claude_desktop_config.json * - Cline (VSCode): settings.json * - Continue (VSCode): config.json * - 其他 MCP 客户端: 通过环境变量配置 */ import { createLogger } from './logger.js'; import { ProjectConfigManager } from './config/project.js'; import { GlobalConfigManager } from './config/global.js'; const logger = createLogger('config'); export interface GiteaConfig { // Gitea 服务器配置(必填) baseUrl: string; // 认证配置(二选一) apiToken?: string; username?: string; password?: string; // 默认上下文(可选) defaultOwner?: string; defaultRepo?: string; defaultOrg?: string; // 默认组织 defaultProject?: number; // 默认项目 ID // 其他配置 logLevel?: string; timeout?: number; // API 请求超时时间(毫秒) } /** * 从环境变量加载配置 */ export function loadConfigFromEnv(): GiteaConfig { const config: GiteaConfig = { // Gitea 服务器配置 baseUrl: process.env.GITEA_BASE_URL || '', // 认证配置 apiToken: process.env.GITEA_API_TOKEN || process.env.GITEA_TOKEN, username: process.env.GITEA_USERNAME, password: process.env.GITEA_PASSWORD, // 默认上下文 defaultOwner: process.env.GITEA_DEFAULT_OWNER, defaultRepo: process.env.GITEA_DEFAULT_REPO, defaultOrg: process.env.GITEA_DEFAULT_ORG, defaultProject: process.env.GITEA_DEFAULT_PROJECT ? parseInt(process.env.GITEA_DEFAULT_PROJECT, 10) : undefined, // 其他配置 logLevel: process.env.LOG_LEVEL || 'info', timeout: process.env.GITEA_TIMEOUT ? parseInt(process.env.GITEA_TIMEOUT, 10) : 30000, }; return config; } /** * 从环境变量、项目配置和全局配置加载完整配置 */ export function loadConfig(): GiteaConfig { const envConfig = loadConfigFromEnv(); // 尝试从项目配置获取默认值 const projectConfig = new ProjectConfigManager().getMergedConfig(); // 尝试从全局配置获取默认服务器/Token const globalConfig = new GlobalConfigManager(); const defaultServer = globalConfig.getDefaultServer(); const serverFromRef = projectConfig.serverRef ? globalConfig.getServer(projectConfig.serverRef) : undefined; const serverFromUrl = !serverFromRef && projectConfig.url ? globalConfig.getServerByUrl(projectConfig.url) : undefined; const preferredServer = serverFromRef || serverFromUrl || defaultServer; const resolveEnvValue = (value?: string) => { if (!value) return undefined; const match = value.match(/^\$\{(.+)\}$/); const varName = match ? match[1] : value; return process.env[varName]; }; const resolveTokenFromGlobalRef = (tokenId?: string): string | undefined => { if (!tokenId) return undefined; const servers = preferredServer ? [preferredServer, ...globalConfig.getServers().filter(s => s.id !== preferredServer.id)] : globalConfig.getServers(); for (const server of servers) { const token = server.tokens.find(t => t.id === tokenId); if (token) { return token.token; } } return undefined; }; const config: GiteaConfig = { baseUrl: envConfig.baseUrl || projectConfig.url || preferredServer?.url || '', apiToken: envConfig.apiToken, username: envConfig.username, password: envConfig.password, defaultOwner: envConfig.defaultOwner || projectConfig.owner, defaultRepo: envConfig.defaultRepo || projectConfig.repo, defaultOrg: envConfig.defaultOrg || projectConfig.org, defaultProject: envConfig.defaultProject || projectConfig.projectId, logLevel: envConfig.logLevel, timeout: envConfig.timeout, }; if (!config.apiToken && !config.username) { config.apiToken = projectConfig.apiToken || resolveEnvValue(projectConfig.apiTokenEnv) || resolveTokenFromGlobalRef(projectConfig.tokenRef) || (preferredServer ? (preferredServer.tokens.find(t => t.isDefault)?.token || preferredServer.tokens[0]?.token) : undefined); } if (!config.baseUrl && preferredServer?.url) { config.baseUrl = preferredServer.url; } return config; } /** * 验证必填配置 */ export function validateConfig(config: GiteaConfig): void { // 验证 baseUrl if (!config.baseUrl) { const errorMessage = `Missing required configuration: baseUrl\n\n` + `Please configure the following environment variable in your MCP client config:\n` + ` - GITEA_BASE_URL (example: http://10.16.72.101:3008)\n\n` + `Configuration examples:\n` + ` - Claude Desktop: ~/Library/Application Support/Claude/claude_desktop_config.json\n` + ` - Cline (VSCode): .vscode/settings.json\n` + ` - Continue (VSCode): ~/.continue/config.json`; logger.error('Missing GITEA_BASE_URL'); throw new Error(errorMessage); } // 验证 URL 格式 try { new URL(config.baseUrl); } catch { throw new Error(`Invalid GITEA_BASE_URL: ${config.baseUrl}`); } // 验证认证配置(二选一) const hasToken = !!config.apiToken; const hasCredentials = !!(config.username && config.password); if (!hasToken && !hasCredentials) { const errorMessage = `Missing authentication configuration.\n\n` + `Please configure ONE of the following:\n\n` + `Option 1 (Recommended): API Token\n` + ` - GITEA_API_TOKEN=your_token_here\n\n` + `Option 2: Username + Password\n` + ` - GITEA_USERNAME=your_username\n` + ` - GITEA_PASSWORD=your_password\n\n` + `To create an API Token:\n` + ` 1. Login to Gitea\n` + ` 2. Go to Settings → Applications\n` + ` 3. Generate New Token\n` + ` 4. Copy and paste it to GITEA_API_TOKEN`; logger.error('Missing authentication configuration'); throw new Error(errorMessage); } if (hasCredentials && !config.username) { throw new Error('GITEA_PASSWORD is set but GITEA_USERNAME is missing'); } if (hasCredentials && !config.password) { throw new Error('GITEA_USERNAME is set but GITEA_PASSWORD is missing'); } logger.info({ baseUrl: config.baseUrl, authMethod: hasToken ? 'api_token' : 'username_password', defaultOwner: config.defaultOwner || '(not set)', defaultRepo: config.defaultRepo || '(not set)', }, 'Configuration validated successfully'); } /** * 获取认证头 */ export function getAuthHeader(config: GiteaConfig): Record<string, string> { if (config.apiToken) { return { 'Authorization': `token ${config.apiToken}`, }; } if (config.username && config.password) { const credentials = Buffer.from(`${config.username}:${config.password}`).toString('base64'); return { 'Authorization': `Basic ${credentials}`, }; } throw new Error('No authentication configuration available'); }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/SupenBysz/gitea-mcp-tool'

If you have feedback or need assistance with the MCP directory API, please join our Discord server