Skip to main content
Glama
project.ts7.37 kB
/** * Project Configuration Manager * * Manages project-level configuration files: * - .gitea-mcp.json (public, committed to Git) * - .gitea-mcp.local.json (private, not committed) * * Provides APIs for: * - Loading/saving project configuration * - Loading/saving local configuration * - Merging configurations with priority handling */ import * as fs from 'fs'; import * as path from 'path'; import { ProjectConfig, LocalConfig } from './types'; /** * Project config file names */ const PROJECT_CONFIG_FILE = '.gitea-mcp.json'; const LOCAL_CONFIG_FILE = '.gitea-mcp.local.json'; /** * Project Configuration Manager */ export class ProjectConfigManager { private projectPath: string; private projectConfigPath: string; private localConfigPath: string; constructor(projectPath: string = process.cwd()) { this.projectPath = projectPath; this.projectConfigPath = path.join(projectPath, PROJECT_CONFIG_FILE); this.localConfigPath = path.join(projectPath, LOCAL_CONFIG_FILE); } // ==================== Project Config (.gitea-mcp.json) ==================== /** * Check if project config exists */ hasProjectConfig(): boolean { return fs.existsSync(this.projectConfigPath); } /** * Load project configuration */ loadProjectConfig(): ProjectConfig | null { try { if (!this.hasProjectConfig()) { return null; } const content = fs.readFileSync(this.projectConfigPath, 'utf-8'); return JSON.parse(content); } catch (error) { console.warn(`Failed to load project config: ${error}`); return null; } } /** * Save project configuration */ saveProjectConfig(config: ProjectConfig): void { try { fs.writeFileSync( this.projectConfigPath, JSON.stringify(config, null, 2), 'utf-8' ); } catch (error) { throw new Error(`Failed to save project config: ${error}`); } } /** * Create a new project configuration */ createProjectConfig( server: { url: string; serverRef?: string; name?: string }, project: { owner: string; repo: string; org?: string; projectId?: number }, defaults?: { setAsDefaultContext?: boolean } ): ProjectConfig { const config: ProjectConfig = { version: '1.0', gitea: { url: server.url, serverRef: server.serverRef, name: server.name, }, project: { owner: project.owner, repo: project.repo, org: project.org, projectId: project.projectId, }, defaults: defaults || {}, }; this.saveProjectConfig(config); return config; } /** * Delete project configuration */ deleteProjectConfig(): boolean { try { if (this.hasProjectConfig()) { fs.unlinkSync(this.projectConfigPath); return true; } return false; } catch (error) { console.error(`Failed to delete project config: ${error}`); return false; } } // ==================== Local Config (.gitea-mcp.local.json) ==================== /** * Check if local config exists */ hasLocalConfig(): boolean { return fs.existsSync(this.localConfigPath); } /** * Load local configuration */ loadLocalConfig(): LocalConfig | null { try { if (!this.hasLocalConfig()) { return null; } const content = fs.readFileSync(this.localConfigPath, 'utf-8'); return JSON.parse(content); } catch (error) { console.warn(`Failed to load local config: ${error}`); return null; } } /** * Save local configuration */ saveLocalConfig(config: LocalConfig): void { try { fs.writeFileSync( this.localConfigPath, JSON.stringify(config, null, 2), 'utf-8' ); } catch (error) { throw new Error(`Failed to save local config: ${error}`); } } /** * Create a new local configuration */ createLocalConfig( token: { apiToken?: string; tokenRef?: string; apiTokenEnv?: string; }, overrides?: { owner?: string; repo?: string; url?: string; } ): LocalConfig { const config: LocalConfig = { gitea: { apiToken: token.apiToken, tokenRef: token.tokenRef, apiTokenEnv: token.apiTokenEnv, }, overrides: overrides || {}, }; this.saveLocalConfig(config); return config; } /** * Delete local configuration */ deleteLocalConfig(): boolean { try { if (this.hasLocalConfig()) { fs.unlinkSync(this.localConfigPath); return true; } return false; } catch (error) { console.error(`Failed to delete local config: ${error}`); return false; } } // ==================== Merged Configuration ==================== /** * Get merged configuration from project + local * Local config takes priority over project config */ getMergedConfig(): { project: ProjectConfig | null; local: LocalConfig | null; url?: string; serverRef?: string; owner?: string; repo?: string; org?: string; projectId?: number; apiToken?: string; tokenRef?: string; apiTokenEnv?: string; } { const project = this.loadProjectConfig(); const local = this.loadLocalConfig(); return { project, local, // Server info (project config) url: project?.gitea.url, serverRef: project?.gitea.serverRef, // Project info (project config, overridden by local) owner: local?.overrides?.owner || project?.project.owner, repo: local?.overrides?.repo || project?.project.repo, org: project?.project.org, projectId: project?.project.projectId, // Token info (local config only) apiToken: local?.gitea.apiToken, tokenRef: local?.gitea.tokenRef, apiTokenEnv: local?.gitea.apiTokenEnv, }; } // ==================== Utility Methods ==================== /** * Add .gitea-mcp.local.json to .gitignore */ addLocalConfigToGitignore(): void { const gitignorePath = path.join(this.projectPath, '.gitignore'); const ignoreEntry = '.gitea-mcp.local.json'; try { let content = ''; // Read existing .gitignore if it exists if (fs.existsSync(gitignorePath)) { content = fs.readFileSync(gitignorePath, 'utf-8'); // Check if already exists if (content.includes(ignoreEntry)) { return; // Already added } } // Add entry if (content && !content.endsWith('\n')) { content += '\n'; } content += ignoreEntry + '\n'; // Write back fs.writeFileSync(gitignorePath, content, 'utf-8'); } catch (error) { console.warn(`Failed to update .gitignore: ${error}`); } } /** * Get project path */ getProjectPath(): string { return this.projectPath; } /** * Get project config file path */ getProjectConfigPath(): string { return this.projectConfigPath; } /** * Get local config file path */ getLocalConfigPath(): string { return this.localConfigPath; } } /** * Create project config manager for current directory */ export function getProjectConfig(projectPath?: string): ProjectConfigManager { return new ProjectConfigManager(projectPath); }

Implementation Reference

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