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
JavaScript
/**
* 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