UNPKG

ids-enterprise-mcp-server

Version:

Model Context Protocol (MCP) server providing comprehensive IDS Enterprise Web Components documentation access via GitLab API. Use with npx and GitLab token for instant access.

134 lines 5.25 kB
/** * GitLab API service for accessing IDS Enterprise Web Components repository */ import axios from 'axios'; import { logger } from '../utils/logger.js'; export class GitLabService { api; config; constructor(config) { this.config = config; this.api = axios.create({ baseURL: `${config.gitlabUrl}/api/v4`, headers: { 'PRIVATE-TOKEN': config.token, }, timeout: 30000, }); } /** * Test GitLab connection */ async testConnection() { try { logger.debug('Testing GitLab connection...'); const encodedProjectId = encodeURIComponent(this.config.projectId); await this.api.get(`/projects/${encodedProjectId}`); logger.debug('✓ GitLab connection successful'); } catch (error) { logger.error('❌ GitLab connection failed:', error.message); if (error.response?.status === 401) { throw new Error('GitLab authentication failed. Please check your token.'); } throw error; } } /** * Get GitLab URL for a file */ getGitLabUrl(filePath, projectId = this.config.projectId) { return `${this.config.gitlabUrl}/${projectId}/-/blob/${this.config.defaultBranch}/${filePath}`; } /** * Get GitLab tree URL */ getGitLabTreeUrl(path, projectId = this.config.projectId) { return `${this.config.gitlabUrl}/${projectId}/-/tree/${this.config.defaultBranch}/${path}`; } /** * Get repository tree (files and directories) with pagination support */ async getTree(path, recursive = false, projectId = this.config.projectId) { try { logger.api(`Fetching GitLab tree: ${path} (recursive: ${recursive})`); const encodedProjectId = encodeURIComponent(projectId); const allItems = []; let page = 1; let hasMorePages = true; while (hasMorePages) { const params = { ref: this.config.defaultBranch, per_page: 100, // Maximum allowed by GitLab page: page, }; if (path && path !== '/') { params.path = path; } if (recursive) { params.recursive = true; } logger.trace(`Fetching page ${page} for ${path}...`); const response = await this.api.get(`/projects/${encodedProjectId}/repository/tree`, { params, }); const pageItems = response.data || []; allItems.push(...pageItems); logger.trace(`Page ${page} returned ${pageItems.length} items`); // Check if there are more pages const totalPages = parseInt(response.headers['x-total-pages'] || '1'); const currentPage = parseInt(response.headers['x-page'] || '1'); hasMorePages = currentPage < totalPages && pageItems.length === 100; page++; // Safety check to prevent infinite loops if (page > 50) { logger.warn(`⚠️ Reached maximum page limit (50) for ${path}`); break; } } logger.api(`✓ GitLab tree for ${path}: ${allItems.length} total items across ${page - 1} pages`); return allItems; } catch (error) { logger.error(`❌ Failed to fetch GitLab tree for ${path}:`, error.message); if (error.response?.status === 401) { throw new Error('GitLab authentication failed. Please check your token.'); } if (error.response?.status === 404) { logger.warn(`⚠️ Path not found: ${path}`); return []; } throw error; } } /** * Get file content from GitLab */ async getFileContent(filePath, projectId = this.config.projectId) { try { logger.trace(`Fetching file content: ${filePath}`); const encodedProjectId = encodeURIComponent(projectId); const encodedFilePath = encodeURIComponent(filePath); const response = await this.api.get(`/projects/${encodedProjectId}/repository/files/${encodedFilePath}`, { params: { ref: this.config.defaultBranch, }, }); if (response.data && response.data.content) { const content = Buffer.from(response.data.content, 'base64').toString('utf-8'); logger.trace(`✓ Loaded ${filePath} (${content.length} chars)`); return content; } return null; } catch (error) { if (error.response?.status === 404) { logger.trace(`⚠️ File not found: ${filePath}`); return null; } logger.error(`❌ Failed to fetch file ${filePath}:`, error.message); return null; } } } //# sourceMappingURL=gitlab.js.map