Skip to main content
Glama
client.ts3.95 kB
import https from 'https'; import fs from 'fs'; import path from 'path'; import { fileURLToPath } from 'url'; import type { ApiConfig, ApiResponse, DockerImage, DockerTag, GitLabReference, GitLabVersion, GitLabPipeline, } from '../types/index.js'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); /** * DevOps API Client with PEM certificate authentication */ export class DevOpsApiClient { private baseUrl: string; private httpsAgent: https.Agent; constructor(config?: Partial<ApiConfig>) { this.baseUrl = config?.baseUrl || 'https://labs.pointware.com'; // Load PEM certificate const certPath = config?.certPath || path.join(__dirname, '../../certs/client-cert.pem'); let cert: Buffer; try { cert = fs.readFileSync(certPath); } catch (error) { throw new Error(`Failed to load PEM certificate from ${certPath}: ${error}`); } // Create HTTPS agent with PEM certificate this.httpsAgent = new https.Agent({ cert, key: cert, // Using same file for both cert and key (combined PEM) rejectUnauthorized: true, }); } /** * Make HTTP request with PEM authentication */ private async request<T>(endpoint: string, method: string = 'GET'): Promise<ApiResponse<T>> { return new Promise((resolve, reject) => { const url = new URL(endpoint, this.baseUrl); const options: https.RequestOptions = { method, agent: this.httpsAgent, headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', }, }; const req = https.request(url, options, (res) => { let data = ''; res.on('data', (chunk) => { data += chunk; }); res.on('end', () => { try { const jsonData = data ? JSON.parse(data) : {}; if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) { resolve({ success: true, data: jsonData as T, }); } else { resolve({ success: false, error: jsonData.error || `HTTP ${res.statusCode}`, message: jsonData.message, }); } } catch (error) { reject(new Error(`Failed to parse response: ${error}`)); } }); }); req.on('error', (error) => { reject(new Error(`Request failed: ${error.message}`)); }); req.end(); }); } // ============ Docker Image APIs ============ /** * Search Docker images by keyword */ async searchDockerImages(keyword: string): Promise<ApiResponse<DockerImage[]>> { return this.request<DockerImage[]>(`/api/v1/docker/images?keyword=${encodeURIComponent(keyword)}`); } /** * Get tags for a Docker image */ async getDockerImageTags(imageName: string): Promise<ApiResponse<DockerTag[]>> { return this.request<DockerTag[]>(`/api/v1/docker/images/${encodeURIComponent(imageName)}/tags`); } // ============ GitLab CI APIs ============ /** * Search GitLab CI reference YAML by keyword */ async searchGitLabReferences(keyword: string): Promise<ApiResponse<GitLabReference[]>> { return this.request<GitLabReference[]>(`/api/v1/gitlab/references?keyword=${encodeURIComponent(keyword)}`); } /** * Get versions for a GitLab CI reference */ async getGitLabReferenceVersions(referenceName: string): Promise<ApiResponse<GitLabVersion[]>> { return this.request<GitLabVersion[]>(`/api/v1/gitlab/references/${encodeURIComponent(referenceName)}/versions`); } /** * Get GitLab CI custom pipeline information */ async getGitLabPipeline(pipelineName: string): Promise<ApiResponse<GitLabPipeline>> { return this.request<GitLabPipeline>(`/api/v1/gitlab/pipelines/${encodeURIComponent(pipelineName)}`); } }

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/pointware/devops-mcp'

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